Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Official Version 1 Support (#1099) #1114

Merged
merged 3 commits into from
Dec 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .azure/templates/build-config-user.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,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: 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 @@ -1427,12 +1427,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
148 changes: 51 additions & 97 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,68 +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;
} else 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;
} else 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;
} else {
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 @@ -2556,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 @@ -2809,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 @@ -2827,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 @@ -3203,9 +3159,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 @@ -289,6 +299,10 @@ QuicCryptoInitializeTls(
TlsConfig.ServerName = Connection->RemoteServerName;
}

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 @@ -302,6 +316,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 @@ -326,8 +345,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 @@ -342,19 +360,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 @@ -386,7 +385,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