Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
CreateVaultLink.cs
1using System;
4using System.Text;
5using System.Threading.Tasks;
6using System.Xml;
7using Waher.Content;
14using Waher.Script;
16using Waher.Security;
20
22{
27 {
32 : base("Storage/CreateVaultLink",
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(StoreInVault).Namespace + ".JSON.CreateVaultLink.req");
39 private static readonly string xmlPattern = Resources.LoadResourceAsText(typeof(StoreInVault).Namespace + ".XML.CreateVaultLink.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 string Nonce = (string)Parameters["PNonce"].AssociatedObjectValue;
55 string KeySignature = (string)Parameters["PKeySignature"].AssociatedObjectValue;
56 string RequestSignature = (string)Parameters["PRequestSignature"].AssociatedObjectValue;
57 string VaultId = (string)Parameters["PVaultId"]?.AssociatedObjectValue;
58 int Ttl = (int)(double)(Parameters["PTtl"]?.AssociatedObjectValue ?? 0.0);
59 int UseCount = (int)(double)(Parameters["PUseCount"]?.AssociatedObjectValue ?? 0.0);
60 bool Masked = (bool)(Parameters["PMasked"]?.AssociatedObjectValue ?? true);
61 byte[] VaultIdBin;
62
63 try
64 {
65 VaultIdBin = Convert.FromBase64String(VaultId);
66 }
67 catch (Exception)
68 {
69 throw new BadRequestException("Invalid Vault ID.");
70 }
71
72 if (string.IsNullOrEmpty(KeyId))
73 throw new BadRequestException("Key ID cannot be empty.");
74
75 if (string.IsNullOrEmpty(Nonce) || Nonce.Length < 32)
76 throw new ForbiddenException(Request, "Nonce too short.");
77
78 StringBuilder sb = new StringBuilder();
79 AgentKey AgentKey = await Database.FindFirstDeleteRest<AgentKey>(new FilterAnd(
80 new FilterFieldEqualTo("Account", User.UserName),
81 new FilterFieldEqualTo("Id", KeyId)))
82 ?? throw new NotFoundException("Key not found.");
83
84 sb.Append(User.UserName);
85 sb.Append(':');
86 sb.Append(Request.Header.Host.Value);
87 sb.Append(':');
88 sb.Append(AgentKey.LocalName);
89 sb.Append(':');
90 sb.Append(AgentKey.Namespace);
91 sb.Append(':');
92 sb.Append(KeyId);
93
94 //string s1 = sb.ToString();
95
96 sb.Append(':');
97 sb.Append(KeySignature);
98
99 string s2 = sb.ToString();
100
101 sb.Append(':');
102 sb.Append(Nonce);
103 sb.Append(':');
104 sb.Append(VaultId);
105 sb.Append(':');
106 sb.Append(Ttl);
107 sb.Append(':');
108 sb.Append(UseCount);
109 sb.Append(':');
110 sb.Append(Masked ? '1' : '0');
111
112 VaultItem Item = await Database.FindFirstIgnoreRest<VaultItem>(
113 new FilterFieldEqualTo("VaultId", VaultIdBin))
114 ?? throw new NotFoundException("Vault item not found.");
115
116 if (Item.Account != User.UserName)
117 throw new ForbiddenException(Request, "Access to vault item denied.");
118 string s3 = sb.ToString();
119
120 string s = Convert.ToBase64String(
122 Encoding.UTF8.GetBytes(User.Account.Password),
123 Encoding.UTF8.GetBytes(s3)));
124
125 if (s != RequestSignature)
126 throw new ForbiddenException(Request, "Request Signature invalid.");
127
128 if (await Gateway.HasNonceBeenUsed(Nonce))
129 throw new ForbiddenException(Request, "Nonce value has already been used.");
130
131 await Gateway.RegisterNonceValue(Nonce);
132
133 EllipticCurveEndpoint KeyEndpoint = ApplyId.GetEndpoint(Request, AgentKey, s2);
134
136 {
137 VaultId = VaultIdBin,
138 UseCount = UseCount,
139 Expires = Ttl > 0 ? DateTime.UtcNow.AddSeconds(Ttl) : DateTime.MaxValue,
140 Masked = Masked,
141 KeyId = KeyId,
142 Seed = s2
143 };
144
145 await Database.Insert(Ref);
146
147 sb.Clear();
148 sb.Append("/Vault/");
149 sb.Append(Ref.ObjectId.ToString());
150 sb.Append('/');
151
152 byte[] Signature = KeyEndpoint.Sign(Encoding.UTF8.GetBytes(sb.ToString()));
153
154 sb.Append(Base64Url.Encode(Signature));
155
156 string Url = Gateway.GetUrl(sb.ToString());
157
158 s = "/Vault";
159 if (!Request.Server.TryGetResource(ref s, out _, out _))
160 Request.Server.Register(new Vault());
161
162 await Response.Return(new NamedDictionary<string, object>("Link", AgentNamespace)
163 {
164 { "url", Url }
165 });
166 }
167 }
168}
Static class that does BASE64URL encoding (using URL and filename safe alphabet), as defined in RFC46...
Definition: Base64Url.cs:11
static string Encode(byte[] Data)
Converts a binary block of data to a Base64URL-encoded string.
Definition: Base64Url.cs:48
A Named dictionary is a dictionary, with a local name and a namespace. Use it to return content that ...
Static class managing the runtime environment of the IoT Gateway.
Definition: Gateway.cs:147
static Task< bool > HasNonceBeenUsed(string Nonce)
Checks if a Nonce value has been used.
Definition: Gateway.cs:6342
static string GetUrl(string LocalResource)
Gets a URL for a resource.
Definition: Gateway.cs:5079
static Task RegisterNonceValue(string Nonce)
Registers a nonce value.
Definition: Gateway.cs:6351
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:22
HttpRequestHeader Header
Request header.
Definition: HttpRequest.cs:182
HttpServer Server
HTTP Server receiving the request.
Definition: HttpRequest.cs:118
Represets a response of an HTTP client request.
Definition: HttpResponse.cs:23
Task Return(Exception ex)
Returns an error to the client.
HttpResource Register(HttpResource Resource)
Registers a resource with the server.
Definition: HttpServer.cs:1568
bool TryGetResource(HttpRequest Request, out HttpResource Resource, out string SubPath)
Tries to get a resource from the server.
Definition: HttpServer.cs:1796
The server has not found anything matching the Request-URI. No indication is given of whether the con...
Abstract base class for Elliptic Curve endpoints.
override byte[] Sign(byte[] Data)
Signs binary data using the local private key.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:21
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
Definition: Database.cs:97
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.
Static class managing loading of resources stored as embedded resources or in content files.
Definition: Resources.cs:13
static string LoadResourceAsText(string ResourceName)
Loads a text resource from an embedded resource.
Definition: Resources.cs:55
Class managing a script expression.
Definition: Expression.cs:41
Contains methods for simple hash calculations.
Definition: Hashes.cs:57
static byte[] ComputeHMACSHA256Hash(byte[] Key, byte[] Data)
Computes the HMAC-SHA-256 hash of a block of binary data.
Definition: Hashes.cs:735
string Password
Password of account
Definition: Account.cs:151
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
Stores information in the Encrypted Vault.
Definition: StoreInVault.cs:22
Contains information about an item in the Vault.
Definition: VaultItem.cs:16
Access to secured vault storage via signed URLs.
Definition: Vault.cs:20
Definition: ImplTypes.g.cs:58