@@ -67,8 +67,7 @@ namespace MimeKit.Cryptography {
67
67
public abstract class BouncyCastleSecureMimeContext : SecureMimeContext
68
68
{
69
69
static readonly string RsassaPssOid = PkcsObjectIdentifiers . IdRsassaPss . Id ;
70
-
71
- HttpClient client ;
70
+ static readonly HttpClient SharedHttpClient = new HttpClient ( ) ;
72
71
73
72
/// <summary>
74
73
/// Initialize a new instance of the <see cref="SecureMimeContext"/> class.
@@ -96,7 +95,6 @@ protected BouncyCastleSecureMimeContext (SecureRandom random)
96
95
throw new ArgumentNullException ( nameof ( random ) ) ;
97
96
98
97
RandomNumberGenerator = random ;
99
- client = new HttpClient ( ) ;
100
98
}
101
99
102
100
/// <summary>
@@ -129,6 +127,17 @@ public bool CheckCertificateRevocation {
129
127
get ; set ;
130
128
}
131
129
130
+ /// <summary>
131
+ /// Get the HTTP client to use for downloading CRLs.
132
+ /// </summary>
133
+ /// <remarks>
134
+ /// Gets the HTTP client to use for downloading CRLs.
135
+ /// </remarks>
136
+ /// <value>The HTTP client used for downloading CRLs.</value>
137
+ protected virtual HttpClient HttpClient {
138
+ get { return SharedHttpClient ; }
139
+ }
140
+
132
141
/// <summary>
133
142
/// Get the X.509 certificate matching the specified selector.
134
143
/// </summary>
@@ -694,12 +703,11 @@ protected IList<X509Certificate> BuildCertificateChain (X509Certificate certific
694
703
695
704
var parameters = new PkixBuilderParameters ( GetTrustedAnchors ( ) , selector ) {
696
705
ValidityModel = PkixParameters . PkixValidityModel ,
697
- IsRevocationEnabled = CheckCertificateRevocation ,
706
+ IsRevocationEnabled = false ,
698
707
Date = DateTime . UtcNow
699
708
} ;
700
709
parameters . AddStoreCert ( intermediates ) ;
701
710
parameters . AddStoreCert ( GetIntermediateCertificates ( ) ) ;
702
- parameters . AddStoreCrl ( GetCertificateRevocationLists ( ) ) ;
703
711
704
712
var builder = new PkixCertPathBuilder ( ) ;
705
713
var result = builder . Build ( parameters ) ;
@@ -879,7 +887,7 @@ async Task<bool> DownloadCrlsOverHttpAsync (string location, Stream stream, bool
879
887
{
880
888
try {
881
889
if ( doAsync ) {
882
- using ( var response = await client . GetAsync ( location , cancellationToken ) . ConfigureAwait ( false ) ) {
890
+ using ( var response = await HttpClient . GetAsync ( location , cancellationToken ) . ConfigureAwait ( false ) ) {
883
891
#if NET6_0_OR_GREATER
884
892
await response . Content . CopyToAsync ( stream , cancellationToken ) . ConfigureAwait ( false ) ;
885
893
#else
@@ -888,7 +896,7 @@ async Task<bool> DownloadCrlsOverHttpAsync (string location, Stream stream, bool
888
896
}
889
897
} else {
890
898
#if NET6_0_OR_GREATER
891
- using ( var response = client . GetAsync ( location , cancellationToken ) . GetAwaiter ( ) . GetResult ( ) )
899
+ using ( var response = HttpClient . GetAsync ( location , cancellationToken ) . GetAwaiter ( ) . GetResult ( ) )
892
900
response . Content . CopyToAsync ( stream , cancellationToken ) . GetAwaiter ( ) . GetResult ( ) ;
893
901
#else
894
902
cancellationToken . ThrowIfCancellationRequested ( ) ;
@@ -1047,8 +1055,10 @@ async Task<DigitalSignatureCollection> GetDigitalSignaturesAsync (CmsSignedDataP
1047
1055
var certificate = GetCertificate ( certificates , signerInfo . SignerID ) ;
1048
1056
var signature = new SecureMimeDigitalSignature ( signerInfo , certificate ) ;
1049
1057
1050
- if ( CheckCertificateRevocation && certificate != null )
1051
- await DownloadCrlsAsync ( certificate , doAsync , cancellationToken ) . ConfigureAwait ( false ) ;
1058
+ if ( CheckCertificateRevocation ) {
1059
+ foreach ( var cert in certificates . EnumerateMatches ( null ) )
1060
+ await DownloadCrlsAsync ( cert , doAsync , cancellationToken ) . ConfigureAwait ( false ) ;
1061
+ }
1052
1062
1053
1063
if ( certificate != null ) {
1054
1064
Import ( certificate , cancellationToken ) ;
@@ -1059,6 +1069,11 @@ async Task<DigitalSignatureCollection> GetDigitalSignaturesAsync (CmsSignedDataP
1059
1069
1060
1070
var anchors = GetTrustedAnchors ( ) ;
1061
1071
1072
+ if ( CheckCertificateRevocation ) {
1073
+ foreach ( var anchor in anchors )
1074
+ await DownloadCrlsAsync ( anchor . TrustedCert , doAsync , cancellationToken ) . ConfigureAwait ( false ) ;
1075
+ }
1076
+
1062
1077
try {
1063
1078
signature . Chain = BuildCertPath ( anchors , certificates , crls , certificate , signature . CreationDate ) ;
1064
1079
} catch ( Exception ex ) {
@@ -1832,22 +1847,5 @@ public override Task<MimePart> ExportAsync (IEnumerable<MailboxAddress> mailboxe
1832
1847
{
1833
1848
return Task . FromResult ( Export ( mailboxes , cancellationToken ) ) ;
1834
1849
}
1835
-
1836
- /// <summary>
1837
- /// Releases all resources used by the <see cref="BouncyCastleSecureMimeContext"/> object.
1838
- /// </summary>
1839
- /// <remarks>Call <see cref="CryptographyContext.Dispose()"/> when you are finished using the <see cref="BouncyCastleSecureMimeContext"/>. The
1840
- /// <see cref="CryptographyContext.Dispose()"/> method leaves the <see cref="BouncyCastleSecureMimeContext"/> in an unusable state. After
1841
- /// calling <see cref="CryptographyContext.Dispose()"/>, you must release all references to the <see cref="BouncyCastleSecureMimeContext"/> so
1842
- /// the garbage collector can reclaim the memory that the <see cref="BouncyCastleSecureMimeContext"/> was occupying.</remarks>
1843
- protected override void Dispose ( bool disposing )
1844
- {
1845
- if ( disposing && client != null ) {
1846
- client . Dispose ( ) ;
1847
- client = null ;
1848
- }
1849
-
1850
- base . Dispose ( disposing ) ;
1851
- }
1852
1850
}
1853
1851
}
0 commit comments