55using Intersect . Server . Web . Configuration ;
66using Microsoft . AspNetCore . Authentication . JwtBearer ;
77using Microsoft . IdentityModel . Tokens ;
8+ using Newtonsoft . Json ;
89using Newtonsoft . Json . Linq ;
910
1011namespace Intersect . Server . Web ;
@@ -64,7 +65,7 @@ private static void ValidateConfiguration()
6465 rawConfiguration = "{}" ;
6566 }
6667
67- var configurationJObject = JObject . Parse ( rawConfiguration ) ;
68+ var configurationJObject = JsonConvert . DeserializeObject < JObject > ( rawConfiguration ) ;
6869 if ( ! configurationJObject . TryGetValue ( "Api" , out var apiSectionJToken ) )
6970 {
7071 apiSectionJToken = JObject . FromObject ( new ApiConfiguration ( ) ) ;
@@ -102,7 +103,10 @@ private static void ValidateConfiguration()
102103
103104 if ( apiConfiguration . StaticFilePaths == default )
104105 {
105- apiConfiguration . StaticFilePaths = new List < StaticFilePathOptions > { new ( "wwwroot" ) } ;
106+ apiConfiguration . StaticFilePaths = new List < StaticFilePathOptions >
107+ {
108+ new ( "wwwroot" )
109+ } ;
106110 }
107111
108112 var updatedApiConfigurationJObject = JObject . FromObject ( apiConfiguration ) ;
@@ -166,21 +170,21 @@ out var validIssuerToken
166170
167171 foreach ( var endpointToken in endpoints . PropertyValues ( ) )
168172 {
169- if ( endpointToken is not JObject endpoint )
173+ if ( endpointToken is not JObject endpointValue )
170174 {
171175 continue ;
172176 }
177+ var endpoint = endpointValue . ToObject < PartialKestrelEndpoint > ( ) ;
173178
174- if ( ! endpoint . TryGetValue ( "Certificate" , out var certificateToken ) ||
175- certificateToken is not JObject certificate )
179+ if ( endpoint . Certificate is not { } certificate )
176180 {
177181 continue ;
178182 }
179183
180184 try
181185 {
182- var certificatePath = certificate . Value < string > ( " Path" ) ;
183- var keyPath = certificate . Value < string > ( " KeyPath" ) ;
186+ var certificatePath = certificate . Path ;
187+ var keyPath = certificate . KeyPath ;
184188
185189 if ( ! string . Equals ( certificatePath , SelfSignedCertificateName ) ||
186190 ! string . Equals ( keyPath , SelfSignedKeyName ) )
@@ -201,17 +205,79 @@ out var validIssuerToken
201205 ) ;
202206 }
203207
204- using var ecdsa = ECDsa . Create ( ) ;
205- CertificateRequest request = new ( "cn=self-signed" , ecdsa , HashAlgorithmName . SHA384 ) ;
206- var selfSignedCertificate = request . CreateSelfSigned (
208+ AsymmetricAlgorithm algorithm ;
209+ CertificateRequest certificateRequest ;
210+ var osVersion = Environment . OSVersion ;
211+
212+ PartialKestrelEndpointCertificateType certificateType = certificate . SelfSignedCertificateType ;
213+ if ( certificateType == PartialKestrelEndpointCertificateType . None )
214+ {
215+ certificateType = osVersion . Platform switch
216+ {
217+ PlatformID . Win32S or PlatformID . Win32Windows or PlatformID . Win32NT or PlatformID . WinCE
218+ or PlatformID . Xbox => osVersion . Version . Major < 11
219+ ? PartialKestrelEndpointCertificateType . RSA
220+ : PartialKestrelEndpointCertificateType . ECDSA ,
221+ PlatformID . Unix or PlatformID . MacOSX or PlatformID . Other =>
222+ PartialKestrelEndpointCertificateType . ECDSA ,
223+ _ => throw new ArgumentOutOfRangeException ( )
224+ } ;
225+ }
226+
227+ switch ( certificateType )
228+ {
229+ case PartialKestrelEndpointCertificateType . None :
230+ throw new InvalidOperationException ( ) ;
231+ case PartialKestrelEndpointCertificateType . RSA :
232+ {
233+ var rsa = RSA . Create ( 4096 ) ;
234+ algorithm = rsa ;
235+ certificateRequest = new CertificateRequest (
236+ "cn=self-signed" ,
237+ rsa ,
238+ HashAlgorithmName . SHA256 ,
239+ RSASignaturePadding . Pkcs1
240+ ) ;
241+ break ;
242+ }
243+ case PartialKestrelEndpointCertificateType . ECDSA :
244+ {
245+ var ecdsa = ECDsa . Create ( ) ;
246+ algorithm = ecdsa ;
247+ certificateRequest = new CertificateRequest ( "cn=self-signed" , ecdsa , HashAlgorithmName . SHA384 ) ;
248+ break ;
249+ }
250+ default :
251+ throw new ArgumentOutOfRangeException ( ) ;
252+ }
253+
254+ var selfSignedCertificate = certificateRequest . CreateSelfSigned (
207255 DateTimeOffset . Now ,
208256 DateTimeOffset . Now . AddDays ( 30 )
209257 ) ;
210258
211259 var certificatePem = selfSignedCertificate . ExportCertificatePem ( ) ;
212- var keyPem = selfSignedCertificate . GetECDsaPrivateKey ( ) . ExportECPrivateKeyPem ( ) ;
260+
261+ string keyPem ;
262+ if ( selfSignedCertificate . GetRSAPrivateKey ( ) is { } rsaPrivateKey )
263+ {
264+ keyPem = rsaPrivateKey . ExportRSAPrivateKeyPem ( ) ;
265+ }
266+ else if ( selfSignedCertificate . GetECDsaPrivateKey ( ) is { } ecDsaPrivateKey )
267+ {
268+ keyPem = ecDsaPrivateKey . ExportECPrivateKeyPem ( ) ;
269+ }
270+ else
271+ {
272+ throw new InvalidOperationException (
273+ "Private key should be RSA or ECDSA, why was this code changed without verifying it?"
274+ ) ;
275+ }
276+
213277 File . WriteAllText ( SelfSignedCertificateName , certificatePem ) ;
214278 File . WriteAllText ( SelfSignedKeyName , keyPem ) ;
279+
280+ algorithm . Dispose ( ) ;
215281 }
216282 catch ( Exception exception )
217283 {
0 commit comments