Esempio n. 1
0
        internal void Receive(ICertificateProvider certProvider, INetState ns, HttpsReader reader)
        {
            RecordHandshake(reader.Buffer, reader.Length, !reader.IsDecrypted);
            EHandshake handshakeType      = (EHandshake)reader.ReadByte();
            int        handshakeMsgLength = reader.Read24BitInt();

            HttpsReader.VerifyLengthRemaining(reader, handshakeMsgLength, "Ssl handshake");
            switch (handshakeType)
            {
            case EHandshake.ClientHello:
                ReceiveClientHello(certProvider, ns, reader);
                break;

            case EHandshake.ClientKeyExchange:
                ReceiveClientKeyExchange(certProvider, ns, reader);
                break;

            case EHandshake.Finished:
                ReceiveClientFinished(ns, reader);
                break;

            default:
                ns.Send(new HttpsSmsgAlert(ns.Https, 2, 10));
                throw new HttpsException($"sent unknown handshake 0x{handshakeType:X}", reader);
            }
        }
Esempio n. 2
0
        private bool TryGetReader(HttpsSession https, ref byte[] buffer, ref int length, out HttpsReader reader)
        {
            reader = null;
            if (length < 5)
            {
                return(false);
            }
            int fragmentLength = (buffer[3] << 8) + buffer[4] + 5;

            if (length < fragmentLength)
            {
                return(false);
            }
            else if (length == fragmentLength)
            {
                reader = new HttpsReader(https, buffer, length);
                length = 0;
            }
            else
            {
                // todo: this is so inefficient!
                byte[] fragmentBuffer = new byte[fragmentLength];
                Array.Copy(buffer, fragmentBuffer, fragmentLength);
                reader = new HttpsReader(https, fragmentBuffer, fragmentLength);
                Array.Copy(buffer, fragmentLength, buffer, 0, length - fragmentLength);
                length -= fragmentLength;
            }
            return(true);
        }
Esempio n. 3
0
        // --- Https Change Cipher Spec ---

        internal void ReceiveChangeCipherSpec(INetState ns, HttpsReader reader)
        {
            byte payload = reader.ReadByte();

            HttpsReader.VerifyLengthRemaining(reader, 0, "ChangeClientSpec");
            if (payload != 0x01)
            {
                throw new HttpsException($"sent ChangeCipherSpec with wrong payload.", reader);
            }
            SessionIdentifier      = _Handshake.SessionIdentifier;
            SequenceNumberReceived = 0;
            SequenceNumberSent     = 0;
            CipherSuite            = _Handshake.CipherSuite;
            _KeyBlock = _Handshake.GetKeyBlock();
            Decryptor = CipherSuite.GetTransform(_KeyBlock.ClientWriteKey);
            Encryptor = CipherSuite.GetTransform(_KeyBlock.ServerWriteKey);
            // DeMAC = CipherSuite.GetMAC(_KeyBlock.ClientWriteMACKey);
            // EnMAC = CipherSuite.GetMAC(_KeyBlock.ServerWriteMACKey);
            IsClientEncrypting = true;
        }
Esempio n. 4
0
        private void ReceiveClientFinished(INetState ns, HttpsReader reader)
        {
            HttpsCmsgFinished packet = new HttpsCmsgFinished(reader);

            byte[]             allHandshakes = _AllHandshakes.ToArray();
            KeyedHashAlgorithm verify        = CipherSuite.GetHMAC(_MasterSecret);

            verify.Initialize();
            verify.TransformBlock(allHandshakes, 0, allHandshakes.Length - reader.Length, allHandshakes, 0);
            if (ns.Https.Protocol == EProtocol.SSLv30)
            {
                verify.TransformFinalBlock(SslBlocks.SenderClient, 0, SslBlocks.SenderClient.Length);
                if (!ByteArrayEquality(packet.Verification, 0, verify.Hash, 0, packet.Verification.Length))
                {
                    throw new HttpsException("ClientFinished hash did not match computed hash.", reader);
                }
            }
            else
            {
                throw new HttpsException($"Unknown protocol {ns.Https.Protocol}", reader);
            }
            ns.Https.SendChangeCipherSpec(ns, 0x01);
            SendServerFinished(ns, allHandshakes);
        }
Esempio n. 5
0
        // --- Https Handshake ---

        internal void ReceiveHandshake(ICertificateProvider certProvider, INetState ns, HttpsReader reader)
        {
            if (_Handshake == null)
            {
                _Handshake = new HttpsHandshakeSession();
            }
            _Handshake.Receive(certProvider, ns, reader);
        }
Esempio n. 6
0
        // --- Handshake Packets -------------------------------------------------------------------------------------
        // -----------------------------------------------------------------------------------------------------------

        private void ReceiveClientHello(ICertificateProvider certProvider, INetState ns, HttpsReader reader)
        {
            HttpsCmsgHello packet = new HttpsCmsgHello(reader);

            if (packet.SessionID != null)
            {
                throw new HttpsException($"provided a sessionID (unsupported)", reader);
            }
            if (!SupportedCiphers.Select(packet.Ciphers, out CipherSuiteInfo cipherSelected))
            {
                throw new HttpsException("does not support any of our cipher suites", reader);
            }
            CipherSuite   = cipherSelected;
            _ClientRandom = packet.ClientRandom;
            _ServerRandom = new byte[32];
            Randoms.NextBytesUnixTimePrefix(_ServerRandom);
            HttpsWriter serverHello     = new HttpsSmsgHello(ns.Https, CipherSuite.CipherSuite, SessionIdentifier, _ServerRandom);
            HttpsWriter serverCerts     = new HttpsSmsgCertificate(ns.Https, certProvider.HttpsGetCerts());
            HttpsWriter serverHelloDone = new HttpsSmsgHelloDone(ns.Https);

            Send(ns, serverHello);
            Send(ns, serverCerts);
            Send(ns, serverHelloDone);
        }
Esempio n. 7
0
        private void ReceiveClientKeyExchange(ICertificateProvider certProvider, INetState ns, HttpsReader reader)
        {
            HttpsCmsgKeyExchange packet = new HttpsCmsgKeyExchange(reader);

            _PreMasterSecret = certProvider.HttpsCertDecrypt(packet.EncryptedPreMasterSecret);
        }