protected virtual ISigner InitSigner(TlsSigner tlsSigner, SecurityParameters securityParameters)
 {
     ISigner signer = tlsSigner.CreateVerifyer(this.serverPublicKey);
     signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
     signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
     return signer;
 }
 protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm,
     SecurityParameters securityParameters)
 {
     ISigner signer = tlsSigner.CreateVerifyer(algorithm, this.mServerPublicKey);
     signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
     signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
     return signer;
 }
Ejemplo n.º 3
0
        public virtual DtlsTransport Connect(TlsClient client, DatagramTransport transport)
        {
            if (client == null)
                throw new ArgumentNullException("client");
            if (transport == null)
                throw new ArgumentNullException("transport");

            SecurityParameters securityParameters = new SecurityParameters();
            securityParameters.entity = ConnectionEnd.client;

            ClientHandshakeState state = new ClientHandshakeState();
            state.client = client;
            state.clientContext = new TlsClientContextImpl(mSecureRandom, securityParameters);

            securityParameters.clientRandom = TlsProtocol.CreateRandomBlock(client.ShouldUseGmtUnixTime(),
                state.clientContext.NonceRandomGenerator);

            client.Init(state.clientContext);

            DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.clientContext, client, ContentType.handshake);

            TlsSession sessionToResume = state.client.GetSessionToResume();
            if (sessionToResume != null && sessionToResume.IsResumable)
            {
                SessionParameters sessionParameters = sessionToResume.ExportSessionParameters();
                if (sessionParameters != null)
                {
                    state.tlsSession = sessionToResume;
                    state.sessionParameters = sessionParameters;
                }
            }

            try
            {
                return ClientHandshake(state, recordLayer);
            }
            catch (TlsFatalAlert fatalAlert)
            {
                AbortClientHandshake(state, recordLayer, fatalAlert.AlertDescription);
                throw fatalAlert;
            }
            catch (IOException e)
            {
                AbortClientHandshake(state, recordLayer, AlertDescription.internal_error);
                throw e;
            }
            catch (Exception e)
            {
                AbortClientHandshake(state, recordLayer, AlertDescription.internal_error);
                throw new TlsFatalAlert(AlertDescription.internal_error, e);
            }
            finally
            {
                securityParameters.Clear();
            }
        }
       internal AbstractTlsContext(SecureRandom secureRandom, SecurityParameters securityParameters)
        {
            IDigest d = TlsUtilities.CreateHash(HashAlgorithm.sha256);
            byte[] seed = new byte[d.GetDigestSize()];
            secureRandom.NextBytes(seed);

            this.mNonceRandom = new DigestRandomGenerator(d);
            mNonceRandom.AddSeedMaterial(NextCounterValue());
            mNonceRandom.AddSeedMaterial(Times.NanoTime());
            mNonceRandom.AddSeedMaterial(seed);

            this.mSecureRandom = secureRandom;
            this.mSecurityParameters = securityParameters;
        }
Ejemplo n.º 5
0
        public virtual DtlsTransport Accept(TlsServer server, DatagramTransport transport)
        {
            if (server == null)
                throw new ArgumentNullException("server");
            if (transport == null)
                throw new ArgumentNullException("transport");

            SecurityParameters securityParameters = new SecurityParameters();
            securityParameters.entity = ConnectionEnd.server;

            ServerHandshakeState state = new ServerHandshakeState();
            state.server = server;
            state.serverContext = new TlsServerContextImpl(mSecureRandom, securityParameters);

            securityParameters.serverRandom = TlsProtocol.CreateRandomBlock(server.ShouldUseGmtUnixTime(),
                state.serverContext.NonceRandomGenerator);

            server.Init(state.serverContext);

            DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.serverContext, server, ContentType.handshake);

            // TODO Need to handle sending of HelloVerifyRequest without entering a full connection

            try
            {
                return ServerHandshake(state, recordLayer);
            }
            catch (TlsFatalAlert fatalAlert)
            {
                AbortServerHandshake(state, recordLayer, fatalAlert.AlertDescription);
                throw fatalAlert;
            }
            catch (IOException e)
            {
                AbortServerHandshake(state, recordLayer, AlertDescription.internal_error);
                throw e;
            }
            catch (Exception e)
            {
                AbortServerHandshake(state, recordLayer, AlertDescription.internal_error);
                throw new TlsFatalAlert(AlertDescription.internal_error, e);
            }
            finally
            {
                securityParameters.Clear();
            }
        }
Ejemplo n.º 6
0
		internal TlsBlockCipher(TlsProtocolHandler handler, IBlockCipher encryptCipher,
			IBlockCipher decryptCipher, IDigest writeDigest, IDigest readDigest, int cipherKeySize,
			SecurityParameters securityParameters)
		{
			this.handler = handler;
			this.encryptCipher = encryptCipher;
			this.decryptCipher = decryptCipher;
			
			int prfSize = (2 * cipherKeySize) + writeDigest.GetDigestSize()
				+ readDigest.GetDigestSize() + encryptCipher.GetBlockSize()
				+ decryptCipher.GetBlockSize();

			byte[] keyBlock = TlsUtilities.PRF(securityParameters.masterSecret, "key expansion",
				TlsUtilities.Concat(securityParameters.serverRandom, securityParameters.clientRandom),
				prfSize);

			int offset = 0;

			// Init MACs
			writeMac = CreateTlsMac(writeDigest, keyBlock, ref offset);
			readMac = CreateTlsMac(readDigest, keyBlock, ref offset);

			// Build keys
			KeyParameter encryptKey = CreateKeyParameter(keyBlock, ref offset, cipherKeySize);
			KeyParameter decryptKey = CreateKeyParameter(keyBlock, ref offset, cipherKeySize);

			// Add IVs
			ParametersWithIV encryptParams = CreateParametersWithIV(encryptKey,
				keyBlock, ref offset, encryptCipher.GetBlockSize());
			ParametersWithIV decryptParams = CreateParametersWithIV(decryptKey,
				keyBlock, ref offset, decryptCipher.GetBlockSize());

			if (offset != prfSize)
				handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_internal_error);

			// Init Ciphers
			encryptCipher.Init(true, encryptParams);
			decryptCipher.Init(false, decryptParams);
		}
Ejemplo n.º 7
0
        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());
        }
Ejemplo n.º 8
0
        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());
        }
Ejemplo n.º 9
0
        public void ProcessServerKeyExchange(Stream input, SecurityParameters securityParameters)
        {
            if (tlsSigner == null)
            {
                handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_unexpected_message);
            }

            Stream  sigIn  = input;
            ISigner signer = null;

            if (tlsSigner != null)
            {
                signer = InitSigner(tlsSigner, securityParameters);
                sigIn  = new SignerStream(input, signer, null);
            }

            byte[] pBytes  = TlsUtilities.ReadOpaque16(sigIn);
            byte[] gBytes  = TlsUtilities.ReadOpaque16(sigIn);
            byte[] YsBytes = TlsUtilities.ReadOpaque16(sigIn);

            if (signer != null)
            {
                byte[] sigByte = TlsUtilities.ReadOpaque16(input);

                if (!signer.VerifySignature(sigByte))
                {
                    handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_bad_certificate);
                }
            }

            BigInteger p  = new BigInteger(1, pBytes);
            BigInteger g  = new BigInteger(1, gBytes);
            BigInteger Ys = new BigInteger(1, YsBytes);

            this.dhAgreeServerPublicKey = ValidateDHPublicKey(
                new DHPublicKeyParameters(Ys, new DHParameters(p, g)));
        }
Ejemplo n.º 10
0
        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());
        }
Ejemplo n.º 11
0
        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());
        }
Ejemplo n.º 12
0
        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));
        }
Ejemplo n.º 13
0
        public override void ProcessServerKeyExchange(Stream input)
        {
            SecurityParameters securityParameters = context.SecurityParameters;

            ISigner signer = InitSigner(tlsSigner, securityParameters);
            Stream  sigIn  = new SignerStream(input, signer, null);

            byte[] pBytes  = TlsUtilities.ReadOpaque16(sigIn);
            byte[] gBytes  = TlsUtilities.ReadOpaque16(sigIn);
            byte[] YsBytes = TlsUtilities.ReadOpaque16(sigIn);

            byte[] sigByte = TlsUtilities.ReadOpaque16(input);
            if (!signer.VerifySignature(sigByte))
            {
                throw new TlsFatalAlert(AlertDescription.bad_certificate);
            }

            BigInteger p  = new BigInteger(1, pBytes);
            BigInteger g  = new BigInteger(1, gBytes);
            BigInteger Ys = new BigInteger(1, YsBytes);

            this.dhAgreeServerPublicKey = ValidateDHPublicKey(
                new DHPublicKeyParameters(Ys, new DHParameters(p, g)));
        }
Ejemplo n.º 14
0
        public virtual byte[] ExportKeyingMaterial(string asciiLabel, byte[] context_value, int length)
        {
            if (context_value != null && !TlsUtilities.IsValidUint16(context_value.Length))
            {
                throw new ArgumentException("must have length less than 2^16 (or be null)", "context_value");
            }
            SecurityParameters securityParameters = SecurityParameters;

            byte[] clientRandom = securityParameters.ClientRandom;
            byte[] serverRandom = securityParameters.ServerRandom;
            int    num          = clientRandom.Length + serverRandom.Length;

            if (context_value != null)
            {
                num += 2 + context_value.Length;
            }
            byte[] array = new byte[num];
            int    num2  = 0;

            Array.Copy(clientRandom, 0, array, num2, clientRandom.Length);
            num2 += clientRandom.Length;
            Array.Copy(serverRandom, 0, array, num2, serverRandom.Length);
            num2 += serverRandom.Length;
            if (context_value != null)
            {
                TlsUtilities.WriteUint16(context_value.Length, array, num2);
                num2 += 2;
                Array.Copy(context_value, 0, array, num2, context_value.Length);
                num2 += context_value.Length;
            }
            if (num2 != num)
            {
                throw new InvalidOperationException("error in calculation of seed for export");
            }
            return(TlsUtilities.PRF(this, securityParameters.MasterSecret, asciiLabel, array, length));
        }
Ejemplo n.º 15
0
		public void ProcessServerKeyExchange(Stream input, SecurityParameters securityParameters)
		{
			if (tlsSigner == null)
			{
				handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_unexpected_message);
			}

			Stream sigIn = input;
			ISigner signer = null;

			if (tlsSigner != null)
			{
				signer = InitSigner(tlsSigner, securityParameters);
				sigIn = new SignerStream(input, signer, null);
			}

			byte[] pBytes = TlsUtilities.ReadOpaque16(sigIn);
			byte[] gBytes = TlsUtilities.ReadOpaque16(sigIn);
			byte[] YsBytes = TlsUtilities.ReadOpaque16(sigIn);

			if (signer != null)
			{
				byte[] sigByte = TlsUtilities.ReadOpaque16(input);

				if (!signer.VerifySignature(sigByte))
				{
					handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_bad_certificate);
				}
			}

			BigInteger p = new BigInteger(1, pBytes);
			BigInteger g = new BigInteger(1, gBytes);
			BigInteger Ys = new BigInteger(1, YsBytes);

			this.dhAgreeServerPublicKey = ValidateDHPublicKey(
				new DHPublicKeyParameters(Ys, new DHParameters(p, g)));
		}
