@@ -253,4 +253,60 @@ export class LocalCA {
253253
254254 return generatedCertificate ;
255255 }
256+
257+ generateSelfSignedCertificate ( domain : string ) {
258+ const cacheKey = `${ domain } :self-signed` ;
259+
260+ const cachedCert = this . certInMemoryCache [ cacheKey ] ;
261+ if ( cachedCert ) return cachedCert ;
262+
263+ const cert = pki . createCertificate ( ) ;
264+
265+ cert . publicKey = KEY_PAIR ! . publicKey ;
266+ cert . serialNumber = generateSerialNumber ( ) ;
267+
268+ cert . validity . notBefore = new Date ( ) ;
269+ cert . validity . notBefore . setDate ( cert . validity . notBefore . getDate ( ) - 1 ) ;
270+
271+ cert . validity . notAfter = new Date ( ) ;
272+ cert . validity . notAfter . setFullYear ( cert . validity . notAfter . getFullYear ( ) + 1 ) ;
273+
274+ const subject = [
275+ { name : 'commonName' , value : domain } ,
276+ { name : 'countryName' , value : this . options ?. countryName ?? 'XX' } ,
277+ { name : 'localityName' , value : this . options ?. localityName ?? 'Unknown' } ,
278+ { name : 'organizationName' , value : this . options ?. organizationName ?? 'Testserver Test Cert' }
279+ ] ;
280+
281+ cert . setSubject ( subject ) ;
282+ cert . setIssuer ( subject ) ; // Self-signed: issuer = subject
283+
284+ cert . setExtensions ( [
285+ { name : 'basicConstraints' , cA : false , critical : true } ,
286+ { name : 'keyUsage' , digitalSignature : true , keyEncipherment : true , critical : true } ,
287+ { name : 'extKeyUsage' , serverAuth : true , clientAuth : true } ,
288+ {
289+ name : 'subjectAltName' ,
290+ altNames : [ { type : 2 , value : domain } ]
291+ } ,
292+ { name : 'subjectKeyIdentifier' }
293+ ] ) ;
294+
295+ cert . sign ( KEY_PAIR ! . privateKey , md . sha256 . create ( ) ) ; // Self-signed: sign with own key
296+
297+ const certPem = pki . certificateToPem ( cert ) ;
298+ const generatedCertificate = {
299+ key : pki . privateKeyToPem ( KEY_PAIR ! . privateKey ) ,
300+ cert : certPem ,
301+ ca : certPem // Self-signed: cert is its own CA
302+ } ;
303+
304+ this . certInMemoryCache [ cacheKey ] = generatedCertificate ;
305+
306+ setTimeout ( ( ) => {
307+ delete this . certInMemoryCache [ cacheKey ] ;
308+ } , 1000 * 60 * 60 * 24 ) . unref ( ) ;
309+
310+ return generatedCertificate ;
311+ }
256312}
0 commit comments