1313
1414using System ;
1515using System . Buffers . Text ;
16+ using System . Net ;
17+ using System . Security . Cryptography ;
1618using System . Security . Cryptography . X509Certificates ;
19+ using System . Text . Json ;
1720using System . Xml ;
1821using System . Xml . Linq ;
1922using AasSecurity . Models ;
2023using AasxServer ;
2124using AdminShellNS ;
2225using IdentityModel ;
26+ using Namotion . Reflection ;
2327
2428namespace AasSecurity
2529{
2630 internal static class SecuritySettingsForServerParser
27- {
28- //private static ILogger _logger = ApplicationLogging.CreateLogger("SecuritySettingsForServerParser");
31+ {
32+ //private static ILogger _logger = ApplicationLogging.CreateLogger("SecuritySettingsForServerParser");
33+
34+ /// <summary>
35+ /// Import the RSA key from a pem file
36+ /// </summary>
37+ /// <param name="pemFile">public key provided as pem file</param>
38+ /// <returns>RSA key object instance</returns>
39+ private static RSA ReadPemFile ( string pemFile )
40+ {
41+ string privateKeyPem = System . IO . File . ReadAllText ( pemFile ) ;
42+
43+ RSA rsa = RSA . Create ( ) ;
44+ rsa . ImportFromPem ( privateKeyPem . AsSpan ( ) ) ;
45+
46+
47+ return rsa ;
48+ }
2949
3050 internal static void ParseSecuritySettingsForServer ( AdminShellPackageEnv env , ISubmodel submodel )
3151 {
@@ -35,35 +55,35 @@ internal static void ParseSecuritySettingsForServer(AdminShellPackageEnv env, IS
3555 {
3656 switch ( submodelElement . IdShort ! . ToLower ( ) )
3757 {
38- case "authenticationserver" :
39- {
40- if ( submodelElement is SubmodelElementCollection authServer )
41- {
42- ParseAuthenticationServer ( env , authServer ) ;
43- }
44- }
45- break ;
46- case "rolemapping" :
47- {
48- if ( submodelElement is SubmodelElementCollection roleMappings )
49- {
50- ParseRoleMappings ( roleMappings ) ;
51- }
52- }
53- break ;
54- case "basicauth" :
55- {
56- if ( submodelElement is SubmodelElementCollection basicAuth )
57- {
58- ParseBasicAuth ( basicAuth ) ;
59- }
60- break ;
61- }
62- default :
63- {
64- //_logger.LogError($"Unhandled submodel element {submodelElement.IdShort} while parsing SecuritySettingsForServer.");
65- break ;
66- }
58+ case "authenticationserver" :
59+ {
60+ if ( submodelElement is SubmodelElementCollection authServer )
61+ {
62+ ParseAuthenticationServer ( env , authServer ) ;
63+ }
64+ }
65+ break ;
66+ case "rolemapping" :
67+ {
68+ if ( submodelElement is SubmodelElementCollection roleMappings )
69+ {
70+ ParseRoleMappings ( roleMappings ) ;
71+ }
72+ }
73+ break ;
74+ case "basicauth" :
75+ {
76+ if ( submodelElement is SubmodelElementCollection basicAuth )
77+ {
78+ ParseBasicAuth ( basicAuth ) ;
79+ }
80+ break ;
81+ }
82+ default :
83+ {
84+ //_logger.LogError($"Unhandled submodel element {submodelElement.IdShort} while parsing SecuritySettingsForServer.");
85+ break ;
86+ }
6787 }
6888 }
6989 }
@@ -83,8 +103,10 @@ private static void ParseBasicAuth(SubmodelElementCollection basicAuth)
83103 }
84104 }
85105
86- private static void ParseAuthenticationServer ( AdminShellPackageEnv env , SubmodelElementCollection ? authServer )
106+ private async static void ParseAuthenticationServer ( AdminShellPackageEnv env , SubmodelElementCollection ? authServer )
87107 {
108+ var trustListOnServer = System . Environment . GetEnvironmentVariable ( "TRUST_LIST" ) ;
109+
88110 if ( System . IO . File . Exists ( "trustlist.txt" ) )
89111 {
90112 Console . WriteLine ( "Read trustlist.txt" ) ;
@@ -156,13 +178,69 @@ private static void ParseAuthenticationServer(AdminShellPackageEnv env, Submodel
156178 }
157179 }
158180 }
159- if ( System . IO . File . Exists ( "trustlist.xml" ) )
181+
182+ XDocument doc = null ;
183+
184+ // Create a new XML document.
185+ XmlDocument xmlDoc = new ( )
160186 {
161- Console . WriteLine ( "Read trustlist.xml" ) ;
187+ // Load an XML file into the XmlDocument object.
188+ PreserveWhitespace = true
189+ } ;
190+
191+ if ( ! string . IsNullOrEmpty ( trustListOnServer ) )
192+ {
193+ var handlerExchange = new HttpClientHandler { DefaultProxyCredentials = CredentialCache . DefaultCredentials } ;
194+ using var client = new HttpClient ( handlerExchange ) ;
195+
196+ try
197+ {
198+ var response = await client . GetAsync ( trustListOnServer ) ;
199+ response . EnsureSuccessStatusCode ( ) ;
200+
201+ var content = await response . Content . ReadAsStreamAsync ( ) ;
202+
203+ xmlDoc . Load ( content ) ;
204+
205+ content . Position = 0 ;
206+
207+ doc = XDocument . Load ( content ) ;
208+ }
209+ catch ( Exception ex )
210+ {
211+ Console . WriteLine ( $ "Error: { ex . Message } ") ;
212+ }
213+ }
162214
215+ var localTrustListPath = "trustlist.xml" ;
163216
217+ if ( doc == null && System . IO . File . Exists ( localTrustListPath ) )
218+ {
164219 // Load the XML
165- var doc = XDocument . Load ( "trustlist.xml" ) ;
220+ doc = XDocument . Load ( localTrustListPath ) ;
221+ xmlDoc . Load ( localTrustListPath ) ;
222+ }
223+
224+ var localPemFilePath = "publickey.pem" ;
225+
226+ if ( doc != null )
227+ {
228+ if ( System . IO . File . Exists ( localPemFilePath ) )
229+ {
230+ RSA rsa = ReadPemFile ( localPemFilePath ) ;
231+
232+ bool sigValidation = TrustListVerifier . VerifyXmlSignature ( xmlDoc , rsa ) ;
233+
234+ if ( sigValidation )
235+ {
236+ Console . WriteLine ( "Signature could get validated" ) ;
237+ }
238+ else
239+ {
240+ Console . WriteLine ( "Signature validation failed" ) ;
241+ return ;
242+ }
243+ }
166244
167245 // Default ETSI namespace present in the document
168246 XNamespace ns = "http://uri.etsi.org/02231/v2#" ; // <- critical
@@ -245,6 +323,7 @@ private static void ParseAuthenticationServer(AdminShellPackageEnv env, Submodel
245323 }
246324 }
247325 }
326+
248327 if ( authServer == null || authServer . Value == null )
249328 {
250329 return ;
0 commit comments