Ejemplo n.º 16
0
 internal TlsServerContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters)
     : base(secureRandom, securityParameters)
 {
 }
Ejemplo n.º 17
0
        protected virtual void ProcessServerHello(ClientHandshakeState state, byte[] body)
        {
            //IL_000e: Unknown result type (might be due to invalid IL or missing references)
            //IL_0014: Expected O, but got Unknown
            SecurityParameters securityParameters = state.clientContext.SecurityParameters;
            MemoryStream       input          = new MemoryStream(body, false);
            ProtocolVersion    server_version = TlsUtilities.ReadVersion((Stream)(object)input);

            ReportServerVersion(state, server_version);
            securityParameters.serverRandom = TlsUtilities.ReadFully(32, (Stream)(object)input);
            state.selectedSessionID         = TlsUtilities.ReadOpaque8((Stream)(object)input);
            if (state.selectedSessionID.Length > 32)
            {
                throw new TlsFatalAlert(47);
            }
            state.client.NotifySessionID(state.selectedSessionID);
            state.resumedSession = state.selectedSessionID.Length > 0 && state.tlsSession != null && Arrays.AreEqual(state.selectedSessionID, state.tlsSession.SessionID);
            int num = TlsUtilities.ReadUint16((Stream)(object)input);

            if (!Arrays.Contains(state.offeredCipherSuites, num) || num == 0 || CipherSuite.IsScsv(num) || !TlsUtilities.IsValidCipherSuiteForVersion(num, state.clientContext.ServerVersion))
            {
                throw new TlsFatalAlert(47);
            }
            DtlsProtocol.ValidateSelectedCipherSuite(num, 47);
            state.client.NotifySelectedCipherSuite(num);
            byte b = TlsUtilities.ReadUint8((Stream)(object)input);

            if (!Arrays.Contains(state.offeredCompressionMethods, b))
            {
                throw new TlsFatalAlert(47);
            }
            state.client.NotifySelectedCompressionMethod(b);
            state.serverExtensions = TlsProtocol.ReadExtensions(input);
            if (state.serverExtensions != null)
            {
                {
                    global::System.Collections.IEnumerator enumerator = ((global::System.Collections.IEnumerable)state.serverExtensions.get_Keys()).GetEnumerator();
                    try
                    {
                        while (enumerator.MoveNext())
                        {
                            int num2 = (int)enumerator.get_Current();
                            if (num2 != 65281)
                            {
                                if (TlsUtilities.GetExtensionData(state.clientExtensions, num2) == null)
                                {
                                    throw new TlsFatalAlert(110);
                                }
                                _ = state.resumedSession;
                            }
                        }
                    }
                    finally
                    {
                        global::System.IDisposable disposable = enumerator as global::System.IDisposable;
                        if (disposable != null)
                        {
                            disposable.Dispose();
                        }
                    }
                }
            }
            byte[] extensionData = TlsUtilities.GetExtensionData(state.serverExtensions, 65281);
            if (extensionData != null)
            {
                state.secure_renegotiation = true;
                if (!Arrays.ConstantTimeAreEqual(extensionData, TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
                {
                    throw new TlsFatalAlert(40);
                }
            }
            state.client.NotifySecureRenegotiation(state.secure_renegotiation);
            IDictionary val  = state.clientExtensions;
            IDictionary val2 = state.serverExtensions;

            if (state.resumedSession)
            {
                if (num != state.sessionParameters.CipherSuite || b != state.sessionParameters.CompressionAlgorithm)
                {
                    throw new TlsFatalAlert(47);
                }
                val  = null;
                val2 = state.sessionParameters.ReadServerExtensions();
            }
            securityParameters.cipherSuite          = num;
            securityParameters.compressionAlgorithm = b;
            if (val2 != null)
            {
                bool flag = TlsExtensionsUtilities.HasEncryptThenMacExtension(val2);
                if (flag && !TlsUtilities.IsBlockCipherSuite(securityParameters.CipherSuite))
                {
                    throw new TlsFatalAlert(47);
                }
                securityParameters.encryptThenMac       = flag;
                securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(val2);
                securityParameters.maxFragmentLength    = DtlsProtocol.EvaluateMaxFragmentLengthExtension(state.resumedSession, val, val2, 47);
                securityParameters.truncatedHMac        = TlsExtensionsUtilities.HasTruncatedHMacExtension(val2);
                state.allowCertificateStatus            = !state.resumedSession && TlsUtilities.HasExpectedEmptyExtensionData(val2, 5, 47);
                state.expectSessionTicket = !state.resumedSession && TlsUtilities.HasExpectedEmptyExtensionData(val2, 35, 47);
            }
            if (val != null)
            {
                state.client.ProcessServerExtensions(val2);
            }
            securityParameters.prfAlgorithm     = TlsProtocol.GetPrfAlgorithm(state.clientContext, securityParameters.CipherSuite);
            securityParameters.verifyDataLength = 12;
        }
Ejemplo n.º 18
0
		private TlsCipher CreateDesEdeCipher(int cipherKeySize, SecurityParameters securityParameters)
		{
			return new TlsBlockCipher(handler, CreateDesEdeBlockCipher(), CreateDesEdeBlockCipher(),
				new Sha1Digest(), new Sha1Digest(), cipherKeySize, securityParameters);
		}
Ejemplo n.º 19
0
        public virtual DtlsTransport Connect(TlsClient client, DatagramTransport transport)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }
            if (transport == null)
            {
                throw new ArgumentNullException("transport");
            }

            SecurityParameters securityParameters = new SecurityParameters();

            securityParameters.entity = ConnectionEnd.client;

            ClientHandshakeState state = new ClientHandshakeState();

            state.client        = client;
            state.clientContext = new TlsClientContextImpl(mSecureRandom, securityParameters);

            securityParameters.clientRandom = TlsProtocol.CreateRandomBlock(client.ShouldUseGmtUnixTime(),
                                                                            state.clientContext.NonceRandomGenerator);

            client.Init(state.clientContext);

            DtlsRecordLayer recordLayer = new DtlsRecordLayer(transport, state.clientContext, client, ContentType.handshake);

            TlsSession sessionToResume = state.client.GetSessionToResume();

            if (sessionToResume != null && sessionToResume.IsResumable)
            {
                SessionParameters sessionParameters = sessionToResume.ExportSessionParameters();
                if (sessionParameters != null)
                {
                    state.tlsSession        = sessionToResume;
                    state.sessionParameters = sessionParameters;
                }
            }

            try
            {
                return(ClientHandshake(state, recordLayer));
            }
            catch (TlsFatalAlert fatalAlert)
            {
                AbortClientHandshake(state, recordLayer, fatalAlert.AlertDescription);
                throw fatalAlert;
            }
            catch (IOException e)
            {
                AbortClientHandshake(state, recordLayer, AlertDescription.internal_error);
                throw e;
            }
            catch (Exception e)
            {
                AbortClientHandshake(state, recordLayer, AlertDescription.internal_error);
                throw new TlsFatalAlert(AlertDescription.internal_error, e);
            }
            finally
            {
                securityParameters.Clear();
            }
        }
 internal TlsClientContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters)
 {
     this.secureRandom       = secureRandom;
     this.securityParameters = securityParameters;
 }
Ejemplo n.º 21
0
        protected virtual void ProcessServerHello(DtlsClientProtocol.ClientHandshakeState state, byte[] body)
        {
            SecurityParameters securityParameters = state.clientContext.SecurityParameters;
            MemoryStream       input          = new MemoryStream(body, false);
            ProtocolVersion    server_version = TlsUtilities.ReadVersion(input);

            this.ReportServerVersion(state, server_version);
            securityParameters.serverRandom = TlsUtilities.ReadFully(32, input);
            state.selectedSessionID         = TlsUtilities.ReadOpaque8(input);
            if (state.selectedSessionID.Length > 32)
            {
                throw new TlsFatalAlert(47);
            }
            state.client.NotifySessionID(state.selectedSessionID);
            state.resumedSession = (state.selectedSessionID.Length > 0 && state.tlsSession != null && Arrays.AreEqual(state.selectedSessionID, state.tlsSession.SessionID));
            int num = TlsUtilities.ReadUint16(input);

            if (!Arrays.Contains(state.offeredCipherSuites, num) || num == 0 || CipherSuite.IsScsv(num) || !TlsUtilities.IsValidCipherSuiteForVersion(num, state.clientContext.ServerVersion))
            {
                throw new TlsFatalAlert(47);
            }
            DtlsProtocol.ValidateSelectedCipherSuite(num, 47);
            state.client.NotifySelectedCipherSuite(num);
            byte b = TlsUtilities.ReadUint8(input);

            if (!Arrays.Contains(state.offeredCompressionMethods, b))
            {
                throw new TlsFatalAlert(47);
            }
            state.client.NotifySelectedCompressionMethod(b);
            state.serverExtensions = TlsProtocol.ReadExtensions(input);
            if (state.serverExtensions != null)
            {
                foreach (int num2 in state.serverExtensions.Keys)
                {
                    if (num2 != 65281)
                    {
                        if (TlsUtilities.GetExtensionData(state.clientExtensions, num2) == null)
                        {
                            throw new TlsFatalAlert(110);
                        }
                        bool arg_16B_0 = state.resumedSession;
                    }
                }
            }
            byte[] extensionData = TlsUtilities.GetExtensionData(state.serverExtensions, 65281);
            if (extensionData != null)
            {
                state.secure_renegotiation = true;
                if (!Arrays.ConstantTimeAreEqual(extensionData, TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
                {
                    throw new TlsFatalAlert(40);
                }
            }
            state.client.NotifySecureRenegotiation(state.secure_renegotiation);
            IDictionary dictionary  = state.clientExtensions;
            IDictionary dictionary2 = state.serverExtensions;

            if (state.resumedSession)
            {
                if (num != state.sessionParameters.CipherSuite || b != state.sessionParameters.CompressionAlgorithm)
                {
                    throw new TlsFatalAlert(47);
                }
                dictionary  = null;
                dictionary2 = state.sessionParameters.ReadServerExtensions();
            }
            securityParameters.cipherSuite          = num;
            securityParameters.compressionAlgorithm = b;
            if (dictionary2 != null)
            {
                bool flag = TlsExtensionsUtilities.HasEncryptThenMacExtension(dictionary2);
                if (flag && !TlsUtilities.IsBlockCipherSuite(securityParameters.CipherSuite))
                {
                    throw new TlsFatalAlert(47);
                }
                securityParameters.encryptThenMac       = flag;
                securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(dictionary2);
                securityParameters.maxFragmentLength    = DtlsProtocol.EvaluateMaxFragmentLengthExtension(state.resumedSession, dictionary, dictionary2, 47);
                securityParameters.truncatedHMac        = TlsExtensionsUtilities.HasTruncatedHMacExtension(dictionary2);
                state.allowCertificateStatus            = (!state.resumedSession && TlsUtilities.HasExpectedEmptyExtensionData(dictionary2, 5, 47));
                state.expectSessionTicket = (!state.resumedSession && TlsUtilities.HasExpectedEmptyExtensionData(dictionary2, 35, 47));
            }
            if (dictionary != null)
            {
                state.client.ProcessServerExtensions(dictionary2);
            }
            securityParameters.prfAlgorithm     = TlsProtocol.GetPrfAlgorithm(state.clientContext, securityParameters.CipherSuite);
            securityParameters.verifyDataLength = 12;
        }
Ejemplo n.º 22
0
        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));
        }
