@@ -79,7 +79,7 @@ internal sealed class CertificateAuthority : IDisposable
79
79
private byte [ ] _certData ;
80
80
private X509Extension _cdpExtension ;
81
81
private X509Extension _aiaExtension ;
82
- private X509Extension _akidExtension ;
82
+ private X509AuthorityKeyIdentifierExtension _akidExtension ;
83
83
84
84
private List < ( byte [ ] , DateTimeOffset ) > _revocationList ;
85
85
private byte [ ] _crl ;
@@ -305,7 +305,67 @@ internal byte[] GetCrl()
305
305
}
306
306
307
307
DateTimeOffset newExpiry = now . AddSeconds ( 2 ) ;
308
+ X509AuthorityKeyIdentifierExtension akid = _akidExtension ??= CreateAkidExtension ( ) ;
308
309
310
+ if ( OmitNextUpdateInCrl )
311
+ {
312
+ crl = BuildCrlManually ( now , newExpiry , akid ) ;
313
+ }
314
+ else
315
+ {
316
+ CertificateRevocationListBuilder builder = new CertificateRevocationListBuilder ( ) ;
317
+
318
+ if ( _revocationList is not null )
319
+ {
320
+ foreach ( ( byte [ ] serial , DateTimeOffset when ) in _revocationList )
321
+ {
322
+ builder . AddEntry ( serial , when ) ;
323
+ }
324
+ }
325
+
326
+ DateTimeOffset thisUpdate ;
327
+ DateTimeOffset nextUpdate ;
328
+
329
+ if ( RevocationExpiration . HasValue )
330
+ {
331
+ nextUpdate = RevocationExpiration . GetValueOrDefault ( ) ;
332
+ thisUpdate = _cert . NotBefore ;
333
+ }
334
+ else
335
+ {
336
+ thisUpdate = now ;
337
+ nextUpdate = newExpiry ;
338
+ }
339
+
340
+ using ( RSA key = _cert . GetRSAPrivateKey ( ) )
341
+ {
342
+ crl = builder . Build (
343
+ CorruptRevocationIssuerName ? s_nonParticipatingName : _cert . SubjectName ,
344
+ X509SignatureGenerator . CreateForRSA ( key , RSASignaturePadding . Pkcs1 ) ,
345
+ _crlNumber ,
346
+ nextUpdate ,
347
+ HashAlgorithmName . SHA256 ,
348
+ _akidExtension ,
349
+ thisUpdate ) ;
350
+ }
351
+ }
352
+
353
+ if ( CorruptRevocationSignature )
354
+ {
355
+ crl [ ^ 2 ] ^= 0xFF ;
356
+ }
357
+
358
+ _crl = crl ;
359
+ _crlExpiry = newExpiry ;
360
+ _crlNumber ++ ;
361
+ return crl ;
362
+ }
363
+
364
+ private byte [ ] BuildCrlManually (
365
+ DateTimeOffset now ,
366
+ DateTimeOffset newExpiry ,
367
+ X509AuthorityKeyIdentifierExtension akidExtension )
368
+ {
309
369
AsnWriter writer = new AsnWriter ( AsnEncodingRules . DER ) ;
310
370
311
371
using ( writer . PushSequence ( ) )
@@ -383,22 +443,17 @@ internal byte[] GetCrl()
383
443
// Extensions (SEQUENCE OF)
384
444
using ( writer . PushSequence ( ) )
385
445
{
386
- if ( _akidExtension == null )
387
- {
388
- _akidExtension = CreateAkidExtension ( ) ;
389
- }
390
-
391
446
// Authority Key Identifier Extension
392
447
using ( writer . PushSequence ( ) )
393
448
{
394
- writer . WriteObjectIdentifier ( _akidExtension . Oid . Value ) ;
449
+ writer . WriteObjectIdentifier ( akidExtension . Oid . Value ) ;
395
450
396
- if ( _akidExtension . Critical )
451
+ if ( akidExtension . Critical )
397
452
{
398
453
writer . WriteBoolean ( true ) ;
399
454
}
400
455
401
- writer . WriteOctetString ( _akidExtension . RawData ) ;
456
+ writer . WriteOctetString ( akidExtension . RawData ) ;
402
457
}
403
458
404
459
// CRL Number Extension
@@ -439,11 +494,7 @@ internal byte[] GetCrl()
439
494
writer . WriteBitString ( signature ) ;
440
495
}
441
496
442
- _crl = writer . Encode ( ) ;
443
-
444
- _crlExpiry = newExpiry ;
445
- _crlNumber ++ ;
446
- return _crl ;
497
+ return writer . Encode ( ) ;
447
498
}
448
499
449
500
internal void DesignateOcspResponder ( X509Certificate2 responder )
@@ -706,7 +757,7 @@ private static X509Extension CreateCdpExtension(string cdp)
706
757
return CertificateRevocationListBuilder . BuildCrlDistributionPointExtension ( new [ ] { cdp } ) ;
707
758
}
708
759
709
- private X509Extension CreateAkidExtension ( )
760
+ private X509AuthorityKeyIdentifierExtension CreateAkidExtension ( )
710
761
{
711
762
X509SubjectKeyIdentifierExtension skid =
712
763
_cert . Extensions . OfType < X509SubjectKeyIdentifierExtension > ( ) . SingleOrDefault ( ) ;
0 commit comments