protected virtual void ProcessServerKeyExchange(DtlsClientProtocol.ClientHandshakeState state, byte[] body) { MemoryStream memoryStream = new MemoryStream(body, false); state.keyExchange.ProcessServerKeyExchange(memoryStream); TlsProtocol.AssertEmpty(memoryStream); }
protected virtual void ProcessServerSupplementalData(DtlsClientProtocol.ClientHandshakeState state, byte[] body) { MemoryStream input = new MemoryStream(body, false); IList serverSupplementalData = TlsProtocol.ReadSupplementalDataMessage(input); state.client.ProcessServerSupplementalData(serverSupplementalData); }
protected virtual byte[] GenerateClientKeyExchange(DtlsClientProtocol.ClientHandshakeState state) { MemoryStream memoryStream = new MemoryStream(); state.keyExchange.GenerateClientKeyExchange(memoryStream); return(memoryStream.ToArray()); }
protected virtual byte[] GenerateCertificateVerify(DtlsClientProtocol.ClientHandshakeState state, DigitallySigned certificateVerify) { MemoryStream memoryStream = new MemoryStream(); certificateVerify.Encode(memoryStream); return(memoryStream.ToArray()); }
protected virtual void ProcessNewSessionTicket(DtlsClientProtocol.ClientHandshakeState state, byte[] body) { MemoryStream memoryStream = new MemoryStream(body, false); NewSessionTicket newSessionTicket = NewSessionTicket.Parse(memoryStream); TlsProtocol.AssertEmpty(memoryStream); state.client.NotifyNewSessionTicket(newSessionTicket); }
protected virtual Certificate ProcessServerCertificate(DtlsClientProtocol.ClientHandshakeState state, byte[] body) { MemoryStream memoryStream = new MemoryStream(body, false); Certificate certificate = Certificate.Parse(memoryStream); TlsProtocol.AssertEmpty(memoryStream); state.keyExchange.ProcessServerCertificate(certificate); state.authentication = state.client.GetAuthentication(); state.authentication.NotifyServerCertificate(certificate); return(certificate); }
protected virtual void ProcessCertificateStatus(DtlsClientProtocol.ClientHandshakeState state, byte[] body) { if (!state.allowCertificateStatus) { throw new TlsFatalAlert(10); } MemoryStream memoryStream = new MemoryStream(body, false); state.certificateStatus = CertificateStatus.Parse(memoryStream); TlsProtocol.AssertEmpty(memoryStream); }
public virtual DtlsTransport Connect(TlsClient client, DatagramTransport transport) { if (client == null) { throw new ArgumentNullException("client"); } if (transport == null) { throw new ArgumentNullException("transport"); } SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = 1; DtlsClientProtocol.ClientHandshakeState clientHandshakeState = new DtlsClientProtocol.ClientHandshakeState(); clientHandshakeState.client = client; clientHandshakeState.clientContext = new TlsClientContextImpl(this.mSecureRandom, securityParameters); securityParameters.clientRandom = TlsProtocol.CreateRandomBlock(client.ShouldUseGmtUnixTime(), clientHandshakeState.clientContext.NonceRandomGenerator); client.Init(clientHandshakeState.clientContext); DtlsRecordLayer dtlsRecordLayer = new DtlsRecordLayer(transport, clientHandshakeState.clientContext, client, 22); TlsSession sessionToResume = clientHandshakeState.client.GetSessionToResume(); if (sessionToResume != null && sessionToResume.IsResumable) { SessionParameters sessionParameters = sessionToResume.ExportSessionParameters(); if (sessionParameters != null) { clientHandshakeState.tlsSession = sessionToResume; clientHandshakeState.sessionParameters = sessionParameters; } } DtlsTransport result; try { result = this.ClientHandshake(clientHandshakeState, dtlsRecordLayer); } catch (TlsFatalAlert tlsFatalAlert) { dtlsRecordLayer.Fail(tlsFatalAlert.AlertDescription); throw tlsFatalAlert; } catch (IOException ex) { dtlsRecordLayer.Fail(80); throw ex; } catch (Exception alertCause) { dtlsRecordLayer.Fail(80); throw new TlsFatalAlert(80, alertCause); } return(result); }
protected virtual void ProcessCertificateRequest(DtlsClientProtocol.ClientHandshakeState state, byte[] body) { if (state.authentication == null) { throw new TlsFatalAlert(40); } MemoryStream memoryStream = new MemoryStream(body, false); state.certificateRequest = CertificateRequest.Parse(state.clientContext, memoryStream); TlsProtocol.AssertEmpty(memoryStream); state.keyExchange.ValidateCertificateRequest(state.certificateRequest); }
protected virtual byte[] GenerateClientHello(DtlsClientProtocol.ClientHandshakeState state, TlsClient client) { MemoryStream memoryStream = new MemoryStream(); ProtocolVersion clientVersion = client.ClientVersion; if (!clientVersion.IsDtls) { throw new TlsFatalAlert(80); } TlsClientContextImpl clientContext = state.clientContext; clientContext.SetClientVersion(clientVersion); TlsUtilities.WriteVersion(clientVersion, memoryStream); SecurityParameters securityParameters = clientContext.SecurityParameters; memoryStream.Write(securityParameters.ClientRandom, 0, securityParameters.ClientRandom.Length); byte[] array = TlsUtilities.EmptyBytes; if (state.tlsSession != null) { array = state.tlsSession.SessionID; if (array == null || array.Length > 32) { array = TlsUtilities.EmptyBytes; } } TlsUtilities.WriteOpaque8(array, memoryStream); TlsUtilities.WriteOpaque8(TlsUtilities.EmptyBytes, memoryStream); bool isFallback = client.IsFallback; state.offeredCipherSuites = client.GetCipherSuites(); state.clientExtensions = client.GetClientExtensions(); byte[] extensionData = TlsUtilities.GetExtensionData(state.clientExtensions, 65281); bool flag = null == extensionData; bool flag2 = !Arrays.Contains(state.offeredCipherSuites, 255); if (flag && flag2) { state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, 255); } if (isFallback && !Arrays.Contains(state.offeredCipherSuites, 22016)) { state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, 22016); } TlsUtilities.WriteUint16ArrayWithUint16Length(state.offeredCipherSuites, memoryStream); byte[] offeredCompressionMethods = new byte[1]; state.offeredCompressionMethods = offeredCompressionMethods; TlsUtilities.WriteUint8ArrayWithUint8Length(state.offeredCompressionMethods, memoryStream); if (state.clientExtensions != null) { TlsProtocol.WriteExtensions(memoryStream, state.clientExtensions); } return(memoryStream.ToArray()); }
protected virtual void InvalidateSession(DtlsClientProtocol.ClientHandshakeState state) { if (state.sessionParameters != null) { state.sessionParameters.Clear(); state.sessionParameters = null; } if (state.tlsSession != null) { state.tlsSession.Invalidate(); state.tlsSession = null; } }
protected virtual void ReportServerVersion(DtlsClientProtocol.ClientHandshakeState state, ProtocolVersion server_version) { TlsClientContextImpl clientContext = state.clientContext; ProtocolVersion serverVersion = clientContext.ServerVersion; if (serverVersion == null) { clientContext.SetServerVersion(server_version); state.client.NotifyServerVersion(server_version); return; } if (!serverVersion.Equals(server_version)) { throw new TlsFatalAlert(47); } }
protected virtual byte[] ProcessHelloVerifyRequest(DtlsClientProtocol.ClientHandshakeState state, byte[] body) { MemoryStream memoryStream = new MemoryStream(body, false); ProtocolVersion protocolVersion = TlsUtilities.ReadVersion(memoryStream); byte[] array = TlsUtilities.ReadOpaque8(memoryStream); TlsProtocol.AssertEmpty(memoryStream); if (!protocolVersion.IsEqualOrEarlierVersionOf(state.clientContext.ClientVersion)) { throw new TlsFatalAlert(47); } if (!ProtocolVersion.DTLSv12.IsEqualOrEarlierVersionOf(protocolVersion) && array.Length > 32) { throw new TlsFatalAlert(47); } return(array); }
protected virtual void ProcessServerHello(DtlsClientProtocol.ClientHandshakeState state, byte[] body) { SecurityParameters securityParameters = state.clientContext.SecurityParameters; MemoryStream input = new MemoryStream(body, false); ProtocolVersion server_version = TlsUtilities.ReadVersion(input); this.ReportServerVersion(state, server_version); securityParameters.serverRandom = TlsUtilities.ReadFully(32, input); state.selectedSessionID = TlsUtilities.ReadOpaque8(input); if (state.selectedSessionID.Length > 32) { throw new TlsFatalAlert(47); } state.client.NotifySessionID(state.selectedSessionID); state.resumedSession = (state.selectedSessionID.Length > 0 && state.tlsSession != null && Arrays.AreEqual(state.selectedSessionID, state.tlsSession.SessionID)); int num = TlsUtilities.ReadUint16(input); if (!Arrays.Contains(state.offeredCipherSuites, num) || num == 0 || CipherSuite.IsScsv(num) || !TlsUtilities.IsValidCipherSuiteForVersion(num, state.clientContext.ServerVersion)) { throw new TlsFatalAlert(47); } DtlsProtocol.ValidateSelectedCipherSuite(num, 47); state.client.NotifySelectedCipherSuite(num); byte b = TlsUtilities.ReadUint8(input); if (!Arrays.Contains(state.offeredCompressionMethods, b)) { throw new TlsFatalAlert(47); } state.client.NotifySelectedCompressionMethod(b); state.serverExtensions = TlsProtocol.ReadExtensions(input); if (state.serverExtensions != null) { foreach (int num2 in state.serverExtensions.Keys) { if (num2 != 65281) { if (TlsUtilities.GetExtensionData(state.clientExtensions, num2) == null) { throw new TlsFatalAlert(110); } bool arg_16B_0 = state.resumedSession; } } } byte[] extensionData = TlsUtilities.GetExtensionData(state.serverExtensions, 65281); if (extensionData != null) { state.secure_renegotiation = true; if (!Arrays.ConstantTimeAreEqual(extensionData, TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes))) { throw new TlsFatalAlert(40); } } state.client.NotifySecureRenegotiation(state.secure_renegotiation); IDictionary dictionary = state.clientExtensions; IDictionary dictionary2 = state.serverExtensions; if (state.resumedSession) { if (num != state.sessionParameters.CipherSuite || b != state.sessionParameters.CompressionAlgorithm) { throw new TlsFatalAlert(47); } dictionary = null; dictionary2 = state.sessionParameters.ReadServerExtensions(); } securityParameters.cipherSuite = num; securityParameters.compressionAlgorithm = b; if (dictionary2 != null) { bool flag = TlsExtensionsUtilities.HasEncryptThenMacExtension(dictionary2); if (flag && !TlsUtilities.IsBlockCipherSuite(securityParameters.CipherSuite)) { throw new TlsFatalAlert(47); } securityParameters.encryptThenMac = flag; securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(dictionary2); securityParameters.maxFragmentLength = DtlsProtocol.EvaluateMaxFragmentLengthExtension(state.resumedSession, dictionary, dictionary2, 47); securityParameters.truncatedHMac = TlsExtensionsUtilities.HasTruncatedHMacExtension(dictionary2); state.allowCertificateStatus = (!state.resumedSession && TlsUtilities.HasExpectedEmptyExtensionData(dictionary2, 5, 47)); state.expectSessionTicket = (!state.resumedSession && TlsUtilities.HasExpectedEmptyExtensionData(dictionary2, 35, 47)); } if (dictionary != null) { state.client.ProcessServerExtensions(dictionary2); } securityParameters.prfAlgorithm = TlsProtocol.GetPrfAlgorithm(state.clientContext, securityParameters.CipherSuite); securityParameters.verifyDataLength = 12; }
internal virtual DtlsTransport ClientHandshake(DtlsClientProtocol.ClientHandshakeState state, DtlsRecordLayer recordLayer) { SecurityParameters securityParameters = state.clientContext.SecurityParameters; DtlsReliableHandshake dtlsReliableHandshake = new DtlsReliableHandshake(state.clientContext, recordLayer); byte[] array = this.GenerateClientHello(state, state.client); dtlsReliableHandshake.SendMessage(1, array); DtlsReliableHandshake.Message message = dtlsReliableHandshake.ReceiveMessage(); while (message.Type == 3) { ProtocolVersion protocolVersion = recordLayer.ResetDiscoveredPeerVersion(); ProtocolVersion clientVersion = state.clientContext.ClientVersion; if (!protocolVersion.IsEqualOrEarlierVersionOf(clientVersion)) { throw new TlsFatalAlert(47); } byte[] cookie = this.ProcessHelloVerifyRequest(state, message.Body); byte[] body = DtlsClientProtocol.PatchClientHelloWithCookie(array, cookie); dtlsReliableHandshake.ResetHandshakeMessagesDigest(); dtlsReliableHandshake.SendMessage(1, body); message = dtlsReliableHandshake.ReceiveMessage(); } if (message.Type != 2) { throw new TlsFatalAlert(10); } this.ReportServerVersion(state, recordLayer.DiscoveredPeerVersion); this.ProcessServerHello(state, message.Body); dtlsReliableHandshake.NotifyHelloComplete(); DtlsProtocol.ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength); if (state.resumedSession) { securityParameters.masterSecret = Arrays.Clone(state.sessionParameters.MasterSecret); recordLayer.InitPendingEpoch(state.client.GetCipher()); byte[] expected_verify_data = TlsUtilities.CalculateVerifyData(state.clientContext, "server finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null)); this.ProcessFinished(dtlsReliableHandshake.ReceiveMessageBody(20), expected_verify_data); byte[] body2 = TlsUtilities.CalculateVerifyData(state.clientContext, "client finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null)); dtlsReliableHandshake.SendMessage(20, body2); dtlsReliableHandshake.Finish(); state.clientContext.SetResumableSession(state.tlsSession); state.client.NotifyHandshakeComplete(); return(new DtlsTransport(recordLayer)); } this.InvalidateSession(state); if (state.selectedSessionID.Length > 0) { state.tlsSession = new TlsSessionImpl(state.selectedSessionID, null); } message = dtlsReliableHandshake.ReceiveMessage(); if (message.Type == 23) { this.ProcessServerSupplementalData(state, message.Body); message = dtlsReliableHandshake.ReceiveMessage(); } else { state.client.ProcessServerSupplementalData(null); } state.keyExchange = state.client.GetKeyExchange(); state.keyExchange.Init(state.clientContext); Certificate certificate = null; if (message.Type == 11) { certificate = this.ProcessServerCertificate(state, message.Body); message = dtlsReliableHandshake.ReceiveMessage(); } else { state.keyExchange.SkipServerCredentials(); } if (certificate == null || certificate.IsEmpty) { state.allowCertificateStatus = false; } if (message.Type == 22) { this.ProcessCertificateStatus(state, message.Body); message = dtlsReliableHandshake.ReceiveMessage(); } if (message.Type == 12) { this.ProcessServerKeyExchange(state, message.Body); message = dtlsReliableHandshake.ReceiveMessage(); } else { state.keyExchange.SkipServerKeyExchange(); } if (message.Type == 13) { this.ProcessCertificateRequest(state, message.Body); TlsUtilities.TrackHashAlgorithms(dtlsReliableHandshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms); message = dtlsReliableHandshake.ReceiveMessage(); } if (message.Type != 14) { throw new TlsFatalAlert(10); } if (message.Body.Length != 0) { throw new TlsFatalAlert(50); } dtlsReliableHandshake.HandshakeHash.SealHashAlgorithms(); IList clientSupplementalData = state.client.GetClientSupplementalData(); if (clientSupplementalData != null) { byte[] body3 = DtlsProtocol.GenerateSupplementalData(clientSupplementalData); dtlsReliableHandshake.SendMessage(23, body3); } if (state.certificateRequest != null) { state.clientCredentials = state.authentication.GetClientCredentials(state.certificateRequest); Certificate certificate2 = null; if (state.clientCredentials != null) { certificate2 = state.clientCredentials.Certificate; } if (certificate2 == null) { certificate2 = Certificate.EmptyChain; } byte[] body4 = DtlsProtocol.GenerateCertificate(certificate2); dtlsReliableHandshake.SendMessage(11, body4); } if (state.clientCredentials != null) { state.keyExchange.ProcessClientCredentials(state.clientCredentials); } else { state.keyExchange.SkipClientCredentials(); } byte[] body5 = this.GenerateClientKeyExchange(state); dtlsReliableHandshake.SendMessage(16, body5); TlsHandshakeHash tlsHandshakeHash = dtlsReliableHandshake.PrepareToFinish(); securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.clientContext, tlsHandshakeHash, null); TlsProtocol.EstablishMasterSecret(state.clientContext, state.keyExchange); recordLayer.InitPendingEpoch(state.client.GetCipher()); if (state.clientCredentials != null && state.clientCredentials is TlsSignerCredentials) { TlsSignerCredentials tlsSignerCredentials = (TlsSignerCredentials)state.clientCredentials; SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(state.clientContext, tlsSignerCredentials); byte[] hash; if (signatureAndHashAlgorithm == null) { hash = securityParameters.SessionHash; } else { hash = tlsHandshakeHash.GetFinalHash(signatureAndHashAlgorithm.Hash); } byte[] signature = tlsSignerCredentials.GenerateCertificateSignature(hash); DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); byte[] body6 = this.GenerateCertificateVerify(state, certificateVerify); dtlsReliableHandshake.SendMessage(15, body6); } byte[] body7 = TlsUtilities.CalculateVerifyData(state.clientContext, "client finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null)); dtlsReliableHandshake.SendMessage(20, body7); if (state.expectSessionTicket) { message = dtlsReliableHandshake.ReceiveMessage(); if (message.Type != 4) { throw new TlsFatalAlert(10); } this.ProcessNewSessionTicket(state, message.Body); } byte[] expected_verify_data2 = TlsUtilities.CalculateVerifyData(state.clientContext, "server finished", TlsProtocol.GetCurrentPrfHash(state.clientContext, dtlsReliableHandshake.HandshakeHash, null)); this.ProcessFinished(dtlsReliableHandshake.ReceiveMessageBody(20), expected_verify_data2); dtlsReliableHandshake.Finish(); if (state.tlsSession != null) { state.sessionParameters = new SessionParameters.Builder().SetCipherSuite(securityParameters.CipherSuite).SetCompressionAlgorithm(securityParameters.CompressionAlgorithm).SetMasterSecret(securityParameters.MasterSecret).SetPeerCertificate(certificate).SetPskIdentity(securityParameters.PskIdentity).SetSrpIdentity(securityParameters.SrpIdentity).SetServerExtensions(state.serverExtensions).Build(); state.tlsSession = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters); state.clientContext.SetResumableSession(state.tlsSession); } state.client.NotifyHandshakeComplete(); return(new DtlsTransport(recordLayer)); }