Ejemplo n.º 23
0
        protected virtual void ProcessClientHello(ServerHandshakeState state, byte[] body)
        {
            //IL_0002: Unknown result type (might be due to invalid IL or missing references)
            //IL_0008: Expected O, but got Unknown
            MemoryStream    input           = new MemoryStream(body, false);
            ProtocolVersion protocolVersion = TlsUtilities.ReadVersion((Stream)(object)input);

            if (!protocolVersion.IsDtls)
            {
                throw new TlsFatalAlert(47);
            }
            byte[] clientRandom = TlsUtilities.ReadFully(32, (Stream)(object)input);
            byte[] array        = TlsUtilities.ReadOpaque8((Stream)(object)input);
            if (array.Length > 32)
            {
                throw new TlsFatalAlert(47);
            }
            TlsUtilities.ReadOpaque8((Stream)(object)input);
            int num = TlsUtilities.ReadUint16((Stream)(object)input);

            if (num < 2 || ((uint)num & (true ? 1u : 0u)) != 0)
            {
                throw new TlsFatalAlert(50);
            }
            state.offeredCipherSuites = TlsUtilities.ReadUint16Array(num / 2, (Stream)(object)input);
            int num2 = TlsUtilities.ReadUint8((Stream)(object)input);

            if (num2 < 1)
            {
                throw new TlsFatalAlert(47);
            }
            state.offeredCompressionMethods = TlsUtilities.ReadUint8Array(num2, (Stream)(object)input);
            state.clientExtensions          = TlsProtocol.ReadExtensions(input);
            TlsServerContextImpl serverContext      = state.serverContext;
            SecurityParameters   securityParameters = serverContext.SecurityParameters;

            securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(state.clientExtensions);
            serverContext.SetClientVersion(protocolVersion);
            state.server.NotifyClientVersion(protocolVersion);
            state.server.NotifyFallback(Arrays.Contains(state.offeredCipherSuites, 22016));
            securityParameters.clientRandom = clientRandom;
            state.server.NotifyOfferedCipherSuites(state.offeredCipherSuites);
            state.server.NotifyOfferedCompressionMethods(state.offeredCompressionMethods);
            if (Arrays.Contains(state.offeredCipherSuites, 255))
            {
                state.secure_renegotiation = true;
            }
            byte[] extensionData = TlsUtilities.GetExtensionData(state.clientExtensions, 65281);
            if (extensionData != null)
            {
                state.secure_renegotiation = true;
                if (!Arrays.ConstantTimeAreEqual(extensionData, TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
                {
                    throw new TlsFatalAlert(40);
                }
            }
            state.server.NotifySecureRenegotiation(state.secure_renegotiation);
            if (state.clientExtensions != null)
            {
                state.server.ProcessClientExtensions(state.clientExtensions);
            }
        }
Ejemplo n.º 24
0
        protected virtual byte[] GenerateServerHello(ServerHandshakeState state)
        {
            //IL_000c: Unknown result type (might be due to invalid IL or missing references)
            //IL_0012: Expected O, but got Unknown
            SecurityParameters securityParameters = state.serverContext.SecurityParameters;
            MemoryStream       val           = new MemoryStream();
            ProtocolVersion    serverVersion = state.server.GetServerVersion();

            if (!serverVersion.IsEqualOrEarlierVersionOf(state.serverContext.ClientVersion))
            {
                throw new TlsFatalAlert(80);
            }
            state.serverContext.SetServerVersion(serverVersion);
            TlsUtilities.WriteVersion(state.serverContext.ServerVersion, (Stream)(object)val);
            ((Stream)val).Write(securityParameters.ServerRandom, 0, securityParameters.ServerRandom.Length);
            TlsUtilities.WriteOpaque8(TlsUtilities.EmptyBytes, (Stream)(object)val);
            int selectedCipherSuite = state.server.GetSelectedCipherSuite();

            if (!Arrays.Contains(state.offeredCipherSuites, selectedCipherSuite) || selectedCipherSuite == 0 || CipherSuite.IsScsv(selectedCipherSuite) || !TlsUtilities.IsValidCipherSuiteForVersion(selectedCipherSuite, state.serverContext.ServerVersion))
            {
                throw new TlsFatalAlert(80);
            }
            DtlsProtocol.ValidateSelectedCipherSuite(selectedCipherSuite, 80);
            securityParameters.cipherSuite = selectedCipherSuite;
            byte selectedCompressionMethod = state.server.GetSelectedCompressionMethod();

            if (!Arrays.Contains(state.offeredCompressionMethods, selectedCompressionMethod))
            {
                throw new TlsFatalAlert(80);
            }
            securityParameters.compressionAlgorithm = selectedCompressionMethod;
            TlsUtilities.WriteUint16(selectedCipherSuite, (Stream)(object)val);
            TlsUtilities.WriteUint8(selectedCompressionMethod, (Stream)(object)val);
            state.serverExtensions = state.server.GetServerExtensions();
            if (state.secure_renegotiation)
            {
                byte[] extensionData = TlsUtilities.GetExtensionData(state.serverExtensions, 65281);
                if (null == extensionData)
                {
                    state.serverExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(state.serverExtensions);
                    state.serverExtensions.set_Item((object)65281, (object)TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes));
                }
            }
            if (securityParameters.extendedMasterSecret)
            {
                state.serverExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(state.serverExtensions);
                TlsExtensionsUtilities.AddExtendedMasterSecretExtension(state.serverExtensions);
            }
            if (state.serverExtensions != null)
            {
                securityParameters.encryptThenMac    = TlsExtensionsUtilities.HasEncryptThenMacExtension(state.serverExtensions);
                securityParameters.maxFragmentLength = DtlsProtocol.EvaluateMaxFragmentLengthExtension(state.resumedSession, state.clientExtensions, state.serverExtensions, 80);
                securityParameters.truncatedHMac     = TlsExtensionsUtilities.HasTruncatedHMacExtension(state.serverExtensions);
                state.allowCertificateStatus         = !state.resumedSession && TlsUtilities.HasExpectedEmptyExtensionData(state.serverExtensions, 5, 80);
                state.expectSessionTicket            = !state.resumedSession && TlsUtilities.HasExpectedEmptyExtensionData(state.serverExtensions, 35, 80);
                TlsProtocol.WriteExtensions((Stream)(object)val, state.serverExtensions);
            }
            securityParameters.prfAlgorithm     = TlsProtocol.GetPrfAlgorithm(state.serverContext, securityParameters.CipherSuite);
            securityParameters.verifyDataLength = 12;
            return(val.ToArray());
        }
Ejemplo n.º 25
0
        protected virtual void ProcessServerHello(ClientHandshakeState state, byte[] body)
        {
            SecurityParameters securityParameters = state.clientContext.SecurityParameters;

            MemoryStream buf = new MemoryStream(body, false);

            {
                ProtocolVersion server_version = TlsUtilities.ReadVersion(buf);
                ReportServerVersion(state, server_version);
            }

            securityParameters.serverRandom = TlsUtilities.ReadFully(32, buf);

            state.selectedSessionID = TlsUtilities.ReadOpaque8(buf);
            if (state.selectedSessionID.Length > 32)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }
            state.client.NotifySessionID(state.selectedSessionID);
            state.resumedSession = state.selectedSessionID.Length > 0 && state.tlsSession != null &&
                                   Arrays.AreEqual(state.selectedSessionID, state.tlsSession.SessionID);

            int selectedCipherSuite = TlsUtilities.ReadUint16(buf);

            if (!Arrays.Contains(state.offeredCipherSuites, selectedCipherSuite) ||
                selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL ||
                CipherSuite.IsScsv(selectedCipherSuite) ||
                !TlsUtilities.IsValidCipherSuiteForVersion(selectedCipherSuite, state.clientContext.ServerVersion))
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }
            ValidateSelectedCipherSuite(selectedCipherSuite, AlertDescription.illegal_parameter);
            state.client.NotifySelectedCipherSuite(selectedCipherSuite);

            byte selectedCompressionMethod = TlsUtilities.ReadUint8(buf);

            if (CompressionMethod.cls_null != selectedCompressionMethod)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }
            state.client.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.
             */

            // Integer -> byte[]
            state.serverExtensions = TlsProtocol.ReadExtensions(buf);

            /*
             * RFC 7627 4. Clients and servers SHOULD NOT accept handshakes that do not use the extended
             * master secret [..]. (and see 5.2, 5.3)
             */
            securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(state.serverExtensions);

            if (!securityParameters.IsExtendedMasterSecret &&
                (state.resumedSession || state.client.RequiresExtendedMasterSecret()))
            {
                throw new TlsFatalAlert(AlertDescription.handshake_failure);
            }

            /*
             * RFC 3546 2.2 Note that the extended server hello message is only sent in response to an
             * extended client hello message. However, see RFC 5746 exception below. We always include
             * the SCSV, so an Extended Server Hello is always allowed.
             */
            if (state.serverExtensions != null)
            {
                foreach (int extType in state.serverExtensions.Keys)
                {
                    /*
                     * RFC 5746 3.6. Note that sending a "renegotiation_info" extension in response to a
                     * ClientHello containing only the SCSV is an explicit exception to the prohibition
                     * in RFC 5246, Section 7.4.1.4, on the server sending unsolicited extensions and is
                     * only allowed because the client is signaling its willingness to receive the
                     * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV.
                     */
                    if (extType == ExtensionType.renegotiation_info)
                    {
                        continue;
                    }

                    /*
                     * RFC 5246 7.4.1.4 An extension type MUST NOT appear in the ServerHello unless the
                     * same extension type appeared in the corresponding ClientHello. If a client
                     * receives an extension type in ServerHello that it did not request in the
                     * associated ClientHello, it MUST abort the handshake with an unsupported_extension
                     * fatal alert.
                     */
                    if (null == TlsUtilities.GetExtensionData(state.clientExtensions, extType))
                    {
                        throw new TlsFatalAlert(AlertDescription.unsupported_extension);
                    }

                    /*
                     * 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[.]
                     */
                    if (state.resumedSession)
                    {
                        // TODO[compat-gnutls] GnuTLS test server sends server extensions e.g. ec_point_formats
                        // TODO[compat-openssl] OpenSSL test server sends server extensions e.g. ec_point_formats
                        // TODO[compat-polarssl] PolarSSL test server sends server extensions e.g. ec_point_formats
                        //throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                    }
                }
            }

            /*
             * RFC 5746 3.4. Client Behavior: Initial Handshake
             */
            {
                /*
                 * When a ServerHello is received, the client MUST check if it includes the
                 * "renegotiation_info" extension:
                 */
                byte[] renegExtData = TlsUtilities.GetExtensionData(state.serverExtensions, ExtensionType.renegotiation_info);
                if (renegExtData != null)
                {
                    /*
                     * 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).
                     */
                    state.secure_renegotiation = true;

                    if (!Arrays.ConstantTimeAreEqual(renegExtData, TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
                    {
                        throw new TlsFatalAlert(AlertDescription.handshake_failure);
                    }
                }
            }

            // TODO[compat-gnutls] GnuTLS test server fails to send renegotiation_info extension when resuming
            state.client.NotifySecureRenegotiation(state.secure_renegotiation);

            IDictionary sessionClientExtensions = state.clientExtensions, sessionServerExtensions = state.serverExtensions;

            if (state.resumedSession)
            {
                if (selectedCipherSuite != state.sessionParameters.CipherSuite ||
                    selectedCompressionMethod != state.sessionParameters.CompressionAlgorithm)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                sessionClientExtensions = null;
                sessionServerExtensions = state.sessionParameters.ReadServerExtensions();
            }

            securityParameters.cipherSuite          = selectedCipherSuite;
            securityParameters.compressionAlgorithm = selectedCompressionMethod;

            if (sessionServerExtensions != null && sessionServerExtensions.Count > 0)
            {
                {
                    /*
                     * RFC 7366 3. If a server receives an encrypt-then-MAC request extension from a client
                     * and then selects a stream or Authenticated Encryption with Associated Data (AEAD)
                     * ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the
                     * client.
                     */
                    bool serverSentEncryptThenMAC = TlsExtensionsUtilities.HasEncryptThenMacExtension(sessionServerExtensions);
                    if (serverSentEncryptThenMAC && !TlsUtilities.IsBlockCipherSuite(securityParameters.CipherSuite))
                    {
                        throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                    }
                    securityParameters.encryptThenMac = serverSentEncryptThenMAC;
                }

                securityParameters.maxFragmentLength = EvaluateMaxFragmentLengthExtension(state.resumedSession,
                                                                                          sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter);

                securityParameters.truncatedHMac = TlsExtensionsUtilities.HasTruncatedHMacExtension(sessionServerExtensions);

                /*
                 * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be
                 * sent in a session resumption handshake.
                 */
                state.allowCertificateStatus = !state.resumedSession &&
                                               TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, ExtensionType.status_request,
                                                                                          AlertDescription.illegal_parameter);

                state.expectSessionTicket = !state.resumedSession &&
                                            TlsUtilities.HasExpectedEmptyExtensionData(sessionServerExtensions, ExtensionType.session_ticket,
                                                                                       AlertDescription.illegal_parameter);
            }

            if (sessionClientExtensions != null)
            {
                state.client.ProcessServerExtensions(sessionServerExtensions);
            }

            securityParameters.prfAlgorithm = TlsProtocol.GetPrfAlgorithm(state.clientContext,
                                                                          securityParameters.CipherSuite);

            /*
             * RFC 5246 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;
        }
Ejemplo n.º 26
0
        protected virtual byte[] GenerateClientHello(ClientHandshakeState state, TlsClient client)
        {
            ProtocolVersion client_version = client.ClientVersion;

            if (!client_version.IsDtls)
            {
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            TlsClientContextImpl context = state.clientContext;

            context.SetClientVersion(client_version);

            SecurityParameters securityParameters = context.SecurityParameters;

            // Session ID
            byte[] session_id = TlsUtilities.EmptyBytes;
            if (state.tlsSession != null)
            {
                session_id = state.tlsSession.SessionID;
                if (session_id == null || session_id.Length > 32)
                {
                    session_id = TlsUtilities.EmptyBytes;
                }
            }

            bool fallback = client.IsFallback;

            state.offeredCipherSuites = client.GetCipherSuites();

            if (session_id.Length > 0 && state.sessionParameters != null)
            {
                if (!state.sessionParameters.IsExtendedMasterSecret ||
                    !Arrays.Contains(state.offeredCipherSuites, state.sessionParameters.CipherSuite) ||
                    CompressionMethod.cls_null != state.sessionParameters.CompressionAlgorithm)
                {
                    session_id = TlsUtilities.EmptyBytes;
                }
            }

            state.clientExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(client.GetClientExtensions());

            TlsExtensionsUtilities.AddExtendedMasterSecretExtension(state.clientExtensions);

            MemoryStream buf = new MemoryStream();

            TlsUtilities.WriteVersion(client_version, buf);

            buf.Write(securityParameters.ClientRandom, 0, securityParameters.ClientRandom.Length);

            TlsUtilities.WriteOpaque8(session_id, buf);

            // Cookie
            TlsUtilities.WriteOpaque8(TlsUtilities.EmptyBytes, buf);

            // Cipher Suites (and SCSV)
            {
                /*
                 * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension,
                 * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the
                 * ClientHello. Including both is NOT RECOMMENDED.
                 */
                byte[] renegExtData = TlsUtilities.GetExtensionData(state.clientExtensions, ExtensionType.renegotiation_info);
                bool   noRenegExt   = (null == renegExtData);

                bool noRenegSCSV = !Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV);

                if (noRenegExt && noRenegSCSV)
                {
                    // TODO Consider whether to default to a client extension instead
                    state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
                }

                /*
                 * RFC 7507 4. If a client sends a ClientHello.client_version containing a lower value
                 * than the latest (highest-valued) version supported by the client, it SHOULD include
                 * the TLS_FALLBACK_SCSV cipher suite value in ClientHello.cipher_suites [..]. (The
                 * client SHOULD put TLS_FALLBACK_SCSV after all cipher suites that it actually intends
                 * to negotiate.)
                 */
                if (fallback && !Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV))
                {
                    state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV);
                }

                TlsUtilities.WriteUint16ArrayWithUint16Length(state.offeredCipherSuites, buf);
            }

            TlsUtilities.WriteUint8ArrayWithUint8Length(new byte[] { CompressionMethod.cls_null }, buf);

            TlsProtocol.WriteExtensions(buf, state.clientExtensions);

            return(buf.ToArray());
        }
