public HandshakeCertificateRequest(ProtocolVersion version)
     : base(HandshakeMessageType.CertificateRequest, version)
 {
     CertificateTypes = new List<byte>();
     SignatureAndHashAlgorithms = new List<ushort>();
     CertificateAuthorities = new List<string>();
 }
 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 SupportsProtocolVersion(ProtocolVersion version)
 {
     if (version == ProtocolVersion.TLS1_0 ||
         version == ProtocolVersion.TLS1_1 || version == ProtocolVersion.DTLS1_0) {
         return true;
     }
     return false;
 }
        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 HandshakeClientHello(ProtocolVersion version)
     : base(HandshakeMessageType.ClientHello, version)
 {
     ClientVersion       = version;
     Random              = new HandshakeRandom();
     SessionID           = new byte[0];
     Cookie              = new byte[0];
     CipherSuites        = new List<UInt16>();
     CompressionMethods  = new List<Byte>();
     Extensions          = new List<HelloExtension>();
 }
Exemple #6
0
        public HandshakeMessage(HandshakeMessageType type, ProtocolVersion version, byte[] data)
        {
            if (data == null) {
                throw new AlertException(AlertDescription.InternalError,
                                         "Trying to create HandshakeMessage with null data");
            }

            Type = type;
            _version = version;
            _data = (byte[])data.Clone();
        }
Exemple #7
0
        public CipherSuite(ProtocolVersion version)
        {
            ProtocolVersion = version;
            CipherSuiteID = 0x0000;
            CipherSuiteName = "TLS_NULL_WITH_NULL_NULL";

            _keyExchangeAlgorithm = new KeyExchangeAlgorithmNull();
            _signatureAlgorithm = new SignatureAlgorithmNull();
            _pseudoRandomFunction = null;
            _bulkCipherAlgorithm = new BulkCipherAlgorithmNull();
            _macAlgorithm = new MACAlgorithmNull();
        }
        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);
        }
Exemple #9
0
        public static HandshakeMessage GetInstance(ProtocolVersion version, byte[] data)
        {
            HandshakeMessage ret = null;

            switch ((HandshakeMessageType) data[0]) {
            case HandshakeMessageType.HelloRequest:
                ret = new HandshakeMessage(HandshakeMessageType.HelloRequest, version);
                break;
            case HandshakeMessageType.ClientHello:
                ret = new HandshakeClientHello();
                break;
            case HandshakeMessageType.ServerHello:
                ret = new HandshakeServerHello();
                break;
            case HandshakeMessageType.HelloVerifyRequest:
                ret = new HandshakeMessage(HandshakeMessageType.HelloVerifyRequest, version);
                break;
            case HandshakeMessageType.NewSessionTicket:
                ret = new HandshakeMessage(HandshakeMessageType.NewSessionTicket, version);
                break;
            case HandshakeMessageType.Certificate:
                ret = new HandshakeCertificate(version);
                break;
            case HandshakeMessageType.ServerKeyExchange:
                ret = new HandshakeMessage(HandshakeMessageType.ServerKeyExchange, version);
                break;
            case HandshakeMessageType.CertificateRequest:
                ret = new HandshakeCertificateRequest(version);
                break;
            case HandshakeMessageType.ServerHelloDone:
                ret = new HandshakeMessage(HandshakeMessageType.ServerHelloDone, version);
                break;
            case HandshakeMessageType.CertificateVerify:
                ret = new HandshakeMessage(HandshakeMessageType.CertificateVerify, version);
                break;
            case HandshakeMessageType.ClientKeyExchange:
                ret = new HandshakeMessage(HandshakeMessageType.ClientKeyExchange, version);
                break;
            case HandshakeMessageType.Finished:
                ret = new HandshakeMessage(HandshakeMessageType.Finished, version);
                break;
            }

            if (ret != null) {
                ret.Decode(data);
                return ret;
            }
            return null;
        }
        public override byte[] GetServerKeys(ProtocolVersion version)
        {
            _ecdhCng = new ECDiffieHellmanCng(256);

            UInt16 namedCurve = KeySizeToNamedCurve(256);
            byte[] ecPoint = Blob2Point(_ecdhCng.PublicKey.ToByteArray());

            byte[] ret = new byte[4+ecPoint.Length];
            ret[0] = 3;  // ECCurveType.named_curve
            ret[1] = (byte) (namedCurve >> 8);
            ret[2] = (byte) (namedCurve);
            ret[3] = (byte) (ecPoint.Length);
            Buffer.BlockCopy(ecPoint, 0, ret, 4, ecPoint.Length);
            return ret;
        }
