Пример #1
0
        public AsyncDtlsClientProtocol(AsyncDtlsClient client, SecureRandom secureRandom, IChannel channel, HandshakeHandler parentHandler, DtlsStateHandler handler, Boolean useExtendedMasterSecret, ProtocolVersion initialVersion)
        {
            this.parentHandler = parentHandler;
            this.handler       = handler;

            this.channel         = channel;
            this.protocolVersion = initialVersion;

            AsyncDtlsSecurityParameters securityParameters = new AsyncDtlsSecurityParameters();

            securityParameters.SetEntity(ConnectionEnd.client);

            clientState               = new AsyncDtlsClientState();
            clientState.Client        = client;
            clientState.ClientContext = new AsyncDtlsClientContext(secureRandom, securityParameters);

            securityParameters.SetExtendedMasterSecret(useExtendedMasterSecret);
            securityParameters.SetClientRandom(DtlsHelper.CreateRandomBlock(client.ShouldUseGmtUnixTime(), clientState.ClientContext.NonceRandomGenerator));
            client.InitClient(clientState.ClientContext);

            clientState.HandshakeHash = new DeferredHash();
            clientState.HandshakeHash.Init(clientState.ClientContext);

            recordLayer = new AsyncDtlsRecordLayer(clientState.HandshakeHash, this, channel, clientState.ClientContext, client);
        }
