Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
CertificateChain.cs
1using System;
3using System.Globalization;
4using System.Threading.Tasks;
9
11{
15 public static class CertificateChain
16 {
23 public static Task<Certificate[]> GetChain(Certificate Certificate, string CertificateHost)
24 {
25 return GetChain(Certificate, [], CertificateHost, null);
26 }
27
35 public static Task<Certificate[]> GetChain(Certificate Certificate, string CertificateHost,
36 ICommunicationLayer? Client)
37 {
38 return GetChain(Certificate, [], CertificateHost, Client);
39 }
40
50 public static async Task<Certificate[]> GetChain(Certificate Certificate,
51 Dictionary<string, bool> CertificateRevocationLists, string CertificateHost,
52 ICommunicationLayer? Client)
53 {
55
56 foreach (string CrlUrl in TravelDocumentsClient.GetRevocationListUrls(Certificate))
57 CertificateRevocationLists[CrlUrl] = true;
58
59 KeyValuePair<string?, byte[]?> P = TravelDocumentsClient.GetAuthorityKeyIdentifier(Certificate);
60 KeyValuePair<string?, byte[]?> P2 = TravelDocumentsClient.GetSubjectKeyIdentifier(Certificate);
61
62 if (P.Value is null || (AreEquals(P.Value, P2.Value) && P.Key == P2.Key))
63 return [.. Certificates];
64
65 Dictionary<string, bool> Processed = [];
66 string? CountryCode = P.Key;
67 byte[]? IssuerKeyReference = P.Value;
68
69 while (!string.IsNullOrEmpty(CountryCode) && IssuerKeyReference is not null)
70 {
71 string Key = Convert.ToBase64String(IssuerKeyReference);
72 if (Processed.ContainsKey(Key))
73 break;
74
75 Processed[Key] = true;
76
77 Certificate? IssuerCertificate = await CertificateStore.TryLoadCertificate(
78 CertificateHost, CountryCode, IssuerKeyReference, Client);
79
80 if (IssuerCertificate is null)
81 {
82 Client?.Error("Issuer certificate not found: " + CountryCode + ", " +
83 Hashes.BinaryToString(IssuerKeyReference));
84 break;
85 }
86
87 Certificates.Insert(0, IssuerCertificate);
88
89 foreach (string CrlUrl in TravelDocumentsClient.GetRevocationListUrls(IssuerCertificate))
90 CertificateRevocationLists[CrlUrl] = true;
91
92 P = TravelDocumentsClient.GetAuthorityKeyIdentifier(IssuerCertificate);
93 CountryCode = P.Key;
94 IssuerKeyReference = P.Value;
95 }
96
97 return [.. Certificates];
98 }
99
100 private static bool AreEquals(byte[]? A1, byte[]? A2)
101 {
102 if ((A1 is null) ^ (A2 is null))
103 return false;
104
105 if (A1 is null)
106 return true;
107
108 int c = A1.Length;
109 if (A2!.Length != c)
110 return false;
111
112 for (int i = 0; i < c; i++)
113 {
114 if (A1[i] != A2[i])
115 return false;
116 }
117
118 return true;
119 }
120
127 public static bool VerifySignatures(params Certificate[] Certificates)
128 {
129 return VerifySignatures(null, Certificates);
130 }
131
139 public static bool VerifySignatures(ICommunicationLayer? Client, params Certificate[] Certificates)
140 {
141 if (Certificates.Length == 0)
142 return false;
143
144 Certificate Issuer = Certificates[0]; // Root is self-signed.
145 int Index = 0;
146
147 foreach (Certificate Cert in Certificates)
148 {
149 Client?.Information("Validating certificate " + (++Index) + " signature, serial number: " + Cert.SerialNumber.ToString(CultureInfo.InvariantCulture));
150
151 if (Issuer.PublicKey is null)
152 {
153 Client?.Error("Unable to decode issuer signature algorithm and public key.\r\n\r\n" +
154 Convert.ToBase64String(Cert.Binary, Base64FormattingOptions.InsertLineBreaks));
155
156 return false;
157 }
158
159 if (Issuer.PublicKey is ISecurityObject PublicKeyObject &&
160 !PublicKeyObject.IsConfigured)
161 {
162 Client?.Error("Issuer public key not configured properly.\r\n\r\n" +
163 Convert.ToBase64String(Cert.Binary, Base64FormattingOptions.InsertLineBreaks));
164
165 return false;
166 }
167
168 if (!Cert.IssuerSignatureAlgorithm.VerifySignature(Cert.ToBeSignedCertificate.Binary,
169 Cert.Signature, Issuer.PublicKey, Client))
170 {
171 Client?.Error("Certificate signature not valid.\r\n\r\n" +
172 Convert.ToBase64String(Cert.Binary, Base64FormattingOptions.InsertLineBreaks));
173
174 return false;
175 }
176
177 Issuer = Cert;
178 }
179
180 return true;
181 }
182 }
183}
Static class for validation of ICAO certificate chains
static Task< Certificate[]> GetChain(Certificate Certificate, string CertificateHost)
Gets the certificate chain for a given certificate.
static async Task< Certificate[]> GetChain(Certificate Certificate, Dictionary< string, bool > CertificateRevocationLists, string CertificateHost, ICommunicationLayer? Client)
Gets the certificate chain for a given certificate, as well as the URLs for associated Certificate Re...
static bool VerifySignatures(params Certificate[] Certificates)
Verifies the signatures of a chain of ICAO certificates.
static bool VerifySignatures(ICommunicationLayer? Client, params Certificate[] Certificates)
Verifies the signatures of a chain of ICAO certificates.
static Task< Certificate[]> GetChain(Certificate Certificate, string CertificateHost, ICommunicationLayer? Client)
Gets the certificate chain for a given certificate.
Certificate, as defined in RFC 5280, §4.1.
Definition: Certificate.cs:13
ToBeSignedCertificate ToBeSignedCertificate
Certificate that is signed.
Definition: Certificate.cs:91
ISignatureAlgorithm IssuerSignatureAlgorithm
Signature algorithm used by issuer to sign the certificate.
Definition: Certificate.cs:96
System.Numerics.BigInteger SerialNumber
Serial Number
Definition: Certificate.cs:121
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.
byte[] Binary
Binary representation of certificate to be signed.
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
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
bool IsConfigured
If the object has been configured.
Interface for observable classes implementing communication protocols.