protected override void ProcessCertificateVerify(HandshakeMessage verify)
        {
            if (_state != HandshakeState.ReceivedClientKeyExchange)
            {
                throw new AlertException(AlertDescription.UnexpectedMessage,
                                         "Certificate verify received at the wrong time");
            }
            if (!_clientCertificateReceived)
            {
                throw new AlertException(AlertDescription.UnexpectedMessage,
                                         "Certificate verify received even though client certificate not received");
            }

            // Get all handshake messages up to, but not including, this one
            byte[] allMessages       = _handshakeStream.ToArray();
            byte[] handshakeMessages = new byte[allMessages.Length - verify.Encode().Length];
            Buffer.BlockCopy(allMessages, 0, handshakeMessages, 0, handshakeMessages.Length);

            // Verify the signature of handshake messages
            CertificatePublicKey publicKey = new CertificatePublicKey(_clientCertificates[0]);
            bool signatureOk = VerifySignature(publicKey, handshakeMessages, verify.Data);

            if (!signatureOk)
            {
                throw new AlertException(AlertDescription.DecodeError,
                                         "Signature from client incorrect");
            }

            // Wait for changecipherspec+finished
            _state = HandshakeState.ReceivedClientKeyExchange;
        }
		public override byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey)
		{
			if (!(publicKey.Algorithm is RSACryptoServiceProvider)) {
				throw new CryptographicException("RSA key exchange requires RSA public key");
			}
			return GetClientKeys(version, clientVersion, (RSACryptoServiceProvider)publicKey.Algorithm);
		}
		public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey key, byte[] signature)
		{
			if (signature.Length == 0) {
				return true;
			}
			return false;
		}
Example #4
0
        protected bool VerifySignature(CertificatePublicKey publicKey, byte[] data, byte[] signedParams)
        {
            // Initialize the signature position and validity
            int  position    = 0;
            bool signatureOk = false;

            // Get the corresponding signer for public key
            SignatureAlgorithm sigAlg = _pluginManager.GetSignatureAlgorithmByOid(publicKey.Oid);

            if (sigAlg == null)
            {
                throw new AlertException(AlertDescription.IllegalParameter,
                                         "Signer for given public key not found");
            }

            // Select hash algorithm, null means SSLv3/TLSv1 hash
            HashAlgorithm hashAlgorithm = null;

            if (_version.HasSelectableSighash)
            {
                byte hashAlgorithmType = signedParams[position++];
                byte signAlgorithmType = signedParams[position++];
                if (sigAlg.SignatureAlgorithmType != signAlgorithmType)
                {
                    throw new AlertException(AlertDescription.DecryptError,
                                             "Certificate signed with invalid signature algorithm");
                }
                if (!sigAlg.SupportsHashAlgorithmType(hashAlgorithmType))
                {
                    throw new AlertException(AlertDescription.DecryptError,
                                             "Certificate signed with invalid hash algorithm");
                }
                hashAlgorithm = GetSignatureHashAlgorithm(sigAlg, hashAlgorithmType);
            }

            // Check that signature length is valid (same as stored)
            int len = (signedParams[position] << 8) | signedParams[position + 1];

            if (len != signedParams.Length - position - 2)
            {
                throw new AlertException(AlertDescription.DecodeError,
                                         "Signature length not valid");
            }
            position += 2;

            // Extract the signature from the end of the signed parameters
            byte[] signature = new byte[len];
            Buffer.BlockCopy(signedParams, position, signature, 0, len);

            // Verify correctness of the signature
            signatureOk = sigAlg.VerifyData(_version, data, hashAlgorithm, publicKey, signature);
            if (!signatureOk)
            {
                throw new AlertException(AlertDescription.DecodeError,
                                         "Signature from server incorrect");
            }

            return(signatureOk);
        }
        public override byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey)
        {
            byte[] ecPoint = Blob2Point(_ecdhCng.PublicKey.ToByteArray());

            byte[] ret = new byte[1+ecPoint.Length];
            ret[0] = (byte) (ecPoint.Length);
            Buffer.BlockCopy(ecPoint, 0, ret, 1, ecPoint.Length);
            return ret;
        }
        public override bool VerifyData(byte[] buffer, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid)) {
                throw new Exception("ECDSA signature verification requires ECDSA public key");
            }

            string curveOid = DER2OID(publicKey.Parameters);
            if (curveOid == null) {
                throw new Exception("Unsupported ECDSA public key parameters");
            }

            byte[] keyData = publicKey.KeyValue;
            if (keyData[0] != 0x04) {
                throw new Exception("Only uncompressed ECDSA keys supported, format: " + keyData[0]);
            }

            UInt32 keyLength;
            byte[] blobMagic;
            if (curveOid.Equals(P256OID)) {
                keyLength = 32;
                blobMagic = Encoding.ASCII.GetBytes("ECS1");
            } else if (curveOid.Equals(P384OID)) {
                keyLength = 48;
                blobMagic = Encoding.ASCII.GetBytes("ECS3");
            } else if (curveOid.Equals(P521OID)) {
                keyLength = 66;
                blobMagic = Encoding.ASCII.GetBytes("ECS5");
            } else {
                throw new Exception("Unsupported ECC curve type OID: " + curveOid);
            }

            if (2*keyLength != keyData.Length-1) {
                throw new Exception("Invalid length of ECDSA public key: " + keyData.Length +
                                    " (should be " + (1+2*keyLength) + ")");
            }
            byte[] lengthData = BitConverter.GetBytes(keyLength);

            // Create the ECC public blob for ECDsaCng class
            byte[] eccBlob = new byte[8+2*keyLength];
            Buffer.BlockCopy(blobMagic, 0, eccBlob, 0, 4);
            Buffer.BlockCopy(lengthData, 0, eccBlob, 4, 4);
            Buffer.BlockCopy(keyData, 1, eccBlob, 8, (int) (2*keyLength));

            CngKey cngKey = CngKey.Import(eccBlob, CngKeyBlobFormat.EccPublicBlob);
            ECDsaCng ecdsaKey = new ECDsaCng(cngKey);
            ecdsaKey.HashAlgorithm = GetCngAlgorithm(hashAlgorithm);

            return ecdsaKey.VerifyData(buffer, DERDecodeSignature(signature, (int)keyLength));
        }
        protected override void ProcessServerKeyExchange(HandshakeMessage keyExchange)
        {
            if (_state != HandshakeState.ReceivedServerHello &&
                _state != HandshakeState.ReceivedCertificate)
            {
                throw new AlertException(AlertDescription.UnexpectedMessage,
                                         "Server key exchange received at the wrong time");
            }
            if (!_cipherSuite.IsAnonymous && _serverCertificates.Count == 0)
            {
                throw new AlertException(AlertDescription.HandshakeFailure,
                                         "No certificate received even though cipher suite is not anonymous");
            }

            // Process server keys, also returns us the signature data
            var cert = _serverCertificates[0];

            byte[] signature = _cipherSuite.KeyExchangeAlgorithm.ProcessServerKeys(_version, keyExchange.Data, cert);

            // Extract the signed data from the complete payload
            byte[] serverKeys = new byte[keyExchange.Data.Length - signature.Length];
            Buffer.BlockCopy(keyExchange.Data, 0, serverKeys, 0, serverKeys.Length);

            // Verify correctness of the signature
            if (!_cipherSuite.IsAnonymous)
            {
                CertificatePublicKey publicKey = new CertificatePublicKey(cert);

                // Generate the original data signed from server keys
                byte[] signedData = new byte[_connectionState.ClientRandom.Length + _connectionState.ServerRandom.Length + serverKeys.Length];
                Buffer.BlockCopy(_connectionState.ClientRandom, 0, signedData, 0, _connectionState.ClientRandom.Length);
                Buffer.BlockCopy(_connectionState.ServerRandom, 0, signedData, _connectionState.ClientRandom.Length, _connectionState.ServerRandom.Length);
                Buffer.BlockCopy(serverKeys, 0, signedData, _connectionState.ClientRandom.Length + _connectionState.ServerRandom.Length, serverKeys.Length);

                bool signatureOk = VerifySignature(publicKey, signedData, signature);
                if (!signatureOk)
                {
                    throw new AlertException(AlertDescription.DecodeError,
                                             "Signature from server incorrect");
                }
            }

            // Wait for certificate request or server hello done
            _state = HandshakeState.ReceivedServerKeyExchange;
        }