Ejemplo n.º 27
0
        protected virtual ISigner InitVerifyer(TlsSigner tlsSigner, SignatureAndHashAlgorithm algorithm, SecurityParameters securityParameters)
        {
            ISigner signer = tlsSigner.CreateVerifyer(algorithm, mServerPublicKey);

            signer.BlockUpdate(securityParameters.clientRandom, 0, securityParameters.clientRandom.Length);
            signer.BlockUpdate(securityParameters.serverRandom, 0, securityParameters.serverRandom.Length);
            return(signer);
        }
Ejemplo n.º 28
0
//    public void Connect(ICertificateVerifyer verifyer, Certificate clientCertificate,
//        AsymmetricKeyParameter clientPrivateKey)
//    {
//        DefaultTlsClient client = new DefaultTlsClient(verifyer);
//        client.EnableClientAuthentication(clientCertificate, clientPrivateKey);
//
//        this.Connect(client);
//    }

		// TODO Make public
		internal virtual void Connect(TlsClient tlsClient)
		{
			if (tlsClient == null)
				throw new ArgumentNullException("tlsClient");
			if (this.tlsClient != null)
				throw new InvalidOperationException("Connect can only be called once");

			this.tlsClient = tlsClient;
			this.tlsClient.Init(this);

			/*
			 * Send Client hello
			 *
			 * First, generate some random data.
			 */
			securityParameters = new SecurityParameters();
			securityParameters.clientRandom = new byte[32];
			random.NextBytes(securityParameters.clientRandom, 4, 28);
			TlsUtilities.WriteGmtUnixTime(securityParameters.clientRandom, 0);

			MemoryStream outStr = new MemoryStream();
			TlsUtilities.WriteVersion(outStr);
			outStr.Write(securityParameters.clientRandom, 0, 32);

			/*
			* Length of Session id
			*/
			TlsUtilities.WriteUint8((short)0, outStr);

			/*
			* Cipher suites
			*/
			this.offeredCipherSuites = this.tlsClient.GetCipherSuites();

			// Note: 1 extra slot for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
			TlsUtilities.WriteUint16(2 * (offeredCipherSuites.Length + 1), outStr);
			for (int i = 0; i < offeredCipherSuites.Length; ++i)
			{
				TlsUtilities.WriteUint16(offeredCipherSuites[i], outStr);
			}

			// RFC 5746 3.3
			// Note: If renegotiation added, remove this (and extra slot above)
			TlsUtilities.WriteUint16(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, outStr);

			/*
			* Compression methods, just the null method.
			*/
			byte[] compressionMethods = new byte[]{0x00};
			TlsUtilities.WriteOpaque8(compressionMethods, outStr);

			/*
			* Extensions
			*/
			// Int32 -> byte[]
			Hashtable clientExtensions = this.tlsClient.GenerateClientExtensions();

			// RFC 5746 3.4
			// Note: If renegotiation is implemented, need to use this instead of TLS_EMPTY_RENEGOTIATION_INFO_SCSV
//			{
//				if (clientExtensions == null)
//					clientExtensions = new Hashtable();
//
//				clientExtensions[EXT_RenegotiationInfo] = CreateRenegotiationInfo(emptybuf);
//			}

			this.extendedClientHello = clientExtensions != null && clientExtensions.Count > 0;

			if (extendedClientHello)
			{
				MemoryStream ext = new MemoryStream();
				foreach (int extType in clientExtensions.Keys)
				{
					byte[] extValue = (byte[])clientExtensions[extType];

					TlsUtilities.WriteUint16(extType, ext);
					TlsUtilities.WriteOpaque16(extValue, ext);
				}

				TlsUtilities.WriteOpaque16(ext.ToArray(), outStr);
			}

			MemoryStream bos = new MemoryStream();
			TlsUtilities.WriteUint8(HP_CLIENT_HELLO, bos);
			TlsUtilities.WriteUint24((int) outStr.Length, bos);
			byte[] outBytes = outStr.ToArray();
			bos.Write(outBytes, 0, outBytes.Length);
			byte[] message = bos.ToArray();
			rs.WriteMessage(RL_HANDSHAKE, message, 0, message.Length);
			connection_state = CS_CLIENT_HELLO_SEND;

			/*
			* We will now read data, until we have completed the handshake.
			*/
			while (connection_state != CS_DONE)
			{
				// TODO Should we send fatal alerts in the event of an exception
				// (see readApplicationData) 
				rs.ReadData();
			}

			this.tlsStream = new TlsStream(this);
		}
