/// <summary> /// Räumt abgelaufende Client-Verbindungen weg. /// </summary> private void SweepConnections(object sender, ElapsedEventArgs e) { lock (_connections.SyncRoot) { // Liste für Löschungen erzeugen ArrayList toDelete = new ArrayList(_connections.Count); // Alle Verbindungen durchlaufen foreach (DictionaryEntry entry in _connections) { // Daten der aktuell durchlaufenen Verbindung abrufen ClientConnectionData connectionData = (ClientConnectionData)entry.Value; // Wenn die Verbindung bereits das Zeitlimit überschritten hat (abgelaufen ist) ... if (connectionData.Timestamp.AddSeconds(_connectionAgeLimit).CompareTo(DateTime.UtcNow) < 0) { // Sicherheitstransaktionskennung der Verbindung zur Löschliste zufügen toDelete.Add(entry.Key); // Verbindung entsorgen ((IDisposable)connectionData).Dispose(); } } // Löschliste durchlaufen foreach (Object obj in toDelete) { // Verbindung löschen _connections.Remove(obj); } } }
/// <summary> /// Erzeugt den gemeinsamen Schlüssel und bereitet dessen Übertragung zum Client vor. /// </summary> /// <param name="transactID">Sicherheitstransaktionskennung</param> /// <param name="requestHeaders">Anfrage-Header vom Client</param> /// <param name="responseMsg">Antwortnachricht</param> /// <param name="responseHeaders">Antwort-Header</param> /// <param name="responseStream">Antwort-Datenstrom</param> /// <returns>Status</returns> private ServerProcessing MakeSharedKey(Guid transactID, ITransportHeaders requestHeaders, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { // Gemeinsamer Schlüssel und Inizialisierungsvektor SymmetricAlgorithm symmetricProvider = CryptoTools.CreateSymmetricCryptoProvider(_algorithm); // Clientverbindungsdaten erzeugen ClientConnectionData connectionData = new ClientConnectionData(transactID, symmetricProvider); lock (_connections.SyncRoot) { // Clientverbindungsdaten unter der angegebenen Sicherheitstransaktionskennung speichern _connections[transactID.ToString()] = connectionData; } // RSA Kryptografieanbieter erzeugen RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(); // Öffentlichen Schlüssel (vom Client) aus den Anfrage-Headern lesen string publicKey = (string)requestHeaders[CommonHeaderNames.PUBLIC_KEY]; // Wenn kein öffentlicher Schlüssel gefunden wurde ... if (string.IsNullOrEmpty(publicKey)) { throw new CryptoRemotingException(LanguageResource.CryptoRemotingException_PublicKeyNotFound); } // Öffentlichen Schlüssel in den Kryptografieanbieter laden rsaProvider.FromXmlString(publicKey); // Gemeinsamen Schlüssel und dessen Inizialisierungsfaktor verschlüsseln byte[] encryptedKey = rsaProvider.Encrypt(symmetricProvider.Key, _oaep); byte[] encryptedIV = rsaProvider.Encrypt(symmetricProvider.IV, _oaep); // Antwort-Header zusammenstellen responseHeaders = new TransportHeaders(); responseHeaders[CommonHeaderNames.SECURE_TRANSACTION_STATE] = ((int)SecureTransactionStage.SendingSharedKey).ToString(); responseHeaders[CommonHeaderNames.SHARED_KEY] = Convert.ToBase64String(encryptedKey); responseHeaders[CommonHeaderNames.SHARED_IV] = Convert.ToBase64String(encryptedIV); // Es wird keine Antwortnachricht benötigt responseMsg = null; responseStream = new MemoryStream(); // Vollständige Verarbeitung zurückmelden return(ServerProcessing.Complete); }
/// <summary> /// Creates the shared key. /// </summary> /// <param name="transactID">Secure transaction identifier.</param> /// <param name="requestHeaders">Request transport headers.</param> /// <param name="responseMsg">The response message.</param> /// <param name="responseHeaders">The response headers.</param> /// <param name="responseStream">The response stream.</param> private ServerProcessing MakeSharedKey(Guid transactID, ITransportHeaders requestHeaders, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { // save shared symmetric encryption key and initialization vector for the current client connection SymmetricAlgorithm symmetricProvider = CryptoTools.CreateSymmetricCryptoProvider(_algorithm); ClientConnectionData connectionData = new ClientConnectionData(transactID, symmetricProvider); // Store client data connection under the specified security transaction identifier lock (_connections.SyncRoot) { _connections[transactID.ToString()] = connectionData; } // Get client's RSA public key string publicKey = (string)requestHeaders[CommonHeaderNames.PUBLIC_KEY]; if (string.IsNullOrEmpty(publicKey)) { throw new CryptoRemotingException(LanguageResource.CryptoRemotingException_PublicKeyNotFound); } // Initialize RSA cryptographic provider using the client's public key RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(); rsaProvider.FromXmlString(publicKey); // Encrypt shared key for the symmetric algorithm using the client's public key byte[] encryptedKey = rsaProvider.Encrypt(symmetricProvider.Key, _oaep); byte[] encryptedIV = rsaProvider.Encrypt(symmetricProvider.IV, _oaep); // Put the data to the response headers responseHeaders = new TransportHeaders(); responseHeaders[CommonHeaderNames.SECURE_TRANSACTION_STATE] = ((int)SecureTransactionStage.SendingSharedKey).ToString(); responseHeaders[CommonHeaderNames.SHARED_KEY] = Convert.ToBase64String(encryptedKey); responseHeaders[CommonHeaderNames.SHARED_IV] = Convert.ToBase64String(encryptedIV); // There is no response message responseMsg = null; responseStream = new MemoryStream(); return(ServerProcessing.Complete); }
/// <summary> /// Sweeps the connections. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="ElapsedEventArgs"/> instance containing the event data.</param> private void SweepConnections(object sender, ElapsedEventArgs e) { lock (_connections.SyncRoot) { // Connections to be swept ArrayList toDelete = new ArrayList(_connections.Count); foreach (DictionaryEntry entry in _connections) { ClientConnectionData connectionData = (ClientConnectionData)entry.Value; if (connectionData.Timestamp.AddSeconds(_connectionAgeLimit).CompareTo(DateTime.UtcNow) < 0 && !connectionData.CallInProgress) { toDelete.Add(entry.Key); ((IDisposable)connectionData).Dispose(); } } foreach (Object obj in toDelete) { _connections.Remove(obj); } } }
/// <summary> /// Erzeugt den gemeinsamen Schlüssel und bereitet dessen Übertragung zum Client vor. /// </summary> /// <param name="transactID">Sicherheitstransaktionskennung</param> /// <param name="requestHeaders">Anfrage-Header vom Client</param> /// <param name="responseMsg">Antwortnachricht</param> /// <param name="responseHeaders">Antwort-Header</param> /// <param name="responseStream">Antwort-Datenstrom</param> /// <returns>Status</returns> private ServerProcessing MakeSharedKey(Guid transactID, ITransportHeaders requestHeaders, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { // Gemeinsamer Schlüssel und Inizialisierungsvektor SymmetricAlgorithm symmetricProvider = CryptoTools.CreateSymmetricCryptoProvider(_algorithm); // Clientverbindungsdaten erzeugen ClientConnectionData connectionData = new ClientConnectionData(transactID, symmetricProvider); lock (_connections.SyncRoot) { // Clientverbindungsdaten unter der angegebenen Sicherheitstransaktionskennung speichern _connections[transactID.ToString()] = connectionData; } // RSA Kryptografieanbieter erzeugen RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(); // Öffentlichen Schlüssel (vom Client) aus den Anfrage-Headern lesen string publicKey = (string)requestHeaders[CommonHeaderNames.PUBLIC_KEY]; // Wenn kein öffentlicher Schlüssel gefunden wurde ... if (string.IsNullOrEmpty(publicKey)) throw new CryptoRemotingException(LanguageResource.CryptoRemotingException_PublicKeyNotFound); // Öffentlichen Schlüssel in den Kryptografieanbieter laden rsaProvider.FromXmlString(publicKey); // Gemeinsamen Schlüssel und dessen Inizialisierungsfaktor verschlüsseln byte[] encryptedKey = rsaProvider.Encrypt(symmetricProvider.Key, _oaep); byte[] encryptedIV = rsaProvider.Encrypt(symmetricProvider.IV, _oaep); // Antwort-Header zusammenstellen responseHeaders = new TransportHeaders(); responseHeaders[CommonHeaderNames.SECURE_TRANSACTION_STATE] = ((int)SecureTransactionStage.SendingSharedKey).ToString(); responseHeaders[CommonHeaderNames.SHARED_KEY] = Convert.ToBase64String(encryptedKey); responseHeaders[CommonHeaderNames.SHARED_IV] = Convert.ToBase64String(encryptedIV); // Es wird keine Antwortnachricht benötigt responseMsg = null; responseStream = new MemoryStream(); // Vollständige Verarbeitung zurückmelden return ServerProcessing.Complete; }
/// <summary> /// Creates the shared key. /// </summary> /// <param name="transactID">Secure transaction identifier.</param> /// <param name="requestHeaders">Request transport headers.</param> /// <param name="responseMsg">The response message.</param> /// <param name="responseHeaders">The response headers.</param> /// <param name="responseStream">The response stream.</param> private ServerProcessing MakeSharedKey(Guid transactID, ITransportHeaders requestHeaders, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { // save shared symmetric encryption key and initialization vector for the current client connection SymmetricAlgorithm symmetricProvider = CryptoTools.CreateSymmetricCryptoProvider(_algorithm); ClientConnectionData connectionData = new ClientConnectionData(transactID, symmetricProvider); // Store client data connection under the specified security transaction identifier lock (_connections.SyncRoot) { _connections[transactID.ToString()] = connectionData; } // Get client's RSA public key string publicKey = (string)requestHeaders[CommonHeaderNames.PUBLIC_KEY]; if (string.IsNullOrEmpty(publicKey)) throw new CryptoRemotingException(LanguageResource.CryptoRemotingException_PublicKeyNotFound); // Initialize RSA cryptographic provider using the client's public key RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(); rsaProvider.FromXmlString(publicKey); // Encrypt shared key for the symmetric algorithm using the client's public key byte[] encryptedKey = rsaProvider.Encrypt(symmetricProvider.Key, _oaep); byte[] encryptedIV = rsaProvider.Encrypt(symmetricProvider.IV, _oaep); // Put the data to the response headers responseHeaders = new TransportHeaders(); responseHeaders[CommonHeaderNames.SECURE_TRANSACTION_STATE] = ((int)SecureTransactionStage.SendingSharedKey).ToString(); responseHeaders[CommonHeaderNames.SHARED_KEY] = Convert.ToBase64String(encryptedKey); responseHeaders[CommonHeaderNames.SHARED_IV] = Convert.ToBase64String(encryptedIV); // There is no response message responseMsg = null; responseStream = new MemoryStream(); return ServerProcessing.Complete; }