Пример #2
0
        private void ProcessServerHello(IByteBuffer body)
        {
            ProtocolVersion recordLayerVersion = recordLayer.GetReadVersion();

            ReportServerVersion(recordLayerVersion);
            recordLayer.SetWriteVersion(recordLayerVersion);

            AsyncDtlsSecurityParameters securityParameters = (AsyncDtlsSecurityParameters)clientState.ClientContext.SecurityParameters;

            ProtocolVersion server_version = ProtocolVersion.Get(body.ReadByte() & 0xFF, body.ReadByte() & 0xFF);

            ReportServerVersion(server_version);

            byte[] serverRandom = new byte[32];
            body.ReadBytes(serverRandom);
            securityParameters.SetServerRandom(serverRandom);

            byte[] selectedSessionID = new byte[body.ReadByte() & 0x0FF];
            if (selectedSessionID.Length > 0)
            {
                body.ReadBytes(selectedSessionID);
            }

            clientState.SelectedSessionID = selectedSessionID;
            if (selectedSessionID.Length > 32)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            clientState.Client.NotifySessionID(selectedSessionID);
            clientState.ResumedSession = selectedSessionID.Length > 0 && clientState.TlsSession != null && ArrayUtils.Equals(clientState.SelectedSessionID, clientState.TlsSession.SessionID);

            int     selectedCipherSuite   = body.ReadUnsignedShort();
            Boolean inOfferedCipherSuites = false;

            for (int i = 0; i < clientState.OfferedCipherSuites.Length; i++)
            {
                if (selectedCipherSuite == clientState.OfferedCipherSuites[i])
                {
                    inOfferedCipherSuites = true;
                    break;
                }
            }

            if (!inOfferedCipherSuites || selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL || CipherSuite.IsScsv(selectedCipherSuite) || !DtlsHelper.GetMinimumVersion(selectedCipherSuite).IsEqualOrEarlierVersionOf(clientState.ClientContext.ServerVersion.GetEquivalentTLSVersion()))
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            switch (DtlsHelper.GetEncryptionAlgorithm(selectedCipherSuite))
            {
            case EncryptionAlgorithm.RC4_40:
            case EncryptionAlgorithm.RC4_128:
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            clientState.Client.NotifySelectedCipherSuite(selectedCipherSuite);

            byte    selectedCompressionMethod   = body.ReadByte();
            Boolean inOfferedCompressionMethods = false;

            for (int i = 0; i < clientState.OfferedCompressionMethods.Length; i++)
            {
                if (selectedCompressionMethod == clientState.OfferedCompressionMethods[i])
                {
                    inOfferedCompressionMethods = true;
                    break;
                }
            }

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

            clientState.Client.NotifySelectedCompressionMethod(selectedCompressionMethod);
            clientState.ServerExtensions = DtlsHelper.ReadSelectedExtensions(body);

            if (clientState.ServerExtensions != null)
            {
                foreach (Int32 extType in clientState.ServerExtensions.Keys)
                {
                    if (extType.Equals(DtlsHelper.EXT_RenegotiationInfo))
                    {
                        continue;
                    }

                    if (!clientState.ClientExtensions.Contains(extType))
                    {
                        throw new TlsFatalAlert(AlertDescription.unsupported_extension);
                    }
                }
            }

            byte[] renegExtData = null;
            if (clientState.ServerExtensions.Contains(DtlsHelper.EXT_RenegotiationInfo))
            {
                renegExtData = (byte[])clientState.ServerExtensions[DtlsHelper.EXT_RenegotiationInfo];
            }

            if (renegExtData != null)
            {
                clientState.SecureRenegotiation = true;

                if (!ArrayUtils.Equals(renegExtData, DtlsHelper.EMPTY_BYTES_WITH_LENGTH))
                {
                    throw new TlsFatalAlert(AlertDescription.handshake_failure);
                }
            }

            if (clientState.SecureRenegotiation)
            {
                clientState.Client.NotifySecureRenegotiation(clientState.SecureRenegotiation);
            }

            IDictionary sessionClientExtensions = clientState.ClientExtensions;
            IDictionary sessionServerExtensions = clientState.ServerExtensions;

            if (clientState.ResumedSession)
            {
                if (selectedCipherSuite != clientState.SessionParameters.CipherSuite || selectedCompressionMethod != clientState.SessionParameters.CompressionAlgorithm)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                sessionClientExtensions = null;
                sessionServerExtensions = (Dictionary <Int32, byte[]>)clientState.SessionParameters.ReadServerExtensions();
            }

            securityParameters.SetCipherSuite(selectedCipherSuite);
            securityParameters.SetCompressionAlgorithm(selectedCompressionMethod);

            if (sessionServerExtensions != null)
            {
                byte[] encryptThenMac = null;
                if (sessionServerExtensions.Contains(DtlsHelper.EXT_encrypt_then_mac))
                {
                    encryptThenMac = (byte[])sessionServerExtensions[DtlsHelper.EXT_encrypt_then_mac];
                }

                if (encryptThenMac != null && encryptThenMac.Length > 0)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                Boolean serverSentEncryptThenMAC = encryptThenMac != null;
                if (serverSentEncryptThenMAC && DtlsHelper.GetCipherType(securityParameters.CipherSuite) != CipherType.block)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                securityParameters.SetEncryptThenMAC(serverSentEncryptThenMAC);

                byte[] extendedMacSecret = null;
                if (sessionServerExtensions.Contains(DtlsHelper.EXT_extended_master_secret))
                {
                    extendedMacSecret = (byte[])sessionServerExtensions[DtlsHelper.EXT_extended_master_secret];
                }

                if (extendedMacSecret != null && extendedMacSecret.Length > 0)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                securityParameters.SetExtendedMasterSecret(extendedMacSecret != null);

                securityParameters.SetMaxFragmentLength(DtlsHelper.EvaluateMaxFragmentLengthExtension(clientState.ResumedSession, sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter));

                byte[] truncatedHMAC = null;
                if (sessionServerExtensions.Contains(DtlsHelper.EXT_truncated_hmac))
                {
                    truncatedHMAC = (byte[])sessionServerExtensions[DtlsHelper.EXT_truncated_hmac];
                }

                if (truncatedHMAC != null && truncatedHMAC.Length > 0)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                securityParameters.SetTruncatedHMac(truncatedHMAC != null);

                byte[] statusRequest = null;
                if (sessionServerExtensions.Contains(DtlsHelper.EXT_status_request))
                {
                    statusRequest = (byte[])sessionServerExtensions[DtlsHelper.EXT_status_request];
                }

                if (statusRequest != null && statusRequest.Length > 0)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                clientState.AllowCertificateStatus = (!clientState.ResumedSession && statusRequest != null);

                byte[] sessionTicket = null;
                if (sessionServerExtensions.Contains(DtlsHelper.EXT_SessionTicket))
                {
                    sessionTicket = (byte[])sessionServerExtensions[DtlsHelper.EXT_SessionTicket];
                }

                if (sessionTicket != null && sessionTicket.Length > 0)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                clientState.ExpectSessionTicket = (!clientState.ResumedSession && sessionTicket != null);
            }

            if (sessionClientExtensions != null)
            {
                clientState.Client.ProcessServerExtensions(sessionServerExtensions);
            }

            securityParameters.SetPrfAlgorithm(DtlsHelper.GetPRFAlgorithm(clientState.ClientContext.ServerVersion, securityParameters.CipherSuite));
            securityParameters.SetVerifyDataLength(12);
        }