Ejemplo n.º 29
0
        protected virtual void ProcessClientHello(ServerHandshakeState state, byte[] body)
        {
            MemoryStream buf = new MemoryStream(body, false);

            // TODO Read RFCs for guidance on the expected record layer version number
            ProtocolVersion client_version = TlsUtilities.ReadVersion(buf);

            if (!client_version.IsDtls)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            /*
             * Read the client random
             */
            byte[] client_random = TlsUtilities.ReadFully(32, buf);

            byte[] sessionID = TlsUtilities.ReadOpaque8(buf);
            if (sessionID.Length > 32)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            // TODO RFC 4347 has the cookie length restricted to 32, but not in RFC 6347
            byte[] cookie = TlsUtilities.ReadOpaque8(buf);

            int cipher_suites_length = TlsUtilities.ReadUint16(buf);

            if (cipher_suites_length < 2 || (cipher_suites_length & 1) != 0)
            {
                throw new TlsFatalAlert(AlertDescription.decode_error);
            }

            /*
             * NOTE: "If the session_id field is not empty (implying a session resumption request) this
             * vector must include at least the cipher_suite from that session."
             */
            state.offeredCipherSuites = TlsUtilities.ReadUint16Array(cipher_suites_length / 2, buf);

            int compression_methods_length = TlsUtilities.ReadUint8(buf);

            if (compression_methods_length < 1)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            state.offeredCompressionMethods = TlsUtilities.ReadUint8Array(compression_methods_length, buf);

            /*
             * 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.
             */
            state.clientExtensions = TlsProtocol.ReadExtensions(buf);

            TlsServerContextImpl context            = state.serverContext;
            SecurityParameters   securityParameters = context.SecurityParameters;

            /*
             * TODO[session-hash]
             *
             * draft-ietf-tls-session-hash-04 4. Clients and servers SHOULD NOT accept handshakes
             * that do not use the extended master secret [..]. (and see 5.2, 5.3)
             */
            securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(state.clientExtensions);

            context.SetClientVersion(client_version);

            state.server.NotifyClientVersion(client_version);
            state.server.NotifyFallback(Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV));

            securityParameters.clientRandom = client_random;

            state.server.NotifyOfferedCipherSuites(state.offeredCipherSuites);
            state.server.NotifyOfferedCompressionMethods(state.offeredCompressionMethods);

            /*
             * RFC 5746 3.6. Server Behavior: Initial Handshake
             */
            {
                /*
                 * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension,
                 * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the
                 * ClientHello. Including both is NOT RECOMMENDED.
                 */

                /*
                 * When a ClientHello is received, the server MUST check if it includes the
                 * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. If it does, set the secure_renegotiation flag
                 * to TRUE.
                 */
                if (Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV))
                {
                    state.secure_renegotiation = true;
                }

                /*
                 * The server MUST check if the "renegotiation_info" extension is included in the
                 * ClientHello.
                 */
                byte[] renegExtData = TlsUtilities.GetExtensionData(state.clientExtensions, ExtensionType.renegotiation_info);
                if (renegExtData != null)
                {
                    /*
                     * If the extension is present, set secure_renegotiation flag to TRUE. The
                     * server MUST then verify that the length of the "renegotiated_connection"
                     * field is zero, and if it is not, MUST abort the handshake.
                     */
                    state.secure_renegotiation = true;

                    if (!Arrays.ConstantTimeAreEqual(renegExtData, TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
                    {
                        throw new TlsFatalAlert(AlertDescription.handshake_failure);
                    }
                }
            }

            state.server.NotifySecureRenegotiation(state.secure_renegotiation);

            if (state.clientExtensions != null)
            {
                // NOTE: Validates the padding extension data, if present
                TlsExtensionsUtilities.GetPaddingExtension(state.clientExtensions);

                state.server.ProcessClientExtensions(state.clientExtensions);
            }
        }
Ejemplo n.º 30
0
 internal TlsClientContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters)
     :   base(secureRandom, securityParameters)
 {
 }
Ejemplo n.º 31
0
 internal TlsClientContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters)
     :   base(secureRandom, securityParameters)
 {
 }
Ejemplo n.º 32
0
        protected virtual void ProcessServerHello(ClientHandshakeState state, byte[] body)
        {
            SecurityParameters securityParameters = state.clientContext.SecurityParameters;

            MemoryStream buf = new MemoryStream(body, false);

            ProtocolVersion server_version = TlsUtilities.ReadVersion(buf);

            ReportServerVersion(state, server_version);

            securityParameters.serverRandom = TlsUtilities.ReadFully(32, buf);

            state.selectedSessionID = TlsUtilities.ReadOpaque8(buf);
            if (state.selectedSessionID.Length > 32)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }
            state.client.NotifySessionID(state.selectedSessionID);

            state.selectedCipherSuite = TlsUtilities.ReadUint16(buf);
            if (!Arrays.Contains(state.offeredCipherSuites, state.selectedCipherSuite) ||
                state.selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL ||
                CipherSuite.IsScsv(state.selectedCipherSuite) ||
                !TlsUtilities.IsValidCipherSuiteForVersion(state.selectedCipherSuite, server_version))
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            ValidateSelectedCipherSuite(state.selectedCipherSuite, AlertDescription.illegal_parameter);

            state.client.NotifySelectedCipherSuite(state.selectedCipherSuite);

            state.selectedCompressionMethod = TlsUtilities.ReadUint8(buf);
            if (!Arrays.Contains(state.offeredCompressionMethods, (byte)state.selectedCompressionMethod))
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }
            state.client.NotifySelectedCompressionMethod((byte)state.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.
             */

            // Integer -> byte[]
            IDictionary serverExtensions = TlsProtocol.ReadExtensions(buf);

            /*
             * draft-ietf-tls-session-hash-01 5.2. If a server receives the "extended_master_secret"
             * extension, it MUST include the "extended_master_secret" extension in its ServerHello
             * message.
             */
            bool serverSentExtendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(serverExtensions);

            if (serverSentExtendedMasterSecret != securityParameters.extendedMasterSecret)
            {
                throw new TlsFatalAlert(AlertDescription.handshake_failure);
            }

            /*
             * RFC 3546 2.2 Note that the extended server hello message is only sent in response to an
             * extended client hello message. However, see RFC 5746 exception below. We always include
             * the SCSV, so an Extended Server Hello is always allowed.
             */
            if (serverExtensions != null)
            {
                foreach (int extType in serverExtensions.Keys)
                {
                    /*
                     * RFC 5746 3.6. Note that sending a "renegotiation_info" extension in response to a
                     * ClientHello containing only the SCSV is an explicit exception to the prohibition
                     * in RFC 5246, Section 7.4.1.4, on the server sending unsolicited extensions and is
                     * only allowed because the client is signaling its willingness to receive the
                     * extension via the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV.
                     */
                    if (extType == ExtensionType.renegotiation_info)
                    {
                        continue;
                    }

                    /*
                     * RFC 5246 7.4.1.4 An extension type MUST NOT appear in the ServerHello unless the
                     * same extension type appeared in the corresponding ClientHello. If a client
                     * receives an extension type in ServerHello that it did not request in the
                     * associated ClientHello, it MUST abort the handshake with an unsupported_extension
                     * fatal alert.
                     */
                    if (null == TlsUtilities.GetExtensionData(state.clientExtensions, extType))
                    {
                        throw new TlsFatalAlert(AlertDescription.unsupported_extension);
                    }

                    /*
                     * draft-ietf-tls-session-hash-01 5.2. Implementation note: if the server decides to
                     * proceed with resumption, the extension does not have any effect. Requiring the
                     * extension to be included anyway makes the extension negotiation logic easier,
                     * because it does not depend on whether resumption is accepted or not.
                     */
                    if (extType == ExtensionType.extended_master_secret)
                    {
                        continue;
                    }

                    /*
                     * 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[.]
                     */
                    // TODO[sessions]
                    //                if (this.mResumedSession)
                    //                {
                    //                    // TODO[compat-gnutls] GnuTLS test server sends server extensions e.g. ec_point_formats
                    //                    // TODO[compat-openssl] OpenSSL test server sends server extensions e.g. ec_point_formats
                    //                    // TODO[compat-polarssl] PolarSSL test server sends server extensions e.g. ec_point_formats
                    ////                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                    //                }
                }

                /*
                 * RFC 5746 3.4. Client Behavior: Initial Handshake
                 */
                {
                    /*
                     * When a ServerHello is received, the client MUST check if it includes the
                     * "renegotiation_info" extension:
                     */
                    byte[] renegExtData = (byte[])serverExtensions[ExtensionType.renegotiation_info];
                    if (renegExtData != null)
                    {
                        /*
                         * 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).
                         */
                        state.secure_renegotiation = true;

                        if (!Arrays.ConstantTimeAreEqual(renegExtData, TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes)))
                        {
                            throw new TlsFatalAlert(AlertDescription.handshake_failure);
                        }
                    }
                }

                /*
                 * RFC 7366 3. If a server receives an encrypt-then-MAC request extension from a client
                 * and then selects a stream or Authenticated Encryption with Associated Data (AEAD)
                 * ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the
                 * client.
                 */
                bool serverSentEncryptThenMAC = TlsExtensionsUtilities.HasEncryptThenMacExtension(serverExtensions);
                if (serverSentEncryptThenMAC && !TlsUtilities.IsBlockCipherSuite(state.selectedCipherSuite))
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                securityParameters.encryptThenMac = serverSentEncryptThenMAC;

                state.maxFragmentLength = EvaluateMaxFragmentLengthExtension(state.clientExtensions, serverExtensions,
                                                                             AlertDescription.illegal_parameter);

                securityParameters.truncatedHMac = TlsExtensionsUtilities.HasTruncatedHMacExtension(serverExtensions);

                state.allowCertificateStatus = TlsUtilities.HasExpectedEmptyExtensionData(serverExtensions,
                                                                                          ExtensionType.status_request, AlertDescription.illegal_parameter);

                state.expectSessionTicket = TlsUtilities.HasExpectedEmptyExtensionData(serverExtensions,
                                                                                       ExtensionType.session_ticket, AlertDescription.illegal_parameter);
            }

            state.client.NotifySecureRenegotiation(state.secure_renegotiation);

            if (state.clientExtensions != null)
            {
                state.client.ProcessServerExtensions(serverExtensions);
            }
        }
Ejemplo n.º 33
0
		public TlsCipher CreateCipher(SecurityParameters securityParameters)
		{
			switch (selectedCipherSuite)
			{
				case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
				case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
				case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
				case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
				case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
				case TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA:
				case TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA:
				case TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA:
					return CreateDesEdeCipher(24, securityParameters);
				
				case TLS_RSA_WITH_AES_128_CBC_SHA:
				case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
				case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
				case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
				case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
				case TLS_SRP_SHA_WITH_AES_128_CBC_SHA:
				case TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA:
				case TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA:
					return CreateAesCipher(16, securityParameters);
				
				case TLS_RSA_WITH_AES_256_CBC_SHA:
				case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
				case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
				case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
				case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
				case TLS_SRP_SHA_WITH_AES_256_CBC_SHA:
				case TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA:
				case TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA:
					return CreateAesCipher(32, securityParameters);
				
				default:
					/*
					* Note: internal error here; the TlsProtocolHandler verifies that the
					* server-selected cipher suite was in the list of client-offered cipher
					* suites, so if we now can't produce an implementation, we shouldn't have
					* offered it!
					*/
					handler.FailWithError(TlsProtocolHandler.AL_fatal,
						TlsProtocolHandler.AP_internal_error);
					return null; // Unreachable!
			}
		}
