コード例 #1
0
        protected virtual void ProcessServerKeyExchange(DtlsClientProtocol.ClientHandshakeState state, byte[] body)
        {
            MemoryStream memoryStream = new MemoryStream(body, false);

            state.keyExchange.ProcessServerKeyExchange(memoryStream);
            TlsProtocol.AssertEmpty(memoryStream);
        }
コード例 #2
0
        protected virtual void ProcessServerSupplementalData(DtlsClientProtocol.ClientHandshakeState state, byte[] body)
        {
            MemoryStream input = new MemoryStream(body, false);
            IList        serverSupplementalData = TlsProtocol.ReadSupplementalDataMessage(input);

            state.client.ProcessServerSupplementalData(serverSupplementalData);
        }
コード例 #3
0
        protected virtual byte[] GenerateClientKeyExchange(DtlsClientProtocol.ClientHandshakeState state)
        {
            MemoryStream memoryStream = new MemoryStream();

            state.keyExchange.GenerateClientKeyExchange(memoryStream);
            return(memoryStream.ToArray());
        }
コード例 #4
0
        protected virtual byte[] GenerateCertificateVerify(DtlsClientProtocol.ClientHandshakeState state, DigitallySigned certificateVerify)
        {
            MemoryStream memoryStream = new MemoryStream();

            certificateVerify.Encode(memoryStream);
            return(memoryStream.ToArray());
        }
コード例 #5
0
        protected virtual void ProcessNewSessionTicket(DtlsClientProtocol.ClientHandshakeState state, byte[] body)
        {
            MemoryStream     memoryStream     = new MemoryStream(body, false);
            NewSessionTicket newSessionTicket = NewSessionTicket.Parse(memoryStream);

            TlsProtocol.AssertEmpty(memoryStream);
            state.client.NotifyNewSessionTicket(newSessionTicket);
        }
コード例 #6
0
        protected virtual Certificate ProcessServerCertificate(DtlsClientProtocol.ClientHandshakeState state, byte[] body)
        {
            MemoryStream memoryStream = new MemoryStream(body, false);
            Certificate  certificate  = Certificate.Parse(memoryStream);

            TlsProtocol.AssertEmpty(memoryStream);
            state.keyExchange.ProcessServerCertificate(certificate);
            state.authentication = state.client.GetAuthentication();
            state.authentication.NotifyServerCertificate(certificate);
            return(certificate);
        }
コード例 #7
0
        protected virtual void ProcessCertificateStatus(DtlsClientProtocol.ClientHandshakeState state, byte[] body)
        {
            if (!state.allowCertificateStatus)
            {
                throw new TlsFatalAlert(10);
            }
            MemoryStream memoryStream = new MemoryStream(body, false);

            state.certificateStatus = CertificateStatus.Parse(memoryStream);
            TlsProtocol.AssertEmpty(memoryStream);
        }
コード例 #8
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 = 1;
            DtlsClientProtocol.ClientHandshakeState clientHandshakeState = new DtlsClientProtocol.ClientHandshakeState();
            clientHandshakeState.client        = client;
            clientHandshakeState.clientContext = new TlsClientContextImpl(this.mSecureRandom, securityParameters);
            securityParameters.clientRandom    = TlsProtocol.CreateRandomBlock(client.ShouldUseGmtUnixTime(), clientHandshakeState.clientContext.NonceRandomGenerator);
            client.Init(clientHandshakeState.clientContext);
            DtlsRecordLayer dtlsRecordLayer = new DtlsRecordLayer(transport, clientHandshakeState.clientContext, client, 22);
            TlsSession      sessionToResume = clientHandshakeState.client.GetSessionToResume();

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

            try
            {
                result = this.ClientHandshake(clientHandshakeState, dtlsRecordLayer);
            }
            catch (TlsFatalAlert tlsFatalAlert)
            {
                dtlsRecordLayer.Fail(tlsFatalAlert.AlertDescription);
                throw tlsFatalAlert;
            }
            catch (IOException ex)
            {
                dtlsRecordLayer.Fail(80);
                throw ex;
            }
            catch (Exception alertCause)
            {
                dtlsRecordLayer.Fail(80);
                throw new TlsFatalAlert(80, alertCause);
            }
            return(result);
        }
