Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
PetitionSignature.cs
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading.Tasks;
5using System.Xml;
6using Waher.Content;
13using Waher.Script;
15using Waher.Security;
20
22{
27 {
32 : base("Legal/PetitionSignature",
33 new KeyValuePair<Type, Expression>(typeof(Dictionary<string, object>), new Expression(jsonPattern)),
34 new KeyValuePair<Type, Expression>(typeof(XmlDocument), new Expression(xmlPattern)))
35 {
36 }
37
38 private static readonly string jsonPattern = Resources.LoadResourceAsText(typeof(PetitionSignature).Namespace + ".JSON.PetitionSignature.req");
39 private static readonly string xmlPattern = Resources.LoadResourceAsText(typeof(PetitionSignature).Namespace + ".XML.PetitionSignature.req");
40
49 public override async Task POST(HttpRequest Request, HttpResponse Response, Dictionary<string, IElement> Parameters)
50 {
52
53 string KeyId = (string)Parameters["PKeyId"].AssociatedObjectValue;
54 if (string.IsNullOrEmpty(KeyId))
55 throw new BadRequestException("Key ID cannot be empty.");
56
57 CaseInsensitiveString LegalId = (string)Parameters["PLegalId"].AssociatedObjectValue;
59 throw new BadRequestException("No Legal ID specified.");
60
61 XmppAddress LegalIdAddress = new XmppAddress(LegalId);
62 if (!LegalIdAddress.IsBareJID)
63 throw new BadRequestException("Invalid Legal ID.");
64
65 if (!(XmppServerModule.Legal is null) && !XmppServerModule.Legal.IsComponentDomain(LegalIdAddress.Domain, true))
66 throw new BadRequestException("Not a local Legal ID.");
67
68 CaseInsensitiveString RemoteId = (string)Parameters["PRemoteId"].AssociatedObjectValue;
70 throw new BadRequestException("No Remote ID specified.");
71
72 XmppAddress RemoteAddress = new XmppAddress(RemoteId);
73 if (!RemoteAddress.IsBareJID)
74 throw new BadRequestException("Invalid Remote ID.");
75
76 AgentKey AgentKey = await Database.FindFirstDeleteRest<AgentKey>(new FilterAnd(
77 new FilterFieldEqualTo("Account", User.UserName),
78 new FilterFieldEqualTo("Id", KeyId)))
79 ?? throw new NotFoundException("Key not found.");
80
81 string ContentBase64 = (string)Parameters["PContentBase64"].AssociatedObjectValue;
82 byte[] Content;
83 string PetitionId = (string)Parameters["PPetitionId"].AssociatedObjectValue;
84 string Purpose = (string)Parameters["PPurpose"].AssociatedObjectValue;
85 string KeySignature = (string)Parameters["PKeySignature"].AssociatedObjectValue;
86 string RequestSignature = (string)Parameters["PRequestSignature"].AssociatedObjectValue;
87
88 try
89 {
90 Content = Convert.FromBase64String(ContentBase64);
91 }
92 catch (Exception)
93 {
94 throw new BadRequestException("Invalid base64-encoded data.");
95 }
96
97 string s = Encoding.UTF8.GetString(Content);
98 if (s.StartsWith("<identity") && s.EndsWith("</identity>"))
99 throw new ForbiddenException("Use the PetitionPeerReview request to ask a peer to sign a legal identity.");
100
101 StringBuilder sb = new StringBuilder();
102
103 sb.Append(User.UserName);
104 sb.Append(':');
105 sb.Append(Request.Header.Host.Value);
106 sb.Append(':');
107 sb.Append(AgentKey.LocalName);
108 sb.Append(':');
109 sb.Append(AgentKey.Namespace);
110 sb.Append(':');
111 sb.Append(KeyId);
112
113 //string s1 = sb.ToString();
114
115 sb.Append(':');
116 sb.Append(KeySignature);
117
118 //string s2 = sb.ToString();
119
120 sb.Append(':');
121 sb.Append(PetitionId);
122 sb.Append(':');
123 sb.Append(Purpose);
124 sb.Append(':');
125 sb.Append(LegalId);
126 sb.Append(':');
127 sb.Append(RemoteId);
128 sb.Append(':');
129 sb.Append(ContentBase64);
130
131 string s3 = sb.ToString();
132
133 s = Convert.ToBase64String(
135 Encoding.UTF8.GetBytes(User.Account.Password),
136 Encoding.UTF8.GetBytes(s3)));
137
138 if (s != RequestSignature)
139 {
140 string Msg = "Request Signature invalid.";
141 throw new ForbiddenException(Msg);
142 }
143
144 LegalIdentity Identity = await LegalComponent.GetLocalLegalIdentity(LegalId)
145 ?? throw new NotFoundException("Legal identity not found.");
146
147 if (User.UserName != Identity.Account)
148 throw new ForbiddenException("Not your identity.");
149
150 if (!(XmppServerModule.Legal is null))
151 {
152 LegalComponent.ClientInformation ClientInfo = await XmppServerModule.Legal.GetNetworkIdentity(RemoteId, true, false, Identity.Version);
153 CaseInsensitiveString RemoteJid = ClientInfo.Jid;
154 CaseInsensitiveString From = User.UserName + "@" + Gateway.Domain;
155 XmppServerModule.Legal.IdentityAuthorization(RemoteJid, From, LegalId, true);
156 Dictionary<string, string> AttachmentUrls = XmppServerModule.Legal.GetAttachmentUrls(Identity);
157
158 StringBuilder Msg = new StringBuilder();
159
160 Msg.Append("<petitionSignatureMsg id=\"");
161 Msg.Append(XML.Encode(RemoteId));
162 Msg.Append("\" pid=\"");
163 Msg.Append(XML.Encode(PetitionId));
164 Msg.Append("\" from=\"");
165 Msg.Append(XML.Encode(From));
166 Msg.Append("\" purpose=\"");
167 Msg.Append(XML.Encode(Purpose));
168 Msg.Append("\" clientEp=\"");
169 Msg.Append(XML.Encode(Request.RemoteEndPoint));
170 Msg.Append("\" xmlns=\"");
171 Msg.Append(LegalComponent.NamespaceLegalIdentity(Identity.Version));
172 Msg.Append("\"><content>");
173 Msg.Append(ContentBase64);
174 Msg.Append("</content>");
175 Identity.Serialize(Msg, false, true, true, true, true, true, true, AttachmentUrls, XmppServerModule.Legal);
176 Msg.Append("</petitionSignatureMsg>");
177
178 await XmppServerModule.Server.SendMessage(string.Empty, string.Empty,
179 XmppServerModule.Legal.MainDomain.Address, RemoteJid, string.Empty,
180 Msg.ToString());
181 }
182
183 await Response.Return(new NamedDictionary<string, object>("AckResponse", AgentNamespace));
184 }
185 }
186}
A Named dictionary is a dictionary, with a local name and a namespace. Use it to return content that ...
Static class managing loading of resources stored as embedded resources or in content files.
Definition: Resources.cs:15
static string LoadResourceAsText(string ResourceName)
Loads a text resource from an embedded resource.
Definition: Resources.cs:96
Helps with common XML-related tasks.
Definition: XML.cs:19
static string Encode(string s)
Encodes a string for use in XML.
Definition: XML.cs:27
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:126
static CaseInsensitiveString Domain
Domain name.
Definition: Gateway.cs:2354
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repe...
The server understood the request, but is refusing to fulfill it. Authorization will not help and the...
HttpFieldHost Host
Host HTTP Field header. (RFC 2616, §14.23)
Represents an HTTP request.
Definition: HttpRequest.cs:18
HttpRequestHeader Header
Request header.
Definition: HttpRequest.cs:134
string RemoteEndPoint
Remote end-point.
Definition: HttpRequest.cs:195
Represets a response of an HTTP client request.
Definition: HttpResponse.cs:21
async Task Return(object Object)
Returns an object to the client. This method can only be called once per response,...
The server has not found anything matching the Request-URI. No indication is given of whether the con...
XmppAddress MainDomain
Main/principal domain address
Definition: Component.cs:86
bool IsComponentDomain(CaseInsensitiveString Domain, bool IncludeAlternativeDomains)
Checks if a domain is the component domain, or optionally, an alternative component domain.
Definition: Component.cs:123
Contains information about one XMPP address.
Definition: XmppAddress.cs:9
bool IsBareJID
If the address is a Bare JID.
Definition: XmppAddress.cs:159
CaseInsensitiveString Domain
Domain
Definition: XmppAddress.cs:97
CaseInsensitiveString Address
XMPP Address
Definition: XmppAddress.cs:37
Task< bool > SendMessage(string Type, string Id, string From, string To, string Language, string ContentXml)
Sends a Message stanza to a recipient.
Definition: XmppServer.cs:3412
Represents a case-insensitive string.
static readonly CaseInsensitiveString Empty
Empty case-insensitive string
static bool IsNullOrEmpty(CaseInsensitiveString value)
Indicates whether the specified string is null or an CaseInsensitiveString.Empty string.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:19
This filter selects objects that conform to all child-filters provided.
Definition: FilterAnd.cs:10
This filter selects objects that have a named field equal to a given value.
Class managing a script expression.
Definition: Expression.cs:39
Contains methods for simple hash calculations.
Definition: Hashes.cs:59
static byte[] ComputeHMACSHA256Hash(byte[] Key, byte[] Data)
Computes the HMAC-SHA-256 hash of a block of binary data.
Definition: Hashes.cs:585
string Password
Password of account
Definition: Account.cs:109
Abstract base class for agent resources supporting the POST method.
static AccountUser AssertUserAuthenticated(HttpRequest Request)
Makes sure the request is made by an authenticated API user.
const string AgentNamespace
https://waher.se/Schema/BrokerAgent.xsd
Contains an encrypted key for an agent.
Definition: AgentKey.cs:13
Service Module hosting the XMPP broker and its components.