Ejemplo n.º 34
0
        protected virtual byte[] GenerateServerHello(ServerHandshakeState state)
        {
            SecurityParameters securityParameters = state.serverContext.SecurityParameters;

            MemoryStream buf = new MemoryStream();

            {
                ProtocolVersion server_version = state.server.GetServerVersion();
                if (!server_version.IsEqualOrEarlierVersionOf(state.serverContext.ClientVersion))
                {
                    throw new TlsFatalAlert(AlertDescription.internal_error);
                }

                // TODO Read RFCs for guidance on the expected record layer version number
                // recordStream.setReadVersion(server_version);
                // recordStream.setWriteVersion(server_version);
                // recordStream.setRestrictReadVersion(true);
                state.serverContext.SetServerVersion(server_version);

                TlsUtilities.WriteVersion(state.serverContext.ServerVersion, buf);
            }

            buf.Write(securityParameters.ServerRandom, 0, securityParameters.ServerRandom.Length);

            /*
             * The server may return an empty session_id to indicate that the session will not be cached
             * and therefore cannot be resumed.
             */
            TlsUtilities.WriteOpaque8(TlsUtilities.EmptyBytes, buf);

            int selectedCipherSuite = state.server.GetSelectedCipherSuite();

            if (!Arrays.Contains(state.offeredCipherSuites, selectedCipherSuite) ||
                selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL ||
                CipherSuite.IsScsv(selectedCipherSuite) ||
                !TlsUtilities.IsValidCipherSuiteForVersion(selectedCipherSuite, state.serverContext.ServerVersion))
            {
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }
            ValidateSelectedCipherSuite(selectedCipherSuite, AlertDescription.internal_error);
            securityParameters.cipherSuite = selectedCipherSuite;

            byte selectedCompressionMethod = state.server.GetSelectedCompressionMethod();

            if (!Arrays.Contains(state.offeredCompressionMethods, selectedCompressionMethod))
            {
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }
            securityParameters.compressionAlgorithm = selectedCompressionMethod;

            TlsUtilities.WriteUint16(selectedCipherSuite, buf);
            TlsUtilities.WriteUint8(selectedCompressionMethod, buf);

            state.serverExtensions = state.server.GetServerExtensions();

            /*
             * RFC 5746 3.6. Server Behavior: Initial Handshake
             */
            if (state.secure_renegotiation)
            {
                byte[] renegExtData = TlsUtilities.GetExtensionData(state.serverExtensions, ExtensionType.renegotiation_info);
                bool   noRenegExt   = (null == renegExtData);

                if (noRenegExt)
                {
                    /*
                     * Note that sending a "renegotiation_info" extension in response to a ClientHello
                     * containing only the SCSV is an explicit exception to the prohibition in RFC 5246,
                     * Section 7.4.1.4, on the server sending unsolicited extensions and is only allowed
                     * because the client is signaling its willingness to receive the extension via the
                     * TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV.
                     */

                    /*
                     * If the secure_renegotiation flag is set to TRUE, the server MUST include an empty
                     * "renegotiation_info" extension in the ServerHello message.
                     */
                    state.serverExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(state.serverExtensions);
                    state.serverExtensions[ExtensionType.renegotiation_info] = TlsProtocol.CreateRenegotiationInfo(TlsUtilities.EmptyBytes);
                }
            }

            if (securityParameters.extendedMasterSecret)
            {
                state.serverExtensions = TlsExtensionsUtilities.EnsureExtensionsInitialised(state.serverExtensions);
                TlsExtensionsUtilities.AddExtendedMasterSecretExtension(state.serverExtensions);
            }

            /*
             * 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.
             */

            if (state.serverExtensions != null)
            {
                securityParameters.encryptThenMac = TlsExtensionsUtilities.HasEncryptThenMacExtension(state.serverExtensions);

                securityParameters.maxFragmentLength = EvaluateMaxFragmentLengthExtension(state.resumedSession,
                                                                                          state.clientExtensions, state.serverExtensions, AlertDescription.internal_error);

                securityParameters.truncatedHMac = TlsExtensionsUtilities.HasTruncatedHMacExtension(state.serverExtensions);

                /*
                 * TODO It's surprising that there's no provision to allow a 'fresh' CertificateStatus to be sent in
                 * a session resumption handshake.
                 */
                state.allowCertificateStatus = !state.resumedSession &&
                                               TlsUtilities.HasExpectedEmptyExtensionData(state.serverExtensions, ExtensionType.status_request,
                                                                                          AlertDescription.internal_error);

                state.expectSessionTicket = !state.resumedSession &&
                                            TlsUtilities.HasExpectedEmptyExtensionData(state.serverExtensions, ExtensionType.session_ticket,
                                                                                       AlertDescription.internal_error);

                TlsProtocol.WriteExtensions(buf, state.serverExtensions);
            }

            securityParameters.prfAlgorithm = TlsProtocol.GetPrfAlgorithm(state.serverContext,
                                                                          securityParameters.CipherSuite);

            /*
             * RFC 5246 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;

            return(buf.ToArray());
        }
 internal TlsServerContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters)
     : base(secureRandom, securityParameters)
 {
 }
Ejemplo n.º 36
0
        internal virtual DtlsTransport ServerHandshake(ServerHandshakeState state, DtlsRecordLayer recordLayer)
        {
            SecurityParameters    securityParameters = state.serverContext.SecurityParameters;
            DtlsReliableHandshake handshake          = new DtlsReliableHandshake(state.serverContext, recordLayer);

            DtlsReliableHandshake.Message clientMessage = handshake.ReceiveMessage();

            // NOTE: DTLSRecordLayer requires any DTLS version, we don't otherwise constrain this
            //ProtocolVersion recordLayerVersion = recordLayer.ReadVersion;

            if (clientMessage.Type == HandshakeType.client_hello)
            {
                ProcessClientHello(state, clientMessage.Body);
            }
            else
            {
                throw new TlsFatalAlert(AlertDescription.unexpected_message);
            }

            {
                byte[] serverHelloBody = GenerateServerHello(state);

                ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength);

                ProtocolVersion recordLayerVersion = state.serverContext.ServerVersion;
                recordLayer.ReadVersion = recordLayerVersion;
                recordLayer.SetWriteVersion(recordLayerVersion);

                handshake.SendMessage(HandshakeType.server_hello, serverHelloBody);
            }

            handshake.NotifyHelloComplete();

            IList serverSupplementalData = state.server.GetServerSupplementalData();

            if (serverSupplementalData != null)
            {
                byte[] supplementalDataBody = GenerateSupplementalData(serverSupplementalData);
                handshake.SendMessage(HandshakeType.supplemental_data, supplementalDataBody);
            }

            state.keyExchange = state.server.GetKeyExchange();
            state.keyExchange.Init(state.serverContext);

            state.serverCredentials = state.server.GetCredentials();

            Certificate serverCertificate = null;

            if (state.serverCredentials == null)
            {
                state.keyExchange.SkipServerCredentials();
            }
            else
            {
                state.keyExchange.ProcessServerCredentials(state.serverCredentials);

                serverCertificate = state.serverCredentials.Certificate;
                byte[] certificateBody = GenerateCertificate(serverCertificate);
                handshake.SendMessage(HandshakeType.certificate, certificateBody);
            }

            // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes CertificateStatus
            if (serverCertificate == null || serverCertificate.IsEmpty)
            {
                state.allowCertificateStatus = false;
            }

            if (state.allowCertificateStatus)
            {
                CertificateStatus certificateStatus = state.server.GetCertificateStatus();
                if (certificateStatus != null)
                {
                    byte[] certificateStatusBody = GenerateCertificateStatus(state, certificateStatus);
                    handshake.SendMessage(HandshakeType.certificate_status, certificateStatusBody);
                }
            }

            byte[] serverKeyExchange = state.keyExchange.GenerateServerKeyExchange();
            if (serverKeyExchange != null)
            {
                handshake.SendMessage(HandshakeType.server_key_exchange, serverKeyExchange);
            }

            if (state.serverCredentials != null)
            {
                state.certificateRequest = state.server.GetCertificateRequest();
                if (state.certificateRequest != null)
                {
                    if (TlsUtilities.IsTlsV12(state.serverContext) != (state.certificateRequest.SupportedSignatureAlgorithms != null))
                    {
                        throw new TlsFatalAlert(AlertDescription.internal_error);
                    }

                    state.keyExchange.ValidateCertificateRequest(state.certificateRequest);

                    byte[] certificateRequestBody = GenerateCertificateRequest(state, state.certificateRequest);
                    handshake.SendMessage(HandshakeType.certificate_request, certificateRequestBody);

                    TlsUtilities.TrackHashAlgorithms(handshake.HandshakeHash,
                                                     state.certificateRequest.SupportedSignatureAlgorithms);
                }
            }

            handshake.SendMessage(HandshakeType.server_hello_done, TlsUtilities.EmptyBytes);

            handshake.HandshakeHash.SealHashAlgorithms();

            clientMessage = handshake.ReceiveMessage();

            if (clientMessage.Type == HandshakeType.supplemental_data)
            {
                ProcessClientSupplementalData(state, clientMessage.Body);
                clientMessage = handshake.ReceiveMessage();
            }
            else
            {
                state.server.ProcessClientSupplementalData(null);
            }

            if (state.certificateRequest == null)
            {
                state.keyExchange.SkipClientCredentials();
            }
            else
            {
                if (clientMessage.Type == HandshakeType.certificate)
                {
                    ProcessClientCertificate(state, clientMessage.Body);
                    clientMessage = handshake.ReceiveMessage();
                }
                else
                {
                    if (TlsUtilities.IsTlsV12(state.serverContext))
                    {
                        /*
                         * RFC 5246 If no suitable certificate is available, the client MUST send a
                         * certificate message containing no certificates.
                         *
                         * NOTE: In previous RFCs, this was SHOULD instead of MUST.
                         */
                        throw new TlsFatalAlert(AlertDescription.unexpected_message);
                    }

                    NotifyClientCertificate(state, Certificate.EmptyChain);
                }
            }

            if (clientMessage.Type == HandshakeType.client_key_exchange)
            {
                ProcessClientKeyExchange(state, clientMessage.Body);
            }
            else
            {
                throw new TlsFatalAlert(AlertDescription.unexpected_message);
            }

            TlsHandshakeHash prepareFinishHash = handshake.PrepareToFinish();

            securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.serverContext, prepareFinishHash, null);

            TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange);
            recordLayer.InitPendingEpoch(state.server.GetCipher());

            /*
             * RFC 5246 7.4.8 This message is only sent following a client certificate that has signing
             * capability (i.e., all certificates except those containing fixed Diffie-Hellman
             * parameters).
             */
            if (ExpectCertificateVerifyMessage(state))
            {
                byte[] certificateVerifyBody = handshake.ReceiveMessageBody(HandshakeType.certificate_verify);
                ProcessCertificateVerify(state, certificateVerifyBody, prepareFinishHash);
            }

            // NOTE: Calculated exclusive of the actual Finished message from the client
            byte[] expectedClientVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.client_finished,
                                                                               TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null));
            ProcessFinished(handshake.ReceiveMessageBody(HandshakeType.finished), expectedClientVerifyData);

            if (state.expectSessionTicket)
            {
                NewSessionTicket newSessionTicket     = state.server.GetNewSessionTicket();
                byte[]           newSessionTicketBody = GenerateNewSessionTicket(state, newSessionTicket);
                handshake.SendMessage(HandshakeType.session_ticket, newSessionTicketBody);
            }

            // NOTE: Calculated exclusive of the Finished message itself
            byte[] serverVerifyData = TlsUtilities.CalculateVerifyData(state.serverContext, ExporterLabel.server_finished,
                                                                       TlsProtocol.GetCurrentPrfHash(state.serverContext, handshake.HandshakeHash, null));
            handshake.SendMessage(HandshakeType.finished, serverVerifyData);

            handshake.Finish();

            state.server.NotifyHandshakeComplete();

            return(new DtlsTransport(recordLayer));
        }
		internal TlsClientContextImpl(SecureRandom secureRandom, SecurityParameters securityParameters)
		{
			this.secureRandom = secureRandom;
			this.securityParameters = securityParameters;
		}