コード例 #9
0
        protected virtual void ProcessCertificateRequest(DtlsClientProtocol.ClientHandshakeState state, byte[] body)
        {
            if (state.authentication == null)
            {
                throw new TlsFatalAlert(40);
            }
            MemoryStream memoryStream = new MemoryStream(body, false);

            state.certificateRequest = CertificateRequest.Parse(state.clientContext, memoryStream);
            TlsProtocol.AssertEmpty(memoryStream);
            state.keyExchange.ValidateCertificateRequest(state.certificateRequest);
        }
コード例 #10
0
        protected virtual byte[] GenerateClientHello(DtlsClientProtocol.ClientHandshakeState state, TlsClient client)
        {
            MemoryStream    memoryStream  = new MemoryStream();
            ProtocolVersion clientVersion = client.ClientVersion;

            if (!clientVersion.IsDtls)
            {
                throw new TlsFatalAlert(80);
            }
            TlsClientContextImpl clientContext = state.clientContext;

            clientContext.SetClientVersion(clientVersion);
            TlsUtilities.WriteVersion(clientVersion, memoryStream);
            SecurityParameters securityParameters = clientContext.SecurityParameters;

            memoryStream.Write(securityParameters.ClientRandom, 0, securityParameters.ClientRandom.Length);
            byte[] array = TlsUtilities.EmptyBytes;
            if (state.tlsSession != null)
            {
                array = state.tlsSession.SessionID;
                if (array == null || array.Length > 32)
                {
                    array = TlsUtilities.EmptyBytes;
                }
            }
            TlsUtilities.WriteOpaque8(array, memoryStream);
            TlsUtilities.WriteOpaque8(TlsUtilities.EmptyBytes, memoryStream);
            bool isFallback = client.IsFallback;

            state.offeredCipherSuites = client.GetCipherSuites();
            state.clientExtensions    = client.GetClientExtensions();
            byte[] extensionData = TlsUtilities.GetExtensionData(state.clientExtensions, 65281);
            bool   flag          = null == extensionData;
            bool   flag2         = !Arrays.Contains(state.offeredCipherSuites, 255);

            if (flag && flag2)
            {
                state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, 255);
            }
            if (isFallback && !Arrays.Contains(state.offeredCipherSuites, 22016))
            {
                state.offeredCipherSuites = Arrays.Append(state.offeredCipherSuites, 22016);
            }
            TlsUtilities.WriteUint16ArrayWithUint16Length(state.offeredCipherSuites, memoryStream);
            byte[] offeredCompressionMethods = new byte[1];
            state.offeredCompressionMethods = offeredCompressionMethods;
            TlsUtilities.WriteUint8ArrayWithUint8Length(state.offeredCompressionMethods, memoryStream);
            if (state.clientExtensions != null)
            {
                TlsProtocol.WriteExtensions(memoryStream, state.clientExtensions);
            }
            return(memoryStream.ToArray());
        }
コード例 #11
0
 protected virtual void InvalidateSession(DtlsClientProtocol.ClientHandshakeState state)
 {
     if (state.sessionParameters != null)
     {
         state.sessionParameters.Clear();
         state.sessionParameters = null;
     }
     if (state.tlsSession != null)
     {
         state.tlsSession.Invalidate();
         state.tlsSession = null;
     }
 }
コード例 #12
0
        protected virtual void ReportServerVersion(DtlsClientProtocol.ClientHandshakeState state, ProtocolVersion server_version)
        {
            TlsClientContextImpl clientContext = state.clientContext;
            ProtocolVersion      serverVersion = clientContext.ServerVersion;

            if (serverVersion == null)
            {
                clientContext.SetServerVersion(server_version);
                state.client.NotifyServerVersion(server_version);
                return;
            }
            if (!serverVersion.Equals(server_version))
            {
                throw new TlsFatalAlert(47);
            }
        }
コード例 #13
0
        protected virtual byte[] ProcessHelloVerifyRequest(DtlsClientProtocol.ClientHandshakeState state, byte[] body)
        {
            MemoryStream    memoryStream    = new MemoryStream(body, false);
            ProtocolVersion protocolVersion = TlsUtilities.ReadVersion(memoryStream);

            byte[] array = TlsUtilities.ReadOpaque8(memoryStream);
            TlsProtocol.AssertEmpty(memoryStream);
            if (!protocolVersion.IsEqualOrEarlierVersionOf(state.clientContext.ClientVersion))
            {
                throw new TlsFatalAlert(47);
            }
            if (!ProtocolVersion.DTLSv12.IsEqualOrEarlierVersionOf(protocolVersion) && array.Length > 32)
            {
                throw new TlsFatalAlert(47);
            }
            return(array);
        }
コード例 #14
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;
        }
コード例 #15
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));
        }