public override byte[] SignData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePrivateKey privateKey) { var ms = new MemoryStream(privateKey.KeyValue); var pemReader = new PemReader(new StreamReader(ms)); var keyParam = pemReader.ReadObject(); var key = keyParam as AsymmetricCipherKeyPair; var signer = new ECDsaSigner(); signer.Init(true, key.Private); var hashedData = hashAlgorithm.ComputeHash(data); Log.Trace("Hashing data (S):" + BitConverter.ToString(data)); Log.Trace("Hashed data (S):" + BitConverter.ToString(hashedData)); var sig = signer.GenerateSignature(hashedData); // test verify var _tmpEcPubkey = key.Public as ECPublicKeyParameters; Log.Debug("Associated PubKey Q: " + BitConverter.ToString(_tmpEcPubkey.Q.GetEncoded())); var signerTest = new ECDsaSigner(); signerTest.Init(false, key.Public); var result = signerTest.VerifySignature(hashedData, sig[0], sig[1]); if (!result) { throw new CryptographicUnexpectedOperationException("Invalid!!!"); } Log.Debug("R value: " + sig[0].SignValue + " " + sig[0].LongValue); Log.Debug("S value: " + sig[1].SignValue + " " + sig[1].LongValue); // TODO: check how BigIntegers are encoded before sent over the wire // Maybe DER encoding of R and S as integer would do it. However for the moment it works with stuffing 0x00 in. var rl = new List<byte>(sig[0].ToByteArray()); var sl = new List<byte>(sig[1].ToByteArray()); while (rl.Count < 33) { rl.Insert(0, 0x00); } while (sl.Count < 33) { sl.Insert(0, 0x00); } var r = rl.ToArray(); var s = sl.ToArray(); var rs = new byte[r.Length + s.Length]; Buffer.BlockCopy(r, 0, rs, 0, r.Length); Buffer.BlockCopy(s, 0, rs, r.Length, s.Length); var derSig = DEREncodeSignature(rs); // Log.Debug("DER Signature (S): " + BitConverter.ToString(derSig)); Log.Trace("Signature R (S)" + BitConverter.ToString(r)); Log.Trace("Signature S (S)" + BitConverter.ToString(s)); return derSig; }
public static void Main(string[] args) { SecurityParameters securityParameters = new SecurityParameters(); securityParameters.MaximumVersion = ProtocolVersion.SSL3_0; if (args.Length < 2) { Console.WriteLine("Usage: TLSServer.exe cert.pem key.xml"); return; } else if (args.Length >= 2) { X509CertificateCollection certs = new X509CertificateCollection(); for (int i = 0; i < args.Length - 1; i++) { certs.Add(new X509Certificate(args[i])); } // Get plugin manager for importing the private key string path = System.Reflection.Assembly.GetAssembly(typeof(HandshakeSession)).Location; string directory = Path.GetDirectoryName(path); CipherSuitePluginManager pluginManager = new CipherSuitePluginManager(directory); // Import the private key into asymmetric algorithm byte[] privateKeyData = File.ReadAllBytes(args[args.Length - 1]); CertificatePrivateKey privateKey = pluginManager.GetPrivateKey(privateKeyData); securityParameters.AddCertificate(certs, privateKey); securityParameters.CipherSuiteIDs.AddRange(pluginManager.GetSupportedCipherSuiteIDs(securityParameters.MaximumVersion, certs[0], false)); } try { TcpListener tcpListener = new TcpListener(IPAddress.Any, 4433); tcpListener.Start(); while (true) { TcpClient tcpClient = tcpListener.AcceptTcpClient(); Console.WriteLine("Accepted client"); TLSServer server = new TLSServer(tcpClient, securityParameters); Thread thread = new Thread(new ThreadStart(server.Thread)); thread.Start(); } } catch (SocketException) { Console.WriteLine("Unable to listen to socket"); return; } }
/// <summary> /// Called by TLS server to create his ephemeral keys. /// TODO: get information about which ECC curve should be used /// </summary> /// <param name="version"></param> /// <returns></returns> public override byte[] GetServerKeys(ProtocolVersion version, CertificatePrivateKey certPrivateKey) { var ms = new MemoryStream(certPrivateKey.KeyValue); var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(new StreamReader(ms)); var keyParam = pemReader.ReadObject(); var key = keyParam as AsymmetricCipherKeyPair; var pk = key.Public as ECPublicKeyParameters; var certCurve = pk.Q.Curve; string curveName = string.Empty; for (int i = 0; i < knownCurveNames.Length; i++) { var curveParams = SecNamedCurves.GetByName(knownCurveNames[i]); if (certCurve.GetHashCode() == curveParams.Curve.GetHashCode()) { curveName = knownCurveNames[i]; break; } } if (curveName == string.Empty) { throw new InvalidOperationException("Could not find EC curve for server private key"); } this.logger?.Debug("Getting server keys for curve '{0}'.", curveName); this.GenerateKeys(curveName); byte[] pubKeyBytes = this.publicKey.Q.GetEncoded(); byte[] serverKeyBytes = new byte[4 + pubKeyBytes.Length]; serverKeyBytes[0] = 3; if (curveName.Contains("192")) { serverKeyBytes[2] = (byte) EccNamedCurve.Secp192R1; // 19: Should match curve type > secp192r1 } else { serverKeyBytes[2] = (byte)EccNamedCurve.Secp256R1; // 23: Should match curve type > secp256r1 if (curveName.StartsWith("brainpool")) { serverKeyBytes[2] = (byte) EccNamedCurve.BrainpoolP256R1; } } serverKeyBytes[3] = (byte)pubKeyBytes.Length; Buffer.BlockCopy(pubKeyBytes, 0, serverKeyBytes, 4, pubKeyBytes.Length); return serverKeyBytes; }
public override byte[] SignData(byte[] buffer, HashAlgorithm hashAlgorithm, CertificatePrivateKey privateKey) { if (!(privateKey.Algorithm is ECDsaCng)) { throw new Exception("ECDSA signature requires ECDSA private key"); } ECDsaCng ecdsaKey = (ECDsaCng)privateKey.Algorithm; ecdsaKey.HashAlgorithm = GetCngAlgorithm(hashAlgorithm); byte[] signature = ecdsaKey.SignData(buffer); signature = DEREncodeSignature(signature); return(signature); }
public override byte[] SignData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePrivateKey privateKey) { if (hashAlgorithm != null && !(hashAlgorithm is SHA1)) { throw new Exception("DSA signature requires SHA1 hash algorithm"); } if (!(privateKey.Algorithm is DSACryptoServiceProvider)) { throw new Exception("DSA signature requires DSA private key"); } DSACryptoServiceProvider dsaKey = (DSACryptoServiceProvider) privateKey.Algorithm; if (dsaKey.PublicOnly) { throw new Exception("DSA private key required for signing"); } return DEREncodeSignature(dsaKey.SignData(data)); }
public static void Main(string[] args) { SecurityParameters securityParameters = new SecurityParameters(); securityParameters.CipherSuiteIDs.Add(0x000a); securityParameters.ServerCertificateValidationCallback = new ServerCertificateValidationCallback(CertificateValidationCallback); securityParameters.ClientCertificateSelectionCallback = new ClientCertificateSelectionCallback(CertificateSelectionCallback); if (args.Length >= 2) { X509CertificateCollection certs = new X509CertificateCollection(); for (int i = 0; i < args.Length - 1; i++) { certs.Add(new X509Certificate(args[i])); } // Get plugin manager for importing the private key string path = System.Reflection.Assembly.GetAssembly(typeof(AaltoTLS.HandshakeLayer.HandshakeSession)).Location; string directory = Path.GetDirectoryName(path); CipherSuitePluginManager pluginManager = new CipherSuitePluginManager(directory); // Import the private key into asymmetric algorithm byte[] privateKeyData = File.ReadAllBytes(args[args.Length - 1]); CertificatePrivateKey privateKey = pluginManager.GetPrivateKey(privateKeyData); securityParameters.AddCertificate(certs, privateKey); } string host = "www.mikestoolbox.net"; int port = 443; string request = "GET / HTTP/1.1\r\nHost: " + host + "\r\n\r\n"; try { TcpClient tcpClient = new TcpClient(host, port); NetworkStream ns = tcpClient.GetStream(); SecureSession session = new SecureSession(ns, securityParameters); session.PerformClientHandshake(host); session.Send(Encoding.UTF8.GetBytes(request)); byte[] received = session.Receive(); Console.WriteLine("Received data: " + Encoding.UTF8.GetString(received)); session.Close(); } catch (SocketException) { Console.WriteLine("Unable to connect to server"); return; } }
protected byte[] GenerateSignature(CertificatePrivateKey privateKey, byte[] data) { // This array contains our results byte[] signedParams = new byte[0]; byte[] temp; // Get the corresponding signer for private key SignatureAlgorithm sigAlg = _pluginManager.GetSignatureAlgorithmByOid(privateKey.Oid); if (sigAlg == null) { throw new AlertException(AlertDescription.IllegalParameter, "Signer for given private key not found"); } // Select hash algorithm, null means SSLv3/TLSv1 hash HashAlgorithm hashAlgorithm = null; if (_version.HasSelectableSighash) { // FIXME: Not checked to be same as negotiated, but SHA-1 should be safe //byte hashAlgorithmType = 2; // SHA-1 byte hashAlgorithmType = (byte)HashAlgorithmType.Sha256; // for LMN we use SHA256 byte signAlgorithmType = sigAlg.SignatureAlgorithmType; hashAlgorithm = GetSignatureHashAlgorithm(sigAlg, hashAlgorithmType); // Update signed parameters temp = new byte[signedParams.Length + 2]; Buffer.BlockCopy(signedParams, 0, temp, 0, signedParams.Length); temp[signedParams.Length] = hashAlgorithmType; temp[signedParams.Length + 1] = signAlgorithmType; signedParams = temp; } // Sign the actual data byte[] signature = sigAlg.SignData(_version, data, hashAlgorithm, privateKey); // Add signature to the end of the signedParams temp = new byte[signedParams.Length + 2 + signature.Length]; Buffer.BlockCopy(signedParams, 0, temp, 0, signedParams.Length); temp[signedParams.Length] = (byte)(signature.Length >> 8); temp[signedParams.Length + 1] = (byte)(signature.Length); Buffer.BlockCopy(signature, 0, temp, signedParams.Length + 2, signature.Length); signedParams = temp; return(signedParams); }
/// <summary> /// Called by TLS server to create his ephemeral keys. /// TODO: get information about which ECC curve should be used /// </summary> /// <param name="version"></param> /// <returns></returns> public override byte[] GetServerKeys(ProtocolVersion version, CertificatePrivateKey certPrivateKey) { var ms = new MemoryStream(certPrivateKey.KeyValue); var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(new StreamReader(ms)); var keyParam = pemReader.ReadObject(); var key = keyParam as AsymmetricCipherKeyPair; var pk = key.Public as ECPublicKeyParameters; var certCurve = pk.Q.Curve; string curveName = string.Empty; for (int i = 0; i < knownCurveNames.Length; i++) { var curveParams = SecNamedCurves.GetByName(knownCurveNames[i]); if (certCurve.GetHashCode() == curveParams.Curve.GetHashCode()) { curveName = knownCurveNames[i]; break; } } if (curveName == string.Empty) { throw new InvalidOperationException("Could not find EC curve for server private key"); } this.logger?.Debug("Getting server keys for curve '{0}'.", curveName); this.GenerateKeys(curveName); byte[] pubKeyBytes = this.publicKey.Q.GetEncoded(); byte[] serverKeyBytes = new byte[4 + pubKeyBytes.Length]; serverKeyBytes[0] = 3; // get named curve for curve id if (Enum.TryParse <EccNamedCurve>(curveName, true, out var curve) == false) { throw new InvalidOperationException("Could not find named curve for: " + curveName); } serverKeyBytes[2] = (byte)curve; serverKeyBytes[3] = (byte)pubKeyBytes.Length; Buffer.BlockCopy(pubKeyBytes, 0, serverKeyBytes, 4, pubKeyBytes.Length); return(serverKeyBytes); }
public void AddCertificate(X509CertificateCollection certificate, CertificatePrivateKey privateKey) { if (certificate == null) { throw new ArgumentNullException("certificate"); } if (privateKey == null) { throw new ArgumentNullException("privateKey"); } if (certificate.Count == 0) { throw new ArgumentException("certificate"); } _availableCertificates.Add(certificate); _availablePrivateKeys.Add(privateKey); }
public CertificatePrivateKey GetPrivateKey(byte[] keyData) { foreach (CipherSuitePlugin plugin in _plugins) { string[] signatureIDs = plugin.SupportedSignatureAlgorithms; foreach (string id in signatureIDs) { SignatureAlgorithm signatureAlgorithm = plugin.GetSignatureAlgorithm(id); CertificatePrivateKey privateKey = signatureAlgorithm.ImportPrivateKey(keyData); if (privateKey != null) { return(privateKey); } } } return(null); }
public static void Load() { string path = System.Reflection.Assembly.GetExecutingAssembly().Location; string directory = Path.GetDirectoryName(path); CipherSuitePluginManager pluginManager = new CipherSuitePluginManager(directory); X509Certificate2 cert = new X509Certificate2(Convert.FromBase64String(Pfx), "temp", X509KeyStorageFlags.Exportable); PublicKey = new CertificatePublicKey(cert); PrivateKey = new CertificatePrivateKey("1.2.840.113549.1.1.1", cert.PrivateKey); SecurityParameters = new SecurityParameters() { MaximumVersion = ProtocolVersion.TLS1_0 }; SecurityParameters.CipherSuiteIDs.Add(0x0039); // TLS_DHE_RSA_WITH_AES_256_CBC_SHA SecurityParameters.AddCertificate(new X509CertificateCollection(new X509Certificate[] { cert }), PrivateKey); Certificate = cert; }
public override byte[] GetServerKeys(ProtocolVersion version, CertificatePrivateKey certPrivateKey) { // Set default length for P; _pLength = 1024 / 8; // Generate P, G and X BigInteger p, g; GenerateKey(_pLength * 8, out p, out g); BigInteger x = GenerateX(p); // Calculate the server parameter BigInteger Ys = BigInteger.ModPow(g, x, p); // Store all values to the byte arrays _dh_p = BigIntegerToByteArray(p, _pLength); _dh_g = BigIntegerToByteArray(g, 1); // Single byte _dh_x = BigIntegerToByteArray(x, _pLength); _dh_Ys = BigIntegerToByteArray(Ys, _pLength); int idx = 0; byte[] data = new byte[2 + _dh_p.Length + 2 + _dh_g.Length + 2 + _dh_Ys.Length]; data[idx++] = (byte)(_dh_p.Length >> 8); data[idx++] = (byte)(_dh_p.Length); Array.Copy(_dh_p, 0, data, idx, _dh_p.Length); idx += _dh_p.Length; data[idx++] = (byte)(_dh_g.Length >> 8); data[idx++] = (byte)(_dh_g.Length); Array.Copy(_dh_g, 0, data, idx, _dh_g.Length); idx += _dh_g.Length; data[idx++] = (byte)(_dh_Ys.Length >> 8); data[idx++] = (byte)(_dh_Ys.Length); Array.Copy(_dh_Ys, 0, data, idx, _dh_Ys.Length); idx += _dh_Ys.Length; return(data); }
public override byte[] GetServerKeys(ProtocolVersion version, CertificatePrivateKey certPrivateKey) { // Set default length for P; _pLength = 1024/8; // Generate P, G and X BigInteger p, g; GenerateKey(_pLength*8, out p, out g); BigInteger x = GenerateX(p); // Calculate the server parameter BigInteger Ys = BigInteger.ModPow(g, x, p); // Store all values to the byte arrays _dh_p = BigIntegerToByteArray(p, _pLength); _dh_g = BigIntegerToByteArray(g, 1); // Single byte _dh_x = BigIntegerToByteArray(x, _pLength); _dh_Ys = BigIntegerToByteArray(Ys, _pLength); int idx = 0; byte[] data = new byte[2+_dh_p.Length + 2+_dh_g.Length + 2+_dh_Ys.Length]; data[idx++] = (byte) (_dh_p.Length >> 8); data[idx++] = (byte) (_dh_p.Length); Array.Copy(_dh_p, 0, data, idx, _dh_p.Length); idx += _dh_p.Length; data[idx++] = (byte) (_dh_g.Length >> 8); data[idx++] = (byte) (_dh_g.Length); Array.Copy(_dh_g, 0, data, idx, _dh_g.Length); idx += _dh_g.Length; data[idx++] = (byte) (_dh_Ys.Length >> 8); data[idx++] = (byte) (_dh_Ys.Length); Array.Copy(_dh_Ys, 0, data, idx, _dh_Ys.Length); idx += _dh_Ys.Length; return data; }
public abstract void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data);
// Returns the server key exchange message as a byte array public abstract byte[] GetServerKeys(ProtocolVersion version, CertificatePrivateKey certPrivateKey);
// Returns the server key exchange message as a byte array public abstract byte[] GetServerKeys(ProtocolVersion version, CertificatePrivateKey certPrivateKey);
public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data) { if (_dh_p.Length == 0 || _dh_g.Length == 0 || _dh_Ys.Length == 0) throw new Exception("Server keys not generated/received"); if (((data[0] << 8) | data[1]) != data.Length-2) throw new Exception("Client key exchange vector length incorrect"); // Store the client parameter byte[] _dh_Yc = new byte[data.Length-2]; Buffer.BlockCopy(data, 2, _dh_Yc, 0, data.Length-2); // Create corresponding BigIntegers BigInteger p = ByteArrayToBigInteger(_dh_p); BigInteger x = ByteArrayToBigInteger(_dh_x); BigInteger Yc = ByteArrayToBigInteger(_dh_Yc); // Calculate pre-master secret BigInteger Z = BigInteger.ModPow(Yc, x, p); _preMasterSecret = BigIntegerToByteArray(Z, _pLength); }
public override byte[] GetServerKeys(ProtocolVersion version, CertificatePrivateKey certPrivateKey) { // No server keys sent in RSA key exchange return(null); }
public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data) { if (!(privateKey.Algorithm is RSACryptoServiceProvider)) { throw new CryptographicException("RSA key exchange requires RSA private key"); } RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)privateKey.Algorithm; try { // TLS 1.0 and later require a useless vector length if (version != ProtocolVersion.SSL3_0) { if (((data[0] << 8) | data[1]) != data.Length-2) { throw new Exception("Client key exchange vector length incorrect"); } // Remove vector length from the data bytes byte[] tmpArray = new byte[data.Length-2]; Buffer.BlockCopy(data, 2, tmpArray, 0, tmpArray.Length); data = tmpArray; } data = rsa.Decrypt(data, false); if (data.Length != 48) { throw new Exception("Invalid premaster secret length"); } if (data[0] != clientVersion.Major || data[1] != clientVersion.Minor) { throw new Exception("RSA client key version mismatch"); } _preMasterSecret = data; } catch (Exception) { // Randomize the pre-master secret in case of an error RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); _preMasterSecret = new byte[48]; rngCsp.GetBytes(_preMasterSecret); } }
public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data) { throw new Exception("Client keys received in null key exchange"); }
public override byte[] SignData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePrivateKey privateKey) { var ms = new MemoryStream(privateKey.KeyValue); var pemReader = new PemReader(new StreamReader(ms)); var keyParam = pemReader.ReadObject(); var key = keyParam as AsymmetricCipherKeyPair; var signer = new ECDsaSigner(); signer.Init(true, key.Private); var hashedData = hashAlgorithm.ComputeHash(data); Log.Trace("Hashing data (S):" + BitConverter.ToString(data)); Log.Trace("Hashed data (S):" + BitConverter.ToString(hashedData)); var bitLength = ((ECPrivateKeyParameters)key.Private).Parameters.Curve.FieldSize; Log.Trace("Signing for bit length {@l}", bitLength); var sig = signer.GenerateSignature(hashedData); var maxRetries = 500; while (sig[0].BitLength != bitLength || sig[1].BitLength != bitLength) { sig = signer.GenerateSignature(hashedData); if (maxRetries-- < 1) { throw new InvalidOperationException("SignData finally failed"); } } // test verify var _tmpEcPubkey = key.Public as ECPublicKeyParameters; Log.Debug("Associated PubKey Q: " + BitConverter.ToString(_tmpEcPubkey.Q.GetEncoded())); var signerTest = new ECDsaSigner(); signerTest.Init(false, key.Public); var result = signerTest.VerifySignature(hashedData, sig[0], sig[1]); if (!result) { throw new CryptographicUnexpectedOperationException("Invalid!!!"); } Log.Debug("R value: " + sig[0].SignValue + " " + sig[0].LongValue); Log.Debug("S value: " + sig[1].SignValue + " " + sig[1].LongValue); // TODO: check how BigIntegers are encoded before sent over the wire // Maybe DER encoding of R and S as integer would do it. However for the moment it works with stuffing 0x00 in. var rl = new List <byte>(sig[0].ToByteArray()); var sl = new List <byte>(sig[1].ToByteArray()); //while (rl.Count < 33) //{ // rl.Insert(0, 0x00); //} //while (sl.Count < 33) //{ // sl.Insert(0, 0x00); //} var r = rl.ToArray(); var s = sl.ToArray(); var rs = new byte[r.Length + s.Length]; Buffer.BlockCopy(r, 0, rs, 0, r.Length); Buffer.BlockCopy(s, 0, rs, r.Length, s.Length); var derSig = DEREncodeSignature(rs); // Log.Debug("DER Signature (S): " + BitConverter.ToString(derSig)); Log.Trace("Signature R (S)" + BitConverter.ToString(r)); Log.Trace("Signature S (S)" + BitConverter.ToString(s)); return(derSig); }
public override byte[] SignData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePrivateKey privateKey) { if (hashAlgorithm != null && !(hashAlgorithm is SHA1)) { throw new Exception("DSA signature requires SHA1 hash algorithm"); } if (!(privateKey.Algorithm is DSACryptoServiceProvider)) { throw new Exception("DSA signature requires DSA private key"); } DSACryptoServiceProvider dsaKey = (DSACryptoServiceProvider)privateKey.Algorithm; if (dsaKey.PublicOnly) { throw new Exception("DSA private key required for signing"); } return(DEREncodeSignature(dsaKey.SignData(data))); }
// WARNING: these are called with null hash algorithm for SSL 3.0, TLS 1.0 and TLS 1.1 public abstract byte[] SignData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePrivateKey privateKey);
public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data) { throw new Exception("Client keys received in null key exchange"); }
public override byte[] GetServerKeys(ProtocolVersion version, CertificatePrivateKey certPrivateKey) { return(null); }
public override byte[] SignData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePrivateKey privateKey) { return new byte[0]; }
public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length < 1) { throw new ArgumentException("data"); } byte[] ecPointData = new byte[data[0]]; Buffer.BlockCopy(data, 1, ecPointData, 0, ecPointData.Length); ECPoint ecPoint = domainParameters.Curve.DecodePoint(ecPointData); var theirPublicKey = new ECPublicKeyParameters(ecPoint, domainParameters); // Calculate the actual agreement var agreement = new ECDHBasicAgreement(); agreement.Init(this.privateKey); preMasterSecret = BigIntegerToByteArray(agreement.CalculateAgreement(theirPublicKey), 32); this.logger?.Debug("Pre-Master secret: " + BitConverter.ToString(preMasterSecret)); }
public override byte[] GetServerKeys(ProtocolVersion version, CertificatePrivateKey certPrivateKey) { // No server keys sent in RSA key exchange return null; }
public override byte[] SignData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePrivateKey privateKey) { if (!(privateKey.Algorithm is RSACryptoServiceProvider)) { throw new Exception("RSA signature requires RSA private key"); } RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)privateKey.Algorithm; if (rsaKey.PublicOnly) { throw new Exception("RSA private key required for signing"); } if (hashAlgorithm == null) { // Before TLS 1.2 RSA signatures always used MD5+SHA1 // MD5+SHA1 is not supported by .NET, so we need custom code return(TLSv1SignData(rsaKey, data)); } else { // Starting from TLS 1.2 the standard signature is used return(rsaKey.SignData(data, hashAlgorithm)); } }
public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data) { if (data[0] != data.Length - 1) { throw new Exception("Incorrect ECPoint length"); } // Exctract the ECPoint byte[] ecPoint = new byte[data.Length - 1]; Buffer.BlockCopy(data, 1, ecPoint, 0, ecPoint.Length); // Create key blob and public key byte[] keyBlob = Point2Blob(ecPoint); _publicKey = ECDiffieHellmanCngPublicKey.FromByteArray(keyBlob, CngKeyBlobFormat.EccPublicBlob); }
public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length < 1) { throw new ArgumentException("data"); } byte[] ecPointData = new byte[data[0]]; Buffer.BlockCopy(data, 1, ecPointData, 0, ecPointData.Length); ECPoint ecPoint = domainParameters.Curve.DecodePoint(ecPointData); var theirPublicKey = new ECPublicKeyParameters(ecPoint, domainParameters); // Calculate the actual agreement var agreement = new ECDHBasicAgreement(); agreement.Init(this.privateKey); var pmsLength = this.privateKey.Parameters.Curve.FieldSize / 8; preMasterSecret = BigIntegerToByteArray(agreement.CalculateAgreement(theirPublicKey), pmsLength); this.logger?.Debug("Pre-Master secret: " + BitConverter.ToString(preMasterSecret)); }
public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data) { if (!(privateKey.Algorithm is RSACryptoServiceProvider)) { throw new CryptographicException("RSA key exchange requires RSA private key"); } RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)privateKey.Algorithm; try { // TLS 1.0 and later require a useless vector length if (version != ProtocolVersion.SSL3_0) { if (((data[0] << 8) | data[1]) != data.Length - 2) { throw new Exception("Client key exchange vector length incorrect"); } // Remove vector length from the data bytes byte[] tmpArray = new byte[data.Length - 2]; Buffer.BlockCopy(data, 2, tmpArray, 0, tmpArray.Length); data = tmpArray; } data = rsa.Decrypt(data, false); if (data.Length != 48) { throw new Exception("Invalid premaster secret length"); } if (data[0] != clientVersion.Major || data[1] != clientVersion.Minor) { throw new Exception("RSA client key version mismatch"); } _preMasterSecret = data; } catch (Exception) { // Randomize the pre-master secret in case of an error RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider(); _preMasterSecret = new byte[48]; rngCsp.GetBytes(_preMasterSecret); } }
public abstract void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data);
public override byte[] GetServerKeys(ProtocolVersion version, CertificatePrivateKey certPrivateKey) { return null; }
public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length < 1) { throw new ArgumentException("data"); } byte[] ecPointData = new byte[data[0]]; Buffer.BlockCopy(data, 1, ecPointData, 0, ecPointData.Length); ECPoint ecPoint = _domainParameters.Curve.DecodePoint(ecPointData); ECPublicKeyParameters theirPublicKey = new ECPublicKeyParameters(ecPoint, _domainParameters); // Calculate the actual agreement ECDHBasicAgreement agreement = new ECDHBasicAgreement(); agreement.Init(_privateKey); _preMasterSecret = BigIntegerToByteArray(agreement.CalculateAgreement(theirPublicKey), 32); }
public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data) { if (_dh_p.Length == 0 || _dh_g.Length == 0 || _dh_Ys.Length == 0) { throw new Exception("Server keys not generated/received"); } if (((data[0] << 8) | data[1]) != data.Length - 2) { throw new Exception("Client key exchange vector length incorrect"); } // Store the client parameter byte[] _dh_Yc = new byte[data.Length - 2]; Buffer.BlockCopy(data, 2, _dh_Yc, 0, data.Length - 2); // Create corresponding BigIntegers BigInteger p = ByteArrayToBigInteger(_dh_p); BigInteger x = ByteArrayToBigInteger(_dh_x); BigInteger Yc = ByteArrayToBigInteger(_dh_Yc); // Calculate pre-master secret BigInteger Z = BigInteger.ModPow(Yc, x, p); _preMasterSecret = BigIntegerToByteArray(Z, _pLength); }
public override byte[] SignData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePrivateKey privateKey) { if (!(privateKey.Algorithm is RSACryptoServiceProvider)) { throw new Exception("RSA signature requires RSA private key"); } RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)privateKey.Algorithm; if (rsaKey.PublicOnly) { throw new Exception("RSA private key required for signing"); } if (hashAlgorithm == null) { // Before TLS 1.2 RSA signatures always used MD5+SHA1 // MD5+SHA1 is not supported by .NET, so we need custom code return TLSv1SignData(rsaKey, data); } else { // Starting from TLS 1.2 the standard signature is used return rsaKey.SignData(data, hashAlgorithm); } }