Example #8
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[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey)
		{
			return null;
		}
Example #10
0
        public override byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey)
        {
            byte[] ecPoint = Blob2Point(_ecdhCng.PublicKey.ToByteArray());

            byte[] ret = new byte[1 + ecPoint.Length];
            ret[0] = (byte)(ecPoint.Length);
            Buffer.BlockCopy(ecPoint, 0, ret, 1, ecPoint.Length);
            return(ret);
        }
 public override byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey)
 {
     if (!(publicKey.Algorithm is RSACryptoServiceProvider))
     {
         throw new CryptographicException("RSA key exchange requires RSA public key");
     }
     return(GetClientKeys(version, clientVersion, (RSACryptoServiceProvider)publicKey.Algorithm));
 }
        public override bool VerifyData(byte[] buffer, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid))
            {
                throw new Exception("ECDSA signature verification requires ECDSA public key");
            }

            string curveOid = DER2OID(publicKey.Parameters);

            if (curveOid == null)
            {
                throw new Exception("Unsupported ECDSA public key parameters");
            }

            byte[] keyData = publicKey.KeyValue;
            if (keyData[0] != 0x04)
            {
                throw new Exception("Only uncompressed ECDSA keys supported, format: " + keyData[0]);
            }

            UInt32 keyLength;

            byte[] blobMagic;
            if (curveOid.Equals(P256OID))
            {
                keyLength = 32;
                blobMagic = Encoding.ASCII.GetBytes("ECS1");
            }
            else if (curveOid.Equals(P384OID))
            {
                keyLength = 48;
                blobMagic = Encoding.ASCII.GetBytes("ECS3");
            }
            else if (curveOid.Equals(P521OID))
            {
                keyLength = 66;
                blobMagic = Encoding.ASCII.GetBytes("ECS5");
            }
            else
            {
                throw new Exception("Unsupported ECC curve type OID: " + curveOid);
            }

            if (2 * keyLength != keyData.Length - 1)
            {
                throw new Exception("Invalid length of ECDSA public key: " + keyData.Length +
                                    " (should be " + (1 + 2 * keyLength) + ")");
            }
            byte[] lengthData = BitConverter.GetBytes(keyLength);

            // Create the ECC public blob for ECDsaCng class
            byte[] eccBlob = new byte[8 + 2 * keyLength];
            Buffer.BlockCopy(blobMagic, 0, eccBlob, 0, 4);
            Buffer.BlockCopy(lengthData, 0, eccBlob, 4, 4);
            Buffer.BlockCopy(keyData, 1, eccBlob, 8, (int)(2 * keyLength));

            CngKey   cngKey   = CngKey.Import(eccBlob, CngKeyBlobFormat.EccPublicBlob);
            ECDsaCng ecdsaKey = new ECDsaCng(cngKey);

            ecdsaKey.HashAlgorithm = GetCngAlgorithm(hashAlgorithm);

            return(ecdsaKey.VerifyData(buffer, DERDecodeSignature(signature, (int)keyLength)));
        }
		// Returns the client key exchange message as a byte array
		public abstract byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey);
        public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid))
            {
                throw new Exception("ECDSA signature verification requires ECDSA public key");
            }

            // Decode the public key parameters
            string curveOid = DER2OID(publicKey.Parameters);
            if (curveOid == null)
            {
                throw new Exception("Unsupported ECDSA public key parameters");
            }

            // Get parameters from the curve OID
            X9ECParameters ecParams = SecNamedCurves.GetByOid(new DerObjectIdentifier(curveOid));
            if (ecParams == null)
            {
                throw new Exception("Unsupported ECC curve type OID: " + curveOid);
            }

            // Construct domain parameters
            ECDomainParameters domainParameters = new ECDomainParameters(ecParams.Curve,
                                                                         ecParams.G, ecParams.N, ecParams.H,
                                                                         ecParams.GetSeed());

            // Decode the public key data
            byte[] ecPointData = publicKey.KeyValue;
            if (ecPointData[0] != 0x04)
            {
                throw new Exception("Only uncompressed ECDSA keys supported, format: " + ecPointData[0]);
            }
            ECPoint ecPoint = domainParameters.Curve.DecodePoint(ecPointData);
            ECPublicKeyParameters theirPublicKey = new ECPublicKeyParameters(ecPoint, domainParameters);
            
            // Hash input data buffer
            byte[] dataHash;
            if (hashAlgorithm == null)
            {
                dataHash = TLSv1HashData(data);
            }
            else
            {
                dataHash = hashAlgorithm.ComputeHash(data);
            }

            // Actually verify the signature
            BigInteger[] sig = DERDecodeSignature(signature);
            var r = sig[0];
            var s = sig[1];
            Log.Trace("Hashed data (V): " + BitConverter.ToString(dataHash));
            Log.Trace("Public Key Q (V): " + BitConverter.ToString(theirPublicKey.Q.GetEncoded()));
            Log.Trace("Signature R (V): " + BitConverter.ToString(r.ToByteArrayUnsigned()));
            Log.Trace("Signature S (V): " + BitConverter.ToString(s.ToByteArrayUnsigned()));
            Log.Trace("R value: " + sig[0].SignValue + " " + sig[0].LongValue);
            Log.Trace("S value: " + sig[1].SignValue + " " + sig[1].LongValue);


            ECDsaSigner signer = new ECDsaSigner();
            signer.Init(false, theirPublicKey);
            var result = signer.VerifySignature(dataHash, r, s);
            Log.Debug("Signature verification status: {0}.", result);
            return result;
        }
        protected override void ProcessServerHelloDone(HandshakeMessage serverHelloDone)
        {
            if (_state != HandshakeState.ReceivedCertificate &&
                _state != HandshakeState.ReceivedServerKeyExchange &&
                _state != HandshakeState.ReceivedCertificateRequest) {
                throw new AlertException(AlertDescription.UnexpectedMessage,
                                         "Server hello done received at the wrong time");
            }

            bool clientCertificateSent = false;
            if (_clientCertificateRequested) {
                // Ask for correct certificate from the callback
                int certificateIndex = _certificateSelectionCallback(_availableCertificates.ToArray(), _serverCertificates);
                if (certificateIndex >= 0 && certificateIndex < _availableCertificates.Count) {
                    _clientCertificates.AddRange(_availableCertificates[certificateIndex]);
                    _selectedPrivateKey = _availablePrivateKeys[certificateIndex];
                }

                // If certificate was selected, send it to server
                if (_clientCertificates.Count > 0) {
                    HandshakeCertificate certificate = new HandshakeCertificate(_version);
                    certificate.CertificateList.AddRange(_clientCertificates);
                    OutputMessage(certificate);

                    clientCertificateSent = true;
                } else {
                    // TODO: In case of SSLv3 we should send warning alert instead?
                    HandshakeCertificate certificate = new HandshakeCertificate(_version);
                    OutputMessage(certificate);
                }
            }

            // Send client key exchange message
            byte[] clientKeys = null;
            if (_serverCertificates.Count > 0) {
                CertificatePublicKey publicKey = new CertificatePublicKey(_serverCertificates[0]);
                clientKeys = _cipherSuite.KeyExchangeAlgorithm.GetClientKeys(_version, _maxVersion, publicKey);
            }
            HandshakeMessage keyex = new HandshakeMessage(HandshakeMessageType.ClientKeyExchange, _version, clientKeys);
            OutputMessage(keyex);

            if (clientCertificateSent) {
                // Get all handshake messages
                byte[] handshakeMessages = _handshakeStream.ToArray();

                // FIXME: Generate the signature of handshakeMessages with client cert signature
                //        this breaks if client certificate signature is different type than negotiated
                byte[] signature = GenerateSignature(_selectedPrivateKey, handshakeMessages);

                // Create CertificateVerify message and send it to server
                HandshakeMessage verify = new HandshakeMessage(HandshakeMessageType.CertificateVerify, _version, signature);
                OutputMessage(verify);
            }

            // Generate the master secret from key exchange
            _connectionState.MasterSecret = GenerateMasterSecret(_version, _cipherSuite, _connectionState);

            // Wait for changecipherspec+finished
            _state = HandshakeState.SendChangeCipherSpec;
        }
        public override byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey)
        {
            byte[] ecPoint = this.publicKey.Q.GetEncoded();

            byte[] ret = new byte[1 + ecPoint.Length];
            ret[0] = (byte)ecPoint.Length;
            Buffer.BlockCopy(ecPoint, 0, ret, 1, ecPoint.Length);
            return ret;
        }
        protected override void ProcessCertificateVerify(HandshakeMessage verify)
        {
            if (_state != HandshakeState.ReceivedClientKeyExchange) {
                throw new AlertException(AlertDescription.UnexpectedMessage,
                                         "Certificate verify received at the wrong time");
            }
            if (!_clientCertificateReceived) {
                throw new AlertException(AlertDescription.UnexpectedMessage,
                                         "Certificate verify received even though client certificate not received");
            }

            // Get all handshake messages up to, but not including, this one
            byte[] allMessages = _handshakeStream.ToArray();
            byte[] handshakeMessages = new byte[allMessages.Length - verify.Encode().Length];
            Buffer.BlockCopy(allMessages, 0, handshakeMessages, 0, handshakeMessages.Length);

            // Verify the signature of handshake messages
            CertificatePublicKey publicKey = new CertificatePublicKey(_clientCertificates[0]);
            bool signatureOk = VerifySignature(publicKey, handshakeMessages, verify.Data);
            if (!signatureOk) {
                throw new AlertException(AlertDescription.DecodeError,
                                         "Signature from client incorrect");
            }

            // Wait for changecipherspec+finished
            _state = HandshakeState.ReceivedClientKeyExchange;
        }
        protected override void ProcessServerHelloDone(HandshakeMessage serverHelloDone)
        {
            if (_state != HandshakeState.ReceivedCertificate &&
                _state != HandshakeState.ReceivedServerKeyExchange &&
                _state != HandshakeState.ReceivedCertificateRequest)
            {
                throw new AlertException(AlertDescription.UnexpectedMessage,
                                         "Server hello done received at the wrong time");
            }

            bool clientCertificateSent = false;

            if (_clientCertificateRequested)
            {
                // Ask for correct certificate from the callback
                int certificateIndex = _certificateSelectionCallback(_availableCertificates.ToArray(), _serverCertificates);
                if (certificateIndex >= 0 && certificateIndex < _availableCertificates.Count)
                {
                    _clientCertificates.AddRange(_availableCertificates[certificateIndex]);
                    _selectedPrivateKey = _availablePrivateKeys[certificateIndex];
                }

                // If certificate was selected, send it to server
                if (_clientCertificates.Count > 0)
                {
                    HandshakeCertificate certificate = new HandshakeCertificate(_version);
                    certificate.CertificateList.AddRange(_clientCertificates);
                    OutputMessage(certificate);

                    clientCertificateSent = true;
                }
                else
                {
                    // TODO: In case of SSLv3 we should send warning alert instead?
                    HandshakeCertificate certificate = new HandshakeCertificate(_version);
                    OutputMessage(certificate);
                }
            }

            // Send client key exchange message
            byte[] clientKeys = null;
            if (_serverCertificates.Count > 0)
            {
                var cert = _serverCertificates[0];
                CertificatePublicKey publicKey = new CertificatePublicKey(cert);
                this.logger?.Trace($"OID (lookup with http://www.oid-info.com/get/[oid]) of key from server certificate: {publicKey.Oid}");
                var data = Asn1Object.FromByteArray(cert.GetKeyAlgorithmParameters());
                this.logger?.Trace($" OID of key parameters from server certificate: {data}");
                clientKeys = _cipherSuite.KeyExchangeAlgorithm.GetClientKeys(_version, _maxVersion, publicKey);
            }
            HandshakeMessage keyex = new HandshakeMessage(HandshakeMessageType.ClientKeyExchange, _version, clientKeys);

            OutputMessage(keyex);

            if (clientCertificateSent)
            {
                // Get all handshake messages
                byte[] handshakeMessages = _handshakeStream.ToArray();

                // FIXME: Generate the signature of handshakeMessages with client cert signature
                //        this breaks if client certificate signature is different type than negotiated
                byte[] signature = GenerateSignature(_selectedPrivateKey, handshakeMessages);

                // Create CertificateVerify message and send it to server
                HandshakeMessage verify = new HandshakeMessage(HandshakeMessageType.CertificateVerify, _version, signature);
                OutputMessage(verify);
            }

            // Generate the master secret from key exchange
            _connectionState.MasterSecret = GenerateMasterSecret(_version, _cipherSuite, _connectionState);

            // Wait for changecipherspec+finished
            _state = HandshakeState.SendChangeCipherSpec;
        }
