protected virtual void SendCertificateMessage(Certificate certificate) { if (certificate == null) { certificate = Certificate.EmptyChain; } if (certificate.IsEmpty) { TlsContext context = Context; if (!context.IsServer) { ProtocolVersion serverVersion = Context.ServerVersion; if (serverVersion.IsSsl) { string errorMessage = serverVersion.ToString() + " client didn't provide credentials"; RaiseWarning(AlertDescription.no_certificate, errorMessage); return; } } } HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate); certificate.Encode(message); message.WriteToRecordStream(this); }
public override void ProcessServerCertificate(Certificate serverCertificate) { if (mTlsSigner == null) throw new TlsFatalAlert(AlertDescription.unexpected_message); if (serverCertificate.IsEmpty) throw new TlsFatalAlert(AlertDescription.bad_certificate); X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; try { this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo); } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); } if (!mTlsSigner.IsValidPublicKey(this.mServerPublicKey)) throw new TlsFatalAlert(AlertDescription.certificate_unknown); TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); base.ProcessServerCertificate(serverCertificate); }
public void ProcessServerCertificate(Certificate serverCertificate) { if (tlsSigner == null) { handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_unexpected_message); } X509CertificateStructure x509Cert = serverCertificate.certs[0]; SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; try { this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo); } // catch (RuntimeException) catch (Exception) { handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_unsupported_certificate); } // Sanity check the PublicKeyFactory if (this.serverPublicKey.IsPrivate) { handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_internal_error); } // TODO /* * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the * signing algorithm for the certificate must be the same as the algorithm for the * certificate key." */ switch (this.keyExchange) { case TlsKeyExchangeAlgorithm.KE_SRP_RSA: if (!(this.serverPublicKey is RsaKeyParameters)) { handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_certificate_unknown); } ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); break; case TlsKeyExchangeAlgorithm.KE_SRP_DSS: if (!(this.serverPublicKey is DsaPublicKeyParameters)) { handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_certificate_unknown); } break; default: handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_unsupported_certificate); break; } /* * Verify them. */ if (!this.verifyer.IsValid(serverCertificate.GetCerts())) { handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_user_canceled); } }
private Connection GetConnectionHttpsPrivate(Uri uri, Uri proxy, AsymmetricKeyParameter asymmetricKeyParameter, Certificate clientCertificates, Action<Certificate> serverCertificateValidator) { Connection conn = new HttpsConnection(this, uri, proxy, clientCertificates, asymmetricKeyParameter, serverCertificateValidator); return InitiateConnection(conn); }
public DefaultTlsAgreementCredentials(Certificate certificate, AsymmetricKeyParameter privateKey) { if (certificate == null) throw new ArgumentNullException("certificate"); if (certificate.IsEmpty) throw new ArgumentException("cannot be empty", "certificate"); if (privateKey == null) throw new ArgumentNullException("privateKey"); if (!privateKey.IsPrivate) throw new ArgumentException("must be private", "privateKey"); if (privateKey is DHPrivateKeyParameters) { mBasicAgreement = new DHBasicAgreement(); mTruncateAgreement = true; } else if (privateKey is ECPrivateKeyParameters) { mBasicAgreement = new ECDHBasicAgreement(); mTruncateAgreement = false; } else { throw new ArgumentException("type not supported: " + privateKey.GetType().FullName, "privateKey"); } this.mCertificate = certificate; this.mPrivateKey = privateKey; }
public override void ProcessServerCertificate(Certificate serverCertificate) { if (serverCertificate.IsEmpty) throw new TlsFatalAlert(AlertDescription.bad_certificate); X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; try { this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo); } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); } // Sanity check the PublicKeyFactory if (this.mServerPublicKey.IsPrivate) throw new TlsFatalAlert(AlertDescription.internal_error); this.mRsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.mServerPublicKey); TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment); base.ProcessServerCertificate(serverCertificate); }
public virtual void ProcessServerCertificate(Certificate serverCertificate) { X509CertificateStructure x509Cert = serverCertificate.certs[0]; SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; try { this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo); } // catch (RuntimeException) catch (Exception) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } // Sanity check the PublicKeyFactory if (this.serverPublicKey.IsPrivate) { throw new TlsFatalAlert(AlertDescription.internal_error); } this.rsaServerPublicKey = ValidateRsaPublicKey((RsaKeyParameters)this.serverPublicKey); TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyEncipherment); // TODO /* * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the * signing algorithm for the certificate must be the same as the algorithm for the * certificate key." */ }
public virtual void ProcessServerCertificate(Certificate serverCertificate) { if (tlsSigner == null) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } X509CertificateStructure x509Cert = serverCertificate.certs[0]; SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; try { this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo); } // catch (RuntimeException) catch (Exception) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } if (!tlsSigner.IsValidPublicKey(this.serverPublicKey)) { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); // TODO /* * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the * signing algorithm for the certificate must be the same as the algorithm for the * certificate key." */ }
public static (Org.BouncyCastle.Crypto.Tls.Certificate crtificate, AsymmetricKeyParameter privateKey) CreateSelfSignedTlsCert(string subjectName, string issuerName, AsymmetricKeyParameter issuerPrivateKey) { const int keyStrength = DEFAULT_KEY_SIZE; if (issuerPrivateKey == null) { issuerPrivateKey = CreatePrivateKeyResource(issuerName); } // Generating Random Numbers var randomGenerator = new CryptoApiRandomGenerator(); var random = new SecureRandom(randomGenerator); ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", issuerPrivateKey, random); // The Certificate Generator var certificateGenerator = new X509V3CertificateGenerator(); certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(new GeneralName[] { new GeneralName(GeneralName.DnsName, "localhost"), new GeneralName(GeneralName.DnsName, "127.0.0.1") })); certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(new List <DerObjectIdentifier>() { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1") })); // Serial Number var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); certificateGenerator.SetSerialNumber(serialNumber); // Issuer and Subject Name var subjectDn = new X509Name(subjectName); var issuerDn = new X509Name(issuerName); certificateGenerator.SetIssuerDN(issuerDn); certificateGenerator.SetSubjectDN(subjectDn); // Valid For var notBefore = DateTime.UtcNow.Date; var notAfter = notBefore.AddYears(70); certificateGenerator.SetNotBefore(notBefore); certificateGenerator.SetNotAfter(notAfter); // Subject Public Key var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); var subjectKeyPair = keyPairGenerator.GenerateKeyPair(); certificateGenerator.SetPublicKey(subjectKeyPair.Public); // self sign certificate var certificate = certificateGenerator.Generate(signatureFactory); var chain = new Org.BouncyCastle.Asn1.X509.X509CertificateStructure[] { X509CertificateStructure.GetInstance(certificate.GetEncoded()) }; var tlsCertificate = new Org.BouncyCastle.Crypto.Tls.Certificate(chain); return(tlsCertificate, subjectKeyPair.Private); }
private SessionParameters(int cipherSuite, byte compressionAlgorithm, byte[] masterSecret, Certificate peerCertificate, byte[] encodedServerExtensions) { this.mCipherSuite = cipherSuite; this.mCompressionAlgorithm = compressionAlgorithm; this.mMasterSecret = Arrays.Clone(masterSecret); this.mPeerCertificate = peerCertificate; this.mEncodedServerExtensions = encodedServerExtensions; }
internal CustomTlsClient( Certificate clientCertificates, AsymmetricKeyParameter asymmetricKeyParameter, Action<Certificate> serverCertificateValidator) { _clientCertificates = clientCertificates; _asymmetricKeyParameter = asymmetricKeyParameter; _serverCertificateValidator = serverCertificateValidator; }
public void NotifyServerCertificate(Certificate certificate) { bool valid = true; foreach(ValidateCertificate del in SslStream.CertificateIsValid.GetInvocationList()) valid &= del(certificate); if(!valid) throw new InvalidCertificateException(); }
public HttpClient( Certificate clientCertificates, AsymmetricKeyParameter asymmetricKeyParameter, Action<Certificate> serverCertificateValidator) : this() { _clientCertificates = clientCertificates; _asymmetricKeyParameter = asymmetricKeyParameter; _serverCertificateValidator = serverCertificateValidator; }
public virtual void ProcessServerCertificate(Certificate serverCertificate) { X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; try { this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo); } catch (Exception) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } if (tlsSigner == null) { try { this.dhAgreeServerPublicKey = ValidateDHPublicKey((DHPublicKeyParameters)this.serverPublicKey); } catch (InvalidCastException) { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyAgreement); } else { if (!tlsSigner.IsValidPublicKey(this.serverPublicKey)) { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); } // TODO /* * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the * signing algorithm for the certificate must be the same as the algorithm for the * certificate key." */ }
public override void ProcessServerCertificate(Certificate serverCertificate) { if (serverCertificate.IsEmpty) throw new TlsFatalAlert(AlertDescription.bad_certificate); X509CertificateStructure x509Cert = serverCertificate.GetCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; try { this.mServerPublicKey = PublicKeyFactory.CreateKey(keyInfo); } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); } if (mTlsSigner == null) { try { this.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey((DHPublicKeyParameters)this.mServerPublicKey); this.mDHParameters = ValidateDHParameters(mDHAgreePublicKey.Parameters); } catch (InvalidCastException e) { throw new TlsFatalAlert(AlertDescription.certificate_unknown, e); } TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.KeyAgreement); } else { if (!mTlsSigner.IsValidPublicKey(this.mServerPublicKey)) { throw new TlsFatalAlert(AlertDescription.certificate_unknown); } TlsUtilities.ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); } base.ProcessServerCertificate(serverCertificate); }
public DefaultTlsSignerCredentials(TlsClientContext context, Certificate clientCertificate, AsymmetricKeyParameter clientPrivateKey) { if (clientCertificate == null) { throw new ArgumentNullException("clientCertificate"); } if (clientCertificate.Length == 0) { throw new ArgumentException("cannot be empty", "clientCertificate"); } if (clientPrivateKey == null) { throw new ArgumentNullException("clientPrivateKey"); } if (!clientPrivateKey.IsPrivate) { throw new ArgumentException("must be private", "clientPrivateKey"); } if (clientPrivateKey is RsaKeyParameters) { clientSigner = new TlsRsaSigner(); } else if (clientPrivateKey is DsaPrivateKeyParameters) { clientSigner = new TlsDssSigner(); } else if (clientPrivateKey is ECPrivateKeyParameters) { clientSigner = new TlsECDsaSigner(); } else { throw new ArgumentException("type not supported: " + clientPrivateKey.GetType().FullName, "clientPrivateKey"); } this.context = context; this.clientCert = clientCertificate; this.clientPrivateKey = clientPrivateKey; }
public DefaultTlsAgreementCredentials(Certificate clientCertificate, AsymmetricKeyParameter clientPrivateKey) { if (clientCertificate == null) { throw new ArgumentNullException("clientCertificate"); } if (clientCertificate.Length == 0) { throw new ArgumentException("cannot be empty", "clientCertificate"); } if (clientPrivateKey == null) { throw new ArgumentNullException("clientPrivateKey"); } if (!clientPrivateKey.IsPrivate) { throw new ArgumentException("must be private", "clientPrivateKey"); } if (clientPrivateKey is DHPrivateKeyParameters) { basicAgreement = new DHBasicAgreement(); truncateAgreement = true; } else if (clientPrivateKey is ECPrivateKeyParameters) { basicAgreement = new ECDHBasicAgreement(); truncateAgreement = false; } else { throw new ArgumentException("type not supported: " + clientPrivateKey.GetType().FullName, "clientPrivateKey"); } this.clientCert = clientCertificate; this.clientPrivateKey = clientPrivateKey; }
public DefaultTlsSignerCredentials(TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey, SignatureAndHashAlgorithm signatureAndHashAlgorithm) { if (certificate == null) throw new ArgumentNullException("certificate"); if (certificate.IsEmpty) throw new ArgumentException("cannot be empty", "clientCertificate"); if (privateKey == null) throw new ArgumentNullException("privateKey"); if (!privateKey.IsPrivate) throw new ArgumentException("must be private", "privateKey"); if (TlsUtilities.IsTlsV12(context) && signatureAndHashAlgorithm == null) throw new ArgumentException("cannot be null for (D)TLS 1.2+", "signatureAndHashAlgorithm"); if (privateKey is RsaKeyParameters) { mSigner = new TlsRsaSigner(); } else if (privateKey is DsaPrivateKeyParameters) { mSigner = new TlsDssSigner(); } else if (privateKey is ECPrivateKeyParameters) { mSigner = new TlsECDsaSigner(); } else { throw new ArgumentException("type not supported: " + privateKey.GetType().FullName, "privateKey"); } this.mSigner.Init(context); this.mContext = context; this.mCertificate = certificate; this.mPrivateKey = privateKey; this.mSignatureAndHashAlgorithm = signatureAndHashAlgorithm; }
internal void EnableClientAuthentication(Certificate clientCertificate, AsymmetricKeyParameter clientPrivateKey) { if (clientCertificate == null) { throw new ArgumentNullException("clientCertificate"); } if (clientCertificate.certs.Length == 0) { throw new ArgumentException("cannot be empty", "clientCertificate"); } if (clientPrivateKey == null) { throw new ArgumentNullException("clientPrivateKey"); } if (!clientPrivateKey.IsPrivate) { throw new ArgumentException("must be private", "clientPrivateKey"); } if (clientPrivateKey is RsaKeyParameters) { clientSigner = new TlsRsaSigner(); } else if (clientPrivateKey is DsaPrivateKeyParameters) { clientSigner = new TlsDssSigner(); } else { throw new ArgumentException("type not supported: " + clientPrivateKey.GetType().FullName, "clientPrivateKey"); } this.clientCert = clientCertificate; this.clientPrivateKey = clientPrivateKey; }
public DefaultTlsEncryptionCredentials(TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey) { if (certificate == null) throw new ArgumentNullException("certificate"); if (certificate.IsEmpty) throw new ArgumentException("cannot be empty", "certificate"); if (privateKey == null) throw new ArgumentNullException("'privateKey' cannot be null"); if (!privateKey.IsPrivate) throw new ArgumentException("must be private", "privateKey"); if (privateKey is RsaKeyParameters) { } else { throw new ArgumentException("type not supported: " + Platform.GetTypeName(privateKey), "privateKey"); } this.mContext = context; this.mCertificate = certificate; this.mPrivateKey = privateKey; }
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.sessionParameters = new SessionParameters.Builder() // .SetCipherSuite(securityParameters.CipherSuite) // .SetCompressionAlgorithm(securityParameters.CompressionAlgorithm) // .SetExtendedMasterSecret(securityParameters.IsExtendedMasterSecret) // .SetMasterSecret(securityParameters.MasterSecret) // .SetPeerCertificate(state.clientCertificate) // .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.serverContext.SetResumableSession(state.tlsSession); //} state.server.NotifyHandshakeComplete(); return(new DtlsTransport(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); } 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) .Build(); state.tlsSession = TlsUtilities.ImportSession(state.tlsSession.SessionID, state.sessionParameters); state.clientContext.SetResumableSession(state.tlsSession); } state.client.NotifyHandshakeComplete(); return(new DtlsTransport(recordLayer)); }
public virtual void NotifyServerCertificate(Certificate serverCertificate) { if (!this.verifyer.IsValid(this.TargetUri, serverCertificate.GetCertificateList())) throw new TlsFatalAlert(AlertDescription.user_canceled); }
public static List <X509Certificate2> ToCertificateList(this Org.BouncyCastle.Crypto.Tls.Certificate certificate) { return(certificate.GetCertificateList().Select(_ => new X509Certificate2(_.GetDerEncoded())).ToList()); }
protected virtual void CleanupHandshake() { if (this.mExpectedVerifyData != null) { Arrays.Fill(this.mExpectedVerifyData, (byte)0); this.mExpectedVerifyData = null; } this.mSecurityParameters.Clear(); this.mPeerCertificate = null; this.mOfferedCipherSuites = null; this.mOfferedCompressionMethods = null; this.mClientExtensions = null; this.mServerExtensions = null; this.mResumedSession = false; this.mReceivedChangeCipherSpec = false; this.mSecureRenegotiation = false; this.mAllowCertificateStatus = false; this.mExpectSessionTicket = false; }
internal static short GetClientCertificateType(Certificate clientCertificate, Certificate serverCertificate) { if (clientCertificate.IsEmpty) return -1; X509CertificateStructure x509Cert = clientCertificate.GetCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; try { AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo); if (publicKey.IsPrivate) throw new TlsFatalAlert(AlertDescription.internal_error); /* * TODO RFC 5246 7.4.6. The certificates MUST be signed using an acceptable hash/ * signature algorithm pair, as described in Section 7.4.4. Note that this relaxes the * constraints on certificate-signing algorithms found in prior versions of TLS. */ /* * RFC 5246 7.4.6. Client Certificate */ /* * RSA public key; the certificate MUST allow the key to be used for signing with the * signature scheme and hash algorithm that will be employed in the certificate verify * message. */ if (publicKey is RsaKeyParameters) { ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); return ClientCertificateType.rsa_sign; } /* * DSA public key; the certificate MUST allow the key to be used for signing with the * hash algorithm that will be employed in the certificate verify message. */ if (publicKey is DsaPublicKeyParameters) { ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); return ClientCertificateType.dss_sign; } /* * ECDSA-capable public key; the certificate MUST allow the key to be used for signing * with the hash algorithm that will be employed in the certificate verify message; the * public key MUST use a curve and point format supported by the server. */ if (publicKey is ECPublicKeyParameters) { ValidateKeyUsage(x509Cert, KeyUsage.DigitalSignature); // TODO Check the curve and point format return ClientCertificateType.ecdsa_sign; } // TODO Add support for ClientCertificateType.*_fixed_* throw new TlsFatalAlert(AlertDescription.unsupported_certificate); } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e); } }
protected override void HandleHandshakeMessage(byte type, byte[] data) { MemoryStream buf = new MemoryStream(data, false); if (this.mResumedSession) { if (type != HandshakeType.finished || this.mConnectionState != CS_SERVER_HELLO) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } ProcessFinishedMessage(buf); this.mConnectionState = CS_SERVER_FINISHED; SendFinishedMessage(); this.mConnectionState = CS_CLIENT_FINISHED; this.mConnectionState = CS_END; return; } switch (type) { case HandshakeType.certificate: { switch (this.mConnectionState) { case CS_SERVER_HELLO: case CS_SERVER_SUPPLEMENTAL_DATA: { if (this.mConnectionState == CS_SERVER_HELLO) { HandleSupplementalData(null); } // Parse the Certificate message and Send to cipher suite this.mPeerCertificate = Certificate.Parse(buf); AssertEmpty(buf); // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus if (this.mPeerCertificate == null || this.mPeerCertificate.IsEmpty) { this.mAllowCertificateStatus = false; } this.mKeyExchange.ProcessServerCertificate(this.mPeerCertificate); this.mAuthentication = mTlsClient.GetAuthentication(); this.mAuthentication.NotifyServerCertificate(this.mPeerCertificate); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.mConnectionState = CS_SERVER_CERTIFICATE; break; } case HandshakeType.certificate_status: { switch (this.mConnectionState) { case CS_SERVER_CERTIFICATE: { if (!this.mAllowCertificateStatus) { /* * RFC 3546 3.6. If a server returns a "CertificateStatus" message, then the * server MUST have included an extension of type "status_request" with empty * "extension_data" in the extended server hello.. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.mCertificateStatus = CertificateStatus.Parse(buf); AssertEmpty(buf); // TODO[RFC 3546] Figure out how to provide this to the client/authentication. this.mConnectionState = CS_CERTIFICATE_STATUS; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.finished: { switch (this.mConnectionState) { case CS_CLIENT_FINISHED: case CS_SERVER_SESSION_TICKET: { if (this.mConnectionState == CS_CLIENT_FINISHED && this.mExpectSessionTicket) { /* * RFC 5077 3.3. This message MUST be sent if the server included a * SessionTicket extension in the ServerHello. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } ProcessFinishedMessage(buf); this.mConnectionState = CS_SERVER_FINISHED; this.mConnectionState = CS_END; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.server_hello: { switch (this.mConnectionState) { case CS_CLIENT_HELLO: { ReceiveServerHelloMessage(buf); this.mConnectionState = CS_SERVER_HELLO; this.mRecordStream.NotifyHelloComplete(); ApplyMaxFragmentLengthExtension(); if (this.mResumedSession) { this.mSecurityParameters.masterSecret = Arrays.Clone(this.mSessionParameters.MasterSecret); this.mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); SendChangeCipherSpecMessage(); } else { InvalidateSession(); if (this.mSelectedSessionID.Length > 0) { this.mTlsSession = new TlsSessionImpl(this.mSelectedSessionID, null); } } break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.supplemental_data: { switch (this.mConnectionState) { case CS_SERVER_HELLO: { HandleSupplementalData(ReadSupplementalDataMessage(buf)); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.server_hello_done: { switch (this.mConnectionState) { case CS_SERVER_HELLO: case CS_SERVER_SUPPLEMENTAL_DATA: case CS_SERVER_CERTIFICATE: case CS_CERTIFICATE_STATUS: case CS_SERVER_KEY_EXCHANGE: case CS_CERTIFICATE_REQUEST: { if (mConnectionState < CS_SERVER_SUPPLEMENTAL_DATA) { HandleSupplementalData(null); } if (mConnectionState < CS_SERVER_CERTIFICATE) { // There was no server certificate message; check it's OK this.mKeyExchange.SkipServerCredentials(); this.mAuthentication = null; } if (mConnectionState < CS_SERVER_KEY_EXCHANGE) { // There was no server key exchange message; check it's OK this.mKeyExchange.SkipServerKeyExchange(); } AssertEmpty(buf); this.mConnectionState = CS_SERVER_HELLO_DONE; this.mRecordStream.HandshakeHash.SealHashAlgorithms(); IList clientSupplementalData = mTlsClient.GetClientSupplementalData(); if (clientSupplementalData != null) { SendSupplementalDataMessage(clientSupplementalData); } this.mConnectionState = CS_CLIENT_SUPPLEMENTAL_DATA; TlsCredentials clientCreds = null; if (mCertificateRequest == null) { this.mKeyExchange.SkipClientCredentials(); } else { clientCreds = this.mAuthentication.GetClientCredentials(this.Context, mCertificateRequest); if (clientCreds == null) { this.mKeyExchange.SkipClientCredentials(); /* * 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. */ SendCertificateMessage(Certificate.EmptyChain); } else { this.mKeyExchange.ProcessClientCredentials(clientCreds); SendCertificateMessage(clientCreds.Certificate); } } this.mConnectionState = CS_CLIENT_CERTIFICATE; /* * Send the client key exchange message, depending on the key exchange we are using * in our CipherSuite. */ SendClientKeyExchangeMessage(); this.mConnectionState = CS_CLIENT_KEY_EXCHANGE; TlsHandshakeHash prepareFinishHash = mRecordStream.PrepareToFinish(); this.mSecurityParameters.sessionHash = GetCurrentPrfHash(Context, prepareFinishHash, null); EstablishMasterSecret(Context, mKeyExchange); mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); if (clientCreds != null && clientCreds is TlsSignerCredentials) { TlsSignerCredentials signerCredentials = (TlsSignerCredentials)clientCreds; /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( Context, signerCredentials); byte[] hash; if (signatureAndHashAlgorithm == null) { hash = mSecurityParameters.SessionHash; } else { hash = prepareFinishHash.GetFinalHash(signatureAndHashAlgorithm.Hash); } byte[] signature = signerCredentials.GenerateCertificateSignature(hash); DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); SendCertificateVerifyMessage(certificateVerify); this.mConnectionState = CS_CERTIFICATE_VERIFY; } SendChangeCipherSpecMessage(); SendFinishedMessage(); break; } default: throw new TlsFatalAlert(AlertDescription.handshake_failure); } this.mConnectionState = CS_CLIENT_FINISHED; break; } case HandshakeType.server_key_exchange: { switch (this.mConnectionState) { case CS_SERVER_HELLO: case CS_SERVER_SUPPLEMENTAL_DATA: case CS_SERVER_CERTIFICATE: case CS_CERTIFICATE_STATUS: { if (mConnectionState < CS_SERVER_SUPPLEMENTAL_DATA) { HandleSupplementalData(null); } if (mConnectionState < CS_SERVER_CERTIFICATE) { // There was no server certificate message; check it's OK this.mKeyExchange.SkipServerCredentials(); this.mAuthentication = null; } this.mKeyExchange.ProcessServerKeyExchange(buf); AssertEmpty(buf); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.mConnectionState = CS_SERVER_KEY_EXCHANGE; break; } case HandshakeType.certificate_request: { switch (this.mConnectionState) { case CS_SERVER_CERTIFICATE: case CS_CERTIFICATE_STATUS: case CS_SERVER_KEY_EXCHANGE: { if (this.mConnectionState != CS_SERVER_KEY_EXCHANGE) { // There was no server key exchange message; check it's OK this.mKeyExchange.SkipServerKeyExchange(); } if (this.mAuthentication == null) { /* * RFC 2246 7.4.4. It is a fatal handshake_failure alert for an anonymous server * to request client identification. */ throw new TlsFatalAlert(AlertDescription.handshake_failure); } this.mCertificateRequest = CertificateRequest.Parse(Context, buf); AssertEmpty(buf); this.mKeyExchange.ValidateCertificateRequest(this.mCertificateRequest); /* * TODO Give the client a chance to immediately select the CertificateVerify hash * algorithm here to avoid tracking the other hash algorithms unnecessarily? */ TlsUtilities.TrackHashAlgorithms(this.mRecordStream.HandshakeHash, this.mCertificateRequest.SupportedSignatureAlgorithms); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.mConnectionState = CS_CERTIFICATE_REQUEST; break; } case HandshakeType.session_ticket: { switch (this.mConnectionState) { case CS_CLIENT_FINISHED: { if (!this.mExpectSessionTicket) { /* * RFC 5077 3.3. This message MUST NOT be sent if the server did not include a * SessionTicket extension in the ServerHello. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } /* * RFC 5077 3.4. If the client receives a session ticket from the server, then it * discards any Session ID that was sent in the ServerHello. */ InvalidateSession(); ReceiveNewSessionTicketMessage(buf); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } this.mConnectionState = CS_SERVER_SESSION_TICKET; break; } case HandshakeType.hello_request: { AssertEmpty(buf); /* * RFC 2246 7.4.1.1 Hello request This message will be ignored by the client if the * client is currently negotiating a session. This message may be ignored by the client * if it does not wish to renegotiate a session, or the client may, if it wishes, * respond with a no_renegotiation alert. */ if (this.mConnectionState == CS_END) { RefuseRenegotiation(); } break; } case HandshakeType.client_hello: case HandshakeType.client_key_exchange: case HandshakeType.certificate_verify: case HandshakeType.hello_verify_request: default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } }
public virtual void ProcessServerCertificate(Certificate serverCertificate) { throw new TlsFatalAlert(AlertDescription.unexpected_message); }
protected override void HandleHandshakeMessage(byte type, MemoryStream buf) { switch (type) { case HandshakeType.client_hello: { switch (this.mConnectionState) { case CS_START: { ReceiveClientHelloMessage(buf); this.mConnectionState = CS_CLIENT_HELLO; SendServerHelloMessage(); this.mConnectionState = CS_SERVER_HELLO; mRecordStream.NotifyHelloComplete(); IList serverSupplementalData = mTlsServer.GetServerSupplementalData(); if (serverSupplementalData != null) { SendSupplementalDataMessage(serverSupplementalData); } this.mConnectionState = CS_SERVER_SUPPLEMENTAL_DATA; this.mKeyExchange = mTlsServer.GetKeyExchange(); this.mKeyExchange.Init(Context); this.mServerCredentials = mTlsServer.GetCredentials(); Certificate serverCertificate = null; if (this.mServerCredentials == null) { this.mKeyExchange.SkipServerCredentials(); } else { this.mKeyExchange.ProcessServerCredentials(this.mServerCredentials); serverCertificate = this.mServerCredentials.Certificate; SendCertificateMessage(serverCertificate); } this.mConnectionState = CS_SERVER_CERTIFICATE; // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus if (serverCertificate == null || serverCertificate.IsEmpty) { this.mAllowCertificateStatus = false; } if (this.mAllowCertificateStatus) { CertificateStatus certificateStatus = mTlsServer.GetCertificateStatus(); if (certificateStatus != null) { SendCertificateStatusMessage(certificateStatus); } } this.mConnectionState = CS_CERTIFICATE_STATUS; byte[] serverKeyExchange = this.mKeyExchange.GenerateServerKeyExchange(); if (serverKeyExchange != null) { SendServerKeyExchangeMessage(serverKeyExchange); } this.mConnectionState = CS_SERVER_KEY_EXCHANGE; if (this.mServerCredentials != null) { this.mCertificateRequest = mTlsServer.GetCertificateRequest(); if (this.mCertificateRequest != null) { if (TlsUtilities.IsTlsV12(Context) != (mCertificateRequest.SupportedSignatureAlgorithms != null)) { throw new TlsFatalAlert(AlertDescription.internal_error); } this.mKeyExchange.ValidateCertificateRequest(mCertificateRequest); SendCertificateRequestMessage(mCertificateRequest); TlsUtilities.TrackHashAlgorithms(this.mRecordStream.HandshakeHash, this.mCertificateRequest.SupportedSignatureAlgorithms); } } this.mConnectionState = CS_CERTIFICATE_REQUEST; SendServerHelloDoneMessage(); this.mConnectionState = CS_SERVER_HELLO_DONE; this.mRecordStream.HandshakeHash.SealHashAlgorithms(); break; } case CS_END: { RefuseRenegotiation(); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.supplemental_data: { switch (this.mConnectionState) { case CS_SERVER_HELLO_DONE: { mTlsServer.ProcessClientSupplementalData(ReadSupplementalDataMessage(buf)); this.mConnectionState = CS_CLIENT_SUPPLEMENTAL_DATA; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.certificate: { switch (this.mConnectionState) { case CS_SERVER_HELLO_DONE: case CS_CLIENT_SUPPLEMENTAL_DATA: { if (mConnectionState < CS_CLIENT_SUPPLEMENTAL_DATA) { mTlsServer.ProcessClientSupplementalData(null); } if (this.mCertificateRequest == null) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } ReceiveCertificateMessage(buf); this.mConnectionState = CS_CLIENT_CERTIFICATE; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.client_key_exchange: { switch (this.mConnectionState) { case CS_SERVER_HELLO_DONE: case CS_CLIENT_SUPPLEMENTAL_DATA: case CS_CLIENT_CERTIFICATE: { if (mConnectionState < CS_CLIENT_SUPPLEMENTAL_DATA) { mTlsServer.ProcessClientSupplementalData(null); } if (mConnectionState < CS_CLIENT_CERTIFICATE) { if (this.mCertificateRequest == null) { this.mKeyExchange.SkipClientCredentials(); } else { if (TlsUtilities.IsTlsV12(Context)) { /* * 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); } else if (TlsUtilities.IsSsl(Context)) { if (this.mPeerCertificate == null) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } } else { NotifyClientCertificate(Certificate.EmptyChain); } } } ReceiveClientKeyExchangeMessage(buf); this.mConnectionState = CS_CLIENT_KEY_EXCHANGE; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.certificate_verify: { switch (this.mConnectionState) { case CS_CLIENT_KEY_EXCHANGE: { /* * 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()) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } ReceiveCertificateVerifyMessage(buf); this.mConnectionState = CS_CERTIFICATE_VERIFY; break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.finished: { switch (this.mConnectionState) { case CS_CLIENT_KEY_EXCHANGE: case CS_CERTIFICATE_VERIFY: { if (mConnectionState < CS_CERTIFICATE_VERIFY && ExpectCertificateVerifyMessage()) { throw new TlsFatalAlert(AlertDescription.unexpected_message); } ProcessFinishedMessage(buf); this.mConnectionState = CS_CLIENT_FINISHED; if (this.mExpectSessionTicket) { SendNewSessionTicketMessage(mTlsServer.GetNewSessionTicket()); } this.mConnectionState = CS_SERVER_SESSION_TICKET; SendChangeCipherSpecMessage(); SendFinishedMessage(); this.mConnectionState = CS_SERVER_FINISHED; CompleteHandshake(); break; } default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } break; } case HandshakeType.hello_request: case HandshakeType.hello_verify_request: case HandshakeType.server_hello: case HandshakeType.server_key_exchange: case HandshakeType.certificate_request: case HandshakeType.server_hello_done: case HandshakeType.session_ticket: default: throw new TlsFatalAlert(AlertDescription.unexpected_message); } }
public virtual void NotifyClientCertificate(Certificate clientCertificate) { throw new TlsFatalAlert(AlertDescription.internal_error); }
public Builder SetPeerCertificate(Certificate peerCertificate) { this.mPeerCertificate = peerCertificate; return(this); }
protected override void HandleHandshakeMessage(byte type, byte[] data) { MemoryStream memoryStream = new MemoryStream(data, writable: false); if (mResumedSession) { if (type != 20 || base.mConnectionState != 2) { throw new TlsFatalAlert(10); } ProcessFinishedMessage(memoryStream); base.mConnectionState = 15; SendFinishedMessage(); base.mConnectionState = 13; base.mConnectionState = 16; } else { switch (type) { case 11: { short mConnectionState = base.mConnectionState; if (mConnectionState != 2 && mConnectionState != 3) { throw new TlsFatalAlert(10); } if (base.mConnectionState == 2) { HandleSupplementalData(null); } mPeerCertificate = Certificate.Parse(memoryStream); TlsProtocol.AssertEmpty(memoryStream); if (mPeerCertificate == null || mPeerCertificate.IsEmpty) { mAllowCertificateStatus = false; } mKeyExchange.ProcessServerCertificate(mPeerCertificate); mAuthentication = mTlsClient.GetAuthentication(); mAuthentication.NotifyServerCertificate(mPeerCertificate); base.mConnectionState = 4; break; } case 22: { short mConnectionState = base.mConnectionState; if (mConnectionState != 4) { throw new TlsFatalAlert(10); } if (!mAllowCertificateStatus) { throw new TlsFatalAlert(10); } mCertificateStatus = CertificateStatus.Parse(memoryStream); TlsProtocol.AssertEmpty(memoryStream); base.mConnectionState = 5; break; } case 20: { short mConnectionState = base.mConnectionState; if (mConnectionState != 13 && mConnectionState != 14) { throw new TlsFatalAlert(10); } if (base.mConnectionState == 13 && mExpectSessionTicket) { throw new TlsFatalAlert(10); } ProcessFinishedMessage(memoryStream); base.mConnectionState = 15; base.mConnectionState = 16; break; } case 2: { short mConnectionState = base.mConnectionState; if (mConnectionState != 1) { throw new TlsFatalAlert(10); } ReceiveServerHelloMessage(memoryStream); base.mConnectionState = 2; mRecordStream.NotifyHelloComplete(); ApplyMaxFragmentLengthExtension(); if (mResumedSession) { mSecurityParameters.masterSecret = Arrays.Clone(mSessionParameters.MasterSecret); mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); SendChangeCipherSpecMessage(); } else { InvalidateSession(); if (mSelectedSessionID.Length > 0) { mTlsSession = new TlsSessionImpl(mSelectedSessionID, null); } } break; } case 23: { short mConnectionState = base.mConnectionState; if (mConnectionState != 2) { throw new TlsFatalAlert(10); } HandleSupplementalData(TlsProtocol.ReadSupplementalDataMessage(memoryStream)); break; } case 14: switch (base.mConnectionState) { case 2: case 3: case 4: case 5: case 6: case 7: { if (base.mConnectionState < 3) { HandleSupplementalData(null); } if (base.mConnectionState < 4) { mKeyExchange.SkipServerCredentials(); mAuthentication = null; } if (base.mConnectionState < 6) { mKeyExchange.SkipServerKeyExchange(); } TlsProtocol.AssertEmpty(memoryStream); base.mConnectionState = 8; mRecordStream.HandshakeHash.SealHashAlgorithms(); IList clientSupplementalData = mTlsClient.GetClientSupplementalData(); if (clientSupplementalData != null) { SendSupplementalDataMessage(clientSupplementalData); } base.mConnectionState = 9; TlsCredentials tlsCredentials = null; if (mCertificateRequest == null) { mKeyExchange.SkipClientCredentials(); } else { tlsCredentials = mAuthentication.GetClientCredentials(Context, mCertificateRequest); if (tlsCredentials == null) { mKeyExchange.SkipClientCredentials(); SendCertificateMessage(Certificate.EmptyChain); } else { mKeyExchange.ProcessClientCredentials(tlsCredentials); SendCertificateMessage(tlsCredentials.Certificate); } } base.mConnectionState = 10; SendClientKeyExchangeMessage(); base.mConnectionState = 11; TlsHandshakeHash tlsHandshakeHash = mRecordStream.PrepareToFinish(); mSecurityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(Context, tlsHandshakeHash, null); TlsProtocol.EstablishMasterSecret(Context, mKeyExchange); mRecordStream.SetPendingConnectionState(Peer.GetCompression(), Peer.GetCipher()); if (tlsCredentials != null && tlsCredentials is TlsSignerCredentials) { TlsSignerCredentials tlsSignerCredentials = (TlsSignerCredentials)tlsCredentials; SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(Context, tlsSignerCredentials); byte[] hash = (signatureAndHashAlgorithm != null) ? tlsHandshakeHash.GetFinalHash(signatureAndHashAlgorithm.Hash) : mSecurityParameters.SessionHash; byte[] signature = tlsSignerCredentials.GenerateCertificateSignature(hash); DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); SendCertificateVerifyMessage(certificateVerify); base.mConnectionState = 12; } SendChangeCipherSpecMessage(); SendFinishedMessage(); base.mConnectionState = 13; break; } default: throw new TlsFatalAlert(40); } break; case 12: switch (base.mConnectionState) { case 2: case 3: case 4: case 5: if (base.mConnectionState < 3) { HandleSupplementalData(null); } if (base.mConnectionState < 4) { mKeyExchange.SkipServerCredentials(); mAuthentication = null; } mKeyExchange.ProcessServerKeyExchange(memoryStream); TlsProtocol.AssertEmpty(memoryStream); base.mConnectionState = 6; break; default: throw new TlsFatalAlert(10); } break; case 13: switch (base.mConnectionState) { case 4: case 5: case 6: if (base.mConnectionState != 6) { mKeyExchange.SkipServerKeyExchange(); } if (mAuthentication == null) { throw new TlsFatalAlert(40); } mCertificateRequest = CertificateRequest.Parse(Context, memoryStream); TlsProtocol.AssertEmpty(memoryStream); mKeyExchange.ValidateCertificateRequest(mCertificateRequest); TlsUtilities.TrackHashAlgorithms(mRecordStream.HandshakeHash, mCertificateRequest.SupportedSignatureAlgorithms); base.mConnectionState = 7; break; default: throw new TlsFatalAlert(10); } break; case 4: { short mConnectionState = base.mConnectionState; if (mConnectionState != 13) { throw new TlsFatalAlert(10); } if (!mExpectSessionTicket) { throw new TlsFatalAlert(10); } InvalidateSession(); ReceiveNewSessionTicketMessage(memoryStream); base.mConnectionState = 14; break; } case 0: TlsProtocol.AssertEmpty(memoryStream); if (base.mConnectionState == 16) { RefuseRenegotiation(); } break; default: throw new TlsFatalAlert(10); } } }
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); 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.serverContext, 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.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)); }
public static List <X509Certificate2> ToCertificateList(this Certificate certificate) { return(certificate.GetCertificateList().Select(_ => new X509Certificate2(_.GetDerEncoded())).ToList()); }
public override void ProcessClientCertificate(Certificate clientCertificate) { }
private void ProcessHandshakeMessage(HandshakeType type, byte[] buf) { MemoryStream inStr = new MemoryStream(buf, false); /* * Check the type. */ switch (type) { case HandshakeType.certificate: { switch (connection_state) { case CS_SERVER_HELLO_RECEIVED: { // Parse the Certificate message and send to cipher suite Certificate serverCertificate = Certificate.Parse(inStr); AssertEmpty(inStr); this.keyExchange.ProcessServerCertificate(serverCertificate); this.authentication = tlsClient.GetAuthentication(); this.authentication.NotifyServerCertificate(serverCertificate); break; } default: this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } connection_state = CS_SERVER_CERTIFICATE_RECEIVED; break; } case HandshakeType.finished: switch (connection_state) { case CS_SERVER_CHANGE_CIPHER_SPEC_RECEIVED: /* * Read the checksum from the finished message, it has always 12 bytes. */ byte[] serverVerifyData = new byte[12]; TlsUtilities.ReadFully(serverVerifyData, inStr); AssertEmpty(inStr); /* * Calculate our own checksum. */ byte[] expectedServerVerifyData = TlsUtilities.PRF( securityParameters.masterSecret, "server finished", rs.GetCurrentHash(), 12); /* * Compare both checksums. */ if (!Arrays.ConstantTimeAreEqual(expectedServerVerifyData, serverVerifyData)) { /* * Wrong checksum in the finished message. */ this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } connection_state = CS_DONE; /* * We are now ready to receive application data. */ this.appDataReady = true; break; default: this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } break; case HandshakeType.server_hello: switch (connection_state) { case CS_CLIENT_HELLO_SEND: /* * Read the server hello message */ TlsUtilities.CheckVersion(inStr, this); /* * Read the server random */ securityParameters.serverRandom = new byte[32]; TlsUtilities.ReadFully(securityParameters.serverRandom, inStr); byte[] sessionID = TlsUtilities.ReadOpaque8(inStr); if (sessionID.Length > 32) { this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } this.tlsClient.NotifySessionID(sessionID); /* * Find out which CipherSuite the server has chosen and check that * it was one of the offered ones. */ CipherSuite selectedCipherSuite = (CipherSuite)TlsUtilities.ReadUint16(inStr); if (!ArrayContains(offeredCipherSuites, selectedCipherSuite) || selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV) { this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } this.tlsClient.NotifySelectedCipherSuite(selectedCipherSuite); /* * Find out which CompressionMethod the server has chosen and check that * it was one of the offered ones. */ CompressionMethod selectedCompressionMethod = (CompressionMethod)TlsUtilities.ReadUint8(inStr); if (!ArrayContains(offeredCompressionMethods, selectedCompressionMethod)) { this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } this.tlsClient.NotifySelectedCompressionMethod(selectedCompressionMethod); /* * RFC3546 2.2 The extended server hello message format MAY be * sent in place of the server hello message when the client has * requested extended functionality via the extended client hello * message specified in Section 2.1. * ... * Note that the extended server hello message is only sent in response * to an extended client hello message. This prevents the possibility * that the extended server hello message could "break" existing TLS 1.0 * clients. */ /* * TODO RFC 3546 2.3 * If [...] the older session is resumed, then the server MUST ignore * extensions appearing in the client hello, and send a server hello * containing no extensions. */ // ExtensionType -> byte[] IDictionary serverExtensions = Platform.CreateHashtable(); if (inStr.Position < inStr.Length) { // Process extensions from extended server hello byte[] extBytes = TlsUtilities.ReadOpaque16(inStr); MemoryStream ext = new MemoryStream(extBytes, false); while (ext.Position < ext.Length) { ExtensionType extType = (ExtensionType)TlsUtilities.ReadUint16(ext); byte[] extValue = TlsUtilities.ReadOpaque16(ext); // Note: RFC 5746 makes a special case for EXT_RenegotiationInfo if (extType != ExtensionType.renegotiation_info && !clientExtensions.Contains(extType)) { /* * RFC 3546 2.3 * Note that for all extension types (including those defined in * future), the extension type MUST NOT appear in the extended server * hello unless the same extension type appeared in the corresponding * client hello. Thus clients MUST abort the handshake if they receive * an extension type in the extended server hello that they did not * request in the associated (extended) client hello. */ this.FailWithError(AlertLevel.fatal, AlertDescription.unsupported_extension); } if (serverExtensions.Contains(extType)) { /* * RFC 3546 2.3 * Also note that when multiple extensions of different types are * present in the extended client hello or the extended server hello, * the extensions may appear in any order. There MUST NOT be more than * one extension of the same type. */ this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter); } serverExtensions.Add(extType, extValue); } } AssertEmpty(inStr); /* * RFC 5746 3.4. When a ServerHello is received, the client MUST check if it * includes the "renegotiation_info" extension: */ { bool secure_negotiation = serverExtensions.Contains(ExtensionType.renegotiation_info); /* * If the extension is present, set the secure_renegotiation flag * to TRUE. The client MUST then verify that the length of the * "renegotiated_connection" field is zero, and if it is not, MUST * abort the handshake (by sending a fatal handshake_failure * alert). */ if (secure_negotiation) { byte[] renegExtValue = (byte[])serverExtensions[ExtensionType.renegotiation_info]; if (!Arrays.ConstantTimeAreEqual(renegExtValue, CreateRenegotiationInfo(emptybuf))) { this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } } tlsClient.NotifySecureRenegotiation(secure_negotiation); } if (clientExtensions != null) { tlsClient.ProcessServerExtensions(serverExtensions); } this.keyExchange = tlsClient.GetKeyExchange(); connection_state = CS_SERVER_HELLO_RECEIVED; break; default: this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } break; case HandshakeType.server_hello_done: switch (connection_state) { case CS_SERVER_CERTIFICATE_RECEIVED: case CS_SERVER_KEY_EXCHANGE_RECEIVED: case CS_CERTIFICATE_REQUEST_RECEIVED: // NB: Original code used case label fall-through if (connection_state == CS_SERVER_CERTIFICATE_RECEIVED) { // There was no server key exchange message; check it's OK this.keyExchange.SkipServerKeyExchange(); } AssertEmpty(inStr); connection_state = CS_SERVER_HELLO_DONE_RECEIVED; TlsCredentials clientCreds = null; if (certificateRequest == null) { this.keyExchange.SkipClientCredentials(); } else { clientCreds = this.authentication.GetClientCredentials(certificateRequest); Certificate clientCert; if (clientCreds == null) { this.keyExchange.SkipClientCredentials(); clientCert = Certificate.EmptyChain; } else { this.keyExchange.ProcessClientCredentials(clientCreds); clientCert = clientCreds.Certificate; } SendClientCertificate(clientCert); } /* * Send the client key exchange message, depending on the key * exchange we are using in our CipherSuite. */ SendClientKeyExchange(); connection_state = CS_CLIENT_KEY_EXCHANGE_SEND; if (clientCreds != null && clientCreds is TlsSignerCredentials) { TlsSignerCredentials signerCreds = (TlsSignerCredentials)clientCreds; byte[] md5andsha1 = rs.GetCurrentHash(); byte[] clientCertificateSignature = signerCreds.GenerateCertificateSignature( md5andsha1); SendCertificateVerify(clientCertificateSignature); connection_state = CS_CERTIFICATE_VERIFY_SEND; } /* * Now, we send change cipher state */ byte[] cmessage = new byte[1]; cmessage[0] = 1; rs.WriteMessage(ContentType.change_cipher_spec, cmessage, 0, cmessage.Length); connection_state = CS_CLIENT_CHANGE_CIPHER_SPEC_SEND; /* * Calculate the master_secret */ byte[] pms = this.keyExchange.GeneratePremasterSecret(); securityParameters.masterSecret = TlsUtilities.PRF(pms, "master secret", TlsUtilities.Concat(securityParameters.clientRandom, securityParameters.serverRandom), 48); // TODO Is there a way to ensure the data is really overwritten? /* * RFC 2246 8.1. The pre_master_secret should be deleted from * memory once the master_secret has been computed. */ Array.Clear(pms, 0, pms.Length); /* * Initialize our cipher suite */ rs.ClientCipherSpecDecided(tlsClient.GetCompression(), tlsClient.GetCipher()); /* * Send our finished message. */ byte[] clientVerifyData = TlsUtilities.PRF(securityParameters.masterSecret, "client finished", rs.GetCurrentHash(), 12); MemoryStream bos = new MemoryStream(); TlsUtilities.WriteUint8((byte)HandshakeType.finished, bos); TlsUtilities.WriteOpaque24(clientVerifyData, bos); byte[] message = bos.ToArray(); rs.WriteMessage(ContentType.handshake, message, 0, message.Length); this.connection_state = CS_CLIENT_FINISHED_SEND; break; default: this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure); break; } break; case HandshakeType.server_key_exchange: { switch (connection_state) { case CS_SERVER_HELLO_RECEIVED: case CS_SERVER_CERTIFICATE_RECEIVED: { // NB: Original code used case label fall-through if (connection_state == CS_SERVER_HELLO_RECEIVED) { // There was no server certificate message; check it's OK this.keyExchange.SkipServerCertificate(); this.authentication = null; } this.keyExchange.ProcessServerKeyExchange(inStr); AssertEmpty(inStr); break; } default: this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } this.connection_state = CS_SERVER_KEY_EXCHANGE_RECEIVED; break; } case HandshakeType.certificate_request: switch (connection_state) { case CS_SERVER_CERTIFICATE_RECEIVED: case CS_SERVER_KEY_EXCHANGE_RECEIVED: { // NB: Original code used case label fall-through if (connection_state == CS_SERVER_CERTIFICATE_RECEIVED) { // There was no server key exchange message; check it's OK this.keyExchange.SkipServerKeyExchange(); } if (this.authentication == null) { /* * RFC 2246 7.4.4. It is a fatal handshake_failure alert * for an anonymous server to request client identification. */ this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure); } int numTypes = TlsUtilities.ReadUint8(inStr); ClientCertificateType[] certificateTypes = new ClientCertificateType[numTypes]; for (int i = 0; i < numTypes; ++i) { certificateTypes[i] = (ClientCertificateType)TlsUtilities.ReadUint8(inStr); } byte[] authorities = TlsUtilities.ReadOpaque16(inStr); AssertEmpty(inStr); IList authorityDNs = Platform.CreateArrayList(); MemoryStream bis = new MemoryStream(authorities, false); while (bis.Position < bis.Length) { byte[] dnBytes = TlsUtilities.ReadOpaque16(bis); // TODO Switch to X500Name when available authorityDNs.Add(X509Name.GetInstance(Asn1Object.FromByteArray(dnBytes))); } this.certificateRequest = new CertificateRequest(certificateTypes, authorityDNs); this.keyExchange.ValidateCertificateRequest(this.certificateRequest); break; } default: this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } this.connection_state = CS_CERTIFICATE_REQUEST_RECEIVED; break; case HandshakeType.hello_request: /* * RFC 2246 7.4.1.1 Hello request * This message will be ignored by the client if the client is currently * negotiating a session. This message may be ignored by the client if it * does not wish to renegotiate a session, or the client may, if it wishes, * respond with a no_renegotiation alert. */ if (connection_state == CS_DONE) { // Renegotiation not supported yet SendAlert(AlertLevel.warning, AlertDescription.no_renegotiation); } break; case HandshakeType.client_key_exchange: case HandshakeType.certificate_verify: case HandshakeType.client_hello: default: // We do not support this! this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message); break; } }
public DefaultTlsSignerCredentials(TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey) : this(context, certificate, privateKey, null) { }
public SessionParameters.Builder SetPeerCertificate(Certificate peerCertificate) { this.mPeerCertificate = peerCertificate; return(this); }
internal HttpsConnection(HttpConnectionFactory factory, Uri uri, Uri proxy, Certificate clientCertificates, AsymmetricKeyParameter asymmetricKeyParameter, Action<Certificate> serverCertificateValidator) : base(factory, uri, proxy) { _tlsClient = new CustomTlsClient(clientCertificates, asymmetricKeyParameter, serverCertificateValidator); }
/** * Sets the certificate used to provide the text in the appearance. * This certificate doesn't take part in the actual signing process. * @param signCertificate the certificate */ public void SetCertificate(Certificate signCertificate) { this.signCertificate = signCertificate; }
/// <exception cref="IOException"/> protected static byte[] GenerateCertificate(Certificate certificate) { MemoryStream buf = new MemoryStream(); certificate.Encode(buf); return buf.ToArray(); }
protected virtual void NotifyClientCertificate(ServerHandshakeState state, Certificate clientCertificate) { if (state.certificateRequest == null) throw new InvalidOperationException(); if (state.clientCertificate != null) throw new TlsFatalAlert(AlertDescription.unexpected_message); state.clientCertificate = clientCertificate; if (clientCertificate.IsEmpty) { state.keyExchange.SkipClientCredentials(); } else { /* * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request * message was non-empty, one of the certificates in the certificate chain SHOULD be * issued by one of the listed CAs. */ state.clientCertificateType = TlsUtilities.GetClientCertificateType(clientCertificate, state.serverCredentials.Certificate); state.keyExchange.ProcessClientCertificate(clientCertificate); } /* * RFC 5246 7.4.6. If the client does not send any certificates, the server MAY at its * discretion either continue the handshake without client authentication, or respond with a * fatal handshake_failure alert. Also, if some aspect of the certificate chain was * unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its * discretion either continue the handshake (considering the client unauthenticated) or send * a fatal alert. */ state.server.NotifyClientCertificate(clientCertificate); }
private void SendClientCertificate(Certificate clientCert) { MemoryStream bos = new MemoryStream(); TlsUtilities.WriteUint8(HP_CERTIFICATE, bos); clientCert.Encode(bos); byte[] message = bos.ToArray(); rs.WriteMessage(RL_HANDSHAKE, message, 0, message.Length); }
public override void ProcessClientCertificate(Certificate clientCertificate) { // TODO Extract the public key // TODO If the certificate is 'fixed', take the public key as dhAgreeClientPublicKey }
public override void ProcessClientCertificate(Certificate clientCertificate) { // TODO Extract the public key // TODO If the certificate is 'fixed', take the public key as dhAgreeClientPublicKey }
private SessionParameters(int cipherSuite, byte compressionAlgorithm, byte[] masterSecret, Certificate peerCertificate, byte[] pskIdentity, byte[] srpIdentity, byte[] encodedServerExtensions) { this.mCipherSuite = cipherSuite; this.mCompressionAlgorithm = compressionAlgorithm; this.mMasterSecret = Arrays.Clone(masterSecret); this.mPeerCertificate = peerCertificate; this.mPskIdentity = Arrays.Clone(pskIdentity); this.mSrpIdentity = Arrays.Clone(srpIdentity); this.mEncodedServerExtensions = encodedServerExtensions; }
private void SendClientCertificate(Certificate clientCert) { MemoryStream bos = new MemoryStream(); TlsUtilities.WriteUint8((byte)HandshakeType.certificate, bos); // Reserve space for length TlsUtilities.WriteUint24(0, bos); clientCert.Encode(bos); byte[] message = bos.ToArray(); // Patch actual length back in TlsUtilities.WriteUint24(message.Length - 4, message, 1); rs.WriteMessage(ContentType.handshake, message, 0, message.Length); }
public virtual void NotifyClientCertificate(Certificate clientCertificate) { throw new TlsFatalAlert(80); }
public virtual void ProcessServerCertificate(Certificate serverCertificate) { if (mSupportedSignatureAlgorithms != null) { } }
public virtual void ProcessClientCertificate(Certificate clientCertificate) { }
protected override void HandleHandshakeMessage(byte type, byte[] data) { MemoryStream buf = new MemoryStream(data, false); if (base.mResumedSession) { if ((type != 20) || (base.mConnectionState != 2)) { throw new TlsFatalAlert(10); } this.ProcessFinishedMessage(buf); base.mConnectionState = 15; this.SendFinishedMessage(); base.mConnectionState = 13; base.mConnectionState = 0x10; this.CompleteHandshake(); } else { switch (type) { case 0: TlsProtocol.AssertEmpty(buf); if (base.mConnectionState == 0x10) { this.RefuseRenegotiation(); } return; case 2: if (base.mConnectionState != 1) { throw new TlsFatalAlert(10); } this.ReceiveServerHelloMessage(buf); base.mConnectionState = 2; base.mRecordStream.NotifyHelloComplete(); this.ApplyMaxFragmentLengthExtension(); if (base.mResumedSession) { base.mSecurityParameters.masterSecret = Arrays.Clone(base.mSessionParameters.MasterSecret); base.mRecordStream.SetPendingConnectionState(this.Peer.GetCompression(), this.Peer.GetCipher()); this.SendChangeCipherSpecMessage(); } else { this.InvalidateSession(); if (this.mSelectedSessionID.Length > 0) { base.mTlsSession = new TlsSessionImpl(this.mSelectedSessionID, null); } } return; case 4: if (base.mConnectionState != 13) { throw new TlsFatalAlert(10); } if (!base.mExpectSessionTicket) { throw new TlsFatalAlert(10); } this.InvalidateSession(); this.ReceiveNewSessionTicketMessage(buf); base.mConnectionState = 14; return; case 11: switch (base.mConnectionState) { case 2: case 3: if (base.mConnectionState == 2) { this.HandleSupplementalData(null); } base.mPeerCertificate = Certificate.Parse(buf); TlsProtocol.AssertEmpty(buf); if ((base.mPeerCertificate == null) || base.mPeerCertificate.IsEmpty) { base.mAllowCertificateStatus = false; } this.mKeyExchange.ProcessServerCertificate(base.mPeerCertificate); this.mAuthentication = this.mTlsClient.GetAuthentication(); this.mAuthentication.NotifyServerCertificate(base.mPeerCertificate); base.mConnectionState = 4; return; } throw new TlsFatalAlert(10); case 12: switch (base.mConnectionState) { case 2: case 3: case 4: case 5: if (base.mConnectionState < 3) { this.HandleSupplementalData(null); } if (base.mConnectionState < 4) { this.mKeyExchange.SkipServerCredentials(); this.mAuthentication = null; } this.mKeyExchange.ProcessServerKeyExchange(buf); TlsProtocol.AssertEmpty(buf); base.mConnectionState = 6; return; } throw new TlsFatalAlert(10); case 13: switch (base.mConnectionState) { case 4: case 5: case 6: if (base.mConnectionState != 6) { this.mKeyExchange.SkipServerKeyExchange(); } if (this.mAuthentication == null) { throw new TlsFatalAlert(40); } this.mCertificateRequest = CertificateRequest.Parse(this.Context, buf); TlsProtocol.AssertEmpty(buf); this.mKeyExchange.ValidateCertificateRequest(this.mCertificateRequest); TlsUtilities.TrackHashAlgorithms(base.mRecordStream.HandshakeHash, this.mCertificateRequest.SupportedSignatureAlgorithms); base.mConnectionState = 7; return; } throw new TlsFatalAlert(10); case 14: switch (base.mConnectionState) { case 2: case 3: case 4: case 5: case 6: case 7: { if (base.mConnectionState < 3) { this.HandleSupplementalData(null); } if (base.mConnectionState < 4) { this.mKeyExchange.SkipServerCredentials(); this.mAuthentication = null; } if (base.mConnectionState < 6) { this.mKeyExchange.SkipServerKeyExchange(); } TlsProtocol.AssertEmpty(buf); base.mConnectionState = 8; base.mRecordStream.HandshakeHash.SealHashAlgorithms(); IList clientSupplementalData = this.mTlsClient.GetClientSupplementalData(); if (clientSupplementalData != null) { this.SendSupplementalDataMessage(clientSupplementalData); } base.mConnectionState = 9; TlsCredentials clientCredentials = null; if (this.mCertificateRequest == null) { this.mKeyExchange.SkipClientCredentials(); } else { clientCredentials = this.mAuthentication.GetClientCredentials(this.Context, this.mCertificateRequest); if (clientCredentials == null) { this.mKeyExchange.SkipClientCredentials(); this.SendCertificateMessage(Certificate.EmptyChain); } else { this.mKeyExchange.ProcessClientCredentials(clientCredentials); this.SendCertificateMessage(clientCredentials.Certificate); } } base.mConnectionState = 10; this.SendClientKeyExchangeMessage(); base.mConnectionState = 11; TlsHandshakeHash handshakeHash = base.mRecordStream.PrepareToFinish(); base.mSecurityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(this.Context, handshakeHash, null); TlsProtocol.EstablishMasterSecret(this.Context, this.mKeyExchange); base.mRecordStream.SetPendingConnectionState(this.Peer.GetCompression(), this.Peer.GetCipher()); if ((clientCredentials != null) && (clientCredentials is TlsSignerCredentials)) { byte[] sessionHash; TlsSignerCredentials signerCredentials = (TlsSignerCredentials)clientCredentials; SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(this.Context, signerCredentials); if (signatureAndHashAlgorithm == null) { sessionHash = base.mSecurityParameters.SessionHash; } else { sessionHash = handshakeHash.GetFinalHash(signatureAndHashAlgorithm.Hash); } byte[] signature = signerCredentials.GenerateCertificateSignature(sessionHash); DigitallySigned certificateVerify = new DigitallySigned(signatureAndHashAlgorithm, signature); this.SendCertificateVerifyMessage(certificateVerify); base.mConnectionState = 12; } this.SendChangeCipherSpecMessage(); this.SendFinishedMessage(); base.mConnectionState = 13; return; } } throw new TlsFatalAlert(40); case 20: switch (base.mConnectionState) { case 13: case 14: if ((base.mConnectionState == 13) && base.mExpectSessionTicket) { throw new TlsFatalAlert(10); } this.ProcessFinishedMessage(buf); base.mConnectionState = 15; base.mConnectionState = 0x10; this.CompleteHandshake(); return; } throw new TlsFatalAlert(10); case 0x16: if (base.mConnectionState != 4) { throw new TlsFatalAlert(10); } if (!base.mAllowCertificateStatus) { throw new TlsFatalAlert(10); } this.mCertificateStatus = CertificateStatus.Parse(buf); TlsProtocol.AssertEmpty(buf); base.mConnectionState = 5; return; case 0x17: if (base.mConnectionState != 2) { throw new TlsFatalAlert(10); } this.HandleSupplementalData(TlsProtocol.ReadSupplementalDataMessage(buf)); return; } throw new TlsFatalAlert(10); } }
public abstract void NotifyServerCertificate(Certificate serverCertificate);