protected virtual void SendCertificateVerifyMessage(DigitallySigned certificateVerify) { HandshakeMessage handshakeMessage = new HandshakeMessage(15); certificateVerify.Encode((Stream)(object)handshakeMessage); handshakeMessage.WriteToRecordStream(this); }
public override byte[] GenerateServerKeyExchange() { if (this.mDHParameters == null) throw new TlsFatalAlert(AlertDescription.internal_error); DigestInputBuffer buf = new DigestInputBuffer(); this.mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, this.mDHParameters, buf); /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( mContext, mServerCredentials); IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm); SecurityParameters securityParameters = mContext.SecurityParameters; d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); buf.UpdateDigest(d); byte[] hash = DigestUtilities.DoFinal(d); byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); signed_params.Encode(buf); return buf.ToArray(); }
public override byte[] GenerateServerKeyExchange() { DigestInputBuffer buf = new DigestInputBuffer(); this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves, mClientECPointFormats, buf); /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( mContext, mServerCredentials); IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm); SecurityParameters securityParameters = mContext.SecurityParameters; d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); buf.UpdateDigest(d); byte[] hash = DigestUtilities.DoFinal(d); byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); signed_params.Encode(buf); return buf.ToArray(); }
public override byte[] GenerateServerKeyExchange() { DigestInputBuffer buf = new DigestInputBuffer(); this.mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves, mClientECPointFormats, buf); /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( mContext, mServerCredentials); IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm); SecurityParameters securityParameters = mContext.SecurityParameters; d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); buf.UpdateDigest(d); byte[] hash = DigestUtilities.DoFinal(d); byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); signed_params.Encode(buf); return(buf.ToArray()); }
protected virtual void SendCertificateVerifyMessage(DigitallySigned certificateVerify) { HandshakeMessage message = new HandshakeMessage(HandshakeType.certificate_verify); certificateVerify.Encode(message); message.WriteToRecordStream(this); }
protected virtual DigitallySigned ParseSignature(Stream input) { DigitallySigned signature = DigitallySigned.Parse(mContext, input); SignatureAndHashAlgorithm signatureAlgorithm = signature.Algorithm; if (signatureAlgorithm != null) { TlsUtilities.VerifySupportedSignatureAlgorithm(mSupportedSignatureAlgorithms, signatureAlgorithm); } return(signature); }
public override void ProcessServerKeyExchange(Stream input) { SecurityParameters securityParameters = context.SecurityParameters; SignerInputBuffer buf = null; Stream teeIn = input; if (mTlsSigner != null) { buf = new SignerInputBuffer(); teeIn = new TeeInputStream(input, buf); } byte[] NBytes = TlsUtilities.ReadOpaque16(teeIn); byte[] gBytes = TlsUtilities.ReadOpaque16(teeIn); byte[] sBytes = TlsUtilities.ReadOpaque8(teeIn); byte[] BBytes = TlsUtilities.ReadOpaque16(teeIn); if (buf != null) { DigitallySigned signed_params = DigitallySigned.Parse(context, input); ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters); buf.UpdateSigner(signer); if (!signer.VerifySignature(signed_params.Signature)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } BigInteger N = new BigInteger(1, NBytes); BigInteger g = new BigInteger(1, gBytes); // TODO Validate group parameters (see RFC 5054) // throw new TlsFatalAlert(AlertDescription.insufficient_security); this.mS = sBytes; /* * RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter" alert if * B % N = 0. */ try { this.mB = Srp6Utilities.ValidatePublicValue(N, new BigInteger(1, BBytes)); } catch (CryptoException e) { throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); } this.mSrpClient.Init(N, g, TlsUtilities.CreateHash(HashAlgorithm.sha1), context.SecureRandom); }
public override void ProcessServerKeyExchange(Stream input) { SecurityParameters securityParameters = mContext.SecurityParameters; SignerInputBuffer buf = null; Stream teeIn = input; if (mTlsSigner != null) { buf = new SignerInputBuffer(); teeIn = new TeeInputStream(input, buf); } ServerSrpParams srpParams = ServerSrpParams.Parse(teeIn); if (buf != null) { DigitallySigned signed_params = DigitallySigned.Parse(mContext, input); ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters); buf.UpdateSigner(signer); if (!signer.VerifySignature(signed_params.Signature)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } this.mSrpGroup = new Srp6GroupParameters(srpParams.N, srpParams.G); if (!mGroupVerifier.Accept(mSrpGroup)) { throw new TlsFatalAlert(AlertDescription.insufficient_security); } this.mSrpSalt = srpParams.S; /* * RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter" alert if * B % N = 0. */ try { this.mSrpPeerCredentials = Srp6Utilities.ValidatePublicValue(mSrpGroup.N, srpParams.B); } catch (CryptoException e) { throw new TlsFatalAlert(AlertDescription.illegal_parameter, e); } this.mSrpClient.Init(mSrpGroup, TlsUtilities.CreateHash(HashAlgorithm.sha1), mContext.SecureRandom); }
public override byte[] GenerateServerKeyExchange() { if (this.mDHParameters == null) { throw new TlsFatalAlert(AlertDescription.internal_error); } DigestInputBuffer buf = new DigestInputBuffer(); this.mDHAgreeServerPrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(context.SecureRandom, this.mDHParameters, buf); /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm; IDigest d; if (TlsUtilities.IsTlsV12(context)) { signatureAndHashAlgorithm = mServerCredentials.SignatureAndHashAlgorithm; if (signatureAndHashAlgorithm == null) { throw new TlsFatalAlert(AlertDescription.internal_error); } d = TlsUtilities.CreateHash(signatureAndHashAlgorithm.Hash); } else { signatureAndHashAlgorithm = null; d = new CombinedHash(); } SecurityParameters securityParameters = context.SecurityParameters; d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); buf.UpdateDigest(d); byte[] hash = DigestUtilities.DoFinal(d); byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); signed_params.Encode(buf); return(buf.ToArray()); }
protected virtual void ProcessCertificateVerify(ServerHandshakeState state, byte[] body, TlsHandshakeHash prepareFinishHash) { if (state.certificateRequest == null) { throw new InvalidOperationException(); } MemoryStream buf = new MemoryStream(body, false); TlsServerContextImpl context = state.serverContext; DigitallySigned clientCertificateVerify = DigitallySigned.Parse(context, buf); TlsProtocol.AssertEmpty(buf); // Verify the CertificateVerify message contains a correct signature. try { SignatureAndHashAlgorithm signatureAlgorithm = clientCertificateVerify.Algorithm; byte[] hash; if (TlsUtilities.IsTlsV12(context)) { TlsUtilities.VerifySupportedSignatureAlgorithm(state.certificateRequest.SupportedSignatureAlgorithms, signatureAlgorithm); hash = prepareFinishHash.GetFinalHash(signatureAlgorithm.Hash); } else { hash = context.SecurityParameters.SessionHash; } X509CertificateStructure x509Cert = state.clientCertificate.GetCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo); TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)state.clientCertificateType); tlsSigner.Init(context); if (!tlsSigner.VerifyRawSignature(signatureAlgorithm, clientCertificateVerify.Signature, publicKey, hash)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } catch (TlsFatalAlert e) { throw e; } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.decrypt_error, e); } }
protected virtual void ReceiveCertificateVerifyMessage(MemoryStream buf) { if (mCertificateRequest == null) { throw new InvalidOperationException(); } DigitallySigned clientCertificateVerify = DigitallySigned.Parse(Context, buf); AssertEmpty(buf); // Verify the CertificateVerify message contains a correct signature. try { SignatureAndHashAlgorithm signatureAlgorithm = clientCertificateVerify.Algorithm; byte[] hash; if (TlsUtilities.IsTlsV12(Context)) { TlsUtilities.VerifySupportedSignatureAlgorithm(mCertificateRequest.SupportedSignatureAlgorithms, signatureAlgorithm); hash = mPrepareFinishHash.GetFinalHash(signatureAlgorithm.Hash); } else { hash = mSecurityParameters.SessionHash; } X509CertificateStructure x509Cert = mPeerCertificate.GetCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo); TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)mClientCertificateType); tlsSigner.Init(Context); if (!tlsSigner.VerifyRawSignature(signatureAlgorithm, clientCertificateVerify.Signature, publicKey, hash)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } catch (TlsFatalAlert e) { throw e; } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.decrypt_error, e); } }
public override void ProcessServerKeyExchange(Stream input) { SecurityParameters securityParameters = mContext.SecurityParameters; SignerInputBuffer signerInputBuffer = new SignerInputBuffer(); Stream input2 = new TeeInputStream(input, signerInputBuffer); ServerDHParams serverDHParams = ServerDHParams.Parse(input2); DigitallySigned digitallySigned = DigitallySigned.Parse(mContext, input); ISigner signer = InitVerifyer(mTlsSigner, digitallySigned.Algorithm, securityParameters); signerInputBuffer.UpdateSigner(signer); if (!signer.VerifySignature(digitallySigned.Signature)) { throw new TlsFatalAlert(51); } mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(serverDHParams.PublicKey); mDHParameters = mDHAgreePublicKey.Parameters; }
protected virtual void ProcessCertificateVerify(ServerHandshakeState state, byte[] body, TlsHandshakeHash prepareFinishHash) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown if (state.certificateRequest == null) { throw new InvalidOperationException(); } MemoryStream val = new MemoryStream(body, false); TlsServerContextImpl serverContext = state.serverContext; DigitallySigned digitallySigned = DigitallySigned.Parse(serverContext, (Stream)(object)val); TlsProtocol.AssertEmpty(val); try { SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm; byte[] hash; if (TlsUtilities.IsTlsV12(serverContext)) { TlsUtilities.VerifySupportedSignatureAlgorithm(state.certificateRequest.SupportedSignatureAlgorithms, algorithm); hash = prepareFinishHash.GetFinalHash(algorithm.Hash); } else { hash = serverContext.SecurityParameters.SessionHash; } X509CertificateStructure certificateAt = state.clientCertificate.GetCertificateAt(0); SubjectPublicKeyInfo subjectPublicKeyInfo = certificateAt.SubjectPublicKeyInfo; AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(subjectPublicKeyInfo); TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)state.clientCertificateType); tlsSigner.Init(serverContext); if (!tlsSigner.VerifyRawSignature(algorithm, digitallySigned.Signature, publicKey, hash)) { throw new TlsFatalAlert(51); } } catch (TlsFatalAlert tlsFatalAlert) { throw tlsFatalAlert; } catch (global::System.Exception alertCause) { throw new TlsFatalAlert(51, alertCause); } }
public override void ProcessServerKeyExchange(Stream input) { SecurityParameters securityParameters = base.mContext.SecurityParameters; SignerInputBuffer tee = new SignerInputBuffer(); Stream stream = new TeeInputStream(input, tee); ServerDHParams @params = ServerDHParams.Parse(stream); DigitallySigned signed = this.ParseSignature(input); ISigner s = this.InitVerifyer(base.mTlsSigner, signed.Algorithm, securityParameters); tee.UpdateSigner(s); if (!s.VerifySignature(signed.Signature)) { throw new TlsFatalAlert(0x33); } base.mDHAgreePublicKey = TlsDHUtilities.ValidateDHPublicKey(@params.PublicKey); base.mDHParameters = this.ValidateDHParameters(base.mDHAgreePublicKey.Parameters); }
public override void ProcessServerKeyExchange(Stream input) { SecurityParameters securityParameters = mContext.SecurityParameters; SignerInputBuffer signerInputBuffer = new SignerInputBuffer(); Stream input2 = (Stream)(object)new TeeInputStream(input, (Stream)(object)signerInputBuffer); ECDomainParameters curve_params = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, input2); byte[] encoding = TlsUtilities.ReadOpaque8(input2); DigitallySigned digitallySigned = ParseSignature(input); ISigner signer = InitVerifyer(mTlsSigner, digitallySigned.Algorithm, securityParameters); signerInputBuffer.UpdateSigner(signer); if (!signer.VerifySignature(digitallySigned.Signature)) { throw new TlsFatalAlert(51); } mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(mClientECPointFormats, curve_params, encoding)); }
public override void ProcessServerKeyExchange(Stream input) { SecurityParameters securityParameters = base.mContext.SecurityParameters; SignerInputBuffer tee = new SignerInputBuffer(); Stream stream = new TeeInputStream(input, tee); ECDomainParameters parameters2 = TlsEccUtilities.ReadECParameters(base.mNamedCurves, base.mClientECPointFormats, stream); byte[] encoding = TlsUtilities.ReadOpaque8(stream); DigitallySigned signed = this.ParseSignature(input); ISigner s = this.InitVerifyer(base.mTlsSigner, signed.Algorithm, securityParameters); tee.UpdateSigner(s); if (!s.VerifySignature(signed.Signature)) { throw new TlsFatalAlert(0x33); } base.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey(base.mClientECPointFormats, parameters2, encoding)); }
public override byte[] GenerateServerKeyExchange() { DigestInputBuffer digestInputBuffer = new DigestInputBuffer(); mECAgreePrivateKey = TlsEccUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mNamedCurves, mClientECPointFormats, (Stream)(object)digestInputBuffer); SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(mContext, mServerCredentials); IDigest digest = TlsUtilities.CreateHash(signatureAndHashAlgorithm); SecurityParameters securityParameters = mContext.SecurityParameters; digest.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); digest.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); digestInputBuffer.UpdateDigest(digest); byte[] hash = DigestUtilities.DoFinal(digest); byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); DigitallySigned digitallySigned = new DigitallySigned(signatureAndHashAlgorithm, signature); digitallySigned.Encode((Stream)(object)digestInputBuffer); return(((MemoryStream)digestInputBuffer).ToArray()); }
protected virtual void ReceiveCertificateVerifyMessage(MemoryStream buf) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (mCertificateRequest == null) { throw new InvalidOperationException(); } DigitallySigned digitallySigned = DigitallySigned.Parse(Context, (Stream)(object)buf); TlsProtocol.AssertEmpty(buf); try { SignatureAndHashAlgorithm algorithm = digitallySigned.Algorithm; byte[] hash; if (TlsUtilities.IsTlsV12(Context)) { TlsUtilities.VerifySupportedSignatureAlgorithm(mCertificateRequest.SupportedSignatureAlgorithms, algorithm); hash = mPrepareFinishHash.GetFinalHash(algorithm.Hash); } else { hash = mSecurityParameters.SessionHash; } X509CertificateStructure certificateAt = mPeerCertificate.GetCertificateAt(0); SubjectPublicKeyInfo subjectPublicKeyInfo = certificateAt.SubjectPublicKeyInfo; AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(subjectPublicKeyInfo); TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)mClientCertificateType); tlsSigner.Init(Context); if (!tlsSigner.VerifyRawSignature(algorithm, digitallySigned.Signature, publicKey, hash)) { throw new TlsFatalAlert(51); } } catch (TlsFatalAlert tlsFatalAlert) { throw tlsFatalAlert; } catch (global::System.Exception alertCause) { throw new TlsFatalAlert(51, alertCause); } }
public override void ProcessServerKeyExchange(Stream input) { SecurityParameters securityParameters = mContext.SecurityParameters; SignerInputBuffer buf = new SignerInputBuffer(); Stream teeIn = new TeeInputStream(input, buf); this.mDHParameters = TlsDHUtilities.ReceiveDHParameters(mDHVerifier, teeIn); this.mDHAgreePublicKey = new DHPublicKeyParameters(TlsDHUtilities.ReadDHParameter(teeIn), mDHParameters); DigitallySigned signed_params = ParseSignature(input); ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters); buf.UpdateSigner(signer); if (!signer.VerifySignature(signed_params.Signature)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } }
public override void ProcessServerKeyExchange(Stream input) { SecurityParameters securityParameters = context.SecurityParameters; SignerInputBuffer buf = new SignerInputBuffer(); Stream teeIn = new TeeInputStream(input, buf); ServerDHParams dhParams = ServerDHParams.Parse(teeIn); DigitallySigned signed_params = DigitallySigned.Parse(context, input); ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters); buf.UpdateSigner(signer); if (!signer.VerifySignature(signed_params.Signature)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } this.mDHAgreeServerPublicKey = TlsDHUtilities.ValidateDHPublicKey(dhParams.PublicKey); }
public override void ProcessServerKeyExchange(Stream input) { SecurityParameters securityParameters = mContext.SecurityParameters; SignerInputBuffer signerInputBuffer = null; Stream input2 = input; if (mTlsSigner != null) { signerInputBuffer = new SignerInputBuffer(); input2 = (Stream)(object)new TeeInputStream(input, (Stream)(object)signerInputBuffer); } ServerSrpParams serverSrpParams = ServerSrpParams.Parse(input2); if (signerInputBuffer != null) { DigitallySigned digitallySigned = ParseSignature(input); ISigner signer = InitVerifyer(mTlsSigner, digitallySigned.Algorithm, securityParameters); signerInputBuffer.UpdateSigner(signer); if (!signer.VerifySignature(digitallySigned.Signature)) { throw new TlsFatalAlert(51); } } mSrpGroup = new Srp6GroupParameters(serverSrpParams.N, serverSrpParams.G); if (!mGroupVerifier.Accept(mSrpGroup)) { throw new TlsFatalAlert(71); } mSrpSalt = serverSrpParams.S; try { mSrpPeerCredentials = Srp6Utilities.ValidatePublicValue(mSrpGroup.N, serverSrpParams.B); } catch (CryptoException alertCause) { throw new TlsFatalAlert(47, alertCause); } mSrpClient.Init(mSrpGroup, TlsUtilities.CreateHash(2), mContext.SecureRandom); }
public override byte[] GenerateServerKeyExchange() { if (mDHParameters == null) { throw new TlsFatalAlert(80); } DigestInputBuffer digestInputBuffer = new DigestInputBuffer(); mDHAgreePrivateKey = TlsDHUtilities.GenerateEphemeralServerKeyExchange(mContext.SecureRandom, mDHParameters, digestInputBuffer); SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(mContext, mServerCredentials); IDigest digest = TlsUtilities.CreateHash(signatureAndHashAlgorithm); SecurityParameters securityParameters = mContext.SecurityParameters; digest.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); digest.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); digestInputBuffer.UpdateDigest(digest); byte[] hash = DigestUtilities.DoFinal(digest); byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); DigitallySigned digitallySigned = new DigitallySigned(signatureAndHashAlgorithm, signature); digitallySigned.Encode(digestInputBuffer); return(digestInputBuffer.ToArray()); }
public override byte[] GenerateServerKeyExchange() { mSrpServer.Init(mSrpGroup, mSrpVerifier, TlsUtilities.CreateHash(HashAlgorithm.sha1), mContext.SecureRandom); BigInteger B = mSrpServer.GenerateServerCredentials(); ServerSrpParams srpParams = new ServerSrpParams(mSrpGroup.N, mSrpGroup.G, mSrpSalt, B); DigestInputBuffer buf = new DigestInputBuffer(); srpParams.Encode(buf); if (mServerCredentials != null) { /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( mContext, mServerCredentials); IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm); SecurityParameters securityParameters = mContext.SecurityParameters; d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); buf.UpdateDigest(d); byte[] hash = new byte[d.GetDigestSize()]; d.DoFinal(hash, 0); byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); signed_params.Encode(buf); } return(buf.ToArray()); }
public override byte[] GenerateServerKeyExchange() { mSrpServer.Init(mSrpGroup, mSrpVerifier, TlsUtilities.CreateHash(2), mContext.SecureRandom); BigInteger b = mSrpServer.GenerateServerCredentials(); ServerSrpParams serverSrpParams = new ServerSrpParams(mSrpGroup.N, mSrpGroup.G, mSrpSalt, b); DigestInputBuffer digestInputBuffer = new DigestInputBuffer(); serverSrpParams.Encode((Stream)(object)digestInputBuffer); if (mServerCredentials != null) { SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm(mContext, mServerCredentials); IDigest digest = TlsUtilities.CreateHash(signatureAndHashAlgorithm); SecurityParameters securityParameters = mContext.SecurityParameters; digest.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); digest.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); digestInputBuffer.UpdateDigest(digest); byte[] array = new byte[digest.GetDigestSize()]; digest.DoFinal(array, 0); byte[] signature = mServerCredentials.GenerateCertificateSignature(array); DigitallySigned digitallySigned = new DigitallySigned(signatureAndHashAlgorithm, signature); digitallySigned.Encode((Stream)(object)digestInputBuffer); } return(((MemoryStream)digestInputBuffer).ToArray()); }
public override void ProcessServerKeyExchange(Stream input) { SecurityParameters securityParameters = mContext.SecurityParameters; SignerInputBuffer buf = new SignerInputBuffer(); Stream teeIn = new TeeInputStream(input, buf); ECDomainParameters curve_params = TlsEccUtilities.ReadECParameters(mNamedCurves, mClientECPointFormats, teeIn); byte[] point = TlsUtilities.ReadOpaque8(teeIn); DigitallySigned signed_params = DigitallySigned.Parse(mContext, input); ISigner signer = InitVerifyer(mTlsSigner, signed_params.Algorithm, securityParameters); buf.UpdateSigner(signer); if (!signer.VerifySignature(signed_params.Signature)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } this.mECAgreePublicKey = TlsEccUtilities.ValidateECPublicKey(TlsEccUtilities.DeserializeECPublicKey( mClientECPointFormats, curve_params, point)); }
protected virtual void ReceiveCertificateVerifyMessage(MemoryStream buf) { DigitallySigned clientCertificateVerify = DigitallySigned.Parse(Context, buf); AssertEmpty(buf); // Verify the CertificateVerify message contains a correct signature. try { byte[] certificateVerifyHash; if (TlsUtilities.IsTlsV12(Context)) { certificateVerifyHash = mPrepareFinishHash.GetFinalHash(clientCertificateVerify.Algorithm.Hash); } else { certificateVerifyHash = TlsProtocol.GetCurrentPrfHash(Context, mPrepareFinishHash, null); } X509CertificateStructure x509Cert = mPeerCertificate.GetCertificateAt(0); SubjectPublicKeyInfo keyInfo = x509Cert.SubjectPublicKeyInfo; AsymmetricKeyParameter publicKey = PublicKeyFactory.CreateKey(keyInfo); TlsSigner tlsSigner = TlsUtilities.CreateTlsSigner((byte)mClientCertificateType); tlsSigner.Init(Context); if (!tlsSigner.VerifyRawSignature(clientCertificateVerify.Algorithm, clientCertificateVerify.Signature, publicKey, certificateVerifyHash)) { throw new TlsFatalAlert(AlertDescription.decrypt_error); } } catch (Exception e) { throw new TlsFatalAlert(AlertDescription.decrypt_error, e); } }
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)); }
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); } }
protected virtual byte[] GenerateCertificateVerify(ClientHandshakeState state, DigitallySigned certificateVerify) { MemoryStream buf = new MemoryStream(); certificateVerify.Encode(buf); return buf.ToArray(); }
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); }
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); } }
protected virtual byte[] GenerateCertificateVerify(ClientHandshakeState state, DigitallySigned certificateVerify) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown MemoryStream val = new MemoryStream(); certificateVerify.Encode((Stream)(object)val); return(val.ToArray()); }
public override byte[] GenerateServerKeyExchange() { /* * First we try to find a supported named curve from the client's list. */ int namedCurve = -1; if (mNamedCurves == null) { // TODO Let the peer choose the default named curve namedCurve = NamedCurve.secp256r1; } else { for (int i = 0; i < mNamedCurves.Length; ++i) { int entry = mNamedCurves[i]; if (NamedCurve.IsValid(entry) && TlsEccUtilities.IsSupportedNamedCurve(entry)) { namedCurve = entry; break; } } } ECDomainParameters curve_params = null; if (namedCurve >= 0) { curve_params = TlsEccUtilities.GetParametersForNamedCurve(namedCurve); } else { /* * If no named curves are suitable, check if the client supports explicit curves. */ if (Arrays.Contains(mNamedCurves, NamedCurve.arbitrary_explicit_prime_curves)) { curve_params = TlsEccUtilities.GetParametersForNamedCurve(NamedCurve.secp256r1); } else if (Arrays.Contains(mNamedCurves, NamedCurve.arbitrary_explicit_char2_curves)) { curve_params = TlsEccUtilities.GetParametersForNamedCurve(NamedCurve.sect283r1); } } if (curve_params == null) { /* * NOTE: We shouldn't have negotiated ECDHE key exchange since we apparently can't find * a suitable curve. */ throw new TlsFatalAlert(AlertDescription.internal_error); } AsymmetricCipherKeyPair kp = TlsEccUtilities.GenerateECKeyPair(context.SecureRandom, curve_params); this.mECAgreePrivateKey = (ECPrivateKeyParameters)kp.Private; DigestInputBuffer buf = new DigestInputBuffer(); if (namedCurve < 0) { TlsEccUtilities.WriteExplicitECParameters(mClientECPointFormats, curve_params, buf); } else { TlsEccUtilities.WriteNamedECParameters(namedCurve, buf); } ECPublicKeyParameters ecPublicKey = (ECPublicKeyParameters)kp.Public; TlsEccUtilities.WriteECPoint(mClientECPointFormats, ecPublicKey.Q, buf); /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm; IDigest d; if (TlsUtilities.IsTlsV12(context)) { signatureAndHashAlgorithm = mServerCredentials.SignatureAndHashAlgorithm; if (signatureAndHashAlgorithm == null) throw new TlsFatalAlert(AlertDescription.internal_error); d = TlsUtilities.CreateHash(signatureAndHashAlgorithm.Hash); } else { signatureAndHashAlgorithm = null; d = new CombinedHash(); } SecurityParameters securityParameters = context.SecurityParameters; d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); buf.UpdateDigest(d); byte[] hash = DigestUtilities.DoFinal(d); byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); signed_params.Encode(buf); return buf.ToArray(); }
protected virtual byte[] GenerateCertificateVerify(ClientHandshakeState state, DigitallySigned certificateVerify) { MemoryStream buf = new MemoryStream(); certificateVerify.Encode(buf); return(buf.ToArray()); }
public override byte[] GenerateServerKeyExchange() { mSrpServer.Init(mSrpGroup, mSrpVerifier, TlsUtilities.CreateHash(HashAlgorithm.sha1), mContext.SecureRandom); BigInteger B = mSrpServer.GenerateServerCredentials(); ServerSrpParams srpParams = new ServerSrpParams(mSrpGroup.N, mSrpGroup.G, mSrpSalt, B); DigestInputBuffer buf = new DigestInputBuffer(); srpParams.Encode(buf); if (mServerCredentials != null) { /* * RFC 5246 4.7. digitally-signed element needs SignatureAndHashAlgorithm from TLS 1.2 */ SignatureAndHashAlgorithm signatureAndHashAlgorithm = TlsUtilities.GetSignatureAndHashAlgorithm( mContext, mServerCredentials); IDigest d = TlsUtilities.CreateHash(signatureAndHashAlgorithm); SecurityParameters securityParameters = mContext.SecurityParameters; d.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length); d.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length); buf.UpdateDigest(d); byte[] hash = new byte[d.GetDigestSize()]; d.DoFinal(hash, 0); byte[] signature = mServerCredentials.GenerateCertificateSignature(hash); DigitallySigned signed_params = new DigitallySigned(signatureAndHashAlgorithm, signature); signed_params.Encode(buf); } return buf.ToArray(); }
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)); }
protected virtual byte[] GenerateCertificateVerify(DtlsClientProtocol.ClientHandshakeState state, DigitallySigned certificateVerify) { MemoryStream memoryStream = new MemoryStream(); certificateVerify.Encode(memoryStream); return(memoryStream.ToArray()); }