Example #19
0
		public abstract bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature);
Example #20
0
        public bool ReadPacket(Stream stream)
        {
            byte[] header    = new byte[5];
            int    readBytes = 0;

            while (readBytes < header.Length)
            {
                readBytes += stream.Read(header, readBytes, header.Length - readBytes);
            }

            Record record = new Record(header);

            readBytes = 0;
            while (readBytes < record.Fragment.Length)
            {
                readBytes += stream.Read(record.Fragment, readBytes, record.Fragment.Length - readBytes);
            }

            _recordHandler.ProcessInputRecord(record);

            if (record.Type == 22)
            {
                HandshakeMessage hs = HandshakeMessage.GetInstance(VERSION, record.Fragment);
                if (hs == null)
                {
                    Console.WriteLine("Skipped handling packet");
                    return(true);
                }

                Console.WriteLine("adding bytes to hash " + record.Fragment.Length);
                _handshakeStream.Write(record.Fragment, 0, record.Fragment.Length);

                if (hs.Type == HandshakeMessageType.ServerHello)
                {
                    HandshakeServerHello sh = (HandshakeServerHello)hs;
                    _serverRandom = sh.Random.GetBytes();
                    if (sh.ServerVersion != VERSION)
                    {
                        throw new Exception("Version doesn't match");
                    }
                }
                else if (hs.Type == HandshakeMessageType.Certificate)
                {
                    Console.WriteLine("Found certificate");
                    HandshakeCertificate cert = (HandshakeCertificate)hs;

                    _rsaPublicKey = null;
                    foreach (X509Certificate c in cert.CertificateList)
                    {
                        Console.WriteLine(c.ToString(true));

                        if (_rsaPublicKey == null)
                        {
                            X509Certificate c2 = new X509Certificate(c);
                            _rsaPublicKey = new CertificatePublicKey(c2);
                        }
                    }
                }
                else if (hs.Type == HandshakeMessageType.ServerHelloDone)
                {
                    SendClientKey(stream);

                    byte[] seed = new byte[64];
                    Array.Copy(_clientRandom, 0, seed, 0, 32);
                    Array.Copy(_serverRandom, 0, seed, 32, 32);
                    PrintBytes("hash seed", seed);

                    _masterSecret = _cipherSuite.KeyExchangeAlgorithm.GetMasterSecret(_cipherSuite.PseudoRandomFunction, seed);
                    PrintBytes("master secret", _masterSecret);

                    seed = new byte[64];
                    Array.Copy(_serverRandom, 0, seed, 0, 32);
                    Array.Copy(_clientRandom, 0, seed, 32, 32);

                    ConnectionState connectionState = new ConnectionState(_clientRandom, _serverRandom, _masterSecret);
                    _recordHandler.SetCipherSuite(_cipherSuite, connectionState);

                    SendFinished(stream);
                }
                else if (hs.Type == HandshakeMessageType.Finished)
                {
                    Console.WriteLine("Got Finished message!!!");
                    SendHttpGet(stream);
                }
            }
            else if (record.Type == 20)
            {
                Console.WriteLine("Got change cipher spec from server");
                _recordHandler.ChangeRemoteState();
            }
            else if (record.Type == 21)
            {
                // This is an alert
                if (record.Fragment.Length >= 2 && record.Fragment[1] == 0)
                {
                    // Close notify
                    Console.WriteLine("Close notify received");
                    return(false);
                }
            }
            else if (record.Type == 23)
            {
                Console.WriteLine("Got data: " + Encoding.UTF8.GetString(record.Fragment));
            }

            return(true);
        }
        protected override void ProcessServerKeyExchange(HandshakeMessage keyExchange)
        {
            if (_state != HandshakeState.ReceivedServerHello &&
                _state != HandshakeState.ReceivedCertificate) {
                throw new AlertException(AlertDescription.UnexpectedMessage,
                                         "Server key exchange received at the wrong time");
            }
            if (!_cipherSuite.IsAnonymous && _serverCertificates.Count == 0) {
                throw new AlertException(AlertDescription.HandshakeFailure,
                                         "No certificate received even though cipher suite is not anonymous");
            }

            // Process server keys, also returns us the signature data
            byte[] signature = _cipherSuite.KeyExchangeAlgorithm.ProcessServerKeys(_version, keyExchange.Data);

            // Extract the signed data from the complete payload
            byte[] serverKeys = new byte[keyExchange.Data.Length - signature.Length];
            Buffer.BlockCopy(keyExchange.Data, 0, serverKeys, 0, serverKeys.Length);

            // Verify correctness of the signature
            if (!_cipherSuite.IsAnonymous) {
                CertificatePublicKey publicKey = new CertificatePublicKey(_serverCertificates[0]);

                // Generate the original data signed from server keys
                byte[] signedData = new byte[_connectionState.ClientRandom.Length + _connectionState.ServerRandom.Length + serverKeys.Length];
                Buffer.BlockCopy(_connectionState.ClientRandom, 0, signedData, 0, _connectionState.ClientRandom.Length);
                Buffer.BlockCopy(_connectionState.ServerRandom, 0, signedData, _connectionState.ClientRandom.Length, _connectionState.ServerRandom.Length);
                Buffer.BlockCopy(serverKeys, 0, signedData, _connectionState.ClientRandom.Length + _connectionState.ServerRandom.Length, serverKeys.Length);

                bool signatureOk = VerifySignature(publicKey, signedData, signature);
                if (!signatureOk) {
                    throw new AlertException(AlertDescription.DecodeError,
                                             "Signature from server incorrect");
                }
            }

            // Wait for certificate request or server hello done
            _state = HandshakeState.ReceivedServerKeyExchange;
        }
