using System; using System.Globalization; using System.Text; using ArchestrAServices.Common; namespace Asb.Base.V2; public class SystemAuthenticationClientAuthentication : SystemAuthenticationConnectionBase { public uint Timeout { get; set; } public SystemAuthenticationClientAuthentication(string asbSolution) : base(asbSolution) { Reset(); base.ReasonSecureSessionNotEstablished = "Constructed"; } public static bool EstablishSecureSession(string asbSolution, ClientMetadata clientMetadata, Func connectDelegate, Func authenticateMeDelegate, Action connectionIdHandler, Action reasonSecureSessionNotEstablishedHandler) { SystemAuthenticationClientAuthentication systemAuthenticationClientAuthentication = new SystemAuthenticationClientAuthentication(asbSolution); SysAuthenticatorClientCache.AddClientAuthenticator(systemAuthenticationClientAuthentication); Guid connectionId = systemAuthenticationClientAuthentication.ConnectionId; PublicKey consumerPublicKey = new PublicKey { Data = systemAuthenticationClientAuthentication.LocalPublicKey }; ConnectRequest arg = new ConnectRequest(connectionId, consumerPublicKey, asbSolution); ConnectResponse connectResponse = null; try { connectResponse = connectDelegate?.Invoke(arg); } catch (Exception ex) { string text = string.Format(CultureInfo.CurrentCulture, "Exception connecting to service during EstablishSecureSession: {0}", new object[1] { ex.Message }); ServiceTrace.LogWarning(text); reasonSecureSessionNotEstablishedHandler?.Invoke(text); } if (connectResponse != null) { if (connectResponse.Result.Success) { systemAuthenticationClientAuthentication.RemotePublicKey = connectResponse.ServicePublicKey.Data; systemAuthenticationClientAuthentication.ReasonSecureSessionNotEstablished = string.Empty; if (systemAuthenticationClientAuthentication.ValidResponse(connectResponse, forceHmac: true)) { byte[] initializationVector; AuthenticateMeRequest authenticateMeRequest = new AuthenticateMeRequest(new AuthenticationData { Data = systemAuthenticationClientAuthentication.CalculateAuthenticationData(systemAuthenticationClientAuthentication.LocalPublicKey, systemAuthenticationClientAuthentication.RemotePublicKey, out initializationVector), InitializationVector = initializationVector }, clientMetadata); systemAuthenticationClientAuthentication.Sign(authenticateMeRequest, forceHmac: true); AuthenticateMeResponse authenticateMeResponse = authenticateMeDelegate(authenticateMeRequest); if (authenticateMeResponse != null && authenticateMeResponse.Result.Success) { systemAuthenticationClientAuthentication.SecureSessionEstablished = true; connectionIdHandler?.Invoke(connectionId); } else { ServiceTrace.LogVerbose("Service rejected the connection at the AuthenticateMe stage"); string obj = "Service rejected the connection at the AuthenticateMe stage"; if (authenticateMeResponse != null) { obj = ((authenticateMeResponse.Result.ErrorMessages == null || authenticateMeResponse.Result.ErrorMessages.Length == 0) ? string.Format(CultureInfo.CurrentCulture, "Service returned error {0} in response to AuthenticateMe method, cannot establish secure connection.", new object[1] { authenticateMeResponse.Result.ResultCodeAsError }) : authenticateMeResponse.Result.ErrorMessages[0]); } reasonSecureSessionNotEstablishedHandler?.Invoke(obj); SysAuthenticatorClientCache.RemoveClientAuthenticator(connectionId); connectionIdHandler?.Invoke(Guid.Empty); } } else { if (!string.IsNullOrEmpty(systemAuthenticationClientAuthentication.ReasonSecureSessionNotEstablished)) { reasonSecureSessionNotEstablishedHandler?.Invoke("Service returned response to Connect method, but validation failed: " + systemAuthenticationClientAuthentication.ReasonSecureSessionNotEstablished); } else { reasonSecureSessionNotEstablishedHandler?.Invoke("Service returned response to Connect method, but validation data was not valid, cannot establish secure session"); } SysAuthenticatorClientCache.RemoveClientAuthenticator(connectionId); connectionIdHandler?.Invoke(Guid.Empty); } } else { if (connectResponse.Result.ErrorMessages != null && connectResponse.Result.ErrorMessages.Length != 0) { reasonSecureSessionNotEstablishedHandler?.Invoke(string.Format(CultureInfo.CurrentCulture, "Service returned error {0} in response to Connect method, cannot establish secure connection. Additional information:", new object[1] { connectResponse.Result.ResultCodeAsError })); string[] errorMessages = connectResponse.Result.ErrorMessages; foreach (string obj2 in errorMessages) { reasonSecureSessionNotEstablishedHandler?.Invoke(obj2); } } else { reasonSecureSessionNotEstablishedHandler?.Invoke(string.Format(CultureInfo.CurrentCulture, "Service returned error {0} in response to Connect method, cannot establish secure connection.", new object[1] { connectResponse.Result.ResultCodeAsError })); } SysAuthenticatorClientCache.RemoveClientAuthenticator(connectionId); connectionIdHandler?.Invoke(Guid.Empty); } } else { SysAuthenticatorClientCache.RemoveClientAuthenticator(connectionId); connectionIdHandler?.Invoke(Guid.Empty); } return systemAuthenticationClientAuthentication.SecureSessionEstablished; } public void AbortSession() { Reset(); base.ReasonSecureSessionNotEstablished = "Session Aborted"; } public static void DisconnectSecureSession(Guid connectionId, Action disconnectDelegate) { SystemAuthenticationClientAuthentication clientAuthenticator = SysAuthenticatorClientCache.GetClientAuthenticator(connectionId); if (clientAuthenticator != null) { byte[] initializationVector; DisconnectRequest disconnectRequest = new DisconnectRequest(new AuthenticationData { Data = clientAuthenticator.EncypherWithNewInitializationVector(Encoding.UTF8.GetBytes(clientAuthenticator.ConnectionId.ToString()), out initializationVector), InitializationVector = initializationVector }); clientAuthenticator.Sign(disconnectRequest, forceHmac: false); disconnectDelegate?.Invoke(disconnectRequest); } } private new void Reset() { base.Reset(); Timeout = 10000u; } }