Exemple #11
0
        public RecordHandler(ProtocolVersion version, bool isClient)
        {
            _isClient = isClient;

            // Start with NULL cipher suite and key block
            _nextCipherSuite = new CipherSuite(version);
            _nextKeyBlock = new KeyBlock();

            // Initialize all the other variables
            ChangeLocalState();
            ChangeRemoteState();

            _inputEpoch = 0;
            _outputEpoch = 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));
        }
        protected override void DecodeDataBytes(ProtocolVersion version, byte[] data)
        {
            CertificateTypes.Clear();
            CertificateAuthorities.Clear();

            MemoryStream memStream = new MemoryStream(data);
            HandshakeStream stream = new HandshakeStream(memStream);

            int typesLength = stream.ReadUInt8();
            for (int i=0; i<typesLength; i++) {
                CertificateTypes.Add(stream.ReadUInt8());
            }

            if (version.HasSelectableSighash) {
                int sighashLength = stream.ReadUInt16();
                if ((sighashLength%2) != 0) {
                    throw new AlertException(AlertDescription.IllegalParameter,
                                             "SianatureAndHashAlgorithms length invalid: " + sighashLength);
                }

                byte[] sighashData = stream.ReadBytes(sighashLength);
                for (int i=0; i<sighashLength; i+=2) {
                    SignatureAndHashAlgorithms.Add((UInt16)((sighashData[i] << 8) | sighashData[i+1]));
                }
            }

            int authsLength = stream.ReadUInt16();
            byte[] authData = stream.ReadBytes(authsLength);
            stream.ConfirmEndOfStream();

            int position=0;
            while (position < authData.Length) {
                int authLength = (authData[position] << 8) | authData[position+1];
                position += 2;

                if (position > authData.Length) {
                    throw new AlertException(AlertDescription.IllegalParameter,
                                             "Authorities total length doesn't match contents");
                }

                string name = Encoding.ASCII.GetString(authData, position, authLength);
                position += authLength;

                CertificateAuthorities.Add(name);
            }
        }
        protected override byte[] EncodeDataBytes(ProtocolVersion version)
        {
            int certsLength = 0;
            foreach (X509Certificate cert in CertificateList) {
                certsLength += 3;
                certsLength += cert.GetRawCertData().Length;
            }

            MemoryStream memStream = new MemoryStream();
            HandshakeStream stream = new HandshakeStream(memStream);

            stream.WriteUInt24((UInt32) certsLength);
            foreach (X509Certificate cert in CertificateList) {
                byte[] certBytes = cert.GetRawCertData();

                stream.WriteUInt24((UInt32) certBytes.Length);
                stream.WriteBytes(certBytes);
            }

            return memStream.ToArray();
        }
        protected override void DecodeDataBytes(ProtocolVersion version, byte[] data)
        {
            CertificateList.Clear();

            MemoryStream memStream = new MemoryStream(data);
            HandshakeStream stream = new HandshakeStream(memStream);
            int certsLength = (int) stream.ReadUInt24();

            int readBytes = 0;
            while (readBytes<certsLength) {
                int certLength = (int) stream.ReadUInt24();
                byte[] certBytes = stream.ReadBytes(certLength);
                readBytes += 3+certLength;

                CertificateList.Add(new X509Certificate(certBytes));
            }
            if (readBytes != certsLength) {
                throw new AlertException(AlertDescription.IllegalParameter,
                                         "Certificate total length doesn't match contents");
            }
            stream.ConfirmEndOfStream();
        }
        public byte[] GetClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, RSACryptoServiceProvider rsa)
        {
            _preMasterSecret = new byte[48];

            RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
            rngCsp.GetBytes(_preMasterSecret);

            _preMasterSecret[0] = clientVersion.Major;
            _preMasterSecret[1] = clientVersion.Minor;

            byte[] encryptedBytes = rsa.Encrypt(_preMasterSecret, false);

            byte[] ret;
            if (version != ProtocolVersion.SSL3_0) {
                // TLS 1.0 and later require a useless vector length
                ret = new byte[2+encryptedBytes.Length];
                ret[0] = (byte) (encryptedBytes.Length >> 8);
                ret[1] = (byte) (encryptedBytes.Length);
                Buffer.BlockCopy(encryptedBytes, 0, ret, 2, encryptedBytes.Length);
            } else {
                ret = encryptedBytes;
            }
            return ret;
        }