Example #22
0
        public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid))
            {
                throw new Exception("RSA signature verification requires RSA public key");
            }

            RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)publicKey.Algorithm;

            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(TLSv1VerifyData(rsaKey, data, signature));
            }
            else
            {
                // Starting from TLS 1.2 the standard signature is used
                return(rsaKey.VerifyData(data, hashAlgorithm, signature));
            }
        }
Example #23
0
        protected bool VerifySignature(CertificatePublicKey publicKey, byte[] data, byte[] signedParams)
        {
            // Initialize the signature position and validity
            int position = 0;
            bool signatureOk = false;

            // Get the corresponding signer for public key
            SignatureAlgorithm sigAlg = _pluginManager.GetSignatureAlgorithmByOid(publicKey.Oid);
            if (sigAlg == null) {
                throw new AlertException(AlertDescription.IllegalParameter,
                                         "Signer for given public key not found");
            }

            // Select hash algorithm, null means SSLv3/TLSv1 hash
            HashAlgorithm hashAlgorithm = null;
            if (_version.HasSelectableSighash) {
                byte hashAlgorithmType = signedParams[position++];
                byte signAlgorithmType = signedParams[position++];
                if (sigAlg.SignatureAlgorithmType != signAlgorithmType) {
                    throw new AlertException(AlertDescription.DecryptError,
                                             "Certificate signed with invalid signature algorithm");
                }
                if (!sigAlg.SupportsHashAlgorithmType(hashAlgorithmType)) {
                    throw new AlertException(AlertDescription.DecryptError,
                                             "Certificate signed with invalid hash algorithm");
                }
                hashAlgorithm = GetSignatureHashAlgorithm(sigAlg, hashAlgorithmType);
            }

            // Check that signature length is valid (same as stored)
            int len = (signedParams[position] << 8) | signedParams[position+1];
            if (len != signedParams.Length-position-2) {
                throw new AlertException(AlertDescription.DecodeError,
                                         "Signature length not valid");
            }
            position += 2;

            // Extract the signature from the end of the signed parameters
            byte[] signature = new byte[len];
            Buffer.BlockCopy(signedParams, position, signature, 0, len);

            // Verify correctness of the signature
            signatureOk = sigAlg.VerifyData(_version, data, hashAlgorithm, publicKey, signature);
            if (!signatureOk) {
                throw new AlertException(AlertDescription.DecodeError,
                                         "Signature from server incorrect");
            }

            return signatureOk;
        }
