internal DtlsReliableHandshake(TlsContext context, DtlsRecordLayer transport, int timeoutMillis) { this.mRecordLayer = transport; this.mHandshakeTimeout = Timeout.ForWaitMillis(timeoutMillis); this.mHandshakeHash = new DeferredHash(); this.mHandshakeHash.Init(context); }
private void SendRecord(byte contentType, byte[] buf, int off, int len) { if (len > this.mPlaintextLimit) { throw new TlsFatalAlert(80); } if (len < 1 && contentType != 23) { throw new TlsFatalAlert(80); } int epoch = this.mWriteEpoch.Epoch; long num = this.mWriteEpoch.AllocateSequenceNumber(); byte[] array = this.mWriteEpoch.Cipher.EncodePlaintext(DtlsRecordLayer.GetMacSequenceNumber(epoch, num), contentType, buf, off, len); byte[] array2 = new byte[array.Length + 13]; TlsUtilities.WriteUint8(contentType, array2, 0); ProtocolVersion version = (this.mDiscoveredPeerVersion != null) ? this.mDiscoveredPeerVersion : this.mContext.ClientVersion; TlsUtilities.WriteVersion(version, array2, 1); TlsUtilities.WriteUint16(epoch, array2, 3); TlsUtilities.WriteUint48(num, array2, 5); TlsUtilities.WriteUint16(array.Length, array2, 11); Array.Copy(array, 0, array2, 13, array.Length); this.mTransport.Send(array2, 0, array2.Length); }
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 = ConnectionEnd.client; ClientHandshakeState state = new ClientHandshakeState(); state.client = client; state.clientContext = new TlsClientContextImpl(mSecureRandom, securityParameters); securityParameters.clientRandom = TlsProtocol.CreateRandomBlock(client.ShouldUseGmtUnixTime(), state.clientContext.NonceRandomGenerator); client.Init(state.clientContext); DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.clientContext, client, ContentType.handshake); TlsSession sessionToResume = state.client.GetSessionToResume(); if (sessionToResume != null) { SessionParameters sessionParameters = sessionToResume.ExportSessionParameters(); if (sessionParameters != null) { state.tlsSession = sessionToResume; state.sessionParameters = sessionParameters; } } try { return(ClientHandshake(state, recordLayer)); } catch (TlsFatalAlert fatalAlert) { recordLayer.Fail(fatalAlert.AlertDescription); throw fatalAlert; } catch (IOException e) { recordLayer.Fail(AlertDescription.internal_error); throw e; } catch (Exception e) { recordLayer.Fail(AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error, e); } }
internal void SendToRecordLayer(DtlsRecordLayer recordLayer) { byte[] buffer = ((MemoryStream)this).GetBuffer(); int len = (int)((Stream)this).get_Length(); recordLayer.Send(buffer, 0, len); Platform.Dispose((Stream)(object)this); }
internal void SendToRecordLayer(DtlsRecordLayer recordLayer) { byte[] buf = ToArray(); int bufLen = buf.Length; recordLayer.Send(buf, 0, bufLen); Platform.Dispose(this); }
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 = ConnectionEnd.client; ClientHandshakeState state = new ClientHandshakeState(); state.client = client; state.clientContext = new TlsClientContextImpl(mSecureRandom, securityParameters); securityParameters.clientRandom = TlsProtocol.CreateRandomBlock(client.ShouldUseGmtUnixTime(), state.clientContext.NonceRandomGenerator); client.Init(state.clientContext); DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.clientContext, client, ContentType.handshake); TlsSession sessionToResume = state.client.GetSessionToResume(); if (sessionToResume != null && sessionToResume.IsResumable) { SessionParameters sessionParameters = sessionToResume.ExportSessionParameters(); if (sessionParameters != null) { state.tlsSession = sessionToResume; state.sessionParameters = sessionParameters; } } try { return ClientHandshake(state, recordLayer); } catch (TlsFatalAlert fatalAlert) { AbortClientHandshake(state, recordLayer, fatalAlert.AlertDescription); throw fatalAlert; } catch (IOException e) { AbortClientHandshake(state, recordLayer, AlertDescription.internal_error); throw e; } catch (Exception e) { AbortClientHandshake(state, recordLayer, AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error, e); } finally { securityParameters.Clear(); } }
public virtual DtlsTransport Connect(TlsClient client, DatagramTransport transport) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown if (client == null) { throw new ArgumentNullException("client"); } if (transport == null) { throw new ArgumentNullException("transport"); } SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = 1; ClientHandshakeState clientHandshakeState = new ClientHandshakeState(); clientHandshakeState.client = client; clientHandshakeState.clientContext = new TlsClientContextImpl(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; } } try { return(ClientHandshake(clientHandshakeState, dtlsRecordLayer)); } catch (TlsFatalAlert tlsFatalAlert) { dtlsRecordLayer.Fail(tlsFatalAlert.AlertDescription); throw tlsFatalAlert; } catch (IOException val) { IOException val2 = val; dtlsRecordLayer.Fail(80); throw val2; } catch (global::System.Exception alertCause) { dtlsRecordLayer.Fail(80); throw new TlsFatalAlert(80, alertCause); } }
public virtual DtlsTransport Accept(TlsServer server, DatagramTransport transport) { if (server == null) { throw new ArgumentNullException("server"); } if (transport == null) { throw new ArgumentNullException("transport"); } SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = ConnectionEnd.server; ServerHandshakeState state = new ServerHandshakeState(); state.server = server; state.serverContext = new TlsServerContextImpl(mSecureRandom, securityParameters); securityParameters.serverRandom = TlsProtocol.CreateRandomBlock(server.ShouldUseGmtUnixTime(), state.serverContext.NonceRandomGenerator); server.Init(state.serverContext); DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.serverContext, server, ContentType.handshake); server.NotifyCloseHandle(recordLayer); // TODO Need to handle sending of HelloVerifyRequest without entering a full connection try { return(ServerHandshake(state, recordLayer)); } catch (TlsFatalAlert fatalAlert) { AbortServerHandshake(state, recordLayer, fatalAlert.AlertDescription); throw fatalAlert; } catch (IOException e) { AbortServerHandshake(state, recordLayer, AlertDescription.internal_error); throw e; } catch (Exception e) { AbortServerHandshake(state, recordLayer, AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error, e); } finally { securityParameters.Clear(); } }
/// <exception cref="IOException"/> internal static void ApplyMaxFragmentLengthExtension(DtlsRecordLayer recordLayer, short maxFragmentLength) { if (maxFragmentLength >= 0) { if (!MaxFragmentLength.IsValid((byte)maxFragmentLength)) throw new TlsFatalAlert(AlertDescription.internal_error); int plainTextLimit = 1 << (8 + maxFragmentLength); recordLayer.SetPlaintextLimit(plainTextLimit); } }
internal static void ApplyMaxFragmentLengthExtension(DtlsRecordLayer recordLayer, short maxFragmentLength) { if (maxFragmentLength >= 0) { if (!MaxFragmentLength.IsValid((byte)maxFragmentLength)) { throw new TlsFatalAlert(80); } int plaintextLimit = 1 << 8 + maxFragmentLength; recordLayer.SetPlaintextLimit(plaintextLimit); } }
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); }
internal void SendToRecordLayer(DtlsRecordLayer recordLayer) { #if PORTABLE byte[] buf = ToArray(); int bufLen = buf.Length; #else byte[] buf = GetBuffer(); int bufLen = (int)Length; #endif recordLayer.Send(buf, 0, bufLen); Platform.Dispose(this); }
public virtual DtlsTransport Accept(TlsServer server, DatagramTransport transport) { if (server == null) throw new ArgumentNullException("server"); if (transport == null) throw new ArgumentNullException("transport"); SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = ConnectionEnd.server; ServerHandshakeState state = new ServerHandshakeState(); state.server = server; state.serverContext = new TlsServerContextImpl(mSecureRandom, securityParameters); securityParameters.serverRandom = TlsProtocol.CreateRandomBlock(server.ShouldUseGmtUnixTime(), state.serverContext.NonceRandomGenerator); server.Init(state.serverContext); DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.serverContext, server, ContentType.handshake); // TODO Need to handle sending of HelloVerifyRequest without entering a full connection try { return ServerHandshake(state, recordLayer); } catch (TlsFatalAlert fatalAlert) { AbortServerHandshake(state, recordLayer, fatalAlert.AlertDescription); throw fatalAlert; } catch (IOException e) { AbortServerHandshake(state, recordLayer, AlertDescription.internal_error); throw e; } catch (Exception e) { AbortServerHandshake(state, recordLayer, AlertDescription.internal_error); throw new TlsFatalAlert(AlertDescription.internal_error, e); } finally { securityParameters.Clear(); } }
public virtual DtlsTransport Accept(TlsServer server, DatagramTransport transport) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown if (server == null) { throw new ArgumentNullException("server"); } if (transport == null) { throw new ArgumentNullException("transport"); } SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = 0; ServerHandshakeState serverHandshakeState = new ServerHandshakeState(); serverHandshakeState.server = server; serverHandshakeState.serverContext = new TlsServerContextImpl(mSecureRandom, securityParameters); securityParameters.serverRandom = TlsProtocol.CreateRandomBlock(server.ShouldUseGmtUnixTime(), serverHandshakeState.serverContext.NonceRandomGenerator); server.Init(serverHandshakeState.serverContext); DtlsRecordLayer dtlsRecordLayer = new DtlsRecordLayer(transport, serverHandshakeState.serverContext, server, 22); try { return(ServerHandshake(serverHandshakeState, dtlsRecordLayer)); } catch (TlsFatalAlert tlsFatalAlert) { dtlsRecordLayer.Fail(tlsFatalAlert.AlertDescription); throw tlsFatalAlert; } catch (IOException val) { IOException val2 = val; dtlsRecordLayer.Fail(80); throw val2; } catch (global::System.Exception alertCause) { dtlsRecordLayer.Fail(80); throw new TlsFatalAlert(80, alertCause); } }
public virtual DtlsTransport Accept(TlsServer server, DatagramTransport transport) { if (server == null) { throw new ArgumentNullException("server"); } if (transport == null) { throw new ArgumentNullException("transport"); } SecurityParameters securityParameters = new SecurityParameters(); securityParameters.entity = 0; DtlsServerProtocol.ServerHandshakeState serverHandshakeState = new DtlsServerProtocol.ServerHandshakeState(); serverHandshakeState.server = server; serverHandshakeState.serverContext = new TlsServerContextImpl(this.mSecureRandom, securityParameters); securityParameters.serverRandom = TlsProtocol.CreateRandomBlock(server.ShouldUseGmtUnixTime(), serverHandshakeState.serverContext.NonceRandomGenerator); server.Init(serverHandshakeState.serverContext); DtlsRecordLayer dtlsRecordLayer = new DtlsRecordLayer(transport, serverHandshakeState.serverContext, server, 22); DtlsTransport result; try { result = this.ServerHandshake(serverHandshakeState, 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); }
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)); }
internal virtual DtlsTransport ServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer) { SecurityParameters securityParameters = state.serverContext.SecurityParameters; DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.serverContext, recordLayer); DtlsReliableHandshake.Message clientMessage = handshake.ReceiveMessage(); { // NOTE: After receiving a record from the client, we discover the record layer version ProtocolVersion client_version = recordLayer.DiscoveredPeerVersion; // TODO Read RFCs for guidance on the expected record layer version number state.serverContext.SetClientVersion(client_version); } if (clientMessage.Type == HandshakeType.client_hello) { ProcessClientHello(state, clientMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } { byte[] serverHelloBody = GenerateServerHello(state); ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength); handshake.SendMessage(HandshakeType.server_hello, serverHelloBody); } handshake.NotifyHelloComplete(); IList serverSupplementalData = state.server.GetServerSupplementalData(); if (serverSupplementalData != null) { byte[] supplementalDataBody = GenerateSupplementalData(serverSupplementalData); handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); } state.keyExchange = state.server.GetKeyExchange(); state.keyExchange.Init(state.serverContext); state.serverCredentials = state.server.GetCredentials(); Certificate serverCertificate = null; if (state.serverCredentials == null) { state.keyExchange.SkipServerCredentials(); } else { state.keyExchange.ProcessServerCredentials(state.serverCredentials); serverCertificate = state.serverCredentials.Certificate; byte[] certificateBody = GenerateCertificate(serverCertificate); handshake.SendMessage(HandshakeType.certificate, certificateBody); } // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus if (serverCertificate == null || serverCertificate.IsEmpty) { state.allowCertificateStatus = false; } if (state.allowCertificateStatus) { CertificateStatus certificateStatus = state.server.GetCertificateStatus(); if (certificateStatus != null) { byte[] certificateStatusBody = GenerateCertificateStatus(state, certificateStatus); handshake.SendMessage(HandshakeType.certificate_status, certificateStatusBody); } } byte[] serverKeyExchange = state.keyExchange.GenerateServerKeyExchange(); if (serverKeyExchange != null) { handshake.SendMessage(HandshakeType.server_key_exchange, serverKeyExchange); } if (state.serverCredentials != null) { state.certificateRequest = state.server.GetCertificateRequest(); if (state.certificateRequest != null) { state.keyExchange.ValidateCertificateRequest(state.certificateRequest); byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest); handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody); TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms); } } handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes); handshake.HandshakeHash.SealHashAlgorithms(); clientMessage = handshake.ReceiveMessage(); if (clientMessage.Type == HandshakeType.supplemental_data) { ProcessClientSupplementalData(state, clientMessage.Body); clientMessage = handshake.ReceiveMessage(); } else { state.server.ProcessClientSupplementalData(null); } if (state.certificateRequest == null) { state.keyExchange.SkipClientCredentials(); } else { if (clientMessage.Type == HandshakeType.certificate) { ProcessClientCertificate(state, clientMessage.Body); clientMessage = handshake.ReceiveMessage(); } else { if (TlsUtilities.IsTlsV12(state.serverContext)) { /* * RFC 5246 If no suitable certificate is available, the client MUST send a * certificate message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } NotifyClientCertificate(state, Certificate.EmptyChain); } } if (clientMessage.Type == HandshakeType.client_key_exchange) { ProcessClientKeyExchange(state, clientMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish(); securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.serverContext, prepareFinishHash, null); TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange); recordLayer.InitPendingEpoch(state.server.GetCipher()); /* * RFC 5246 7.4.8 This message is only sent following a client certificate that has signing * capability (i.e., all certificates except those containing fixed Diffie-Hellman * parameters). */ if (ExpectCertificateVerifyMessage(state)) { byte[] certificateVerifyBody = handshake.ReceiveMessageBody(HandshakeType.certificate_verify); ProcessCertificateVerify(state, certificateVerifyBody, prepareFinishHash); } // NOTE: Calculated exclusive of the actual Finished message from the client byte[] expectedClientVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.client_finished, TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null)); ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedClientVerifyData); if (state.expectSessionTicket) { NewSessionTicket newSessionTicket = state.server.GetNewSessionTicket(); byte[] newSessionTicketBody = GenerateNewSessionTicket(state, newSessionTicket); handshake.SendMessage(HandshakeType.session_ticket, newSessionTicketBody); } // NOTE: Calculated exclusive of the Finished message itself byte[] serverVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.server_finished, TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null)); handshake.SendMessage(HandshakeType.finished, serverVerifyData); handshake.Finish(); state.server.NotifyHandshakeComplete(); return new DtlsTransport(recordLayer); }
internal virtual DtlsTransport ServerHandshake(DtlsServerProtocol.ServerHandshakeState state, DtlsRecordLayer recordLayer) { SecurityParameters securityParameters = state.serverContext.SecurityParameters; DtlsReliableHandshake dtlsReliableHandshake = new DtlsReliableHandshake(state.serverContext, recordLayer); DtlsReliableHandshake.Message message = dtlsReliableHandshake.ReceiveMessage(); ProtocolVersion discoveredPeerVersion = recordLayer.DiscoveredPeerVersion; state.serverContext.SetClientVersion(discoveredPeerVersion); if (message.Type != 1) { throw new TlsFatalAlert(10); } this.ProcessClientHello(state, message.Body); byte[] body = this.GenerateServerHello(state); DtlsProtocol.ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength); dtlsReliableHandshake.SendMessage(2, body); dtlsReliableHandshake.NotifyHelloComplete(); IList serverSupplementalData = state.server.GetServerSupplementalData(); if (serverSupplementalData != null) { byte[] body2 = DtlsProtocol.GenerateSupplementalData(serverSupplementalData); dtlsReliableHandshake.SendMessage(23, body2); } state.keyExchange = state.server.GetKeyExchange(); state.keyExchange.Init(state.serverContext); state.serverCredentials = state.server.GetCredentials(); Certificate certificate = null; if (state.serverCredentials == null) { state.keyExchange.SkipServerCredentials(); } else { state.keyExchange.ProcessServerCredentials(state.serverCredentials); certificate = state.serverCredentials.Certificate; byte[] body3 = DtlsProtocol.GenerateCertificate(certificate); dtlsReliableHandshake.SendMessage(11, body3); } if (certificate == null || certificate.IsEmpty) { state.allowCertificateStatus = false; } if (state.allowCertificateStatus) { CertificateStatus certificateStatus = state.server.GetCertificateStatus(); if (certificateStatus != null) { byte[] body4 = this.GenerateCertificateStatus(state, certificateStatus); dtlsReliableHandshake.SendMessage(22, body4); } } byte[] array = state.keyExchange.GenerateServerKeyExchange(); if (array != null) { dtlsReliableHandshake.SendMessage(12, array); } if (state.serverCredentials != null) { state.certificateRequest = state.server.GetCertificateRequest(); if (state.certificateRequest != null) { state.keyExchange.ValidateCertificateRequest(state.certificateRequest); byte[] body5 = this.GenerateCertificateRequest(state, state.certificateRequest); dtlsReliableHandshake.SendMessage(13, body5); TlsUtilities.TrackHashAlgorithms(dtlsReliableHandshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms); } } dtlsReliableHandshake.SendMessage(14, TlsUtilities.EmptyBytes); dtlsReliableHandshake.HandshakeHash.SealHashAlgorithms(); message = dtlsReliableHandshake.ReceiveMessage(); if (message.Type == 23) { this.ProcessClientSupplementalData(state, message.Body); message = dtlsReliableHandshake.ReceiveMessage(); } else { state.server.ProcessClientSupplementalData(null); } if (state.certificateRequest == null) { state.keyExchange.SkipClientCredentials(); } else if (message.Type == 11) { this.ProcessClientCertificate(state, message.Body); message = dtlsReliableHandshake.ReceiveMessage(); } else { if (TlsUtilities.IsTlsV12(state.serverContext)) { throw new TlsFatalAlert(10); } this.NotifyClientCertificate(state, Certificate.EmptyChain); } if (message.Type == 16) { this.ProcessClientKeyExchange(state, message.Body); TlsHandshakeHash tlsHandshakeHash = dtlsReliableHandshake.PrepareToFinish(); securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.serverContext, tlsHandshakeHash, null); TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange); recordLayer.InitPendingEpoch(state.server.GetCipher()); if (this.ExpectCertificateVerifyMessage(state)) { byte[] body6 = dtlsReliableHandshake.ReceiveMessageBody(15); this.ProcessCertificateVerify(state, body6, tlsHandshakeHash); } byte[] expected_verify_data = TlsUtilities.CalculateVerifyData(state.serverContext, "client finished", TlsProtocol.GetCurrentPrfHash(state.serverContext, dtlsReliableHandshake.HandshakeHash, null)); this.ProcessFinished(dtlsReliableHandshake.ReceiveMessageBody(20), expected_verify_data); if (state.expectSessionTicket) { NewSessionTicket newSessionTicket = state.server.GetNewSessionTicket(); byte[] body7 = this.GenerateNewSessionTicket(state, newSessionTicket); dtlsReliableHandshake.SendMessage(4, body7); } byte[] body8 = TlsUtilities.CalculateVerifyData(state.serverContext, "server finished", TlsProtocol.GetCurrentPrfHash(state.serverContext, dtlsReliableHandshake.HandshakeHash, null)); dtlsReliableHandshake.SendMessage(20, body8); dtlsReliableHandshake.Finish(); state.server.NotifyHandshakeComplete(); return(new DtlsTransport(recordLayer)); } throw new TlsFatalAlert(10); }
internal virtual void AbortServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer, byte alertDescription) { recordLayer.Fail(alertDescription); InvalidateSession(state); }
internal virtual DtlsTransport ServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer) { SecurityParameters securityParameters = state.serverContext.SecurityParameters; DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.serverContext, recordLayer); DtlsReliableHandshake.Message clientMessage = handshake.ReceiveMessage(); // NOTE: DTLSRecordLayer requires any DTLS version, we don't otherwise constrain this //ProtocolVersion recordLayerVersion = recordLayer.ReadVersion; if (clientMessage.Type == HandshakeType.client_hello) { ProcessClientHello(state, clientMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } { byte[] serverHelloBody = GenerateServerHello(state); ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength); ProtocolVersion recordLayerVersion = state.serverContext.ServerVersion; recordLayer.ReadVersion = recordLayerVersion; recordLayer.SetWriteVersion(recordLayerVersion); handshake.SendMessage(HandshakeType.server_hello, serverHelloBody); } handshake.NotifyHelloComplete(); IList serverSupplementalData = state.server.GetServerSupplementalData(); if (serverSupplementalData != null) { byte[] supplementalDataBody = GenerateSupplementalData(serverSupplementalData); handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); } state.keyExchange = state.server.GetKeyExchange(); state.keyExchange.Init(state.serverContext); state.serverCredentials = state.server.GetCredentials(); Certificate serverCertificate = null; if (state.serverCredentials == null) { state.keyExchange.SkipServerCredentials(); } else { state.keyExchange.ProcessServerCredentials(state.serverCredentials); serverCertificate = state.serverCredentials.Certificate; byte[] certificateBody = GenerateCertificate(serverCertificate); handshake.SendMessage(HandshakeType.certificate, certificateBody); } // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus if (serverCertificate == null || serverCertificate.IsEmpty) { state.allowCertificateStatus = false; } if (state.allowCertificateStatus) { CertificateStatus certificateStatus = state.server.GetCertificateStatus(); if (certificateStatus != null) { byte[] certificateStatusBody = GenerateCertificateStatus(state, certificateStatus); handshake.SendMessage(HandshakeType.certificate_status, certificateStatusBody); } } byte[] serverKeyExchange = state.keyExchange.GenerateServerKeyExchange(); if (serverKeyExchange != null) { handshake.SendMessage(HandshakeType.server_key_exchange, serverKeyExchange); } if (state.serverCredentials != null) { state.certificateRequest = state.server.GetCertificateRequest(); if (state.certificateRequest != null) { if (TlsUtilities.IsTlsV12(state.serverContext) != (state.certificateRequest.SupportedSignatureAlgorithms != null)) { throw new TlsFatalAlert(AlertDescription.internal_error); } state.keyExchange.ValidateCertificateRequest(state.certificateRequest); byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest); handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody); TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms); } } handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes); handshake.HandshakeHash.SealHashAlgorithms(); clientMessage = handshake.ReceiveMessage(); if (clientMessage.Type == HandshakeType.supplemental_data) { ProcessClientSupplementalData(state, clientMessage.Body); clientMessage = handshake.ReceiveMessage(); } else { state.server.ProcessClientSupplementalData(null); } if (state.certificateRequest == null) { state.keyExchange.SkipClientCredentials(); } else { if (clientMessage.Type == HandshakeType.certificate) { ProcessClientCertificate(state, clientMessage.Body); clientMessage = handshake.ReceiveMessage(); } else { if (TlsUtilities.IsTlsV12(state.serverContext)) { /* * RFC 5246 If no suitable certificate is available, the client MUST send a * certificate message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } NotifyClientCertificate(state, Certificate.EmptyChain); } } if (clientMessage.Type == HandshakeType.client_key_exchange) { ProcessClientKeyExchange(state, clientMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish(); securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.serverContext, prepareFinishHash, null); TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange); recordLayer.InitPendingEpoch(state.server.GetCipher()); /* * RFC 5246 7.4.8 This message is only sent following a client certificate that has signing * capability (i.e., all certificates except those containing fixed Diffie-Hellman * parameters). */ if (ExpectCertificateVerifyMessage(state)) { byte[] certificateVerifyBody = handshake.ReceiveMessageBody(HandshakeType.certificate_verify); ProcessCertificateVerify(state, certificateVerifyBody, prepareFinishHash); } // NOTE: Calculated exclusive of the actual Finished message from the client byte[] expectedClientVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.client_finished, TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null)); ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedClientVerifyData); if (state.expectSessionTicket) { NewSessionTicket newSessionTicket = state.server.GetNewSessionTicket(); byte[] newSessionTicketBody = GenerateNewSessionTicket(state, newSessionTicket); handshake.SendMessage(HandshakeType.session_ticket, newSessionTicketBody); } // NOTE: Calculated exclusive of the Finished message itself byte[] serverVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.server_finished, TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null)); handshake.SendMessage(HandshakeType.finished, serverVerifyData); handshake.Finish(); state.server.NotifyHandshakeComplete(); return(new DtlsTransport(recordLayer)); }
internal DtlsReliableHandshake(TlsContext context, DtlsRecordLayer transport) { this.mRecordLayer = transport; this.mHandshakeHash = new DeferredHash(); this.mHandshakeHash.Init(context); }
internal void SendToRecordLayer(DtlsRecordLayer recordLayer) { recordLayer.Send(GetBuffer(), 0, (int)Length); this.Close(); }
public virtual int Receive(byte[] buf, int off, int len, int waitMillis) { byte[] array = null; int result; while (true) { int num = Math.Min(len, this.GetReceiveLimit()) + 13; if (array == null || array.Length < num) { array = new byte[num]; } try { if (this.mRetransmit != null && DateTimeUtilities.CurrentUnixMs() > this.mRetransmitExpiry) { this.mRetransmit = null; this.mRetransmitEpoch = null; } int num2 = this.ReceiveRecord(array, 0, num, waitMillis); if (num2 < 0) { result = num2; } else { if (num2 < 13) { continue; } int num3 = TlsUtilities.ReadUint16(array, 11); if (num2 != num3 + 13) { continue; } byte b = TlsUtilities.ReadUint8(array, 0); switch (b) { case 20: case 21: case 22: case 23: case 24: { int num4 = TlsUtilities.ReadUint16(array, 3); DtlsEpoch dtlsEpoch = null; if (num4 == this.mReadEpoch.Epoch) { dtlsEpoch = this.mReadEpoch; } else if (b == 22 && this.mRetransmitEpoch != null && num4 == this.mRetransmitEpoch.Epoch) { dtlsEpoch = this.mRetransmitEpoch; } if (dtlsEpoch == null) { continue; } long num5 = TlsUtilities.ReadUint48(array, 5); if (dtlsEpoch.ReplayWindow.ShouldDiscard(num5)) { continue; } ProtocolVersion other = TlsUtilities.ReadVersion(array, 1); if (this.mDiscoveredPeerVersion != null && !this.mDiscoveredPeerVersion.Equals(other)) { continue; } byte[] array2 = dtlsEpoch.Cipher.DecodeCiphertext(DtlsRecordLayer.GetMacSequenceNumber(dtlsEpoch.Epoch, num5), b, array, 13, num2 - 13); dtlsEpoch.ReplayWindow.ReportAuthenticated(num5); if (array2.Length > this.mPlaintextLimit) { continue; } if (this.mDiscoveredPeerVersion == null) { this.mDiscoveredPeerVersion = other; } switch (b) { case 20: for (int i = 0; i < array2.Length; i++) { byte b2 = TlsUtilities.ReadUint8(array2, i); if (b2 == 1 && this.mPendingEpoch != null) { this.mReadEpoch = this.mPendingEpoch; } } continue; case 21: if (array2.Length == 2) { byte b3 = array2[0]; byte b4 = array2[1]; this.mPeer.NotifyAlertReceived(b3, b4); if (b3 == 2) { this.Fail(b4); throw new TlsFatalAlert(b4); } if (b4 == 0) { this.CloseTransport(); } } continue; case 22: if (!this.mInHandshake) { if (this.mRetransmit != null) { this.mRetransmit.ReceivedHandshakeRecord(num4, array2, 0, array2.Length); } continue; } break; case 23: if (this.mInHandshake) { continue; } break; case 24: continue; } if (!this.mInHandshake && this.mRetransmit != null) { this.mRetransmit = null; this.mRetransmitEpoch = null; } Array.Copy(array2, 0, buf, off, array2.Length); result = array2.Length; break; } default: continue; } } } catch (IOException ex) { throw ex; } break; } return(result); }
internal DtlsTransport(DtlsRecordLayer recordLayer) { mRecordLayer = recordLayer; }
internal virtual DtlsTransport ClientHandshake(ClientHandshakeState state, DtlsRecordLayer recordLayer) { SecurityParameters securityParameters = state.clientContext.SecurityParameters; DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.clientContext, recordLayer); byte[] clientHelloBody = GenerateClientHello(state, state.client); handshake.SendMessage(HandshakeType.client_hello, clientHelloBody); DtlsReliableHandshake.Message serverMessage = handshake.ReceiveMessage(); while (serverMessage.Type == HandshakeType.hello_verify_request) { ProtocolVersion recordLayerVersion = recordLayer.ResetDiscoveredPeerVersion(); ProtocolVersion client_version = state.clientContext.ClientVersion; /* * RFC 6347 4.2.1 DTLS 1.2 server implementations SHOULD use DTLS version 1.0 regardless of * the version of TLS that is expected to be negotiated. DTLS 1.2 and 1.0 clients MUST use * the version solely to indicate packet formatting (which is the same in both DTLS 1.2 and * 1.0) and not as part of version negotiation. */ if (!recordLayerVersion.IsEqualOrEarlierVersionOf(client_version)) throw new TlsFatalAlert(AlertDescription.illegal_parameter); byte[] cookie = ProcessHelloVerifyRequest(state, serverMessage.Body); byte[] patched = PatchClientHelloWithCookie(clientHelloBody, cookie); handshake.ResetHandshakeMessagesDigest(); handshake.SendMessage(HandshakeType.client_hello, patched); serverMessage = handshake.ReceiveMessage(); } if (serverMessage.Type == HandshakeType.server_hello) { ReportServerVersion(state, recordLayer.DiscoveredPeerVersion); ProcessServerHello(state, serverMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } handshake.NotifyHelloComplete(); ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength); if (state.resumedSession) { securityParameters.masterSecret = Arrays.Clone(state.sessionParameters.MasterSecret); recordLayer.InitPendingEpoch(state.client.GetCipher()); // NOTE: Calculated exclusive of the actual Finished message from the server byte[] resExpectedServerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.server_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), resExpectedServerVerifyData); // NOTE: Calculated exclusive of the Finished message itself byte[] resClientVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.client_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); handshake.SendMessage(HandshakeType.finished, resClientVerifyData); handshake.Finish(); state.clientContext.SetResumableSession(state.tlsSession); state.client.NotifyHandshakeComplete(); return new DtlsTransport(recordLayer); } InvalidateSession(state); if (state.selectedSessionID.Length > 0) { state.tlsSession = new TlsSessionImpl(state.selectedSessionID, null); } serverMessage = handshake.ReceiveMessage(); if (serverMessage.Type == HandshakeType.supplemental_data) { ProcessServerSupplementalData(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { state.client.ProcessServerSupplementalData(null); } state.keyExchange = state.client.GetKeyExchange(); state.keyExchange.Init(state.clientContext); Certificate serverCertificate = null; if (serverMessage.Type == HandshakeType.certificate) { serverCertificate = ProcessServerCertificate(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { // Okay, Certificate is optional state.keyExchange.SkipServerCredentials(); } // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus if (serverCertificate == null || serverCertificate.IsEmpty) { state.allowCertificateStatus = false; } if (serverMessage.Type == HandshakeType.certificate_status) { ProcessCertificateStatus(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { // Okay, CertificateStatus is optional } if (serverMessage.Type == HandshakeType.server_key_exchange) { ProcessServerKeyExchange(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { // Okay, ServerKeyExchange is optional state.keyExchange.SkipServerKeyExchange(); } if (serverMessage.Type == HandshakeType.certificate_request) { ProcessCertificateRequest(state, serverMessage.Body); /* * TODO Give the client a chance to immediately select the CertificateVerify hash * algorithm here to avoid tracking the other hash algorithms unnecessarily? */ TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms); serverMessage = handshake.ReceiveMessage(); } else { // Okay, CertificateRequest is optional } if (serverMessage.Type == HandshakeType.server_hello_done) { if (serverMessage.Body.Length != 0) { throw new TlsFatalAlert(AlertDescription.decode_error); } } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } handshake.HandshakeHash.SealHashAlgorithms(); IList clientSupplementalData = state.client.GetClientSupplementalData(); if (clientSupplementalData != null) { byte[] supplementalDataBody = GenerateSupplementalData(clientSupplementalData); handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); } if (state.certificateRequest != null) { state.clientCredentials = state.authentication.GetClientCredentials(state.certificateRequest); /* * RFC 5246 If no suitable certificate is available, the client MUST send a certificate * message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ Certificate clientCertificate = null; if (state.clientCredentials != null) { clientCertificate = state.clientCredentials.Certificate; } if (clientCertificate == null) { clientCertificate = Certificate.EmptyChain; } byte[] certificateBody = GenerateCertificate(clientCertificate); handshake.SendMessage(HandshakeType.certificate, certificateBody); } if (state.clientCredentials != null) { state.keyExchange.ProcessClientCredentials(state.clientCredentials); } else { state.keyExchange.SkipClientCredentials(); } byte[] clientKeyExchangeBody = GenerateClientKeyExchange(state); handshake.SendMessage(HandshakeType.client_key_exchange, clientKeyExchangeBody); TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish(); securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.clientContext, prepareFinishHash, null); TlsProtocol.EstablishMasterSecret(state.clientContext, state.keyExchange); recordLayer.InitPendingEpoch(state.client.GetCipher()); if (state.clientCredentials != null && state.clientCredentials is TlsSignerCredentials) { TlsSignerCredentials signerCredentials = (TlsSignerCredentials)state.clientCredentials; /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( state.clientContext, signerCredentials); byte[] hash; if (signatureAndHashAlgorithm == null) { hash = securityParameters.SessionHash; } else { hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash); } byte[] signature = signerCredentials.GenerateCertificateSignature(hash); DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); byte[] certificateVerifyBody = GenerateCertificateVerify(state, certificateVerify); handshake.SendMessage(HandshakeType.certificate_verify, certificateVerifyBody); } // NOTE: Calculated exclusive of the Finished message itself byte[] clientVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.client_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); handshake.SendMessage(HandshakeType.finished, clientVerifyData); if (state.expectSessionTicket) { serverMessage = handshake.ReceiveMessage(); if (serverMessage.Type == HandshakeType.session_ticket) { ProcessNewSessionTicket(state, serverMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } // NOTE: Calculated exclusive of the actual Finished message from the server byte[] expectedServerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.server_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedServerVerifyData); handshake.Finish(); if (state.tlsSession != null) { state.sessionParameters = new SessionParameters.Builder() .SetCipherSuite(securityParameters.CipherSuite) .SetCompressionAlgorithm(securityParameters.CompressionAlgorithm) .SetMasterSecret(securityParameters.MasterSecret) .SetPeerCertificate(serverCertificate) .SetPskIdentity(securityParameters.PskIdentity) .SetSrpIdentity(securityParameters.SrpIdentity) // TODO Consider filtering extensions that aren't relevant to resumed sessions .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); }
internal void SendToRecordLayer(DtlsRecordLayer recordLayer) { recordLayer.Send(this.GetBuffer(), 0, (int)this.Length); this.Close(); }
internal virtual DtlsTransport ClientHandshake(ClientHandshakeState state, DtlsRecordLayer recordLayer) { SecurityParameters securityParameters = state.clientContext.SecurityParameters; DtlsReliableHandshake handshake = new DtlsReliableHandshake(state.clientContext, recordLayer); byte[] clientHelloBody = GenerateClientHello(state, state.client); handshake.SendMessage(HandshakeType.client_hello, clientHelloBody); DtlsReliableHandshake.Message serverMessage = handshake.ReceiveMessage(); while (serverMessage.Type == HandshakeType.hello_verify_request) { ProtocolVersion recordLayerVersion = recordLayer.ResetDiscoveredPeerVersion(); ProtocolVersion client_version = state.clientContext.ClientVersion; /* * RFC 6347 4.2.1 DTLS 1.2 server implementations SHOULD use DTLS version 1.0 regardless of * the version of TLS that is expected to be negotiated. DTLS 1.2 and 1.0 clients MUST use * the version solely to indicate packet formatting (which is the same in both DTLS 1.2 and * 1.0) and not as part of version negotiation. */ if (!recordLayerVersion.IsEqualOrEarlierVersionOf(client_version)) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } byte[] cookie = ProcessHelloVerifyRequest(state, serverMessage.Body); byte[] patched = PatchClientHelloWithCookie(clientHelloBody, cookie); handshake.ResetHandshakeMessagesDigest(); handshake.SendMessage(HandshakeType.client_hello, patched); serverMessage = handshake.ReceiveMessage(); } if (serverMessage.Type == HandshakeType.server_hello) { ReportServerVersion(state, recordLayer.DiscoveredPeerVersion); ProcessServerHello(state, serverMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } if (state.maxFragmentLength >= 0) { int plainTextLimit = 1 << (8 + state.maxFragmentLength); recordLayer.SetPlaintextLimit(plainTextLimit); } securityParameters.cipherSuite = state.selectedCipherSuite; securityParameters.compressionAlgorithm = (byte)state.selectedCompressionMethod; securityParameters.prfAlgorithm = TlsProtocol.GetPrfAlgorithm(state.clientContext, state.selectedCipherSuite); /* * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify verify_data_length has * a verify_data_length equal to 12. This includes all existing cipher suites. */ securityParameters.verifyDataLength = 12; handshake.NotifyHelloComplete(); bool resumedSession = state.selectedSessionID.Length > 0 && state.tlsSession != null && Arrays.AreEqual(state.selectedSessionID, state.tlsSession.SessionID); if (resumedSession) { if (securityParameters.CipherSuite != state.sessionParameters.CipherSuite || securityParameters.CompressionAlgorithm != state.sessionParameters.CompressionAlgorithm) { throw new TlsFatalAlert(AlertDescription.illegal_parameter); } IDictionary sessionServerExtensions = state.sessionParameters.ReadServerExtensions(); securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(sessionServerExtensions); securityParameters.masterSecret = Arrays.Clone(state.sessionParameters.MasterSecret); recordLayer.InitPendingEpoch(state.client.GetCipher()); // NOTE: Calculated exclusive of the actual Finished message from the server byte[] resExpectedServerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.server_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), resExpectedServerVerifyData); // NOTE: Calculated exclusive of the Finished message itself byte[] resClientVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.client_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); handshake.SendMessage(HandshakeType.finished, resClientVerifyData); handshake.Finish(); state.clientContext.SetResumableSession(state.tlsSession); state.client.NotifyHandshakeComplete(); return(new DtlsTransport(recordLayer)); } InvalidateSession(state); if (state.selectedSessionID.Length > 0) { state.tlsSession = new TlsSessionImpl(state.selectedSessionID, null); } serverMessage = handshake.ReceiveMessage(); if (serverMessage.Type == HandshakeType.supplemental_data) { ProcessServerSupplementalData(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { state.client.ProcessServerSupplementalData(null); } state.keyExchange = state.client.GetKeyExchange(); state.keyExchange.Init(state.clientContext); Certificate serverCertificate = null; if (serverMessage.Type == HandshakeType.certificate) { serverCertificate = ProcessServerCertificate(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { // Okay, Certificate is optional state.keyExchange.SkipServerCredentials(); } // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus if (serverCertificate == null || serverCertificate.IsEmpty) { state.allowCertificateStatus = false; } if (serverMessage.Type == HandshakeType.certificate_status) { ProcessCertificateStatus(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { // Okay, CertificateStatus is optional } if (serverMessage.Type == HandshakeType.server_key_exchange) { ProcessServerKeyExchange(state, serverMessage.Body); serverMessage = handshake.ReceiveMessage(); } else { // Okay, ServerKeyExchange is optional state.keyExchange.SkipServerKeyExchange(); } if (serverMessage.Type == HandshakeType.certificate_request) { ProcessCertificateRequest(state, serverMessage.Body); /* * TODO Give the client a chance to immediately select the CertificateVerify hash * algorithm here to avoid tracking the other hash algorithms unnecessarily? */ TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms); serverMessage = handshake.ReceiveMessage(); } else { // Okay, CertificateRequest is optional } if (serverMessage.Type == HandshakeType.server_hello_done) { if (serverMessage.Body.Length != 0) { throw new TlsFatalAlert(AlertDescription.decode_error); } } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } handshake.HandshakeHash.SealHashAlgorithms(); IList clientSupplementalData = state.client.GetClientSupplementalData(); if (clientSupplementalData != null) { byte[] supplementalDataBody = GenerateSupplementalData(clientSupplementalData); handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody); } if (state.certificateRequest != null) { state.clientCredentials = state.authentication.GetClientCredentials(state.certificateRequest); /* * RFC 5246 If no suitable certificate is available, the client MUST send a certificate * message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ Certificate clientCertificate = null; if (state.clientCredentials != null) { clientCertificate = state.clientCredentials.Certificate; } if (clientCertificate == null) { clientCertificate = Certificate.EmptyChain; } byte[] certificateBody = GenerateCertificate(clientCertificate); handshake.SendMessage(HandshakeType.certificate, certificateBody); } if (state.clientCredentials != null) { state.keyExchange.ProcessClientCredentials(state.clientCredentials); } else { state.keyExchange.SkipClientCredentials(); } byte[] clientKeyExchangeBody = GenerateClientKeyExchange(state); handshake.SendMessage(HandshakeType.client_key_exchange, clientKeyExchangeBody); TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish(); securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.clientContext, prepareFinishHash, null); TlsProtocol.EstablishMasterSecret(state.clientContext, state.keyExchange); recordLayer.InitPendingEpoch(state.client.GetCipher()); if (state.clientCredentials != null && state.clientCredentials is TlsSignerCredentials) { TlsSignerCredentials signerCredentials = (TlsSignerCredentials)state.clientCredentials; /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm; byte[] hash; if (TlsUtilities.IsTlsV12(state.clientContext)) { signatureAndHashAlgorithm = signerCredentials.SignatureAndHashAlgorithm; if (signatureAndHashAlgorithm == null) { throw new TlsFatalAlert(AlertDescription.internal_error); } hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash); } else { signatureAndHashAlgorithm = null; hash = securityParameters.SessionHash; } byte[] signature = signerCredentials.GenerateCertificateSignature(hash); DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); byte[] certificateVerifyBody = GenerateCertificateVerify(state, certificateVerify); handshake.SendMessage(HandshakeType.certificate_verify, certificateVerifyBody); } // NOTE: Calculated exclusive of the Finished message itself byte[] clientVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.client_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); handshake.SendMessage(HandshakeType.finished, clientVerifyData); if (state.expectSessionTicket) { serverMessage = handshake.ReceiveMessage(); if (serverMessage.Type == HandshakeType.session_ticket) { ProcessNewSessionTicket(state, serverMessage.Body); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } // NOTE: Calculated exclusive of the actual Finished message from the server byte[] expectedServerVerifyData = TlsUtilities.CalculateVerifyData(state.clientContext, ExporterLabel.server_finished, TlsProtocol.GetCurrentPrfHash(state.clientContext, handshake.HandshakeHash, null)); ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedServerVerifyData); handshake.Finish(); if (state.tlsSession != null) { state.sessionParameters = new SessionParameters.Builder() .SetCipherSuite(securityParameters.cipherSuite) .SetCompressionAlgorithm(securityParameters.compressionAlgorithm) .SetMasterSecret(securityParameters.masterSecret) .SetPeerCertificate(serverCertificate) .SetPskIdentity(securityParameters.pskIdentity) .Build(); state.tlsSession = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters); state.clientContext.SetResumableSession(state.tlsSession); } state.client.NotifyHandshakeComplete(); return(new DtlsTransport(recordLayer)); }
internal DtlsTransport(DtlsRecordLayer recordLayer) { this.mRecordLayer = recordLayer; }