golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/key_update_test.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build go1.21 6 7 package quic 8 9 import ( 10 "testing" 11 ) 12 13 func TestKeyUpdatePeerUpdates(t *testing.T) { 14 tc := newTestConn(t, serverSide) 15 tc.handshake() 16 tc.ignoreFrames = nil // ignore nothing 17 18 // Peer initiates a key update. 19 tc.sendKeyNumber = 1 20 tc.sendKeyPhaseBit = true 21 tc.writeFrames(packetType1RTT, debugFramePing{}) 22 23 // We update to the new key. 24 tc.advanceToTimer() 25 tc.wantFrameType("conn ACKs last packet", 26 packetType1RTT, debugFrameAck{}) 27 tc.wantFrame("first packet after a key update is always ack-eliciting", 28 packetType1RTT, debugFramePing{}) 29 if got, want := tc.lastPacket.keyNumber, 1; got != want { 30 t.Errorf("after key rotation, conn sent packet with key %v, want %v", got, want) 31 } 32 if !tc.lastPacket.keyPhaseBit { 33 t.Errorf("after key rotation, conn failed to change Key Phase bit") 34 } 35 tc.wantIdle("conn has nothing to send") 36 37 // Peer's ACK of a packet we sent in the new phase completes the update. 38 tc.writeAckForAll() 39 40 // Peer initiates a second key update. 41 tc.sendKeyNumber = 2 42 tc.sendKeyPhaseBit = false 43 tc.writeFrames(packetType1RTT, debugFramePing{}) 44 45 // We update to the new key. 46 tc.advanceToTimer() 47 tc.wantFrameType("conn ACKs last packet", 48 packetType1RTT, debugFrameAck{}) 49 tc.wantFrame("first packet after a key update is always ack-eliciting", 50 packetType1RTT, debugFramePing{}) 51 if got, want := tc.lastPacket.keyNumber, 2; got != want { 52 t.Errorf("after key rotation, conn sent packet with key %v, want %v", got, want) 53 } 54 if tc.lastPacket.keyPhaseBit { 55 t.Errorf("after second key rotation, conn failed to change Key Phase bit") 56 } 57 tc.wantIdle("conn has nothing to send") 58 } 59 60 func TestKeyUpdateAcceptPreviousPhaseKeys(t *testing.T) { 61 // "An endpoint SHOULD retain old keys for some time after 62 // unprotecting a packet sent using the new keys." 63 // https://www.rfc-editor.org/rfc/rfc9001#section-6.1-8 64 tc := newTestConn(t, serverSide) 65 tc.handshake() 66 tc.ignoreFrames = nil // ignore nothing 67 68 // Peer initiates a key update, skipping one packet number. 69 pnum0 := tc.peerNextPacketNum[appDataSpace] 70 tc.peerNextPacketNum[appDataSpace]++ 71 tc.sendKeyNumber = 1 72 tc.sendKeyPhaseBit = true 73 tc.writeFrames(packetType1RTT, debugFramePing{}) 74 75 // We update to the new key. 76 // This ACK is not delayed, because we've skipped a packet number. 77 tc.wantFrame("conn ACKs last packet", 78 packetType1RTT, debugFrameAck{ 79 ranges: []i64range[packetNumber]{ 80 {0, pnum0}, 81 {pnum0 + 1, pnum0 + 2}, 82 }, 83 }) 84 tc.wantFrame("first packet after a key update is always ack-eliciting", 85 packetType1RTT, debugFramePing{}) 86 if got, want := tc.lastPacket.keyNumber, 1; got != want { 87 t.Errorf("after key rotation, conn sent packet with key %v, want %v", got, want) 88 } 89 if !tc.lastPacket.keyPhaseBit { 90 t.Errorf("after key rotation, conn failed to change Key Phase bit") 91 } 92 tc.wantIdle("conn has nothing to send") 93 94 // We receive the previously-skipped packet in the earlier key phase. 95 tc.peerNextPacketNum[appDataSpace] = pnum0 96 tc.sendKeyNumber = 0 97 tc.sendKeyPhaseBit = false 98 tc.writeFrames(packetType1RTT, debugFramePing{}) 99 100 // We ack the reordered packet immediately, still in the new key phase. 101 tc.wantFrame("conn ACKs reordered packet", 102 packetType1RTT, debugFrameAck{ 103 ranges: []i64range[packetNumber]{ 104 {0, pnum0 + 2}, 105 }, 106 }) 107 tc.wantIdle("packet is not ack-eliciting") 108 if got, want := tc.lastPacket.keyNumber, 1; got != want { 109 t.Errorf("after key rotation, conn sent packet with key %v, want %v", got, want) 110 } 111 if !tc.lastPacket.keyPhaseBit { 112 t.Errorf("after key rotation, conn failed to change Key Phase bit") 113 } 114 } 115 116 func TestKeyUpdateRejectPacketFromPriorPhase(t *testing.T) { 117 // "Packets with higher packet numbers MUST be protected with either 118 // the same or newer packet protection keys than packets with lower packet numbers." 119 // https://www.rfc-editor.org/rfc/rfc9001#section-6.4-2 120 tc := newTestConn(t, serverSide) 121 tc.handshake() 122 tc.ignoreFrames = nil // ignore nothing 123 124 // Peer initiates a key update. 125 tc.sendKeyNumber = 1 126 tc.sendKeyPhaseBit = true 127 tc.writeFrames(packetType1RTT, debugFramePing{}) 128 129 // We update to the new key. 130 tc.advanceToTimer() 131 tc.wantFrameType("conn ACKs last packet", 132 packetType1RTT, debugFrameAck{}) 133 tc.wantFrame("first packet after a key update is always ack-eliciting", 134 packetType1RTT, debugFramePing{}) 135 if got, want := tc.lastPacket.keyNumber, 1; got != want { 136 t.Errorf("after key rotation, conn sent packet with key %v, want %v", got, want) 137 } 138 if !tc.lastPacket.keyPhaseBit { 139 t.Errorf("after key rotation, conn failed to change Key Phase bit") 140 } 141 tc.wantIdle("conn has nothing to send") 142 143 // Peer sends an ack-eliciting packet using the prior phase keys. 144 // We fail to unprotect the packet and ignore it. 145 skipped := tc.peerNextPacketNum[appDataSpace] 146 tc.sendKeyNumber = 0 147 tc.sendKeyPhaseBit = false 148 tc.writeFrames(packetType1RTT, debugFramePing{}) 149 150 // Peer sends an ack-eliciting packet using the current phase keys. 151 tc.sendKeyNumber = 1 152 tc.sendKeyPhaseBit = true 153 tc.writeFrames(packetType1RTT, debugFramePing{}) 154 155 // We ack the peer's packets, not including the one sent with the wrong keys. 156 tc.wantFrame("conn ACKs packets, not including packet sent with wrong keys", 157 packetType1RTT, debugFrameAck{ 158 ranges: []i64range[packetNumber]{ 159 {0, skipped}, 160 {skipped + 1, skipped + 2}, 161 }, 162 }) 163 } 164 165 func TestKeyUpdateLocallyInitiated(t *testing.T) { 166 const updateAfter = 4 // initiate key update after 1-RTT packet 4 167 tc := newTestConn(t, serverSide) 168 tc.conn.keysAppData.updateAfter = updateAfter 169 tc.handshake() 170 171 for { 172 tc.writeFrames(packetType1RTT, debugFramePing{}) 173 tc.advanceToTimer() 174 tc.wantFrameType("conn ACKs last packet", 175 packetType1RTT, debugFrameAck{}) 176 if tc.lastPacket.num > updateAfter { 177 break 178 } 179 if got, want := tc.lastPacket.keyNumber, 0; got != want { 180 t.Errorf("before key update, conn sent packet with key %v, want %v", got, want) 181 } 182 if tc.lastPacket.keyPhaseBit { 183 t.Errorf("before key update, keyPhaseBit is set, want unset") 184 } 185 } 186 if got, want := tc.lastPacket.keyNumber, 1; got != want { 187 t.Errorf("after key update, conn sent packet with key %v, want %v", got, want) 188 } 189 if !tc.lastPacket.keyPhaseBit { 190 t.Errorf("after key update, keyPhaseBit is unset, want set") 191 } 192 tc.wantFrame("first packet after a key update is always ack-eliciting", 193 packetType1RTT, debugFramePing{}) 194 tc.wantIdle("no more frames") 195 196 // Peer sends another packet using the prior phase keys. 197 tc.writeFrames(packetType1RTT, debugFramePing{}) 198 tc.advanceToTimer() 199 tc.wantFrameType("conn ACKs packet in prior phase", 200 packetType1RTT, debugFrameAck{}) 201 tc.wantIdle("packet is not ack-eliciting") 202 if got, want := tc.lastPacket.keyNumber, 1; got != want { 203 t.Errorf("after key update, conn sent packet with key %v, want %v", got, want) 204 } 205 206 // Peer updates to the next phase. 207 tc.sendKeyNumber = 1 208 tc.sendKeyPhaseBit = true 209 tc.writeAckForAll() 210 tc.writeFrames(packetType1RTT, debugFramePing{}) 211 tc.advanceToTimer() 212 tc.wantFrameType("conn ACKs packet in current phase", 213 packetType1RTT, debugFrameAck{}) 214 tc.wantIdle("packet is not ack-eliciting") 215 if got, want := tc.lastPacket.keyNumber, 1; got != want { 216 t.Errorf("after key update, conn sent packet with key %v, want %v", got, want) 217 } 218 219 // Peer initiates its own update. 220 tc.sendKeyNumber = 2 221 tc.sendKeyPhaseBit = false 222 tc.writeFrames(packetType1RTT, debugFramePing{}) 223 tc.advanceToTimer() 224 tc.wantFrameType("conn ACKs packet in current phase", 225 packetType1RTT, debugFrameAck{}) 226 tc.wantFrame("first packet after a key update is always ack-eliciting", 227 packetType1RTT, debugFramePing{}) 228 if got, want := tc.lastPacket.keyNumber, 2; got != want { 229 t.Errorf("after peer key update, conn sent packet with key %v, want %v", got, want) 230 } 231 if tc.lastPacket.keyPhaseBit { 232 t.Errorf("after peer key update, keyPhaseBit is unset, want set") 233 } 234 }