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;
        }
Пример #2
0
        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;
        }
Пример #4
0
        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));
		}
Пример #6
0
        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;
            }
        }
Пример #7
0
        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);
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
        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);
        }
Пример #11
0
        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);
Пример #16
0
 // 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");
		}
Пример #21
0
        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);
        }
Пример #22
0
        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)));
        }
Пример #23
0
		// 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);
Пример #24
0
 public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data)
 {
     throw new Exception("Client keys received in null key exchange");
 }
Пример #25
0
 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;
		}
Пример #29
0
        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));
            }
        }
Пример #30
0
        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);
        }
Пример #31
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);
            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);
            }
        }
Пример #33
0
 public abstract void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data);
		public override byte[] GetServerKeys(ProtocolVersion version, CertificatePrivateKey certPrivateKey)
		{
			return null;
		}
Пример #35
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);
            ECPublicKeyParameters theirPublicKey = new ECPublicKeyParameters(ecPoint, _domainParameters);

            // Calculate the actual agreement
            ECDHBasicAgreement agreement = new ECDHBasicAgreement();

            agreement.Init(_privateKey);
            _preMasterSecret = BigIntegerToByteArray(agreement.CalculateAgreement(theirPublicKey), 32);
        }
Пример #36
0
        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);
            }
        }