protected HandshakeSession(SecurityParameters securityParameters, ILogger logger)
        {
            this.logger = logger;

            _pluginManager = new CipherSuitePluginManager(this.logger);
            _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
            _version = _minVersion;

            
            _cipherSuite = new CipherSuite(_version);
        }
        public Record[] ProcessHandshakeMessages(ProtocolVersion version,
                                                 HandshakeMessage[] messages,
                                                 int maxFragmentLength)
        {
            List<Record> records = new List<Record>();

            // Write all handshake data to memory stream
            MemoryStream memStream = new MemoryStream();
            for (int i = 0; i < messages.Length; i++)
            {
                byte[] msgBytes = messages[i].Encode();
                memStream.Write(msgBytes, 0, msgBytes.Length);
            }

            // Read handshake data from memory stream one at a time
            memStream.Position = 0;
            while (memStream.Position < memStream.Length)
            {
                long fragmentLength = Math.Min(memStream.Length - memStream.Position, maxFragmentLength);
                byte[] fragment = new byte[fragmentLength];
                memStream.Read(fragment, 0, fragment.Length);
                Record record = new Record(RecordType.Handshake, version);
                record.Fragment = fragment;
                records.Add(record);
            }

            return records.ToArray();
        }
        protected override byte[] EncodeDataBytes(ProtocolVersion ver)
        {
            if (CipherSuites.Count == 0 || CompressionMethods.Count == 0)
            {
                throw new Exception("No cipher suites or compression methods defined");
            }

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

            stream.WriteUInt8(ClientVersion.Major);
            stream.WriteUInt8(ClientVersion.Minor);
            stream.WriteBytes(Random.GetBytes());
            stream.WriteUInt8((Byte)SessionID.Length);
            stream.WriteBytes(SessionID);
            if (ClientVersion.IsUsingDatagrams)
            {
                stream.WriteUInt8((Byte)Cookie.Length);
                stream.WriteBytes(Cookie);
            }

            stream.WriteUInt16((UInt16)(2 * CipherSuites.Count));
            foreach (UInt16 cipher in CipherSuites)
            {
                stream.WriteUInt16(cipher);
            }

            stream.WriteUInt8((Byte)CompressionMethods.Count);
            foreach (Byte compression in CompressionMethods)
            {
                stream.WriteUInt8(compression);
            }

            if (Extensions.Count > 0)
            {
                int length = 0;
                foreach (HelloExtension ext in Extensions)
                {
                    if (!ext.SupportsProtocolVersion(ClientVersion))
                        continue;
                    length += 4 + ext.Data.Length;
                }
                stream.WriteUInt16((UInt16)length);
                foreach (HelloExtension ext in Extensions)
                {
                    if (!ext.SupportsProtocolVersion(ClientVersion))
                        continue;

                    HelloExtensionType type = ext.Type;
                    byte[] data = ext.Data;

                    stream.WriteUInt16((ushort)type);
                    stream.WriteUInt16((UInt16)data.Length);
                    stream.WriteBytes(data);
                }
            }

            return memStream.ToArray();
        }
 public HandshakeServerHello(ProtocolVersion version)
     : base(HandshakeMessageType.ServerHello, version)
 {
     ServerVersion = version;
     Random = new HandshakeRandom();
     SessionID = new byte[0];
     CipherSuite = 0x0000;
     CompressionMethod = 0x00;
     Extensions = new List<HelloExtension>();
 }
 public HandshakeClientHello(ProtocolVersion version)
     : base(HandshakeMessageType.ClientHello, version)
 {
     ClientVersion = version;
     Random = new HandshakeRandom();
     SessionID = new byte[0];
     Cookie = new byte[0];
     CipherSuites = new List<CipherSuiteId>();
     CompressionMethods = new List<Byte>();
     Extensions = new List<HelloExtension>();
 }
		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();
		}
        private static CipherSuite SelectCipherSuite(CipherSuitePluginManager pluginManager,
            ProtocolVersion clientVersion, ProtocolVersion minVersion, ProtocolVersion maxVersion,
            List<CipherSuiteId> clientSuites, List<CipherSuiteId> serverSuites,
            ServerCertificateSelectionCallback certificateSelectionCallback,
            List<X509CertificateCollection> availableCertificates)
        {
            if (clientVersion < minVersion)
            {
                throw new AlertException(AlertDescription.ProtocolVersion,
                                         "Offered client version " + clientVersion +
                                         " lower than minimum supported version " + minVersion);
            }

            // Initialize our return value as null
            CipherSuite selectedCipherSuite = null;

            // Run as long as we either select a cipher suite or run out of versions
            ProtocolVersion selectedVersion = clientVersion < maxVersion ? clientVersion : maxVersion;
            while (selectedCipherSuite == null)
            {
                foreach (CipherSuiteId id in clientSuites)
                {
                    if (!serverSuites.Contains(id))
                        continue;

                    // Try initializing the cipher suite based on ID
                    selectedCipherSuite = pluginManager.GetCipherSuite(selectedVersion, (ushort)id);
                    if (selectedCipherSuite == null)
                        continue;

                    // Try selecting a suitable certificate for this cipher suite
                    int certificateIndex = certificateSelectionCallback(selectedCipherSuite, availableCertificates.ToArray());
                    if (certificateIndex >= 0 && certificateIndex < availableCertificates.Count)
                    {
                        // We finally found the valid suite, break out from the loop
                        break;
                    }
                    // No certificate was found for the suite, ignore
                    selectedCipherSuite = null;
                }

                if (selectedCipherSuite != null) break;
                if (selectedVersion == minVersion) break;
                selectedVersion = selectedVersion.PreviousProtocolVersion;
            }

            if (selectedCipherSuite == null)
            {
                throw new AlertException(AlertDescription.HandshakeFailure,
                                         "None of the cipher suites offered by client is accepted");
            }
            return selectedCipherSuite;
        }
        protected override void DecodeDataBytes(ProtocolVersion ver, byte[] data)
        {
            MemoryStream memStream = new MemoryStream(data);
            HandshakeStream stream = new HandshakeStream(memStream);

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

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

            int idLength = (int)stream.ReadUInt8();
            SessionID = stream.ReadBytes(idLength);
            Trace.WriteLine($"SessionId: {SessionID}");

            CipherSuite = (CipherSuiteId)stream.ReadUInt16();
            Trace.WriteLine($"Cipher Suite Id: {CipherSuite} refer to list at http://www.thesprawl.org/research/tls-and-ssl-cipher-suites/");
            CompressionMethod = stream.ReadUInt8();

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

            int pos = 0;
            while (pos + 4 <= extensionList.Length)
            {
                HelloExtensionType extensionType = (HelloExtensionType)(UInt16)((extensionList[pos] << 8) | extensionList[pos + 1]);
                Trace.WriteLine($"Extension Type { extensionType }");
                UInt16 extensionDataLength = (UInt16)((extensionList[pos + 2] << 8) | extensionList[pos + 3]);
                pos += 4;

                if (pos + extensionDataLength > extensionList.Length)
                {
                    throw new AlertException(AlertDescription.IllegalParameter,
                                             "ServerHello 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 Record[] ProcessOutputData(ProtocolVersion version, byte type, byte[] data, int maxFragmentLength)
        {
            List<Record> records = new List<Record>();

            // Read handshake data from memory stream one at a time
            MemoryStream memStream = new MemoryStream(data);
            while (memStream.Position < memStream.Length)
            {
                long fragmentLength = Math.Min(memStream.Length - memStream.Position, maxFragmentLength);
                byte[] fragment = new byte[fragmentLength];
                memStream.Read(fragment, 0, fragment.Length);
                Record record = new Record((RecordType)type, version);
                record.Fragment = fragment;
                records.Add(record);
            }

            return records.ToArray();
        }
        public SecurityParameters()
        {
            _availableCertificates = new List<X509CertificateCollection>();
            _availablePrivateKeys = new List<CertificatePrivateKey>();

            MinimumVersion = ProtocolVersion.SSL3_0;
            MaximumVersion = ProtocolVersion.TLS1_2;

            CipherSuiteIDs = new List<CipherSuiteId>();
            //CipherSuiteIDs.Add(0x002F); // TLS_RSA_WITH_AES_128_CBC_SHA
            //CipherSuiteIDs.Add(0x0033); // TLS_DHE_RSA_WITH_AES_128_CBC_SHA

            CompressionIDs = new List<byte>();
            CompressionIDs.Add(0x00);

            ClientCertificateTypes = new List<CertificateType>();
            ClientCertificateAuthorities = new List<string>();
        }
        protected override byte[] EncodeDataBytes(ProtocolVersion ver)
        {
            MemoryStream memStream = new MemoryStream();
            HandshakeStream stream = new HandshakeStream(memStream);

            stream.WriteUInt8(ServerVersion.Major);
            stream.WriteUInt8(ServerVersion.Minor);

            stream.WriteBytes(Random.GetBytes());

            stream.WriteUInt8((Byte)SessionID.Length);
            stream.WriteBytes(SessionID);

            stream.WriteUInt16((ushort)CipherSuite);
            stream.WriteUInt8(CompressionMethod);

            if (Extensions.Count > 0)
            {
                int length = 0;
                foreach (HelloExtension ext in Extensions)
                {
                    if (!ext.SupportsProtocolVersion(ServerVersion))
                        continue;
                    length += 4 + ext.Data.Length;
                }
                stream.WriteUInt16((UInt16)length);
                foreach (HelloExtension ext in Extensions)
                {
                    if (!ext.SupportsProtocolVersion(ServerVersion))
                        continue;

                    HelloExtensionType type = ext.Type;
                    byte[] data = ext.Data;

                    stream.WriteUInt16((ushort)type);
                    stream.WriteUInt16((UInt16)data.Length);
                    stream.WriteBytes(data);
                }
            }

            return memStream.ToArray();
        }
        public HandshakeMessage[] ProcessHandshakeRecord(ProtocolVersion version,
                                                         Record record)
        {
            List<HandshakeMessage> ret = new List<HandshakeMessage>();

            // Write record to input stream and attempt to parse a handshake message
            _inputStream.Write(record.Fragment, 0, record.Fragment.Length);
            while (_inputStream.Length - _inputtedBytes >= 4)
            {
                byte[] inputBuffer = _inputStream.GetBuffer();

                int dataLength = (inputBuffer[_inputtedBytes + 1] << 16) |
                                 (inputBuffer[_inputtedBytes + 2] << 8) |
                                  inputBuffer[_inputtedBytes + 3];

                // Check that if we have enough data to read message now
                if (4 + dataLength > _inputStream.Length - _inputtedBytes)
                    break;

                byte[] msgData = new byte[4 + dataLength];
                long writePosition = _inputStream.Position;

                // Read message data from inputStream
                _inputStream.Position = _inputtedBytes;
                _inputStream.Read(msgData, 0, msgData.Length);
                _inputStream.Position = writePosition;
                _inputtedBytes += msgData.Length;

                // Add resulting handshake message to the results
                ret.Add(HandshakeMessage.GetInstance(version, msgData));
            }

            if (_inputtedBytes == _inputStream.Length)
            {
                // Reset stream to save memory
                _inputStream.Position = 0;
                _inputStream.SetLength(0);
                _inputtedBytes = 0;
            }

            return ret.ToArray();
        }
		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();
		}
        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((CipherSuiteId)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)
            {
                HelloExtensionType extensionType = (HelloExtensionType)((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));
            }
        }
        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;
        }
Пример #17
0
		private void ValidateForProtocolVersion(ProtocolVersion version)
		{
			switch (Description) {
			// Warning alerts that are SSLv3 only
			case AlertDescription.NoCertificate:
				Level = AlertLevel.Warning;
				if (version != ProtocolVersion.SSL3_0)
					Level = AlertLevel.None;
				break;
				
			// Warning alerts supported in all versions
			case AlertDescription.CloseNotify:
				Level = AlertLevel.Warning;
				break;

			// Fatal alerts supported in all versions
			case AlertDescription.UnexpectedMessage:
			case AlertDescription.BadRecordMAC:
			case AlertDescription.DecompressionFailure:
			case AlertDescription.HandshakeFailure:
			case AlertDescription.IllegalParameter:
				Level = AlertLevel.Fatal;
				break;
				
			// Other alerts supported in all versions
			case AlertDescription.BadCertificate:
			case AlertDescription.UnsupportedCertificate:
			case AlertDescription.CertificateRevoked:
			case AlertDescription.CertificateExpired:
			case AlertDescription.CertificateUnknown:
				break;

			// Fatal alerts that are TLS only
			case AlertDescription.UnknownCA:
			case AlertDescription.AccessDenied:
				Level = AlertLevel.Fatal;
				if (version == ProtocolVersion.SSL3_0)
					Description = AlertDescription.CertificateUnknown;
				break;
			case AlertDescription.RecordOverflow:
			case AlertDescription.DecodeError:
			case AlertDescription.DecryptError:
			case AlertDescription.InternalError:
				Level = AlertLevel.Fatal;
				if (version == ProtocolVersion.SSL3_0)
					Description = AlertDescription.IllegalParameter;
				break;
			case AlertDescription.ProtocolVersion:
			case AlertDescription.InsufficientSecurity:
				Level = AlertLevel.Fatal;
				if (version == ProtocolVersion.SSL3_0)
					Description = AlertDescription.HandshakeFailure;
				break;
			
			// Warning alerts that are TLS only
			case AlertDescription.UserCanceled:
			case AlertDescription.NoRenegotiation:
				Level = AlertLevel.Warning;
				if (version == ProtocolVersion.SSL3_0)
					Level = AlertLevel.None;
				break;
			
			// Fatal alerts that are TLSv1.2 only
			case AlertDescription.UnsupportedExtension:
				Level = AlertLevel.Fatal;
				if (version != ProtocolVersion.TLS1_2)
					Description = AlertDescription.IllegalParameter;
				break;
			}
		}
		public HandshakeHelloVerifyRequest(ProtocolVersion version) : base(HandshakeMessageType.HelloVerifyRequest, version)
		{
			ServerVersion  = version;
			Cookie         = new byte[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;
		}
		protected virtual void DecodeDataBytes(ProtocolVersion version, byte[] data)
		{
			_data = data;
		}
		protected virtual byte[] EncodeDataBytes(ProtocolVersion version)
		{
			return _data;
		}
		public HandshakeCertificate(ProtocolVersion version) : base(HandshakeMessageType.Certificate, version)
		{
			CertificateList = new X509CertificateCollection();
		}
		public HandshakeMessage(HandshakeMessageType type, ProtocolVersion version)
		{
			Type = type;
			_version = version;
			_data = new byte[0];
		}
        protected override void ProcessClientHello(HandshakeClientHello clientHello)
        {
            if (_state == HandshakeState.Finished)
            {
                throw new AlertException(AlertDescription.NoRenegotiation,
                                         "Renegotiation not supported");
            }
            else if (_state != HandshakeState.Initial)
            {
                throw new AlertException(AlertDescription.UnexpectedMessage,
                                         "Client hello received at the wrong time");
            }

            // Find the compressions that match our supported compressions
            List<Byte> matchedCompressions = new List<Byte>();
            foreach (Byte id in _supportedCompressions)
            {
                if (clientHello.CompressionMethods.Contains(id))
                {
                    matchedCompressions.Add(id);
                }
            }
            if (matchedCompressions.Count == 0)
            {
                throw new AlertException(AlertDescription.HandshakeFailure,
                                         "None of the compression methods offered by client is accepted");
            }

            _clientVersion = clientHello.ClientVersion;
            _cipherSuite = SelectCipherSuite(_pluginManager, _clientVersion, _minVersion, _maxVersion, clientHello.CipherSuites, new List<CipherSuiteId>(_supportedCipherSuites), _certificateSelectionCallback, _availableCertificates);
            _version = _cipherSuite.ProtocolVersion;

            // Select the certificate and private key we are going to send
            int certificateIndex = _certificateSelectionCallback(_cipherSuite, _availableCertificates.ToArray());
            if (certificateIndex >= 0 && certificateIndex < _availableCertificates.Count)
            {
                _serverCertificates.AddRange(_availableCertificates[certificateIndex]);
                _selectedPrivateKey = _availablePrivateKeys[certificateIndex];
            }

            // TODO: Create the server hello message correctly
            HandshakeServerHello serverHello = new HandshakeServerHello(_version);
            serverHello.CipherSuite = (CipherSuiteId)_cipherSuite.CipherSuiteID;
            serverHello.CompressionMethod = matchedCompressions[0];
            OutputMessage(serverHello);

            // Initialize the handshake randoms and cipher suite
            _connectionState.ClientRandom = clientHello.Random.GetBytes();
            _connectionState.ServerRandom = serverHello.Random.GetBytes();

            // TODO: If we resumed our session, set state to SendChangeCipherSpec and return

            // Send certificate if required and valid
            if (!_cipherSuite.IsAnonymous)
            {
                if (_serverCertificates.Count == 0)
                {
                    throw new AlertException(AlertDescription.HandshakeFailure,
                                             "Certificate required but not selected");
                }

                string keyexAlg = _cipherSuite.KeyExchangeAlgorithm.CertificateKeyAlgorithm;
                string signAlg = _cipherSuite.SignatureAlgorithm.CertificateKeyAlgorithm;

                X509Certificate cert = _serverCertificates[0];
                if (keyexAlg != null && !keyexAlg.Equals(cert.GetKeyAlgorithm()))
                {
                    throw new AlertException(AlertDescription.HandshakeFailure,
                                             "Selected certificate type " + cert.GetKeyAlgorithm() + " doesn't match key exchange type " + keyexAlg);
                }
                if (signAlg != null && !signAlg.Equals(cert.GetKeyAlgorithm()))
                {
                    throw new AlertException(AlertDescription.HandshakeFailure,
                                             "Selected certificate type " + cert.GetKeyAlgorithm() + " doesn't match signature type " + signAlg);
                }

                HandshakeCertificate certificate = new HandshakeCertificate(_version);
                certificate.CertificateList.AddRange(_serverCertificates);
                OutputMessage(certificate);
            }

            byte[] serverKeys = _cipherSuite.KeyExchangeAlgorithm.GetServerKeys(_maxVersion, _selectedPrivateKey);
            if (serverKeys != null)
            {
                // Generate the signature for server keys
                byte[] dataToSign = new byte[_connectionState.ClientRandom.Length + _connectionState.ServerRandom.Length + serverKeys.Length];
                Buffer.BlockCopy(_connectionState.ClientRandom, 0, dataToSign, 0, _connectionState.ClientRandom.Length);
                Buffer.BlockCopy(_connectionState.ServerRandom, 0, dataToSign, _connectionState.ClientRandom.Length, _connectionState.ServerRandom.Length);
                Buffer.BlockCopy(serverKeys, 0, dataToSign, _connectionState.ClientRandom.Length + _connectionState.ServerRandom.Length, serverKeys.Length);
                byte[] signature = GenerateSignature(_selectedPrivateKey, dataToSign);
                Log.Debug("Server Signature: " + BitConverter.ToString(signature));
                
                // Combine the server keys with the signature
                byte[] signedKeys = new byte[serverKeys.Length + signature.Length];
                Buffer.BlockCopy(serverKeys, 0, signedKeys, 0, serverKeys.Length);
                Buffer.BlockCopy(signature, 0, signedKeys, serverKeys.Length, signature.Length);
                
                HandshakeMessage keyex = new HandshakeMessage(HandshakeMessageType.ServerKeyExchange, _version, signedKeys);
                OutputMessage(keyex);
            }

            // Send certificate request if needed
            if (!_cipherSuite.IsAnonymous && _certificateRequest != null)
            {
                OutputMessage(_certificateRequest);
                _certificateRequestSent = true;
            }

            HandshakeMessage serverHelloDone = new HandshakeMessage(HandshakeMessageType.ServerHelloDone, _version);
            OutputMessage(serverHelloDone);

            // Wait for client certificate or client key exchange
            _state = HandshakeState.ReceivedClientHello;
        }
Пример #25
0
		public Alert(AlertLevel level, AlertDescription description, ProtocolVersion version)
		{
			Level = level;
			Description = description;
			ValidateForProtocolVersion(version);
		}
Пример #26
0
 public Record(RecordType type, ProtocolVersion version)
     : this(type, version, new byte[0])
 {
 }
Пример #27
0
 public Record(RecordType type, ProtocolVersion version, byte[] fragment)
 {
     this.Type = type;
     this.Version = version;
     this.Fragment = fragment;
 }
 public virtual bool SupportsProtocolVersion(ProtocolVersion version)
 {
     return version.HasExtensions;
 }
 public override bool SupportsProtocolVersion(ProtocolVersion version)
 {
     return version.HasSelectableSighash;
 }
Пример #30
0
		public Alert(AlertDescription description, ProtocolVersion version)
			: this(AlertLevel.Fatal, description, version) {}