Exemple #17
0
 public virtual bool SupportsProtocolVersion(ProtocolVersion version)
 {
     return version.HasExtensions;
 }
 public HandshakeCertificate(ProtocolVersion version)
     : base(HandshakeMessageType.Certificate, version)
 {
     CertificateList = new X509CertificateCollection();
 }
        public CipherSuite GetCipherSuite(ProtocolVersion version, UInt16 id)
        {
            CipherSuiteInfo cipherSuiteInfo = null;

            foreach (CipherSuitePlugin plugin in _plugins)
            {
                List <UInt16> supported = new List <UInt16>(plugin.SupportedCipherSuites);
                if (supported.Contains(id))
                {
                    cipherSuiteInfo = plugin.GetCipherSuiteFromID(id);
                    break;
                }
            }

            if (cipherSuiteInfo == null)
            {
                Console.WriteLine("CipherSuite ID 0x" + id.ToString("x").PadLeft(2, '0') + " not found");
                return(null);
            }

            CipherSuite cipherSuite = new CipherSuite(version, id, cipherSuiteInfo.CipherSuiteName);

            if (cipherSuiteInfo.KeyExchangeAlgorithmName == null)
            {
                cipherSuite.KeyExchangeAlgorithm = new KeyExchangeAlgorithmNull();
            }
            if (cipherSuiteInfo.SignatureAlgorithmName == null)
            {
                cipherSuite.SignatureAlgorithm = new SignatureAlgorithmNull();
            }
            if (cipherSuiteInfo.BulkCipherAlgorithmName == null)
            {
                cipherSuite.BulkCipherAlgorithm = new BulkCipherAlgorithmNull();
            }
            if (cipherSuiteInfo.MACAlgorithmName == null)
            {
                cipherSuite.MACAlgorithm = new MACAlgorithmNull();
            }

            // These need to be edited in different versions
            string prfName = cipherSuiteInfo.PseudoRandomFunctionName;
            string macName = cipherSuiteInfo.MACAlgorithmName;

            if (version == ProtocolVersion.SSL3_0)
            {
                if (prfName == null)
                {
                    prfName = "SSLv3";
                }
                else
                {
                    // PRF selection not supported, but PRF defined, ignore this suite
                    return(null);
                }

                if (macName == null)
                {
                    macName = null;
                }
                else if (macName.Equals("MD5"))
                {
                    macName = "SSLv3_MD5";
                }
                else if (macName.Equals("SHA1"))
                {
                    macName = "SSLv3_SHA1";
                }
                else
                {
                    // Only MD5 and SHA1 MAC accepted in SSLv3, ignore this suite
                    return(null);
                }
            }
            else
            {
                if (version.HasSelectablePRF)
                {
                    if (prfName == null)
                    {
                        prfName = "TLS_SHA256";
                    }
                }
                else
                {
                    if (prfName == null)
                    {
                        prfName = "TLSv1";
                    }
                    else
                    {
                        // PRF selection not supported, but PRF defined, ignore this suite
                        return(null);
                    }
                }
            }

            foreach (CipherSuitePlugin plugin in _plugins)
            {
                if (cipherSuite.KeyExchangeAlgorithm == null)
                {
                    cipherSuite.KeyExchangeAlgorithm =
                        plugin.GetKeyExchangeAlgorithm(cipherSuiteInfo.KeyExchangeAlgorithmName);
                }
                if (cipherSuite.SignatureAlgorithm == null)
                {
                    cipherSuite.SignatureAlgorithm =
                        plugin.GetSignatureAlgorithm(cipherSuiteInfo.SignatureAlgorithmName);
                }
                if (cipherSuite.PseudoRandomFunction == null)
                {
                    cipherSuite.PseudoRandomFunction =
                        plugin.GetPseudoRandomFunction(prfName);

                    /* Check that the PRF is valid as per RFC 5246 section 7.4.9 */
                    if (cipherSuite.PseudoRandomFunction != null && cipherSuite.PseudoRandomFunction.VerifyDataLength < 12)
                    {
                        Console.WriteLine("Invalid PseudoRandomFunction, verify data less than 12, ignored");
                        cipherSuite.PseudoRandomFunction = null;
                    }
                }
                if (cipherSuite.BulkCipherAlgorithm == null)
                {
                    cipherSuite.BulkCipherAlgorithm =
                        plugin.GetBulkCipherAlgorithm(cipherSuiteInfo.BulkCipherAlgorithmName);
                }
                if (cipherSuite.MACAlgorithm == null)
                {
                    cipherSuite.MACAlgorithm =
                        plugin.GetMACAlgorithm(macName);
                }
            }

            if (cipherSuite.KeyExchangeAlgorithm == null || !cipherSuite.KeyExchangeAlgorithm.SupportsProtocolVersion(version))
            {
                Console.WriteLine("KeyExchangeAlgorithm '" + cipherSuiteInfo.KeyExchangeAlgorithmName + "' not found");
                return(null);
            }
            if (cipherSuite.SignatureAlgorithm == null || !cipherSuite.SignatureAlgorithm.SupportsProtocolVersion(version))
            {
                Console.WriteLine("SignatureAlgorithm '" + cipherSuiteInfo.SignatureAlgorithmName + "' not found");
                return(null);
            }
            if (cipherSuite.PseudoRandomFunction == null || !cipherSuite.PseudoRandomFunction.SupportsProtocolVersion(version))
            {
                Console.WriteLine("PseudoRandomFunction '" + cipherSuiteInfo.PseudoRandomFunctionName + "' not found");
                return(null);
            }
            if (cipherSuite.BulkCipherAlgorithm == null || !cipherSuite.BulkCipherAlgorithm.SupportsProtocolVersion(version))
            {
                Console.WriteLine("BulkCipherAlgorithm '" + cipherSuiteInfo.BulkCipherAlgorithmName + "' not found");
                return(null);
            }
            if (cipherSuite.MACAlgorithm == null || !cipherSuite.MACAlgorithm.SupportsProtocolVersion(version))
            {
                Console.WriteLine("MACAlgorithm '" + cipherSuiteInfo.MACAlgorithmName + "' not found");
                return(null);
            }

            return(cipherSuite);
        }