Ejemplo n.º 38
0
        public virtual void Connect(TlsClient tlsClient)
        {
            if (tlsClient == null)
                throw new ArgumentNullException("tlsClient");
            if (this.tlsClient != null)
                throw new InvalidOperationException("Connect can only be called once");

            /*
             * Send Client hello
             *
             * First, generate some random data.
             */
            this.securityParameters = new SecurityParameters();
            this.securityParameters.clientRandom = CreateRandomBlock(tlsClient.ShouldUseGmtUnixTime(), random,
                ExporterLabel.client_random);

            this.tlsClientContext = new TlsClientContextImpl(random, securityParameters);
            this.tlsClient = tlsClient;
            this.tlsClient.Init(tlsClientContext);

            MemoryStream outStr = new MemoryStream();
            TlsUtilities.WriteVersion(outStr);
            outStr.Write(securityParameters.clientRandom, 0, 32);

            /*
            * Length of Session id
            */
            TlsUtilities.WriteUint8(0, outStr);

            this.offeredCipherSuites = this.tlsClient.GetCipherSuites();

            // Int32 -> byte[]
            this.clientExtensions = this.tlsClient.GetClientExtensions();

            // Cipher Suites (and SCSV)
            {
                /*
                 * RFC 5746 3.4.
                 * The client MUST include either an empty "renegotiation_info"
                 * extension, or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling
                 * cipher suite value in the ClientHello.  Including both is NOT
                 * RECOMMENDED.
                 */
                bool noRenegExt = clientExtensions == null
                    || !clientExtensions.Contains(ExtensionType.renegotiation_info);

                int count = offeredCipherSuites.Length;
                if (noRenegExt)
                {
                    // Note: 1 extra slot for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
                    ++count;
                }

                TlsUtilities.WriteUint16(2 * count, outStr);

                for (int i = 0; i < offeredCipherSuites.Length; ++i)
                {
                    TlsUtilities.WriteUint16((int)offeredCipherSuites[i], outStr);
                }

                if (noRenegExt)
                {
                    TlsUtilities.WriteUint16((int)CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV, outStr);
                }
            }

            /*
             * Compression methods, just the null method.
             */
            this.offeredCompressionMethods = tlsClient.GetCompressionMethods();

            {
                TlsUtilities.WriteUint8((byte)offeredCompressionMethods.Length, outStr);
                for (int i = 0; i < offeredCompressionMethods.Length; ++i)
                {
                    TlsUtilities.WriteUint8(offeredCompressionMethods[i], outStr);
                }
            }

            // Extensions
            if (clientExtensions != null)
            {
                MemoryStream ext = new MemoryStream();

                foreach (int extType in clientExtensions.Keys)
                {
                    WriteExtension(ext, extType, (byte[])clientExtensions[extType]);
                }

                TlsUtilities.WriteOpaque16(ext.ToArray(), outStr);
            }

            MemoryStream bos = new MemoryStream();
            TlsUtilities.WriteUint8((byte)HandshakeType.client_hello, bos);
            TlsUtilities.WriteUint24((int)outStr.Length, bos);
            byte[] outBytes = outStr.ToArray();
            bos.Write(outBytes, 0, outBytes.Length);
            byte[] message = bos.ToArray();
            SafeWriteMessage(ContentType.handshake, message, 0, message.Length);
            connection_state = CS_CLIENT_HELLO_SEND;

            /*
            * We will now read data, until we have completed the handshake.
            */
            while (connection_state != CS_DONE)
            {
                SafeReadData();
            }

            this.tlsStream = new TlsStream(this);
        }
Ejemplo n.º 39
0
//    public void Connect(ICertificateVerifyer verifyer, Certificate clientCertificate,
//        AsymmetricKeyParameter clientPrivateKey)
//    {
//        DefaultTlsClient client = new DefaultTlsClient(verifyer);
//        client.EnableClientAuthentication(clientCertificate, clientPrivateKey);
//
//        this.Connect(client);
//    }

        // TODO Make public
        internal virtual void Connect(TlsClient tlsClient)
        {
            if (tlsClient == null)
            {
                throw new ArgumentNullException("tlsClient");
            }
            if (this.tlsClient != null)
            {
                throw new InvalidOperationException("Connect can only be called once");
            }

            this.tlsClient = tlsClient;
            this.tlsClient.Init(this);

            /*
             * Send Client hello
             *
             * First, generate some random data.
             */
            securityParameters = new SecurityParameters();
            securityParameters.clientRandom = new byte[32];
            random.NextBytes(securityParameters.clientRandom, 4, 28);
            TlsUtilities.WriteGmtUnixTime(securityParameters.clientRandom, 0);

            MemoryStream outStr = new MemoryStream();

            TlsUtilities.WriteVersion(outStr);
            outStr.Write(securityParameters.clientRandom, 0, 32);

            /*
             * Length of Session id
             */
            TlsUtilities.WriteUint8((short)0, outStr);

            /*
             * Cipher suites
             */
            this.offeredCipherSuites = this.tlsClient.GetCipherSuites();

            // Note: 1 extra slot for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
            TlsUtilities.WriteUint16(2 * (offeredCipherSuites.Length + 1), outStr);
            for (int i = 0; i < offeredCipherSuites.Length; ++i)
            {
                TlsUtilities.WriteUint16(offeredCipherSuites[i], outStr);
            }

            // RFC 5746 3.3
            // Note: If renegotiation added, remove this (and extra slot above)
            TlsUtilities.WriteUint16(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, outStr);

            /*
             * Compression methods, just the null method.
             */
            byte[] compressionMethods = new byte[] { 0x00 };
            TlsUtilities.WriteOpaque8(compressionMethods, outStr);

            /*
             * Extensions
             */
            // Int32 -> byte[]
            Hashtable clientExtensions = this.tlsClient.GenerateClientExtensions();

            // RFC 5746 3.4
            // Note: If renegotiation is implemented, need to use this instead of TLS_EMPTY_RENEGOTIATION_INFO_SCSV
//			{
//				if (clientExtensions == null)
//					clientExtensions = new Hashtable();
//
//				clientExtensions[EXT_RenegotiationInfo] = CreateRenegotiationInfo(emptybuf);
//			}

            this.extendedClientHello = clientExtensions != null && clientExtensions.Count > 0;

            if (extendedClientHello)
            {
                MemoryStream ext = new MemoryStream();
                foreach (int extType in clientExtensions.Keys)
                {
                    byte[] extValue = (byte[])clientExtensions[extType];

                    TlsUtilities.WriteUint16(extType, ext);
                    TlsUtilities.WriteOpaque16(extValue, ext);
                }

                TlsUtilities.WriteOpaque16(ext.ToArray(), outStr);
            }

            MemoryStream bos = new MemoryStream();

            TlsUtilities.WriteUint8(HP_CLIENT_HELLO, bos);
            TlsUtilities.WriteUint24((int)outStr.Length, bos);
            byte[] outBytes = outStr.ToArray();
            bos.Write(outBytes, 0, outBytes.Length);
            byte[] message = bos.ToArray();
            rs.WriteMessage(RL_HANDSHAKE, message, 0, message.Length);
            connection_state = CS_CLIENT_HELLO_SEND;

            /*
             * We will now read data, until we have completed the handshake.
             */
            while (connection_state != CS_DONE)
            {
                // TODO Should we send fatal alerts in the event of an exception
                // (see readApplicationData)
                rs.ReadData();
            }

            this.tlsStream = new TlsStream(this);
        }
Ejemplo n.º 40
0
        internal virtual DtlsTransport ServerHandshake(DtlsServerProtocol.ServerHandshakeState state, DtlsRecordLayer recordLayer)
        {
            SecurityParameters    securityParameters    = state.serverContext.SecurityParameters;
            DtlsReliableHandshake dtlsReliableHandshake = new DtlsReliableHandshake(state.serverContext, recordLayer);

            DtlsReliableHandshake.Message message = dtlsReliableHandshake.ReceiveMessage();
            ProtocolVersion discoveredPeerVersion = recordLayer.DiscoveredPeerVersion;

            state.serverContext.SetClientVersion(discoveredPeerVersion);
            if (message.Type != 1)
            {
                throw new TlsFatalAlert(10);
            }
            this.ProcessClientHello(state, message.Body);
            byte[] body = this.GenerateServerHello(state);
            DtlsProtocol.ApplyMaxFragmentLengthExtension(recordLayer, securityParameters.maxFragmentLength);
            dtlsReliableHandshake.SendMessage(2, body);
            dtlsReliableHandshake.NotifyHelloComplete();
            IList serverSupplementalData = state.server.GetServerSupplementalData();

            if (serverSupplementalData != null)
            {
                byte[] body2 = DtlsProtocol.GenerateSupplementalData(serverSupplementalData);
                dtlsReliableHandshake.SendMessage(23, body2);
            }
            state.keyExchange = state.server.GetKeyExchange();
            state.keyExchange.Init(state.serverContext);
            state.serverCredentials = state.server.GetCredentials();
            Certificate certificate = null;

            if (state.serverCredentials == null)
            {
                state.keyExchange.SkipServerCredentials();
            }
            else
            {
                state.keyExchange.ProcessServerCredentials(state.serverCredentials);
                certificate = state.serverCredentials.Certificate;
                byte[] body3 = DtlsProtocol.GenerateCertificate(certificate);
                dtlsReliableHandshake.SendMessage(11, body3);
            }
            if (certificate == null || certificate.IsEmpty)
            {
                state.allowCertificateStatus = false;
            }
            if (state.allowCertificateStatus)
            {
                CertificateStatus certificateStatus = state.server.GetCertificateStatus();
                if (certificateStatus != null)
                {
                    byte[] body4 = this.GenerateCertificateStatus(state, certificateStatus);
                    dtlsReliableHandshake.SendMessage(22, body4);
                }
            }
            byte[] array = state.keyExchange.GenerateServerKeyExchange();
            if (array != null)
            {
                dtlsReliableHandshake.SendMessage(12, array);
            }
            if (state.serverCredentials != null)
            {
                state.certificateRequest = state.server.GetCertificateRequest();
                if (state.certificateRequest != null)
                {
                    state.keyExchange.ValidateCertificateRequest(state.certificateRequest);
                    byte[] body5 = this.GenerateCertificateRequest(state, state.certificateRequest);
                    dtlsReliableHandshake.SendMessage(13, body5);
                    TlsUtilities.TrackHashAlgorithms(dtlsReliableHandshake.HandshakeHash, state.certificateRequest.SupportedSignatureAlgorithms);
                }
            }
            dtlsReliableHandshake.SendMessage(14, TlsUtilities.EmptyBytes);
            dtlsReliableHandshake.HandshakeHash.SealHashAlgorithms();
            message = dtlsReliableHandshake.ReceiveMessage();
            if (message.Type == 23)
            {
                this.ProcessClientSupplementalData(state, message.Body);
                message = dtlsReliableHandshake.ReceiveMessage();
            }
            else
            {
                state.server.ProcessClientSupplementalData(null);
            }
            if (state.certificateRequest == null)
            {
                state.keyExchange.SkipClientCredentials();
            }
            else if (message.Type == 11)
            {
                this.ProcessClientCertificate(state, message.Body);
                message = dtlsReliableHandshake.ReceiveMessage();
            }
            else
            {
                if (TlsUtilities.IsTlsV12(state.serverContext))
                {
                    throw new TlsFatalAlert(10);
                }
                this.NotifyClientCertificate(state, Certificate.EmptyChain);
            }
            if (message.Type == 16)
            {
                this.ProcessClientKeyExchange(state, message.Body);
                TlsHandshakeHash tlsHandshakeHash = dtlsReliableHandshake.PrepareToFinish();
                securityParameters.sessionHash = TlsProtocol.GetCurrentPrfHash(state.serverContext, tlsHandshakeHash, null);
                TlsProtocol.EstablishMasterSecret(state.serverContext, state.keyExchange);
                recordLayer.InitPendingEpoch(state.server.GetCipher());
                if (this.ExpectCertificateVerifyMessage(state))
                {
                    byte[] body6 = dtlsReliableHandshake.ReceiveMessageBody(15);
                    this.ProcessCertificateVerify(state, body6, tlsHandshakeHash);
                }
                byte[] expected_verify_data = TlsUtilities.CalculateVerifyData(state.serverContext, "client finished", TlsProtocol.GetCurrentPrfHash(state.serverContext, dtlsReliableHandshake.HandshakeHash, null));
                this.ProcessFinished(dtlsReliableHandshake.ReceiveMessageBody(20), expected_verify_data);
                if (state.expectSessionTicket)
                {
                    NewSessionTicket newSessionTicket = state.server.GetNewSessionTicket();
                    byte[]           body7            = this.GenerateNewSessionTicket(state, newSessionTicket);
                    dtlsReliableHandshake.SendMessage(4, body7);
                }
                byte[] body8 = TlsUtilities.CalculateVerifyData(state.serverContext, "server finished", TlsProtocol.GetCurrentPrfHash(state.serverContext, dtlsReliableHandshake.HandshakeHash, null));
                dtlsReliableHandshake.SendMessage(20, body8);
                dtlsReliableHandshake.Finish();
                state.server.NotifyHandshakeComplete();
                return(new DtlsTransport(recordLayer));
            }
            throw new TlsFatalAlert(10);
        }
