Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
JwsAlgorithm.cs
1using System;
3using System.Reflection;
4using System.Text;
5using Waher.Content;
6using Waher.Events;
8
9namespace Waher.Security.JWS
10{
14 public abstract class JwsAlgorithm : IJwsAlgorithm
15 {
19 public const string JwsContentType = "application/jose+json";
20
24 public abstract string Name
25 {
26 get;
27 }
28
32 public abstract bool HasPublicWebKey
33 {
34 get;
35 }
36
40 public virtual IEnumerable<KeyValuePair<string, object>> PublicWebKey
41 {
42 get { throw new NotSupportedException("Algorithm does not have a public web key."); }
43 }
44
48 public abstract void Dispose();
49
58 public virtual void Sign(IEnumerable<KeyValuePair<string, object>> Header,
59 IEnumerable<KeyValuePair<string, object>> Payload, out string HeaderString,
60 out string PayloadString, out string Signature)
61 {
62 string HeaderJson;
63 bool HasKeyID = false;
64
65 foreach (KeyValuePair<string, object> P in Header)
66 {
67 if (P.Key == "kid")
68 {
69 HasKeyID = true;
70 break;
71 }
72 }
73
74 if (this.HasPublicWebKey && !HasKeyID)
75 {
76 HeaderJson = JSON.Encode(Header, null,
77 new KeyValuePair<string, object>("alg", this.Name),
78 new KeyValuePair<string, object>("jwk", this.PublicWebKey));
79 }
80 else
81 HeaderJson = JSON.Encode(Header, null, new KeyValuePair<string, object>("alg", this.Name));
82
83 byte[] HeaderBin = Encoding.UTF8.GetBytes(HeaderJson);
84 HeaderString = Base64Url.Encode(HeaderBin);
85
86 string PayloadJson = Payload is null ? string.Empty : JSON.Encode(Payload, null);
87 byte[] PayloadBin = Encoding.UTF8.GetBytes(PayloadJson);
88 PayloadString = Base64Url.Encode(PayloadBin);
89
90 Signature = this.Sign(HeaderString, PayloadString);
91 }
92
99 public abstract string Sign(string HeaderEncoded, string PayloadEncoded);
100
108 public virtual bool IsValid(string HeaderEncoded, string PayloadEncoded, string SignatureEncoded)
109 {
110 return this.Sign(HeaderEncoded, PayloadEncoded) == SignatureEncoded;
111 }
112
119 public static bool TryGetAlgorithm(string Name, out IJwsAlgorithm Algorithm)
120 {
121 lock (algorithms)
122 {
123 if (!initialized)
124 InitializeLocked();
125
126 return algorithms.TryGetValue(Name, out Algorithm);
127 }
128 }
129
134 public static IJwsAlgorithm[] GetAlgorithms()
135 {
136 lock (algorithms)
137 {
138 if (!initialized)
139 InitializeLocked();
140
141 IJwsAlgorithm[] Result = new IJwsAlgorithm[algorithms.Count];
142 algorithms.Values.CopyTo(Result, 0);
143 return Result;
144 }
145 }
146
151 public static string[] GetAlgorithmNames()
152 {
153 lock (algorithms)
154 {
155 if (!initialized)
156 InitializeLocked();
157
158 int i = 0;
159 int c = algorithms.Count;
160 string[] Result = new string[c];
161
162 foreach (IJwsAlgorithm Algorithm in algorithms.Values)
163 Result[i++] = Algorithm.Name;
164
165 return Result;
166 }
167 }
168
169 private static void InitializeLocked()
170 {
171 foreach (Type T in Types.GetTypesImplementingInterface(typeof(IJwsAlgorithm)))
172 {
173 ConstructorInfo CI = Types.GetDefaultConstructor(T);
174 if (CI is null)
175 continue;
176
177 try
178 {
179 IJwsAlgorithm Algorithm = (IJwsAlgorithm)CI.Invoke(Types.NoParameters);
180
181 if (algorithms.ContainsKey(Algorithm.Name))
182 Log.Warning("JWS algorithm with name " + Algorithm.Name + " already registered.");
183 else
184 algorithms[Algorithm.Name] = Algorithm;
185 }
186 catch (Exception ex)
187 {
188 Log.Exception(ex);
189 }
190 }
191
192 if (!registered)
193 {
194 Types.OnInvalidated += Types_OnInvalidated;
195 registered = true;
196 }
197
198 initialized = true;
199 }
200
201 private static void Types_OnInvalidated(object Sender, EventArgs e)
202 {
203 lock (algorithms)
204 {
205 algorithms.Clear();
206 initialized = false;
207 }
208 }
209
210 private static readonly Dictionary<string, IJwsAlgorithm> algorithms = new Dictionary<string, IJwsAlgorithm>();
211 private static bool initialized = false;
212 private static bool registered = false;
213 }
214}
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
Helps with common JSON-related tasks.
Definition: JSON.cs:16
static string Encode(string s)
Encodes a string for inclusion in JSON.
Definition: JSON.cs:537
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:14
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.
Definition: Log.cs:1657
static void Warning(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs a warning event.
Definition: Log.cs:576
Static class that dynamically manages types and interfaces available in the runtime environment.
Definition: Types.cs:15
static object[] NoParameters
Contains an empty array of parameter values.
Definition: Types.cs:572
static Type[] GetTypesImplementingInterface(string InterfaceFullName)
Gets all types implementing a given interface.
Definition: Types.cs:85
static ConstructorInfo GetDefaultConstructor(Type Type)
Gets the default constructor of a type, if one exists.
Definition: Types.cs:1742
Abstract base class for JWS algorithm.
Definition: JwsAlgorithm.cs:15
const string JwsContentType
application/jose+json
Definition: JwsAlgorithm.cs:19
virtual IEnumerable< KeyValuePair< string, object > > PublicWebKey
The public JSON web key, if supported.
Definition: JwsAlgorithm.cs:41
virtual void Sign(IEnumerable< KeyValuePair< string, object > > Header, IEnumerable< KeyValuePair< string, object > > Payload, out string HeaderString, out string PayloadString, out string Signature)
Signs data.
Definition: JwsAlgorithm.cs:58
abstract string Sign(string HeaderEncoded, string PayloadEncoded)
Signs data.
static bool TryGetAlgorithm(string Name, out IJwsAlgorithm Algorithm)
Gets the JWS algoritm that corresponds to a given algorithm name.
abstract string Name
Short name for algorithm.
Definition: JwsAlgorithm.cs:25
abstract void Dispose()
IDisposable.Dispose
static IJwsAlgorithm[] GetAlgorithms()
Gets available JWS algorithms.
virtual bool IsValid(string HeaderEncoded, string PayloadEncoded, string SignatureEncoded)
Checks if a signature is valid.
static string[] GetAlgorithmNames()
Gets the names of available JWS algorithms.
abstract bool HasPublicWebKey
If the algorithm has a public key.
Definition: JwsAlgorithm.cs:33
Abstract base class for JWS algorithm.
string Name
Short name for algorithm.