#define TRACE using System; using System.Diagnostics; using System.Globalization; using System.Numerics; using System.Security.Cryptography; using System.Text; using ArchestrAServices.Common; namespace ArchestrAServices.ASBContract; public class SysAuthClientAuthentication : SysAuthConnectionBase { private RNGCryptoServiceProvider m_Random = new RNGCryptoServiceProvider(); private readonly WeakReference owner; public uint Timeout { get; set; } public BigInteger ClientPrivateKey { get; private set; } public BigInteger ClientPublicKey { get; private set; } public BigInteger ServicePublicKey { get; private set; } public bool IsOwnerAlive { get { if (owner != null) { return owner.IsAlive; } return true; } } [Obsolete("Please use the constructor that takes the owner as well.")] public SysAuthClientAuthentication(string ASBSolution) : this(ASBSolution, null) { } public SysAuthClientAuthentication(string ASBSolution, WeakReference owner) : base(ASBSolution) { Reset(); base.ReasonSecureSessionNotEstablished = "Constructed"; this.owner = owner; } public static bool EstablishSecureSession(string application, string domain, string host, string asbSolution, WeakReference owner, MakeCallToAuthenticationConnect connectDelegate, MakeCalltoAuthenticateMe authenticateMeDelegate, out Guid connectionId) { string ReasonSecureSessionNotEstablished; return EstablishSecureSession(application, domain, host, asbSolution, owner, connectDelegate, authenticateMeDelegate, out connectionId, out ReasonSecureSessionNotEstablished); } [Obsolete("Please use the method that requires the owner as well.")] public static bool EstablishSecureSession(string application, string domain, string host, string asbSolution, MakeCallToAuthenticationConnect connectDelegate, MakeCalltoAuthenticateMe authenticateMeDelegate, out Guid connectionId) { return EstablishSecureSession(application, domain, host, asbSolution, null, connectDelegate, authenticateMeDelegate, out connectionId); } [CLSCompliant(false)] [Obsolete("Please use the method that requires the owner as well.")] public static bool EstablishSecureSession(string application, string domain, string host, string asbSolution, MakeCallToAuthenticationConnect connectDelegate, MakeCalltoAuthenticateMe authenticateMeDelegate, out Guid connectionId, out string ReasonSecureSessionNotEstablished) { return EstablishSecureSession(application, domain, host, asbSolution, null, connectDelegate, authenticateMeDelegate, out connectionId, out ReasonSecureSessionNotEstablished); } [CLSCompliant(false)] public static bool EstablishSecureSession(string application, string domain, string host, string asbSolution, WeakReference owner, MakeCallToAuthenticationConnect connectDelegate, MakeCalltoAuthenticateMe authenticateMeDelegate, out Guid connectionId, out string ReasonSecureSessionNotEstablished) { SysAuthClientAuthentication sysAuthClientAuthentication = new SysAuthClientAuthentication(asbSolution, owner); ReasonSecureSessionNotEstablished = string.Empty; SysAuthenticatorClientCache.AddClientAuthenticator(sysAuthClientAuthentication); connectionId = sysAuthClientAuthentication.connectionID; PublicKey publicKey = new PublicKey(); publicKey.Data = sysAuthClientAuthentication.m_LocalPublicKey; ConnectRequest request = new ConnectRequest(connectionId, publicKey); ConnectResponse connectResponse = null; try { connectResponse = connectDelegate(request); } catch (Exception ex) { string text = string.Format(CultureInfo.CurrentCulture, "Exception connecting to service during EstablishSecureSession: {0}", new object[1] { ex.Message }); SvcTrace.DiagControl.TraceEvent(TraceEventType.Warning, 0, text); if (string.IsNullOrEmpty(ReasonSecureSessionNotEstablished)) { ReasonSecureSessionNotEstablished = text; } } if (connectResponse != null) { if (connectResponse.Result.Success) { sysAuthClientAuthentication.m_RemotePublicKey = connectResponse.ServicePublicKey.Data; sysAuthClientAuthentication.SignatureMethod = SigningMethod.Baktun; sysAuthClientAuthentication.ReasonSecureSessionNotEstablished = string.Empty; if (sysAuthClientAuthentication.ValidResponse(connectResponse, ForceHmac: true)) { sysAuthClientAuthentication.m_Authenticated = true; if (connectResponse.ConnectionLifetime.Contains(":" + SysAuthConnectionBase.ASBAuthenticationVersion)) { sysAuthClientAuthentication.SignatureMethod = SigningMethod.Apollo; } SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 100, "SysClientAuth: Connect() response validated, signing set to {0}", (sysAuthClientAuthentication.SignatureMethod == SigningMethod.Baktun) ? "System Platform 2012R2 Comptibility" : "System Platform 2014 Compatibility"); byte[] initializationVector; AuthenticateMe request2 = new AuthenticateMe(new AuthenticationData { Data = sysAuthClientAuthentication.CalculateAuthenticationData(sysAuthClientAuthentication.m_LocalPublicKey, sysAuthClientAuthentication.m_RemotePublicKey, out initializationVector), InitializationVector = initializationVector }); sysAuthClientAuthentication.Sign(request2, ForceHmac: true); authenticateMeDelegate(request2); } else { if (string.IsNullOrEmpty(ReasonSecureSessionNotEstablished)) { if (!string.IsNullOrEmpty(sysAuthClientAuthentication.ReasonSecureSessionNotEstablished)) { ReasonSecureSessionNotEstablished = "Service returned response to Connect method, but validation failed: " + sysAuthClientAuthentication.ReasonSecureSessionNotEstablished; } else { ReasonSecureSessionNotEstablished = "Service returned response to Connect method, but validation data was not valid, cannot establish secure session"; } } SysAuthenticatorClientCache.RemoveClientAuthenticator(connectionId); connectionId = Guid.Empty; } } else { if (string.IsNullOrEmpty(ReasonSecureSessionNotEstablished)) { string text2 = string.Empty; if (connectResponse.Result.ErrorMessages != null && connectResponse.Result.ErrorMessages.Length != 0) { string[] errorMessages = connectResponse.Result.ErrorMessages; foreach (string text3 in errorMessages) { text2 = text2 + text3 + "| "; } } if (string.IsNullOrEmpty(text2)) { ReasonSecureSessionNotEstablished = string.Format(CultureInfo.CurrentCulture, "Service returned error {0} in response to Connect method, cannot establish secure connection.", new object[1] { connectResponse.Result.ErrorCode }); } else { ReasonSecureSessionNotEstablished = string.Format(CultureInfo.CurrentCulture, "Service returned error {0} in response to Connect method, cannot establish secure connection. Additional information: {1}", new object[2] { connectResponse.Result.ErrorCode, text2 }); } } SysAuthenticatorClientCache.RemoveClientAuthenticator(connectionId); connectionId = Guid.Empty; } } else { SysAuthenticatorClientCache.RemoveClientAuthenticator(connectionId); connectionId = Guid.Empty; } return sysAuthClientAuthentication.SecureSessionEstablished; } public void AbortSession() { SysAuthenticatorClientCache.RemoveClientAuthenticator(connectionID); Reset(); base.ReasonSecureSessionNotEstablished = "Session Aborted"; } [CLSCompliant(false)] public static void DisconnectSecureSession(Guid connectionId, MakeCallToServiceDisconnect DisconnectDelegate) { SysAuthClientAuthentication clientAuthenticator = SysAuthenticatorClientCache.GetClientAuthenticator(connectionId); if (clientAuthenticator != null) { byte[] initializationVector; Disconnect request = new Disconnect(new AuthenticationData { Data = clientAuthenticator.Encypher(Encoding.UTF8.GetBytes(clientAuthenticator.connectionID.ToString()), out initializationVector), InitializationVector = initializationVector }); clientAuthenticator.Sign(request); DisconnectDelegate?.Invoke(request); SysAuthenticatorClientCache.RemoveClientAuthenticator(connectionId); } } private new void Reset() { base.Reset(); Timeout = 10000u; } }