Ejemplo n.º 41
0
 private TlsCipher CreateDesEdeCipher(int cipherKeySize, SecurityParameters securityParameters)
 {
     return(new TlsBlockCipher(handler, CreateDesEdeBlockCipher(), CreateDesEdeBlockCipher(),
                               new Sha1Digest(), new Sha1Digest(), cipherKeySize, securityParameters));
 }
Ejemplo n.º 42
0
        protected virtual byte[] GenerateClientHello(ClientHandshakeState state, TlsClient client)
        {
            MemoryStream buf = new MemoryStream();

            ProtocolVersion client_version = client.ClientVersion;

            if (!client_version.IsDtls)
            {
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            TlsClientContextImpl context = state.clientContext;

            context.SetClientVersion(client_version);
            TlsUtilities.WriteVersion(client_version, buf);

            SecurityParameters securityParameters = context.SecurityParameters;

            buf.Write(securityParameters.ClientRandom, 0, securityParameters.ClientRandom.Length);

            // Session ID
            byte[] session_id = TlsUtilities.EmptyBytes;
            if (state.tlsSession != null)
            {
                session_id = state.tlsSession.SessionID;
                if (session_id == null || session_id.Length > 32)
                {
                    session_id = TlsUtilities.EmptyBytes;
                }
            }
            TlsUtilities.WriteOpaque8(session_id, buf);

            // Cookie
            TlsUtilities.WriteOpaque8(TlsUtilities.EmptyBytes, buf);

            bool fallback = client.IsFallback;

            /*
             * Cipher suites
             */
            state.offeredCipherSuites = client.GetCipherSuites();

            // Integer -> byte[]
            state.clientExtensions = client.GetClientExtensions();

            securityParameters.extendedMasterSecret = TlsExtensionsUtilities.HasExtendedMasterSecretExtension(state.clientExtensions);

            // Cipher Suites (and SCSV)
            {
                /*
                 * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info" extension,
                 * or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the
                 * ClientHello. Including both is NOT RECOMMENDED.
                 */
                byte[] renegExtData = TlsUtilities.GetExtensionData(state.clientExtensions, ExtensionType.renegotiation_info);
                bool   noRenegExt   = (null == renegExtData);

                bool noRenegSCSV = !Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV);

                if (noRenegExt && noRenegSCSV)
                {
                    // TODO Consider whether to default to a client extension instead
                    state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
                }

                /*
                 * draft-ietf-tls-downgrade-scsv-00 4. If a client sends a ClientHello.client_version
                 * containing a lower value than the latest (highest-valued) version supported by the
                 * client, it SHOULD include the TLS_FALLBACK_SCSV cipher suite value in
                 * ClientHello.cipher_suites.
                 */
                if (fallback && !Arrays.Contains(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV))
                {
                    state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, CipherSuite.TLS_FALLBACK_SCSV);
                }

                TlsUtilities.WriteUint16ArrayWithUint16Length(state.offeredCipherSuites, buf);
            }

            // TODO Add support for compression
            // Compression methods
            // state.offeredCompressionMethods = client.getCompressionMethods();
            state.offeredCompressionMethods = new byte[] { CompressionMethod.cls_null };

            TlsUtilities.WriteUint8ArrayWithUint8Length(state.offeredCompressionMethods, buf);

            // Extensions
            if (state.clientExtensions != null)
            {
                TlsProtocol.WriteExtensions(buf, state.clientExtensions);
            }

            return(buf.ToArray());
        }
Ejemplo n.º 43
0
        public virtual void Connect(TlsClient tlsClient)
        {
            if (tlsClient == null)
            {
                throw new ArgumentNullException("tlsClient");
            }
            if (this.tlsClient != null)
            {
                throw new InvalidOperationException("Connect can only be called once");
            }

            /*
             * Send Client hello
             *
             * First, generate some random data.
             */
            this.securityParameters = new SecurityParameters();
            this.securityParameters.clientRandom = new byte[32];
            random.NextBytes(securityParameters.clientRandom, 4, 28);
            TlsUtilities.WriteGmtUnixTime(securityParameters.clientRandom, 0);

            this.tlsClientContext = new TlsClientContextImpl(random, securityParameters);
            this.tlsClient        = tlsClient;
            this.tlsClient.Init(tlsClientContext);

            MemoryStream outStr = new MemoryStream();

            TlsUtilities.WriteVersion(outStr);
            outStr.Write(securityParameters.clientRandom, 0, 32);

            /*
             * Length of Session id
             */
            TlsUtilities.WriteUint8(0, outStr);

            this.offeredCipherSuites = this.tlsClient.GetCipherSuites();

            // ExtensionType -> byte[]
            this.clientExtensions = this.tlsClient.GetClientExtensions();

            // Cipher Suites (and SCSV)
            {
                /*
                 * RFC 5746 3.4.
                 * The client MUST include either an empty "renegotiation_info"
                 * extension, or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling
                 * cipher suite value in the ClientHello.  Including both is NOT
                 * RECOMMENDED.
                 */
                bool noRenegExt = clientExtensions == null ||
                                  !clientExtensions.Contains(ExtensionType.renegotiation_info);

                int count = offeredCipherSuites.Length;
                if (noRenegExt)
                {
                    // Note: 1 extra slot for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
                    ++count;
                }

                TlsUtilities.WriteUint16(2 * count, outStr);

                for (int i = 0; i < offeredCipherSuites.Length; ++i)
                {
                    TlsUtilities.WriteUint16((int)offeredCipherSuites[i], outStr);
                }

                if (noRenegExt)
                {
                    TlsUtilities.WriteUint16((int)CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV, outStr);
                }
            }

            /*
             * Compression methods, just the null method.
             */
            this.offeredCompressionMethods = tlsClient.GetCompressionMethods();

            {
                TlsUtilities.WriteUint8((byte)offeredCompressionMethods.Length, outStr);
                for (int i = 0; i < offeredCompressionMethods.Length; ++i)
                {
                    TlsUtilities.WriteUint8((byte)offeredCompressionMethods[i], outStr);
                }
            }

            // Extensions
            if (clientExtensions != null)
            {
                MemoryStream ext = new MemoryStream();

                foreach (ExtensionType extType in clientExtensions.Keys)
                {
                    WriteExtension(ext, extType, (byte[])clientExtensions[extType]);
                }

                TlsUtilities.WriteOpaque16(ext.ToArray(), outStr);
            }

            MemoryStream bos = new MemoryStream();

            TlsUtilities.WriteUint8((byte)HandshakeType.client_hello, bos);
            TlsUtilities.WriteUint24((int)outStr.Length, bos);
            byte[] outBytes = outStr.ToArray();
            bos.Write(outBytes, 0, outBytes.Length);
            byte[] message = bos.ToArray();
            SafeWriteMessage(ContentType.handshake, message, 0, message.Length);
            connection_state = CS_CLIENT_HELLO_SEND;

            /*
             * We will now read data, until we have completed the handshake.
             */
            while (connection_state != CS_DONE)
            {
                SafeReadData();
            }

            this.tlsStream = new TlsStream(this);
        }
Ejemplo n.º 44
0
        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));
        }
Ejemplo n.º 45
0
		public void ProcessServerKeyExchange(Stream input, SecurityParameters securityParameters)
		{
			Stream sigIn = input;
			ISigner signer = null;

			if (tlsSigner != null)
			{
				signer = InitSigner(tlsSigner, securityParameters);
				sigIn = new SignerStream(input, signer, null);
			}

			byte[] NBytes = TlsUtilities.ReadOpaque16(sigIn);
			byte[] gBytes = TlsUtilities.ReadOpaque16(sigIn);
			byte[] sBytes = TlsUtilities.ReadOpaque8(sigIn);
			byte[] BBytes = TlsUtilities.ReadOpaque16(sigIn);

			if (signer != null)
			{
				byte[] sigByte = TlsUtilities.ReadOpaque16(input);

				if (!signer.VerifySignature(sigByte))
				{
					handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_bad_certificate);
				}
			}

			BigInteger N = new BigInteger(1, NBytes);
			BigInteger g = new BigInteger(1, gBytes);

			// TODO Validate group parameters (see RFC 5054)
			//handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_insufficient_security);

			this.s = sBytes;

			/*
			* RFC 5054 2.5.3: The client MUST abort the handshake with an "illegal_parameter"
			* alert if B % N = 0.
			*/
			try
			{
				this.B = Srp6Utilities.ValidatePublicValue(N, new BigInteger(1, BBytes));
			}
			catch (CryptoException)
			{
				handler.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_illegal_parameter);
			}

			this.srpClient.Init(N, g, new Sha1Digest(), handler.Random);
		}