2using System.Collections.Generic;
5using System.Net.Http.Headers;
6using System.Runtime.ExceptionServices;
7using System.Security.Cryptography;
9using System.Threading.Tasks;
11using System.Xml.Schema;
105 private static readonly
string KeySettings = typeof(
ContractsClient).FullName +
".";
106 private static readonly
string ContractKeySettings = typeof(
ContractsClient).Namespace +
".Contracts.";
108 private readonly Dictionary<string, KeyEventArgs> publicKeys =
new Dictionary<string, KeyEventArgs>();
109 private readonly Dictionary<string, KeyEventArgs> matchingKeys =
new Dictionary<string, KeyEventArgs>();
113 private DateTime keysTimestamp = DateTime.MinValue;
115 private object[] approvedSources =
null;
116 private readonly
string componentAddress;
117 private string keySettingsPrefix;
118 private string contractKeySettingsPrefix;
119 private bool keySettingsPrefixLocked =
false;
120 private bool localKeysForE2e =
false;
121 private bool preferredEncryptionAlgorithmLocked =
false;
122 private RandomNumberGenerator rnd = RandomNumberGenerator.Create();
161 this.approvedSources = ApprovedSources;
162 this.localKeys =
null;
164 #region NeuroFoundation V1
167 this.
client.
RegisterMessageHandler(
"petitionIdentityMsg", NamespaceLegalIdentitiesNeuroFoundationV1, this.PetitionIdentityMessageHandler,
false);
168 this.
client.
RegisterMessageHandler(
"petitionIdentityResponseMsg", NamespaceLegalIdentitiesNeuroFoundationV1, this.PetitionIdentityResponseMessageHandler,
false);
169 this.
client.
RegisterMessageHandler(
"petitionSignatureMsg", NamespaceLegalIdentitiesNeuroFoundationV1, this.PetitionSignatureMessageHandler,
false);
170 this.
client.
RegisterMessageHandler(
"petitionSignatureResponseMsg", NamespaceLegalIdentitiesNeuroFoundationV1, this.PetitionSignatureResponseMessageHandler,
false);
171 this.
client.
RegisterMessageHandler(
"petitionClientUrl", NamespaceLegalIdentitiesNeuroFoundationV1, this.PetitionClientUrlEventHandler,
false);
173 this.
client.
RegisterMessageHandler(
"contractSigned", NamespaceSmartContractsNeuroFoundationV1, this.ContractSignedMessageHandler,
true);
174 this.
client.
RegisterMessageHandler(
"contractCreated", NamespaceSmartContractsNeuroFoundationV1, this.ContractCreatedMessageHandler,
false);
175 this.
client.
RegisterMessageHandler(
"contractUpdated", NamespaceSmartContractsNeuroFoundationV1, this.ContractUpdatedMessageHandler,
false);
176 this.
client.
RegisterMessageHandler(
"contractDeleted", NamespaceSmartContractsNeuroFoundationV1, this.ContractDeletedMessageHandler,
false);
177 this.
client.
RegisterMessageHandler(
"petitionContractMsg", NamespaceSmartContractsNeuroFoundationV1, this.PetitionContractMessageHandler,
false);
178 this.
client.
RegisterMessageHandler(
"petitionContractResponseMsg", NamespaceSmartContractsNeuroFoundationV1, this.PetitionContractResponseMessageHandler,
false);
179 this.
client.
RegisterMessageHandler(
"contractProposal", NamespaceSmartContractsNeuroFoundationV1, this.ContractProposalMessageHandler,
false);
187 this.
client.
RegisterMessageHandler(
"petitionIdentityResponseMsg", NamespaceLegalIdentitiesIeeeV1, this.PetitionIdentityResponseMessageHandler,
false);
188 this.
client.
RegisterMessageHandler(
"petitionSignatureMsg", NamespaceLegalIdentitiesIeeeV1, this.PetitionSignatureMessageHandler,
false);
189 this.
client.
RegisterMessageHandler(
"petitionSignatureResponseMsg", NamespaceLegalIdentitiesIeeeV1, this.PetitionSignatureResponseMessageHandler,
false);
197 this.
client.
RegisterMessageHandler(
"petitionContractResponseMsg", NamespaceSmartContractsIeeeV1, this.PetitionContractResponseMessageHandler,
false);
202 this.aes = Aes.Create();
203 this.aes.BlockSize = 128;
204 this.aes.KeySize = 256;
205 this.aes.Mode = CipherMode.CBC;
206 this.aes.Padding = PaddingMode.None;
208 this.keySettingsPrefix = KeySettings;
209 this.contractKeySettingsPrefix = ContractKeySettings;
217 #region NeuroFoundation V1
220 this.
client.
UnregisterMessageHandler(
"petitionIdentityMsg", NamespaceLegalIdentitiesNeuroFoundationV1, this.PetitionIdentityMessageHandler,
false);
221 this.
client.
UnregisterMessageHandler(
"petitionIdentityResponseMsg", NamespaceLegalIdentitiesNeuroFoundationV1, this.PetitionIdentityResponseMessageHandler,
false);
222 this.
client.
UnregisterMessageHandler(
"petitionSignatureMsg", NamespaceLegalIdentitiesNeuroFoundationV1, this.PetitionSignatureMessageHandler,
false);
223 this.
client.
UnregisterMessageHandler(
"petitionSignatureResponseMsg", NamespaceLegalIdentitiesNeuroFoundationV1, this.PetitionSignatureResponseMessageHandler,
false);
230 this.
client.
UnregisterMessageHandler(
"petitionContractMsg", NamespaceSmartContractsNeuroFoundationV1, this.PetitionContractMessageHandler,
false);
231 this.
client.
UnregisterMessageHandler(
"petitionContractResponseMsg", NamespaceSmartContractsNeuroFoundationV1, this.PetitionContractResponseMessageHandler,
false);
240 this.
client.
UnregisterMessageHandler(
"petitionIdentityResponseMsg", NamespaceLegalIdentitiesIeeeV1, this.PetitionIdentityResponseMessageHandler,
false);
242 this.
client.
UnregisterMessageHandler(
"petitionSignatureResponseMsg", NamespaceLegalIdentitiesIeeeV1, this.PetitionSignatureResponseMessageHandler,
false);
250 this.
client.
UnregisterMessageHandler(
"petitionContractResponseMsg", NamespaceSmartContractsIeeeV1, this.PetitionContractResponseMessageHandler,
false);
256 this.localKeys =
null;
257 this.keysTimestamp = DateTime.MinValue;
310 if (this.preferredEncryptionAlgorithm == Algorithm)
313 if (this.preferredEncryptionAlgorithmLocked)
314 throw new InvalidOperationException(
"Preferred Encryptio Algorithm has been locked.");
316 this.preferredEncryptionAlgorithm = Algorithm;
317 this.preferredEncryptionAlgorithmLocked = Lock;
327 return this.
LoadKeys(CreateIfNone,
null);
344 List<IE2eEndpoint> Keys =
new List<IE2eEndpoint>();
350 DateTime? Timestamp =
null;
351 bool DisposeEndpoints =
true;
356 foreach (KeyValuePair<string, object> Setting
in Settings)
358 string LocalName = Setting.Key.Substring(this.keySettingsPrefix.Length);
360 if (Setting.Value is
string d)
362 if (
string.IsNullOrEmpty(d))
367 Key = Convert.FromBase64String(d);
383 else if (Setting.Value is DateTime TP && LocalName ==
"Timestamp")
394 DisposeEndpoints =
false;
400 Key = this.GetKey(Curve.Curve);
406 Timestamp = DateTime.Now;
411 else if (!Timestamp.HasValue)
415 Timestamp = DateTime.Now;
422 this.localKeys =
null;
425 this.keysTimestamp = Timestamp.Value;
427 if (this.localKeysForE2e)
428 this.localE2eEndpoint = this.localKeys;
430 if (DisposeEndpoints)
448 string s = Curve.
Export();
449 XmlDocument Doc =
new XmlDocument()
451 PreserveWhitespace =
true
454 s = Doc.DocumentElement.GetAttribute(
"d");
455 return Convert.FromBase64String(s);
466 lock (this.matchingKeys)
468 this.matchingKeys.Clear();
483 State.State = Identity.
State;
484 State.Timestamp = Identity.
Updated;
486 switch (Identity.
State)
491 State.PublicKey =
null;
516 await this.UpdateSettings(Identity);
537 StringBuilder Xml =
new StringBuilder();
540 using (XmlWriter Output = XmlWriter.Create(Xml, Settings))
545 return Xml.ToString();
554 this.AssertAllowed();
560 foreach (KeyValuePair<string, object> Setting
in Settings)
562 string Name = Setting.Key.Substring(this.keySettingsPrefix.Length);
564 if (Setting.Value is
string s)
566 Output.WriteStartElement(
"S");
567 Output.WriteAttributeString(
"n", Name);
568 Output.WriteAttributeString(
"v", s);
569 Output.WriteEndElement();
571 else if (Setting.Value is DateTime TP)
573 Output.WriteStartElement(
"DT");
574 Output.WriteAttributeString(
"n", Name);
575 Output.WriteAttributeString(
"v",
XML.
Encode(TP));
576 Output.WriteEndElement();
584 Output.WriteStartElement(
"State");
585 Output.WriteAttributeString(
"legalId", State.
LegalId);
586 Output.WriteAttributeString(
"publicKey", Convert.ToBase64String(State.
PublicKey));
588 Output.WriteEndElement();
593 foreach (KeyValuePair<string, object> Setting
in Settings)
595 string Name = Setting.Key.Substring(this.contractKeySettingsPrefix.Length);
597 if (Setting.Value is
string s)
599 Output.WriteStartElement(
"C");
600 Output.WriteAttributeString(
"n", Name);
601 Output.WriteAttributeString(
"v", s);
602 Output.WriteEndElement();
606 Output.WriteEndElement();
616 XmlDocument Doc =
new XmlDocument();
639 this.AssertAllowed();
644 foreach (XmlNode N
in Xml.ChildNodes)
646 if (!(N is XmlElement E))
663 DateTime DateTimeValue =
XML.
Attribute(E,
"v", DateTime.MinValue);
679 DateTimeValue =
XML.
Attribute(E,
"timestamp", DateTime.MinValue);
683 PublicKey = Convert.FromBase64String(PublicKeyStr);
701 Timestamp = DateTimeValue,
702 PublicKey = PublicKey
710 IdState.Timestamp = DateTimeValue;
711 IdState.PublicKey = PublicKey;
732 if (this.keySettingsPrefixLocked)
733 throw new InvalidOperationException(
"Key settings instance is locked.");
735 if (
string.IsNullOrEmpty(InstanceName))
737 this.keySettingsPrefix = KeySettings;
738 this.contractKeySettingsPrefix = ContractKeySettings;
742 this.keySettingsPrefix = InstanceName +
"." + KeySettings;
743 this.contractKeySettingsPrefix = InstanceName +
"." + ContractKeySettings;
746 this.keySettingsPrefixLocked = Locked;
765 bool Reload = !(this.localKeys is
null);
767 this.localKeysForE2e = UseLocalKeys;
770 await this.
LoadKeys(CreateKeysIfNone);
789 bool Reload = !(this.localKeys is
null);
791 this.localKeysForE2e =
false;
795 await this.
LoadKeys(CreateKeysIfNone);
807 throw new ArgumentException(nameof(Nr));
809 byte[] Bytes =
new byte[Nr];
811 this.rnd.GetBytes(Bytes);
823 return BitConverter.ToUInt64(Bin, 0);
833 if (MaxExclusive == 0)
834 throw new ArgumentException(nameof(MaxExclusive));
849 if (MaxInclusive < MinInclusive)
850 throw new ArgumentException(nameof(MaxInclusive));
852 ulong Diff = (uint)(MaxInclusive - MinInclusive);
857 Result += MinInclusive;
873 if (!(this.approvedSources is
null))
874 throw new NotSupportedException(
"Changing approved sources not permitted.");
876 this.approvedSources = ApprovedSources;
879 private void AssertAllowed()
881 if (!(this.approvedSources is
null))
896 return "iotid:" + LegalId;
916 return "iotsc:" + ContractId;
931 #region Server Public Keys
949 public async Task
GetServerPublicKey(
string Address, EventHandlerAsync<KeyEventArgs> Callback,
object State)
953 lock (this.publicKeys)
955 if (!this.publicKeys.TryGetValue(Address, out e0))
966 await Callback.Raise(
this, e0);
975 if (e.Ok && !((E = e.FirstElement) is
null) && E.LocalName ==
"publicKey")
977 foreach (XmlNode N in E.ChildNodes)
979 if (N is XmlElement E2)
981 ServerKey = EndpointSecurity.ParseE2eKey(E2);
982 if (!(ServerKey is null))
987 e.Ok = !(ServerKey is
null);
996 lock (this.publicKeys)
998 this.publicKeys[Address] = e0;
1002 await Callback.Raise(
this, e0);
1013 return this.GetServerPublicKeyAsync(this.componentAddress);
1023 TaskCompletionSource<IE2eEndpoint> Result =
new TaskCompletionSource<IE2eEndpoint>();
1025 await this.GetServerPublicKey(Address, (Sender, e) =>
1028 Result.TrySetResult(e.Key);
1030 Result.TrySetException(e.StanzaError ??
new Exception(
"Unable to get public key."));
1032 return Task.CompletedTask;
1036 return await Result.Task;
1041 #region Matching Local Keys
1050 return this.GetMatchingLocalKey(this.componentAddress, Callback, State);
1060 if (this.localKeys is
null)
1061 throw new InvalidOperationException(
"Local keys not loaded or generated.");
1063 return this.localKeys;
1074 if (this.localE2eEndpoint is
null)
1075 throw new InvalidOperationException(
"End-to-End Encryption not enabled or Local keys not loaded or generated.");
1077 return this.localE2eEndpoint;
1091 lock (this.matchingKeys)
1093 if (!this.matchingKeys.TryGetValue(Address, out e0))
1104 await Callback.Raise(
this, e0);
1108 await this.GetServerPublicKey(Address, async (Sender, e) =>
1114 LocalKey = this.LocalEndpoint.GetLocalKey(e.Key);
1115 if (LocalKey is null)
1123 lock (this.matchingKeys)
1125 this.matchingKeys[Address] = e0;
1129 await Callback.Raise(
this, e0);
1141 return this.GetMatchingLocalKeyAsync(this.componentAddress);
1151 TaskCompletionSource<IE2eEndpoint> Result =
new TaskCompletionSource<IE2eEndpoint>();
1153 await this.GetMatchingLocalKey(Address, (Sender, e) =>
1156 Result.TrySetResult(e.Key);
1158 Result.TrySetException(e.StanzaError ??
new Exception(
"Unable to get matching local key."));
1160 return Task.CompletedTask;
1164 return await Result.Task;
1169 #region ID Application Attributes
1178 return this.client.SendIqGet(this.componentAddress,
"<applicationAttributes xmlns='" + NamespaceLegalIdentitiesCurrent +
"'/>", (Sender, e) =>
1191 TaskCompletionSource<IdApplicationAttributesEventArgs> Result =
new TaskCompletionSource<IdApplicationAttributesEventArgs>();
1193 await this.GetIdApplicationAttributes((Sender, e) =>
1196 Result.TrySetResult(e);
1198 Result.TrySetException(e.StanzaError ??
new Exception(
"Unable to get ID Application attributes."));
1200 return Task.CompletedTask;
1203 return await Result.Task;
1208 #region Apply for a Legal Identity
1216 public Task
Apply(
Property[] Properties, EventHandlerAsync<LegalIdentityEventArgs> Callback,
object State)
1218 return this.Apply(this.componentAddress, Properties, Callback, State);
1228 public async Task
Apply(
string Address,
Property[] Properties, EventHandlerAsync<LegalIdentityEventArgs> Callback,
object State)
1230 this.AssertAllowed();
1232 await this.GetMatchingLocalKey(Address, async (Sender, e) =>
1236 StringBuilder Xml = new StringBuilder();
1238 Xml.Append(
"<apply xmlns=\"");
1239 Xml.Append(NamespaceLegalIdentitiesCurrent);
1242 StringBuilder Identity = new StringBuilder();
1244 Identity.Append(
"<identity><clientPublicKey>");
1245 e.Key.ToXml(Identity, NamespaceLegalIdentitiesCurrent);
1246 Identity.Append(
"</clientPublicKey>");
1248 foreach (Property Property in Properties)
1250 Identity.Append(
"<property name=\"");
1251 Identity.Append(XML.Encode(Property.Name));
1252 Identity.Append(
"\" value=\"");
1253 Identity.Append(XML.Encode(Property.Value));
1254 Identity.Append(
"\"/>");
1257 string s = Identity.ToString();
1262 byte[] Bin = Encoding.UTF8.GetBytes(s);
1265 Xml.Append(
"<clientSignature>");
1266 Xml.Append(Convert.ToBase64String(
Signature));
1267 Xml.Append(
"</clientSignature>");
1269 Xml.Append(
"</identity></apply>");
1271 await
this.client.SendIqSet(Address, Xml.ToString(), async (sender2, e2) =>
1276 if (e2.Ok && !((E = e2.FirstElement) is
null) &&
1277 E.LocalName ==
"identity")
1279 Identity2 = LegalIdentity.Parse(E);
1280 await this.UpdateSettings(Identity2, e.Key.PublicKey);
1300 return this.ApplyAsync(this.componentAddress, Properties);
1311 TaskCompletionSource<LegalIdentity> Result =
new TaskCompletionSource<LegalIdentity>();
1313 await this.Apply(Address, Properties, (Sender, e) =>
1316 Result.TrySetResult(e.Identity);
1318 Result.TrySetException(e.StanzaError ??
new Exception(
"Unable to apply for a legal identity to be registered."));
1320 return Task.CompletedTask;
1324 return await Result.Task;
1329 #region Mark Identity as Ready for Approval
1339 public Task
ReadyForApproval(
string LegalIdentityId, EventHandlerAsync<IqResultEventArgs> Callback,
object State)
1341 return this.ReadyForApproval(this.componentAddress, LegalIdentityId, Callback, State);
1353 public Task
ReadyForApproval(
string Address,
string LegalIdentityId, EventHandlerAsync<IqResultEventArgs> Callback,
object State)
1355 this.AssertAllowed();
1357 StringBuilder Xml =
new StringBuilder();
1359 Xml.Append(
"<readyForApproval xmlns=\"");
1360 Xml.Append(NamespaceLegalIdentitiesCurrent);
1361 Xml.Append(
"\" id=\"");
1362 Xml.Append(
XML.
Encode(LegalIdentityId));
1365 return this.client.SendIqSet(Address, Xml.ToString(), Callback, State);
1376 return this.ReadyForApprovalAsync(this.componentAddress, LegalIdentityId);
1388 TaskCompletionSource<bool> Result =
new TaskCompletionSource<bool>();
1390 await this.ReadyForApproval(Address, LegalIdentityId, (Sender, e) =>
1393 Result.TrySetResult(
true);
1395 Result.TrySetException(e.StanzaError ??
new Exception(
"Unable to flag identity as ready for approval."));
1397 return Task.CompletedTask;
1406 #region Validate Legal Identity
1416 return this.Validate(Identity,
true, Callback, State);
1426 public async Task
Validate(
LegalIdentity Identity,
bool ValidateState, EventHandlerAsync<IdentityValidationEventArgs> Callback,
object State)
1428 if (Identity is
null)
1430 await this.ReturnStatus(
IdentityStatus.IdentityUndefined, Callback, State);
1436 await this.ReturnStatus(
IdentityStatus.NotApproved, Callback, State);
1440 DateTime Now = DateTime.Now;
1442 if (Now.Date.AddDays(1) < Identity.
From)
1444 await this.ReturnStatus(
IdentityStatus.NotValidYet, Callback, State);
1448 if (Now.Date.AddDays(-1) > Identity.
To)
1450 await this.ReturnStatus(
IdentityStatus.NotValidAnymore, Callback, State);
1454 if (
string.IsNullOrEmpty(Identity.
Provider))
1456 await this.ReturnStatus(
IdentityStatus.NoTrustProvider, Callback, State);
1463 await this.ReturnStatus(
IdentityStatus.NoClientPublicKey, Callback, State);
1469 await this.ReturnStatus(
IdentityStatus.NoClientSignature, Callback, State);
1473 StringBuilder Xml =
new StringBuilder();
1474 Identity.
Serialize(Xml,
false,
false,
false,
false,
false,
false,
false);
1475 byte[] Data = Encoding.UTF8.GetBytes(Xml.ToString());
1477 bool? b = this.ValidateSignature(Identity, Data, Identity.
ClientSignature);
1482 await this.ReturnStatus(
IdentityStatus.ClientSignatureInvalid, Callback, State);
1488 await this.ReturnStatus(
IdentityStatus.ClientKeyNotRecognized, Callback, State);
1498 await this.ReturnStatus(
IdentityStatus.AttachmentLacksUrl, Callback, State);
1504 KeyValuePair<string, TemporaryFile> P = await this.GetAttachmentAsync(
Attachment.
Url,
SignWith.LatestApprovedIdOrCurrentKeys, 30000);
1510 await this.ReturnStatus(
IdentityStatus.AttachmentInconsistency, Callback, State);
1521 await this.ReturnStatus(
IdentityStatus.AttachmentSignatureInvalid, Callback, State);
1527 await this.ReturnStatus(
IdentityStatus.ClientKeyNotRecognized, Callback, State);
1532 catch (Exception ex)
1534 await this.client.Error(
"Attachment " +
Attachment.
Url +
"unavailable: " + ex.Message);
1535 await this.ReturnStatus(
IdentityStatus.AttachmentUnavailable, Callback, State);
1543 await this.ReturnStatus(
IdentityStatus.NoProviderSignature, Callback, State);
1548 Identity.
Serialize(Xml,
false,
true,
true,
true,
true,
false,
false);
1549 Data = Encoding.UTF8.GetBytes(Xml.ToString());
1551 bool HasOldPublicKey;
1553 lock (this.publicKeys)
1555 HasOldPublicKey = this.publicKeys.ContainsKey(Identity.
Provider);
1558 await this.GetServerPublicKey(Identity.
Provider, async (Sender, e) =>
1560 if (e.Ok && !(e.Key is
null))
1562 bool Valid = e.Key.Verify(Data, Identity.ServerSignature);
1566 await this.ReturnStatus(IdentityStatus.Valid, Callback, State);
1570 if (!HasOldPublicKey)
1572 await this.ReturnStatus(
IdentityStatus.ProviderSignatureInvalid, Callback, State);
1576 lock (this.publicKeys)
1578 this.publicKeys.Remove(Identity.
Provider);
1581 await this.GetServerPublicKey(Identity.
Provider, (sender2, e2) =>
1583 if (e2.Ok && !(e2.Key is null))
1585 if (e.Key.Equals(e2.Key))
1586 return this.ReturnStatus(IdentityStatus.ProviderSignatureInvalid, Callback, State);
1588 Valid = e2.Key.Verify(Data, Identity.ServerSignature);
1591 return this.ReturnStatus(IdentityStatus.Valid, Callback, State);
1593 return this.ReturnStatus(IdentityStatus.ProviderSignatureInvalid, Callback, State);
1596 return this.ReturnStatus(
IdentityStatus.NoProviderPublicKey, Callback, State);
1601 await this.ReturnStatus(
IdentityStatus.NoProviderPublicKey, Callback, State);
1620 int.TryParse(Identity.
ClientKeyName.Substring(3), out
int KeySize))
1625 Identity.
Namespace.Replace(
":iot:leg:id:",
":iot:e2e:").Replace(
"urn:ieee:",
"urn:nf:"),
1649 int.TryParse(Identity.
ClientKeyName.Substring(3), out
int KeySize))
1654 Identity.
Namespace.Replace(
":iot:leg:id:",
":iot:e2e:").Replace(
"urn:ieee:",
"urn:nf:"),
1664 private async Task ReturnStatus(
IdentityStatus Status, EventHandlerAsync<IdentityValidationEventArgs> Callback,
object State)
1676 return this.ValidateAsync(Identity,
true);
1687 TaskCompletionSource<IdentityStatus> Result =
new TaskCompletionSource<IdentityStatus>();
1689 await this.Validate(Identity, ValidateState, (Sender, e) =>
1691 Result.TrySetResult(e.Status);
1692 return Task.CompletedTask;
1695 return await Result.Task;
1700 #region Legal Identity update event
1702 private bool IsFromTrustProvider(
string Id,
string From)
1704 int i = Id.IndexOf(
'@');
1708 Id = Id.Substring(i + 1);
1710 i = From.IndexOf(
'@');
1714 return (
string.Compare(Id, From,
true) == 0 ||
1715 From.EndsWith(
"." + Id, StringComparison.CurrentCultureIgnoreCase));
1718 private async Task IdentityMessageHandler(
object Sender,
MessageEventArgs e)
1722 if (!this.IsFromTrustProvider(Identity.
Id, e.
From))
1724 await this.client.Warning(
"Incoming identity message discarded: " + Identity.
Id +
" not from " + e.
From +
".");
1730 await this.client.Warning(
"Incoming identity message discarded: Sender " + e.
FromBareJID +
" not equal to Trust Provider " + Identity.
Provider +
".");
1734 await this.Validate(Identity,
false, async (sender2, e2) =>
1738 await this.client.Warning(
"Invalid legal identity received and discarded. Validation status: " + e2.Status.ToString());
1740 Log.Warning(
"Invalid legal identity received and discarded.", this.client.BareJID, e.From,
1741 new KeyValuePair<string, object>(
"Status", e2.Status));
1746 await
this.UpdateSettings(Identity);
1754 return this.UpdateSettings(Identity,
null);
1765 return this.HasPrivateKey(Identity.
Id);
1780 if (State?.PublicKey is
null)
1785 return !(Endpoint is
null);
1794 return this.GetLatestApprovedLegalId(
null);
1804 string PublicKeyBase64 = PublicKey is
null ? string.Empty : Convert.ToBase64String(PublicKey);
1810 if (!(PublicKey is
null) && Convert.ToBase64String(State.
PublicKey) != PublicKeyBase64)
1814 if (Endpoint is
null)
1823 private async Task<IE2eEndpoint> GetLatestApprovedKey(
bool ExceptionIfNone)
1825 bool HaveStates =
false;
1834 if (Endpoint is
null)
1840 if (ExceptionIfNone)
1844 throw new Exception(
"Private keys are not available on this device (" + this.client.BareJID +
1845 "). Were they created on another device?");
1848 throw new Exception(
"No approved legal identity available on this device (" + this.client.BareJID +
").");
1854 private async Task UpdateSettings(
LegalIdentity Identity,
byte[] PublicKey)
1856 if (!
string.IsNullOrEmpty(Identity.
Id))
1860 if (
string.IsNullOrEmpty(StateObj.
ObjectId))
1866 if (StateObj2 is
null)
1867 StateObj.BareJid = this.client.BareJID;
1872 StateObj = StateObj2;
1876 DateTime Timestamp = Identity.Updated > Identity.Created ? Identity.Updated : Identity.
Created;
1879 (StateObj.
PublicKey is
null && !(PublicKey is
null)) ||
1880 Identity.State > StateObj.
State)
1882 StateObj.State = Identity.
State;
1883 StateObj.Timestamp = Timestamp;
1885 if (PublicKey is
null)
1887 switch (Identity.
State)
1892 StateObj.PublicKey =
null;
1897 StateObj.PublicKey = PublicKey;
1899 if (
string.IsNullOrEmpty(StateObj.
ObjectId))
1911 public event EventHandlerAsync<LegalIdentityEventArgs> IdentityUpdated =
null;
1915 #region Get Legal Identities
1924 return this.GetLegalIdentities(this.componentAddress, Callback, State);
1933 public Task
GetLegalIdentities(
string Address, EventHandlerAsync<LegalIdentitiesEventArgs> Callback,
object State)
1935 return this.client.SendIqGet(Address,
"<getLegalIdentities xmlns=\"" + NamespaceLegalIdentitiesCurrent +
"\"/>",
1936 this.IdentitiesResponse,
new object[] { Callback, State });
1941 object[] P = (
object[])e.
State;
1942 EventHandlerAsync<LegalIdentitiesEventArgs> Callback = (EventHandlerAsync<LegalIdentitiesEventArgs>)P[0];
1946 if (e.
Ok && !((E = e.
FirstElement) is
null) && E.LocalName ==
"identities")
1948 List<LegalIdentity> IdentitiesList =
new List<LegalIdentity>();
1950 foreach (XmlNode N
in E.ChildNodes)
1952 if (N is XmlElement E2 && E2.LocalName ==
"identity")
1956 Identities = IdentitiesList.ToArray();
1971 return this.GetLegalIdentitiesAsync(this.componentAddress);
1981 TaskCompletionSource<LegalIdentity[]> Result =
new TaskCompletionSource<LegalIdentity[]>();
1983 await this.GetLegalIdentities(Address, (Sender, e) =>
1986 Result.TrySetResult(e.Identities);
1988 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to get legal identities."));
1990 return Task.CompletedTask;
1994 return await Result.Task;
1999 #region Get Legal Identity
2007 public Task
GetLegalIdentity(
string LegalIdentityId, EventHandlerAsync<LegalIdentityEventArgs> Callback,
object State)
2009 return this.GetLegalIdentity(this.GetTrustProvider(LegalIdentityId), LegalIdentityId, Callback, State);
2019 int i = EntityId.IndexOf(
'@');
2021 return this.componentAddress;
2023 return EntityId.Substring(i + 1);
2033 public Task
GetLegalIdentity(
string Address,
string LegalIdentityId, EventHandlerAsync<LegalIdentityEventArgs> Callback,
object State)
2035 return this.client.SendIqGet(Address,
"<getLegalIdentity id=\"" +
XML.
Encode(LegalIdentityId) +
"\" xmlns=\"" +
2036 NamespaceLegalIdentitiesCurrent +
"\"/>", async (Sender, e) =>
2041 if (e.
Ok && !((E = e.
FirstElement) is
null) && E.LocalName ==
"identity")
2057 return this.GetLegalIdentityAsync(this.GetTrustProvider(LegalIdentityId), LegalIdentityId);
2068 TaskCompletionSource<LegalIdentity> Result =
new TaskCompletionSource<LegalIdentity>();
2070 await this.GetLegalIdentity(Address, LegalIdentityId, (Sender, e) =>
2073 Result.TrySetResult(e.Identity);
2075 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to get legal identity."));
2077 return Task.CompletedTask;
2081 return await Result.Task;
2086 #region Obsolete Legal Identity
2094 public Task
ObsoleteLegalIdentity(
string LegalIdentityId, EventHandlerAsync<LegalIdentityEventArgs> Callback,
object State)
2096 return this.ObsoleteLegalIdentity(this.GetTrustProvider(LegalIdentityId), LegalIdentityId, Callback, State);
2106 public Task
ObsoleteLegalIdentity(
string Address,
string LegalIdentityId, EventHandlerAsync<LegalIdentityEventArgs> Callback,
object State)
2108 this.AssertAllowed();
2110 return this.client.SendIqSet(Address,
"<obsoleteLegalIdentity id=\"" +
XML.
Encode(LegalIdentityId) +
"\" xmlns=\"" +
2111 NamespaceLegalIdentitiesCurrent +
"\"/>", async (Sender, e) =>
2116 if (e.
Ok && !((E = e.
FirstElement) is
null) && E.LocalName ==
"identity")
2118 Identity = LegalIdentity.Parse(E);
2119 await this.UpdateSettings(Identity);
2135 return this.ObsoleteLegalIdentityAsync(this.GetTrustProvider(LegalIdentityId), LegalIdentityId);
2146 TaskCompletionSource<LegalIdentity> Result =
new TaskCompletionSource<LegalIdentity>();
2148 await this.ObsoleteLegalIdentity(Address, LegalIdentityId, (Sender, e) =>
2151 Result.TrySetResult(e.Identity);
2153 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to obsolete legal identity."));
2155 return Task.CompletedTask;
2159 return await Result.Task;
2164 #region Compromised Legal Identity
2174 return this.CompromisedLegalIdentity(this.GetTrustProvider(LegalIdentityId), LegalIdentityId, Callback, State);
2184 public Task
CompromisedLegalIdentity(
string Address,
string LegalIdentityId, EventHandlerAsync<LegalIdentityEventArgs> Callback,
object State)
2186 this.AssertAllowed();
2188 return this.client.SendIqSet(Address,
"<compromisedLegalIdentity id=\"" +
XML.
Encode(LegalIdentityId) +
"\" xmlns=\"" +
2189 NamespaceLegalIdentitiesCurrent +
"\"/>", async (Sender, e) =>
2194 if (e.
Ok && !((E = e.
FirstElement) is
null) && E.LocalName ==
"identity")
2196 Identity = LegalIdentity.Parse(E);
2197 await this.UpdateSettings(Identity);
2213 return this.CompromisedLegalIdentityAsync(this.GetTrustProvider(LegalIdentityId), LegalIdentityId);
2224 TaskCompletionSource<LegalIdentity> Result =
new TaskCompletionSource<LegalIdentity>();
2226 await this.CompromisedLegalIdentity(Address, LegalIdentityId, (Sender, e) =>
2229 Result.TrySetResult(e.Identity);
2231 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to compromise legal identity."));
2233 return Task.CompletedTask;
2237 return await Result.Task;
2253 return this.Sign(this.componentAddress, Data,
SignWith, Callback, State);
2264 public async Task
Sign(
string Address,
byte[] Data,
SignWith SignWith, EventHandlerAsync<SignatureEventArgs> Callback,
object State)
2266 this.AssertAllowed();
2278 Key = await this.GetLatestApprovedKey(
true);
2281 case SignWith.LatestApprovedIdOrCurrentKeys:
2283 Key = await this.GetLatestApprovedKey(
false);
2289 await this.GetMatchingLocalKey(Address, async (Sender, e) =>
2314 return this.SignAsync(this.componentAddress, Data,
SignWith);
2326 TaskCompletionSource<byte[]> Result =
new TaskCompletionSource<byte[]>();
2328 await this.Sign(Address, Data,
SignWith, (Sender, e) =>
2331 Result.TrySetResult(e.Signature);
2333 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to sign data."));
2335 return Task.CompletedTask;
2339 return await Result.Task;
2351 return this.Sign(this.componentAddress, Data,
SignWith, Callback, State);
2362 public async Task
Sign(
string Address, Stream Data,
SignWith SignWith, EventHandlerAsync<SignatureEventArgs> Callback,
object State)
2364 this.AssertAllowed();
2366 IE2eEndpoint Key =
SignWith == SignWith.CurrentKeys ? null : await this.GetLatestApprovedKey(
true);
2371 await this.GetMatchingLocalKey(Address, async (Sender, e) =>
2396 return this.SignAsync(this.componentAddress, Data,
SignWith);
2408 TaskCompletionSource<byte[]> Result =
new TaskCompletionSource<byte[]>();
2410 await this.Sign(Address, Data,
SignWith, (Sender, e) =>
2413 Result.TrySetResult(e.Signature);
2415 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to sign data."));
2417 return Task.CompletedTask;
2421 return await Result.Task;
2426 #region Validating Signatures
2438 return this.ValidateSignature(this.GetTrustProvider(LegalId), LegalId, Data,
Signature, Callback, State);
2450 public Task
ValidateSignature(
string Address,
string LegalId,
byte[] Data,
byte[]
Signature, EventHandlerAsync<LegalIdentityEventArgs> Callback,
object State)
2452 StringBuilder Xml =
new StringBuilder();
2454 Xml.Append(
"<validateSignature data=\"");
2455 Xml.Append(Convert.ToBase64String(Data));
2457 if (!
string.IsNullOrEmpty(LegalId))
2459 Xml.Append(
"\" id=\"");
2463 Xml.Append(
"\" s=\"");
2464 Xml.Append(Convert.ToBase64String(
Signature));
2466 Xml.Append(
"\" xmlns=\"");
2467 Xml.Append(NamespaceLegalIdentitiesCurrent);
2470 return this.client.SendIqGet(Address, Xml.ToString(), async (Sender, e) =>
2475 if (e.
Ok && !((E = e.
FirstElement) is
null) && E.LocalName ==
"identity")
2493 return this.ValidateSignatureAsync(this.GetTrustProvider(LegalId), LegalId, Data,
Signature);
2506 TaskCompletionSource<LegalIdentity> Result =
new TaskCompletionSource<LegalIdentity>();
2508 await this.ValidateSignature(Address, LegalId, Data,
Signature, (Sender, e) =>
2511 Result.TrySetResult(e.Identity);
2513 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to sign data."));
2515 return Task.CompletedTask;
2519 return await Result.Task;
2524 #region Create Contract
2547 Duration? ArchiveRequired,
Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore,
bool CanActAsTemplate,
2548 EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
2550 return this.CreateContract(this.componentAddress, ForMachines, ForHumans, Roles, Parts, Parameters, Visibility, PartsMode,
2551 Duration, ArchiveRequired, ArchiveOptional, SignAfter, SignBefore, CanActAsTemplate, Callback, State);
2576 Duration? ArchiveRequired,
Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore,
bool CanActAsTemplate,
2577 EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
2579 return this.CreateContract(Address, ForMachines, ForHumans, Roles, Parts, Parameters,
2580 Visibility, PartsMode,
Duration, ArchiveRequired, ArchiveOptional, SignAfter,
2581 SignBefore, CanActAsTemplate,
null, Callback, State);
2607 Duration? ArchiveRequired,
Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore,
bool CanActAsTemplate,
2610 StringBuilder Xml =
new StringBuilder();
2612 Xml.Append(
"<createContract xmlns=\"");
2613 Xml.Append(NamespaceSmartContractsCurrent);
2618 Namespace = NamespaceSmartContractsCurrent,
2619 ForMachines = ForMachines,
2620 ForHumans = ForHumans,
2623 Parameters = Parameters,
2624 Visibility = Visibility,
2625 PartsMode = PartsMode,
2627 ArchiveRequired = ArchiveRequired,
2628 ArchiveOptional = ArchiveOptional,
2629 SignAfter = SignAfter,
2630 SignBefore = SignBefore,
2631 CanActAsTemplate = CanActAsTemplate
2634 byte[] Nonce = Guid.NewGuid().ToByteArray();
2635 string NonceStr = Convert.ToBase64String(Nonce);
2640 if (Algorithm is
null)
2650 Xml.Append(
"<transient>");
2662 Xml.Append(
"</transient>");
2665 Xml.Append(
"</createContract>");
2667 await this.client.SendIqSet(Address, Xml.ToString(),
this.ContractResponse,
new object[] { Callback, State, Contract.HasEncryptedParameters, Algorithm?.Algorithm, Algorithm?.Key });
2672 object[] P = (
object[])e.
State;
2673 EventHandlerAsync<SmartContractEventArgs> Callback = (EventHandlerAsync<SmartContractEventArgs>)P[0];
2677 if (e.
Ok && !((E = e.
FirstElement) is
null) && E.LocalName ==
"contract")
2685 string CreatorJid = this.client.BareJID;
2687 if (P.Length >= 5 &&
2688 P[2] is
bool HasEncryptedParameters &&
2689 HasEncryptedParameters &&
2694 CreatorJid, Key, Algorithm,
false);
2698 Tuple<SymmetricCipherAlgorithms, string, byte[]> T = await this.TryLoadContractSharedSecret(
Contract.
ContractId);
2700 if (HasEncryptedParameters = !(T is
null))
2702 Algorithm = T.Item1;
2703 CreatorJid = T.Item2;
2708 Algorithm = this.preferredEncryptionAlgorithm;
2713 if (HasEncryptedParameters)
2749 Duration? ArchiveRequired,
Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore,
bool CanActAsTemplate)
2751 return this.CreateContractAsync(this.componentAddress, ForMachines, ForHumans, Roles, Parts, Parameters, Visibility,
2752 PartsMode,
Duration, ArchiveRequired, ArchiveOptional, SignAfter, SignBefore, CanActAsTemplate);
2776 Duration? ArchiveRequired,
Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore,
bool CanActAsTemplate)
2778 TaskCompletionSource<Contract> Result =
new TaskCompletionSource<Contract>();
2780 await this.CreateContract(Address, ForMachines, ForHumans, Roles, Parts, Parameters, Visibility, PartsMode,
Duration,
2781 ArchiveRequired, ArchiveOptional, SignAfter, SignBefore, CanActAsTemplate, (Sender, e) =>
2784 Result.TrySetResult(e.Contract);
2786 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to create the contract."));
2788 return Task.CompletedTask;
2792 return await Result.Task;
2797 #region Create Contract From Template
2818 DateTime? SignBefore,
bool CanActAsTemplate, EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
2820 return this.CreateContract(this.componentAddress, TemplateId, Parts, Parameters, Visibility, PartsMode,
Duration,
2821 ArchiveRequired, ArchiveOptional, SignAfter, SignBefore, CanActAsTemplate,
null, Callback, State);
2844 DateTime? SignBefore,
bool CanActAsTemplate, EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
2846 return this.CreateContract(Address, TemplateId, Parts, Parameters, Visibility,
2847 PartsMode,
Duration, ArchiveRequired, ArchiveOptional, SignAfter,
2848 SignBefore, CanActAsTemplate,
null, Callback, State);
2874 EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
2876 StringBuilder Xml =
new StringBuilder();
2877 uint i, c = (uint)(Parameters?.Length ?? 0);
2878 bool HasEncryptedParameters =
false;
2880 for (i = 0; i < c; i++)
2886 HasEncryptedParameters =
true;
2891 byte[] Nonce = Guid.NewGuid().ToByteArray();
2892 string NonceStr = Convert.ToBase64String(Nonce);
2895 if (HasEncryptedParameters)
2897 if (Algorithm is
null)
2900 for (i = 0; i < c; i++)
2909 Xml.Append(
"<createContract xmlns=\"");
2910 Xml.Append(NamespaceSmartContractsCurrent);
2911 Xml.Append(
"\"><template archiveOpt=\"");
2912 Xml.Append(ArchiveOptional.
ToString());
2913 Xml.Append(
"\" archiveReq=\"");
2914 Xml.Append(ArchiveRequired.
ToString());
2915 Xml.Append(
"\" canActAsTemplate=\"");
2917 Xml.Append(
"\" duration=\"");
2919 Xml.Append(
"\" id=\"");
2921 Xml.Append(
"\" nonce=\"");
2922 Xml.Append(NonceStr);
2925 if (SignAfter.HasValue && SignAfter > DateTime.MinValue)
2927 Xml.Append(
" signAfter=\"");
2928 Xml.Append(
XML.
Encode(SignAfter.Value));
2932 if (SignBefore.HasValue && SignBefore < DateTime.MaxValue)
2934 Xml.Append(
" signBefore=\"");
2935 Xml.Append(
XML.
Encode(SignBefore.Value));
2939 Xml.Append(
" visibility=\"");
2940 Xml.Append(Visibility.ToString());
2941 Xml.Append(
"\"><parts>");
2946 Xml.Append(
"<open/>");
2950 Xml.Append(
"<templateOnly/>");
2954 if (!(Parts is
null))
2958 Xml.Append(
"<part legalId=\"");
2960 Xml.Append(
"\" role=\"");
2968 Xml.Append(
"</parts>");
2970 LinkedList<Parameter> TransientParameters =
null;
2972 if (!(Parameters is
null) && Parameters.Length > 0)
2974 Xml.Append(
"<parameters>");
2981 Parameter.ProtectedValue = Guid.NewGuid().ToByteArray();
2983 if (TransientParameters is
null)
2984 TransientParameters =
new LinkedList<Parameter>();
2992 Xml.Append(
"</parameters>");
2995 Xml.Append(
"</template>");
2997 if (!(TransientParameters is
null))
2999 Xml.Append(
"<transient>");
3008 Xml.Append(
"</transient>");
3011 Xml.Append(
"</createContract>");
3013 await this.client.SendIqSet(Address, Xml.ToString(),
this.ContractResponse,
new object[] { Callback, State, HasEncryptedParameters, Algorithm?.Algorithm, Algorithm?.Key });
3034 DateTime? SignBefore,
bool CanActAsTemplate)
3036 return this.CreateContractAsync(this.componentAddress, TemplateId, Parts, Parameters, Visibility,
3037 PartsMode,
Duration, ArchiveRequired, ArchiveOptional, SignAfter, SignBefore, CanActAsTemplate);
3059 DateTime? SignAfter, DateTime? SignBefore,
bool CanActAsTemplate)
3061 TaskCompletionSource<Contract> Result =
new TaskCompletionSource<Contract>();
3063 await this.CreateContract(Address, TemplateId, Parts, Parameters, Visibility, PartsMode,
Duration,
3064 ArchiveRequired, ArchiveOptional, SignAfter, SignBefore, CanActAsTemplate, (Sender, e) =>
3067 Result.TrySetResult(e.Contract);
3069 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to create the contract."));
3071 return Task.CompletedTask;
3075 return await Result.Task;
3080 #region Get Created Contract References
3089 return this.GetCreatedContractReferences(this.componentAddress, 0,
int.MaxValue, Callback, State);
3100 return this.GetCreatedContractReferences(Address, 0,
int.MaxValue, Callback, State);
3112 return this.GetCreatedContractReferences(this.componentAddress, Offset, MaxCount, Callback, State);
3126 throw new ArgumentException(
"Offsets cannot be negative.", nameof(Offset));
3129 throw new ArgumentException(
"Must be postitive.", nameof(MaxCount));
3131 StringBuilder Xml =
new StringBuilder();
3133 Xml.Append(
"<getCreatedContracts references='true' xmlns='");
3134 Xml.Append(NamespaceSmartContractsCurrent);
3138 Xml.Append(
"' offset='");
3139 Xml.Append(Offset.ToString());
3142 if (MaxCount <
int.MaxValue)
3144 Xml.Append(
"' maxCount='");
3145 Xml.Append(MaxCount.ToString());
3150 return this.client.SendIqGet(Address, Xml.ToString(),
this.IdReferencesResponse,
new object[] { Callback, State });
3155 object[] P = (
object[])e.
State;
3156 EventHandlerAsync<IdReferencesEventArgs> Callback = (EventHandlerAsync<IdReferencesEventArgs>)P[0];
3158 List<string> IDs =
new List<string>();
3160 if (e.
Ok && !(E is
null))
3162 foreach (XmlNode N
in E.ChildNodes)
3164 if (N is XmlElement E2 && E2.LocalName ==
"ref")
3184 return this.GetCreatedContractReferencesAsync(this.componentAddress, 0,
int.MaxValue);
3194 return this.GetCreatedContractReferencesAsync(Address, 0,
int.MaxValue);
3205 return this.GetCreatedContractReferencesAsync(this.componentAddress, Offset, MaxCount);
3217 TaskCompletionSource<string[]> Result =
new TaskCompletionSource<string[]>();
3219 await this.GetCreatedContractReferences(Address, Offset, MaxCount, (Sender, e) =>
3222 Result.TrySetResult(e.References);
3224 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to get created contract references."));
3226 return Task.CompletedTask;
3230 return await Result.Task;
3235 #region Get Created Contracts
3244 return this.GetCreatedContracts(this.componentAddress, 0,
int.MaxValue, Callback, State);
3255 return this.GetCreatedContracts(Address, 0,
int.MaxValue, Callback, State);
3265 public Task
GetCreatedContracts(
int Offset,
int MaxCount, EventHandlerAsync<ContractsEventArgs> Callback,
object State)
3267 return this.GetCreatedContracts(this.componentAddress, Offset, MaxCount, Callback, State);
3278 public Task
GetCreatedContracts(
string Address,
int Offset,
int MaxCount, EventHandlerAsync<ContractsEventArgs> Callback,
object State)
3281 throw new ArgumentException(
"Offsets cannot be negative.", nameof(Offset));
3284 throw new ArgumentException(
"Must be postitive.", nameof(MaxCount));
3286 StringBuilder Xml =
new StringBuilder();
3288 Xml.Append(
"<getCreatedContracts references='false' xmlns='");
3289 Xml.Append(NamespaceSmartContractsCurrent);
3293 Xml.Append(
"' offset='");
3294 Xml.Append(Offset.ToString());
3297 if (MaxCount <
int.MaxValue)
3299 Xml.Append(
"' maxCount='");
3300 Xml.Append(MaxCount.ToString());
3305 return this.client.SendIqGet(Address, Xml.ToString(),
this.ContractsResponse,
new object[] { Callback, State });
3310 object[] P = (
object[])e.
State;
3311 EventHandlerAsync<ContractsEventArgs> Callback = (EventHandlerAsync<ContractsEventArgs>)P[0];
3313 List<Contract> Contracts =
new List<Contract>();
3314 List<string> References =
new List<string>();
3316 if (e.
Ok && !(E is
null))
3318 foreach (XmlNode N
in E.ChildNodes)
3320 if (N is XmlElement E2)
3322 switch (E2.LocalName)
3333 References.Add(ContractId);
3343 await Callback.Raise(
this,
new ContractsEventArgs(e, Contracts.ToArray(), References.ToArray()));
3352 return this.GetCreatedContractsAsync(this.componentAddress, 0,
int.MaxValue);
3362 return this.GetCreatedContractsAsync(Address, 0,
int.MaxValue);
3373 return this.GetCreatedContractsAsync(this.componentAddress, Offset, MaxCount);
3385 TaskCompletionSource<ContractsEventArgs> Result =
new TaskCompletionSource<ContractsEventArgs>();
3387 await this.GetCreatedContracts(Address, Offset, MaxCount, (Sender, e) =>
3389 Result.TrySetResult(e);
3390 return Task.CompletedTask;
3394 return await Result.Task;
3399 #region Sign Contract
3428 EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
3432 Tuple<SymmetricCipherAlgorithms, string, byte[]> T = await this.TryLoadContractSharedSecret(
Contract.
ContractId);
3442 StringBuilder Xml =
new StringBuilder();
3444 byte[] Data = Encoding.UTF8.GetBytes(Xml.ToString());
3446 await this.Sign(Address, Data,
SignWith.LatestApprovedId, async (Sender, e) =>
3451 Xml.Append(
"<signContract xmlns='");
3452 Xml.Append(NamespaceSmartContractsCurrent);
3453 Xml.Append(
"' id='");
3454 Xml.Append(XML.Encode(Contract.ContractId));
3455 Xml.Append(
"' role='");
3456 Xml.Append(XML.Encode(Role));
3459 Xml.Append(
"' transferable='true");
3461 Xml.Append(
"' s='");
3462 Xml.Append(Convert.ToBase64String(e.Signature));
3465 await this.client.SendIqSet(Address, Xml.ToString(), this.ContractResponse, new object[] { Callback, State });
3498 TaskCompletionSource<Contract> Result =
new TaskCompletionSource<Contract>();
3500 await this.SignContract(Address,
Contract,
Role, Transferable, (Sender, e) =>
3503 Result.TrySetResult(e.Contract);
3505 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to sign the contract."));
3507 return Task.CompletedTask;
3511 return await Result.Task;
3516 #region Get Signed Contract References
3525 return this.GetSignedContractReferences(this.componentAddress, 0,
int.MaxValue, Callback, State);
3536 return this.GetSignedContractReferences(Address, 0,
int.MaxValue, Callback, State);
3550 throw new ArgumentException(
"Offsets cannot be negative.", nameof(Offset));
3553 throw new ArgumentException(
"Must be postitive.", nameof(MaxCount));
3555 StringBuilder Xml =
new StringBuilder();
3557 Xml.Append(
"<getSignedContracts references='true' xmlns='");
3558 Xml.Append(NamespaceSmartContractsCurrent);
3562 Xml.Append(
"' offset='");
3563 Xml.Append(Offset.ToString());
3566 if (MaxCount <
int.MaxValue)
3568 Xml.Append(
"' maxCount='");
3569 Xml.Append(MaxCount.ToString());
3574 return this.client.SendIqGet(Address, Xml.ToString(),
this.IdReferencesResponse,
new object[] { Callback, State });
3583 return this.GetSignedContractReferencesAsync(this.componentAddress, 0,
int.MaxValue);
3594 return this.GetSignedContractReferencesAsync(this.componentAddress, Offset, MaxCount);
3606 TaskCompletionSource<string[]> Result =
new TaskCompletionSource<string[]>();
3608 await this.GetSignedContractReferences(Address, Offset, MaxCount, (Sender, e) =>
3611 Result.TrySetResult(e.References);
3613 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to get signed contract references."));
3615 return Task.CompletedTask;
3619 return await Result.Task;
3624 #region Get Signed Contracts
3633 return this.GetSignedContracts(this.componentAddress, 0,
int.MaxValue, Callback, State);
3642 public Task
GetSignedContracts(
string Address, EventHandlerAsync<ContractsEventArgs> Callback,
object State)
3644 return this.GetSignedContracts(Address, 0,
int.MaxValue, Callback, State);
3654 public Task
GetSignedContracts(
int Offset,
int MaxCount, EventHandlerAsync<ContractsEventArgs> Callback,
object State)
3656 return this.GetSignedContracts(this.componentAddress, Offset, MaxCount, Callback, State);
3667 public Task
GetSignedContracts(
string Address,
int Offset,
int MaxCount, EventHandlerAsync<ContractsEventArgs> Callback,
object State)
3670 throw new ArgumentException(
"Offsets cannot be negative.", nameof(Offset));
3673 throw new ArgumentException(
"Must be postitive.", nameof(MaxCount));
3675 StringBuilder Xml =
new StringBuilder();
3677 Xml.Append(
"<getSignedContracts references='false' xmlns='");
3678 Xml.Append(NamespaceSmartContractsCurrent);
3682 Xml.Append(
"' offset='");
3683 Xml.Append(Offset.ToString());
3686 if (MaxCount <
int.MaxValue)
3688 Xml.Append(
"' maxCount='");
3689 Xml.Append(MaxCount.ToString());
3694 return this.client.SendIqGet(Address, Xml.ToString(),
this.ContractsResponse,
new object[] { Callback, State });
3703 return this.GetSignedContractsAsync(this.componentAddress, 0,
int.MaxValue);
3714 return this.GetSignedContractsAsync(this.componentAddress, Offset, MaxCount);
3726 TaskCompletionSource<ContractsEventArgs> Result =
new TaskCompletionSource<ContractsEventArgs>();
3728 await this.GetSignedContracts(Address, Offset, MaxCount, (Sender, e) =>
3730 Result.TrySetResult(e);
3731 return Task.CompletedTask;
3735 return await Result.Task;
3740 #region Contract Signature event
3742 private Task ContractSignedMessageHandler(
object Sender,
MessageEventArgs e)
3754 public event EventHandlerAsync<ContractSignedEventArgs> ContractSigned =
null;
3758 #region Get Contract
3766 public Task
GetContract(
string ContractId, EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
3768 return this.GetContract(this.GetTrustProvider(ContractId), ContractId, Callback, State);
3778 public Task
GetContract(
string Address,
string ContractId, EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
3780 StringBuilder Xml =
new StringBuilder();
3782 Xml.Append(
"<getContract xmlns='");
3783 Xml.Append(NamespaceSmartContractsCurrent);
3784 Xml.Append(
"' id='");
3788 return this.client.SendIqGet(Address, Xml.ToString(),
this.ContractResponse,
new object[] { Callback, State });
3798 return this.GetContractAsync(this.GetTrustProvider(ContractId), ContractId);
3809 TaskCompletionSource<Contract> Result =
new TaskCompletionSource<Contract>();
3811 await this.GetContract(Address, ContractId, (Sender, e) =>
3814 Result.TrySetResult(e.Contract);
3816 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to get the contract."));
3818 return Task.CompletedTask;
3822 return await Result.Task;
3827 #region Get Contracts
3835 public async Task
GetContracts(
string[] ContractIds, EventHandlerAsync<ContractsEventArgs> Callback,
object State)
3837 Dictionary<string, List<string>> ByTrustProvider =
new Dictionary<string, List<string>>();
3838 string LastTrustProvider =
string.Empty;
3839 List<string> LastList =
null;
3841 foreach (
string ContractId
in ContractIds)
3843 string TrustProvider = this.GetTrustProvider(ContractId);
3845 if (TrustProvider != LastTrustProvider || LastList is
null)
3847 if (!ByTrustProvider.TryGetValue(TrustProvider, out LastList))
3849 LastList =
new List<string>();
3850 ByTrustProvider[TrustProvider] = LastList;
3853 LastTrustProvider = TrustProvider;
3856 LastList.Add(ContractId);
3859 List<Contract> Contracts =
new List<Contract>();
3860 List<string> References =
new List<string>();
3862 int NrLeft = ByTrustProvider.Count;
3864 foreach (KeyValuePair<
string, List<string>> P
in ByTrustProvider)
3866 await this.GetContracts(P.Key, P.Value.ToArray(), async (Sender, e) =>
3872 Contracts.AddRange(e.Contracts);
3873 References.AddRange(e.References);
3888 await Callback.Raise(
this, e2);
3901 public Task
GetContracts(
string Address,
string[] ContractIds, EventHandlerAsync<ContractsEventArgs> Callback,
object State)
3903 StringBuilder Xml =
new StringBuilder();
3905 Xml.Append(
"<getContracts xmlns='");
3906 Xml.Append(NamespaceSmartContractsCurrent);
3909 foreach (
string ContractId
in ContractIds)
3911 Xml.Append(
"<ref id='");
3916 Xml.Append(
"</getContracts>");
3918 return this.client.SendIqGet(Address, Xml.ToString(),
this.ContractsResponse,
new object[] { Callback, State });
3928 TaskCompletionSource<ContractsEventArgs> Result =
new TaskCompletionSource<ContractsEventArgs>();
3930 await this.GetContracts(ContractIds, (Sender, e) =>
3932 Result.TrySetResult(e);
3933 return Task.CompletedTask;
3937 return await Result.Task;
3948 TaskCompletionSource<ContractsEventArgs> Result =
new TaskCompletionSource<ContractsEventArgs>();
3950 await this.GetContracts(Address, ContractIds, (Sender, e) =>
3952 Result.TrySetResult(e);
3953 return Task.CompletedTask;
3957 return await Result.Task;
3962 #region Obsolete Contract
3970 public Task
ObsoleteContract(
string ContractId, EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
3972 return this.ObsoleteContract(this.GetTrustProvider(ContractId), ContractId, Callback, State);
3983 EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
3985 StringBuilder Xml =
new StringBuilder();
3987 Xml.Append(
"<obsoleteContract xmlns='");
3988 Xml.Append(NamespaceSmartContractsCurrent);
3989 Xml.Append(
"' id='");
3993 return this.client.SendIqSet(Address, Xml.ToString(),
this.ContractResponse,
new object[] { Callback, State });
4003 return this.ObsoleteContractAsync(this.GetTrustProvider(ContractId), ContractId);
4014 TaskCompletionSource<Contract> Result =
new TaskCompletionSource<Contract>();
4016 await this.ObsoleteContract(Address, ContractId, (Sender, e) =>
4019 Result.TrySetResult(e.Contract);
4021 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to obsolete the contract."));
4023 return Task.CompletedTask;
4027 return await Result.Task;
4032 #region Delete Contract
4040 public Task
DeleteContract(
string ContractId, EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
4042 return this.DeleteContract(this.GetTrustProvider(ContractId), ContractId, Callback, State);
4053 EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
4055 StringBuilder Xml =
new StringBuilder();
4057 Xml.Append(
"<deleteContract xmlns='");
4058 Xml.Append(NamespaceSmartContractsCurrent);
4059 Xml.Append(
"' id='");
4063 return this.client.SendIqSet(Address, Xml.ToString(),
this.ContractResponse,
new object[] { Callback, State });
4073 return this.DeleteContractAsync(this.GetTrustProvider(ContractId), ContractId);
4084 TaskCompletionSource<Contract> Result =
new TaskCompletionSource<Contract>();
4086 await this.DeleteContract(Address, ContractId, (Sender, e) =>
4089 Result.TrySetResult(e.Contract);
4091 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to delete the contract."));
4093 return Task.CompletedTask;
4097 return await Result.Task;
4102 #region Contract Created event
4104 private Task ContractCreatedMessageHandler(
object Sender,
MessageEventArgs e)
4108 if (!this.IsFromTrustProvider(ContractId, e.
From))
4109 return Task.CompletedTask;
4117 public event EventHandlerAsync<ContractReferenceEventArgs> ContractCreated =
null;
4121 #region Contract Updated event
4123 private Task ContractUpdatedMessageHandler(
object Sender,
MessageEventArgs e)
4127 if (!this.IsFromTrustProvider(ContractId, e.
From))
4128 return Task.CompletedTask;
4136 public event EventHandlerAsync<ContractReferenceEventArgs> ContractUpdated =
null;
4140 #region Contract Deleted event
4142 private Task ContractDeletedMessageHandler(
object Sender,
MessageEventArgs e)
4146 if (!this.IsFromTrustProvider(ContractId, e.
From))
4147 return Task.CompletedTask;
4155 public event EventHandlerAsync<ContractReferenceEventArgs> ContractDeleted =
null;
4159 #region Update Contract
4180 EventHandlerAsync<SmartContractEventArgs> Callback,
object State)
4184 Tuple<SymmetricCipherAlgorithms, string, byte[]> KeyInfo =
4187 if (!(KeyInfo is
null))
4196 StringBuilder Xml =
new StringBuilder();
4198 Xml.Append(
"<updateContract xmlns='");
4199 Xml.Append(NamespaceSmartContractsCurrent);
4204 Xml.Append(
"</updateContract>");
4206 await this.client.SendIqSet(Address, Xml.ToString(),
this.ContractResponse,
new object[] { Callback, State });
4227 TaskCompletionSource<Contract> Result =
new TaskCompletionSource<Contract>();
4229 await this.UpdateContract(Address,
Contract, (Sender, e) =>
4232 Result.TrySetResult(e.Contract);
4234 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to update the contract."));
4236 return Task.CompletedTask;
4240 return await Result.Task;
4245 #region Validate Contract
4255 return this.Validate(
Contract,
true, Callback, State);
4265 public async Task
Validate(
Contract Contract,
bool ValidateState, EventHandlerAsync<ContractValidationEventArgs> Callback,
object State)
4269 await this.ReturnStatus(
ContractStatus.ContractUndefined, Callback, State);
4273 if (ValidateState &&
4278 await this.ReturnStatus(
ContractStatus.NotApproved, Callback, State);
4282 DateTime Now = DateTime.Now;
4286 await this.ReturnStatus(
ContractStatus.NotValidYet, Callback, State);
4292 await this.ReturnStatus(
ContractStatus.NotValidAnymore, Callback, State);
4298 await this.ReturnStatus(
ContractStatus.NoTrustProvider, Callback, State);
4304 await this.ReturnStatus(
ContractStatus.TemplateOnly, Callback, State);
4310 await this.ReturnStatus(
ContractStatus.NoClientSignatures, Callback, State);
4316 await this.ReturnStatus(
ContractStatus.NotLegallyBinding, Callback, State);
4320 if (!await IsHumanReadableWellDefined(
Contract))
4322 await this.ReturnStatus(
ContractStatus.HumanReadableNotWellDefined, Callback, State);
4332 {
"Duration", Contract.Duration }
4342 await this.ReturnStatus(
ContractStatus.ParameterValuesNotValid, Callback, State);
4349 await this.ReturnStatus(
ContractStatus.ParameterValuesNotValid, Callback, State);
4360 await this.ReturnStatus(
ContractStatus.MachineReadableNotWellDefined, Callback, State);
4368 Doc =
new XmlDocument()
4370 PreserveWhitespace =
true
4377 await this.ReturnStatus(
ContractStatus.MachineReadableNotWellDefined, Callback, State);
4381 Dictionary<string, XmlSchema> Schemas =
new Dictionary<string, XmlSchema>();
4382 LinkedList<XmlNode> ToCheck =
new LinkedList<XmlNode>();
4384 ToCheck.AddLast(Doc.DocumentElement);
4386 while (!(ToCheck.First is
null))
4388 XmlNode N = ToCheck.First.Value;
4389 ToCheck.RemoveFirst();
4391 while (!(N is
null))
4393 if (N is XmlElement E)
4395 if (!
string.IsNullOrEmpty(E.NamespaceURI))
4396 Schemas[E.NamespaceURI] =
null;
4398 foreach (XmlNode N2
in E.ChildNodes)
4399 ToCheck.AddLast(N2);
4406 int NrSchemas = Schemas.Count;
4409 await this.ReturnStatus(
ContractStatus.MachineReadableNotWellDefined, Callback, State);
4419 if (this.schemas.TryGetValue(SchemaKey, out KeyValuePair<
byte[], XmlSchema> P))
4431 if (!(Schema is
null))
4434 string[] Namespaces =
new string[Schemas.Count];
4435 Schemas.Keys.CopyTo(Namespaces, 0);
4437 string ContractComponent;
4440 ContractComponent = this.componentAddress;
4444 foreach (
string Namespace
in Namespaces)
4446 if (Schemas.TryGetValue(Namespace, out Schema) && !(Schema is
null))
4449 TaskCompletionSource<ContractStatus> T =
new TaskCompletionSource<ContractStatus>();
4457 await this.GetSchema(ContractComponent, Namespace,
SchemaDigest, (_, e) =>
4463 SchemaBin = e.Schema;
4464 using (MemoryStream ms = new MemoryStream(SchemaBin))
4466 Schema = XSL.LoadSchema(ms, string.Empty);
4469 Schemas[Namespace] = Schema;
4471 if (Namespace == Contract.ForMachinesNamespace)
4473 byte[] Digest = Hashes.ComputeHash(Contract.ContentSchemaHashFunction, SchemaBin);
4475 if (Convert.ToBase64String(Digest) != Convert.ToBase64String(Contract.ContentSchemaDigest))
4477 T.TrySetResult(ContractStatus.FraudulentSchema);
4478 return Task.CompletedTask;
4483 this.schemas[SchemaKey] = new KeyValuePair<byte[], XmlSchema>(SchemaBin, Schema);
4490 this.schemas[Namespace] = new KeyValuePair<byte[], XmlSchema>(SchemaBin, Schema);
4494 T.TrySetResult(ContractStatus.Valid);
4504 return Task.CompletedTask;
4510 await this.ReturnStatus(Temp, Callback, State);
4517 XmlSchema[] Schemas2 =
new XmlSchema[Schemas.Count];
4518 Schemas.Values.CopyTo(Schemas2, 0);
4524 await this.ReturnStatus(
ContractStatus.FraudulentMachineReadable, Callback, State);
4528 StringBuilder Xml =
new StringBuilder();
4530 byte[] Data = Encoding.UTF8.GetBytes(Xml.ToString());
4531 Dictionary<string, LegalIdentity> Identities =
new Dictionary<string, LegalIdentity>();
4536 if (Identity is
null)
4538 await this.ReturnStatus(
ContractStatus.ClientSignatureInvalid, Callback, State);
4545 await this.ReturnStatus(
ContractStatus.ClientIdentityInvalid, Callback, State);
4549 Identities[
Signature.LegalId] = Identity;
4558 await this.ReturnStatus(
ContractStatus.AttachmentLacksUrl, Callback, State);
4564 KeyValuePair<string, TemporaryFile> P = await this.GetAttachmentAsync(
Attachment.
Url,
SignWith.LatestApprovedId, 30000);
4571 await this.ReturnStatus(
ContractStatus.AttachmentInconsistency, Callback, State);
4581 MemoryStream ms =
new MemoryStream();
4582 await File.CopyToAsync(ms);
4583 Data = ms.ToArray();
4597 if (IsValid.HasValue)
4601 await this.ReturnStatus(
ContractStatus.AttachmentSignatureInvalid, Callback, State);
4607 await this.ReturnStatus(
ContractStatus.AttachmentSignatureInvalid, Callback, State);
4614 await this.ReturnStatus(
ContractStatus.AttachmentUnavailable, Callback, State);
4622 await this.ReturnStatus(
ContractStatus.NoProviderSignature, Callback, State);
4628 Data = Encoding.UTF8.GetBytes(Xml.ToString());
4630 bool HasOldPublicKey;
4632 lock (this.publicKeys)
4639 if (e.
Ok && !(e.Key is
null))
4641 bool Valid = e.Key.Verify(Data, Contract.ServerSignature.DigitalSignature);
4646 await this.ReturnStatus(ContractStatus.Valid, Callback, State);
4650 if (!HasOldPublicKey)
4652 await this.ReturnStatus(
ContractStatus.ProviderSignatureInvalid, Callback, State);
4656 lock (this.publicKeys)
4663 if (e2.Ok && !(e2.Key is null))
4665 if (e.Key.Equals(e2.Key))
4666 return this.ReturnStatus(ContractStatus.ProviderSignatureInvalid, Callback, State);
4668 Valid = e2.Key.Verify(Data, Contract.ServerSignature.DigitalSignature);
4671 return this.ReturnStatus(ContractStatus.Valid, Callback, State);
4673 return this.ReturnStatus(ContractStatus.ProviderSignatureInvalid, Callback, State);
4676 return this.ReturnStatus(
ContractStatus.NoProviderPublicKey, Callback, State);
4681 await this.ReturnStatus(
ContractStatus.NoProviderPublicKey, Callback, State);
4686 private readonly Dictionary<string, KeyValuePair<byte[], XmlSchema>> schemas =
new Dictionary<string, KeyValuePair<byte[], XmlSchema>>();
4688 private Task ReturnStatus(
ContractStatus Status, EventHandlerAsync<ContractValidationEventArgs> Callback,
object State)
4693 private static async Task<bool> IsHumanReadableWellDefined(
HumanReadableText[] Texts)
4707 private static async Task<bool> IsHumanReadableWellDefined(
Contract Contract)
4740 return this.ValidateAsync(
Contract,
true);
4751 TaskCompletionSource<ContractStatus> Result =
new TaskCompletionSource<ContractStatus>();
4753 await this.Validate(
Contract, ValidateState, (Sender, e) =>
4755 Result.TrySetResult(e.Status);
4756 return Task.CompletedTask;
4759 return await Result.Task;
4778 if (ReferenceDomain != SignatoryDomain)
4781 TaskCompletionSource<bool> Result =
new TaskCompletionSource<bool>();
4782 StringBuilder Xml =
new StringBuilder();
4784 Xml.Append(
"<canSignAs xmlns='");
4785 Xml.Append(NamespaceLegalIdentitiesCurrent);
4786 Xml.Append(
"' referenceId='");
4788 Xml.Append(
"' signatoryId='");
4792 await this.client.SendIqGet(ReferenceDomain, Xml.ToString(), (_, e) =>
4794 Result.TrySetResult(e.Ok);
4795 return Task.CompletedTask;
4798 return await Result.Task;
4803 #region SendContractProposal
4814 return this.SendContractProposal(
Contract,
Role, To,
string.Empty);
4829 Tuple<SymmetricCipherAlgorithms, string, byte[]> T = await this.TryLoadContractSharedSecret(
Contract.
ContractId);
4849 return this.SendContractProposal(ContractId,
Role, To,
string.Empty);
4876 StringBuilder Xml =
new StringBuilder();
4878 Xml.Append(
"<contractProposal xmlns=\"");
4879 Xml.Append(NamespaceSmartContractsCurrent);
4880 Xml.Append(
"\" contractId=\"");
4882 Xml.Append(
"\" role=\"");
4885 if (!
string.IsNullOrEmpty(Message))
4887 Xml.Append(
"\" message=\"");
4897 if (this.localE2eEndpoint is
null)
4899 await this.client.SendMessage(
MessageType.Normal, To, Xml.ToString(),
string.Empty,
string.Empty,
string.Empty,
4900 string.Empty,
string.Empty);
4905 string.Empty, To, Xml.ToString(),
string.Empty,
string.Empty,
string.Empty,
string.Empty,
string.Empty,
null,
null);
4910 Xml.Append(
"><sharedSecret key=\"");
4911 Xml.Append(Convert.ToBase64String(Key));
4912 Xml.Append(
"\" algorithm=\"");
4914 switch (KeyAlgorithm)
4929 throw new ArgumentException(
"Algorithm not recognized.", nameof(KeyAlgorithm));
4932 Xml.Append(
"\"/></contractProposal>");
4934 if (this.localE2eEndpoint is
null)
4935 throw new InvalidOperationException(
"End-to-End encryption not enabled.");
4940 ??
throw new ArgumentException(
"Recipient not in roster.", nameof(To));
4943 if (
string.IsNullOrEmpty(To))
4944 throw new ArgumentException(
"Recipient not online.", nameof(To));
4948 string.Empty, To, Xml.ToString(),
string.Empty,
string.Empty,
string.Empty,
string.Empty,
string.Empty,
null,
null);
4952 private async Task ContractProposalMessageHandler(
object Sender,
MessageEventArgs e)
4960 foreach (XmlNode N
in e.
Content.ChildNodes)
4962 if (N is XmlElement E && E.LocalName ==
"sharedSecret" && E.NamespaceURI == e.
Content.NamespaceURI)
4966 await this.client.Error(
"Confidential Proposal not sent using end-to-end encryption. Message discarded.");
4972 Key = Convert.FromBase64String(
XML.
Attribute(E,
"key"));
4976 await this.client.Error(
"Invalid base64-encoded shared secret. Message discarded.");
4997 await this.client.Error(
"Unrecognized key algorithm. Message discarded.");
5004 await this.SaveContractSharedSecret(ContractId, e.
FromBareJID, Key, KeyAlgorithm,
true);
5009 internal async Task<bool> SaveContractSharedSecret(
string ContractId,
string CreatorJid,
byte[] Key,
5012 string Name = this.contractKeySettingsPrefix + ContractId;
5017 if (!
string.IsNullOrEmpty(s))
5021 string Value = KeyAlgorithm.ToString() +
"|" + CreatorJid +
"|" + Convert.ToBase64String(Key);
5028 internal async Task<Tuple<SymmetricCipherAlgorithms, string, byte[]>> TryLoadContractSharedSecret(
string ContractId)
5030 string Name = this.contractKeySettingsPrefix + ContractId;
5033 if (
string.IsNullOrEmpty(s))
5036 string[] Parts = s.Split(
'|');
5037 if (Parts.Length != 3)
5043 string CreatorJid = Parts[1];
5048 Key = Convert.FromBase64String(Parts[2]);
5055 return new Tuple<SymmetricCipherAlgorithms, string, byte[]>(Algorithm, CreatorJid, Key);
5061 public event EventHandlerAsync<ContractProposalEventArgs> ContractProposalReceived =
null;
5072 public Task
GetSchemas(EventHandlerAsync<SchemaReferencesEventArgs> Callback,
object State)
5074 return this.GetSchemas(this.componentAddress, Callback, State);
5083 public Task
GetSchemas(
string Address, EventHandlerAsync<SchemaReferencesEventArgs> Callback,
object State)
5085 return this.client.SendIqGet(Address,
"<getSchemas xmlns='" + NamespaceSmartContractsCurrent +
"'/>",
5086 async (Sender, e) =>
5088 XmlElement E = e.FirstElement;
5089 List<SchemaReference> Schemas =
new List<SchemaReference>();
5091 if (e.
Ok && !(E is
null) && E.LocalName ==
"schemas")
5093 foreach (XmlNode N
in E.ChildNodes)
5095 if (N is XmlElement E2 && E2.LocalName ==
"schemaRef")
5098 List<SchemaDigest> Digests =
new List<SchemaDigest>();
5100 foreach (XmlNode N2
in E2.ChildNodes)
5102 if (N2 is XmlElement E3 && E3.LocalName ==
"digest")
5107 byte[] Digest = Convert.FromBase64String(E3.InnerText);
5131 return this.GetSchemasAsync(this.componentAddress);
5141 TaskCompletionSource<SchemaReference[]> Result =
new TaskCompletionSource<SchemaReference[]>();
5143 await this.GetSchemas(Address, (Sender, e) =>
5146 Result.TrySetResult(e.References);
5148 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to get schemas."));
5150 return Task.CompletedTask;
5154 return await Result.Task;
5167 public Task
GetSchema(
string Namespace, EventHandlerAsync<SchemaEventArgs> Callback,
object State)
5169 return this.GetSchema(this.componentAddress, Namespace,
null, Callback, State);
5181 return this.GetSchema(this.componentAddress, Namespace, Digest, Callback, State);
5191 public Task
GetSchema(
string Address,
string Namespace, EventHandlerAsync<SchemaEventArgs> Callback,
object State)
5193 return this.GetSchema(Address, Namespace,
null, Callback, State);
5204 public Task
GetSchema(
string Address,
string Namespace,
SchemaDigest Digest, EventHandlerAsync<SchemaEventArgs> Callback,
object State)
5206 StringBuilder Xml =
new StringBuilder();
5208 Xml.Append(
"<getSchema xmlns='");
5209 Xml.Append(NamespaceSmartContractsCurrent);
5210 Xml.Append(
"' namespace='");
5217 Xml.Append(
"'><digest function='");
5218 Xml.Append(Digest.
Function.ToString());
5220 Xml.Append(Convert.ToBase64String(Digest.
Digest));
5221 Xml.Append(
"</digest></getSchema>");
5224 return this.client.SendIqGet(Address, Xml.ToString(),
5225 async (Sender, e) =>
5227 XmlElement E = e.FirstElement;
5228 byte[] Schema =
null;
5230 if (e.
Ok && !(E is
null) && E.LocalName ==
"schema")
5231 Schema = Convert.FromBase64String(E.InnerText);
5247 return this.GetSchemaAsync(this.componentAddress, Namespace,
null);
5258 return this.GetSchemaAsync(this.componentAddress, Namespace, Digest);
5269 return this.GetSchemaAsync(Address, Namespace,
null);
5281 TaskCompletionSource<byte[]> Result =
new TaskCompletionSource<byte[]>();
5283 await this.GetSchema(Address, Namespace, Digest, (Sender, e) =>
5286 Result.TrySetResult(e.Schema);
5288 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to get schema."));
5290 return Task.CompletedTask;
5294 return await Result.Task;
5299 #region Get Legal Identities of a contract
5309 return this.GetContractLegalIdentities(this.GetTrustProvider(ContractId), ContractId,
false,
true, Callback, State);
5320 public Task
GetContractLegalIdentities(
string ContractId,
bool Current,
bool Historic, EventHandlerAsync<LegalIdentitiesEventArgs> Callback,
object State)
5322 return this.GetContractLegalIdentities(this.GetTrustProvider(ContractId), ContractId, Current, Historic, Callback, State);
5334 return this.GetContractLegalIdentities(Address, ContractId,
false,
true, Callback, State);
5346 public Task
GetContractLegalIdentities(
string Address,
string ContractId,
bool Current,
bool Historic, EventHandlerAsync<LegalIdentitiesEventArgs> Callback,
object State)
5348 StringBuilder Xml =
new StringBuilder();
5350 Xml.Append(
"<getLegalIdentities xmlns='");
5351 Xml.Append(NamespaceSmartContractsCurrent);
5352 Xml.Append(
"' contractId='");
5354 Xml.Append(
"' current='");
5356 Xml.Append(
"' historic='");
5360 return this.client.SendIqGet(Address, Xml.ToString(),
this.IdentitiesResponse,
new object[] { Callback, State });
5370 return this.GetContractLegalIdentitiesAsync(this.GetTrustProvider(ContractId), ContractId,
false,
true);
5382 return this.GetContractLegalIdentitiesAsync(this.GetTrustProvider(ContractId), ContractId, Current, Historic);
5393 return this.GetContractLegalIdentitiesAsync(Address, ContractId,
false,
true);
5406 TaskCompletionSource<LegalIdentity[]> Result =
new TaskCompletionSource<LegalIdentity[]>();
5408 await this.GetContractLegalIdentities(Address, ContractId, Current, Historic, (Sender, e) =>
5411 Result.TrySetResult(e.Identities);
5413 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to get legal identities."));
5415 return Task.CompletedTask;
5419 return await Result.Task;
5424 #region Get Network Identities of a contract
5434 return this.GetContractNetworkIdentities(this.GetTrustProvider(ContractId), ContractId, Callback, State);
5446 StringBuilder Xml =
new StringBuilder();
5448 Xml.Append(
"<getNetworkIdentities xmlns='");
5449 Xml.Append(NamespaceSmartContractsCurrent);
5450 Xml.Append(
"' contractId='");
5454 return this.client.SendIqGet(Address, Xml.ToString(), async (Sender, e) =>
5459 if (e.
Ok && !((E = e.FirstElement) is
null) && E.LocalName ==
"networkIdentities")
5461 List<NetworkIdentity> IdentitiesList = new List<NetworkIdentity>();
5463 foreach (XmlNode N in E.ChildNodes)
5465 if (N is XmlElement E2 && E2.LocalName ==
"networkIdentity")
5467 string BareJid = XML.Attribute(E2,
"bareJid");
5468 string LegalId = XML.Attribute(E2,
"legalId");
5470 IdentitiesList.Add(new NetworkIdentity(BareJid, LegalId));
5474 Identities = IdentitiesList.ToArray();
5490 return this.GetContractNetworkIdentitiesAsync(this.GetTrustProvider(ContractId), ContractId);
5501 TaskCompletionSource<NetworkIdentity[]> Result =
new TaskCompletionSource<NetworkIdentity[]>();
5503 await this.GetContractNetworkIdentities(Address, ContractId, (Sender, e) =>
5506 Result.TrySetResult(e.Identities);
5508 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to get network identities."));
5510 return Task.CompletedTask;
5514 return await Result.Task;
5519 #region Search Public Contracts
5529 return this.Search(this.componentAddress, 0,
int.MaxValue,
Filter, Callback, State);
5541 return this.Search(Address, 0,
int.MaxValue,
Filter, Callback, State);
5554 return this.Search(this.componentAddress, Offset, MaxCount,
Filter, Callback, State);
5566 public Task
Search(
string Address,
int Offset,
int MaxCount,
SearchFilter[]
Filter, EventHandlerAsync<SearchResultEventArgs> Callback,
object State)
5569 throw new ArgumentException(
"Offsets cannot be negative.", nameof(Offset));
5572 throw new ArgumentException(
"Must be postitive.", nameof(MaxCount));
5574 StringBuilder Xml =
new StringBuilder();
5576 Xml.Append(
"<searchPublicContracts xmlns='");
5577 Xml.Append(NamespaceSmartContractsCurrent);
5581 Xml.Append(
"' offset='");
5582 Xml.Append(Offset.ToString());
5585 if (MaxCount <
int.MaxValue)
5587 Xml.Append(
"' maxCount='");
5588 Xml.Append(MaxCount.ToString());
5594 Array.Sort(
Filter, (f1, f2) => f1.Order - f2.Order);
5597 int PrevOrderCount = 0;
5603 if (Order != PrevOrder)
5611 if (PrevOrderCount >= F.MaxOccurs)
5613 throw new ArgumentException(
"Maximum number of occurrences of " + F.GetType().FullName +
" in a search is " +
5614 F.MaxOccurs.ToString() +
".", nameof(
Filter));
5621 Xml.Append(
"</searchPublicContracts>");
5623 return this.client.SendIqGet(Address, Xml.ToString(), async (Sender, e) =>
5625 XmlElement E = e.FirstElement;
5626 List<string> IDs =
null;
5629 if (e.
Ok && !(E is
null) && E.LocalName ==
"searchResult")
5631 More = XML.Attribute(E,
"more", false);
5632 IDs = new List<string>();
5634 foreach (XmlNode N in E.ChildNodes)
5636 if (N is XmlElement E2 && E2.LocalName ==
"ref")
5638 string Id = XML.Attribute(E2,
"id");
5657 return this.SearchAsync(this.componentAddress, 0,
int.MaxValue,
Filter);
5667 return this.SearchAsync(Address, 0,
int.MaxValue,
Filter);
5678 return this.SearchAsync(this.componentAddress, Offset, MaxCount,
Filter);
5690 TaskCompletionSource<SearchResultEventArgs> Result =
new TaskCompletionSource<SearchResultEventArgs>();
5692 await this.Search(Address, Offset, MaxCount,
Filter, (Sender, e) =>
5694 Result.TrySetResult(e);
5695 return Task.CompletedTask;
5698 return await Result.Task;
5703 #region Identity petitions
5717 return this.PetitionIdentityAsync(this.GetTrustProvider(LegalId), LegalId, PetitionId, Purpose,
null);
5733 return this.PetitionIdentityAsync(Address, LegalId, PetitionId, Purpose,
null);
5748 public async Task
PetitionIdentityAsync(
string Address,
string LegalId,
string PetitionId,
string Purpose,
string ContextXml)
5750 StringBuilder Xml =
new StringBuilder();
5751 byte[] Nonce = this.RandomBytes(32);
5753 string NonceStr = Convert.ToBase64String(Nonce);
5754 byte[] Data = Encoding.UTF8.GetBytes(PetitionId +
":" + LegalId +
":" + Purpose +
":" + NonceStr +
":" + this.client.BareJID.ToLower());
5757 Xml.Append(
"<petitionIdentity xmlns='");
5758 Xml.Append(NamespaceLegalIdentitiesCurrent);
5759 Xml.Append(
"' id='");
5761 Xml.Append(
"' pid='");
5763 Xml.Append(
"' purpose='");
5765 Xml.Append(
"' nonce='");
5766 Xml.Append(NonceStr);
5767 Xml.Append(
"' s='");
5768 Xml.Append(Convert.ToBase64String(
Signature));
5770 if (
string.IsNullOrEmpty(ContextXml))
5775 Xml.Append(ContextXml);
5776 Xml.Append(
"</petitionIdentity>");
5779 await this.client.IqSetAsync(Address, Xml.ToString());
5794 return this.PetitionIdentityResponseAsync(this.GetTrustProvider(LegalId), LegalId, PetitionId, RequestorFullJid, Response,
null);
5810 return this.PetitionIdentityResponseAsync(this.GetTrustProvider(LegalId), LegalId, PetitionId, RequestorFullJid, Response, ContextXml);
5826 return this.PetitionIdentityResponseAsync(Address, LegalId, PetitionId, RequestorFullJid, Response,
null);
5844 StringBuilder Xml =
new StringBuilder();
5846 Xml.Append(
"<petitionIdentityResponse xmlns='");
5847 Xml.Append(NamespaceLegalIdentitiesCurrent);
5848 Xml.Append(
"' id='");
5850 Xml.Append(
"' pid='");
5852 Xml.Append(
"' jid='");
5853 Xml.Append(
XML.
Encode(RequestorFullJid));
5854 Xml.Append(
"' response='");
5857 if (
string.IsNullOrEmpty(ContextXml))
5862 Xml.Append(ContextXml);
5863 Xml.Append(
"</petitionIdentityResponse>");
5866 await this.client.IqSetAsync(Address, Xml.ToString());
5869 private async Task PetitionIdentityMessageHandler(
object Sender,
MessageEventArgs e)
5877 XmlElement Context =
null;
5879 foreach (XmlNode N
in e.
Content.ChildNodes)
5881 if (N is XmlElement E)
5883 if (E.LocalName ==
"identity" && E.NamespaceURI == e.
Content.NamespaceURI)
5885 else if (!(Context is
null))
5892 if (Identity is
null)
5895 if (
string.Compare(e.
FromBareJID,
this.componentAddress,
true) == 0)
5897 await this.Validate(Identity,
false, async (sender2, e2) =>
5901 await this.client.Error(
"Invalid legal identity received and discarded.");
5903 Log.Warning(
"Invalid legal identity received and discarded.", this.client.BareJID, e.From,
5904 new KeyValuePair<string, object>(
"Status", e2.Status));
5908 await
this.PetitionForIdentityReceived.Raise(
this,
new LegalIdentityPetitionEventArgs(e, Identity, From, LegalId, PetitionId, Purpose, ClientEndpoint, Context));
5916 public event EventHandlerAsync<LegalIdentityPetitionEventArgs> PetitionForIdentityReceived =
null;
5918 private async Task PetitionIdentityResponseMessageHandler(
object Sender,
MessageEventArgs e)
5924 XmlElement Context =
null;
5926 foreach (XmlNode N
in e.
Content.ChildNodes)
5928 if (N is XmlElement E)
5930 if (E.LocalName ==
"identity" && E.NamespaceURI == e.
Content.NamespaceURI)
5932 else if (!(Context is
null))
5939 if (!Response ||
string.Compare(e.
FromBareJID, Identity?.
Provider ??
string.Empty,
true) == 0)
5946 public event EventHandlerAsync<LegalIdentityPetitionResponseEventArgs> PetitionedIdentityResponseReceived =
null;
5950 #region Signature petitions
5965 return this.PetitionSignatureAsync(this.GetTrustProvider(LegalId), LegalId, Content, PetitionId, Purpose,
false,
null);
5982 return this.PetitionSignatureAsync(Address, LegalId, Content, PetitionId, Purpose,
false,
null);
5998 public Task
PetitionSignatureAsync(
string Address,
string LegalId,
byte[] Content,
string PetitionId,
string Purpose,
string ContextXml)
6000 return this.PetitionSignatureAsync(Address, LegalId, Content, PetitionId, Purpose,
false, ContextXml);
6003 private async Task PetitionSignatureAsync(
string Address,
string LegalId,
byte[] Content,
string PetitionId,
6004 string Purpose,
bool PeerReview,
string ContextXml)
6006 if (this.contentPerPid.TryGetValue(PetitionId, out KeyValuePair<
byte[],
bool> Rec))
6008 if (Convert.ToBase64String(Content) == Convert.ToBase64String(Rec.Key) && PeerReview == Rec.Value)
6011 throw new InvalidOperationException(
"Petition ID must be unique for outstanding petitions.");
6014 this.contentPerPid[PetitionId] =
new KeyValuePair<byte[], bool>(Content, PeerReview);
6016 StringBuilder Xml =
new StringBuilder();
6017 byte[] Nonce = this.RandomBytes(32);
6019 string NonceStr = Convert.ToBase64String(Nonce);
6020 string ContentStr = Convert.ToBase64String(Content);
6021 byte[] Data = Encoding.UTF8.GetBytes(PetitionId +
":" + LegalId +
":" + Purpose +
":" + NonceStr +
":" + this.client.BareJID.ToLower() +
":" + ContentStr);
6024 Xml.Append(
"<petitionSignature xmlns='");
6025 Xml.Append(NamespaceLegalIdentitiesCurrent);
6026 Xml.Append(
"' id='");
6028 Xml.Append(
"' pid='");
6030 Xml.Append(
"' purpose='");
6032 Xml.Append(
"' nonce='");
6033 Xml.Append(NonceStr);
6034 Xml.Append(
"' s='");
6035 Xml.Append(Convert.ToBase64String(
Signature));
6038 if (
string.IsNullOrEmpty(ContextXml))
6039 Xml.Append(ContentStr);
6042 Xml.Append(
"<content>");
6043 Xml.Append(ContentStr);
6044 Xml.Append(
"</content>");
6045 Xml.Append(ContextXml);
6048 Xml.Append(
"</petitionSignature>");
6050 await this.client.IqSetAsync(Address, Xml.ToString());
6066 byte[]
Signature,
string PetitionId,
string RequestorFullJid,
bool Response)
6068 return this.PetitionSignatureResponseAsync(this.GetTrustProvider(LegalId), LegalId, Content,
Signature, PetitionId,
6069 RequestorFullJid, Response,
null);
6086 byte[]
Signature,
string PetitionId,
string RequestorFullJid,
bool Response,
string ContextXml)
6088 return this.PetitionSignatureResponseAsync(this.GetTrustProvider(LegalId), LegalId, Content,
Signature, PetitionId,
6089 RequestorFullJid, Response, ContextXml);
6106 string PetitionId,
string RequestorFullJid,
bool Response)
6108 return this.PetitionSignatureResponseAsync(Address, LegalId, Content,
Signature, PetitionId, RequestorFullJid, Response,
null);
6126 string PetitionId,
string RequestorFullJid,
bool Response,
string ContextXml)
6128 StringBuilder Xml =
new StringBuilder();
6130 Xml.Append(
"<petitionSignatureResponse xmlns='");
6131 Xml.Append(NamespaceLegalIdentitiesCurrent);
6132 Xml.Append(
"' id='");
6134 Xml.Append(
"' pid='");
6136 Xml.Append(
"' jid='");
6137 Xml.Append(
XML.
Encode(RequestorFullJid));
6138 Xml.Append(
"' response='");
6140 Xml.Append(
"'><content>");
6141 Xml.Append(Convert.ToBase64String(Content));
6142 Xml.Append(
"</content><signature>");
6143 Xml.Append(Convert.ToBase64String(
Signature));
6144 Xml.Append(
"</signature>");
6146 if (!
string.IsNullOrEmpty(ContextXml))
6147 Xml.Append(ContextXml);
6149 Xml.Append(
"</petitionSignatureResponse>");
6151 await this.client.IqSetAsync(Address, Xml.ToString());
6154 private async Task PetitionSignatureMessageHandler(
object Sender,
MessageEventArgs e)
6161 string ContentStr =
string.Empty;
6162 byte[] Content =
null;
6164 XmlElement Context =
null;
6165 bool PeerReview =
false;
6167 foreach (XmlNode N
in e.
Content.ChildNodes)
6169 if (!(N is XmlElement E))
6172 switch (E.LocalName)
6175 ContentStr = E.InnerText;
6176 Content = Convert.FromBase64String(ContentStr);
6184 if (!(Context is
null))
6192 if (Content is
null)
6195 if (Identity is
null)
6197 string s = Encoding.UTF8.GetString(Content);
6198 if (s.StartsWith(
"<identity") && s.EndsWith(
"</identity>"))
6202 XmlDocument Doc =
new XmlDocument();
6205 if (Doc.DocumentElement.LocalName ==
"identity")
6223 if (Identity is
null)
6227 if (
string.Compare(e.
FromBareJID,
this.componentAddress,
true) != 0 &&
6233 EventHandlerAsync<SignaturePetitionEventArgs> h = PeerReview ? this.PetitionForPeerReviewIDReceived : this.PetitionForSignatureReceived;
6235 await this.Validate(Identity,
false, async (sender2, e2) =>
6239 await this.client.Error(
"Invalid legal identity received and discarded.");
6241 Log.Warning(
"Invalid legal identity received and discarded.", this.client.BareJID, e.From,
6242 new KeyValuePair<string, object>(
"Status", e2.Status));
6247 await h.Raise(
this,
new SignaturePetitionEventArgs(e, Identity, From, LegalId, PetitionId, Purpose, Content, ClientEndpoint, Context));
6255 public event EventHandlerAsync<SignaturePetitionEventArgs> PetitionForSignatureReceived =
null;
6257 private async Task PetitionSignatureResponseMessageHandler(
object Sender,
MessageEventArgs e)
6262 string SignatureStr =
string.Empty;
6265 XmlElement Context =
null;
6267 foreach (XmlNode N
in e.
Content.ChildNodes)
6269 if (N is XmlElement E)
6271 switch (E.LocalName)
6278 SignatureStr = E.InnerText;
6279 Signature = Convert.FromBase64String(SignatureStr);
6283 if (!(Context is
null))
6292 if (!this.contentPerPid.TryGetValue(PetitionId, out KeyValuePair<
byte[],
bool> P))
6294 await this.client.Warning(
"Petition ID not recognized: " + PetitionId +
". Response ignored.");
6298 EventHandlerAsync<SignaturePetitionResponseEventArgs> h = P.Value ? this.PetitionedPeerReviewIDResponseReceived : this.PetitionedSignatureResponseReceived;
6302 if (Identity is
null)
6304 await this.client.Warning(
"Identity missing. Response ignored.");
6310 await this.client.Warning(
"Signature missing. Response ignored.");
6314 bool? Result = this.ValidateSignature(Identity, P.Key,
Signature);
6315 if (!Result.HasValue)
6317 await this.client.Warning(
"Unable to validate signature. Response ignored.");
6323 await this.client.Warning(
"Invalid signature. Response ignored.");
6328 if (!Response ||
string.Compare(e.
FromBareJID, Identity?.
Provider ??
string.Empty,
true) == 0)
6332 await this.Client.Information(h.Method.Name);
6338 this.contentPerPid.Remove(PetitionId);
6342 await this.client.Warning(
"Sender invalid. Response ignored.");
6348 public event EventHandlerAsync<SignaturePetitionResponseEventArgs> PetitionedSignatureResponseReceived =
null;
6352 #region Peer Review of IDs
6373 return this.PetitionPeerReviewIDAsync(this.GetTrustProvider(LegalId), LegalId, Identity, PetitionId, Purpose);
6396 StringBuilder Xml =
new StringBuilder();
6397 Identity.
Serialize(Xml,
true,
true,
true,
true,
true,
true,
true);
6398 byte[] Content = Encoding.UTF8.GetBytes(Xml.ToString());
6400 return this.PetitionSignatureAsync(Address, LegalId, Content, PetitionId, Purpose,
true,
null);
6406 public event EventHandlerAsync<SignaturePetitionEventArgs> PetitionForPeerReviewIDReceived =
null;
6411 public event EventHandlerAsync<SignaturePetitionResponseEventArgs> PetitionedPeerReviewIDResponseReceived =
null;
6424 throw new InvalidOperationException(
"No HTTP File Upload extension added to the XMPP Client.");
6426 StringBuilder Xml =
new StringBuilder();
6428 Xml.Append(
"<peerReview s='");
6429 Xml.Append(Convert.ToBase64String(PeerSignature));
6430 Xml.Append(
"' tp='");
6431 Xml.Append(
XML.
Encode(DateTime.UtcNow));
6432 Xml.Append(
"' xmlns='");
6433 Xml.Append(NamespaceLegalIdentitiesCurrent);
6434 Xml.Append(
"'><reviewed>");
6435 Identity.
Serialize(Xml,
true,
true,
true,
true,
true,
true,
true);
6436 Xml.Append(
"</reviewed><reviewer>");
6437 ReviewerLegalIdentity.
Serialize(Xml,
true,
true,
true,
true,
true,
true,
true);
6438 Xml.Append(
"</reviewer></peerReview>");
6440 byte[] Data = Encoding.UTF8.GetBytes(Xml.ToString());
6442 string FileName = ReviewerLegalIdentity.Id +
".xml";
6443 string ContentType =
"text/xml; charset=utf-8";
6447 throw new IOException(
"Unable to upload Peer Review attachment to broker.");
6449 await e2.
PUT(Data, ContentType, 10000);
6456 #region Contract petitions
6470 return this.PetitionContractAsync(this.GetTrustProvider(ContractId), ContractId, PetitionId, Purpose,
null);
6486 return this.PetitionContractAsync(Address, ContractId, PetitionId, Purpose,
null);
6501 public async Task
PetitionContractAsync(
string Address,
string ContractId,
string PetitionId,
string Purpose,
string ContextXml)
6503 StringBuilder Xml =
new StringBuilder();
6504 byte[] Nonce = this.RandomBytes(32);
6506 string NonceStr = Convert.ToBase64String(Nonce);
6507 byte[] Data = Encoding.UTF8.GetBytes(PetitionId +
":" + ContractId +
":" + Purpose +
":" + NonceStr +
":" + this.client.BareJID.ToLower());
6510 Xml.Append(
"<petitionContract xmlns='");
6511 Xml.Append(NamespaceSmartContractsCurrent);
6512 Xml.Append(
"' id='");
6514 Xml.Append(
"' pid='");
6516 Xml.Append(
"' purpose='");
6518 Xml.Append(
"' nonce='");
6519 Xml.Append(NonceStr);
6520 Xml.Append(
"' s='");
6521 Xml.Append(Convert.ToBase64String(
Signature));
6523 if (
string.IsNullOrEmpty(ContextXml))
6528 Xml.Append(ContextXml);
6529 Xml.Append(
"</petitionContract>");
6532 await this.client.IqSetAsync(Address, Xml.ToString());
6547 return this.PetitionContractResponseAsync(this.GetTrustProvider(ContractId), ContractId, PetitionId, RequestorFullJid, Response,
null);
6563 return this.PetitionContractResponseAsync(this.GetTrustProvider(ContractId), ContractId, PetitionId, RequestorFullJid, Response, ContextXml);
6579 return this.PetitionContractResponseAsync(Address, ContractId, PetitionId, RequestorFullJid, Response,
null);
6595 bool Response,
string ContextXml)
6597 StringBuilder Xml =
new StringBuilder();
6599 Xml.Append(
"<petitionContractResponse xmlns='");
6600 Xml.Append(NamespaceSmartContractsCurrent);
6601 Xml.Append(
"' id='");
6603 Xml.Append(
"' pid='");
6605 Xml.Append(
"' jid='");
6606 Xml.Append(
XML.
Encode(RequestorFullJid));
6607 Xml.Append(
"' response='");
6610 if (
string.IsNullOrEmpty(ContextXml))
6615 Xml.Append(ContextXml);
6616 Xml.Append(
"</petitionContractResponse>");
6619 await this.client.IqSetAsync(Address, Xml.ToString());
6622 private async Task PetitionContractMessageHandler(
object Sender,
MessageEventArgs e)
6629 int i = ContractId.IndexOf(
'@');
6631 XmlElement Context =
null;
6633 foreach (XmlNode N
in e.
Content.ChildNodes)
6635 if (!(N is XmlElement E))
6638 if (E.LocalName ==
"identity" && E.NamespaceURI == e.
Content.NamespaceURI)
6640 else if (!(Context is
null))
6646 if (Identity is
null)
6649 if (!this.IsFromTrustProvider(ContractId, e.
FromBareJID))
6652 await this.Validate(Identity,
false, async (sender2, e2) =>
6656 await this.client.Error(
"Invalid identity received and discarded.");
6658 Log.Warning(
"Invalid identity received and discarded.", this.client.BareJID, e.From,
6659 new KeyValuePair<string, object>(
"Status", e2.Status));
6663 await
this.PetitionForContractReceived.Raise(
this,
new ContractPetitionEventArgs(e, Identity, From, ContractId, PetitionId, Purpose, ClientEndpoint, Context));
6671 public event EventHandlerAsync<ContractPetitionEventArgs> PetitionForContractReceived =
null;
6673 private async Task PetitionContractResponseMessageHandler(
object Sender,
MessageEventArgs e)
6679 XmlElement Context =
null;
6681 foreach (XmlNode N
in e.
Content.ChildNodes)
6683 if (!(N is XmlElement E))
6686 if (E.LocalName ==
"contract" && E.NamespaceURI == e.
Content.NamespaceURI)
6691 else if (!(Context is
null))
6704 public event EventHandlerAsync<ContractPetitionResponseEventArgs> PetitionedContractResponseReceived =
null;
6722 StringBuilder Xml =
new StringBuilder();
6724 Xml.Append(
"<addAttachment xmlns='");
6725 Xml.Append(NamespaceLegalIdentitiesCurrent);
6726 Xml.Append(
"' id='");
6728 Xml.Append(
"' getUrl='");
6730 Xml.Append(
"' s='");
6731 Xml.Append(Convert.ToBase64String(
Signature));
6734 return this.client.SendIqSet(this.componentAddress, Xml.ToString(), async (Sender, e) =>
6739 if (e.
Ok && !((E = e.FirstElement) is
null) && E.LocalName ==
"identity")
6758 TaskCompletionSource<LegalIdentity> Result =
new TaskCompletionSource<LegalIdentity>();
6760 await this.AddLegalIdAttachment(LegalId, GetUrl,
Signature, (Sender, e) =>
6763 Result.TrySetResult(e.Identity);
6765 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to add attachment."));
6767 return Task.CompletedTask;
6771 return await Result.Task;
6785 StringBuilder Xml =
new StringBuilder();
6787 Xml.Append(
"<addAttachment xmlns='");
6788 Xml.Append(NamespaceSmartContractsCurrent);
6789 Xml.Append(
"' contractId='");
6791 Xml.Append(
"' getUrl='");
6793 Xml.Append(
"' s='");
6794 Xml.Append(Convert.ToBase64String(
Signature));
6797 return this.client.SendIqSet(this.componentAddress, Xml.ToString(), async (Sender, e) =>
6802 if (e.
Ok && !((E = e.FirstElement) is
null) && E.LocalName ==
"contract")
6804 ParsedContract Parsed = await Contract.Parse(E, this, false);
6808 Contract = Parsed.Contract;
6826 TaskCompletionSource<Contract> Result =
new TaskCompletionSource<Contract>();
6828 await this.AddContractAttachment(ContractId, GetUrl,
Signature, (Sender, e) =>
6831 Result.TrySetResult(e.Contract);
6833 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to add attachment."));
6835 return Task.CompletedTask;
6839 return await Result.Task;
6850 return this.GetAttachmentAsync(Url,
SignWith, 30000);
6862 using (HttpClient HttpClient =
new HttpClient()
6864 Timeout = TimeSpan.FromMilliseconds(Timeout)
6867 HttpRequestMessage Request;
6868 HttpResponseMessage Response =
null;
6870 Request =
new HttpRequestMessage()
6872 RequestUri =
new Uri(Url),
6873 Method = HttpMethod.Get
6878 Response = await HttpClient.SendAsync(Request);
6880 if (Response.StatusCode == System.Net.HttpStatusCode.Unauthorized &&
6881 !(Response.Headers.WwwAuthenticate is
null))
6883 foreach (AuthenticationHeaderValue Header
in Response.Headers.WwwAuthenticate)
6885 if (Header.Scheme ==
"NeuroFoundation.Sign")
6888 string Realm =
null;
6889 string NonceStr =
null;
6890 byte[] Nonce =
null;
6892 foreach (KeyValuePair<string, string> P
in Parameters)
6902 Nonce = Convert.FromBase64String(NonceStr);
6907 if (!
string.IsNullOrEmpty(Realm) && !
string.IsNullOrEmpty(NonceStr))
6910 StringBuilder sb =
new StringBuilder();
6912 sb.Append(
"jid=\"");
6913 sb.Append(this.client.FullJID);
6914 sb.Append(
"\", realm=\"");
6916 sb.Append(
"\", n=\"");
6917 sb.Append(NonceStr);
6918 sb.Append(
"\", s=\"");
6919 sb.Append(Convert.ToBase64String(
Signature));
6923 Request =
new HttpRequestMessage()
6925 RequestUri =
new Uri(Url),
6926 Method = HttpMethod.Get
6929 Request.Headers.Authorization =
new AuthenticationHeaderValue(Header.Scheme, sb.ToString());
6933 Response = await HttpClient.SendAsync(Request);
6940 if (!Response.IsSuccessStatusCode)
6941 await Content.Getters.WebGetter.ProcessResponse(Response, Request.RequestUri);
6943 string ContentType = Response.Content.Headers.ContentType.ToString();
6947 await Response.Content.CopyToAsync(File);
6949 catch (Exception ex)
6954 ExceptionDispatchInfo.Capture(ex).Throw();
6957 return new KeyValuePair<string, TemporaryFile>(ContentType, File);
6962 Response?.Dispose();
6975 StringBuilder Xml =
new StringBuilder();
6977 Xml.Append(
"<removeAttachment xmlns='");
6978 Xml.Append(NamespaceLegalIdentitiesCurrent);
6979 Xml.Append(
"' attachmentId='");
6983 return this.client.SendIqSet(this.componentAddress, Xml.ToString(), async (Sender, e) =>
6988 if (e.
Ok && !((E = e.FirstElement) is
null) && E.LocalName ==
"identity")
7003 TaskCompletionSource<LegalIdentity> Result =
new TaskCompletionSource<LegalIdentity>();
7005 await this.RemoveLegalIdAttachment(AttachmentId, (Sender, e) =>
7008 Result.TrySetResult(e.Identity);
7010 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to remove attachment."));
7012 return Task.CompletedTask;
7016 return await Result.Task;
7027 StringBuilder Xml =
new StringBuilder();
7029 Xml.Append(
"<removeAttachment xmlns='");
7030 Xml.Append(NamespaceSmartContractsCurrent);
7031 Xml.Append(
"' attachmentId='");
7035 return this.client.SendIqSet(this.componentAddress, Xml.ToString(), async (Sender, e) =>
7040 if (e.
Ok && !((E = e.FirstElement) is
null) && E.LocalName ==
"contract")
7042 ParsedContract Parsed = await Contract.Parse(E, this, false);
7046 Contract = Parsed.Contract;
7061 TaskCompletionSource<Contract> Result =
new TaskCompletionSource<Contract>();
7063 await this.RemoveContractAttachment(AttachmentId, (Sender, e) =>
7066 Result.TrySetResult(e.Contract);
7068 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to remove attachment."));
7070 return Task.CompletedTask;
7074 return await Result.Task;
7091 public (
byte[],
byte[]) Encrypt(
byte[] Message,
byte[] Nonce,
byte[] RecipientPublicKey,
string RecipientPublicKeyName)
7093 return this.Encrypt(Message, Nonce, RecipientPublicKey, RecipientPublicKeyName,
string.Empty);
7107 public (
byte[],
byte[]) Encrypt(
byte[] Message,
byte[] Nonce,
byte[] RecipientPublicKey,
string RecipientPublicKeyName,
string RecipientPublicKeyNamespace)
7109 IE2eEndpoint LocalEndpoint = this.localKeys.FindLocalEndpoint(RecipientPublicKeyName, RecipientPublicKeyNamespace) ??
throw new NotSupportedException(
"Unable to find matching local key.");
7111 byte[] LocalPublicKey = LocalEndpoint.
PublicKey;
7115 byte[] Key =
new byte[16];
7116 byte[] IV =
new byte[16];
7121 for (i = 0; i < 32; i++)
7122 Secret[i] ^= NonceDigest[i];
7134 i = c + Message.Length;
7135 c = (i + 15) & ~0xf;
7137 ToEncrypt =
new byte[c];
7143 ToEncrypt[j] = (byte)(i & 127);
7146 ToEncrypt[j] |= 0x80;
7152 Array.Copy(Message, 0, ToEncrypt, j, Message.Length);
7153 j += Message.Length;
7156 this.rnd.GetBytes(ToEncrypt, j, c - j);
7158 Array.Copy(Digest, 0, Key, 0, 16);
7159 Array.Copy(Digest, 16, IV, 0, 16);
7163 using (ICryptoTransform Aes = this.aes.CreateEncryptor(Key, IV))
7165 Encrypted = Aes.TransformFinalBlock(ToEncrypt, 0, c);
7169 return (Encrypted, LocalPublicKey);
7180 public async Task<byte[]>
Decrypt(
byte[] EncryptedMessage,
byte[] SenderPublicKey,
byte[] Nonce)
7182 IE2eEndpoint LocalEndpoint = await this.GetMatchingLocalKeyAsync();
7186 byte[] Key =
new byte[16];
7187 byte[] IV =
new byte[16];
7192 for (i = 0; i < 32; i++)
7193 Secret[i] ^= NonceDigest[i];
7197 Array.Copy(Digest, 0, Key, 0, 16);
7198 Array.Copy(Digest, 16, IV, 0, 16);
7202 using (ICryptoTransform Aes = this.aes.CreateDecryptor(Key, IV))
7204 Decrypted = Aes.TransformFinalBlock(EncryptedMessage, 0, EncryptedMessage.Length);
7216 while ((b & 0x80) != 0);
7218 if (c < 0 || c > Decrypted.Length - i)
7219 throw new InvalidOperationException(
"Unable to decrypt message.");
7221 byte[] Message =
new byte[c];
7223 Array.Copy(Decrypted, i, Message, 0, c);
7230 #region Explicit authorization of access to Legal IDs
7240 public Task
AuthorizeAccessToId(
string LegalId,
string RemoteId,
bool Authorized, EventHandlerAsync<IqResultEventArgs> Callback,
object State)
7242 return this.AuthorizeAccessToId(this.GetTrustProvider(LegalId), LegalId, RemoteId, Authorized, Callback, State);
7254 public Task
AuthorizeAccessToId(
string Address,
string LegalId,
string RemoteId,
bool Authorized, EventHandlerAsync<IqResultEventArgs> Callback,
object State)
7256 StringBuilder Xml =
new StringBuilder();
7258 Xml.Append(
"<authorizeAccess xmlns='");
7259 Xml.Append(NamespaceLegalIdentitiesCurrent);
7260 Xml.Append(
"' id='");
7262 Xml.Append(
"' remoteId='");
7264 Xml.Append(
"' auth='");
7268 return this.client.SendIqSet(Address, Xml.ToString(), Callback, State);
7279 return this.AuthorizeAccessToIdAsync(this.GetTrustProvider(LegalId), LegalId, RemoteId, Authorized);
7291 TaskCompletionSource<bool> Result =
new TaskCompletionSource<bool>();
7293 await this.AuthorizeAccessToId(Address, LegalId, RemoteId, Authorized, (Sender, e) =>
7296 Result.TrySetResult(
true);
7298 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to authorize access to legal identity."));
7300 return Task.CompletedTask;
7309 #region Explicit authorization of access to Contracts
7319 public Task
AuthorizeAccessToContract(
string ContractId,
string RemoteId,
bool Authorized, EventHandlerAsync<IqResultEventArgs> Callback,
object State)
7321 return this.AuthorizeAccessToContract(this.GetTrustProvider(ContractId), ContractId, RemoteId, Authorized, Callback, State);
7333 public Task
AuthorizeAccessToContract(
string Address,
string ContractId,
string RemoteId,
bool Authorized, EventHandlerAsync<IqResultEventArgs> Callback,
object State)
7335 StringBuilder Xml =
new StringBuilder();
7337 Xml.Append(
"<authorizeAccess xmlns='");
7338 Xml.Append(NamespaceSmartContractsCurrent);
7339 Xml.Append(
"' id='");
7341 Xml.Append(
"' remoteId='");
7343 Xml.Append(
"' auth='");
7347 return this.client.SendIqSet(Address, Xml.ToString(), Callback, State);
7358 return this.AuthorizeAccessToContractAsync(this.GetTrustProvider(ContractId), ContractId, RemoteId, Authorized);
7370 TaskCompletionSource<bool> Result =
new TaskCompletionSource<bool>();
7372 await this.AuthorizeAccessToContract(Address, ContractId, RemoteId, Authorized, (Sender, e) =>
7375 Result.TrySetResult(
true);
7377 Result.TrySetException(e.
StanzaError ??
new Exception(
"Unable to authorize access to legal identity."));
7379 return Task.CompletedTask;
7388 #region Peer-review service providers
7397 return this.GetPeerReviewIdServiceProviders(this.componentAddress, Callback, State);
7409 StringBuilder Xml =
new StringBuilder();
7411 Xml.Append(
"<reviewIdProviders xmlns='");
7412 Xml.Append(NamespaceLegalIdentitiesCurrent);
7415 return this.client.SendIqGet(ComponentAddress, Xml.ToString(), async (Sender, e) =>
7417 List<ServiceProviderWithLegalId> Providers =
null;
7421 !((E = e.FirstElement) is
null) &&
7422 E.LocalName ==
"providers")
7424 Providers = new List<ServiceProviderWithLegalId>();
7426 foreach (XmlNode N in E.ChildNodes)
7428 if (N is XmlElement E2 && E2.LocalName ==
"provider")
7430 ServiceProviderWithLegalId Provider = this.ParseServiceProviderWithLegalId(E2);
7432 if (!(Provider is null))
7433 Providers.Add(Provider);
7450 string IconUrl =
null;
7451 string LegalId =
null;
7453 int IconHeight = -1;
7454 bool External =
false;
7456 foreach (XmlAttribute Attr
in Xml.Attributes)
7473 IconUrl = Attr.Value;
7477 if (!
int.TryParse(Attr.Value, out IconWidth))
7482 if (!
int.TryParse(Attr.Value, out IconHeight))
7487 LegalId = Attr.Value;
7497 if (Id is
null || Type is
null || Name is
null)
7500 if (
string.IsNullOrEmpty(IconUrl))
7504 if (IconWidth < 0 || IconHeight < 0)
7517 return this.GetPeerReviewIdServiceProvidersAsync(this.componentAddress);
7527 TaskCompletionSource<ServiceProviderWithLegalId[]> Providers =
new TaskCompletionSource<ServiceProviderWithLegalId[]>();
7529 await this.GetPeerReviewIdServiceProviders(ComponentAddress, (Sender, e) =>
7532 Providers.TrySetResult(e.ServiceProviders);
7534 Providers.TrySetException(e.
StanzaError ??
new Exception(
"Unable to get service providers."));
7536 return Task.CompletedTask;
7540 return await Providers.Task;
7545 #region Select Peer-review service
7556 public Task
SelectPeerReviewService(
string Provider,
string ServiceId, EventHandlerAsync<IqResultEventArgs> Callback,
object State)
7558 return this.SelectPeerReviewService(this.componentAddress, Provider, ServiceId, Callback, State);
7572 EventHandlerAsync<IqResultEventArgs> Callback,
object State)
7574 StringBuilder Xml =
new StringBuilder();
7576 Xml.Append(
"<selectReviewService xmlns='");
7577 Xml.Append(NamespaceLegalIdentitiesCurrent);
7578 Xml.Append(
"' provider='");
7580 Xml.Append(
"' serviceId='");
7584 return this.client.SendIqSet(ComponentAddress, Xml.ToString(), Callback, State);
7596 return this.SelectPeerReviewServiceAsync(this.componentAddress, Provider, ServiceId);
7609 TaskCompletionSource<bool> Providers =
new TaskCompletionSource<bool>();
7611 await this.SelectPeerReviewService(ComponentAddress, Provider, ServiceId, (Sender, e) =>
7614 Providers.TrySetResult(
true);
7616 Providers.TrySetException(e.
StanzaError ??
new Exception(
"Unable to select peer review service."));
7618 return Task.CompletedTask;
7622 await Providers.Task;
7627 #region Petition Client URL event
7629 private Task PetitionClientUrlEventHandler(
object Sender,
MessageEventArgs e)
Helps with parsing of commong data types.
static string Encode(bool x)
Encodes a Boolean for use in XML and other formats.
static KeyValuePair< string, string >[] ParseFieldValues(string Value)
Parses a set of comma or semicolon-separated field values, optionaly delimited by ' or " characters.
static bool TryParse(string s, out double Value)
Tries to decode a string encoded double.
Helps with common XML-related tasks.
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
static string Encode(string s)
Encodes a string for use in XML.
static XmlWriterSettings WriterSettings(bool Indent, bool OmitXmlDeclaration)
Gets an XML writer settings object.
Static class managing loading of XSL resources stored as embedded resources or in content files.
static void Validate(string ObjectID, XmlDocument Xml, params XmlSchema[] Schemas)
Validates an XML document given a set of XML schemas.
Static class managing the application event log. Applications and services log events on this static ...
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
static void Notice(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs a notice event.
Contains a reference to an attachment assigned to a legal object.
string LegalId
Legal ID of uploader of attachment
string ContentType
Internet Content Type of binary attachment.
string Url
URL to retrieve attachment, if provided.
byte[] Signature
Binary signature of the attachment, generated by an approved legal identity of the account-holder....
Represents a digital signature on a contract.
Contains the definition of a contract
static Task< ParsedContract > Parse(XmlDocument Xml)
Validates a contract XML Document, and returns the contract definition in it.
byte[] ContentSchemaDigest
The hash digest of the schema used to validate the machine-readable contents (ForMachines) of the sma...
string ForMachinesLocalName
Local name used by the root node of the machine-readable contents of the contract (ForMachines).
Security.HashFunction ContentSchemaHashFunction
Hash function of the schema used to validate the machine-readable contents (ForMachines) of the smart...
void EncryptEncryptedParameters(string CreatorJid, IParameterEncryptionAlgorithm Algorithm)
Protects encrypted values, by encrypting the clear text string representations for those that lack en...
Parameter[] Parameters
Defined parameters for the smart contract.
ClientSignature[] ClientSignatures
Client signatures of the contract.
HumanReadableText[] ForHumans
Human-readable contents of the contract.
DateTime From
From when the contract is valid (if signed)
async Task< bool > IsLegallyBinding(bool CheckCurrentTime, ContractsClient Client)
Checks if a contract is legally binding.
Attachment[] Attachments
Attachments assigned to the legal identity.
DateTime To
Until when the contract is valid (if signed)
string Provider
JID of the Trust Provider hosting the contract
bool HasTransientParameters
If contract has parameters that are transient.
XmlElement ForMachines
Machine-readable contents of the contract.
void Serialize(StringBuilder Xml, bool IncludeNamespace, bool IncludeIdAttribute, bool IncludeClientSignatures, bool IncludeAttachments, bool IncludeStatus, bool IncludeServerSignature, bool IncludeAttachmentReferences)
Serializes the Contract, in normalized form.
Role[] Roles
Roles defined in the smart contract.
ContractParts PartsMode
How parts are defined in the smart contract.
ContractState State
Contract state
string ContractId
Contract identity
string ForMachinesNamespace
Namespace used by the root node of the machine-readable contents of the contract (ForMachines).
ServerSignature ServerSignature
Server signature attesting to the validity of the contents of the contract.
bool HasEncryptedParameters
If contract has parameters that require encryption and decryption.
bool DecryptEncryptedParameters(string CreatorJid, IParameterEncryptionAlgorithm Algorithm)
Protects encrypted values, by encrypting the clear text string representations for those that lack en...
Adds support for legal identities, smart contracts and signatures to an XMPP client.
async Task ReadyForApprovalAsync(string Address, string LegalIdentityId)
Marks an Identity as Ready for Approval. Call this after necessary attachments have been added....
Task< bool > ImportKeys(string Xml)
Imports keys
static Uri ContractIdUri(string ContractId)
Contract identity URI.
Task DeleteContract(string Address, string ContractId, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Deletes a contract
Task< bool > ImportKeys(XmlDocument Xml)
Imports keys
async Task< bool > LoadKeys(bool CreateIfNone, ProfilerThread Thread)
Loads keys from the underlying persistence layer.
EventHandlerAsync< PetitionClientUrlEventArgs > PetitionClientUrlReceived
Event raised when a Client URL has been sent to the client as part of a petition process....
byte[] RandomBytes(int Nr)
Creates an array of random bytes.
async Task< LegalIdentity[]> GetContractLegalIdentitiesAsync(string Address, string ContractId, bool Current, bool Historic)
Gets available legal identities related to a contract.
Task CompromisedLegalIdentity(string LegalIdentityId, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Reports as Compromised one of the legal identities of the account, given its ID.
Task PetitionIdentityAsync(string Address, string LegalId, string PetitionId, string Purpose)
Sends a petition to the owner of a legal identity, to access the information in the identity....
async Task< byte[]> Decrypt(byte[] EncryptedMessage, byte[] SenderPublicKey, byte[] Nonce)
Decrypts a message that was aimed at the client using the current keys.
Task GetContractLegalIdentities(string ContractId, EventHandlerAsync< LegalIdentitiesEventArgs > Callback, object State)
Gets available legal identities related to a contract.
Task GetPeerReviewIdServiceProviders(EventHandlerAsync< ServiceProvidersEventArgs< ServiceProviderWithLegalId > > Callback, object State)
Gets available service providers who can help review an ID application.
Task Sign(Stream Data, SignWith SignWith, EventHandlerAsync< SignatureEventArgs > Callback, object State)
Signs binary data with the corresponding private key.
Task GetCreatedContractReferences(string Address, EventHandlerAsync< IdReferencesEventArgs > Callback, object State)
Get references to contracts the account has created.
Task PetitionSignatureResponseAsync(string LegalId, byte[] Content, byte[] Signature, string PetitionId, string RequestorFullJid, bool Response, string ContextXml)
Sends a response to a petition for a signature by the client. When a petition is received,...
async Task< Contract > DeleteContractAsync(string Address, string ContractId)
Deletes a contract
Task GetSignedContractReferences(EventHandlerAsync< IdReferencesEventArgs > Callback, object State)
Get references to contracts the account has signed.
Task CreateContract(XmlElement ForMachines, HumanReadableText[] ForHumans, Role[] Roles, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Creates a new contract.
async Task< string[]> GetCreatedContractReferencesAsync(string Address, int Offset, int MaxCount)
Get references to contracts the account has created.
async Task UpdateContract(string Address, Contract Contract, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Updates a contract
Task SendContractProposal(string ContractId, string Role, string To, string Message)
Sends a contract proposal to a recipient.
Task GetContractLegalIdentities(string Address, string ContractId, EventHandlerAsync< LegalIdentitiesEventArgs > Callback, object State)
Gets available legal identities related to a contract.
async Task< IdentityStatus > ValidateAsync(LegalIdentity Identity, bool ValidateState)
Validates a legal identity.
Task Validate(Contract Contract, EventHandlerAsync< ContractValidationEventArgs > Callback, object State)
Validates a smart contract.
async Task GenerateNewKeys()
Generates new keys for the contracts clients.
Task< ContractsEventArgs > GetCreatedContractsAsync(string Address)
Get contracts the account has created.
Task GetSchema(string Namespace, SchemaDigest Digest, EventHandlerAsync< SchemaEventArgs > Callback, object State)
Gets a schema.
async Task< ContractsEventArgs > GetCreatedContractsAsync(string Address, int Offset, int MaxCount)
Get contracts the account has created.
async Task< LegalIdentity > RemoveLegalIdAttachmentAsync(string AttachmentId)
Removes an attachment from a newly created legal identity.
Task GetCreatedContracts(EventHandlerAsync< ContractsEventArgs > Callback, object State)
Get contracts the account has created.
async Task Validate(Contract Contract, bool ValidateState, EventHandlerAsync< ContractValidationEventArgs > Callback, object State)
Validates a smart contract.
Task< byte[]> GetSchemaAsync(string Address, string Namespace)
Gets a schema.
Task< LegalIdentity > ApplyAsync(Property[] Properties)
Applies for a legal identity to be registered.
Task PetitionContractResponseAsync(string Address, string ContractId, string PetitionId, string RequestorFullJid, bool Response)
Sends a response to a petition to access a smart contract. When a petition for a contract is received...
string KeySettingsPrefix
Prefix for client key runtime settings.
Task SelectPeerReviewServiceAsync(string Provider, string ServiceId)
Selects a service provider for peer review. This needs to be done before requesting the trust provide...
Task ObsoleteLegalIdentity(string Address, string LegalIdentityId, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Obsoletes one of the legal identities of the account, given its ID.
Task PetitionIdentityResponseAsync(string LegalId, string PetitionId, string RequestorFullJid, bool Response)
Sends a response to a petition for information about a legal identity. When a petition is received,...
async Task< LegalIdentity > ApplyAsync(string Address, Property[] Properties)
Applies for a legal identity to be registered.
Task ValidateSignature(string Address, string LegalId, byte[] Data, byte[] Signature, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Validates a signature of binary data.
bool? ValidateSignature(LegalIdentity Identity, byte[] Data, byte[] Signature)
Validates a signature of binary data.
async Task< ContractStatus > ValidateAsync(Contract Contract, bool ValidateState)
Validates a smart contract.
ulong RandomInteger(ulong MaxExclusive)
Creates a random long unsigned integer lower than MaxExclusive .
Task< KeyValuePair< string, TemporaryFile > > GetAttachmentAsync(string Url, SignWith SignWith)
Gets an attachment from a Trust Provider
Task GetSchema(string Namespace, EventHandlerAsync< SchemaEventArgs > Callback, object State)
Gets a schema.
async Task SignContract(string Address, Contract Contract, string Role, bool Transferable, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Signs a contract
Task SelectPeerReviewService(string ComponentAddress, string Provider, string ServiceId, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Selects a service provider for peer review. This needs to be done before requesting the trust provide...
Task< LegalIdentity > ObsoleteLegalIdentityAsync(string LegalIdentityId)
Obsoletes one of the legal identities of the account, given its ID.
Task SendContractProposal(Contract Contract, string Role, string To)
Sends a contract proposal to a recipient. If the contract contains encrypted parameters,...
Task PetitionSignatureResponseAsync(string Address, string LegalId, byte[] Content, byte[] Signature, string PetitionId, string RequestorFullJid, bool Response)
Sends a response to a petition for a signature by the client. When a petition is received,...
Task< ServiceProviderWithLegalId[]> GetPeerReviewIdServiceProvidersAsync()
Gets available service providers who can help review an ID application.
Task Search(SearchFilter[] Filter, EventHandlerAsync< SearchResultEventArgs > Callback, object State)
Performs a search of public smart contracts.
Task ObsoleteLegalIdentity(string LegalIdentityId, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Obsoletes one of the legal identities of the account, given its ID.
SymmetricCipherAlgorithms PreferredEncryptionAlgorithm
Preferred Encryption Algorithm
Task Validate(LegalIdentity Identity, EventHandlerAsync< IdentityValidationEventArgs > Callback, object State)
Validates a legal identity.
ulong RandomInteger()
Creates a random long unsigned integer.
Task PetitionIdentityAsync(string LegalId, string PetitionId, string Purpose)
Sends a petition to the owner of a legal identity, to access the information in the identity....
const string NamespaceSmartContractsNeuroFoundationV1
urn:nf:iot:leg:sc:1.0
async Task< IdApplicationAttributesEventArgs > GetIdApplicationAttributesAsync()
Gets attributes relevant for application for legal identities on the broker.
Task< bool > LoadKeys(bool CreateIfNone)
Loads keys from the underlying persistence layer.
async Task< NetworkIdentity[]> GetContractNetworkIdentitiesAsync(string Address, string ContractId)
Gets available network identities related to a contract.
Task ReadyForApproval(string LegalIdentityId, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Marks an Identity as Ready for Approval. Call this after necessary attachments have been added....
const string NamespaceLegalIdentitiesIeeeV1
urn:ieee:iot:leg:id:1.0
Task< LegalIdentity > GetLegalIdentityAsync(string LegalIdentityId)
Gets legal identity registered with the account.
bool? ValidateSignature(LegalIdentity Identity, Stream Data, byte[] Signature)
Validates a signature of binary data.
Task PetitionSignatureAsync(string Address, string LegalId, byte[] Content, string PetitionId, string Purpose, string ContextXml)
Sends a petition to a third party to request a digital signature of some content. The petition is not...
Task< byte[]> GetSchemaAsync(string Namespace, SchemaDigest Digest)
Gets a schema.
Task< SearchResultEventArgs > SearchAsync(int Offset, int MaxCount, SearchFilter[] Filter)
Performs a search of public smart contracts.
Task CreateContract(string Address, string TemplateId, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Creates a new contract from a template.
Task< ContractStatus > ValidateAsync(Contract Contract)
Validates a smart contract.
Task< ContractsEventArgs > GetCreatedContractsAsync()
Get contracts the account has created.
Task AuthorizeAccessToIdAsync(string LegalId, string RemoteId, bool Authorized)
Authorizes access to (or revokes access to) a Legal ID of the caller.
async Task PetitionSignatureResponseAsync(string Address, string LegalId, byte[] Content, byte[] Signature, string PetitionId, string RequestorFullJid, bool Response, string ContextXml)
Sends a response to a petition for a signature by the client. When a petition is received,...
async Task< LegalIdentity > CompromisedLegalIdentityAsync(string Address, string LegalIdentityId)
Reports as Compromised one of the legal identities of the account, given its ID.
Task PetitionSignatureResponseAsync(string LegalId, byte[] Content, byte[] Signature, string PetitionId, string RequestorFullJid, bool Response)
Sends a response to a petition for a signature by the client. When a petition is received,...
ContractsClient(XmppClient Client, string ComponentAddress, object[] ApprovedSources)
Adds support for legal identities, smart contracts and signatures to an XMPP client.
async Task EnableE2eEncryption(EndpointSecurity E2eEndpoint, bool CreateKeysIfNone)
Enables End-to-End encryption with a separate set of keys.
Task GetMatchingLocalKey(EventHandlerAsync< KeyEventArgs > Callback, object State)
Get the local key that matches the server key.
Task< SchemaReference[]> GetSchemasAsync()
Gets available schemas.
void SetAllowedSources(object[] ApprovedSources)
If access to sensitive methods is only accessible from a set of approved sources.
Task GetContracts(string Address, string[] ContractIds, EventHandlerAsync< ContractsEventArgs > Callback, object State)
Gets a collection of contracts
Task ObsoleteContract(string ContractId, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Obsoletes a contract
async Task< ContractsEventArgs > GetSignedContractsAsync(string Address, int Offset, int MaxCount)
Get contracts the account has signed.
Task GetSchema(string Address, string Namespace, EventHandlerAsync< SchemaEventArgs > Callback, object State)
Gets a schema.
Task GetLegalIdentities(string Address, EventHandlerAsync< LegalIdentitiesEventArgs > Callback, object State)
Gets legal identities registered with the account.
const string NamespaceLegalIdentitiesNeuroFoundationV1
urn:nf:iot:leg:id:1.0
async Task< ServiceProviderWithLegalId[]> GetPeerReviewIdServiceProvidersAsync(string ComponentAddress)
Gets available service providers who can help review an ID application.
Task< bool > HasPrivateKey(LegalIdentity Identity)
Checks if the private key of a legal identity is available. Private keys are required to be able to s...
Task DeleteContract(string ContractId, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Deletes a contract
Task GetCreatedContractReferences(int Offset, int MaxCount, EventHandlerAsync< IdReferencesEventArgs > Callback, object State)
Get references to contracts the account has created.
string ContractKeySettingsPrefix
Prefix for contract key runtime settings.
Task Search(string Address, SearchFilter[] Filter, EventHandlerAsync< SearchResultEventArgs > Callback, object State)
Performs a search of public smart contracts.
Task Search(string Address, int Offset, int MaxCount, SearchFilter[] Filter, EventHandlerAsync< SearchResultEventArgs > Callback, object State)
Performs a search of public smart contracts.
Task< IdentityStatus > ValidateAsync(LegalIdentity Identity)
Validates a legal identity.
Task Sign(byte[] Data, SignWith SignWith, EventHandlerAsync< SignatureEventArgs > Callback, object State)
Signs binary data with the corresponding private key.
Task PetitionContractAsync(string ContractId, string PetitionId, string Purpose)
Sends a petition to the parts of a smart contract, to access the information in the contract....
Task GetSignedContracts(string Address, int Offset, int MaxCount, EventHandlerAsync< ContractsEventArgs > Callback, object State)
Get contracts the account has signed.
Task AuthorizeAccessToId(string LegalId, string RemoteId, bool Authorized, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Authorizes access to (or revokes access to) a Legal ID of the caller.
async Task< LegalIdentity > AddLegalIdAttachmentAsync(string LegalId, string GetUrl, byte[] Signature)
Adds an attachment to a newly created legal identity.
DateTime KeysTimestamp
Timestamps of current keys used for signatures.
Task< LegalIdentity[]> GetContractLegalIdentitiesAsync(string Address, string ContractId)
Gets available legal identities related to a contract.
async Task< Contract > CreateContractAsync(string Address, string TemplateId, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate)
Creates a new contract from a template.
async Task EnableE2eEncryption(bool UseLocalKeys, bool CreateKeysIfNone)
Defines if End-to-End encryption should use the keys used by the contracts client to perform signatur...
async Task PetitionIdentityResponseAsync(string Address, string LegalId, string PetitionId, string RequestorFullJid, bool Response, string ContextXml)
Sends a response to a petition for information about a legal identity. When a petition is received,...
Task CreateContract(string Address, XmlElement ForMachines, HumanReadableText[] ForHumans, Role[] Roles, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Creates a new contract.
Task SignContract(Contract Contract, string Role, bool Transferable, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Signs a contract
Task GetCreatedContractReferences(string Address, int Offset, int MaxCount, EventHandlerAsync< IdReferencesEventArgs > Callback, object State)
Get references to contracts the account has created.
Task< string > GetLatestApprovedLegalId()
Gets the latest approved Legal ID.
Task AddContractAttachment(string ContractId, string GetUrl, byte[] Signature, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Adds an attachment to a proposed or approved contract before it is being signed.
Task< LegalIdentity > CompromisedLegalIdentityAsync(string LegalIdentityId)
Reports as Compromised one of the legal identities of the account, given its ID.
const SymmetricCipherAlgorithms DefaultCipherAlgorithm
Default cipher name for encrypted parameters, if an algorithm is not explicitly defined.
Task GetContractNetworkIdentities(string Address, string ContractId, EventHandlerAsync< NetworkIdentitiesEventArgs > Callback, object State)
Gets available network identities related to a contract.
Task GetContractLegalIdentities(string ContractId, bool Current, bool Historic, EventHandlerAsync< LegalIdentitiesEventArgs > Callback, object State)
Gets available legal identities related to a contract.
Task SelectPeerReviewService(string Provider, string ServiceId, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Selects a service provider for peer review. This needs to be done before requesting the trust provide...
async Task Apply(string Address, Property[] Properties, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Applies for a legal identity to be registered.
Task< Contract > GetContractAsync(string ContractId)
Gets a contract
async Task CreateContract(string Address, string TemplateId, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate, IParameterEncryptionAlgorithm Algorithm, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Creates a new contract from a template.
Task AuthorizeAccessToId(string Address, string LegalId, string RemoteId, bool Authorized, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Authorizes access to (or revokes access to) a Legal ID of the caller.
async Task< IE2eEndpoint > GetMatchingLocalKeyAsync(string Address)
Get the local key that matches a given server key.
string GetTrustProvider(string EntityId)
Gets the trust provider hosting an entity with a given ID, in the form of LocalId@Provider.
async Task< Contract > CreateContractAsync(string Address, XmlElement ForMachines, HumanReadableText[] ForHumans, Role[] Roles, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate)
Creates a new contract.
Task GetIdApplicationAttributes(EventHandlerAsync< IdApplicationAttributesEventArgs > Callback, object State)
Gets attributes relevant for application for legal identities on the broker.
Task PetitionPeerReviewIDAsync(string Address, string LegalId, LegalIdentity Identity, string PetitionId, string Purpose)
Sends a petition to a third party to peer review a new legal identity. The petition is not guaranteed...
async Task< byte[]> SignAsync(string Address, Stream Data, SignWith SignWith)
Signs binary data with the corresponding private key.
async Task ExportKeys(XmlWriter Output)
Exports Keys to XML.
Task PetitionContractAsync(string Address, string ContractId, string PetitionId, string Purpose)
Sends a petition to the parts of a smart contract, to access the information in the contract....
Task< NetworkIdentity[]> GetContractNetworkIdentitiesAsync(string ContractId)
Gets available network identities related to a contract.
Task< LegalIdentity[]> GetContractLegalIdentitiesAsync(string ContractId, bool Current, bool Historic)
Gets available legal identities related to a contract.
async Task< Contract > GetContractAsync(string Address, string ContractId)
Gets a contract
async Task< bool > ImportKeys(XmlElement Xml)
Imports keys
async Task PetitionContractAsync(string Address, string ContractId, string PetitionId, string Purpose, string ContextXml)
Sends a petition to the parts of a smart contract, to access the information in the contract....
Task< IE2eEndpoint > GetServerPublicKeyAsync()
Gets the server public key.
async Task< Contract > ObsoleteContractAsync(string Address, string ContractId)
Obsoletes a contract
Task GetContract(string Address, string ContractId, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Gets a contract
async Task< LegalIdentity[]> GetLegalIdentitiesAsync(string Address)
Gets legal identities registered with the account.
async Task< ContractsEventArgs > GetContractsAsync(string[] ContractIds)
Gets a collection of contracts
Task< byte[]> SignAsync(byte[] Data, SignWith SignWith)
Signs binary data with the corresponding private key.
ContractsClient(XmppClient Client, string ComponentAddress)
Adds support for legal identities, smart contracts and signatures to an XMPP client.
async Task PetitionContractResponseAsync(string Address, string ContractId, string PetitionId, string RequestorFullJid, bool Response, string ContextXml)
Sends a response to a petition to access a smart contract. When a petition for a contract is received...
Task GetSchemas(EventHandlerAsync< SchemaReferencesEventArgs > Callback, object State)
Gets available schemas.
async Task SendContractProposal(Contract Contract, string Role, string To, string Message)
Sends a contract proposal to a recipient. If the contract contains encrypted parameters,...
static string ContractIdUriString(string ContractId)
Contract identity URI, as a string.
Task< string[]> GetSignedContractReferencesAsync(int Offset, int MaxCount)
Get references to contracts the account has signed.
Task GetSignedContracts(string Address, EventHandlerAsync< ContractsEventArgs > Callback, object State)
Get contracts the account has signed.
const string NamespaceOnboarding
http://waher.se/schema/Onboarding/v1.xsd
async Task SelectPeerReviewServiceAsync(string ComponentAddress, string Provider, string ServiceId)
Selects a service provider for peer review. This needs to be done before requesting the trust provide...
static readonly string[] NamespacesSmartContracts
Namespaces supported for smart contracts.
Task GetCreatedContracts(string Address, int Offset, int MaxCount, EventHandlerAsync< ContractsEventArgs > Callback, object State)
Get contracts the account has created.
async Task AuthorizeAccessToContractAsync(string Address, string ContractId, string RemoteId, bool Authorized)
Authorizes access to (or revokes access to) a Contract of which the caller is part and can access.
Task PetitionContractResponseAsync(string ContractId, string PetitionId, string RequestorFullJid, bool Response)
Sends a response to a petition to access a smart contract. When a petition for a contract is received...
Task AuthorizeAccessToContract(string Address, string ContractId, string RemoteId, bool Authorized, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Authorizes access to (or revokes access to) a Contract of which the caller is part and can access.
Task ReadyForApprovalAsync(string LegalIdentityId)
Marks an Identity as Ready for Approval. Call this after necessary attachments have been added....
async Task< LegalIdentity > AddPeerReviewIDAttachment(LegalIdentity Identity, LegalIdentity ReviewerLegalIdentity, byte[] PeerSignature)
Adds an attachment to a legal identity with information about a peer review of the identity.
async Task< KeyValuePair< string, TemporaryFile > > GetAttachmentAsync(string Url, SignWith SignWith, int Timeout)
Gets an attachment from a Trust Provider
Task< Contract > UpdateContractAsync(Contract Contract)
Updates a contract
Task< LegalIdentity[]> GetLegalIdentitiesAsync()
Gets legal identities registered with the account.
async Task< string > ExportKeys()
Exports Keys to XML.
Task GetLegalIdentity(string Address, string LegalIdentityId, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Gets information about a legal identity given its ID.
Task< Contract > SignContractAsync(Contract Contract, string Role, bool Transferable)
Signs a contract
Task GetContract(string ContractId, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Gets a contract
async Task< Contract > RemoveContractAttachmentAsync(string AttachmentId)
Removes an attachment from a proposed or approved contract before it is being signed.
Task UpdateContract(Contract Contract, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Updates a contract
async Task AuthorizeAccessToIdAsync(string Address, string LegalId, string RemoteId, bool Authorized)
Authorizes access to (or revokes access to) a Legal ID of the caller.
Task AuthorizeAccessToContract(string ContractId, string RemoteId, bool Authorized, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Authorizes access to (or revokes access to) a Contract of which the caller is part and can access.
Task< SearchResultEventArgs > SearchAsync(SearchFilter[] Filter)
Performs a search of public smart contracts.
Task PetitionIdentityResponseAsync(string LegalId, string PetitionId, string RequestorFullJid, bool Response, string ContextXml)
Sends a response to a petition for information about a legal identity. When a petition is received,...
Task< LegalIdentity[]> GetContractLegalIdentitiesAsync(string ContractId)
Gets available legal identities related to a contract.
override void Dispose()
Disposes of the extension.
Task RemoveContractAttachment(string AttachmentId, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Removes an attachment from a proposed or approved contract before it is being signed.
Task GetSchemas(string Address, EventHandlerAsync< SchemaReferencesEventArgs > Callback, object State)
Gets available schemas.
async Task< SearchResultEventArgs > SearchAsync(string Address, int Offset, int MaxCount, SearchFilter[] Filter)
Performs a search of public smart contracts.
Task< IE2eEndpoint > GetMatchingLocalKeyAsync()
Get the local key that matches the server key.
Task< LegalIdentity > ValidateSignatureAsync(string LegalId, byte[] Data, byte[] Signature)
Validates a signature of binary data.
async Task< byte[]> SignAsync(string Address, byte[] Data, SignWith SignWith)
Signs binary data with the corresponding private key.
Task< string[]> GetSignedContractReferencesAsync()
Get references to contracts the account has signed.
Task AddLegalIdAttachment(string LegalId, string GetUrl, byte[] Signature, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Adds an attachment to a newly created legal identity.
Task GetSchema(string Address, string Namespace, SchemaDigest Digest, EventHandlerAsync< SchemaEventArgs > Callback, object State)
Gets a schema.
async Task CreateContract(string Address, XmlElement ForMachines, HumanReadableText[] ForHumans, Role[] Roles, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate, IParameterEncryptionAlgorithm Algorithm, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Creates a new contract.
async Task Sign(string Address, byte[] Data, SignWith SignWith, EventHandlerAsync< SignatureEventArgs > Callback, object State)
Signs binary data with the corresponding private key.
int RandomInteger(int MinInclusive, int MaxInclusive)
Creates a random number in a range.
Task PetitionSignatureAsync(string LegalId, byte[] Content, string PetitionId, string Purpose)
Sends a petition to a third party to request a digital signature of some content. The petition is not...
Task< SearchResultEventArgs > SearchAsync(string Address, SearchFilter[] Filter)
Performs a search of public smart contracts.
Task RemoveLegalIdAttachment(string AttachmentId, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Removes an attachment from a newly created legal identity.
Task Search(int Offset, int MaxCount, SearchFilter[] Filter, EventHandlerAsync< SearchResultEventArgs > Callback, object State)
Performs a search of public smart contracts.
Task CreateContract(string TemplateId, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Creates a new contract from a template.
Task GetCreatedContracts(int Offset, int MaxCount, EventHandlerAsync< ContractsEventArgs > Callback, object State)
Get contracts the account has created.
Task EnableE2eEncryption(bool UseLocalKeys)
Defines if End-to-End encryption should use the keys used by the contracts client to perform signatur...
Task PetitionPeerReviewIDAsync(string LegalId, LegalIdentity Identity, string PetitionId, string Purpose)
Sends a petition to a third party to peer review a new legal identity. The petition is not guaranteed...
Task GetSignedContractReferences(string Address, int Offset, int MaxCount, EventHandlerAsync< IdReferencesEventArgs > Callback, object State)
Get references to contracts the account has signed.
Task GetLegalIdentities(EventHandlerAsync< LegalIdentitiesEventArgs > Callback, object State)
Gets legal identities registered with the account.
Task< string[]> GetCreatedContractReferencesAsync(string Address)
Get references to contracts the account has created.
async Task< LegalIdentity > ObsoleteLegalIdentityAsync(string Address, string LegalIdentityId)
Obsoletes one of the legal identities of the account, given its ID.
async Task GetContracts(string[] ContractIds, EventHandlerAsync< ContractsEventArgs > Callback, object State)
Gets a collection of contracts
Task GetSignedContracts(EventHandlerAsync< ContractsEventArgs > Callback, object State)
Get contracts the account has signed.
Task ValidateSignature(string LegalId, byte[] Data, byte[] Signature, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Validates a signature of binary data.
Task GetPeerReviewIdServiceProviders(string ComponentAddress, EventHandlerAsync< ServiceProvidersEventArgs< ServiceProviderWithLegalId > > Callback, object State)
Gets available service providers who can help review an ID application.
Task< Contract > CreateContractAsync(XmlElement ForMachines, HumanReadableText[] ForHumans, Role[] Roles, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate)
Creates a new contract.
override string[] Extensions
Implemented extensions.
Task SendContractProposal(string ContractId, string Role, string To)
Sends a contract proposal to a recipient.
Task< Contract > DeleteContractAsync(string ContractId)
Deletes a contract
async Task< bool > CanSignAs(CaseInsensitiveString ReferenceId, CaseInsensitiveString SignatoryId)
Checks if an identity can sign for another reference identity (i.e. the old might have been obsoleted...
Task EnableE2eEncryption(EndpointSecurity E2eEndpoint)
Enables End-to-End encryption with a separate set of keys.
async Task GetServerPublicKey(string Address, EventHandlerAsync< KeyEventArgs > Callback, object State)
Gets the server public key.
async Task< Contract > SignContractAsync(string Address, Contract Contract, string Role, bool Transferable)
Signs a contract
Task GetLegalIdentity(string LegalIdentityId, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Gets information about a legal identity given its ID.
Task< ContractsEventArgs > GetSignedContractsAsync(int Offset, int MaxCount)
Get contracts the account has signed.
async Task< Contract > AddContractAttachmentAsync(string ContractId, string GetUrl, byte[] Signature)
Adds an attachment to a proposed or approved contract before it is being signed.
Task< byte[]> SignAsync(Stream Data, SignWith SignWith)
Signs binary data with the corresponding private key.
Task PetitionContractResponseAsync(string ContractId, string PetitionId, string RequestorFullJid, bool Response, string ContextXml)
Sends a response to a petition to access a smart contract. When a petition for a contract is received...
Task GetServerPublicKey(EventHandlerAsync< KeyEventArgs > Callback, object State)
Gets the server public key.
async Task< bool > HasPrivateKey(string IdentityId)
Checks if the private key of a legal identity is available. Private keys are required to be able to s...
async Task< IE2eEndpoint > GetServerPublicKeyAsync(string Address)
Gets the server public key.
Task< string[]> GetCreatedContractReferencesAsync(int Offset, int MaxCount)
Get references to contracts the account has created.
Task< string[]> GetCreatedContractReferencesAsync()
Get references to contracts the account has created.
void SetPreferredEncryptionAlgorithm(SymmetricCipherAlgorithms Algorithm, bool Lock)
Sets the preferred encryption algorithm.
Task< ContractsEventArgs > GetSignedContractsAsync()
Get contracts the account has signed.
async Task Sign(string Address, Stream Data, SignWith SignWith, EventHandlerAsync< SignatureEventArgs > Callback, object State)
Signs binary data with the corresponding private key.
async Task< string > GetLatestApprovedLegalId(byte[] PublicKey)
Gets the (latest) approved Legal ID whose public key matches PublicKey .
async Task< LegalIdentity > ValidateSignatureAsync(string Address, string LegalId, byte[] Data, byte[] Signature)
Validates a signature of binary data.
Task Apply(Property[] Properties, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Applies for a legal identity to be registered.
async Task< Contract > UpdateContractAsync(string Address, Contract Contract)
Updates a contract
async Task Validate(LegalIdentity Identity, bool ValidateState, EventHandlerAsync< IdentityValidationEventArgs > Callback, object State)
Validates a legal identity.
Task ReadyForApproval(string Address, string LegalIdentityId, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Marks an Identity as Ready for Approval. Call this after necessary attachments have been added....
Task AuthorizeAccessToContractAsync(string ContractId, string RemoteId, bool Authorized)
Authorizes access to (or revokes access to) a Contract of which the caller is part and can access.
Task GetSignedContracts(int Offset, int MaxCount, EventHandlerAsync< ContractsEventArgs > Callback, object State)
Get contracts the account has signed.
Task GetSignedContractReferences(string Address, EventHandlerAsync< IdReferencesEventArgs > Callback, object State)
Get references to contracts the account has signed.
async Task PetitionIdentityAsync(string Address, string LegalId, string PetitionId, string Purpose, string ContextXml)
Sends a petition to the owner of a legal identity, to access the information in the identity....
const string NamespaceSmartContractsCurrent
Current namespce for smart contracts.
Task< Contract > CreateContractAsync(string TemplateId, Part[] Parts, Parameter[] Parameters, ContractVisibility Visibility, ContractParts PartsMode, Duration? Duration, Duration? ArchiveRequired, Duration? ArchiveOptional, DateTime? SignAfter, DateTime? SignBefore, bool CanActAsTemplate)
Creates a new contract from a template.
Task< byte[]> GetSchemaAsync(string Namespace)
Gets a schema.
const string NamespaceSmartContractsIeeeV1
urn:ieee:iot:leg:sc:1.0
async Task< LegalIdentity > GetLegalIdentityAsync(string Address, string LegalIdentityId)
Gets legal identity registered with the account.
static string LegalIdUriString(string LegalId)
Legal identity URI, as a string.
Task ObsoleteContract(string Address, string ContractId, EventHandlerAsync< SmartContractEventArgs > Callback, object State)
Obsoletes a contract
Task CompromisedLegalIdentity(string Address, string LegalIdentityId, EventHandlerAsync< LegalIdentityEventArgs > Callback, object State)
Reports as Compromised one of the legal identities of the account, given its ID.
void SetKeySettingsInstance(string InstanceName, bool Locked)
Sets the key settings instance name.
Task< Contract > ObsoleteContractAsync(string ContractId)
Obsoletes a contract
Task GetCreatedContractReferences(EventHandlerAsync< IdReferencesEventArgs > Callback, object State)
Get references to contracts the account has created.
Task< ContractsEventArgs > GetCreatedContractsAsync(int Offset, int MaxCount)
Get contracts the account has created.
static readonly string[] NamespacesLegalIdentities
Namespaces supported for legal identities.
async Task< ContractsEventArgs > GetContractsAsync(string Address, string[] ContractIds)
Gets a collection of contracts
const string NamespaceLegalIdentitiesCurrent
Current namespace for legal identities.
async Task SendContractProposal(string ContractId, string Role, string To, string Message, byte[] Key, SymmetricCipherAlgorithms KeyAlgorithm)
Sends a contract proposal to a recipient.
string ComponentAddress
Component address.
async Task GetMatchingLocalKey(string Address, EventHandlerAsync< KeyEventArgs > Callback, object State)
Get the local key that matches a given server key.
async Task< string[]> GetSignedContractReferencesAsync(string Address, int Offset, int MaxCount)
Get references to contracts the account has signed.
static Uri LegalIdUri(string LegalId)
Legal identity URI.
Task PetitionIdentityResponseAsync(string Address, string LegalId, string PetitionId, string RequestorFullJid, bool Response)
Sends a response to a petition for information about a legal identity. When a petition is received,...
async Task< byte[]> GetSchemaAsync(string Address, string Namespace, SchemaDigest Digest)
Gets a schema.
Task PetitionSignatureAsync(string Address, string LegalId, byte[] Content, string PetitionId, string Purpose)
Sends a petition to a third party to request a digital signature of some content. The petition is not...
Task GetCreatedContracts(string Address, EventHandlerAsync< ContractsEventArgs > Callback, object State)
Get contracts the account has created.
Task GetContractLegalIdentities(string Address, string ContractId, bool Current, bool Historic, EventHandlerAsync< LegalIdentitiesEventArgs > Callback, object State)
Gets available legal identities related to a contract.
async Task< SchemaReference[]> GetSchemasAsync(string Address)
Gets available schemas.
Task GetContractNetworkIdentities(string ContractId, EventHandlerAsync< NetworkIdentitiesEventArgs > Callback, object State)
Gets available network identities related to a contract.
Event arguments for smart contract petitions
Event arguments for smart contract petition responses
Event arguments for smart contract proposals
Event arguments for events referencing a contract.
Event arguments for contract signature events
Event arguments for identity validation responses
Event arguments for Contracts responses
Event arguments for callback methods to ID Application attributes queries.
Event arguments for ID References responses
Event arguments for identity validation responses
Event arguments for key responses
IE2eEndpoint Key
Public key of server endpoint.
Event arguments for legal identities responses
Event arguments for legal identity responses
Event arguments for legal identity petitions
Event arguments for legal identity petition responses
Event arguments for network identities responses
Event arguments for events where a client URL needs to be displayed when performing a petition.
Event arguments for schema responses
Event arguments for Schema References responses
Event arguments for Search Result responses
Event arguments for Service Provider callback methods.
Event arguments for signature responses
Event arguments for digital signature petitions
Event arguments for signature petition responses
Event arguments for smart contract responses
override async Task< HumanReadableElement > IsWellDefined()
Checks if the element is well-defined.
Class representing human-readable text.
string Namespace
Namespace used when serializing the identity for signatures.
DateTime From
From what point in time the legal identity is valid.
DateTime Updated
When the identity object was last updated
DateTime To
To what point in time the legal identity is valid.
DateTime Created
When the identity object was created
IdentityState State
Current state of identity
byte[] ClientSignature
Client signature
string ClientKeyName
Type of key used for client signatures
string Provider
Provider where the identity is maintained.
byte[] ClientPubKey
Client Public key
byte[] ServerSignature
Server signature
string Id
ID of the legal identity
void Serialize(StringBuilder Xml, bool IncludeNamespace, bool IncludeIdAttribute, bool IncludeClientSignature, bool IncludeAttachments, bool IncludeStatus, bool IncludeServerSignature, bool IncludeAttachmentReferences)
Serializes the identity to XML
static LegalIdentity Parse(XmlElement Xml)
Parses an identity from its XML representation
Attachment[] Attachments
Attachments assigned to the legal identity.
Contains information about a legal identity generated by the client.
DateTime Timestamp
Timestamp when the legal identity was created or last updated.
IdentityState State
State of the legal identity.
CaseInsensitiveString LegalId
Identity string assigned to the legal identity.
byte[] PublicKey
Public Key used by the cryptographic algororithm used to sign the identity application.
HumanReadableText[] Descriptions
Discriptions of the object, in different languages.
Contains a network identity related to a legal identity
Implements parameter encryption using symmetric ciphers avaialble through IE2eSymmetricCipher in the ...
static Task< ParameterEncryptionAlgorithm > Create(SymmetricCipherAlgorithms Algorithm, ContractsClient Client)
Implements parameter encryption using symmetric ciphers avaialble through IE2eSymmetricCipher in the ...
Abstract base class for contractual parameters
abstract void Populate(Variables Variables)
Populates a variable collection with the value of the parameter.
abstract string StringValue
String representation of value.
Task< bool > IsParameterValid(Variables Variables)
Checks if the parameter value is valid.
string Name
Parameter name
byte[] ProtectedValue
Protected value, in case Protection is not equal to ProtectionLevel.Normal.
abstract string ParameterType
Parameter type name, corresponding to the local name of the parameter element in XML.
abstract object ObjectValue
Parameter value.
void Serialize(StringBuilder Xml)
Serializes the parameter, in normalized form.
ProtectionLevel Protection
Level of confidentiality of the information provided by the parameter.
Contains information about a parsed contract.
Contract Contract
Contract object
Class defining a part in a contract
string LegalId
Legal identity of part
string Role
Role of the part in the contract
HashFunction Function
Hash Function used to calculate the digest.
byte[] Digest
Hash Digest of schema file
References a XML Schema used for validating machine-readable contents in smart contracts.
Abstract base class for Smart Contract Search filters.
Contains information about a service provider with a legal identity.
Abstract base class of signatures
byte[] DigitalSignature
Digital Signature
Event arguments for responses to IQ queries.
bool Ok
If the response is an OK result response (true), or an error response (false).
object State
State object passed to the original request.
XmppException StanzaError
Any stanza error returned.
XmlElement FirstElement
First child element of the Response element.
Event arguments for message events.
string Id
ID attribute of message stanza.
string From
From where the message was received.
XmlElement Message
The message stanza.
string FromBareJID
Bare JID of resource sending the message.
bool Ok
If the response is an OK result response (true), or an error response (false).
string To
To whom the message was sent.
bool UsesE2eEncryption
If end-to-end encryption was used in the request.
XmlElement Content
Content of the message. For messages that are processed by registered message handlers,...
XmppException StanzaError
Any stanza error returned.
Class managing HTTP File uploads, as defined in XEP-0363.
Task< HttpFileUploadEventArgs > RequestUploadSlotAsync(string FileName, string ContentType, long ContentSize)
Uploads a file to the upload component.
Event arguments for HTTP File Upload callback methods.
async Task PUT(byte[] Content, string ContentType, int Timeout)
Uploads file content to the server.
Abstract base class for End-to-End encryption schemes.
Abstract base class for Elliptic Curve endpoints.
RSA / AES-256 hybrid cipher.
override bool Verify(byte[] Data, byte[] Signature)
Verifies a signature.
Class managing end-to-end encryption.
static bool TryGetEndpoint(string LocalName, string Namespace, out IE2eEndpoint Endpoint)
Tries to get an existing endpoint, given its qualified name.
static IE2eEndpoint[] CreateEndpoints(int DesiredSecurityStrength, int MinSecurityStrength, int MaxSecurityStrength)
Creates a set of endpoints within a range of security strengths.
Task SendMessage(XmppClient Client, E2ETransmission E2ETransmission, QoSLevel QoS, MessageType Type, string Id, string To, string CustomXml, string Body, string Subject, string Language, string ThreadId, string ParentThreadId, EventHandlerAsync< DeliveryEventArgs > DeliveryCallback, object State)
Sends an XMPP message to an endpoint.
Maintains information about an item in the roster.
string LastPresenceFullJid
Full JID of last resource sending online presence.
The addressed JID or item requested cannot be found; the associated error type SHOULD be "cancel".
Manages an XMPP client connection. Implements XMPP, as defined in https://tools.ietf....
bool UnregisterMessageHandler(string LocalName, string Namespace, EventHandlerAsync< MessageEventArgs > Handler, bool RemoveNamespaceAsClientFeature)
Unregisters a Message handler.
static string GetDomain(string JID)
Gets the domain part of a JID.
static string GetBareJID(string JID)
Gets the Bare JID from a JID, which may be a Full JID.
void RegisterMessageHandler(string LocalName, string Namespace, EventHandlerAsync< MessageEventArgs > Handler, bool PublishNamespaceAsClientFeature)
Registers a Message handler.
Task< uint > SendIqGet(string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Sends an IQ Get request.
Base class for XMPP Extensions.
XmppClient client
XMPP Client used by the extension.
Task Exception(Exception Exception)
Called to inform the viewer of an exception state.
XmppClient Client
XMPP Client.
Represents a case-insensitive string.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static async Task Update(object Object)
Updates an object in the database.
static async Task Delete(object Object)
Deletes an object in the database.
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
This filter selects objects that conform to all child-filters provided.
This filter selects objects that have a named field equal to a given value.
Base class for all filter classes.
Implements an in-memory cache.
void Dispose()
IDisposable.Dispose
Static class that dynamically manages types and interfaces available in the runtime environment.
static bool UnregisterSingleton(object Object, params object[] Arguments)
Unregisters a singleton instance of a type.
static object Instantiate(Type Type, params object[] Arguments)
Returns an instance of the type Type . If one needs to be created, it is. If the constructor requires...
static void RegisterSingleton(object Object, params object[] Arguments)
Registers a singleton instance of a type.
Class that keeps track of events and timing for one thread.
ProfilerThread CreateSubThread(string Name, ProfilerThreadType Type)
Creates a new profiler thread.
void Start()
Processing starts.
void Stop()
Processing starts.
void NewState(string State)
Thread changes state.
Static class managing persistent settings.
static Task< int > DeleteWhereKeyLikeAsync(string Key, string Wildcard)
Deletes available settings, matching a search filter.
static Task< Dictionary< string, object > > GetWhereKeyLikeAsync(string Key, string Wildcard)
Gets available settings, matching a search filter.
static async Task< string > GetAsync(string Key, string DefaultValue)
Gets a string-valued setting.
static async Task< bool > SetAsync(string Key, string Value)
Sets a string-valued setting.
Class managing the contents of a temporary file. When the class is disposed, the temporary file is de...
override void Dispose(bool disposing)
Disposes of the object, and deletes the temporary file.
Static class containing methods that can be used to make sure calls are made from appropriate locatio...
static void CallFromSource(params string[] Sources)
Makes sure the call is made from one of the listed sources.
Abstract base class for elliptic curves.
virtual void Export(XmlWriter Output)
Exports the curve parameters to XML.
Contains methods for simple hash calculations.
static byte[] ComputeSHA256Hash(byte[] Data)
Computes the SHA-256 hash of a block of binary data.
Interface for parameter encryption algorithms.
byte[] Encrypt(string ParameterName, string ParameterType, uint ParameterIndex, string CreatorJid, byte[] ContractNonce, string ClearText)
Encrypts a parameter value.
SymmetricCipherAlgorithms Algorithm
Symmetric Cipher Algorithm used to encrypt parameters.
Abstract base class for End-to-End encryption schemes.
byte[] Sign(byte[] Data)
Signs binary data using the local private key.
byte[] GetSharedSecret(IE2eEndpoint RemoteEndpoint)
Gets a shared secret
byte[] PublicKey
Remote public key.
IE2eEndpoint CreatePrivate(byte[] Secret)
Creates a new endpoint given a private key.
IE2eEndpoint CreatePublic(byte[] PublicKey)
Creates a new endpoint given a public key.
string LocalName
Local name of the E2E endpoint
delegate Task EventHandlerAsync(object Sender, EventArgs e)
Asynchronous version of EventArgs.
IdentityState
Lists recognized legal identity states.
SignWith
Options on what keys to use when signing data.
ContractParts
How the parts of the contract are defined.
ContractStatus
Validation Status of smart contract
ProtectionLevel
Parameter protection levels
ContractVisibility
Visibility types for contracts.
ContractState
Recognized contract states
IdentityStatus
Validation Status of legal identity
SymmetricCipherAlgorithms
Enumeration of symmetric cipher algorithms available in the library.
QoSLevel
Quality of Service Level for asynchronous messages. Support for QoS Levels must be supported by the r...
MessageType
Type of message received.
E2ETransmission
End-to-end encryption mode.
ProfilerThreadType
Type of profiler thread.
HashFunction
Hash method enumeration.
Represents a duration value, as defined by the xsd:duration data type: http://www....
override string ToString()