Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
CertificateList.cs
1using System;
2using System.Diagnostics.CodeAnalysis;
3using System.Runtime.ConstrainedExecution;
4using System.Text;
5using System.Threading.Tasks;
9using Waher.Content;
11
13{
17 public class CertificateList
18 {
28 {
29 this.Asn1Vector = Asn1Vector;
30 this.ToBeSignedCertificateList = ToBeSignedCertificateList;
31 this.SignatureAlgorithm = SignatureAlgorithm;
32 this.Signature = Signature;
33 }
34
41 public static bool TryParse(byte[] RawCertificateList, [NotNullWhen(true)] out CertificateList? Parsed)
42 {
43 Parsed = null;
44
45 if (!ASN1.TryDecodeDer(RawCertificateList, out object? Content))
46 return false;
47
48 if (Content is not Vector CertificateListVector)
49 return false;
50
51 return TryParse(CertificateListVector, out Parsed);
52 }
53
61 public static bool TryParse(Vector CertificateListVector, [NotNullWhen(true)] out CertificateList? Parsed)
62 {
63 Parsed = null;
64
65 if (CertificateListVector.Length != 3)
66 return false;
67
68 if (CertificateListVector.FirstElement is not Vector TbsCertList)
69 return false;
70
72
73 if (CertificateListVector[1] is ISignatureAlgorithm Algorithm)
74 SignatureAlgorithm = Algorithm;
75 else if (CertificateListVector[1] is Vector AlgorithmIdentifier)
76 SignatureAlgorithm = Security.SignatureAlgorithms.SignatureAlgorithm.TryDecode(AlgorithmIdentifier);
77 else
78 return false;
79
80 if (SignatureAlgorithm is null)
81 return false;
82
83 if (CertificateListVector[2] is not byte[] Signature)
84 return false;
85
86 if (!ToBeSignedCertificateList.TryParse(TbsCertList, out ToBeSignedCertificateList? ToBeSigned))
87 return false;
88
89 Parsed = new CertificateList(CertificateListVector, ToBeSigned, SignatureAlgorithm, Signature);
90
91 return true;
92 }
93
98
103
107 public byte[] Signature { get; }
108
112 public Vector Asn1Vector { get; }
113
117 public int? Version => this.ToBeSignedCertificateList.Version;
118
122 public Vector Issuer => this.ToBeSignedCertificateList.Issuer;
123
127 public DateTimeOffset ThisUpdate => this.ToBeSignedCertificateList.ThisUpdate;
128
132 public DateTimeOffset NextUpdate => this.ToBeSignedCertificateList.NextUpdate;
133
137 public RevokedCertificate[] RevokedCertificates => this.ToBeSignedCertificateList.RevokedCertificates;
138
142 public byte[]? AuthorityKeyIdentifier => this.ToBeSignedCertificateList.AuthorityKeyIdentifier;
143
147 public Vector? Extensions => this.ToBeSignedCertificateList.Extensions;
148
156 {
157 return this.ToBeSignedCertificateList.HasBeenRevoked(Certificate, out Reason);
158 }
159
166 public Task<bool> VerifySignature(string IdDomain, string CountryCode)
167 {
168 return this.VerifySignature(IdDomain, CountryCode, null);
169 }
170
178 public async Task<bool> VerifySignature(string IdDomain, string CountryCode,
179 ICommunicationLayer? Client)
180 {
181 if (this.Signature is null)
182 {
183 Client?.Error("No signature in CRL.");
184 return false;
185 }
186
187 if (this.AuthorityKeyIdentifier is null)
188 {
189 Client?.Error("No AKI in CRL.");
190 return false;
191 }
192
193 Certificate? SignerCertificate = await CertificateStore.TryLoadCertificate(
194 IdDomain, CountryCode, this.AuthorityKeyIdentifier, Client);
195
196 if (SignerCertificate is null)
197 {
198 Client?.Error("Unable to load issuer certificate from the AKI: " +
199 Waher.Security.Hashes.BinaryToString(this.AuthorityKeyIdentifier));
200 return false;
201 }
202
203 if (SignerCertificate.PublicKey is null)
204 {
205 Client?.Error("Unable to decode public key from issuer certificate.\r\n\r\n" +
206 Convert.ToBase64String(SignerCertificate.Binary, Base64FormattingOptions.InsertLineBreaks));
207 return false;
208 }
209
210 if (this.SignatureAlgorithm.VerifySignature(this.ToBeSignedCertificateList.Binary,
211 this.Signature, SignerCertificate.PublicKey, Client))
212 {
213 return true;
214 }
215
216 if (Client?.HasSniffers ?? false)
217 {
218 StringBuilder sb = new();
219
220 sb.AppendLine("CRL signature verification failed.");
221 sb.AppendLine();
222 sb.AppendLine("Data to be signed:");
223 sb.AppendLine(Convert.ToBase64String(this.ToBeSignedCertificateList.Binary,
224 Base64FormattingOptions.InsertLineBreaks));
225 sb.AppendLine();
226 sb.AppendLine("Signature:");
227 sb.AppendLine(Convert.ToBase64String(this.Signature,
228 Base64FormattingOptions.InsertLineBreaks));
229 sb.AppendLine();
230 sb.AppendLine("Authority Key Identifier:");
231 sb.AppendLine(Waher.Security.Hashes.BinaryToString(this.AuthorityKeyIdentifier));
232 sb.AppendLine();
233 sb.AppendLine("Public Key to verify signature:");
234 sb.AppendLine(JSON.Encode(SignerCertificate.PublicKey, true));
235
236 Client.Warning(sb.ToString());
237 }
238
239 return false;
240 }
241
242 }
243}
Static class for parsing and decoding security objects encoded using Abstract Syntax Notation 1 (ASN....
Definition: ASN1.cs:22
static bool TryDecodeDer(byte[] Data, out object? Value)
Decodes a DER-encoded object.
Definition: ASN1.cs:77
Certificate, as defined in RFC 5280, §4.1.
Definition: Certificate.cs:13
IPublicKey PublicKey
Certificate public key, used to verify signatures issued by the certificate.
Definition: Certificate.cs:156
byte[] Binary
ASN.1 DER encoded certificate.
Definition: Certificate.cs:111
static Task< Certificate?> TryLoadCertificate(string IdDomain, string Country, byte[] KeyReference)
Tries to load an ICAO certificate, provided its country and key reference.
Certificate List, as defined in RFC 5280, §5.1
ToBeSignedCertificateList ToBeSignedCertificateList
List of certificates that is signed.
ISignatureAlgorithm SignatureAlgorithm
Algorithm used to sign the certificate list.
static bool TryParse(Vector CertificateListVector, [NotNullWhen(true)] out CertificateList? Parsed)
Tries to parse an ASN.1-encoded Certificate List, as defined in RFC 5280, §5.1
bool HasBeenRevoked(Certificate Certificate, out RevokedReason Reason)
Checks if a certificate has been revoked.
async Task< bool > VerifySignature(string IdDomain, string CountryCode, ICommunicationLayer? Client)
Verifies the signature of the CRL
DateTimeOffset NextUpdate
Next update, or DateTime.MaxValue if not specified.
RevokedCertificate[] RevokedCertificates
List of revoked certificates.
Task< bool > VerifySignature(string IdDomain, string CountryCode)
Verifies the signature of the CRL
static bool TryParse(byte[] RawCertificateList, [NotNullWhen(true)] out CertificateList? Parsed)
Tries to parse an ASN.1-encoded Certificate List, as defined in RFC 5280, §5.1.
Certificate List, without signature, as defined in RFC 5280, §5.1
DateTimeOffset NextUpdate
Next update, or DateTime.MaxValue if not specified.
static bool TryParse(Vector TbsCertList, [NotNullWhen(true)] out ToBeSignedCertificateList? Parsed)
Tries to parse an ASN.1-encoded Certificate List, as defined in RFC 5280, §5.1
bool HasBeenRevoked(Certificate Certificate, out RevokedReason Reason)
Checks if a certificate has been revoked.
Abstract base class for signature algorithms, as defined in RFC 5280.
SignatureAlgorithm()
Abstract base class for signature algorithms, as defined in RFC 5280.
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
Contains methods for simple hash calculations.
Definition: Hashes.cs:57
static string BinaryToString(byte[] Data)
Converts an array of bytes to a string with their hexadecimal representations (in lower case).
Definition: Hashes.cs:63
Interface for signature algorithms, as defined in RFC 5280.
bool VerifySignature(byte[] Data, byte[] Signature, IPublicKey PublicKey, ICommunicationLayer? Client)
Verifies a digital signature.
void Error(string Error)
Called to inform the viewer of an error state.
void Warning(string Warning)
Called to inform the viewer of a warning state.
Interface for observable classes implementing communication protocols.
RevokedReason
Reason for revoking a certificate
Definition: RevokedReason.cs:7
Definition: App.xaml.cs:4