Example #24
0
        public override byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey)
        {
            byte[] ecPoint = this.publicKey.Q.GetEncoded();

            byte[] ret = new byte[1 + ecPoint.Length];
            ret[0] = (byte)ecPoint.Length;
            Buffer.BlockCopy(ecPoint, 0, ret, 1, ecPoint.Length);
            return(ret);
        }
Example #25
0
        public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (hashAlgorithm != null && !(hashAlgorithm is SHA1)) {
                throw new Exception("DSA signature verification requires SHA1 hash algorithm");
            }
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid) || !(publicKey.Algorithm is DSACryptoServiceProvider)) {
                throw new Exception("DSA signature verification requires DSA public key");
            }

            return VerifyData(data, (DSACryptoServiceProvider)publicKey.Algorithm, signature);
        }
        public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid))
            {
                throw new Exception("ECDSA signature verification requires ECDSA public key");
            }

            // Decode the public key parameters
            string curveOid = DER2OID(publicKey.Parameters);

            if (curveOid == null)
            {
                throw new Exception("Unsupported ECDSA public key parameters");
            }

            // Get parameters from the curve OID
            X9ECParameters ecParams = SecNamedCurves.GetByOid(new DerObjectIdentifier(curveOid));

            if (ecParams == null)
            {
                throw new Exception("Unsupported ECC curve type OID: " + curveOid);
            }

            // Construct domain parameters
            ECDomainParameters domainParameters = new ECDomainParameters(ecParams.Curve,
                                                                         ecParams.G, ecParams.N, ecParams.H,
                                                                         ecParams.GetSeed());

            // Decode the public key data
            byte[] ecPointData = publicKey.KeyValue;
            if (ecPointData[0] != 0x04)
            {
                throw new Exception("Only uncompressed ECDSA keys supported, format: " + ecPointData[0]);
            }
            ECPoint ecPoint = domainParameters.Curve.DecodePoint(ecPointData);
            ECPublicKeyParameters theirPublicKey = new ECPublicKeyParameters(ecPoint, domainParameters);

            // Hash input data buffer
            byte[] dataHash;
            if (hashAlgorithm == null)
            {
                dataHash = TLSv1HashData(data);
            }
            else
            {
                dataHash = hashAlgorithm.ComputeHash(data);
            }

            // Actually verify the signature
            BigInteger[] sig    = DERDecodeSignature(signature);
            ECDsaSigner  signer = new ECDsaSigner();

            signer.Init(false, theirPublicKey);
            return(signer.VerifySignature(dataHash, sig[0], sig[1]));
        }
		public override byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey)
		{
			if (_dh_p.Length == 0 || _dh_g.Length == 0 || _dh_Ys.Length == 0)
				throw new Exception("Server keys not generated/received");
			
			// Create corresponding BigIntegers
			BigInteger p = ByteArrayToBigInteger(_dh_p);
			BigInteger g = ByteArrayToBigInteger(_dh_g);
			BigInteger Ys = ByteArrayToBigInteger(_dh_Ys);

			// Generate new private value X between 0 and P-1
			BigInteger x = GenerateX(p);

			// Calculate pre-master secret
			BigInteger Z = BigInteger.ModPow(Ys, x, p);
			_preMasterSecret = BigIntegerToByteArray(Z, _pLength);

			// Calculate the client parameter
			BigInteger Yc = BigInteger.ModPow(g, x, p);
			_dh_Yc = BigIntegerToByteArray(Yc, _pLength);

			// Return the client parameter that will be sent
			byte[] ret = new byte[2+_dh_Yc.Length];
			ret[0] = (byte) (_dh_Yc.Length >> 8);
			ret[1] = (byte) (_dh_Yc.Length);
			Buffer.BlockCopy(_dh_Yc, 0, ret, 2, _dh_Yc.Length);
			return ret;
		}
