Initial project state: .NET reference, design, Rust port (M0+M1), evidence
rust / build / test / clippy / fmt (push) Has been cancelled
rust / build / test / clippy / fmt (push) Has been cancelled
Layout:
- src/ .NET 10 x64 reference: MxNativeCodec, MxNativeClient,
MxAsbClient, probes, tests, harnesses. Executable spec.
- design/ Architectural plan for the Rust port (M0–M6), error
model, protocol invariants, risks (R1–R16), adversarial
review log (review.md).
- rust/ Rust workspace. M0 skeleton + M1 codec parity.
mxaccess-codec: 215 unit tests + 2 cross-implementation
parity tests (byte-identical against .NET reference).
Other crates are M0 stubs awaiting M2+.
- captures/ Frida + netsh + pcap evidence per CLAUDE.md
("captures are evidence, not throwaway logs").
- analysis/ Decompiled C# (frida/proxy/decompiled-*),
Ghidra exports for native DLLs (`exports/` only —
working state at `projects/` and AVEVA's input
binaries at `input/` are gitignored).
- docs/ Reverse-engineering reference docs.
- tools/ Setup-LiveProbeEnv.ps1 (Infisical credential fetcher),
Compute-Crc.ps1 (.NET parity helper).
- .github/workflows/ Rust CI: fmt + build + test + clippy on Windows.
- LICENSE MIT (Joseph Doherty, 2026).
Verified:
- cargo test --workspace → 217 passed (215 unit + 2 .NET parity), 0 failed
- cargo clippy --workspace -- -D warnings → clean
- cargo fmt --all -- --check → clean
- cargo publish --dry-run -p mxaccess-codec → packages cleanly
Excluded from history (see .gitignore):
- **/bin, **/obj, **/target — build artifacts
- analysis/ghidra/projects/ — Ghidra working state (regenerable)
- analysis/ghidra/input/ — AVEVA proprietary DLLs (vendor IP)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+117
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[Serializable]
|
||||
[GeneratedCode("System.Xml", "4.0.30319.233")]
|
||||
[DebuggerStepThrough]
|
||||
[DesignerCategory("code")]
|
||||
[XmlType(Namespace = "http://asb.contracts.data/20111111")]
|
||||
public class ASBArchestrAResult
|
||||
{
|
||||
private bool successField;
|
||||
|
||||
private int resultCodeField;
|
||||
|
||||
private string locationField;
|
||||
|
||||
private string[] successMessagesField;
|
||||
|
||||
private string[] informationMessagesField;
|
||||
|
||||
private string[] errorMessagesField;
|
||||
|
||||
private NamedValue[] extensionsField;
|
||||
|
||||
public bool Success
|
||||
{
|
||||
get
|
||||
{
|
||||
return successField;
|
||||
}
|
||||
set
|
||||
{
|
||||
successField = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int ResultCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return resultCodeField;
|
||||
}
|
||||
set
|
||||
{
|
||||
resultCodeField = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return locationField;
|
||||
}
|
||||
set
|
||||
{
|
||||
locationField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement("SuccessMessages")]
|
||||
public string[] SuccessMessages
|
||||
{
|
||||
get
|
||||
{
|
||||
return successMessagesField;
|
||||
}
|
||||
set
|
||||
{
|
||||
successMessagesField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement("InformationMessages")]
|
||||
public string[] InformationMessages
|
||||
{
|
||||
get
|
||||
{
|
||||
return informationMessagesField;
|
||||
}
|
||||
set
|
||||
{
|
||||
informationMessagesField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement("ErrorMessages")]
|
||||
public string[] ErrorMessages
|
||||
{
|
||||
get
|
||||
{
|
||||
return errorMessagesField;
|
||||
}
|
||||
set
|
||||
{
|
||||
errorMessagesField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement("Extensions")]
|
||||
public NamedValue[] Extensions
|
||||
{
|
||||
get
|
||||
{
|
||||
return extensionsField;
|
||||
}
|
||||
set
|
||||
{
|
||||
extensionsField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public enum ArchestrAError : ushort
|
||||
{
|
||||
Success = 0,
|
||||
InvalidConnectionId = 1,
|
||||
ApplicationAuthenticationError = 2,
|
||||
UserAuthenticationError = 3,
|
||||
UserAuthorizationError = 4,
|
||||
NotSupportedOperation = 5,
|
||||
MonitoredItemsNotFound = 6,
|
||||
InvalidSubscriptionID = 7,
|
||||
ItemAlreadyRegistered = 8,
|
||||
ItemAlreadyDeletedOrDoesNotExist = 9,
|
||||
InvalidMonitoredItems = 10,
|
||||
OperationFailed = 11,
|
||||
SpecificError = 12,
|
||||
BadNoCommunication = 13,
|
||||
Bad_NothingToDo = 14,
|
||||
Bad_TooManyOperations = 15,
|
||||
Bad_NodeIdInvalid = 16,
|
||||
BrowseFailed = 17,
|
||||
WriteFailed_BadOutOfRange = 18,
|
||||
WriteFailed_BadTypeMismatch = 19,
|
||||
WriteFailed_BadDimensionMismatch = 20,
|
||||
WriteFailed_AccessDenied = 21,
|
||||
WriteFailed_SecuredWrite = 22,
|
||||
WriteFailed_VerifiedWrite = 23,
|
||||
IndexOutOfRange = 24,
|
||||
RequestTimedOut = 25,
|
||||
DataTypeConversionNotSupported = 26,
|
||||
ItemCannotBeRegistered_NoName = 27,
|
||||
ItemCannotBeRegistered_NoId = 28,
|
||||
ItemAlreadyBeingMonitored = 29,
|
||||
SubscriptionIDAlreadyExist = 30,
|
||||
OperationWouldBlock = 31,
|
||||
PublishComplete = 32,
|
||||
WriteFailed_UserNotHavingAccessRights = 33,
|
||||
WriteFailed_VerifierNotHavingVerifyRights = 34,
|
||||
Unknown = ushort.MaxValue
|
||||
}
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[Serializable]
|
||||
[GeneratedCode("System.Xml", "4.0.30319.233")]
|
||||
[DebuggerStepThrough]
|
||||
[XmlType(Namespace = "http://asb.contracts.data/20111111")]
|
||||
public struct ArchestrAResult
|
||||
{
|
||||
private bool successField;
|
||||
|
||||
private int resultCodeField;
|
||||
|
||||
private uint specificErrorCodeField;
|
||||
|
||||
private uint statusCodeField;
|
||||
|
||||
private string locationField;
|
||||
|
||||
private string[] successMessagesField;
|
||||
|
||||
private string[] informationMessagesField;
|
||||
|
||||
private string[] errorMessagesField;
|
||||
|
||||
private NamedValue[] extensionsField;
|
||||
|
||||
public bool Success
|
||||
{
|
||||
get
|
||||
{
|
||||
return successField;
|
||||
}
|
||||
set
|
||||
{
|
||||
successField = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int ResultCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return resultCodeField;
|
||||
}
|
||||
set
|
||||
{
|
||||
resultCodeField = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int ErrorCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return resultCodeField;
|
||||
}
|
||||
set
|
||||
{
|
||||
resultCodeField = value;
|
||||
}
|
||||
}
|
||||
|
||||
public uint SpecificErrorCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return specificErrorCodeField;
|
||||
}
|
||||
set
|
||||
{
|
||||
specificErrorCodeField = value;
|
||||
}
|
||||
}
|
||||
|
||||
public uint Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return statusCodeField;
|
||||
}
|
||||
set
|
||||
{
|
||||
statusCodeField = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return locationField;
|
||||
}
|
||||
set
|
||||
{
|
||||
locationField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement("SuccessMessages")]
|
||||
public string[] SuccessMessages
|
||||
{
|
||||
get
|
||||
{
|
||||
return successMessagesField;
|
||||
}
|
||||
set
|
||||
{
|
||||
successMessagesField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement("InformationMessages")]
|
||||
public string[] InformationMessages
|
||||
{
|
||||
get
|
||||
{
|
||||
return informationMessagesField;
|
||||
}
|
||||
set
|
||||
{
|
||||
informationMessagesField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement("ErrorMessages")]
|
||||
public string[] ErrorMessages
|
||||
{
|
||||
get
|
||||
{
|
||||
return errorMessagesField;
|
||||
}
|
||||
set
|
||||
{
|
||||
errorMessagesField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement("Extensions")]
|
||||
public NamedValue[] Extensions
|
||||
{
|
||||
get
|
||||
{
|
||||
return extensionsField;
|
||||
}
|
||||
set
|
||||
{
|
||||
extensionsField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
[MessageContract(WrapperName = "AuthenticateMeRequest", WrapperNamespace = "http://asb.contracts.messages/20111111", IsWrapped = true)]
|
||||
public class AuthenticateMe : ConnectedRequest
|
||||
{
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 0)]
|
||||
public AuthenticationData ConsumerAuthenticationData;
|
||||
|
||||
public AuthenticateMe()
|
||||
{
|
||||
}
|
||||
|
||||
public AuthenticateMe(AuthenticationData ConsumerAuthenticationData)
|
||||
{
|
||||
this.ConsumerAuthenticationData = ConsumerAuthenticationData;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[Serializable]
|
||||
[GeneratedCode("System.Xml", "4.0.30319.233")]
|
||||
[DebuggerStepThrough]
|
||||
[DesignerCategory("code")]
|
||||
[XmlType(Namespace = "http://asb.contracts.data/20111111")]
|
||||
public class AuthenticationData
|
||||
{
|
||||
private byte[] dataField;
|
||||
|
||||
private byte[] initializationVectorField;
|
||||
|
||||
[XmlElement(DataType = "base64Binary")]
|
||||
public byte[] Data
|
||||
{
|
||||
get
|
||||
{
|
||||
return dataField;
|
||||
}
|
||||
set
|
||||
{
|
||||
dataField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement(DataType = "base64Binary")]
|
||||
public byte[] InitializationVector
|
||||
{
|
||||
get
|
||||
{
|
||||
return initializationVectorField;
|
||||
}
|
||||
set
|
||||
{
|
||||
initializationVectorField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public static class AuthenticationDataExtensions
|
||||
{
|
||||
public static bool AreEqual(this AuthenticationData value, AuthenticationData other)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (value != null && value.Data != null && other != null && other.Data != null)
|
||||
{
|
||||
return value.AreEqual(other.Data);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool AreEqual(this AuthenticationData value, byte[] expected)
|
||||
{
|
||||
bool result = false;
|
||||
try
|
||||
{
|
||||
if (value != null && value.Data != null && expected != null && value.Data.Length == expected.Length)
|
||||
{
|
||||
result = true;
|
||||
for (int i = 0; i < value.Data.Length; i++)
|
||||
{
|
||||
if (value.Data[i] != expected[i])
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
[MessageContract(WrapperName = "ConnectRequest", WrapperNamespace = "http://asb.contracts.messages/20111111", IsWrapped = true)]
|
||||
public class ConnectRequest : ServiceMessage
|
||||
{
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 0)]
|
||||
public Guid ConnectionId;
|
||||
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 1)]
|
||||
public PublicKey ConsumerPublicKey;
|
||||
|
||||
public ConnectRequest()
|
||||
{
|
||||
}
|
||||
|
||||
public ConnectRequest(Guid ConnectionId, PublicKey ConsumerPublicKey)
|
||||
{
|
||||
this.ConnectionId = ConnectionId;
|
||||
this.ConsumerPublicKey = ConsumerPublicKey;
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceModel;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
[MessageContract(WrapperName = "ConnectResponse", WrapperNamespace = "http://asb.contracts.messages/20111111", IsWrapped = true)]
|
||||
public class ConnectResponse : ConnectedResponse
|
||||
{
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 0)]
|
||||
public PublicKey ServicePublicKey;
|
||||
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 1)]
|
||||
public AuthenticationData ServiceAuthenticationData;
|
||||
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 2)]
|
||||
[XmlElement(DataType = "duration")]
|
||||
public string ConnectionLifetime;
|
||||
|
||||
public ConnectResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public ConnectResponse(PublicKey ServicePublicKey, AuthenticationData ServiceAuthenticationData, string ConnectionLifetime)
|
||||
{
|
||||
this.ServicePublicKey = ServicePublicKey;
|
||||
this.ServiceAuthenticationData = ServiceAuthenticationData;
|
||||
this.ConnectionLifetime = ConnectionLifetime;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
[MessageContract]
|
||||
public class ConnectedRequest : ServiceMessage
|
||||
{
|
||||
[MessageHeader(Namespace = "http://asb.contracts.headers/20111111")]
|
||||
public ConnectionValidator ConnectionValidator;
|
||||
|
||||
public ConnectedRequest()
|
||||
{
|
||||
ConnectionValidator = new ConnectionValidator();
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
[MessageContract]
|
||||
public class ConnectedResponse : ConnectedRequest
|
||||
{
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111")]
|
||||
public ArchestrAResult Result;
|
||||
|
||||
public ConnectedResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public ConnectedResponse(ArchestrAResult result)
|
||||
{
|
||||
Result = result;
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[Serializable]
|
||||
[GeneratedCode("System.Xml", "4.0.30319.233")]
|
||||
[DebuggerStepThrough]
|
||||
[DesignerCategory("code")]
|
||||
[XmlType(Namespace = "http://asb.contracts.data/20111111")]
|
||||
public class ConnectionValidator
|
||||
{
|
||||
private Guid connectionIdField;
|
||||
|
||||
private ulong messageNumberField;
|
||||
|
||||
private byte[] messageAuthenticationCodeField;
|
||||
|
||||
private byte[] signatureInitializationVectorField;
|
||||
|
||||
public Guid ConnectionId
|
||||
{
|
||||
get
|
||||
{
|
||||
return connectionIdField;
|
||||
}
|
||||
set
|
||||
{
|
||||
connectionIdField = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ulong MessageNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
return messageNumberField;
|
||||
}
|
||||
set
|
||||
{
|
||||
messageNumberField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement(DataType = "base64Binary")]
|
||||
public byte[] MessageAuthenticationCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return messageAuthenticationCodeField;
|
||||
}
|
||||
set
|
||||
{
|
||||
messageAuthenticationCodeField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement(DataType = "base64Binary")]
|
||||
public byte[] SignatureInitializationVector
|
||||
{
|
||||
get
|
||||
{
|
||||
return signatureInitializationVectorField;
|
||||
}
|
||||
set
|
||||
{
|
||||
signatureInitializationVectorField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public enum CredentialType : ushort
|
||||
{
|
||||
UsernamePassword = 0,
|
||||
X509Certificate = 1,
|
||||
SamlToken = 2,
|
||||
Other = ushort.MaxValue
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public enum CredentialValidity : ushort
|
||||
{
|
||||
UserIdentityValid = 0,
|
||||
UserIdentityInvalid_BadPassword = 1,
|
||||
UserIdentityInvalid_NoUser = 2,
|
||||
UserIdentityInvalid_CannotAuthenticate = 3,
|
||||
UesrIdentityValidityUnknown = ushort.MaxValue
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public static class DataConversionUtilities
|
||||
{
|
||||
public static string ToBase64(this string value)
|
||||
{
|
||||
string result = string.Empty;
|
||||
if (value != null)
|
||||
{
|
||||
result = Encoding.UTF8.GetBytes(value).ToBase64();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string FromBase64(this string value)
|
||||
{
|
||||
string result = string.Empty;
|
||||
if (value != null)
|
||||
{
|
||||
byte[] bytes = value.FromBase64ToByteArray();
|
||||
result = Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string ToBase64(this byte[] value)
|
||||
{
|
||||
string result = string.Empty;
|
||||
try
|
||||
{
|
||||
result = Convert.ToBase64String(value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static string ToHex(this byte[] value)
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (value != null)
|
||||
{
|
||||
foreach (byte b in value)
|
||||
{
|
||||
stringBuilder.Append(b.ToString("X2", CultureInfo.CurrentCulture));
|
||||
}
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public static byte[] FromBase64ToByteArray(this string value)
|
||||
{
|
||||
byte[] result = null;
|
||||
if (value != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = Convert.FromBase64String(value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] FromHexToByteArray(this string value)
|
||||
{
|
||||
List<byte> list = new List<byte>();
|
||||
if (value != null)
|
||||
{
|
||||
string text = value.Replace(" ", string.Empty);
|
||||
text = text.Replace("\r", string.Empty);
|
||||
text = text.Replace("\n", string.Empty);
|
||||
if (text.Length % 2 == 0)
|
||||
{
|
||||
for (int i = 0; i < text.Length; i += 2)
|
||||
{
|
||||
if (byte.TryParse(text.Substring(i, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result))
|
||||
{
|
||||
list.Add(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
[MessageContract(WrapperName = "DisconnectRequest", WrapperNamespace = "http://asb.contracts.messages/20111111", IsWrapped = true)]
|
||||
public class Disconnect : ConnectedRequest
|
||||
{
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 0)]
|
||||
public AuthenticationData ConsumerAuthenticationData;
|
||||
|
||||
public Disconnect()
|
||||
{
|
||||
}
|
||||
|
||||
public Disconnect(AuthenticationData ConsumerAuthenticationData)
|
||||
{
|
||||
this.ConsumerAuthenticationData = ConsumerAuthenticationData;
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public enum EncryptionType : ushort
|
||||
{
|
||||
None
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public static class EnumASBFactory
|
||||
{
|
||||
public static ArchestrAError IntToArchestrAError(ushort iValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (ArchestrAError)iValue;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return ArchestrAError.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public static ushort ArchestrAErrorToInt(ArchestrAError eValue)
|
||||
{
|
||||
return (ushort)eValue;
|
||||
}
|
||||
|
||||
public static CredentialType IntToCredentialType(ushort iValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (CredentialType)iValue;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return CredentialType.Other;
|
||||
}
|
||||
}
|
||||
|
||||
public static ushort CredentialTypeToInt(CredentialType eValue)
|
||||
{
|
||||
return (ushort)eValue;
|
||||
}
|
||||
|
||||
public static EncryptionType IntToEncryptionType(ushort iValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (EncryptionType)iValue;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return EncryptionType.None;
|
||||
}
|
||||
}
|
||||
|
||||
public static ushort EncryptionTypeToInt(EncryptionType eValue)
|
||||
{
|
||||
return (ushort)eValue;
|
||||
}
|
||||
|
||||
public static CredentialValidity IntToCredentialValidity(ushort iValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (CredentialValidity)iValue;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return CredentialValidity.UesrIdentityValidityUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
public static ushort CredentialValidityToInt(CredentialValidity eValue)
|
||||
{
|
||||
return (ushort)eValue;
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[ServiceContract(Namespace = "http://asb.contracts/20111111", ConfigurationName = "IAuthenticateASB")]
|
||||
public interface IAuthenticateASB
|
||||
{
|
||||
[OperationContract(Action = "http://asb.contracts/20111111:connectIn", ReplyAction = "*")]
|
||||
[XmlSerializerFormat(SupportFaults = true)]
|
||||
ConnectResponse Connect(ConnectRequest request);
|
||||
|
||||
[OperationContract(Action = "http://asb.contracts/20111111:renewIn", ReplyAction = "*")]
|
||||
[XmlSerializerFormat(SupportFaults = true)]
|
||||
RenewResponse Renew(RenewRequest request);
|
||||
|
||||
[OperationContract(IsOneWay = true, Action = "http://asb.contracts/20111111:authenticateMeIn")]
|
||||
[XmlSerializerFormat(SupportFaults = true)]
|
||||
void AuthenticateMe(AuthenticateMe request);
|
||||
|
||||
[OperationContract(IsOneWay = true, Action = "http://asb.contracts/20111111:updateSystemAuthenticationConfigurationIn")]
|
||||
[XmlSerializerFormat(SupportFaults = true)]
|
||||
void UpdateSystemAuthenticationConfiguration(UpdateSystemAuthenticationConfiguration request);
|
||||
|
||||
[OperationContract(IsOneWay = true, Action = "http://asb.contracts/20111111:disconnectIn")]
|
||||
[XmlSerializerFormat(SupportFaults = true)]
|
||||
void Disconnect(Disconnect request);
|
||||
|
||||
[OperationContract(IsOneWay = true, Action = "http://asb.contracts/20111111:keepAliveIn")]
|
||||
[XmlSerializerFormat(SupportFaults = true)]
|
||||
void KeepAlive(KeepAlive request);
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[Serializable]
|
||||
[GeneratedCode("System.Xml", "4.0.30319.233")]
|
||||
[XmlType(Namespace = "http://asb.contracts.data/20111111", IncludeInSchema = false)]
|
||||
public enum ItemChoiceType
|
||||
{
|
||||
Blob,
|
||||
Boolean,
|
||||
Byte,
|
||||
Date,
|
||||
DateTime,
|
||||
Decimal,
|
||||
Double,
|
||||
Duration,
|
||||
Float,
|
||||
Guid,
|
||||
Hex,
|
||||
Int,
|
||||
Integer,
|
||||
Long,
|
||||
Short,
|
||||
String,
|
||||
Time,
|
||||
UnsignedByte,
|
||||
UnsignedInt,
|
||||
UnsignedLong,
|
||||
UnsignedShort
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
[MessageContract(WrapperName = "KeepAliveRequest", WrapperNamespace = "http://asb.contracts.messages/20111111", IsWrapped = true)]
|
||||
public class KeepAlive : ConnectedRequest
|
||||
{
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 0)]
|
||||
public AuthenticationData ConsumerAuthenticationData;
|
||||
|
||||
public KeepAlive()
|
||||
{
|
||||
}
|
||||
|
||||
public KeepAlive(AuthenticationData ConsumerAuthenticationData)
|
||||
{
|
||||
this.ConsumerAuthenticationData = ConsumerAuthenticationData;
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public delegate ConnectResponse MakeCallToAuthenticationConnect(ConnectRequest request);
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public delegate void MakeCallToServiceDisconnect(Disconnect request);
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public delegate void MakeCalltoAuthenticateMe(AuthenticateMe request);
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[Serializable]
|
||||
[GeneratedCode("System.Xml", "4.0.30319.233")]
|
||||
[DebuggerStepThrough]
|
||||
[DesignerCategory("code")]
|
||||
[XmlType(Namespace = "http://asb.contracts.data/20111111")]
|
||||
public class NamedValue
|
||||
{
|
||||
private string nameField;
|
||||
|
||||
private ResultVariant valueField;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return nameField;
|
||||
}
|
||||
set
|
||||
{
|
||||
nameField = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ResultVariant Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return valueField;
|
||||
}
|
||||
set
|
||||
{
|
||||
valueField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[Serializable]
|
||||
[GeneratedCode("System.Xml", "4.0.30319.233")]
|
||||
[DebuggerStepThrough]
|
||||
[DesignerCategory("code")]
|
||||
[XmlType(Namespace = "http://asb.contracts.data/20111111")]
|
||||
public class PublicKey
|
||||
{
|
||||
private byte[] dataField;
|
||||
|
||||
[XmlElement(DataType = "base64Binary")]
|
||||
public byte[] Data
|
||||
{
|
||||
get
|
||||
{
|
||||
return dataField;
|
||||
}
|
||||
set
|
||||
{
|
||||
dataField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
[MessageContract(WrapperName = "RenewRequest", WrapperNamespace = "http://asb.contracts.messages/20111111", IsWrapped = true)]
|
||||
public class RenewRequest : ConnectedRequest
|
||||
{
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 0)]
|
||||
public AuthenticationData ConsumerAuthenticationData;
|
||||
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 1)]
|
||||
public Guid NewConnectionId;
|
||||
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 2)]
|
||||
public PublicKey NewConsumerPublicKey;
|
||||
|
||||
public RenewRequest()
|
||||
{
|
||||
}
|
||||
|
||||
public RenewRequest(AuthenticationData ConsumerAuthenticationData, Guid NewConnectionId, PublicKey NewConsumerPublicKey)
|
||||
{
|
||||
this.ConsumerAuthenticationData = ConsumerAuthenticationData;
|
||||
this.NewConnectionId = NewConnectionId;
|
||||
this.NewConsumerPublicKey = NewConsumerPublicKey;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceModel;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
[MessageContract(WrapperName = "RenewResponse", WrapperNamespace = "http://asb.contracts.messages/20111111", IsWrapped = true)]
|
||||
public class RenewResponse : ConnectedResponse
|
||||
{
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 0)]
|
||||
public Guid NewConnectionId;
|
||||
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 1)]
|
||||
[XmlElement(DataType = "duration")]
|
||||
public string NewConnectionLifetime;
|
||||
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 2)]
|
||||
public PublicKey NewServicePublicKey;
|
||||
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 3)]
|
||||
public AuthenticationData NewServiceAuthenticationData;
|
||||
|
||||
public RenewResponse()
|
||||
{
|
||||
}
|
||||
|
||||
public RenewResponse(Guid NewConnectionId, string NewConnectionLifetime, PublicKey NewServicePublicKey, AuthenticationData NewServiceAuthenticationData)
|
||||
{
|
||||
this.NewConnectionId = NewConnectionId;
|
||||
this.NewConnectionLifetime = NewConnectionLifetime;
|
||||
this.NewServicePublicKey = NewServicePublicKey;
|
||||
this.NewServiceAuthenticationData = NewServiceAuthenticationData;
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
using ArchestrAServices.Contract;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public static class ResultFactory
|
||||
{
|
||||
public static ArchestrAResult MakeGoodResult()
|
||||
{
|
||||
return new ArchestrAResult
|
||||
{
|
||||
ErrorCode = EnumASBFactory.ArchestrAErrorToInt(ArchestrAError.Success),
|
||||
Status = 0u,
|
||||
SpecificErrorCode = 0u,
|
||||
Success = true
|
||||
};
|
||||
}
|
||||
|
||||
public static ArchestrAResult MakeResult(ArchestrAError error, ushort status)
|
||||
{
|
||||
return new ArchestrAResult
|
||||
{
|
||||
ErrorCode = EnumASBFactory.ArchestrAErrorToInt(error),
|
||||
Status = status,
|
||||
Success = (error == ArchestrAError.Success)
|
||||
};
|
||||
}
|
||||
|
||||
public static ArchestrAResult MakeResult(ArchestrAError error, ushort status, uint specificError)
|
||||
{
|
||||
return new ArchestrAResult
|
||||
{
|
||||
ResultCode = EnumASBFactory.ArchestrAErrorToInt(error),
|
||||
Status = status,
|
||||
SpecificErrorCode = specificError,
|
||||
Success = (error == ArchestrAError.Success)
|
||||
};
|
||||
}
|
||||
|
||||
public static void AddExtension(this ArchestrAResult Result, string Name, object Value, ItemChoiceType ValueType)
|
||||
{
|
||||
NamedValue[] array = null;
|
||||
array = ((Result.Extensions != null) ? Result.Extensions : new NamedValue[0]);
|
||||
Result.Extensions = new NamedValue[array.Length + 1];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
Result.Extensions[i] = array[i];
|
||||
}
|
||||
NamedValue namedValue = new NamedValue();
|
||||
namedValue.Name = Name;
|
||||
namedValue.Value = new ResultVariant();
|
||||
namedValue.Value.Item = Value;
|
||||
namedValue.Value.ItemElementName = ValueType;
|
||||
Result.Extensions[Result.Extensions.Length - 1] = namedValue;
|
||||
}
|
||||
|
||||
public static ArchestrAResult MakeResult(int Error)
|
||||
{
|
||||
return new ArchestrAResult
|
||||
{
|
||||
ResultCode = Error,
|
||||
Success = (Error == 0)
|
||||
};
|
||||
}
|
||||
|
||||
public static ArchestrAResult MakeResult(int Error, string Location)
|
||||
{
|
||||
return new ArchestrAResult
|
||||
{
|
||||
Location = Location,
|
||||
ResultCode = Error,
|
||||
Success = (Error == 0)
|
||||
};
|
||||
}
|
||||
|
||||
public static ArchestrAResult MakeResult(ArchestrAServices.Contract.ArchestrAResult result)
|
||||
{
|
||||
ArchestrAResult result2 = default(ArchestrAResult);
|
||||
result2.ResultCode = result.ErrorCode;
|
||||
result2.Status = result.Status;
|
||||
result2.SpecificErrorCode = result.SpecificErrorCode;
|
||||
result2.Success = result2.ResultCode == 0;
|
||||
return result2;
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[Serializable]
|
||||
[GeneratedCode("System.Xml", "4.0.30319.233")]
|
||||
[DebuggerStepThrough]
|
||||
[DesignerCategory("code")]
|
||||
[XmlType(Namespace = "http://asb.contracts.data/20111111")]
|
||||
public class ResultVariant
|
||||
{
|
||||
private object itemField;
|
||||
|
||||
private ItemChoiceType itemElementNameField;
|
||||
|
||||
[XmlElement("Blob", typeof(byte[]), DataType = "base64Binary")]
|
||||
[XmlElement("Boolean", typeof(bool))]
|
||||
[XmlElement("Byte", typeof(sbyte))]
|
||||
[XmlElement("Date", typeof(DateTime), DataType = "date")]
|
||||
[XmlElement("DateTime", typeof(DateTime))]
|
||||
[XmlElement("Decimal", typeof(decimal))]
|
||||
[XmlElement("Double", typeof(double))]
|
||||
[XmlElement("Duration", typeof(string), DataType = "duration")]
|
||||
[XmlElement("Float", typeof(float))]
|
||||
[XmlElement("Guid", typeof(Guid))]
|
||||
[XmlElement("Hex", typeof(byte[]), DataType = "hexBinary")]
|
||||
[XmlElement("Int", typeof(int))]
|
||||
[XmlElement("Integer", typeof(string), DataType = "integer")]
|
||||
[XmlElement("Long", typeof(long))]
|
||||
[XmlElement("Short", typeof(short))]
|
||||
[XmlElement("String", typeof(string))]
|
||||
[XmlElement("Time", typeof(DateTime), DataType = "time")]
|
||||
[XmlElement("UnsignedByte", typeof(byte))]
|
||||
[XmlElement("UnsignedInt", typeof(uint))]
|
||||
[XmlElement("UnsignedLong", typeof(ulong))]
|
||||
[XmlElement("UnsignedShort", typeof(ushort))]
|
||||
[XmlChoiceIdentifier("ItemElementName")]
|
||||
public object Item
|
||||
{
|
||||
get
|
||||
{
|
||||
return itemField;
|
||||
}
|
||||
set
|
||||
{
|
||||
itemField = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public ItemChoiceType ItemElementName
|
||||
{
|
||||
get
|
||||
{
|
||||
return itemElementNameField;
|
||||
}
|
||||
set
|
||||
{
|
||||
itemElementNameField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public static class SerializationExtensions
|
||||
{
|
||||
private static readonly Dictionary<Type, XmlSerializer> xmlSerializers = new Dictionary<Type, XmlSerializer>();
|
||||
|
||||
private static readonly object serializersLock = new object();
|
||||
|
||||
public static XmlSerializer GetTypeSerializer(Type objectType)
|
||||
{
|
||||
if (objectType == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
XmlSerializer xmlSerializer;
|
||||
lock (serializersLock)
|
||||
{
|
||||
if (!xmlSerializers.ContainsKey(objectType))
|
||||
{
|
||||
string defaultNamespace = "urn:invensys.schemas";
|
||||
object[] customAttributes = objectType.GetCustomAttributes(inherit: true);
|
||||
if (customAttributes.Length != 0)
|
||||
{
|
||||
object[] array = customAttributes;
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
if (array[i] is XmlRootAttribute xmlRootAttribute)
|
||||
{
|
||||
defaultNamespace = xmlRootAttribute.Namespace;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlSerializer = new XmlSerializer(objectType, defaultNamespace);
|
||||
xmlSerializers.Add(objectType, xmlSerializer);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlSerializer = xmlSerializers[objectType];
|
||||
}
|
||||
}
|
||||
return xmlSerializer;
|
||||
}
|
||||
|
||||
public static string ToXml(this object value)
|
||||
{
|
||||
string text = string.Empty;
|
||||
if (value != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using TextWriter textWriter = new StringWriter(CultureInfo.CurrentCulture);
|
||||
lock (serializersLock)
|
||||
{
|
||||
XmlSerializer typeSerializer = GetTypeSerializer(value.GetType());
|
||||
if (typeSerializer != null)
|
||||
{
|
||||
typeSerializer.Serialize(textWriter, value);
|
||||
text = textWriter.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
if (Environment.Is64BitProcess)
|
||||
{
|
||||
using TextReader textReader = new StringReader(text);
|
||||
using IEnumerator<XElement> enumerator = XDocument.Load(textReader).Elements().GetEnumerator();
|
||||
if (enumerator.MoveNext())
|
||||
{
|
||||
XElement current = enumerator.Current;
|
||||
XAttribute xAttribute = current.Attribute(XNamespace.Xmlns + "xsd");
|
||||
XAttribute xAttribute2 = current.Attribute(XNamespace.Xmlns + "xsi");
|
||||
if (xAttribute != null && xAttribute2 != null)
|
||||
{
|
||||
current.ReplaceAttributes(xAttribute2, xAttribute);
|
||||
}
|
||||
using TextWriter textWriter2 = new StringWriter(CultureInfo.CurrentCulture);
|
||||
current.Save(textWriter2);
|
||||
text = textWriter2.ToString();
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceModel;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
[MessageContract]
|
||||
public class ServiceMessage
|
||||
{
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public enum SigningMethod
|
||||
{
|
||||
Baktun,
|
||||
Apollo
|
||||
}
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
+701
@@ -0,0 +1,701 @@
|
||||
#define TRACE
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Numerics;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using ArchestrAServices.Common;
|
||||
using Invensys.Compression;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public class SysAuthConnectionBase
|
||||
{
|
||||
private static RandomNumberGenerator mRANDOM = RandomNumberGenerator.Create();
|
||||
|
||||
private static readonly byte[] PASSWORDSALT = Encoding.ASCII.GetBytes("ArchestrAService");
|
||||
|
||||
protected static string ASBAuthenticationVersion = "V2";
|
||||
|
||||
protected static readonly object MessageNumberLock = new object();
|
||||
|
||||
protected SysAuthParameters m_SolutionParameters;
|
||||
|
||||
public Guid connectionID = Guid.Empty;
|
||||
|
||||
protected byte[] m_PrivateKey;
|
||||
|
||||
protected byte[] m_LocalPublicKey;
|
||||
|
||||
protected byte[] m_RemotePublicKey;
|
||||
|
||||
protected bool m_Authenticated;
|
||||
|
||||
protected ulong m_NextMessageNumber = 1uL;
|
||||
|
||||
private ulong m_HighestMessageNumberReceived;
|
||||
|
||||
private List<ulong> m_OutOfSyncMessageNumbers = new List<ulong>();
|
||||
|
||||
private byte[] SolutionPassphrase
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] result = null;
|
||||
if (m_SolutionParameters.ASBSolutionValid)
|
||||
{
|
||||
if (m_SolutionParameters.DH_passphrase != null && m_SolutionParameters.DH_passphrase.Length > 0)
|
||||
{
|
||||
result = Encoding.UTF8.GetBytes(m_SolutionParameters.DH_passphrase);
|
||||
}
|
||||
if (m_SolutionParameters.DH_certificate != null && m_SolutionParameters.DH_certificate.Length != 0)
|
||||
{
|
||||
result = new X509Certificate(m_SolutionParameters.DH_certificate).GetPublicKey();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] CryptoKey
|
||||
{
|
||||
get
|
||||
{
|
||||
List<byte> list = new List<byte>();
|
||||
list.AddRange(CalculateConnectionKey(m_RemotePublicKey, m_PrivateKey));
|
||||
byte[] solutionPassphrase = SolutionPassphrase;
|
||||
if (solutionPassphrase != null)
|
||||
{
|
||||
list.AddRange(solutionPassphrase);
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public ConnectionValidator m_ConnectionValidator { get; protected set; }
|
||||
|
||||
public bool SecureSessionEstablished
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Authenticated;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
m_Authenticated = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string ReasonSecureSessionNotEstablished { get; protected set; }
|
||||
|
||||
public string DH_passphrase
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SolutionParameters.DH_passphrase;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_SolutionParameters.DH_passphrase = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string DH_hashAlgorithm => m_SolutionParameters.hashAlgorithm;
|
||||
|
||||
public string DH_asbSolutionName => m_SolutionParameters.ASBSolutionName;
|
||||
|
||||
public SigningMethod SignatureMethod { get; set; }
|
||||
|
||||
public SysAuthConnectionBase(string asbSolutionName = null)
|
||||
{
|
||||
m_SolutionParameters = new SysAuthParameters(asbSolutionName);
|
||||
ReasonSecureSessionNotEstablished = "Constructed";
|
||||
Reset();
|
||||
}
|
||||
|
||||
protected void Reset()
|
||||
{
|
||||
SecureSessionEstablished = false;
|
||||
ReasonSecureSessionNotEstablished = "Reset";
|
||||
SignatureMethod = SigningMethod.Baktun;
|
||||
connectionID = Guid.NewGuid();
|
||||
m_PrivateKey = GetPrivateKey(m_SolutionParameters.KeySize);
|
||||
m_LocalPublicKey = CalculatePublicKey(m_PrivateKey);
|
||||
m_Authenticated = false;
|
||||
}
|
||||
|
||||
private byte[] GetPrivateKey(int length)
|
||||
{
|
||||
byte[] array = null;
|
||||
if (length > 0)
|
||||
{
|
||||
BigInteger bigInteger = m_SolutionParameters.DH_p - new BigInteger(1);
|
||||
BigInteger bigInteger2 = new BigInteger(0);
|
||||
while (bigInteger2 >= bigInteger || bigInteger2 <= 0L)
|
||||
{
|
||||
array = new byte[length / 8];
|
||||
mRANDOM.GetBytes(array);
|
||||
bigInteger2 = new BigInteger(array);
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
protected byte[] CalculatePublicKey(byte[] privateKey)
|
||||
{
|
||||
BigInteger exponent = new BigInteger(privateKey);
|
||||
BigInteger dH_g = m_SolutionParameters.DH_g;
|
||||
BigInteger dH_p = m_SolutionParameters.DH_p;
|
||||
return BigInteger.ModPow(dH_g, exponent, dH_p).ToByteArray();
|
||||
}
|
||||
|
||||
protected byte[] CalculateConnectionKey(byte[] remotePublicKey, byte[] localPrivateKey)
|
||||
{
|
||||
BigInteger value = new BigInteger(remotePublicKey);
|
||||
BigInteger exponent = new BigInteger(localPrivateKey);
|
||||
BigInteger dH_p = m_SolutionParameters.DH_p;
|
||||
return BigInteger.ModPow(value, exponent, dH_p).ToByteArray();
|
||||
}
|
||||
|
||||
private HMAC NewSolutionHmac(bool ForceHMAC = false)
|
||||
{
|
||||
HMAC result;
|
||||
switch (DH_hashAlgorithm.ToLower())
|
||||
{
|
||||
case "md5":
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, "Solution HMAC is MD5");
|
||||
result = new HMACMD5(CryptoKey);
|
||||
break;
|
||||
case "sha1":
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, "Solution HMAC is SHA1");
|
||||
result = new HMACSHA1(CryptoKey);
|
||||
break;
|
||||
case "sha512":
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, "Solution HMAC is SHA512");
|
||||
result = new HMACSHA512(CryptoKey);
|
||||
break;
|
||||
default:
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, "Solution HMAC is NONE");
|
||||
result = null;
|
||||
if (ForceHMAC)
|
||||
{
|
||||
result = new HMACSHA1(CryptoKey);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool ValidRequest(ConnectedRequest request, bool ForceHmac = false)
|
||||
{
|
||||
bool flag = false;
|
||||
if (request != null && request.ConnectionValidator != null)
|
||||
{
|
||||
ConnectionValidator connectionValidator = request.ConnectionValidator;
|
||||
byte[] messageAuthenticationCode = connectionValidator.MessageAuthenticationCode;
|
||||
byte[] signatureInitializationVector = connectionValidator.SignatureInitializationVector;
|
||||
byte[] array = null;
|
||||
using (HMAC hMAC = NewSolutionHmac(ForceHmac))
|
||||
{
|
||||
if (hMAC != null)
|
||||
{
|
||||
connectionValidator.MessageAuthenticationCode = new byte[0];
|
||||
connectionValidator.SignatureInitializationVector = new byte[0];
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(request.ToXml());
|
||||
connectionValidator.MessageAuthenticationCode = messageAuthenticationCode;
|
||||
connectionValidator.SignatureInitializationVector = signatureInitializationVector;
|
||||
if (SignatureMethod == SigningMethod.Baktun)
|
||||
{
|
||||
array = EncypherBaktun(hMAC.ComputeHash(bytes), signatureInitializationVector);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] array2 = hMAC.ComputeHash(bytes);
|
||||
byte[] array3 = DecypherApollo(messageAuthenticationCode, signatureInitializationVector);
|
||||
bool flag2 = false;
|
||||
if (array2 != null && array3 != null && array2.Length == array3.Length)
|
||||
{
|
||||
flag2 = true;
|
||||
for (int i = 0; i < array2.Length; i++)
|
||||
{
|
||||
if (array2[i] != array3[i])
|
||||
{
|
||||
flag2 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
array = ((!flag2) ? new byte[0] : messageAuthenticationCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (array != null)
|
||||
{
|
||||
if (messageAuthenticationCode != null && array.Length == messageAuthenticationCode.Length)
|
||||
{
|
||||
flag = true;
|
||||
for (int j = 0; j < messageAuthenticationCode.Length; j++)
|
||||
{
|
||||
if (messageAuthenticationCode[j] != array[j])
|
||||
{
|
||||
if (string.IsNullOrEmpty(ReasonSecureSessionNotEstablished))
|
||||
{
|
||||
ReasonSecureSessionNotEstablished = string.Format(CultureInfo.CurrentCulture, "ValidRequest: Received message hmac correct length {0} but differs at byte {1}, cannot validate", new object[2] { messageAuthenticationCode.Length, j });
|
||||
}
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (messageAuthenticationCode == null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ReasonSecureSessionNotEstablished))
|
||||
{
|
||||
ReasonSecureSessionNotEstablished = "ValidRequest: Received message has null hmac, cannot validate";
|
||||
}
|
||||
}
|
||||
else if (string.IsNullOrEmpty(ReasonSecureSessionNotEstablished))
|
||||
{
|
||||
ReasonSecureSessionNotEstablished = string.Format(CultureInfo.CurrentCulture, "ValidRequest: Received message hmac wrong length, cannot validate (received {0}, computed {1})", new object[2] { messageAuthenticationCode.Length, array.Length });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (connectionValidator.MessageNumber <= m_HighestMessageNumberReceived)
|
||||
{
|
||||
ReasonSecureSessionNotEstablished = string.Format(CultureInfo.CurrentCulture, "ValidRequest: Received message out of sequence, cannot validate (current {0}, highest {1})", new object[2] { connectionValidator.MessageNumber, m_HighestMessageNumberReceived });
|
||||
flag = false;
|
||||
}
|
||||
else if (m_OutOfSyncMessageNumbers.Contains(connectionValidator.MessageNumber))
|
||||
{
|
||||
ReasonSecureSessionNotEstablished = string.Format(CultureInfo.CurrentCulture, "ValidRequest: Received message received late, cannot validate (current {0})", new object[1] { connectionValidator.MessageNumber });
|
||||
flag = false;
|
||||
}
|
||||
else if (connectionValidator.MessageNumber == m_HighestMessageNumberReceived + 1)
|
||||
{
|
||||
m_HighestMessageNumberReceived = connectionValidator.MessageNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_OutOfSyncMessageNumbers.Add(connectionValidator.MessageNumber);
|
||||
}
|
||||
m_OutOfSyncMessageNumbers.Sort();
|
||||
foreach (ulong outOfSyncMessageNumber in m_OutOfSyncMessageNumbers)
|
||||
{
|
||||
if (outOfSyncMessageNumber == m_HighestMessageNumberReceived + 1)
|
||||
{
|
||||
m_HighestMessageNumberReceived = outOfSyncMessageNumber;
|
||||
}
|
||||
}
|
||||
List<ulong> list = new List<ulong>();
|
||||
foreach (ulong outOfSyncMessageNumber2 in m_OutOfSyncMessageNumbers)
|
||||
{
|
||||
if (outOfSyncMessageNumber2 <= m_HighestMessageNumberReceived)
|
||||
{
|
||||
list.Add(outOfSyncMessageNumber2);
|
||||
}
|
||||
}
|
||||
foreach (ulong item in list)
|
||||
{
|
||||
m_OutOfSyncMessageNumbers.Remove(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ReasonSecureSessionNotEstablished = "ValidRequest: Either the message or its ConnectionValidator field is null, cannot validate";
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
public bool ValidResponse(ConnectedResponse response, bool ForceHmac = false)
|
||||
{
|
||||
if (response != null && response.Result.Success)
|
||||
{
|
||||
return ValidRequest(response, ForceHmac);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected byte[] ReCalculateAuthenticationData(byte[] leftPart, byte[] rightPart, byte[] initializationVector)
|
||||
{
|
||||
List<byte> list = new List<byte>();
|
||||
if (leftPart != null)
|
||||
{
|
||||
list.AddRange(leftPart);
|
||||
}
|
||||
if (rightPart != null)
|
||||
{
|
||||
list.AddRange(rightPart);
|
||||
}
|
||||
return ReEncypher(list.ToArray(), initializationVector);
|
||||
}
|
||||
|
||||
protected byte[] CalculateAuthenticationData(byte[] leftPart, byte[] rightPart, out byte[] initializationVector)
|
||||
{
|
||||
List<byte> list = new List<byte>();
|
||||
initializationVector = null;
|
||||
if (leftPart != null)
|
||||
{
|
||||
list.AddRange(leftPart);
|
||||
}
|
||||
if (rightPart != null)
|
||||
{
|
||||
list.AddRange(rightPart);
|
||||
}
|
||||
return Encypher(list.ToArray(), out initializationVector);
|
||||
}
|
||||
|
||||
public ConnectionValidator MakeConnectionValidator()
|
||||
{
|
||||
lock (MessageNumberLock)
|
||||
{
|
||||
return new ConnectionValidator
|
||||
{
|
||||
ConnectionId = connectionID,
|
||||
MessageNumber = m_NextMessageNumber++,
|
||||
MessageAuthenticationCode = new byte[0],
|
||||
SignatureInitializationVector = new byte[0]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void Sign(ConnectedRequest request, bool ForceHmac = false)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lock (MessageNumberLock)
|
||||
{
|
||||
ConnectionValidator connectionValidator = new ConnectionValidator();
|
||||
connectionValidator.ConnectionId = connectionID;
|
||||
connectionValidator.MessageNumber = m_NextMessageNumber++;
|
||||
connectionValidator.MessageAuthenticationCode = new byte[0];
|
||||
connectionValidator.SignatureInitializationVector = new byte[0];
|
||||
request.ConnectionValidator = connectionValidator;
|
||||
using HMAC hMAC = NewSolutionHmac(ForceHmac);
|
||||
if (hMAC != null)
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(request.ToXml());
|
||||
connectionValidator.MessageAuthenticationCode = Encypher(hMAC.ComputeHash(bytes), out var initializationVector);
|
||||
connectionValidator.SignatureInitializationVector = initializationVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] EncypherBaktun(byte[] clearData, byte[] initializationVector)
|
||||
{
|
||||
byte[] result = null;
|
||||
if (clearData != null)
|
||||
{
|
||||
using AesManaged aesManaged = new AesManaged();
|
||||
using Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(CryptoKey.ToBase64(), PASSWORDSALT);
|
||||
aesManaged.Key = rfc2898DeriveBytes.GetBytes(16);
|
||||
aesManaged.IV = initializationVector;
|
||||
using ICryptoTransform transform = aesManaged.CreateEncryptor();
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
using (CryptoStream stream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
|
||||
{
|
||||
using AADeflateStream aADeflateStream = new AADeflateStream(stream, CompressionMode.Compress);
|
||||
aADeflateStream.Write(clearData, 0, clearData.Length);
|
||||
aADeflateStream.Close();
|
||||
}
|
||||
result = memoryStream.ToArray();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] EncypherBaktun(byte[] clearData, out byte[] initializationVector)
|
||||
{
|
||||
byte[] result = null;
|
||||
initializationVector = null;
|
||||
if (clearData != null)
|
||||
{
|
||||
using AesManaged aesManaged = new AesManaged();
|
||||
using Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(CryptoKey.ToBase64(), PASSWORDSALT);
|
||||
aesManaged.Key = rfc2898DeriveBytes.GetBytes(16);
|
||||
initializationVector = aesManaged.IV;
|
||||
using ICryptoTransform transform = aesManaged.CreateEncryptor();
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
using (CryptoStream stream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
|
||||
{
|
||||
using AADeflateStream aADeflateStream = new AADeflateStream(stream, CompressionMode.Compress);
|
||||
aADeflateStream.Write(clearData, 0, clearData.Length);
|
||||
aADeflateStream.Close();
|
||||
}
|
||||
result = memoryStream.ToArray();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public string EncypherBaktun(string clearText, out byte[] initializationVector)
|
||||
{
|
||||
string result = string.Empty;
|
||||
initializationVector = null;
|
||||
if (!string.IsNullOrEmpty(clearText))
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(clearText);
|
||||
result = EncypherBaktun(bytes, out initializationVector).ToBase64();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] ReEncypherBaktun(byte[] clearData, byte[] initializationVector)
|
||||
{
|
||||
byte[] result = null;
|
||||
if (clearData != null)
|
||||
{
|
||||
using AesManaged aesManaged = new AesManaged();
|
||||
using Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(CryptoKey.ToBase64(), PASSWORDSALT);
|
||||
aesManaged.Key = rfc2898DeriveBytes.GetBytes(16);
|
||||
aesManaged.IV = initializationVector;
|
||||
using ICryptoTransform transform = aesManaged.CreateEncryptor();
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
using (CryptoStream stream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
|
||||
{
|
||||
using AADeflateStream aADeflateStream = new AADeflateStream(stream, CompressionMode.Compress);
|
||||
aADeflateStream.Write(clearData, 0, clearData.Length);
|
||||
aADeflateStream.Close();
|
||||
}
|
||||
result = memoryStream.ToArray();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public string ReEncypherBaktun(string clearText, byte[] initializationVector)
|
||||
{
|
||||
string result = string.Empty;
|
||||
if (!string.IsNullOrEmpty(clearText))
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(clearText);
|
||||
result = ReEncypherBaktun(bytes, initializationVector).ToBase64();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] DecypherBaktun(byte[] cypherData, byte[] initializationVector)
|
||||
{
|
||||
byte[] result = null;
|
||||
if (cypherData != null)
|
||||
{
|
||||
using AesManaged aesManaged = new AesManaged();
|
||||
using Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(CryptoKey.ToBase64(), PASSWORDSALT);
|
||||
aesManaged.Key = rfc2898DeriveBytes.GetBytes(16);
|
||||
aesManaged.IV = initializationVector;
|
||||
using ICryptoTransform transform = aesManaged.CreateDecryptor();
|
||||
using MemoryStream stream = new MemoryStream(cypherData);
|
||||
using CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Read);
|
||||
using AADeflateStream aADeflateStream = new AADeflateStream(stream2, CompressionMode.Decompress);
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
aADeflateStream.CopyTo(memoryStream);
|
||||
result = memoryStream.ToArray();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public string DecypherBaktun(string cypherText, byte[] initializationVector)
|
||||
{
|
||||
string result = string.Empty;
|
||||
if (!string.IsNullOrEmpty(cypherText))
|
||||
{
|
||||
byte[] cypherData = cypherText.FromBase64ToByteArray();
|
||||
byte[] bytes = DecypherBaktun(cypherData, initializationVector);
|
||||
result = Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] EncypherApollo(byte[] clearData, byte[] initializationVector)
|
||||
{
|
||||
byte[] result = null;
|
||||
if (clearData != null)
|
||||
{
|
||||
using AesManaged aesManaged = new AesManaged();
|
||||
using Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(CryptoKey.ToBase64(), PASSWORDSALT);
|
||||
aesManaged.Key = rfc2898DeriveBytes.GetBytes(16);
|
||||
aesManaged.IV = initializationVector;
|
||||
using ICryptoTransform transform = aesManaged.CreateEncryptor();
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
|
||||
{
|
||||
cryptoStream.Write(clearData, 0, clearData.Length);
|
||||
cryptoStream.Close();
|
||||
}
|
||||
result = memoryStream.ToArray();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] EncypherApollo(byte[] clearData, out byte[] initializationVector)
|
||||
{
|
||||
byte[] result = null;
|
||||
initializationVector = null;
|
||||
if (clearData != null)
|
||||
{
|
||||
using AesManaged aesManaged = new AesManaged();
|
||||
using Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(CryptoKey.ToBase64(), PASSWORDSALT);
|
||||
aesManaged.Key = rfc2898DeriveBytes.GetBytes(16);
|
||||
initializationVector = aesManaged.IV;
|
||||
using ICryptoTransform transform = aesManaged.CreateEncryptor();
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
|
||||
{
|
||||
cryptoStream.Write(clearData, 0, clearData.Length);
|
||||
cryptoStream.Close();
|
||||
}
|
||||
result = memoryStream.ToArray();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public string EncypherApollo(string clearText, out byte[] initializationVector)
|
||||
{
|
||||
string result = string.Empty;
|
||||
initializationVector = null;
|
||||
if (!string.IsNullOrEmpty(clearText))
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(clearText);
|
||||
result = EncypherApollo(bytes, out initializationVector).ToBase64();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] ReEncypherApollo(byte[] clearData, byte[] initializationVector)
|
||||
{
|
||||
byte[] result = null;
|
||||
if (clearData != null)
|
||||
{
|
||||
using AesManaged aesManaged = new AesManaged();
|
||||
using Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(CryptoKey.ToBase64(), PASSWORDSALT);
|
||||
aesManaged.Key = rfc2898DeriveBytes.GetBytes(16);
|
||||
aesManaged.IV = initializationVector;
|
||||
using ICryptoTransform transform = aesManaged.CreateEncryptor();
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
|
||||
{
|
||||
cryptoStream.Write(clearData, 0, clearData.Length);
|
||||
cryptoStream.Close();
|
||||
}
|
||||
result = memoryStream.ToArray();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public string ReEncypherApollo(string clearText, byte[] initializationVector)
|
||||
{
|
||||
string result = string.Empty;
|
||||
if (!string.IsNullOrEmpty(clearText))
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(clearText);
|
||||
result = ReEncypherApollo(bytes, initializationVector).ToBase64();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] DecypherApollo(byte[] cypherData, byte[] initializationVector)
|
||||
{
|
||||
byte[] result = null;
|
||||
if (cypherData != null)
|
||||
{
|
||||
using AesManaged aesManaged = new AesManaged();
|
||||
using Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(CryptoKey.ToBase64(), PASSWORDSALT);
|
||||
aesManaged.Key = rfc2898DeriveBytes.GetBytes(16);
|
||||
aesManaged.IV = initializationVector;
|
||||
using ICryptoTransform transform = aesManaged.CreateDecryptor();
|
||||
using MemoryStream stream = new MemoryStream(cypherData);
|
||||
using CryptoStream cryptoStream = new CryptoStream(stream, transform, CryptoStreamMode.Read);
|
||||
using MemoryStream memoryStream = new MemoryStream();
|
||||
cryptoStream.CopyTo(memoryStream);
|
||||
result = memoryStream.ToArray();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public string DecypherApollo(string cypherText, byte[] initializationVector)
|
||||
{
|
||||
string result = string.Empty;
|
||||
if (!string.IsNullOrEmpty(cypherText))
|
||||
{
|
||||
byte[] cypherData = cypherText.FromBase64ToByteArray();
|
||||
byte[] bytes = DecypherApollo(cypherData, initializationVector);
|
||||
result = Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] Encypher(byte[] clearData, byte[] initializationVector)
|
||||
{
|
||||
if (SignatureMethod == SigningMethod.Baktun)
|
||||
{
|
||||
return EncypherBaktun(clearData, initializationVector);
|
||||
}
|
||||
return EncypherApollo(clearData, initializationVector);
|
||||
}
|
||||
|
||||
public byte[] Encypher(byte[] clearData, out byte[] initializationVector)
|
||||
{
|
||||
if (SignatureMethod == SigningMethod.Baktun)
|
||||
{
|
||||
return EncypherBaktun(clearData, out initializationVector);
|
||||
}
|
||||
return EncypherApollo(clearData, out initializationVector);
|
||||
}
|
||||
|
||||
public string Encypher(string clearText, out byte[] initializationVector)
|
||||
{
|
||||
if (SignatureMethod == SigningMethod.Baktun)
|
||||
{
|
||||
return EncypherBaktun(clearText, out initializationVector);
|
||||
}
|
||||
return EncypherApollo(clearText, out initializationVector);
|
||||
}
|
||||
|
||||
public byte[] ReEncypher(byte[] clearData, byte[] initializationVector)
|
||||
{
|
||||
if (SignatureMethod == SigningMethod.Baktun)
|
||||
{
|
||||
return ReEncypherBaktun(clearData, initializationVector);
|
||||
}
|
||||
return ReEncypherApollo(clearData, initializationVector);
|
||||
}
|
||||
|
||||
public string ReEncypher(string clearText, byte[] initializationVector)
|
||||
{
|
||||
if (SignatureMethod == SigningMethod.Baktun)
|
||||
{
|
||||
return ReEncypherBaktun(clearText, initializationVector);
|
||||
}
|
||||
return ReEncypherApollo(clearText, initializationVector);
|
||||
}
|
||||
|
||||
public byte[] Decypher(byte[] cypherData, byte[] initializationVector)
|
||||
{
|
||||
if (SignatureMethod == SigningMethod.Baktun)
|
||||
{
|
||||
return DecypherBaktun(cypherData, initializationVector);
|
||||
}
|
||||
return DecypherApollo(cypherData, initializationVector);
|
||||
}
|
||||
|
||||
public string Decypher(string cypherText, byte[] initializationVector)
|
||||
{
|
||||
if (SignatureMethod == SigningMethod.Baktun)
|
||||
{
|
||||
return DecypherBaktun(cypherText, initializationVector);
|
||||
}
|
||||
return DecypherApollo(cypherText, initializationVector);
|
||||
}
|
||||
}
|
||||
+249
@@ -0,0 +1,249 @@
|
||||
#define TRACE
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using ArchestrAServices.Common;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public class SysAuthParameters
|
||||
{
|
||||
public string ASBSolutionName;
|
||||
|
||||
public bool ASBSolutionValid;
|
||||
|
||||
public int DH_KeySize;
|
||||
|
||||
public int DH_SecretSize;
|
||||
|
||||
public BigInteger DH_p;
|
||||
|
||||
public BigInteger DH_g;
|
||||
|
||||
private string m_SysAuthPassphrase;
|
||||
|
||||
private byte[] m_SysAuthCertificate;
|
||||
|
||||
public uint ConnectionLifetime;
|
||||
|
||||
public string SaltValue;
|
||||
|
||||
public string hashAlgorithm;
|
||||
|
||||
public int PasswordIterations;
|
||||
|
||||
public string InitialVector;
|
||||
|
||||
public int KeySize;
|
||||
|
||||
private static string RegKeyRelativePath = string.Empty;
|
||||
|
||||
public static int DH_KeySize_Dft = 1024;
|
||||
|
||||
public static int DH_SecretSize_Dft = 160;
|
||||
|
||||
public static string DH_passphrase_Dft = Environment.MachineName;
|
||||
|
||||
public static uint ConnectionLifetime_Dft = 60000u;
|
||||
|
||||
public static string SaltValue_Dft = "s@1tValue";
|
||||
|
||||
public static string hashAlgorithm_Dft = CngAlgorithm.MD5.ToString();
|
||||
|
||||
public static int PasswordIterations_Dft = 1;
|
||||
|
||||
public static string InitialVector_Dft = "ba172e9941be138b";
|
||||
|
||||
public static int KeySize_Dft = 256;
|
||||
|
||||
private static string s_DECIMAL768 = "1552518092300708935130918131258481755631334049434514313202351194902966239949102107258669453876591642442910007680288864229150803718918046342632727613031282983744380820890196288509170691316593175367469551763119843371637221007210577919";
|
||||
|
||||
private static byte[] s_OAKLEY768 = new byte[96]
|
||||
{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 201, 15,
|
||||
218, 162, 33, 104, 194, 52, 196, 198, 98, 139,
|
||||
128, 220, 28, 209, 41, 2, 78, 8, 138, 103,
|
||||
204, 116, 2, 11, 190, 166, 59, 19, 155, 34,
|
||||
81, 74, 8, 121, 142, 52, 4, 221, 239, 149,
|
||||
25, 179, 205, 58, 67, 27, 48, 43, 10, 109,
|
||||
242, 95, 20, 55, 79, 225, 53, 109, 109, 81,
|
||||
194, 69, 228, 133, 181, 118, 98, 94, 126, 198,
|
||||
244, 76, 66, 233, 166, 58, 54, 32, 255, 255,
|
||||
255, 255, 255, 255, 255, 255
|
||||
};
|
||||
|
||||
private static string s_DECIMAL1024 = "179769313486231590770839156793787453197860296048756011706444423684197180216158519368947833795864925541502180565485980503646440548199239100050792877003355816639229553136239076508735759914822574862575007425302077447712589550957937778424442426617334727629299387668709205606050270810842907692932019128194";
|
||||
|
||||
private static byte[] s_OAKLEY1024 = new byte[128]
|
||||
{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 201, 15,
|
||||
218, 162, 33, 104, 194, 52, 196, 198, 98, 139,
|
||||
128, 220, 28, 209, 41, 2, 78, 8, 138, 103,
|
||||
204, 116, 2, 11, 190, 166, 59, 19, 155, 34,
|
||||
81, 74, 8, 121, 142, 52, 4, 221, 239, 149,
|
||||
25, 179, 205, 58, 67, 27, 48, 43, 10, 109,
|
||||
242, 95, 20, 55, 79, 225, 53, 109, 109, 81,
|
||||
194, 69, 228, 133, 181, 118, 98, 94, 126, 198,
|
||||
244, 76, 66, 233, 166, 55, 237, 107, 11, 255,
|
||||
92, 182, 244, 6, 183, 237, 238, 56, 107, 251,
|
||||
90, 137, 159, 165, 174, 159, 36, 17, 124, 75,
|
||||
31, 230, 73, 40, 102, 81, 236, 230, 83, 129,
|
||||
255, 255, 255, 255, 255, 255, 255, 255
|
||||
};
|
||||
|
||||
private static string s_DECIMAL1536 = "2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919";
|
||||
|
||||
private static byte[] s_OAKLEY1536 = new byte[192]
|
||||
{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 201, 15,
|
||||
218, 162, 33, 104, 194, 52, 196, 198, 98, 139,
|
||||
128, 220, 28, 209, 41, 2, 78, 8, 138, 103,
|
||||
204, 116, 2, 11, 190, 166, 59, 19, 155, 34,
|
||||
81, 74, 8, 121, 142, 52, 4, 221, 239, 149,
|
||||
25, 179, 205, 58, 67, 27, 48, 43, 10, 109,
|
||||
242, 95, 20, 55, 79, 225, 53, 109, 109, 81,
|
||||
194, 69, 228, 133, 181, 118, 98, 94, 126, 198,
|
||||
244, 76, 66, 233, 166, 55, 237, 107, 11, 255,
|
||||
92, 182, 244, 6, 183, 237, 238, 56, 107, 251,
|
||||
90, 137, 159, 165, 174, 159, 36, 17, 124, 75,
|
||||
31, 230, 73, 40, 102, 81, 236, 228, 91, 61,
|
||||
194, 0, 124, 184, 161, 99, 191, 5, 152, 218,
|
||||
72, 54, 28, 85, 211, 154, 105, 22, 63, 168,
|
||||
253, 36, 207, 95, 131, 101, 93, 35, 220, 163,
|
||||
173, 150, 28, 98, 243, 86, 32, 133, 82, 187,
|
||||
158, 213, 41, 7, 112, 150, 150, 109, 103, 12,
|
||||
53, 78, 74, 188, 152, 4, 241, 116, 108, 8,
|
||||
202, 35, 115, 39, 255, 255, 255, 255, 255, 255,
|
||||
255, 255
|
||||
};
|
||||
|
||||
public string DH_passphrase
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_SysAuthPassphrase;
|
||||
}
|
||||
set
|
||||
{
|
||||
ResetToDefaults();
|
||||
m_SysAuthPassphrase = value;
|
||||
ASBSolutionValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] DH_certificate => m_SysAuthCertificate;
|
||||
|
||||
public SysAuthParameters(string asbSolutionName = null)
|
||||
{
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, "SysAuthParameters constructor with asbSolutionName = {0}", string.IsNullOrEmpty(asbSolutionName) ? "<null>" : asbSolutionName);
|
||||
ASBSolutionName = asbSolutionName;
|
||||
ASBSolutionValid = false;
|
||||
ResetToDefaults();
|
||||
LoadASBSolution();
|
||||
}
|
||||
|
||||
public void ResetToDefaults()
|
||||
{
|
||||
ASBSolutionValid = false;
|
||||
DH_KeySize = DH_KeySize_Dft;
|
||||
DH_SecretSize = DH_SecretSize_Dft;
|
||||
m_SysAuthPassphrase = DH_passphrase_Dft;
|
||||
m_SysAuthCertificate = null;
|
||||
ConnectionLifetime = ConnectionLifetime_Dft;
|
||||
SaltValue = SaltValue_Dft;
|
||||
hashAlgorithm = hashAlgorithm_Dft;
|
||||
PasswordIterations = PasswordIterations_Dft;
|
||||
InitialVector = InitialVector_Dft;
|
||||
KeySize = KeySize_Dft;
|
||||
GenerateKey();
|
||||
}
|
||||
|
||||
private void LoadASBSolution()
|
||||
{
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, "LoadASBSolution entry");
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(ASBSolutionName))
|
||||
{
|
||||
ASBSolutionName = SvcUtilities.ReadKeyValue(string.Empty, "DefaultASBSolution");
|
||||
if (string.IsNullOrEmpty(ASBSolutionName))
|
||||
{
|
||||
SvcTrace.DiagException.TraceEvent(TraceEventType.Error, 0, "LoadASBSolution: Unable to get default ASB solution name");
|
||||
ASBSolutionValid = false;
|
||||
}
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, "LoadASBSolution created with empty solution name, resetting to default '{0}'", string.IsNullOrEmpty(ASBSolutionName) ? "<null>" : ASBSolutionName);
|
||||
}
|
||||
ASBSolutionValid = false;
|
||||
if (!string.IsNullOrEmpty(ASBSolutionName))
|
||||
{
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, "LoadASBSolution: Using solution {0}", ASBSolutionName);
|
||||
if (string.IsNullOrEmpty(RegistryHandler.GetSolutionPassphrase(ASBSolutionName, out var passphrase)) && !string.IsNullOrEmpty(passphrase))
|
||||
{
|
||||
DH_passphrase = passphrase;
|
||||
}
|
||||
if ((passphrase = SvcUtilities.ReadKeyValue(RegKeyRelativePath + ASBSolutionName, "Certificate")) != null)
|
||||
{
|
||||
m_SysAuthCertificate = Encoding.UTF8.GetBytes(passphrase);
|
||||
}
|
||||
if ((passphrase = SvcUtilities.ReadKeyValue(RegKeyRelativePath + ASBSolutionName, "saltValue")) != null)
|
||||
{
|
||||
SaltValue = passphrase;
|
||||
}
|
||||
if ((passphrase = SvcUtilities.ReadKeyValue(RegKeyRelativePath + ASBSolutionName, "HashAlgorthim")) != null)
|
||||
{
|
||||
hashAlgorithm = passphrase;
|
||||
}
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 0, "LoadASBSolution: Using hashAlgorithm {0}", hashAlgorithm);
|
||||
if ((passphrase = SvcUtilities.ReadKeyValue(RegKeyRelativePath + ASBSolutionName, "passowordIterations")) != null)
|
||||
{
|
||||
PasswordIterations = int.Parse(passphrase);
|
||||
}
|
||||
if ((passphrase = SvcUtilities.ReadKeyValue(RegKeyRelativePath + ASBSolutionName, "initailizationVector")) != null)
|
||||
{
|
||||
InitialVector = passphrase;
|
||||
}
|
||||
if ((passphrase = SvcUtilities.ReadKeyValue(RegKeyRelativePath + ASBSolutionName, "keySize")) != null)
|
||||
{
|
||||
int.TryParse(passphrase, out KeySize);
|
||||
}
|
||||
if ((passphrase = SvcUtilities.ReadKeyValue(RegKeyRelativePath + ASBSolutionName, "Prime")) != null)
|
||||
{
|
||||
BigInteger.TryParse(passphrase, out DH_p);
|
||||
}
|
||||
if ((passphrase = SvcUtilities.ReadKeyValue(RegKeyRelativePath + ASBSolutionName, "Generator")) != null)
|
||||
{
|
||||
BigInteger.TryParse(passphrase, out DH_g);
|
||||
}
|
||||
ASBSolutionValid = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SvcTrace.DiagException.TraceEvent(TraceEventType.Error, 0, "LoadASBSolution: Exception caught: {0}", ex.Message);
|
||||
ASBSolutionValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateKey()
|
||||
{
|
||||
if (DH_KeySize == 768)
|
||||
{
|
||||
BigInteger.TryParse(s_DECIMAL768, out DH_p);
|
||||
}
|
||||
else if (DH_KeySize == 1024)
|
||||
{
|
||||
BigInteger.TryParse(s_DECIMAL1024, out DH_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DH_KeySize != 1536)
|
||||
{
|
||||
throw new ArgumentException("Invalid bit size.");
|
||||
}
|
||||
BigInteger.TryParse(s_DECIMAL1536, out DH_p);
|
||||
}
|
||||
DH_g = new BigInteger(22);
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
#define TRACE
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using ArchestrAServices.Common;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public class SysAuthServiceAuthentication : SysAuthConnectionBase
|
||||
{
|
||||
private RNGCryptoServiceProvider m_Random = new RNGCryptoServiceProvider();
|
||||
|
||||
public BigInteger ClientPublicKey { get; private set; }
|
||||
|
||||
public BigInteger ServicePrivateKey { get; private set; }
|
||||
|
||||
public BigInteger ServicePublicKey { get; private set; }
|
||||
|
||||
public ulong Lifetime { get; private set; }
|
||||
|
||||
public SysAuthServiceAuthentication()
|
||||
{
|
||||
Reset();
|
||||
Lifetime = 18000000uL;
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public static ConnectResponse ProcessClientConnection(ConnectRequest request)
|
||||
{
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 100, "SysSvcAuth: Processing client Connect() call '{0}'", request.ConnectionId.ToString());
|
||||
ConnectResponse connectResponse = null;
|
||||
if (request != null && request.ConsumerPublicKey != null && request.ConsumerPublicKey.Data != null)
|
||||
{
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 100, "SysSvcAuth: Validated request message, processing");
|
||||
SysAuthServiceAuthentication sysAuthServiceAuthentication = new SysAuthServiceAuthentication();
|
||||
sysAuthServiceAuthentication.connectionID = request.ConnectionId;
|
||||
sysAuthServiceAuthentication.m_RemotePublicKey = request.ConsumerPublicKey.Data;
|
||||
SysAuthenticatorServiceCache.AddServiceAuthenticator(sysAuthServiceAuthentication);
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 100, "SysSvcAuth: Added authenticator for connection, captured client public key");
|
||||
PublicKey servicePublicKey = new PublicKey
|
||||
{
|
||||
Data = sysAuthServiceAuthentication.m_LocalPublicKey
|
||||
};
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 100, "SysSvcAuth: Established service public key to return");
|
||||
byte[] initializationVector;
|
||||
AuthenticationData serviceAuthenticationData = new AuthenticationData
|
||||
{
|
||||
Data = sysAuthServiceAuthentication.CalculateAuthenticationData(sysAuthServiceAuthentication.m_LocalPublicKey, sysAuthServiceAuthentication.m_RemotePublicKey, out initializationVector),
|
||||
InitializationVector = initializationVector
|
||||
};
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 100, "SysSvcAuth: Calculated authentication data to return");
|
||||
ArchestrAResult result = ResultFactory.MakeGoodResult();
|
||||
sysAuthServiceAuthentication.Lifetime = sysAuthServiceAuthentication.m_SolutionParameters.ConnectionLifetime;
|
||||
connectResponse = new ConnectResponse(servicePublicKey, serviceAuthenticationData, sysAuthServiceAuthentication.Lifetime + ":" + SysAuthConnectionBase.ASBAuthenticationVersion);
|
||||
connectResponse.Result = result;
|
||||
sysAuthServiceAuthentication.SignatureMethod = SigningMethod.Baktun;
|
||||
sysAuthServiceAuthentication.Sign(connectResponse, ForceHmac: true);
|
||||
sysAuthServiceAuthentication.SignatureMethod = SigningMethod.Apollo;
|
||||
sysAuthServiceAuthentication.ReasonSecureSessionNotEstablished = string.Empty;
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 100, "SysSvcAuth: Signed Connect response message");
|
||||
}
|
||||
return connectResponse;
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public bool ProcessClientAuthenticateMe(AuthenticateMe request)
|
||||
{
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 100, "SysSvcAuth: Processing client AuthenticateMe() call for connection id {0}", connectionID.ToString());
|
||||
base.SignatureMethod = SigningMethod.Apollo;
|
||||
if (!ValidRequest(request, ForceHmac: true))
|
||||
{
|
||||
base.SignatureMethod = SigningMethod.Baktun;
|
||||
if (!ValidRequest(request, ForceHmac: true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 100, "SysSvcAuth: AuthenticateMe() validated, signing set to {0}", (base.SignatureMethod == SigningMethod.Baktun) ? "System Platform 2012R2 Comptibility" : "System Platform 2014 Compatibility");
|
||||
AuthenticationData consumerAuthenticationData = request.ConsumerAuthenticationData;
|
||||
if (consumerAuthenticationData != null)
|
||||
{
|
||||
byte[] expected = ReCalculateAuthenticationData(m_RemotePublicKey, m_LocalPublicKey, consumerAuthenticationData.InitializationVector);
|
||||
if (consumerAuthenticationData.AreEqual(expected))
|
||||
{
|
||||
SvcTrace.DiagDiagnostics.TraceEvent(TraceEventType.Information, 100, "SysSvcAuth: AuthenticateMe() authenticated client");
|
||||
m_Authenticated = true;
|
||||
}
|
||||
}
|
||||
return m_Authenticated;
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public static RenewResponse ProcessClientRenew(RenewRequest request)
|
||||
{
|
||||
SysAuthenticatorServiceCache.GetServiceAuthenticator(request.ConnectionValidator.ConnectionId)?.ValidRequest(request);
|
||||
return null;
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public static void ProcessClientUpdateSystemAuthenticationConfiguration(UpdateSystemAuthenticationConfiguration request)
|
||||
{
|
||||
SysAuthenticatorServiceCache.GetServiceAuthenticator(request.ConnectionValidator.ConnectionId)?.ValidRequest(request);
|
||||
}
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public void ProcessClientDisconnect(Disconnect request)
|
||||
{
|
||||
AuthenticationData consumerAuthenticationData = request.ConsumerAuthenticationData;
|
||||
if (consumerAuthenticationData != null)
|
||||
{
|
||||
byte[] bytes = Decypher(consumerAuthenticationData.Data, consumerAuthenticationData.InitializationVector);
|
||||
if (Guid.TryParse(Encoding.UTF8.GetString(bytes), out var result) && result == connectionID)
|
||||
{
|
||||
SysAuthenticatorServiceCache.RemoveServiceAuthenticator(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public class SysAuthenticatorClientCache : SynchronizedKeyedCollection<Guid, SysAuthClientAuthentication>
|
||||
{
|
||||
private static readonly SysAuthenticatorClientCache clientConnections = new SysAuthenticatorClientCache();
|
||||
|
||||
private static object cacheLockObject = new object();
|
||||
|
||||
private SysAuthenticatorClientCache()
|
||||
{
|
||||
}
|
||||
|
||||
public static IEnumerable<SysAuthClientAuthentication> GetAllClientAuthenticators()
|
||||
{
|
||||
List<SysAuthClientAuthentication> list = new List<SysAuthClientAuthentication>();
|
||||
lock (cacheLockObject)
|
||||
{
|
||||
list.AddRange(clientConnections.Items);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddClientAuthenticator(SysAuthClientAuthentication clientAuthenticator)
|
||||
{
|
||||
lock (cacheLockObject)
|
||||
{
|
||||
clientConnections.Purge();
|
||||
}
|
||||
if (clientAuthenticator == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lock (cacheLockObject)
|
||||
{
|
||||
if (!clientConnections.Contains(clientAuthenticator.connectionID))
|
||||
{
|
||||
clientConnections.Add(clientAuthenticator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static SysAuthClientAuthentication GetClientAuthenticator(Guid connectionId)
|
||||
{
|
||||
SysAuthClientAuthentication result = null;
|
||||
lock (cacheLockObject)
|
||||
{
|
||||
if (clientConnections.Contains(connectionId))
|
||||
{
|
||||
result = clientConnections[connectionId];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static SysAuthClientAuthentication RemoveClientAuthenticator(Guid connectionId)
|
||||
{
|
||||
SysAuthClientAuthentication result = GetClientAuthenticator(connectionId);
|
||||
lock (cacheLockObject)
|
||||
{
|
||||
if (clientConnections.Contains(connectionId))
|
||||
{
|
||||
result = clientConnections[connectionId];
|
||||
clientConnections.Remove(connectionId);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void Purge()
|
||||
{
|
||||
foreach (Guid item in this.Where((SysAuthClientAuthentication item) => !item.IsOwnerAlive).Select(GetKeyForItem).ToList())
|
||||
{
|
||||
Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Guid GetKeyForItem(SysAuthClientAuthentication item)
|
||||
{
|
||||
return item.connectionID;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
public class SysAuthenticatorServiceCache : SynchronizedKeyedCollection<Guid, SysAuthServiceAuthentication>
|
||||
{
|
||||
private static readonly SysAuthenticatorServiceCache serviceConnections = new SysAuthenticatorServiceCache();
|
||||
|
||||
private static object ServiceCacheLockObject = new object();
|
||||
|
||||
private SysAuthenticatorServiceCache()
|
||||
{
|
||||
}
|
||||
|
||||
public static IEnumerable<SysAuthServiceAuthentication> GetAllServiceAuthenticators()
|
||||
{
|
||||
List<SysAuthServiceAuthentication> list = new List<SysAuthServiceAuthentication>();
|
||||
lock (ServiceCacheLockObject)
|
||||
{
|
||||
list.AddRange(serviceConnections.Items);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddServiceAuthenticator(SysAuthServiceAuthentication serviceAuthenticator)
|
||||
{
|
||||
if (serviceAuthenticator == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lock (ServiceCacheLockObject)
|
||||
{
|
||||
if (!serviceConnections.Contains(serviceAuthenticator.connectionID))
|
||||
{
|
||||
serviceConnections.Add(serviceAuthenticator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static SysAuthServiceAuthentication GetServiceAuthenticator(Guid connectionId)
|
||||
{
|
||||
SysAuthServiceAuthentication result = null;
|
||||
lock (ServiceCacheLockObject)
|
||||
{
|
||||
if (serviceConnections.Contains(connectionId))
|
||||
{
|
||||
result = serviceConnections[connectionId];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static SysAuthServiceAuthentication RemoveServiceAuthenticator(Guid connectionId)
|
||||
{
|
||||
SysAuthServiceAuthentication serviceAuthenticator = GetServiceAuthenticator(connectionId);
|
||||
if (serviceAuthenticator != null)
|
||||
{
|
||||
lock (ServiceCacheLockObject)
|
||||
{
|
||||
serviceConnections.Remove(connectionId);
|
||||
}
|
||||
}
|
||||
return serviceAuthenticator;
|
||||
}
|
||||
|
||||
protected override Guid GetKeyForItem(SysAuthServiceAuthentication item)
|
||||
{
|
||||
return item.connectionID;
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
using System.CodeDom.Compiler;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.ServiceModel;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace ArchestrAServices.ASBContract;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
|
||||
[EditorBrowsable(EditorBrowsableState.Advanced)]
|
||||
[MessageContract(WrapperName = "UpdateSystemAuthenticationConfigurationRequest", WrapperNamespace = "http://asb.contracts.messages/20111111", IsWrapped = true)]
|
||||
public class UpdateSystemAuthenticationConfiguration : ConnectedRequest
|
||||
{
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 0)]
|
||||
public string EncryptedConfigurationData;
|
||||
|
||||
[MessageBodyMember(Namespace = "http://asb.contracts.messages/20111111", Order = 1)]
|
||||
[XmlElement(DataType = "base64Binary")]
|
||||
public byte[] InitializationVector;
|
||||
|
||||
public UpdateSystemAuthenticationConfiguration()
|
||||
{
|
||||
}
|
||||
|
||||
public UpdateSystemAuthenticationConfiguration(string EncryptedConfigurationData, byte[] InitializationVector)
|
||||
{
|
||||
this.EncryptedConfigurationData = EncryptedConfigurationData;
|
||||
this.InitializationVector = InitializationVector;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user