22// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33
44using System ;
5+ using System . Security . Cryptography ;
56using System . Security . Cryptography . X509Certificates ;
67using System . Threading . Tasks ;
8+ using Microsoft . Internal . NuGet . Testing . SignedPackages ;
79using NuGet . Common ;
8- using Org . BouncyCastle . Asn1 . X509 ;
9- using Org . BouncyCastle . Crypto . Parameters ;
10- using Org . BouncyCastle . Security ;
11- using Org . BouncyCastle . X509 ;
12- using Org . BouncyCastle . X509 . Extension ;
13- using Test . Utility . Signing ;
1410using TestUtil ;
1511using Xunit ;
16- using BCCertificate = Org . BouncyCastle . X509 . X509Certificate ;
1712
1813namespace Validation . PackageSigning . Core . Tests . Support
1914{
@@ -38,7 +33,7 @@ public CertificateIntegrationTestFixture()
3833 {
3934 Assert . True (
4035 UserHelper . IsAdministrator ( ) ,
41- $ "This test must be executing with administrator privileges since it installs a trusted root. Add { UserHelper . EnableSkipVariableName } environment variable to skip this test.") ;
36+ $ "This test must be executing with administrator privileges since it installs a trusted root. Add { UserHelper . EnableSkipVariableName } environment variable to skip this test.") ;
4237 _testServer = new AsyncLazy < SigningTestServer > ( SigningTestServer . CreateAsync ) ;
4338 _rootCertificateAuthority = new AsyncLazy < CertificateAuthority > ( CreateDefaultTrustedRootCertificateAuthorityAsync ) ;
4439 _certificateAuthority = new AsyncLazy < CertificateAuthority > ( CreateDefaultTrustedCertificateAuthorityAsync ) ;
@@ -88,7 +83,7 @@ private async Task<CertificateAuthority> CreateDefaultTrustedRootCertificateAuth
8883 {
8984 var testServer = await GetTestServerAsync ( ) ;
9085 var rootCa = CertificateAuthority . Create ( testServer . Url ) ;
91- var rootCertificate = rootCa . Certificate . ToX509Certificate2 ( ) ;
86+ var rootCertificate = new X509Certificate2 ( rootCa . Certificate ) ;
9287
9388 _trustedRoot = new TrustedTestCert < X509Certificate2 > (
9489 rootCertificate ,
@@ -138,10 +133,10 @@ private async Task<X509Certificate2> CreateDefaultTrustedSigningCertificateAsync
138133
139134 public X509Certificate2 CreateSigningCertificate ( CertificateAuthority ca )
140135 {
141- void CustomizeAsSigningCertificate ( X509V3CertificateGenerator generator )
136+ void CustomizeAsSigningCertificate ( CertificateRequest certificateRequest )
142137 {
143- generator . AddSigningEku ( ) ;
144- generator . AddAuthorityInfoAccess ( ca , addOcsp : true , addCAIssuers : true ) ;
138+ certificateRequest . AddSigningEku ( ) ;
139+ certificateRequest . AddAuthorityInfoAccess ( ca , addOcsp : true , addCAIssuers : true ) ;
145140 }
146141
147142 return IssueCertificate ( ca , "Signing" , CustomizeAsSigningCertificate ) . certificate ;
@@ -151,49 +146,39 @@ public async Task<X509Certificate2> CreateUntrustedRootSigningCertificateAsync()
151146 {
152147 var options = IssueCertificateOptions . CreateDefaultForRootCertificateAuthority ( ) ;
153148
154- options . CustomizeCertificate = ( X509V3CertificateGenerator generator ) =>
149+ options . CustomizeCertificate = ( CertificateRequest certificateRequest ) =>
155150 {
156- generator . AddExtension (
157- X509Extensions . SubjectKeyIdentifier ,
158- critical : false ,
159- extensionValue : new SubjectKeyIdentifierStructure ( options . KeyPair . Public ) ) ;
160- generator . AddExtension (
161- X509Extensions . BasicConstraints ,
162- critical : true ,
163- extensionValue : new BasicConstraints ( cA : true ) ) ;
164- generator . AddExtension (
165- X509Extensions . KeyUsage ,
166- critical : true ,
167- extensionValue : new KeyUsage ( KeyUsage . DigitalSignature | KeyUsage . KeyCertSign | KeyUsage . CrlSign ) ) ;
168- generator . AddSigningEku ( ) ;
151+ certificateRequest . CertificateExtensions . Add (
152+ new X509SubjectKeyIdentifierExtension ( certificateRequest . PublicKey , critical : false ) ) ;
153+ certificateRequest . CertificateExtensions . Add (
154+ new X509BasicConstraintsExtension ( certificateAuthority : true , hasPathLengthConstraint : false , pathLengthConstraint : 0 , critical : true ) ) ;
155+ certificateRequest . CertificateExtensions . Add (
156+ new X509KeyUsageExtension ( X509KeyUsageFlags . DigitalSignature | X509KeyUsageFlags . KeyCertSign | X509KeyUsageFlags . CrlSign , critical : true ) ) ;
157+ certificateRequest . AddSigningEku ( ) ;
169158 } ;
170159
171160 var testServer = await GetTestServerAsync ( ) ;
172161 var rootCa = CertificateAuthority . Create ( testServer . Url , options ) ;
173162
174- var certificate = rootCa . Certificate . ToX509Certificate2 ( ) ;
175-
176- certificate . PrivateKey = DotNetUtilities . ToRSA ( options . KeyPair . Private as RsaPrivateCrtKeyParameters ) ;
177-
178- return certificate ;
163+ return rootCa . Certificate ;
179164 }
180165
181166 public async Task < RevokableCertificate > CreateRevokableSigningCertificateAsync ( )
182167 {
183168 var ca = await GetCertificateAuthorityAsync ( ) ;
184169
185- void CustomizeAsSigningCertificate ( X509V3CertificateGenerator generator )
170+ void CustomizeAsSigningCertificate ( CertificateRequest certificateRequest )
186171 {
187- generator . AddSigningEku ( ) ;
188- generator . AddAuthorityInfoAccess ( ca , addOcsp : true , addCAIssuers : true ) ;
172+ certificateRequest . AddSigningEku ( ) ;
173+ certificateRequest . AddAuthorityInfoAccess ( ca , addOcsp : true , addCAIssuers : true ) ;
189174 }
190175
191176 var issued = IssueCertificate ( ca , "Revoked Signing" , CustomizeAsSigningCertificate ) ;
192177 var revocationDate = DateTimeOffset . UtcNow . Subtract ( TimeSpan . FromHours ( 1 ) ) ;
193178
194179 void Revoke ( )
195180 {
196- ca . Revoke ( issued . publicCertificate , RevocationReason . Unspecified , revocationDate ) ;
181+ ca . Revoke ( issued . publicCertificate , X509RevocationReason . Unspecified , revocationDate ) ;
197182 }
198183
199184 Task WaitForResponseExpirationAsync ( )
@@ -211,7 +196,7 @@ public async Task<UntrustedSigningCertificate> CreateUntrustedSigningCertificate
211196 {
212197 var testServer = await GetTestServerAsync ( ) ;
213198 var untrustedRootCa = CertificateAuthority . Create ( testServer . Url ) ;
214- var untrustedRootCertificate = untrustedRootCa . Certificate . ToX509Certificate2 ( ) ;
199+ var untrustedRootCertificate = new X509Certificate2 ( untrustedRootCa . Certificate ) ;
215200 var responders = testServer . RegisterRespondersForEntireChain ( untrustedRootCa ) ;
216201
217202 var certificate = CreateSigningCertificate ( untrustedRootCa ) ;
@@ -225,16 +210,16 @@ public async Task<X509Certificate2> CreateExpiringSigningCertificateAsync()
225210 {
226211 var ca = await GetCertificateAuthorityAsync ( ) ;
227212
228- void CustomizeExpiringSigningCertificate ( X509V3CertificateGenerator generator )
213+ void CustomizeExpiringSigningCertificate ( CertificateRequest certificateRequest )
229214 {
230- generator . AddSigningEku ( ) ;
231- generator . AddAuthorityInfoAccess ( ca , addOcsp : true , addCAIssuers : true ) ;
232-
233- generator . SetNotBefore ( DateTime . UtcNow . AddSeconds ( - 2 ) ) ;
234- generator . SetNotAfter ( DateTime . UtcNow . AddSeconds ( 10 ) ) ;
215+ certificateRequest . AddSigningEku ( ) ;
216+ certificateRequest . AddAuthorityInfoAccess ( ca , addOcsp : true , addCAIssuers : true ) ;
235217 }
236218
237- var ( @public , certificate ) = IssueCertificate ( ca , "Expired Signing" , CustomizeExpiringSigningCertificate ) ;
219+ DateTimeOffset notBefore = DateTimeOffset . UtcNow . AddSeconds ( - 2 ) ;
220+ DateTimeOffset notAfter = DateTimeOffset . UtcNow . AddSeconds ( 10 ) ;
221+
222+ var ( @public , certificate ) = IssueCertificate ( ca , "Expired Signing" , CustomizeExpiringSigningCertificate , notBefore , notAfter ) ;
238223
239224 return certificate ;
240225 }
@@ -255,7 +240,7 @@ public async Task<UntrustedTimestampService> CreateUntrustedTimestampServiceAsyn
255240 {
256241 var testServer = await GetTestServerAsync ( ) ;
257242 var untrustedRootCa = CertificateAuthority . Create ( testServer . Url ) ;
258- var untrustedRootCertificate = untrustedRootCa . Certificate . ToX509Certificate2 ( ) ;
243+ var untrustedRootCertificate = new X509Certificate2 ( untrustedRootCa . Certificate ) ;
259244 var timestampService = TimestampService . Create ( untrustedRootCa ) ;
260245 var responders = testServer . RegisterDefaultResponders ( timestampService ) ;
261246
@@ -276,7 +261,7 @@ public async Task<RevokableTimestampService> CreateRevokableTimestampServiceAsyn
276261
277262 void Revoke ( )
278263 {
279- rootCa . Revoke ( timestampService . Certificate , RevocationReason . Unspecified , revocationDate ) ;
264+ rootCa . Revoke ( timestampService . Certificate , X509RevocationReason . Unspecified , revocationDate ) ;
280265 }
281266
282267 Task WaitForResponseExpirationAsync ( )
@@ -304,10 +289,10 @@ IDisposable AddOcspResponder()
304289 return testServer . RegisterResponder ( intermediateCa . OcspResponder ) ;
305290 }
306291
307- void CustomizeAsSigningCertificate ( X509V3CertificateGenerator generator )
292+ void CustomizeAsSigningCertificate ( CertificateRequest certificateRequest )
308293 {
309- generator . AddSigningEku ( ) ;
310- generator . AddAuthorityInfoAccess ( intermediateCa , addOcsp : true , addCAIssuers : true ) ;
294+ certificateRequest . AddSigningEku ( ) ;
295+ certificateRequest . AddAuthorityInfoAccess ( intermediateCa , addOcsp : true , addCAIssuers : true ) ;
311296 }
312297
313298 var issued = IssueCertificate ( intermediateCa , "Signing Certificate With Unavailable Revocation" , CustomizeAsSigningCertificate ) ;
@@ -328,7 +313,7 @@ public async Task<TimestampServiceWithUnavailableRevocation> CreateTimestampServ
328313 {
329314 var testServer = await GetTestServerAsync ( ) ;
330315 var rootCa = CertificateAuthority . Create ( testServer . Url ) ;
331- var rootCertificate = rootCa . Certificate . ToX509Certificate2 ( ) ;
316+ var rootCertificate = new X509Certificate2 ( rootCa . Certificate ) ;
332317
333318 var trust = new TrustedTestCert < X509Certificate2 > (
334319 rootCertificate ,
@@ -356,27 +341,31 @@ Task WaitForResponseExpirationAsync()
356341 disposable ) ;
357342 }
358343
359- protected ( BCCertificate publicCertificate , X509Certificate2 certificate ) IssueCertificate (
344+ protected ( X509Certificate2 publicCertificate , X509Certificate2 certificate ) IssueCertificate (
360345 CertificateAuthority ca ,
361346 string name ,
362- Action < X509V3CertificateGenerator > customizeCertificate )
347+ Action < CertificateRequest > customizeCertificate ,
348+ DateTimeOffset ? notBefore = null ,
349+ DateTimeOffset ? notAfter = null )
363350 {
364- var keyPair = SigningTestUtility . GenerateKeyPair ( publicKeyLength : 2048 ) ;
365-
366- var publicCertificate = ca . IssueCertificate ( new IssueCertificateOptions
351+ using ( RSA keyPair = SigningTestUtility . GenerateKeyPair ( publicKeyLength : 2048 ) )
367352 {
368- CustomizeCertificate = customizeCertificate ,
369- NotAfter = DateTime . UtcNow . AddMinutes ( 10 ) ,
370- NotBefore = DateTime . UtcNow . AddSeconds ( - 10 ) ,
371- KeyPair = keyPair ,
353+ notBefore ??= DateTimeOffset . UtcNow . AddSeconds ( - 10 ) ;
354+ notAfter ??= DateTimeOffset . UtcNow . AddMinutes ( 10 ) ;
372355
373- SubjectName = new X509Name ( $ "C=US,ST=WA,L=Redmond,O=NuGet,CN=NuGet Test ${ name } Certificate ({ Guid . NewGuid ( ) } )")
374- } ) ;
356+ X509Certificate2 certificate = ca . IssueCertificate ( new IssueCertificateOptions
357+ {
358+ CustomizeCertificate = customizeCertificate ,
359+ NotAfter = notAfter . Value ,
360+ NotBefore = notBefore . Value ,
361+ KeyPair = keyPair ,
362+ SubjectName = new X500DistinguishedName ( $ "C=US,ST=WA,L=Redmond,O=NuGet,CN=NuGet Test ${ name } Certificate ({ Guid . NewGuid ( ) } )")
363+ } ) ;
375364
376- var certificate = publicCertificate . ToX509Certificate2 ( ) ;
377- certificate . PrivateKey = DotNetUtilities . ToRSA ( keyPair . Private as RsaPrivateCrtKeyParameters ) ;
365+ X509Certificate2 publicCertificate = new ( certificate . RawData ) ;
378366
379- return ( publicCertificate , certificate ) ;
367+ return ( publicCertificate , certificate ) ;
368+ }
380369 }
381370
382371 private async Task < string > GetDefaultTrustedSigningCertificateThumbprintAsync ( )
0 commit comments