Example #28
0
        public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid))
            {
                throw new Exception("ECDSA signature verification requires ECDSA public key");
            }

            // Decode the public key parameters
            string curveOid = DER2OID(publicKey.Parameters);

            if (curveOid == null)
            {
                throw new Exception("Unsupported ECDSA public key parameters");
            }

            // Get parameters from the curve OID
            X9ECParameters ecParams = SecNamedCurves.GetByOid(new DerObjectIdentifier(curveOid));

            if (ecParams == null)
            {
                throw new Exception("Unsupported ECC curve type OID: " + curveOid);
            }

            // Construct domain parameters
            ECDomainParameters domainParameters = new ECDomainParameters(ecParams.Curve,
                                                                         ecParams.G, ecParams.N, ecParams.H,
                                                                         ecParams.GetSeed());

            // Decode the public key data
            byte[] ecPointData = publicKey.KeyValue;
            if (ecPointData[0] != 0x04)
            {
                throw new Exception("Only uncompressed ECDSA keys supported, format: " + ecPointData[0]);
            }

            Org.BouncyCastle.Math.EC.ECPoint ecPoint        = domainParameters.Curve.DecodePoint(ecPointData);
            ECPublicKeyParameters            theirPublicKey = new ECPublicKeyParameters(ecPoint, domainParameters);

            // Hash input data buffer
            byte[] dataHash;
            if (hashAlgorithm == null)
            {
                dataHash = TLSv1HashData(data);
            }
            else
            {
                dataHash = hashAlgorithm.ComputeHash(data);
            }

            // Actually verify the signature
            BigInteger[] sig = DERDecodeSignature(signature);
            var          r   = sig[0];
            var          s   = sig[1];

            Log.Trace("Hashed data (V): " + BitConverter.ToString(dataHash));
            Log.Trace("Public Key Q (V): " + BitConverter.ToString(theirPublicKey.Q.GetEncoded()));
            Log.Trace("Signature R (V): " + BitConverter.ToString(r.ToByteArrayUnsigned()));
            Log.Trace("Signature S (V): " + BitConverter.ToString(s.ToByteArrayUnsigned()));
            Log.Trace("R value: " + sig[0].SignValue + " " + sig[0].LongValue);
            Log.Trace("S value: " + sig[1].SignValue + " " + sig[1].LongValue);


            ECDsaSigner signer = new ECDsaSigner();

            signer.Init(false, theirPublicKey);
            var result = signer.VerifySignature(dataHash, r, s);

            Log.Debug("Signature verification status: {0}.", result);
            return(result);
        }
