Skip to content

Commit b81417c

Browse files
dnadobayim-lee
authored andcommitted
Adopt swift-certificates 0.6.0
1 parent 0d43a5e commit b81417c

File tree

6 files changed

+112
-130
lines changed

6 files changed

+112
-130
lines changed

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
726726
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMinor(from: "2.5.0")),
727727
.package(url: "https://github.com/apple/swift-system.git", .upToNextMinor(from: "1.1.1")),
728728
.package(url: "https://github.com/apple/swift-collections.git", .upToNextMinor(from: "1.0.1")),
729-
.package(url: "https://github.com/apple/swift-certificates.git", .upToNextMinor(from: "0.4.1")),
729+
.package(url: "https://github.com/apple/swift-certificates.git", .upToNextMinor(from: "0.6.0")),
730730
]
731731
} else {
732732
package.dependencies += [

Sources/PackageCollectionsSigning/CertificatePolicy.swift

Lines changed: 60 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ extension CertificatePolicy {
7777
func verify(
7878
certChain: [Certificate],
7979
trustedRoots: [Certificate]?,
80-
policies: [VerifierPolicy],
80+
@PolicyBuilder policies: () -> some VerifierPolicy,
8181
observabilityScope: ObservabilityScope,
8282
callbackQueue: DispatchQueue,
8383
callback: @escaping (Result<Void, Error>) -> Void
@@ -87,7 +87,7 @@ extension CertificatePolicy {
8787
guard !certChain.isEmpty else {
8888
return wrappedCallback(.failure(CertificatePolicyError.emptyCertChain))
8989
}
90-
90+
let policies = policies()
9191
Task {
9292
var trustStore = CertificateStores.defaultTrustRoots
9393
if let trustedRoots {
@@ -98,9 +98,9 @@ extension CertificatePolicy {
9898
return wrappedCallback(.failure(CertificatePolicyError.noTrustedRootCertsConfigured))
9999
}
100100

101-
let policySet = PolicySet(policies: policies)
102-
103-
var verifier = Verifier(rootCertificates: CertificateStore(trustStore), policy: policySet)
101+
var verifier = Verifier(rootCertificates: CertificateStore(trustStore)) {
102+
policies
103+
}
104104
let result = await verifier.validate(
105105
leafCertificate: certChain[0],
106106
intermediates: CertificateStore(certChain)
@@ -182,31 +182,26 @@ struct DefaultCertificatePolicy: CertificatePolicy {
182182
return wrappedCallback(.failure(CertificatePolicyError.emptyCertChain))
183183
}
184184

185-
var policies = [VerifierPolicy]()
186-
policies.append(_ADPCertificatePolicy()) // included for testing
187-
// Check if subject name matches
188-
policies.append(
189-
_SubjectNamePolicy(
190-
expectedUserID: self.expectedSubjectUserID,
191-
expectedOrganizationalUnit: self.expectedSubjectOrganizationalUnit
192-
)
193-
)
194-
// Must be a code signing certificate
195-
policies.append(_CodeSigningPolicy())
196-
// Basic validations including expiry check
197-
policies.append(RFC5280Policy(validationTime: validationTime))
198-
// Must support OCSP
199-
policies.append(
200-
_OCSPVerifierPolicy(
201-
httpClient: self.httpClient,
202-
validationTime: validationTime
203-
)
204-
)
205-
206185
self.verify(
207186
certChain: certChain,
208187
trustedRoots: self.trustedRoots,
209-
policies: policies,
188+
policies: {
189+
_ADPCertificatePolicy() // included for testing
190+
// Check if subject name matches
191+
_SubjectNamePolicy(
192+
expectedUserID: self.expectedSubjectUserID,
193+
expectedOrganizationalUnit: self.expectedSubjectOrganizationalUnit
194+
)
195+
// Must be a code signing certificate
196+
_CodeSigningPolicy()
197+
// Basic validations including expiry check
198+
RFC5280Policy(validationTime: validationTime)
199+
// Must support OCSP
200+
_OCSPVerifierPolicy(
201+
httpClient: self.httpClient,
202+
validationTime: validationTime
203+
)
204+
},
210205
observabilityScope: self.observabilityScope,
211206
callbackQueue: self.callbackQueue,
212207
callback: callback
@@ -269,33 +264,28 @@ struct ADPSwiftPackageCollectionCertificatePolicy: CertificatePolicy {
269264
return wrappedCallback(.failure(CertificatePolicyError.emptyCertChain))
270265
}
271266

272-
var policies = [VerifierPolicy]()
273-
// Check for specific markers
274-
policies.append(_ADPSwiftPackageCertificatePolicy())
275-
policies.append(_ADPCertificatePolicy()) // included for testing
276-
// Check if subject name matches
277-
policies.append(
278-
_SubjectNamePolicy(
279-
expectedUserID: self.expectedSubjectUserID,
280-
expectedOrganizationalUnit: self.expectedSubjectOrganizationalUnit
281-
)
282-
)
283-
// Must be a code signing certificate
284-
policies.append(_CodeSigningPolicy())
285-
// Basic validations including expiry check
286-
policies.append(RFC5280Policy(validationTime: validationTime))
287-
// Must support OCSP
288-
policies.append(
289-
_OCSPVerifierPolicy(
290-
httpClient: self.httpClient,
291-
validationTime: validationTime
292-
)
293-
)
294-
295267
self.verify(
296268
certChain: certChain,
297269
trustedRoots: self.trustedRoots,
298-
policies: policies,
270+
policies: {
271+
// Check for specific markers
272+
_ADPSwiftPackageCertificatePolicy()
273+
_ADPCertificatePolicy() // included for testing
274+
// Check if subject name matches
275+
_SubjectNamePolicy(
276+
expectedUserID: self.expectedSubjectUserID,
277+
expectedOrganizationalUnit: self.expectedSubjectOrganizationalUnit
278+
)
279+
// Must be a code signing certificate
280+
_CodeSigningPolicy()
281+
// Basic validations including expiry check
282+
RFC5280Policy(validationTime: validationTime)
283+
// Must support OCSP
284+
_OCSPVerifierPolicy(
285+
httpClient: self.httpClient,
286+
validationTime: validationTime
287+
)
288+
},
299289
observabilityScope: self.observabilityScope,
300290
callbackQueue: self.callbackQueue,
301291
callback: callback
@@ -358,33 +348,28 @@ struct ADPAppleDistributionCertificatePolicy: CertificatePolicy {
358348
return wrappedCallback(.failure(CertificatePolicyError.emptyCertChain))
359349
}
360350

361-
var policies = [VerifierPolicy]()
362-
// Check for specific markers
363-
policies.append(_ADPAppleDistributionCertificatePolicy())
364-
policies.append(_ADPCertificatePolicy()) // included for testing
365-
// Check if subject name matches
366-
policies.append(
367-
_SubjectNamePolicy(
368-
expectedUserID: self.expectedSubjectUserID,
369-
expectedOrganizationalUnit: self.expectedSubjectOrganizationalUnit
370-
)
371-
)
372-
// Must be a code signing certificate
373-
policies.append(_CodeSigningPolicy())
374-
// Basic validations including expiry check
375-
policies.append(RFC5280Policy(validationTime: validationTime))
376-
// Must support OCSP
377-
policies.append(
378-
_OCSPVerifierPolicy(
379-
httpClient: self.httpClient,
380-
validationTime: validationTime
381-
)
382-
)
383-
384351
self.verify(
385352
certChain: certChain,
386353
trustedRoots: self.trustedRoots,
387-
policies: policies,
354+
policies: {
355+
// Check for specific markers
356+
_ADPAppleDistributionCertificatePolicy()
357+
_ADPCertificatePolicy() // included for testing
358+
// Check if subject name matches
359+
_SubjectNamePolicy(
360+
expectedUserID: self.expectedSubjectUserID,
361+
expectedOrganizationalUnit: self.expectedSubjectOrganizationalUnit
362+
)
363+
// Must be a code signing certificate
364+
_CodeSigningPolicy()
365+
// Basic validations including expiry check
366+
RFC5280Policy(validationTime: validationTime)
367+
// Must support OCSP
368+
_OCSPVerifierPolicy(
369+
httpClient: self.httpClient,
370+
validationTime: validationTime
371+
)
372+
},
388373
observabilityScope: self.observabilityScope,
389374
callbackQueue: self.callbackQueue,
390375
callback: callback

Sources/PackageSigning/SignatureProvider.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,11 @@ struct CMSSignatureProvider: SignatureProviderProtocol {
280280
// the WWDR roots are in the trust store or not, which by default
281281
// they are but user may disable that through configuration.
282282
additionalIntermediateCertificates: Certificates.wwdrIntermediates,
283-
trustRoots: CertificateStore(trustRoots),
284-
policy: self.buildPolicySet(configuration: verifierConfiguration, httpClient: self.httpClient)
285-
)
283+
trustRoots: CertificateStore(trustRoots)
284+
) {
285+
self.buildPolicySet(configuration: verifierConfiguration, httpClient: self.httpClient)
286+
}
287+
286288

287289
switch result {
288290
case .success(let valid):
@@ -341,9 +343,9 @@ struct CMSSignatureProvider: SignatureProviderProtocol {
341343
// For self-signed certificate, the signature should include intermediate(s).
342344
untrustedIntermediates.append(contentsOf: cmsSignature.certificates)
343345

344-
let policySet = self.buildPolicySet(configuration: verifierConfiguration, httpClient: self.httpClient)
345-
346-
var verifier = Verifier(rootCertificates: CertificateStore(trustRoots), policy: policySet)
346+
var verifier = Verifier(rootCertificates: CertificateStore(trustRoots)) {
347+
self.buildPolicySet(configuration: verifierConfiguration, httpClient: self.httpClient)
348+
}
347349
let result = await verifier.validate(
348350
leafCertificate: signingCertificate,
349351
intermediates: CertificateStore(untrustedIntermediates)

Sources/PackageSigning/VerifierPolicies.swift

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,56 +20,49 @@ import Basics
2020
@_implementationOnly @_spi(DisableValidityCheck) import X509
2121

2222
extension SignatureProviderProtocol {
23-
func buildPolicySet(configuration: VerifierConfiguration, httpClient: HTTPClient) -> PolicySet {
24-
var policies: [VerifierPolicy] = [
25-
_CodeSigningPolicy(),
26-
_ADPCertificatePolicy(),
27-
]
28-
23+
@PolicyBuilder
24+
func buildPolicySet(configuration: VerifierConfiguration, httpClient: HTTPClient) -> some VerifierPolicy {
25+
_CodeSigningPolicy()
26+
_ADPCertificatePolicy()
27+
2928
let now = Date()
3029
switch (configuration.certificateExpiration, configuration.certificateRevocation) {
3130
case (.enabled(let expiryValidationTime), .strict(let revocationValidationTime)):
32-
policies.append(RFC5280Policy(validationTime: expiryValidationTime ?? now))
33-
policies
34-
.append(_OCSPVerifierPolicy(
35-
failureMode: .hard,
36-
httpClient: httpClient,
37-
validationTime: revocationValidationTime ?? now
38-
))
31+
RFC5280Policy(validationTime: expiryValidationTime ?? now)
32+
_OCSPVerifierPolicy(
33+
failureMode: .hard,
34+
httpClient: httpClient,
35+
validationTime: revocationValidationTime ?? now
36+
)
3937
case (.enabled(let expiryValidationTime), .allowSoftFail(let revocationValidationTime)):
40-
policies.append(RFC5280Policy(validationTime: expiryValidationTime ?? now))
41-
policies
42-
.append(_OCSPVerifierPolicy(
43-
failureMode: .soft,
44-
httpClient: httpClient,
45-
validationTime: revocationValidationTime ?? now
46-
))
38+
RFC5280Policy(validationTime: expiryValidationTime ?? now)
39+
_OCSPVerifierPolicy(
40+
failureMode: .soft,
41+
httpClient: httpClient,
42+
validationTime: revocationValidationTime ?? now
43+
)
4744
case (.enabled(let expiryValidationTime), .disabled):
48-
policies.append(RFC5280Policy(validationTime: expiryValidationTime ?? now))
45+
RFC5280Policy(validationTime: expiryValidationTime ?? now)
4946
case (.disabled, .strict(let revocationValidationTime)):
5047
// Always do expiry check (and before) if revocation check is enabled
51-
policies.append(RFC5280Policy(validationTime: revocationValidationTime ?? now))
52-
policies
53-
.append(_OCSPVerifierPolicy(
54-
failureMode: .hard,
55-
httpClient: httpClient,
56-
validationTime: revocationValidationTime ?? now
57-
))
48+
RFC5280Policy(validationTime: revocationValidationTime ?? now)
49+
_OCSPVerifierPolicy(
50+
failureMode: .hard,
51+
httpClient: httpClient,
52+
validationTime: revocationValidationTime ?? now
53+
)
5854
case (.disabled, .allowSoftFail(let revocationValidationTime)):
5955
// Always do expiry check (and before) if revocation check is enabled
60-
policies.append(RFC5280Policy(validationTime: revocationValidationTime ?? now))
61-
policies
62-
.append(_OCSPVerifierPolicy(
63-
failureMode: .soft,
64-
httpClient: httpClient,
65-
validationTime: revocationValidationTime ?? now
66-
))
56+
RFC5280Policy(validationTime: revocationValidationTime ?? now)
57+
_OCSPVerifierPolicy(
58+
failureMode: .soft,
59+
httpClient: httpClient,
60+
validationTime: revocationValidationTime ?? now
61+
)
6762
case (.disabled, .disabled):
6863
// We should still do basic certificate validations even if expiry check is disabled
69-
policies.append(RFC5280Policy.withValidityCheckDisabled())
64+
RFC5280Policy.withValidityCheckDisabled()
7065
}
71-
72-
return PolicySet(policies: policies)
7366
}
7467
}
7568

Tests/PackageCollectionsSigningTests/Utilities.swift

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,16 @@ struct TestCertificatePolicy: CertificatePolicy {
5656
validationTime: Date,
5757
callback: @escaping (Result<Void, Error>) -> Void
5858
) {
59-
var policies = [VerifierPolicy]()
60-
// Must be a code signing certificate
61-
policies.append(_CodeSigningPolicy())
62-
// Basic validations including expiry check
63-
policies.append(RFC5280Policy(validationTime: validationTime))
64-
// Doesn't require OCSP
65-
6659
self.verify(
6760
certChain: certChain,
6861
trustedRoots: self.trustedRoots,
69-
policies: policies,
62+
policies: {
63+
// Must be a code signing certificate
64+
_CodeSigningPolicy()
65+
// Basic validations including expiry check
66+
RFC5280Policy(validationTime: validationTime)
67+
// Doesn't require OCSP
68+
},
7069
observabilityScope: ObservabilitySystem.NOOP,
7170
callbackQueue: callbackQueue,
7271
callback: callback

Tests/PackageSigningTests/SigningTests.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,15 +1241,18 @@ extension BasicOCSPResponse {
12411241
responses: [OCSPSingleResponse],
12421242
privateKey: P256.Signing.PrivateKey,
12431243
certs: [Certificate]? = [],
1244-
@ExtensionsBuilder responseExtensions: () -> Certificate.Extensions = { .init() }
1244+
@ExtensionsBuilder responseExtensions: () throws -> Result<Certificate.Extensions, any Error> = {
1245+
// workaround for rdar://108897294
1246+
Result.success(Certificate.Extensions())
1247+
}
12451248
) throws -> Self {
12461249
try .signed(
12471250
responseData: .init(
12481251
version: version,
12491252
responderID: responderID,
12501253
producedAt: producedAt,
12511254
responses: responses,
1252-
responseExtensions: responseExtensions()
1255+
responseExtensions: try .init(builder: responseExtensions)
12531256
),
12541257
privateKey: privateKey,
12551258
certs: certs

0 commit comments

Comments
 (0)