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); }
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; }