Beispiel #1
0
        Result Fragment_EncryptedHandshake(Handshakes.EncryptedFragment frag)
        {
            if (State == TLSSessionState.Client_ChangeCipherSpec)
            {
                var encrypt        = frag.EncryptedData;
                var decryptedBytes = _params.Cipher.BulkDecrypt(encrypt, frag.IV);
                // 14 00 00 0C
                // 12-bytes-verify-data
                // 32-bytes-mac
                // 15-bytes-padding
                // 0x0F(padding-length)
                if (decryptedBytes[0] == 0x14 && Utils.ToUInt24(decryptedBytes, 1) == 12)
                {
                    var fragWithoutMac = new Handshakes.Fragment(decryptedBytes.Take(4 + _params.Cipher.VerifyDataLength).ToArray());
                    AppendHandshakeMessages(fragWithoutMac);

                    var fragWithMac = new Handshakes.Fragment(decryptedBytes);
                    return(Fragment_Handshake(fragWithMac));
                }
                else
                {
                    return(Result.FatalAlert(AlertDescription.decrypt_error, $"invalid Client_EncryptedHandshake message"));
                }
            }
            else
            {
                return(Result.FatalAlert(AlertDescription.unexpected_message, $"State [{State}] check failed on Client_EncryptedHandshake message"));
            }
        }
Beispiel #2
0
        protected Result Fragment_Handshake(Handshakes.Fragment frag)
        {
            LogSessionInfo(frag.Body);

            if (frag.Body is Fragments.ClientHello ch)
            {
                return(Fragment_ClientHello(ch));
            }
            else if (frag.Body is Fragments.Certificate cert)
            {
                return(Fragment_ClientCertificate(cert));
            }
            else if (frag.Body is Fragments.CertificateVerify certver)
            {
                return(Fragment_ClientCertificateVerify(certver));
            }
            else if (frag.Body is Fragments.ClientKeyExchange cke)
            {
                return(Fragment_ClientKeyExchange(cke));
            }
            else if (frag.Body is Fragments.Finished cf)
            {
                return(Fragment_ClientFinished(cf));
            }
            else if (frag.Body is Fragments.KeyUpdate ku)
            {
                return(Fragment_ClientKeyUpdate(ku));
            }
            else
            {
                return(Result.FatalAlert(AlertDescription.unexpected_message, $"Unhandled TLS HandshakeFragment.Body {frag.Body.GetType().Name}"));
            }
        }
Beispiel #3
0
        Result Fragment_ClientHello_New(Fragments.ClientHello frag)
        {
            var ecdhpub    = GeneratePubKey();
            var extensions = new TLS.Extensions.Extension[]
            {
                new TLS.Extensions.KeyShare(_params.KeyShare.Group, ecdhpub),
                new TLS.Extensions.SupportedVersions(ProtocolVersion.TLSv1_3)
            };
            var serverhelloBody      = new Fragments.ServerHello(ProtocolVersion.TLSv1_2, _params.ServerRandom, _params.Session, _params.Cipher.CipherSuite, extensions);
            var serverhelloFragment  = new Handshakes.Fragment(HandshakeType.Server_Hello, serverhelloBody);
            var encryptedExtFragment = new Handshakes.Fragment(HandshakeType.Encrypted_Extensions, new Fragments.EncryptedExtensions());
            var certRequestFragment  = new Handshakes.Fragment(HandshakeType.Certificate_Request, new Fragments.CertificateRequest(new byte[0]));
            var certificateFragment  = new Handshakes.Fragment(HandshakeType.Certificate, new Fragments.Certificate(new[] { new X509Certificate2(_pubkeyfile) }, true));

            // add [ServerHello] to list
            AppendHandshakeMessages(serverhelloFragment);
            // get (clienthello + serverhello)
            var clientHello_serverHello = GetHandshakeMessages();

            // calculate shared_secret and HandshakeSecret
            (_params.Cipher as Ciphers.CipherSuiteBase13).KeyExchange(_params.KeyShare.KeyExchange, null, null, _params.ServerKey.Private);
            (_params.Cipher as Ciphers.CipherSuiteBase13).Calculate_HandshakeSecret(clientHello_serverHello);
            // add [EncryptedExtensions] to list
            AppendHandshakeMessages(encryptedExtFragment);
            // add [CertificateRequest] to list
            if (_params.ClientCertificateRequire)
            {
                AppendHandshakeMessages(certRequestFragment);
            }
            // add [Certificate] to list
            AppendHandshakeMessages(certificateFragment);
            // get (clienthello + serverhello + encryptedExtensions + certificate)
            var clientHello_cert = GetHandshakeMessages();
            // get signature for CertificateVerify
            var signature          = MakeCertificateVerifySignature(clientHello_cert);
            var certVerifyFragment = new Handshakes.Fragment(HandshakeType.Certificate_Verify, new Fragments.CertificateVerify(_params.SignatureAlgorithm, signature));

            // add [CertificateVerify] to list
            AppendHandshakeMessages(certVerifyFragment);
            // get (clienthello + serverhello + encryptedExtensions + certificate + certificateVerify)
            var clientHello_certVerify = GetHandshakeMessages();
            // get verifyData for ServerFinished
            var verifyData     = (_params.Cipher as Ciphers.CipherSuiteBase13).GetVerifyData("finished", clientHello_certVerify);
            var finishFragment = new Handshakes.Fragment(HandshakeType.Finished, new Fragments.Finished(verifyData));

            // add [ServerFinished] to list
            AppendHandshakeMessages(finishFragment);
            // before return, calculate ApplicationSecret
            // get (clienthello + serverhello + encryptedExtensions + certificate + certificateVerify + serverFinished)
            var clientHello_serverfinish = GetHandshakeMessages();

            (_params.Cipher as Ciphers.CipherSuiteBase13).Calculate_ApplicationSecret(clientHello_serverfinish);
            // wrap 4 fragments in applicationRecord
            var plainPayload = new List <byte>();

            plainPayload.AddRange(encryptedExtFragment.Data);
            if (_params.ClientCertificateRequire)
            {
                plainPayload.AddRange(certRequestFragment.Data);
            }
            plainPayload.AddRange(certificateFragment.Data);
            plainPayload.AddRange(certVerifyFragment.Data);
            plainPayload.AddRange(finishFragment.Data);

            // log info
            LogSessionInfo(serverhelloFragment.Body);
            LogSessionInfo(encryptedExtFragment.Body);
            if (_params.ClientCertificateRequire)
            {
                LogSessionInfo(certRequestFragment.Body);
            }
            LogSessionInfo(certificateFragment.Body);
            LogSessionInfo(certVerifyFragment.Body);
            LogSessionInfo(finishFragment.Body);

            var encryptedPayload = (_params.Cipher as Ciphers.CipherSuiteBase13).BulkEncrypt_Handshake(plainPayload.ToArray());

            return(new PacketResult(new Records.TLSRecord[]
            {
                new Records.Handshake(new [] { serverhelloFragment }), // ServerHello
                new Records.ChangeCipherSpec(),                        // ChangeCipherSpec
                new Records.ApplicationData(encryptedPayload)          // ApplicationData (EncryptedExtensions,Certificate,CertificateVerify,Finished)
            }));
        }
Beispiel #4
0
 protected void AppendHandshakeMessages(Handshakes.Fragment fragment)
 {
     _handshakeMessages.Add(fragment);
 }