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;
2using System.Collections.Generic;
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 {
125 foreach (Type T in Types.GetTypesImplementingInterface(typeof(IJwsAlgorithm)))
126 {
127 ConstructorInfo CI = Types.GetDefaultConstructor(T);
128 if (CI is null)
129 continue;
130
131 try
132 {
133 Algorithm = (IJwsAlgorithm)CI.Invoke(Types.NoParameters);
134
135 if (algorithms.ContainsKey(Algorithm.Name))
136 Log.Warning("JWS algorithm with name " + Algorithm.Name + " already registered.");
137 else
138 algorithms[Algorithm.Name] = Algorithm;
139 }
140 catch (Exception ex)
141 {
142 Log.Exception(ex);
143 }
144 }
145
146 if (!registered)
147 {
148 Types.OnInvalidated += Types_OnInvalidated;
149 registered = true;
150 }
151
152 initialized = true;
153 }
154
155 return algorithms.TryGetValue(Name, out Algorithm);
156 }
157 }
158
159 private static void Types_OnInvalidated(object Sender, EventArgs e)
160 {
161 lock (algorithms)
162 {
163 algorithms.Clear();
164 initialized = false;
165 }
166 }
167
168 private static readonly Dictionary<string, IJwsAlgorithm> algorithms = new Dictionary<string, IJwsAlgorithm>();
169 private static bool initialized = false;
170 private static bool registered = false;
171 }
172}
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:14
static string Encode(string s)
Encodes a string for inclusion in JSON.
Definition: JSON.cs:507
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
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:1647
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:566
Static class that dynamically manages types and interfaces available in the runtime environment.
Definition: Types.cs:14
static object[] NoParameters
Contains an empty array of parameter values.
Definition: Types.cs:548
static Type[] GetTypesImplementingInterface(string InterfaceFullName)
Gets all types implementing a given interface.
Definition: Types.cs:84
static ConstructorInfo GetDefaultConstructor(Type Type)
Gets the default constructor of a type, if one exists.
Definition: Types.cs:1630
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
virtual bool IsValid(string HeaderEncoded, string PayloadEncoded, string SignatureEncoded)
Checks if a signature is valid.
abstract bool HasPublicWebKey
If the algorithm has a public key.
Definition: JwsAlgorithm.cs:33
Abstract base class for JWS algorithm.