Skip to content

Commit 311730d

Browse files
committed
Rework disabling of expiry check
1 parent cd61907 commit 311730d

File tree

2 files changed

+41
-44
lines changed

2 files changed

+41
-44
lines changed

Package.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,8 @@ if ProcessInfo.processInfo.environment["SWIFTCI_USE_LOCAL_DEPS"] == nil {
724724
.package(url: "https://github.com/apple/swift-crypto.git", .upToNextMinor(from: "2.4.0")),
725725
.package(url: "https://github.com/apple/swift-system.git", .upToNextMinor(from: "1.1.1")),
726726
.package(url: "https://github.com/apple/swift-collections.git", .upToNextMinor(from: "1.0.1")),
727-
.package(url: "https://github.com/apple/swift-certificates.git", .upToNextMinor(from: "0.2.0")),
727+
// .package(url: "https://github.com/apple/swift-certificates.git", .upToNextMinor(from: "0.2.0")),
728+
.package(url: "https://github.com/apple/swift-certificates.git", branch: "main"),
728729
]
729730
} else {
730731
package.dependencies += [

Sources/PackageSigning/VerifierPolicies.swift

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import struct Foundation.URL
1717

1818
import Basics
1919
@_implementationOnly import SwiftASN1
20-
@_implementationOnly import X509
20+
@_implementationOnly @_spi(DisableValidityCheck) import X509
2121

2222
extension SignatureProviderProtocol {
2323
func buildPolicySet(configuration: VerifierConfiguration, httpClient: HTTPClient) -> PolicySet {
@@ -26,25 +26,47 @@ extension SignatureProviderProtocol {
2626
_ADPCertificatePolicy(),
2727
]
2828

29-
switch configuration.certificateExpiration {
30-
case .enabled(let validationTime):
31-
policies.append(_RFC5280Policy(validationTime: validationTime, enableExpiryCheck: true))
32-
case .disabled:
33-
policies.append(_RFC5280Policy(validationTime: .none, enableExpiryCheck: false))
34-
}
35-
36-
switch configuration.certificateRevocation {
37-
case .strict(let validationTime):
38-
policies.append(_OCSPVerifierPolicy(httpClient: httpClient, mode: .strict, validationTime: validationTime))
39-
case .allowSoftFail(let validationTime):
29+
let now = Date()
30+
switch (configuration.certificateExpiration, configuration.certificateRevocation) {
31+
case (.enabled(let expiryValidationTime), .strict(let revocationValidationTime)):
32+
policies.append(RFC5280Policy(validationTime: expiryValidationTime ?? now))
33+
policies
34+
.append(_OCSPVerifierPolicy(
35+
httpClient: httpClient,
36+
mode: .strict,
37+
validationTime: revocationValidationTime ?? now
38+
))
39+
case (.enabled(let expiryValidationTime), .allowSoftFail(let revocationValidationTime)):
40+
policies.append(RFC5280Policy(validationTime: expiryValidationTime ?? now))
4041
policies
4142
.append(_OCSPVerifierPolicy(
4243
httpClient: httpClient,
4344
mode: .allowSoftFail,
44-
validationTime: validationTime
45+
validationTime: revocationValidationTime ?? now
4546
))
46-
case .disabled:
47-
()
47+
case (.enabled(let expiryValidationTime), .disabled):
48+
policies.append(RFC5280Policy(validationTime: expiryValidationTime ?? now))
49+
case (.disabled, .strict(let revocationValidationTime)):
50+
// Always do expiry check (and before) if revocation check is enabled
51+
policies.append(RFC5280Policy(validationTime: revocationValidationTime ?? now))
52+
policies
53+
.append(_OCSPVerifierPolicy(
54+
httpClient: httpClient,
55+
mode: .strict,
56+
validationTime: revocationValidationTime ?? now
57+
))
58+
case (.disabled, .allowSoftFail(let revocationValidationTime)):
59+
// Always do expiry check (and before) if revocation check is enabled
60+
policies.append(RFC5280Policy(validationTime: revocationValidationTime ?? now))
61+
policies
62+
.append(_OCSPVerifierPolicy(
63+
httpClient: httpClient,
64+
mode: .allowSoftFail,
65+
validationTime: revocationValidationTime ?? now
66+
))
67+
case (.disabled, .disabled):
68+
// We should still do basic certificate validations even if expiry check is disabled
69+
policies.append(RFC5280Policy.withValidityCheckDisabled())
4870
}
4971

5072
return PolicySet(policies: policies)
@@ -97,32 +119,6 @@ struct _ADPCertificatePolicy: VerifierPolicy {
97119
}
98120
}
99121

100-
struct _RFC5280Policy: VerifierPolicy {
101-
/// See RFC5280Policy
102-
public let verifyingCriticalExtensions: [ASN1ObjectIdentifier] = [
103-
.X509ExtensionID.basicConstraints,
104-
.X509ExtensionID.nameConstraints,
105-
.X509ExtensionID.keyUsage,
106-
]
107-
108-
let validationTime: Date?
109-
let enableExpiryCheck: Bool
110-
111-
func chainMeetsPolicyRequirements(chain: UnverifiedCertificateChain) async -> PolicyEvaluationResult {
112-
let policy: RFC5280Policy
113-
if self.enableExpiryCheck {
114-
policy = RFC5280Policy(validationTime: self.validationTime ?? Date())
115-
} else {
116-
// Use leaf.notValidBefore as validationTime to ensure the leaf
117-
// will pass expiry check. This should work for the chain if the
118-
// chain follows validity nesting, but if a parent expires before
119-
// a child does then the expiry check will fail.
120-
policy = RFC5280Policy(validationTime: chain.leaf.notValidBefore)
121-
}
122-
return policy.chainMeetsPolicyRequirements(chain: chain)
123-
}
124-
}
125-
126122
struct _OCSPVerifierPolicy: VerifierPolicy {
127123
private static let cacheTTL: DispatchTimeInterval = .seconds(5 * 60)
128124
private let cache = ThreadSafeKeyValueStore<
@@ -135,10 +131,10 @@ struct _OCSPVerifierPolicy: VerifierPolicy {
135131

136132
let verifyingCriticalExtensions: [ASN1ObjectIdentifier] = []
137133

138-
init(httpClient: HTTPClient, mode: Mode, validationTime: Date?) {
134+
init(httpClient: HTTPClient, mode: Mode, validationTime: Date) {
139135
self.underlying = OCSPVerifierPolicy(
140136
requester: _OCSPRequester(httpClient: httpClient),
141-
validationTime: validationTime ?? Date()
137+
validationTime: validationTime
142138
)
143139
self.mode = mode
144140
}

0 commit comments

Comments
 (0)