Skip to content

Commit

Permalink
Official Version 1 Support (#1099)
Browse files Browse the repository at this point in the history
* Official Version 1 Support

* Minor fixes

* Update the ALPNs too

* WIP to fix VN

* Refactor reset

* Declare prototype

* Another build error

* Fix assert

* Fix format in interop

* Ingest latest OpenSSL fixes

* Update TLS unit test to set TP type

* Fix unaligned access

* Byteswap only for log

* Free old TLS on reset

* Fix 0-RTT ticket bug in stub
  • Loading branch information
nibanks authored Dec 20, 2020
1 parent ddf73d3 commit e449e47
Show file tree
Hide file tree
Showing 22 changed files with 200 additions and 425 deletions.
2 changes: 1 addition & 1 deletion .azure/templates/build-config-user.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:

- task: Cache@2
inputs:
key: '"${{ parameters.platform }}_${{ parameters.arch }}_${{ parameters.tls }}_${{ parameters.extraName }}_4" | .gitmodules'
key: '"${{ parameters.platform }}_${{ parameters.arch }}_${{ parameters.tls }}_${{ parameters.extraName }}_5" | .gitmodules'
path: build/${{ parameters.platform }}/${{ parameters.arch }}_${{ parameters.tls }}/openssl
displayName: Cache OpenSSL
condition: and(succeeded(), eq('${{ parameters.tls }}', 'openssl'))
Expand Down
6 changes: 1 addition & 5 deletions src/core/binding.c
Original file line number Diff line number Diff line change
Expand Up @@ -1432,12 +1432,8 @@ QuicBindingDeliverDatagrams(
// Only Initial (version specific) packets are processed from here on.
//
switch (Packet->Invariant->LONG_HDR.Version) {
case QUIC_VERSION_DRAFT_27:
case QUIC_VERSION_DRAFT_28:
case QUIC_VERSION_1:
case QUIC_VERSION_DRAFT_29:
case QUIC_VERSION_DRAFT_30:
case QUIC_VERSION_DRAFT_31:
case QUIC_VERSION_DRAFT_32:
case QUIC_VERSION_MS_1:
if (Packet->LH->Type != QUIC_INITIAL) {
QuicPacketLogDrop(Binding, Packet, "Non-initial packet not matched with a connection");
Expand Down
151 changes: 51 additions & 100 deletions src/core/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -1694,12 +1694,8 @@ QuicConnOnQuicVersionSet(
Connection->Stats.QuicVersion);

switch (Connection->Stats.QuicVersion) {
case QUIC_VERSION_DRAFT_27:
case QUIC_VERSION_DRAFT_28:
case QUIC_VERSION_1:
case QUIC_VERSION_DRAFT_29:
case QUIC_VERSION_DRAFT_30:
case QUIC_VERSION_DRAFT_31:
case QUIC_VERSION_DRAFT_32:
case QUIC_VERSION_MS_1:
default:
Connection->State.HeaderProtectionEnabled = TRUE;
Expand Down Expand Up @@ -1888,6 +1884,13 @@ QuicConnStart(
return Status;
}

_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicConnGenerateLocalTransportParameters(
_In_ QUIC_CONNECTION* Connection,
_Out_ QUIC_TRANSPORT_PARAMETERS* LocalTP
);

_IRQL_requires_max_(PASSIVE_LEVEL)
void
QuicConnRestart(
Expand Down Expand Up @@ -1921,8 +1924,30 @@ QuicConnRestart(
QuicCongestionControlReset(&Connection->CongestionControl);
QuicSendReset(&Connection->Send);
QuicLossDetectionReset(&Connection->LossDetection);
QuicCryptoReset(&Connection->Crypto, CompleteReset);

if (CompleteReset) {
QUIC_DBG_ASSERT(Connection->Configuration != NULL);

QUIC_TRANSPORT_PARAMETERS LocalTP = { 0 };
QUIC_STATUS Status =
QuicConnGenerateLocalTransportParameters(Connection, &LocalTP);
QUIC_FRE_ASSERT(QUIC_SUCCEEDED(Status)); // Can't fail since it passed already.
UNREFERENCED_PARAMETER(Status);

Status =
QuicCryptoInitializeTls(
&Connection->Crypto,
Connection->Configuration->SecurityConfig,
&LocalTP);
if (QUIC_FAILED(Status)) {
QuicConnFatalError(Connection, Status, NULL);
}

} else {
QuicCryptoReset(&Connection->Crypto);
}
}

_IRQL_requires_max_(PASSIVE_LEVEL)
QUIC_STATUS
QuicConnSendResumptionTicket(
Expand Down Expand Up @@ -2164,14 +2189,12 @@ QuicConnGenerateLocalTransportParameters(
LocalTP->AckDelayExponent = Connection->AckDelayExponent;
}

if (Connection->Stats.QuicVersion != QUIC_VERSION_DRAFT_27) {
LocalTP->Flags |= QUIC_TP_FLAG_INITIAL_SOURCE_CONNECTION_ID;
LocalTP->InitialSourceConnectionIDLength = SourceCid->CID.Length;
QuicCopyMemory(
LocalTP->InitialSourceConnectionID,
SourceCid->CID.Data,
SourceCid->CID.Length);
}
LocalTP->Flags |= QUIC_TP_FLAG_INITIAL_SOURCE_CONNECTION_ID;
LocalTP->InitialSourceConnectionIDLength = SourceCid->CID.Length;
QuicCopyMemory(
LocalTP->InitialSourceConnectionID,
SourceCid->CID.Data,
SourceCid->CID.Length);

if (Connection->Settings.DatagramReceiveEnabled) {
LocalTP->Flags |= QUIC_TP_FLAG_MAX_DATAGRAM_FRAME_SIZE;
Expand Down Expand Up @@ -2227,8 +2250,7 @@ QuicConnGenerateLocalTransportParameters(
QUIC_FREE(Connection->OrigDestCID, QUIC_POOL_CID);
Connection->OrigDestCID = NULL;

if (Connection->State.HandshakeUsedRetryPacket &&
Connection->Stats.QuicVersion != QUIC_VERSION_DRAFT_27) {
if (Connection->State.HandshakeUsedRetryPacket) {
QUIC_DBG_ASSERT(SourceCid->Link.Next != NULL);
const QUIC_CID_HASH_ENTRY* PrevSourceCid =
QUIC_CONTAINING_RECORD(
Expand Down Expand Up @@ -2369,71 +2391,6 @@ QuicConnSetConfiguration(
return Status;
}

BOOLEAN
QuicConnValidateTransportParameterDraft27CIDs(
_In_ QUIC_CONNECTION* Connection
)
{
if (Connection->State.HandshakeUsedRetryPacket) {
QUIC_DBG_ASSERT(!QuicConnIsServer(Connection));
QUIC_DBG_ASSERT(Connection->OrigDestCID != NULL);
//
// If we received a Retry packet during the handshake, we (the client)
// must validate that the server knew the original connection ID we sent,
// so that we can be sure that no middle box injected the Retry packet.
//
if (!(Connection->PeerTransportParams.Flags & QUIC_TP_FLAG_ORIGINAL_DESTINATION_CONNECTION_ID)) {
QuicTraceEvent(
ConnError,
"[conn][%p] ERROR, %s.",
Connection,
"Peer didn't provide the original destination CID in TP");
return FALSE;
}

if (Connection->PeerTransportParams.OriginalDestinationConnectionIDLength != Connection->OrigDestCID->Length) {
QuicTraceEvent(
ConnError,
"[conn][%p] ERROR, %s.",
Connection,
"Peer provided incorrect length of original destination CID in TP");
return FALSE;
}

if (memcmp(
Connection->PeerTransportParams.OriginalDestinationConnectionID,
Connection->OrigDestCID->Data,
Connection->OrigDestCID->Length) != 0) {
QuicTraceEvent(
ConnError,
"[conn][%p] ERROR, %s.",
Connection,
"Peer provided incorrect original destination CID in TP");
return FALSE;
}

QUIC_FREE(Connection->OrigDestCID, QUIC_POOL_CID);
Connection->OrigDestCID = NULL;

} else if (!QuicConnIsServer(Connection)) {
//
// Per spec, the client must validate no original destination CID TP
// was sent if no Retry occurred. No need to validate cached values, as
// they don't apply to the current connection attempt.
//
if (!!(Connection->PeerTransportParams.Flags & QUIC_TP_FLAG_ORIGINAL_DESTINATION_CONNECTION_ID)) {
QuicTraceEvent(
ConnError,
"[conn][%p] ERROR, %s.",
Connection,
"Peer provided the original destination CID in TP when no Retry occurred");
return FALSE;
}
}

return TRUE;
}

BOOLEAN
QuicConnValidateTransportParameterCIDs(
_In_ QUIC_CONNECTION* Connection
Expand Down Expand Up @@ -2559,17 +2516,10 @@ QuicConnProcessPeerTransportParameters(
}

//
// Version draft-28 and later fully validate all exchanged connection IDs.
// Version draft-27 only validates in the Retry scenario.
// Fully validate all exchanged connection IDs.
//
if (Connection->Stats.QuicVersion == QUIC_VERSION_DRAFT_27) {
if (!QuicConnValidateTransportParameterDraft27CIDs(Connection)) {
goto Error;
}
} else {
if (!QuicConnValidateTransportParameterCIDs(Connection)) {
goto Error;
}
if (!QuicConnValidateTransportParameterCIDs(Connection)) {
goto Error;
}
}

Expand Down Expand Up @@ -2812,16 +2762,20 @@ QuicConnRecvVerNeg(
"Received Version Negotation:");
for (uint16_t i = 0; i < ServerVersionListLength; i++) {

uint32_t ServerVersion;
QuicCopyMemory(&ServerVersion, &ServerVersionList[i], sizeof(ServerVersion));

QuicTraceLogConnVerbose(
VerNegItem,
Connection,
" Ver[%d]: 0x%x", i,
QuicByteSwapUint32(ServerVersionList[i]));
" Ver[%d]: 0x%x",
i,
QuicByteSwapUint32(ServerVersion));

//
// Check to see if this is the current version.
//
if (ServerVersionList[i] == Connection->Stats.QuicVersion) {
if (ServerVersion == Connection->Stats.QuicVersion) {
QuicPacketLogDrop(Connection, Packet, "Version Negotation that includes the current version");
return;
}
Expand All @@ -2830,9 +2784,8 @@ QuicConnRecvVerNeg(
// Check to see if this is supported, if we haven't already found a
// supported version.
//
if (SupportedVersion == 0 &&
QuicIsVersionSupported(ServerVersionList[i])) {
SupportedVersion = ServerVersionList[i];
if (SupportedVersion == 0 && QuicIsVersionSupported(ServerVersion)) {
SupportedVersion = ServerVersion;
}
}

Expand Down Expand Up @@ -3204,9 +3157,7 @@ QuicConnRecvHeader(

QuicPathSetValid(Connection, Path, QUIC_PATH_VALID_INITIAL_TOKEN);

} else if (
Connection->Stats.QuicVersion != QUIC_VERSION_DRAFT_27 &&
Connection->OrigDestCID == NULL) {
} else if (Connection->OrigDestCID == NULL) {

Connection->OrigDestCID =
QUIC_ALLOC_NONPAGED(
Expand Down
38 changes: 23 additions & 15 deletions src/core/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,16 @@ QuicCryptoInitializeTls(
QUIC_DBG_ASSERT(SecConfig != NULL);
QUIC_DBG_ASSERT(Connection->Configuration != NULL);

Crypto->MaxSentLength = 0;
Crypto->UnAckedOffset = 0;
Crypto->NextSendOffset = 0;
Crypto->RecoveryNextOffset = 0;
Crypto->RecoveryEndOffset = 0;
Crypto->InRecovery = FALSE;

Crypto->TlsState.BufferLength = 0;
Crypto->TlsState.BufferTotalLength = 0;

TlsConfig.IsServer = IsServer;
if (IsServer) {
TlsConfig.AlpnBuffer = Crypto->TlsState.NegotiatedAlpn;
Expand All @@ -292,6 +302,10 @@ QuicCryptoInitializeTls(
TlsConfig.TlsSecrets = Connection->TlsSecrets;
#endif

TlsConfig.TPType =
Connection->Stats.QuicVersion != QUIC_VERSION_DRAFT_29 ?
TLS_EXTENSION_TYPE_QUIC_TRANSPORT_PARAMETERS :
TLS_EXTENSION_TYPE_QUIC_TRANSPORT_PARAMETERS_DRAFT;
TlsConfig.LocalTPBuffer =
QuicCryptoTlsEncodeTransportParameters(
Connection,
Expand All @@ -305,6 +319,11 @@ QuicCryptoInitializeTls(
goto Error;
}

if (Crypto->TLS != NULL) {
QuicTlsUninitialize(Crypto->TLS);
Crypto->TLS = NULL;
}

Status = QuicTlsInitialize(&TlsConfig, &Crypto->TlsState, &Crypto->TLS);
if (QUIC_FAILED(Status)) {
QuicTraceEvent(
Expand All @@ -329,8 +348,7 @@ QuicCryptoInitializeTls(
_IRQL_requires_max_(PASSIVE_LEVEL)
void
QuicCryptoReset(
_In_ QUIC_CRYPTO* Crypto,
_In_ BOOLEAN ResetTls
_In_ QUIC_CRYPTO* Crypto
)
{
QUIC_DBG_ASSERT(!QuicConnIsServer(QuicCryptoGetConnection(Crypto)));
Expand All @@ -345,19 +363,9 @@ QuicCryptoReset(
Crypto->RecoveryEndOffset = 0;
Crypto->InRecovery = FALSE;

UNREFERENCED_PARAMETER(ResetTls);
/*if (ResetTls) {
Crypto->TlsState.BufferLength = 0;
Crypto->TlsState.BufferTotalLength = 0;
QuicTlsReset(Crypto->TLS);
QuicCryptoProcessData(Crypto, TRUE);
} else*/ {
QuicSendSetSendFlag(
&QuicCryptoGetConnection(Crypto)->Send,
QUIC_CONN_SEND_FLAG_CRYPTO);
}
QuicSendSetSendFlag(
&QuicCryptoGetConnection(Crypto)->Send,
QUIC_CONN_SEND_FLAG_CRYPTO);

QuicCryptoValidate(Crypto);
}
Expand Down
3 changes: 1 addition & 2 deletions src/core/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,7 @@ QuicCryptoInitializeTls(
_IRQL_requires_max_(PASSIVE_LEVEL)
void
QuicCryptoReset(
_In_ QUIC_CRYPTO* Crypto,
_In_ BOOLEAN ResetTls
_In_ QUIC_CRYPTO* Crypto
);

//
Expand Down
17 changes: 15 additions & 2 deletions src/core/crypto_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ typedef enum eTlsExtensions {
TlsExt_ServerName = 0x00,
TlsExt_AppProtocolNegotiation = 0x10,
TlsExt_SessionTicket = 0x23,
TlsExt_QuicTransportParameters = 0xffa5
} eTlsExtensions;

typedef enum eSniNameType {
Expand Down Expand Up @@ -387,7 +386,21 @@ QuicCryptoTlsReadExtensions(
return Status;
}

} else if (ExtType == TlsExt_QuicTransportParameters) {
} else if (
Connection->Stats.QuicVersion != QUIC_VERSION_DRAFT_29 &&
ExtType == TLS_EXTENSION_TYPE_QUIC_TRANSPORT_PARAMETERS) {
if (!QuicCryptoTlsDecodeTransportParameters(
Connection,
FALSE,
Buffer,
ExtLen,
&Connection->PeerTransportParams)) {
return QUIC_STATUS_INVALID_PARAMETER;
}
FoundTransportParameters = TRUE;
} else if (
Connection->Stats.QuicVersion == QUIC_VERSION_DRAFT_29 &&
ExtType == TLS_EXTENSION_TYPE_QUIC_TRANSPORT_PARAMETERS_DRAFT) {
if (!QuicCryptoTlsDecodeTransportParameters(
Connection,
FALSE,
Expand Down
Loading

0 comments on commit e449e47

Please sign in to comment.