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 . Collections . Generic ;
56using System . Security . Cryptography . X509Certificates ;
67using System . Security . Principal ;
78using System . Threading . Tasks ;
89using Org . BouncyCastle . Asn1 ;
910using Org . BouncyCastle . Asn1 . X509 ;
1011using Org . BouncyCastle . Crypto . Parameters ;
1112using Org . BouncyCastle . Security ;
13+ using Org . BouncyCastle . X509 ;
1214using Test . Utility . Signing ;
1315using Xunit ;
1416using GeneralName = Org . BouncyCastle . Asn1 . X509 . GeneralName ;
17+ using BCCertificate = Org . BouncyCastle . X509 . X509Certificate ;
1518
1619namespace Validation . PackageSigning . Core . Tests . Support
1720{
@@ -22,6 +25,7 @@ namespace Validation.PackageSigning.Core.Tests.Support
2225 public class CertificateIntegrationTestFixture : IDisposable
2326 {
2427 private readonly Lazy < Task < SigningTestServer > > _testServer ;
28+ private readonly Lazy < Task < CertificateAuthority > > _rootCertificateAuthority ;
2529 private readonly Lazy < Task < CertificateAuthority > > _certificateAuthority ;
2630 private readonly Lazy < Task < TimestampService > > _timestampService ;
2731 private readonly Lazy < Task < Uri > > _timestampServiceUrl ;
@@ -37,6 +41,7 @@ public CertificateIntegrationTestFixture()
3741 "This test must be executing with administrator privileges since it installs a trusted root." ) ;
3842
3943 _testServer = new Lazy < Task < SigningTestServer > > ( SigningTestServer . CreateAsync ) ;
44+ _rootCertificateAuthority = new Lazy < Task < CertificateAuthority > > ( CreateDefaultTrustedRootCertificateAuthorityAsync ) ;
4045 _certificateAuthority = new Lazy < Task < CertificateAuthority > > ( CreateDefaultTrustedCertificateAuthorityAsync ) ;
4146 _timestampService = new Lazy < Task < TimestampService > > ( CreateDefaultTrustedTimestampServiceAsync ) ;
4247 _timestampServiceUrl = new Lazy < Task < Uri > > ( CreateDefaultTrustedTimestampServiceUrlAsync ) ;
@@ -50,6 +55,10 @@ public CertificateIntegrationTestFixture()
5055 public Task < X509Certificate2 > GetSigningCertificateAsync ( ) => _signingCertificate . Value ;
5156 public Task < string > GetSigningCertificateThumbprintAsync ( ) => _signingCertificateThumbprint . Value ;
5257
58+ protected Task < CertificateAuthority > GetRootCertificateAuthority ( ) => _rootCertificateAuthority . Value ;
59+ protected Task < CertificateAuthority > GetCertificateAuthority ( ) => _certificateAuthority . Value ;
60+ protected DisposableList GetResponders ( ) => _responders ;
61+
5362 public void Dispose ( )
5463 {
5564 _trustedRoot ? . Dispose ( ) ;
@@ -61,11 +70,10 @@ public void Dispose()
6170 }
6271 }
6372
64- private async Task < CertificateAuthority > CreateDefaultTrustedCertificateAuthorityAsync ( )
73+ private async Task < CertificateAuthority > CreateDefaultTrustedRootCertificateAuthorityAsync ( )
6574 {
6675 var testServer = await GetTestServerAsync ( ) ;
6776 var rootCa = CertificateAuthority . Create ( testServer . Url ) ;
68- var intermediateCa = rootCa . CreateIntermediateCertificateAuthority ( ) ;
6977 var rootCertificate = new X509Certificate2 ( rootCa . Certificate . GetEncoded ( ) ) ;
7078
7179 _trustedRoot = new TrustedTestCert < X509Certificate2 > (
@@ -74,6 +82,15 @@ private async Task<CertificateAuthority> CreateDefaultTrustedCertificateAuthorit
7482 StoreName . Root ,
7583 StoreLocation . LocalMachine ) ;
7684
85+ return rootCa ;
86+ }
87+
88+ private async Task < CertificateAuthority > CreateDefaultTrustedCertificateAuthorityAsync ( )
89+ {
90+ var testServer = await GetTestServerAsync ( ) ;
91+ var rootCa = await GetRootCertificateAuthority ( ) ;
92+ var intermediateCa = rootCa . CreateIntermediateCertificateAuthority ( ) ;
93+
7794 _responders . AddRange ( testServer . RegisterResponders ( intermediateCa ) ) ;
7895
7996 return intermediateCa ;
@@ -103,30 +120,32 @@ private async Task<X509Certificate2> CreateDefaultTrustedSigningCertificateAsync
103120 }
104121
105122 public X509Certificate2 CreateSigningCertificate ( CertificateAuthority ca )
123+ {
124+ void CustomizeAsSigningCertificate ( X509V3CertificateGenerator generator )
125+ {
126+ generator . AddSigningEku ( ) ;
127+ generator . AddAuthorityInfoAccess ( ca , addOcsp : true , addCAIssuers : true ) ;
128+ }
129+
130+ return IssueCertificate ( ca , "Signing" , CustomizeAsSigningCertificate ) . certificate ;
131+ }
132+
133+ protected ( BCCertificate publicCertificate , X509Certificate2 certificate ) IssueCertificate (
134+ CertificateAuthority ca ,
135+ string name ,
136+ Action < X509V3CertificateGenerator > customizeCertificate )
106137 {
107138 var keyPair = SigningTestUtility . GenerateKeyPair ( publicKeyLength : 2048 ) ;
108139 var publicCertificate = ca . IssueCertificate (
109140 keyPair . Public ,
110- new X509Name ( $ "C=US,ST=WA,L=Redmond,O=NuGet,CN=NuGet Test Signing Certificate ({ Guid . NewGuid ( ) } )") ,
111- generator =>
112- {
113- SigningTestUtility . CertificateModificationGeneratorForCodeSigningEkuCert ( generator ) ;
114-
115- generator . AddExtension (
116- X509Extensions . AuthorityInfoAccess ,
117- critical : false ,
118- extensionValue : new DerSequence (
119- new AccessDescription ( AccessDescription . IdADOcsp ,
120- new GeneralName ( GeneralName . UniformResourceIdentifier , ca . OcspResponderUri . OriginalString ) ) ,
121- new AccessDescription ( AccessDescription . IdADCAIssuers ,
122- new GeneralName ( GeneralName . UniformResourceIdentifier , ca . CertificateUri . OriginalString ) ) ) ) ;
123- } ,
141+ new X509Name ( $ "C=US,ST=WA,L=Redmond,O=NuGet,CN=NuGet Test ${ name } Certificate ({ Guid . NewGuid ( ) } )") ,
142+ customizeCertificate ,
124143 notBefore : DateTime . UtcNow . AddSeconds ( - 10 ) ) ;
125144
126145 var certificate = new X509Certificate2 ( publicCertificate . GetEncoded ( ) ) ;
127146 certificate . PrivateKey = DotNetUtilities . ToRSA ( keyPair . Private as RsaPrivateCrtKeyParameters ) ;
128147
129- return certificate ;
148+ return ( publicCertificate , certificate ) ;
130149 }
131150
132151 private async Task < string > GetDefaultTrustedSigningCertificateThumbprintAsync ( )
0 commit comments