Result Fragment_ClientHello_RSA(Fragments.ClientHello frag) { var serverhelloBody = new Fragments.ServerHello(ProtocolVersion.TLSv1_2, _params.ServerRandom, _params.Session, _params.Cipher.CipherSuite); var certificateBody = new Fragments.Certificate(new[] { new X509Certificate2(_pubkeyfile) }, false); var serverhellodoneBody = new Fragments.ServerHelloDone(); var responseFragments = _params.ClientCertificateRequire ? new[] { new Handshakes.Fragment(HandshakeType.Server_Hello, serverhelloBody), new Handshakes.Fragment(HandshakeType.Certificate, certificateBody), new Handshakes.Fragment(HandshakeType.Certificate_Request, new Fragments.CertificateRequest()), new Handshakes.Fragment(HandshakeType.Server_Hello_Done, serverhellodoneBody) } : new[] { new Handshakes.Fragment(HandshakeType.Server_Hello, serverhelloBody), new Handshakes.Fragment(HandshakeType.Certificate, certificateBody), new Handshakes.Fragment(HandshakeType.Server_Hello_Done, serverhellodoneBody) }; foreach (var f in responseFragments) { AppendHandshakeMessages(f); LogSessionInfo(f.Body); } return(new PacketResult(new[] { new Records.Handshake(responseFragments) })); }
protected override Result Fragment_ClientHello(Fragments.ClientHello frag) { var sncheck = Fragment_ClientHello_ServerNameCheck(frag); if (sncheck != null) { return(sncheck); } State = TLSSessionState.Client_Hello; _params.ClientRandom = frag.Random; _params.ServerRandom = new TLS.ValueTypes.Random(); _params.Session = new TLS.ValueTypes.Session(frag.Session.ID); if (frag.PreSharedKeys != null && frag.PreSharedKeys.Identities != null && frag.PreSharedKeys.Identities.Length > 0) { Console.WriteLine($"PreSharedKeys: {string.Join("", frag.PreSharedKeys.Identities[0].Identity.Select(a => a.ToString("X2")))}"); } //if (frag.PreSharedKeys == null || frag.PreSharedKeys.Identities == null || frag.PreSharedKeys.Identities.Length == 0) //{ var result = Fragment_ClientHello_New(frag); State = TLSSessionState.Server_Finished; return(result); //} //else //{ // var result = Fragment_ClientHello_Resumption(frag); // State = TLSSessionState.Server_Finished; // return result; //} }
protected virtual Result Fragment_ClientHello(Fragments.ClientHello frag) { var sncheck = Fragment_ClientHello_ServerNameCheck(frag); if (sncheck != null) { return(sncheck); } State = TLSSessionState.Client_Hello; _params.ClientRandom = frag.Random; _params.ServerRandom = new TLS.ValueTypes.Random(); if (_params.EnableTls13) // only when this is TLS13 server and client is TLS12, orelse ERR_TLS13_DOWNGRADE_DETECTED will be thrown from client { _params.ServerRandom.UpdateLastBytesForTLS12Session(); } _params.Session = new TLS.ValueTypes.Session(Guid.NewGuid()); var result = _params.Cipher.IsRsaKeyExchange ? Fragment_ClientHello_RSA(frag) : Fragment_ClientHello_ECDH(frag); State = TLSSessionState.Server_Hello_Done; return(result); }
protected virtual Result Fragment_ClientHello_ServerNameCheck(Fragments.ClientHello frag) { if (_params.ServerNameCheck) { if (frag.ServerName != null && frag.ServerName.Length > 0) { var subject = new X509Certificate2(_pubkeyfile, "").Subject.Split(new[] { ',' }); var cn = subject.First(a => a.StartsWith("CN=")).Trim().Split(new[] { '=' })[1]; if (!frag.ServerName.Contains(cn)) { return(Result.FatalAlert(AlertDescription.unrecognized_name, "ServerName Extension in [ClientHello] NOT MATCH")); } } else { return(Result.FatalAlert(AlertDescription.missing_extension, "ServerName Extension Missing in [ClientHello]")); } } return(null); }
Result Fragment_ClientHello_ECDH(Fragments.ClientHello frag) { var ecdhpub = GeneratePubKey(); var signdata = _params.ClientRandom.Data.Concat(_params.ServerRandom.Data).Concat(Fragments.ServerKeyExchange.ServerECDHParams(_params.KeyExchangeCurve, ecdhpub)).ToArray(); var signature = MakeSignatureWithCertificate(signdata); var serverhelloBody = new Fragments.ServerHello(ProtocolVersion.TLSv1_2, _params.ServerRandom, _params.Session, _params.Cipher.CipherSuite); var certificateBody = new Fragments.Certificate(new[] { new X509Certificate2(_pubkeyfile) }, false); var serverkeyexBody = new Fragments.ServerKeyExchange(_params.KeyExchangeCurve, ecdhpub, _params.SignatureAlgorithm, signature); var serverhellodoneBody = new Fragments.ServerHelloDone(); var responseFragments = _params.ClientCertificateRequire ? new[] { new Handshakes.Fragment(HandshakeType.Server_Hello, serverhelloBody), new Handshakes.Fragment(HandshakeType.Certificate, certificateBody), new Handshakes.Fragment(HandshakeType.Server_Key_Exchange, serverkeyexBody), new Handshakes.Fragment(HandshakeType.Certificate_Request, new Fragments.CertificateRequest()), new Handshakes.Fragment(HandshakeType.Server_Hello_Done, serverhellodoneBody) } : new[] { new Handshakes.Fragment(HandshakeType.Server_Hello, serverhelloBody), new Handshakes.Fragment(HandshakeType.Certificate, certificateBody), new Handshakes.Fragment(HandshakeType.Server_Key_Exchange, serverkeyexBody), new Handshakes.Fragment(HandshakeType.Server_Hello_Done, serverhellodoneBody) }; foreach (var f in responseFragments) { AppendHandshakeMessages(f); LogSessionInfo(f.Body); } return(new PacketResult(new[] { new Records.Handshake(responseFragments) })); }
Result Fragment_ClientHello_Resumption(Fragments.ClientHello frag) { throw new NotImplementedException(); }
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) })); }