Exemplo n.º 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);
        }
        public AsyncDtlsClientContext(SecureRandom secureRandom, AsyncDtlsSecurityParameters securityParameters)
        {
            IDigest d = TlsUtilities.CreateHash(HashAlgorithm.sha256);

            byte[] seed = new byte[d.GetDigestSize()];
            secureRandom.NextBytes(seed);

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

            this.secureRandom       = secureRandom;
            this.securityParameters = securityParameters;
        }
Exemplo n.º 3
0
        public void PostProcessFinished()
        {
            if (handshakeState == State.SERVER_HELLO_RECEIVED)
            {
                byte[]      clientVerifyData   = DtlsHelper.CalculateVerifyData(clientState.ClientContext, ExporterLabel.client_finished, DtlsHelper.GetCurrentPRFHash(clientState.ClientContext, clientState.HandshakeHash, null));
                IByteBuffer serverVerifyBuffer = Unpooled.Buffer(DtlsHelper.HANDSHAKE_MESSAGE_HEADER_LENGTH + clientVerifyData.Length);
                short       currSequence       = sequence++;
                DtlsHelper.WriteHandshakeHeader(currSequence, MessageType.FINISHED, serverVerifyBuffer, clientVerifyData.Length);
                serverVerifyBuffer.WriteBytes(clientVerifyData);
                recordLayer.Send(currSequence, MessageType.FINISHED, serverVerifyBuffer);
            }

            recordLayer.HandshakeSuccessful();

            if (handshakeState == State.SERVER_HELLO_RECEIVED)
            {
                clientState.ClientContext.ResumableSession = clientState.TlsSession;
            }
            else
            {
                if (clientState.TlsSession != null)
                {
                    AsyncDtlsSecurityParameters parameters = (AsyncDtlsSecurityParameters)clientState.ClientContext.SecurityParameters;
                    clientState.SessionParameters = new SessionParameters.Builder()
                                                    .SetCipherSuite(parameters.CipherSuite)
                                                    .SetCompressionAlgorithm(parameters.CompressionAlgorithm)
                                                    .SetMasterSecret(parameters.MasterSecret)
                                                    .SetPeerCertificate(serverCertificate)
                                                    .SetPskIdentity(parameters.PskIdentity)
                                                    .SetSrpIdentity(parameters.SrpIdentity)
                                                    .SetServerExtensions(clientState.ServerExtensions)
                                                    .Build();

                    clientState.TlsSession = new AsyncDtlsSessionImpl(clientState.TlsSession.SessionID, clientState.SessionParameters);
                    clientState.ClientContext.ResumableSession = clientState.TlsSession;
                }
            }

            clientState.Client.NotifyHandshakeComplete();
        }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