Exemple #20
0
 // Returns true if this version is supported, otherwise false
 public abstract bool SupportsProtocolVersion(ProtocolVersion version);
Exemple #21
0
 public HandshakeMessage(HandshakeMessageType type, ProtocolVersion version)
 {
     Type = type;
     _version = version;
     _data = new byte[0];
 }
Exemple #22
0
 protected virtual byte[] EncodeDataBytes(ProtocolVersion version)
 {
     return _data;
 }
Exemple #23
0
 protected virtual void DecodeDataBytes(ProtocolVersion version, byte[] data)
 {
     _data = data;
 }
 public override bool SupportsProtocolVersion(ProtocolVersion version)
 {
     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);
        }
        protected HandshakeSession(SecurityParameters securityParameters)
        {
            string path = System.Reflection.Assembly.GetAssembly(typeof(HandshakeSession)).Location;
            string directory = Path.GetDirectoryName(path);

            _pluginManager = new CipherSuitePluginManager(directory);
            _state = HandshakeState.Initial;

            _minVersion = securityParameters.MinimumVersion;
            _maxVersion = securityParameters.MaximumVersion;
            _supportedCipherSuites = securityParameters.CipherSuiteIDs.ToArray();
            _supportedCompressions = securityParameters.CompressionIDs.ToArray();

            _availableCertificates = new List<X509CertificateCollection>(securityParameters.AvailableCertificates);
            _availablePrivateKeys = new List<CertificatePrivateKey>(securityParameters.AvailablePrivateKeys);

            _clientCertificates = new X509CertificateCollection();
            _serverCertificates = new X509CertificateCollection();

            // Initialize the default ClientHello version, to
            // be as compatible as possible based on maxVersion
            if (_maxVersion == ProtocolVersion.SSL3_0) {
                _version = ProtocolVersion.SSL3_0;
            } else if (_maxVersion.IsUsingDatagrams) {
                _version = ProtocolVersion.DTLS1_0;
            } else {
                _version = ProtocolVersion.TLS1_0;
            }
            _cipherSuite = new CipherSuite(_version);
        }
        protected static byte[] GenerateMasterSecret(ProtocolVersion version, CipherSuite cipherSuite, ConnectionState connectionState)
        {
            byte[] seed = new byte[64];
            Array.Copy(connectionState.ClientRandom, 0, seed, 0, 32);
            Array.Copy(connectionState.ServerRandom, 0, seed, 32, 32);

            byte[] masterSecret = cipherSuite.KeyExchangeAlgorithm.GetMasterSecret(cipherSuite.PseudoRandomFunction, seed);
            if (masterSecret == null) {
                throw new Exception("Could not generate master secret");
            }
            return masterSecret;
        }
        protected override void DecodeDataBytes(ProtocolVersion ver, byte[] data)
        {
            CipherSuites.Clear();
            CompressionMethods.Clear();

            MemoryStream memStream = new MemoryStream(data);
            HandshakeStream stream = new HandshakeStream(memStream);

            byte major = stream.ReadUInt8();
            byte minor = stream.ReadUInt8();
            ClientVersion = new ProtocolVersion(major, minor);

            byte[] randomBytes = stream.ReadBytes(32);
            Random = new HandshakeRandom(randomBytes);

            int idLength = (int) stream.ReadUInt8();
            SessionID = stream.ReadBytes(idLength);

            if (ClientVersion.IsUsingDatagrams) {
                int cookieLength = (int) stream.ReadUInt8();
                Cookie = stream.ReadBytes(cookieLength);
            }

            int cipherLength = (int) stream.ReadUInt16();
            for (int i=0; i<cipherLength; i+=2) {
                CipherSuites.Add(stream.ReadUInt16());
            }

            int compressionLength = (int) stream.ReadUInt8();
            for (int i=0; i<compressionLength; i++) {
                CompressionMethods.Add(stream.ReadUInt8());
            }

            byte[] extensionList = new byte[0];
            if (!stream.EndOfStream && ClientVersion.HasExtensions) {
                UInt16 extensionListLength = stream.ReadUInt16();
                extensionList = stream.ReadBytes(extensionListLength);
            }
            stream.ConfirmEndOfStream();

            int pos = 0;
            while (pos+4 <= extensionList.Length) {
                UInt16 extensionType = (UInt16) ((extensionList[pos] << 8) | extensionList[pos+1]);
                UInt16 extensionDataLength = (UInt16) ((extensionList[pos+2] << 8) | extensionList[pos+3]);
                pos += 4;

                if (pos+extensionDataLength > extensionList.Length) {
                    throw new AlertException(AlertDescription.IllegalParameter,
                                             "ClientHello extension data length too large: " + extensionDataLength);
                }

                byte[] extensionData = new byte[extensionDataLength];
                Buffer.BlockCopy(extensionList, pos, extensionData, 0, extensionData.Length);
                pos += extensionData.Length;

                Extensions.Add(new HelloExtension(extensionType, extensionData));
            }
        }
 public HandshakeHelloVerifyRequest(ProtocolVersion version)
     : base(HandshakeMessageType.HelloVerifyRequest, version)
 {
     ServerVersion  = version;
     Cookie         = new byte[0];
 }
 public override bool SupportsProtocolVersion(ProtocolVersion version)
 {
     return (version == ProtocolVersion.SSL3_0);
 }
 public override bool SupportsProtocolVersion(ProtocolVersion version)
 {
     return version.HasSelectablePRF;
 }
Exemple #32
0
 // Returns true if this version is supported, otherwise false
 public abstract bool SupportsProtocolVersion(ProtocolVersion version);