Example #29
0
        public bool ReadPacket(Stream stream)
        {
            byte[] header = new byte[5];
            int readBytes = 0;
            while (readBytes < header.Length) {
                readBytes += stream.Read(header, readBytes, header.Length-readBytes);
            }

            Record record = new Record(header);
            readBytes = 0;
            while (readBytes < record.Fragment.Length) {
                readBytes += stream.Read(record.Fragment, readBytes, record.Fragment.Length-readBytes);
            }

            _recordHandler.ProcessInputRecord(record);

            if (record.Type == 22) {
                HandshakeMessage hs = HandshakeMessage.GetInstance(VERSION, record.Fragment);
                if (hs == null) {
                    Console.WriteLine("Skipped handling packet");
                    return true;
                }

                Console.WriteLine("adding bytes to hash " + record.Fragment.Length);
                _handshakeStream.Write(record.Fragment, 0, record.Fragment.Length);

                if (hs.Type == HandshakeMessageType.ServerHello) {
                    HandshakeServerHello sh = (HandshakeServerHello) hs;
                    _serverRandom = sh.Random.GetBytes();
                    if (sh.ServerVersion != VERSION) {
                        throw new Exception("Version doesn't match");
                    }
                } else if (hs.Type == HandshakeMessageType.Certificate) {
                    Console.WriteLine("Found certificate");
                    HandshakeCertificate cert = (HandshakeCertificate) hs;

                    _rsaPublicKey = null;
                    foreach (X509Certificate c in cert.CertificateList) {
                        Console.WriteLine(c.ToString(true));

                        if (_rsaPublicKey == null) {
                            X509Certificate c2 = new X509Certificate(c);
                            _rsaPublicKey = new CertificatePublicKey(c2);
                        }
                    }
                } else if (hs.Type == HandshakeMessageType.ServerHelloDone) {
                    SendClientKey(stream);

                    byte[] seed = new byte[64];
                    Array.Copy(_clientRandom, 0, seed, 0, 32);
                    Array.Copy(_serverRandom, 0, seed, 32, 32);
                    PrintBytes("hash seed", seed);

                    _masterSecret = _cipherSuite.KeyExchangeAlgorithm.GetMasterSecret(_cipherSuite.PseudoRandomFunction, seed);
                    PrintBytes("master secret", _masterSecret);

                    seed = new byte[64];
                    Array.Copy(_serverRandom, 0, seed, 0, 32);
                    Array.Copy(_clientRandom, 0, seed, 32, 32);

                    ConnectionState connectionState = new ConnectionState(_clientRandom, _serverRandom, _masterSecret);
                    _recordHandler.SetCipherSuite(_cipherSuite, connectionState);

                    SendFinished(stream);
                } else if (hs.Type == HandshakeMessageType.Finished) {
                    Console.WriteLine("Got Finished message!!!");
                    SendHttpGet(stream);
                }

            } else if (record.Type == 20) {
                Console.WriteLine("Got change cipher spec from server");
                _recordHandler.ChangeRemoteState();
            } else if (record.Type == 21) {
                // This is an alert
                if (record.Fragment.Length >= 2 && record.Fragment[1] == 0) {
                    // Close notify
                    Console.WriteLine("Close notify received");
                    return false;
                }
            } else if (record.Type == 23) {
                Console.WriteLine("Got data: " + Encoding.UTF8.GetString(record.Fragment));

            }

            return true;
        }
        public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (hashAlgorithm != null && !(hashAlgorithm is SHA1))
            {
                throw new Exception("DSA signature verification requires SHA1 hash algorithm");
            }
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid) || !(publicKey.Algorithm is DSACryptoServiceProvider))
            {
                throw new Exception("DSA signature verification requires DSA public key");
            }

            return(VerifyData(data, (DSACryptoServiceProvider)publicKey.Algorithm, signature));
        }