0
        public void InitHandshake(byte[] cookie)
        {
            AsyncDtlsSecurityParameters securityParameters = (AsyncDtlsSecurityParameters)clientState.ClientContext.SecurityParameters;

            ProtocolVersion client_version = clientState.Client.ClientVersion;

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

            AsyncDtlsClientContext context = clientState.ClientContext;

            context.ClientVersion = client_version;

            Boolean fallback = clientState.Client.IsFallback;

            //Cipher suites
            clientState.OfferedCipherSuites = clientState.Client.GetCipherSuites();

            // Integer -> byte[]
            clientState.ClientExtensions = clientState.Client.GetClientExtensions();
            if (securityParameters.IsExtendedMasterSecret())
            {
                if (clientState.ClientExtensions == null)
                {
                    clientState.ClientExtensions = new Dictionary <int, byte[]>();
                }

                clientState.ClientExtensions[DtlsHelper.EXT_extended_master_secret] = DtlsHelper.EMPTY_BYTES;
            }

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

            Boolean noRenegExt  = (null == renegExtData);
            Boolean noRenegSCSV = true;

            for (int i = 0; i < clientState.OfferedCipherSuites.Length; i++)
            {
                if (clientState.OfferedCipherSuites[i] == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
                {
                    noRenegSCSV = false;
                    break;
                }
            }

            Boolean tlsFallbackFound = false;

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

            int additionalCount = 0;

            if (noRenegExt && noRenegSCSV)
            {
                additionalCount++;
            }

            if (fallback && !tlsFallbackFound)
            {
                additionalCount++;
            }

            int[] offeredCipherSuites = clientState.OfferedCipherSuites;
            if (additionalCount > 0)
            {
                offeredCipherSuites = new int[clientState.OfferedCipherSuites.Length + additionalCount];
                Array.Copy(clientState.OfferedCipherSuites, 0, offeredCipherSuites, 0, clientState.OfferedCipherSuites.Length);
                if (noRenegExt && noRenegSCSV)
                {
                    offeredCipherSuites[clientState.OfferedCipherSuites.Length] = CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
                }

                if (fallback && !tlsFallbackFound)
                {
                    offeredCipherSuites[offeredCipherSuites.Length - 1] = CipherSuite.TLS_FALLBACK_SCSV;
                }
            }

            clientState.OfferedCompressionMethods = new short[] { CompressionMethod.cls_null };

            byte[] session_id = DtlsHelper.EMPTY_BYTES;
            if (clientState.TlsSession != null)
            {
                session_id = clientState.TlsSession.SessionID;
                if (session_id == null || session_id.Length > 32)
                {
                    session_id = DtlsHelper.EMPTY_BYTES;
                }
            }

            int totalLength = 2;

            totalLength += securityParameters.ClientRandom.Length;
            totalLength += 1 + session_id.Length;

            if (cookie != null)
            {
                totalLength += cookie.Length + 1;
            }
            else
            {
                totalLength += 1;
            }

            totalLength += 2 + 2 * offeredCipherSuites.Length;
            totalLength += 1 + clientState.OfferedCompressionMethods.Length;
            totalLength += DtlsHelper.CalculateExtensionsLength(clientState.ClientExtensions);

            int         capacity     = DtlsHelper.HANDSHAKE_MESSAGE_HEADER_LENGTH + totalLength;
            IByteBuffer data         = Unpooled.Buffer(capacity);
            short       currSequence = sequence++;

            DtlsHelper.WriteHandshakeHeader(currSequence, MessageType.CLIENT_HELLO, data, totalLength);
            data.WriteByte(client_version.MajorVersion);
            data.WriteByte(client_version.MinorVersion);

            data.WriteBytes(securityParameters.ClientRandom);

            // Session ID
            data.WriteByte(session_id.Length);
            data.WriteBytes(session_id);

            //Cookie
            if (cookie != null)
            {
                data.WriteByte(cookie.Length);
                data.WriteBytes(cookie);
            }
            else
            {
                data.WriteBytes(DtlsHelper.EMPTY_BYTES_WITH_LENGTH);
            }

            data.WriteShort(2 * offeredCipherSuites.Length);
            for (int i = 0; i < offeredCipherSuites.Length; i++)
            {
                data.WriteShort(offeredCipherSuites[i]);
            }

            data.WriteByte(clientState.OfferedCompressionMethods.Length);
            for (int i = 0; i < clientState.OfferedCompressionMethods.Length; i++)
            {
                data.WriteByte(clientState.OfferedCompressionMethods[i]);
            }

            // Extensions
            if (clientState.ClientExtensions != null)
            {
                DtlsHelper.WriteExtensions(data, clientState.ClientExtensions);
            }

            if (protocolVersion == null)
            {
                recordLayer.SetWriteVersion(ProtocolVersion.DTLSv10);
            }
            else
            {
                recordLayer.SetWriteVersion(protocolVersion);
            }

            recordLayer.Send(currSequence, MessageType.CLIENT_HELLO, data);
            handshakeState = State.CLIENT_HELLO_SENT;

            if (handler != null)
            {
                handler.handshakeStarted(channel);
            }
        }