4using System.Reflection;
6using System.Threading.Tasks;
25 private static readonly Random rnd =
new Random();
75 private static Dictionary<string, IE2eEndpoint> endpointTypes =
new Dictionary<string, IE2eEndpoint>();
76 private static bool initialized =
false;
77 private static Type[] e2eTypes =
null;
78 private static bool e2eTypesLocked =
false;
80 private readonly Dictionary<string, RemoteEndPoints> contacts;
83 private Dictionary<string, IE2eEndpoint> oldKeys =
null;
84 private Dictionary<string, IE2eEndpoint> keys =
null;
87 private readonly Guid instanceId = Guid.NewGuid();
88 private readonly UTF8Encoding encoding =
new UTF8Encoding(
false,
false);
89 private readonly
object synchObject =
new object();
90 private readonly
int securityStrength;
91 private readonly
bool ephemeralKeys;
96 private class RemoteEndPoints
98 public Dictionary<string, IE2eEndpoint> ByFqn;
111 : this(
Client, null, SecurityStrength)
122 : this(
Client, ServerlessMessaging, SecurityStrength, null)
133 : this(
Client, null, SecurityStrength, LocalEndpoints)
148 this.securityStrength = SecurityStrength;
150 this.serverlessMessaging = ServerlessMessaging;
151 this.contacts =
new Dictionary<string, RemoteEndPoints>(StringComparer.CurrentCultureIgnoreCase);
153 if (LocalEndpoints is
null)
156 this.ephemeralKeys =
true;
159 this.ephemeralKeys =
false;
161 this.keys =
new Dictionary<string, IE2eEndpoint>();
162 this.keysSorted =
null;
165 this.keys[Endpoint.Namespace +
"#" + Endpoint.
LocalName] = Endpoint;
167 if (!(this.client is
null))
178 this.keysSorted ??= SortedArray(this.keys);
179 return this.keysSorted;
190 this.oldKeysSorted ??= SortedArray(this.oldKeys);
191 return this.oldKeysSorted;
203 this.serverlessMessaging?.AppendP2pInfo(e.
Stanza);
205 return Task.CompletedTask;
217 return CreateEndpoints(DesiredSecurityStrength, MinSecurityStrength, MaxSecurityStrength,
null);
229 params Type[] OnlyIfDerivedFrom)
231 return CreateEndpoints(DesiredSecurityStrength, MinSecurityStrength, MaxSecurityStrength, OnlyIfDerivedFrom,
null);
252 int i, c = OnlyIfDerivedFrom?.Length ?? 0;
253 TypeInfo[] OnlyIfDerivedFromType = c == 0 ? null :
new TypeInfo[c];
255 for (i = 0; i < c; i++)
256 OnlyIfDerivedFromType[i] = OnlyIfDerivedFrom[i].GetTypeInfo();
258 List<IE2eEndpoint> Result =
new List<IE2eEndpoint>();
259 IEnumerable<IE2eEndpoint> Templates;
260 bool CheckHeritance =
true;
265 Templates = endpointTypes.Values;
268 Dictionary<string, IE2eEndpoint> E2eTypes =
new Dictionary<string, IE2eEndpoint>();
269 Dictionary<string, bool> TypeNames =
new Dictionary<string, bool>();
270 TypeInfo E2eTypeInfo = typeof(
IE2eEndpoint).GetTypeInfo();
272 foreach (KeyValuePair<string, IE2eEndpoint> P
in endpointTypes)
274 E2eTypes[P.Key] = P.Value;
275 TypeNames[P.Value.GetType().FullName] =
true;
280 if (TypeNames.ContainsKey(T.FullName))
283 TypeInfo TI = T.GetTypeInfo();
284 if (!(e2eTypes is
null) && !E2eTypeInfo.IsAssignableFrom(TI))
289 bool DerivedFrom =
false;
291 for (i = 0; i < c; i++)
293 if (OnlyIfDerivedFromType[i].IsAssignableFrom(TI))
311 E2eTypes[Endpoint.Namespace +
"#" + Endpoint.
LocalName] = Endpoint;
320 endpointTypes = E2eTypes;
321 Templates = E2eTypes.Values;
323 if (OnlyIfDerivedFromType is
null)
326 CheckHeritance =
false;
332 if (CheckHeritance && c > 0)
334 bool DerivedFrom =
false;
336 for (i = 0; i < c; i++)
338 if (OnlyIfDerivedFromType[i].IsAssignableFrom(Endpoint.GetType().GetTypeInfo()))
353 if (i >= MinSecurityStrength && i <= MaxSecurityStrength)
354 Result.Add(Endpoint2);
359 return Result.ToArray();
380 throw new InvalidOperationException(
"Ciphers locked.");
382 e2eTypes = CipherTypes;
383 e2eTypesLocked = Lock;
395 if (Namespace.StartsWith(
"urn:ieee:"))
396 Namespace = Namespace.Replace(
"urn:ieee:",
"urn:nf:");
398 string Key = Namespace +
"#" + LocalName;
400 if (endpointTypes.TryGetValue(Key, out Endpoint))
402 else if (initialized || endpointTypes.Count > 0)
407 return endpointTypes.TryGetValue(Key, out Endpoint);
421 Endpoint = Endpoint.Create(Endpoint.SecurityStrength);
433 if (!(this.client is
null))
439 lock (this.synchObject)
441 if (!(this.oldKeys is
null))
447 if (!(this.keys is
null))
456 foreach (RemoteEndPoints Endpoints
in this.contacts.Values)
458 foreach (
IE2eEndpoint Endpoint
in Endpoints.ByFqn.Values)
462 this.contacts.Clear();
475 private Task Client_OnStateChanged(
object Sender,
XmppState NewState)
477 if (NewState ==
XmppState.RequestingSession &&
this.ephemeralKeys)
480 return Task.CompletedTask;
488 lock (this.synchObject)
492 this.oldKeys = this.keys;
493 this.oldKeysSorted = this.keysSorted;
501 Dictionary<string, IE2eEndpoint> NewKeys =
new Dictionary<string, IE2eEndpoint>();
503 foreach (KeyValuePair<string, IE2eEndpoint> P
in this.keys)
506 NewKey.Previous = P.Value;
507 P.Value.Previous =
null;
508 NewKeys[P.Key] = NewKey;
512 this.keysSorted =
null;
550 if (!(this.client is
null))
557 this.client.
SetTag(
"E2E",
this);
559 #region Neuro-Foundation V1
589 this.client.OnStateChanged += this.Client_OnStateChanged;
590 this.client.OnPresence += this.Client_OnPresence;
591 this.client.CustomPresenceXml += this.Client_CustomPresenceXml;
601 if (this.client ==
Client)
604 #region Neuro-Foundation V1
634 Client.OnStateChanged -= this.Client_OnStateChanged;
635 Client.OnPresence -= this.Client_OnPresence;
636 Client.CustomPresenceXml -= this.Client_CustomPresenceXml;
645 public static Dictionary<string, IE2eEndpoint>
ParseE2eKeys(XmlElement E2E,
int SecurityStrength)
647 Dictionary<string, IE2eEndpoint> Endpoints =
null;
649 foreach (XmlNode N
in E2E.ChildNodes)
651 if (N is XmlElement E)
657 Endpoints ??=
new Dictionary<string, IE2eEndpoint>();
658 Endpoints[Endpoint.Namespace +
"#" + Endpoint.
LocalName] = Endpoint;
674 return Endpoint.
Parse(E);
695 Dictionary<string, IE2eEndpoint> Endpoints =
null;
699 bool HasSymmetricAttributes = Aes || Cha || Acp;
701 if (!HasSymmetricAttributes)
703 if (!E2E.HasAttribute(
"aes") &&
704 !E2E.HasAttribute(
"cha") &&
705 !E2E.HasAttribute(
"acp"))
707 Aes = Cha = Acp =
true;
719 if (Endpoints is
null)
725 bool SymmetricCiphersSupported =
true;
731 SymmetricCiphersSupported =
false;
736 if (!SymmetricCiphersSupported)
750 if (SymmetricCiphers.
Count == 1)
751 SymmetricCipher = SymmetricCiphers.
FirstItem;
756 SymmetricCipher = SymmetricCiphers[rnd.Next(SymmetricCiphers.
Count)];
761 Endpoint.DefaultSymmetricCipher = SymmetricCipher;
764 RemoteEndPoints OldEndpoints;
768 if (!this.contacts.TryGetValue(FullJID, out OldEndpoints))
771 this.contacts[FullJID] =
new RemoteEndPoints()
780 if (!(OldEndpoints is
null))
782 foreach (
IE2eEndpoint Endpoint
in OldEndpoints.ByFqn.Values)
802 RemoteEndPoints Keys;
806 if (!this.contacts.TryGetValue(FullJID, out Keys))
809 this.contacts.Remove(FullJID);
827 return this.contacts.ContainsKey(FullJid);
840 if (this.contacts.TryGetValue(FullJid, out RemoteEndPoints Endpoints))
841 return SortedArray(Endpoints.ByFqn);
844 if (
string.Compare(FullJid, this.client.
BareJID) == 0)
846 StringBuilder Xml =
new StringBuilder();
850 XmlDocument Doc =
XML.
ParseXml(Xml.ToString(),
true);
852 return SortedArray(
ParseE2eKeys(Doc.DocumentElement,
this.securityStrength) ??
new Dictionary<string, IE2eEndpoint>());
858 private static IE2eEndpoint[] SortedArray(Dictionary<string, IE2eEndpoint> Endpoints)
860 int c = Endpoints?.Count ?? 0;
865 Endpoints.Values.CopyTo(Result, 0);
867 Array.Sort(Result, (ep1, ep2) =>
869 int Diff = (ep2.PostQuantumCryptography ? 1 : 0) - (ep1.PostQuantumCryptography ? 1 : 0);
873 Diff = (ep2.Safe ? 1 : 0) - (ep1.Safe ? 1 : 0);
877 Diff = ep2.SecurityStrength - ep1.SecurityStrength;
881 Diff = (ep1.Slow ? 1 : 0) - (ep2.Slow ? 1 : 0);
885 Diff = (ep2.SupportsSignatures ? 1 : 0) - (ep1.SupportsSignatures ? 1 : 0);
889 return ep2.Score - ep1.Score;
906 public Task<KeyValuePair<byte[], IE2eEndpoint>>
Encrypt(
string Id,
string Type,
907 string From,
string To,
byte[] Data)
909 return this.
Encrypt(Id, Type, From, To,
false, 0, Data);
924 public virtual async Task<KeyValuePair<byte[], IE2eEndpoint>>
Encrypt(
string Id,
string Type,
string From,
string To,
925 bool Pqc,
int MinSecurityStrength,
byte[] Data)
927 IE2eEndpoint RemoteEndpoint = this.FindRemoteEndpoint(To, Pqc, MinSecurityStrength);
928 if (RemoteEndpoint is
null)
929 return new KeyValuePair<byte[], IE2eEndpoint>(
null,
null);
932 if (EndpointReference is
null)
933 return new KeyValuePair<byte[], IE2eEndpoint>(
null,
null);
938 return new KeyValuePair<byte[], IE2eEndpoint>(Encrypted, EndpointReference);
952 public virtual Task<byte[]>
Decrypt(
string EndpointReference,
string Id,
string Type,
string From,
string To,
byte[] Data,
955 IE2eEndpoint RemoteEndpoint = this.FindRemoteEndpoint(From, EndpointReference);
956 if (RemoteEndpoint is
null)
960 if (LocalEndpoint is
null)
964 if (!(SymmetricCipher is
null) && Cipher.GetType() != SymmetricCipher.GetType())
965 Cipher = SymmetricCipher;
967 byte[] Decrypted = Cipher.
Decrypt(Id, Type, From, To, Data, RemoteEndpoint, LocalEndpoint);
969 return Task.FromResult(Decrypted);
972 private IE2eEndpoint FindRemoteEndpoint(
string RemoteJid,
bool Pqc,
int MinSecurityStrength)
974 return this.FindRemoteEndpoint(RemoteJid,
null, Pqc, MinSecurityStrength);
977 private IE2eEndpoint FindRemoteEndpoint(
string RemoteJid,
string EndpointReference)
979 return this.FindRemoteEndpoint(RemoteJid, EndpointReference,
false, 0);
982 private IE2eEndpoint FindRemoteEndpoint(
string RemoteJid,
string EndpointReference,
983 bool Pqc,
int MinSecurityStrength)
987 if (!this.contacts.TryGetValue(RemoteJid, out RemoteEndPoints Endpoints))
990 if (EndpointReference is
null)
992 if (Endpoints.Default is
null)
995 IE2eEndpoint LastSafeAndFastAndSignaturesAndPqcAndSharedSecrets =
null;
1001 if (Ordered.Length == 0)
1014 LastSafe = Endpoint;
1018 LastSafeAndFast = Endpoint;
1022 LastSafeAndFastAndSignatures = Endpoint;
1026 LastSafeAndFastAndSignaturesAndPqc = Endpoint;
1029 LastSafeAndFastAndSignaturesAndPqcAndSharedSecrets = Endpoint;
1037 LastSafeAndFastAndSignaturesAndPqcAndSharedSecrets ??
1038 LastSafeAndFastAndSignaturesAndPqc ??
1039 LastSafeAndFastAndSignatures ??
1040 LastSafeAndFast ?? LastSafe ??
1044 return Endpoints.Default;
1047 if (EndpointReference.IndexOf(
'#') < 0)
1050 EndpointReference = EndpointReference.Replace(
"urn:ieee:",
"urn:nf:");
1052 if (Endpoints.ByFqn.TryGetValue(EndpointReference, out
IE2eEndpoint Selected))
1069 public Task<IE2eEndpoint>
Encrypt(
string Id,
string Type,
string From,
1070 string To, Stream Data, Stream Encrypted)
1072 return this.
Encrypt(Id, Type, From, To,
false, 0, Data, Encrypted);
1087 public virtual async Task<IE2eEndpoint>
Encrypt(
string Id,
string Type,
string From,
1088 string To,
bool Pqc,
int MinSecurityStrength, Stream Data, Stream Encrypted)
1090 IE2eEndpoint RemoteEndpoint = this.FindRemoteEndpoint(To, Pqc, MinSecurityStrength);
1091 if (RemoteEndpoint is
null)
1095 if (LocalEndpoint is
null)
1101 return LocalEndpoint;
1115 public virtual async Task<Stream>
Decrypt(
string EndpointReference,
string Id,
string Type,
string From,
string To, Stream Data,
1118 IE2eEndpoint RemoteEndpoint = this.FindRemoteEndpoint(From, EndpointReference);
1119 if (RemoteEndpoint is
null)
1123 if (LocalEndpoint is
null)
1127 if (!(SymmetricCipher is
null) && Cipher.GetType() != SymmetricCipher.GetType())
1128 Cipher = SymmetricCipher;
1130 return await Cipher.
Decrypt(Id, Type, From, To, Data, RemoteEndpoint, LocalEndpoint);
1145 string DataXml, StringBuilder Xml)
1147 return this.
Encrypt(Client, Id, Type, From, To,
false, 0, DataXml, Xml);
1164 string To,
bool Pqc,
int MinSecurityStrength,
string DataXml, StringBuilder Xml)
1166 bool SniffE2eInfo = Client.HasSniffers &&
Client.
TryGetTag(
"ShowE2E", out
object Obj) && Obj is
bool b && b;
1167 IE2eEndpoint RemoteEndpoint = this.FindRemoteEndpoint(To, Pqc, MinSecurityStrength);
1168 if (RemoteEndpoint is
null)
1171 Client.
Warning(
"Remote E2E endpoint not found. Unable to encrypt message.");
1177 if (LocalEndpoint is
null)
1180 Client.
Warning(
"Local E2E endpoint matching remote endpoint not found. Unable to encrypt message.");
1185 byte[] Data = this.encoding.GetBytes(DataXml);
1223 if (
string.IsNullOrEmpty(KeyNamespace))
1226 if (this.keys?.TryGetValue(KeyNamespace +
"#" + KeyName, out
IE2eEndpoint Result) ??
false)
1239 lock (this.synchObject)
1243 if (Endpoint.GetType() == KeyType)
1248 if (!typeof(
IE2eEndpoint).IsAssignableFrom(KeyType.GetTypeInfo()))
1249 throw new ArgumentException(
"Not assignable from " + typeof(
IE2eEndpoint).FullName, nameof(KeyType));
1261 if (PublicKey is
null)
1264 string s = Convert.ToBase64String(PublicKey);
1266 lock (this.synchObject)
1288 int Len = PublicKey?.Length ?? 0;
1290 lock (this.synchObject)
1294 if ((Endpoint.
PublicKey?.Length ?? 0) == Len)
1297 Result.
Add(Endpoint);
1316 public virtual Tuple<string, string>
Decrypt(
XmppClient Client,
string Id,
string Type,
string From,
string To, XmlElement E2eElement,
1319 bool SniffE2eInfo = Client.HasSniffers &&
Client.
TryGetTag(
"ShowE2E", out
object Obj) && Obj is
bool b && b;
1320 string EndpointReference =
XML.
Attribute(E2eElement,
"r");
1321 IE2eEndpoint RemoteEndpoint = this.FindRemoteEndpoint(From, EndpointReference);
1322 if (RemoteEndpoint is
null)
1325 Client.Error(
"Remote E2E endpoint not found. Unable to decrypt message.");
1331 if (LocalEndpoint is
null)
1334 Client.Error(
"Local E2E endpoint matching remote endpoint not found. Unable to decrypt message.");
1340 if (!(SymmetricCipher is
null) && Cipher.GetType() != SymmetricCipher.GetType())
1341 Cipher = SymmetricCipher;
1343 string Xml = Cipher.
Decrypt(Id, Type, From, To, E2eElement, RemoteEndpoint, LocalEndpoint);
1350 return new Tuple<string, string>(Xml, EndpointReference);
1355 return this.E2eMessageHandler(Sender, e, this.aes);
1360 return this.E2eMessageHandler(Sender, e, this.acp);
1365 return this.E2eMessageHandler(Sender, e, this.cha);
1374 this.client.Error(
"Unable to decrypt or verify response.");
1375 return Task.CompletedTask;
1378 string Xml = T.Item1;
1379 string EndpointReference = T.Item2;
1388 E2eEncryption =
this,
1389 E2eReference = EndpointReference
1394 return Task.CompletedTask;
1408 case "aes": Cipher = this.aes;
return true;
1409 case "acp": Cipher = this.acp;
return true;
1410 case "cha": Cipher = this.cha;
return true;
1426 object[] P = (
object[])e.
State;
1427 EventHandlerAsync<IqResultEventArgs> Callback = (EventHandlerAsync<IqResultEventArgs>)P[0];
1428 object State = P[1];
1433 if (!(Cipher is
null))
1435 Tuple<string, string> T = this.
Decrypt(Client, e.
Id, e.
Response.GetAttribute(
"type"), e.
From, e.
To, E, Cipher);
1438 Client.Error(
"Unable to decrypt or verify response.");
1442 string Content = T.Item1;
1443 string EndpointReference = T.Item2;
1444 StringBuilder Xml =
new StringBuilder();
1446 Xml.Append(
"<iq xmlns=\"jabber:client\" id=\"");
1448 Xml.Append(
"\" from=\"");
1450 Xml.Append(
"\" to=\"");
1454 Xml.Append(
"\" type=\"result\">");
1456 Xml.Append(
"\" type=\"error\">");
1458 Xml.Append(Content);
1459 Xml.Append(
"</iq>");
1461 XmlDocument Doc =
XML.
ParseXml(Xml.ToString(),
true);
1464 Doc.DocumentElement, e.
Id, e.
To, e.
From, e.
Ok, State);
1465 await Callback.Raise(Sender, e2);
1470 string Id = (string)P[3];
1471 string To = (string)P[4];
1472 string Xml = (string)P[5];
1473 string Type = (string)P[6];
1474 int RetryTimeout = (int)P[7];
1475 int NrRetries = (int)P[8];
1476 bool DropOff = (bool)P[9];
1477 int MaxRetryTimeout = (int)P[10];
1478 bool PkiSynchronized = (bool)P[11];
1480 if (PkiSynchronized)
1483 await Callback.Raise(Sender, e);
1491 await this.SendIq(Client, E2ETransmission, Id, To, Xml, Type, Callback, State,
1492 RetryTimeout, NrRetries, DropOff, MaxRetryTimeout, true);
1497 await Callback.Raise(Sender, e);
1506 await Callback.Raise(Sender, e);
1510 private bool IsForbidden(XmlElement E)
1517 foreach (XmlNode N
in E.ChildNodes)
1519 E2 = N as XmlElement;
1530 private string EmbedIq(
IqEventArgs e,
string Type,
string Content)
1532 StringBuilder Xml =
new StringBuilder();
1534 Xml.Append(
"<iq xmlns=\"jabber:client\" id=\"");
1536 Xml.Append(
"\" from=\"");
1538 Xml.Append(
"\" to=\"");
1540 Xml.Append(
"\" type=\"");
1543 Xml.Append(Content);
1544 Xml.Append(
"</iq>");
1546 return Xml.ToString();
1549 private Task AesIqGetHandler(
object Sender,
IqEventArgs e)
1551 return this.E2eIqGetHandler(Sender, e, this.aes);
1554 private Task AcpIqGetHandler(
object Sender,
IqEventArgs e)
1556 return this.E2eIqGetHandler(Sender, e, this.acp);
1559 private Task ChaIqGetHandler(
object Sender,
IqEventArgs e)
1561 return this.E2eIqGetHandler(Sender, e, this.cha);
1567 Tuple<string, string> T = this.
Decrypt(Client, e.
Id, e.
IQ.GetAttribute(
"type"), e.
From, e.
To, e.
Query, Cipher);
1574 string Content = T.Item1;
1575 string EndpointReference = T.Item2;
1577 XmlDocument Doc =
XML.
ParseXml(this.EmbedIq(e,
"get", Content),
true);
1583 private Task AesIqSetHandler(
object Sender,
IqEventArgs e)
1585 return this.E2eIqSetHandler(Sender, e, this.aes);
1588 private Task AcpIqSetHandler(
object Sender,
IqEventArgs e)
1590 return this.E2eIqSetHandler(Sender, e, this.acp);
1593 private Task ChaIqSetHandler(
object Sender,
IqEventArgs e)
1595 return this.E2eIqSetHandler(Sender, e, this.cha);
1601 Tuple<string, string> T = this.
Decrypt(Client, e.
Id, e.
IQ.GetAttribute(
"type"), e.
From, e.
To, e.
Query, Cipher);
1608 string Content = T.Item1;
1609 string EndpointReference = T.Item2;
1611 XmlDocument Doc =
XML.
ParseXml(this.EmbedIq(e,
"set", Content),
true);
1635 MessageType Type,
string Id,
string To,
string CustomXml,
string Body,
string Subject,
1636 string Language,
string ThreadId,
string ParentThreadId, EventHandlerAsync<DeliveryEventArgs> DeliveryCallback,
1640 Language, ThreadId, ParentThreadId, DeliveryCallback, State,
false);
1662 MessageType Type,
string Id,
string To,
string CustomXml,
string Body,
string Subject,
1663 string Language,
string ThreadId,
string ParentThreadId, EventHandlerAsync<DeliveryEventArgs> DeliveryCallback,
1664 object State,
bool PkiSynchronized)
1666 if (this.client is
null)
1667 throw new ObjectDisposedException(
"Endpoint security object disposed.");
1669 if (
string.IsNullOrEmpty(Id))
1672 StringBuilder Xml =
new StringBuilder();
1674 Xml.Append(
"<message");
1679 Xml.Append(
" type=\"chat\"");
1683 Xml.Append(
" type=\"error\"");
1687 Xml.Append(
" type=\"groupchat\"");
1691 Xml.Append(
" type=\"headline\"");
1695 if (!
string.IsNullOrEmpty(Language))
1697 Xml.Append(
" xml:lang=\"");
1704 if (!
string.IsNullOrEmpty(Subject))
1706 Xml.Append(
"<subject>");
1708 Xml.Append(
"</subject>");
1711 if (!
string.IsNullOrEmpty(Body))
1713 Xml.Append(
"<body>");
1715 Xml.Append(
"</body>");
1718 if (!
string.IsNullOrEmpty(ThreadId))
1720 Xml.Append(
"<thread");
1722 if (!
string.IsNullOrEmpty(ParentThreadId))
1724 Xml.Append(
" parent=\"");
1731 Xml.Append(
"</thread>");
1734 if (!
string.IsNullOrEmpty(CustomXml))
1736 if (!
XML.
IsValidXml(CustomXml,
true,
true,
true,
true,
false,
false))
1737 throw new ArgumentException(
"Not valid XML.", nameof(CustomXml));
1739 Xml.Append(CustomXml);
1742 Xml.Append(
"</message>");
1744 string MessageXml = Xml.ToString();
1745 StringBuilder Encrypted =
new StringBuilder();
1748 if (await this.
Encrypt(Client, Id,
string.Empty, this.client.
FullJID, To,
1751 MessageXml = Encrypted.ToString();
1754 string.Empty,
string.Empty,
string.Empty,
string.Empty, DeliveryCallback, State);
1763 if (!(Item is
null))
1773 string.Empty,
string.Empty,
string.Empty,
string.Empty, DeliveryCallback, State);
1787 if (!PkiSynchronized)
1793 await this.SendMessage(Client, E2ETransmission, QoS, Type, Id, To, CustomXml, Body, Subject,
1794 Language, ThreadId, ParentThreadId, DeliveryCallback, State, true);
1798 await Client.SendMessage(QoS, Type, Id, To, CustomXml, Body, Subject, Language,
1799 ThreadId, ParentThreadId, DeliveryCallback, State);
1801 else if (!(DeliveryCallback is
null))
1809 ThreadId, ParentThreadId, DeliveryCallback, State);
1812 throw new InvalidOperationException(
"End-to-End Encryption not available between " +
Client.
FullJID +
" and " + To +
".");
1826 EventHandlerAsync<IqResultEventArgs> Callback,
object State)
1845 EventHandlerAsync<IqResultEventArgs> Callback,
object State,
int RetryTimeout,
int NrRetries)
1847 return this.
SendIq(Client,
E2ETransmission,
null, To, Xml,
"get", Callback, State, RetryTimeout, NrRetries,
false,
1848 RetryTimeout,
false);
1867 EventHandlerAsync<IqResultEventArgs> Callback,
object State,
int RetryTimeout,
int NrRetries,
bool DropOff,
1868 int MaxRetryTimeout)
1871 NrRetries, DropOff, MaxRetryTimeout,
false);
1885 EventHandlerAsync<IqResultEventArgs> Callback,
object State)
1905 EventHandlerAsync<IqResultEventArgs> Callback,
object State,
int RetryTimeout,
int NrRetries)
1908 NrRetries,
false, RetryTimeout,
false);
1927 EventHandlerAsync<IqResultEventArgs> Callback,
object State,
int RetryTimeout,
int NrRetries,
bool DropOff,
1928 int MaxRetryTimeout)
1931 NrRetries, DropOff, MaxRetryTimeout,
false);
1946 EventHandlerAsync<IqResultEventArgs> Callback,
object State, EventHandlerAsync<DeliveryEventArgs> DeliveryCallback)
1966 EventHandlerAsync<IqResultEventArgs> Callback,
object State,
int RetryTimeout,
int NrRetries,
1967 EventHandlerAsync<DeliveryEventArgs> DeliveryCallback)
1969 return this.
SendIq(Client,
E2ETransmission,
null, To, Xml,
"get", Callback, State, RetryTimeout, NrRetries,
false,
1970 RetryTimeout,
false, DeliveryCallback);
1990 EventHandlerAsync<IqResultEventArgs> Callback,
object State,
int RetryTimeout,
int NrRetries,
bool DropOff,
1991 int MaxRetryTimeout, EventHandlerAsync<DeliveryEventArgs> DeliveryCallback)
1994 NrRetries, DropOff, MaxRetryTimeout,
false, DeliveryCallback);
2009 EventHandlerAsync<IqResultEventArgs> Callback,
object State, EventHandlerAsync<DeliveryEventArgs> DeliveryCallback)
2030 EventHandlerAsync<IqResultEventArgs> Callback,
object State,
int RetryTimeout,
int NrRetries,
2031 EventHandlerAsync<DeliveryEventArgs> DeliveryCallback)
2034 NrRetries,
false, RetryTimeout,
false, DeliveryCallback);
2054 EventHandlerAsync<IqResultEventArgs> Callback,
object State,
int RetryTimeout,
int NrRetries,
bool DropOff,
2055 int MaxRetryTimeout, EventHandlerAsync<DeliveryEventArgs> DeliveryCallback)
2058 NrRetries, DropOff, MaxRetryTimeout,
false, DeliveryCallback);
2071 return this.
SendIq(Client,
E2ETransmission, Id, To, Xml,
"result",
null,
null, 0, 0,
false, 0,
false);
2084 return this.
SendIq(Client,
E2ETransmission, Id, To, Xml,
"error",
null,
null, 0, 0,
false, 0,
false);
2123 string Type, EventHandlerAsync<IqResultEventArgs> Callback,
object State,
int RetryTimeout,
int NrRetries,
bool DropOff,
2124 int MaxRetryTimeout,
bool PkiSynchronized)
2126 return this.
SendIq(Client,
E2ETransmission, Id, To, Xml, Type, Callback, State, RetryTimeout, NrRetries, DropOff,
2127 MaxRetryTimeout, PkiSynchronized,
null);
2153 string Type, EventHandlerAsync<IqResultEventArgs> Callback,
object State,
int RetryTimeout,
int NrRetries,
bool DropOff,
2154 int MaxRetryTimeout,
bool PkiSynchronized, EventHandlerAsync<DeliveryEventArgs> DeliveryCallback)
2156 if (this.client is
null)
2157 throw new ObjectDisposedException(
"Endpoint security object disposed.");
2159 if (
string.IsNullOrEmpty(Id))
2162 StringBuilder Encrypted =
new StringBuilder();
2164 if (await this.
Encrypt(Client, Id, Type, this.client.
FullJID, To,
2167 string XmlEnc = Encrypted.ToString();
2170 new object[] { Callback, State,
E2ETransmission, Id, To, Xml, Type, RetryTimeout, NrRetries, DropOff, MaxRetryTimeout, PkiSynchronized },
2171 RetryTimeout, NrRetries, DropOff, MaxRetryTimeout, DeliveryCallback);
2176 if (uint.TryParse(Id, out uint SeqNr))
2182 if (!PkiSynchronized)
2184 if (!uint.TryParse(Id, out uint SeqNr))
2187 SeqNr = uint.Parse(Id);
2194 await this.SendIq(Client, E2ETransmission, Id, To, Xml, Type, Callback, State,
2195 RetryTimeout, NrRetries, DropOff, MaxRetryTimeout, true, DeliveryCallback);
2199 await Client.SendIq(Id, To, Xml, Type, Callback, State, RetryTimeout,
2200 NrRetries, DropOff, MaxRetryTimeout, DeliveryCallback);
2204 if (!(DeliveryCallback is null))
2205 await DeliveryCallback.Raise(Sender, new DeliveryEventArgs(Sender, true));
2207 await Callback.Raise(Sender, e);
2215 return await
Client.
SendIq(Id, To, Xml, Type, Callback, State, RetryTimeout,
2216 NrRetries, DropOff, MaxRetryTimeout, DeliveryCallback);
2219 throw new InvalidOperationException(
"End-to-End Encryption not available between " +
Client.
FullJID +
" and " + To +
".");
2237 if (!Result.Wait(Timeout))
2238 throw new TimeoutException();
2240 return Result.Result;
2255 TaskCompletionSource<XmlElement> Result =
new TaskCompletionSource<XmlElement>();
2260 Result.TrySetResult(e.Response);
2264 return Task.CompletedTask;
2268 return await Result.Task;
2286 if (!Result.Wait(Timeout))
2287 throw new TimeoutException();
2289 return Result.Result;
2304 TaskCompletionSource<XmlElement> Result =
new TaskCompletionSource<XmlElement>();
2309 Result.TrySetResult(e.Response);
2313 return Task.CompletedTask;
2317 return await Result.Task;
2326 lock (this.synchObject)
2328 Xml.Append(
"<e2e xmlns=\"");
2330 Xml.Append(
"\" aes=\"true\" cha=\"true\" acp=\"true\">");
2335 Xml.Append(
"</e2e>");
2344 public Task
SynchronizeE2e(
string FullJID, EventHandlerAsync<IqResultEventArgs> Callback)
2355 public async Task
SynchronizeE2e(
string FullJID, EventHandlerAsync<IqResultEventArgs> Callback,
object State)
2357 LinkedList<SynchRec> CallbackList;
2359 lock (this.synchronizationTasks)
2361 SynchRec Rec =
new SynchRec()
2363 Callback = Callback,
2367 if (this.synchronizationTasks.TryGetValue(FullJID, out CallbackList))
2369 CallbackList.AddLast(Rec);
2373 CallbackList =
new LinkedList<SynchRec>();
2374 CallbackList.AddLast(Rec);
2376 this.synchronizationTasks[FullJID] = CallbackList;
2379 await this.client.
SendIqSet(FullJID, this.GetE2eXml(), async (Sender, e) =>
2381 lock (this.synchronizationTasks)
2383 if (!this.synchronizationTasks.TryGetValue(FullJID, out CallbackList))
2386 this.synchronizationTasks.Remove(FullJID);
2389 if (e.
Ok && !(e.FirstElement is
null))
2390 await this.ParseE2e(e.FirstElement, FullJID);
2392 foreach (SynchRec Rec
in CallbackList)
2394 e.State = Rec.State;
2395 await Rec.Callback.Raise(Sender, e);
2400 private readonly Dictionary<string, LinkedList<SynchRec>> synchronizationTasks =
new Dictionary<string, LinkedList<SynchRec>>();
2402 private class SynchRec
2404 public EventHandlerAsync<IqResultEventArgs> Callback;
2405 public object State;
2408 private string GetE2eXml()
2410 StringBuilder Xml =
new StringBuilder();
2412 Xml.Append(
"<synchE2e xmlns=\"");
2417 this.serverlessMessaging?.AppendP2pInfo(Xml);
2419 Xml.Append(
"</synchE2e>");
2421 return Xml.ToString();
2424 private async Task ParseE2e(XmlElement E,
string RemoteFullJID)
2426 XmlElement E2E =
null;
2427 XmlElement P2P =
null;
2429 if (!(E is
null) && E.LocalName ==
"synchE2e")
2431 foreach (XmlNode N
in E.ChildNodes)
2433 if (N is XmlElement E2)
2435 switch (E2.LocalName)
2452 bool HasP2P = !(this.serverlessMessaging is
null) && await this.serverlessMessaging.AddPeerAddressInfo(RemoteFullJID, P2P);
2457 private async Task SynchE2eHandler(
object Sender,
IqEventArgs e)
2462 ((Item =
this.client.GetRosterItem(e.
FromBareJid)) is
null ||
2471 await e.
IqResult(this.GetE2eXml());
2479 XmlElement E2E =
null;
2480 XmlElement P2P =
null;
2482 foreach (XmlNode N
in e.
Presence.ChildNodes)
2484 if (N is XmlElement E)
2486 switch (E.LocalName)
2502 bool HasP2P = !(this.serverlessMessaging is
null) && await this.serverlessMessaging.AddPeerAddressInfo(e.
From, P2P);
2526 public event EventHandlerAsync<PeerSynchronizedEventArgs>
PeerUpdated =
null;
2531 return this.instanceId.ToString();
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 XmlDocument ParseXml(string Xml)
Parses an XML Document from its string representation.
static bool IsValidXml(string Xml)
Checks if a string is valid XML
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.
void Warning(string Warning)
Called to inform the viewer of a warning state.
void Information(string Comment)
Called to inform the viewer of something.
Event arguments for delivery events.
Event Argument for custom presence XML events.
StringBuilder Stanza
Stanza being built.
Event arguments for IQ queries.
async Task IqError(string Xml)
Returns an error response to the current request.
async Task IqResult(string Xml)
Returns a response to the current request.
XmlElement Query
Query element, if found, null otherwise.
string From
From address attribute
string To
To address attribute
string Id
ID of the request.
string FromBareJid
Bare version of the "from" JID.
Event arguments for responses to IQ queries.
string Id
ID of the request.
string From
From address attribute
XmlElement ErrorElement
Error element.
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.
XmlElement Response
IQ Response element.
XmlElement FirstElement
First child element of the Response element.
string To
To address attribute
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.
bool Ok
If the response is an OK result response (true), or an error response (false).
string To
To whom the message was sent.
XmlElement Content
Content of the message. For messages that are processed by registered message handlers,...
Event arguments for presence events.
bool Ok
If the response is an OK result response (true), or an error response (false).
XmppException StanzaError
Any stanza error returned.
string From
From where the presence was received.
XmlElement Presence
Presence element.
PresenceType Type
Type of presence received.
Event arguments for Availability events.
Abstract base class for End-to-End encryption schemes.
Class managing end-to-end encryption.
EventHandlerAsync< AvailableEventArgs > PeerAvailable
Event raised whenever a peer has become available.
Task< uint > SendIqSet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State, int RetryTimeout, int NrRetries, bool DropOff, int MaxRetryTimeout)
Sends an IQ Set stanza
EndpointSecurity(XmppClient Client, XmppServerlessMessaging ServerlessMessaging, int SecurityStrength, params IE2eEndpoint[] LocalEndpoints)
Class managing end-to-end encryption.
static IE2eEndpoint[] CreateEndpoints(int DesiredSecurityStrength, int MinSecurityStrength, int MaxSecurityStrength, params Type[] OnlyIfDerivedFrom)
Creates a set of endpoints within a range of security strengths.
Task< uint > SendIqSet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State, int RetryTimeout, int NrRetries, bool DropOff, int MaxRetryTimeout, EventHandlerAsync< DeliveryEventArgs > DeliveryCallback)
Sends an IQ Set stanza
virtual bool TryGetSymmetricCipher(string LocalName, string Namespace, out IE2eSymmetricCipher Cipher)
Tries to get a symmetric cipher from a reference.
static Dictionary< string, IE2eEndpoint > ParseE2eKeys(XmlElement E2E, int SecurityStrength)
Parses a set of E2E keys from XML.
const string IoTHarmonizationE2ENeuroFoundationV1
urn:nf:iot:e2e:1.0
IE2eEndpoint[] GetE2eEndpoints(string FullJid)
Gets available E2E options for a given endpoint.
XmlElement IqGet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, int Timeout)
Sends an IQ Get stanza
virtual async Task< bool > Encrypt(XmppClient Client, string Id, string Type, string From, string To, bool Pqc, int MinSecurityStrength, string DataXml, StringBuilder Xml)
Encrypts XML data for transmission to an endpoint.
const string IoTHarmonizationP2PIeeeV1
urn:ieee:iot:p2p:1.0
Task< uint > SendIqGet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Sends an IQ Get stanza
static readonly string[] NamespacesIoTHarmonizationE2E
Namespaces supported for End-to-end encryption.
virtual void RegisterHandlers(XmppClient Client)
Registers XMPP stanza handlers
virtual async Task< Stream > Decrypt(string EndpointReference, string Id, string Type, string From, string To, Stream Data, IE2eSymmetricCipher SymmetricCipher)
Decrypts binary data received from an XMPP client out of band.
Task< uint > SendIqGet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State, EventHandlerAsync< DeliveryEventArgs > DeliveryCallback)
Sends an IQ Get stanza
static bool TryCreateEndpoint(string LocalName, string Namespace, out IE2eEndpoint Endpoint)
Tries to create a new endpoint, given its qualified name.
virtual Task< byte[]> Decrypt(string EndpointReference, string Id, string Type, string From, string To, byte[] Data, IE2eSymmetricCipher SymmetricCipher)
Decrypts binary data from an endpoint.
Task< uint > SendIqGet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State, int RetryTimeout, int NrRetries, bool DropOff, int MaxRetryTimeout)
Sends an IQ Get stanza
const string IoTHarmonizationP2PCurrent
Current namespace for peer-to-peer communication
IE2eEndpoint FindLocalEndpoint(IE2eEndpoint RemoteEndpoint)
Returns the local endpoint that matches a given remote endpoint.
Task< uint > SendIqSet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State, int RetryTimeout, int NrRetries, EventHandlerAsync< DeliveryEventArgs > DeliveryCallback)
Sends an IQ Set stanza
static IE2eEndpoint ParseE2eKey(XmlElement E)
Parses a single E2E key from XML.
Task< uint > SendIqGet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State, int RetryTimeout, int NrRetries, bool DropOff, int MaxRetryTimeout, EventHandlerAsync< DeliveryEventArgs > DeliveryCallback)
Sends an IQ Get stanza
Task< uint > SendIqGet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State, int RetryTimeout, int NrRetries)
Sends an IQ Get stanza
virtual Tuple< string, string > Decrypt(XmppClient Client, string Id, string Type, string From, string To, XmlElement E2eElement, IE2eSymmetricCipher SymmetricCipher)
Decrypts XML data from an endpoint.
IE2eEndpoint FindLocalEndpoint(byte[] PublicKey)
Returns the local endpoint that matches a given public key.
virtual void UnregisterHandlers(XmppClient Client)
Unregisters XMPP stanza handlers
Task< uint > SendIqSet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Sends an IQ Set stanza
EndpointSecurity(XmppClient Client, int SecurityStrength, params IE2eEndpoint[] LocalEndpoints)
Class managing end-to-end encryption.
async Task SynchronizeE2e(string FullJID, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Synchronizes End-to-End Encryption and Peer-to-Peer connectivity parameters with a remote entity.
EndpointSecurity(XmppClient Client, XmppServerlessMessaging ServerlessMessaging, int SecurityStrength)
Class managing end-to-end encryption.
Task< uint > SendIq(XmppClient Client, E2ETransmission E2ETransmission, string Id, string To, string Xml, string Type, EventHandlerAsync< IqResultEventArgs > Callback, object State, int RetryTimeout, int NrRetries, bool DropOff, int MaxRetryTimeout, bool PkiSynchronized)
Sends an IQ stanza
virtual async Task IqResult(object Sender, IqResultEventArgs e)
Response handler for E2E encrypted iq stanzas
Task< IE2eEndpoint > Encrypt(string Id, string Type, string From, string To, Stream Data, Stream Encrypted)
Encrypts binary data that can be sent to an XMPP client out of band.
void AppendE2eInfo(StringBuilder Xml)
Appends E2E information to XML.
static bool TryGetEndpoint(string LocalName, string Namespace, out IE2eEndpoint Endpoint)
Tries to get an existing endpoint, given its qualified name.
IE2eEndpoint[] FindCompatibleLocalEndpoints(byte[] PublicKey)
Returns all local endpoints that are compatible with a given public key, based on its length.
Task< uint > SendIqSet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State, int RetryTimeout, int NrRetries)
Sends an IQ Set stanza
static IE2eEndpoint[] CreateEndpoints(int DesiredSecurityStrength, int MinSecurityStrength, int MaxSecurityStrength, Type[] OnlyIfDerivedFrom, ProfilerThread Thread)
Creates a set of endpoints within a range of security strengths.
static readonly string[] NamespacesIoTHarmonizationP2P
Namespaces supported for Peer-to-peer communication.
Task< bool > Encrypt(XmppClient Client, string Id, string Type, string From, string To, string DataXml, StringBuilder Xml)
Encrypts XML data for transmission to an endpoint.
async Task< XmlElement > IqSetAsync(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml)
Sends an IQ Set stanza
Guid InstanceId
ID of IEndToEndEncryption instance.
Task SendIqResult(XmppClient Client, E2ETransmission E2ETransmission, string Id, string To, string Xml)
Sends an IQ Result stanza
EndpointSecurity(XmppClient Client, int SecurityStrength)
Class managing end-to-end encryption.
const string IoTHarmonizationP2PNeuroFoundationV1
urn:nf:iot:p2p:1.0
IE2eEndpoint FindLocalEndpoint(string KeyName)
Returns the local endpoint that matches a given key name.
static bool IsE2eEncryptionEnabled(XmppClient Client)
If End-to-End encryption is enabled on an XMPP client.
IE2eEndpoint FindLocalEndpoint(string KeyName, string KeyNamespace)
Returns the local endpoint that matches a given key name and namespace.
Task< uint > SendIqGet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State, int RetryTimeout, int NrRetries, EventHandlerAsync< DeliveryEventArgs > DeliveryCallback)
Sends an IQ Get stanza
virtual async Task< KeyValuePair< byte[], IE2eEndpoint > > Encrypt(string Id, string Type, string From, string To, bool Pqc, int MinSecurityStrength, byte[] Data)
Encrypts binary data for transmission to an endpoint.
EventHandlerAsync< PeerSynchronizedEventArgs > PeerUpdated
Event raised whenever information about a peer has been updated.
Task SendIqError(XmppClient Client, E2ETransmission E2ETransmission, string Id, string To, Exception ex)
Sends an IQ Error stanza
Task SynchronizeE2e(string FullJID, EventHandlerAsync< IqResultEventArgs > Callback)
Synchronizes End-to-End Encryption and Peer-to-Peer connectivity parameters with a remote entity.
static void SetCiphers(Type[] CipherTypes, bool Lock)
Sets allowed cipers in endpoint security.
Task< KeyValuePair< byte[], IE2eEndpoint > > Encrypt(string Id, string Type, string From, string To, byte[] Data)
Encrypts binary data for transmission to an endpoint.
static IE2eEndpoint[] CreateEndpoints(int DesiredSecurityStrength, int MinSecurityStrength, int MaxSecurityStrength)
Creates a set of endpoints within a range of security strengths.
async Task< uint > SendIq(XmppClient Client, E2ETransmission E2ETransmission, string Id, string To, string Xml, string Type, EventHandlerAsync< IqResultEventArgs > Callback, object State, int RetryTimeout, int NrRetries, bool DropOff, int MaxRetryTimeout, bool PkiSynchronized, EventHandlerAsync< DeliveryEventArgs > DeliveryCallback)
Sends an IQ stanza
XmlElement IqSet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, int Timeout)
Sends an IQ Set stanza
bool AddPeerPkiInfo(string FullJID, XmlElement E2E)
Adds E2E information about a peer.
const string IoTHarmonizationE2ECurrent
Current namespace for End-to-End encryption.
const string IoTHarmonizationE2EIeeeV1
urn:ieee:iot:e2e:1.0
bool ContainsKey(string FullJid)
If infomation is available for a given endpoint.
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.
bool RemovePeerPkiInfo(string FullJID)
Removes E2E information about a peer.
virtual async Task< IE2eEndpoint > Encrypt(string Id, string Type, string From, string To, bool Pqc, int MinSecurityStrength, Stream Data, Stream Encrypted)
Encrypts binary data that can be sent to an XMPP client out of band.
Task< uint > SendIqSet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State, EventHandlerAsync< DeliveryEventArgs > DeliveryCallback)
Sends an IQ Set stanza
override string ToString()
static bool TryGetEndpointSecurity(XmppClient Client, out EndpointSecurity EndpointSecurity)
Tries to get a registered endpoint security manager from an XMPP client.
XmppClient Client
Associated XMPP client, if any.
void GenerateNewKey()
Generates new local keys.
Task SendIqError(XmppClient Client, E2ETransmission E2ETransmission, string Id, string To, string Xml)
Sends an IQ Error stanza
IE2eEndpoint FindLocalEndpoint(Type KeyType)
Returns the local endpoint that matches a given type.
EventHandlerAsync< PresenceEventArgs > PeerUnavailable
Event raised whenever a peer has become unavailable.
async Task< XmlElement > IqGetAsync(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml)
Sends an IQ Get stanza
virtual void Dispose()
IDisposable.Dispose
Event arguments for peer synchronization events.
Implements support for the AEAD-ChaCha20-Poly1305 cipher in hybrid End-to-End encryption schemes.
Implements support for the AES-256 cipher in hybrid End-to-End encryption schemes.
override void Dispose()
IDisposable.Dispose
Implements support for the ChaCha20 cipher in hybrid End-to-End encryption schemes.
virtual void Dispose()
IDisposable.Dispose
Class managing peer-to-peer serveless XMPP communication.
Maintains information about an item in the roster.
SubscriptionState State
roup Current subscription state.
PresenceEventArgs[] Resources
Active resources utilized by contact.
The requesting entity does not possess the necessary permissions to perform an action that only certa...
Manages an XMPP client connection. Implements XMPP, as defined in https://tools.ietf....
async void ProcessMessage(MessageEventArgs e)
Processes an incoming message.
bool UnregisterMessageHandler(string LocalName, string Namespace, EventHandlerAsync< MessageEventArgs > Handler, bool RemoveNamespaceAsClientFeature)
Unregisters a Message handler.
bool UnregisterIqGetHandler(string LocalName, string Namespace, EventHandlerAsync< IqEventArgs > Handler, bool RemoveNamespaceAsClientFeature)
Unregisters an IQ-Get handler.
int DefaultRetryTimeout
Default retry timeout, in milliseconds. This value is used when sending IQ requests wihtout specifyin...
Task SendMessage(MessageType Type, string To, string CustomXml, string Body, string Subject, string Language, string ThreadId, string ParentThreadId)
Sends a simple chat message
string ExceptionToXmppXml(Exception ex)
Converts an exception object to an XMPP XML error element.
bool DefaultDropOff
Default Drop-off value. If drop-off is used, the retry timeout is doubled for each retry,...
int DefaultNrRetries
Default number of retries if results or errors are not returned. This value is used when sending IQ r...
static string GetBareJID(string JID)
Gets the Bare JID from a JID, which may be a Full JID.
void RegisterIqSetHandler(string LocalName, string Namespace, EventHandlerAsync< IqEventArgs > Handler, bool PublishNamespaceAsClientFeature)
Registers an IQ-Set handler.
int DefaultMaxRetryTimeout
Default maximum retry timeout, in milliseconds. This value is used when sending IQ requests wihtout s...
void RegisterIqGetHandler(string LocalName, string Namespace, EventHandlerAsync< IqEventArgs > Handler, bool PublishNamespaceAsClientFeature)
Registers an IQ-Get handler.
Task ProcessIqSet(IqEventArgs e)
Processes an incoming IQ SET stanza.
bool RemoveTag(string TagName)
Removes a tag from the client.
Task ProcessIqGet(IqEventArgs e)
Processes an incoming IQ GET stanza.
void SetTag(string TagName, object Tag)
Sets a tag value.
const string NamespaceXmppStanzas
urn:ietf:params:xml:ns:xmpp-stanzas
void RegisterMessageHandler(string LocalName, string Namespace, EventHandlerAsync< MessageEventArgs > Handler, bool PublishNamespaceAsClientFeature)
Registers a Message handler.
bool UnregisterIqSetHandler(string LocalName, string Namespace, EventHandlerAsync< IqEventArgs > Handler, bool RemoveNamespaceAsClientFeature)
Unregisters an IQ-Set handler.
Task< uint > SendIq(string Id, string To, string Xml, string Type, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Sends an IQ stanza.
Task< uint > SendIqSet(string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Sends an IQ Set request.
bool TryGetTag(string TagName, out object Tag)
Tries to get a tag from the client. Tags can be used to attached application specific objects to the ...
string NextId()
Generates a new id attribute value.
RosterItem GetRosterItem(string BareJID)
Gets a roster item.
Base class of XMPP exceptions
A chunked list is a linked list of chunks of objects of type T .
T FirstItem
First item in the collection.
int Count
Number of elements in collection.
void Add(T Item)
Adds an item to the collection.
T[] ToArray()
Returns an array containing all elements of the collection.
Static class that dynamically manages types and interfaces available in the runtime environment.
static object[] NoParameters
Contains an empty array of parameter values.
static Type[] GetTypesImplementingInterface(string InterfaceFullName)
Gets all types implementing a given interface.
static ConstructorInfo GetDefaultConstructor(Type Type)
Gets the default constructor of a type, if one exists.
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.
Abstract base class for End-to-End encryption schemes.
bool SupportsSignatures
If signatures are supported.
Task< uint > GetNextCounter()
Gets the next counter value.
bool Slow
If implementation is slow, compared to other options.
int SecurityStrength
Security strength of End-to-End encryption scheme.
IE2eEndpoint Create(int SecurityStrength)
Creates a new key.
IE2eEndpoint Parse(XmlElement Xml)
Parses endpoint information from an XML element.
string ToXml()
Exports the public key information to XML.
byte[] PublicKey
Remote public key.
string PublicKeyBase64
Remote public key, as a Base64 string.
string Namespace
Namespace of the E2E endpoint
bool SharedSecretUseCipherText
If the recipient needs a cipher text to generate the same shared secret.
IE2eSymmetricCipher DefaultSymmetricCipher
Default symmetric cipher.
string LocalName
Local name of the E2E endpoint
bool PostQuantumCryptography
If post-quantum cryptography is used.
bool Safe
If endpoint is considered safe (i.e. there are no suspected backdoors)
Interface for symmetric ciphers.
bool Supported(XmlElement E2e)
If the symmetric cipher is supported by a remote endpoint.
byte[] Encrypt(string Id, string Type, string From, string To, uint Counter, byte[] Data, IE2eEndpoint Sender, IE2eEndpoint Receiver)
Encrypts binary data
byte[] Decrypt(string Id, string Type, string From, string To, byte[] Data, IE2eEndpoint Sender, IE2eEndpoint Receiver)
Decrypts binary data
End-to-end encryption interface.
PresenceType
Type of presence received.
QoSLevel
Quality of Service Level for asynchronous messages. Support for QoS Levels must be supported by the r...
SubscriptionState
State of a presence subscription.
MessageType
Type of message received.
XmppState
State of XMPP connection.
E2ETransmission
End-to-end encryption mode.
ProfilerThreadType
Type of profiler thread.