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  }