Example #31
0
 // Returns the client key exchange message as a byte array
 public abstract byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey);
        public override byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey)
        {
            if (_dh_p.Length == 0 || _dh_g.Length == 0 || _dh_Ys.Length == 0)
            {
                throw new Exception("Server keys not generated/received");
            }

            // Create corresponding BigIntegers
            BigInteger p  = ByteArrayToBigInteger(_dh_p);
            BigInteger g  = ByteArrayToBigInteger(_dh_g);
            BigInteger Ys = ByteArrayToBigInteger(_dh_Ys);

            // Generate new private value X between 0 and P-1
            BigInteger x = GenerateX(p);

            // Calculate pre-master secret
            BigInteger Z = BigInteger.ModPow(Ys, x, p);

            _preMasterSecret = BigIntegerToByteArray(Z, _pLength);

            // Calculate the client parameter
            BigInteger Yc = BigInteger.ModPow(g, x, p);

            _dh_Yc = BigIntegerToByteArray(Yc, _pLength);

            // Return the client parameter that will be sent
            byte[] ret = new byte[2 + _dh_Yc.Length];
            ret[0] = (byte)(_dh_Yc.Length >> 8);
            ret[1] = (byte)(_dh_Yc.Length);
            Buffer.BlockCopy(_dh_Yc, 0, ret, 2, _dh_Yc.Length);
            return(ret);
        }
Example #33
0
 public override byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePublicKey publicKey)
 {
     return(null);
 }
 public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey key, byte[] signature)
 {
     if (signature.Length == 0)
     {
         return(true);
     }
     return(false);
 }
        public override bool VerifyData(ProtocolVersion version, byte[] data, HashAlgorithm hashAlgorithm, CertificatePublicKey publicKey, byte[] signature)
        {
            if (!CertificateKeyAlgorithm.Equals(publicKey.Oid))
            {
                throw new Exception("RSA signature verification requires RSA public key");
            }

            RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)publicKey.Algorithm;
            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 TLSv1VerifyData(rsaKey, data, signature);
            }
            else
            {
                // Starting from TLS 1.2 the standard signature is used
                return rsaKey.VerifyData(data, hashAlgorithm, signature);
            }
        }