Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Sources/X509/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ add_library(X509
"Verifier/PolicyBuilder.swift"
"Verifier/RFC5280/BasicConstraintsPolicy.swift"
"Verifier/RFC5280/DNSNames.swift"
"Verifier/RFC5280/DirectoryNames.swift"
"Verifier/RFC5280/ExpiryPolicy.swift"
"Verifier/RFC5280/IPConstraints.swift"
"Verifier/RFC5280/NameConstraintsPolicy.swift"
Expand Down
27 changes: 0 additions & 27 deletions Sources/X509/Verifier/RFC5280/DirectoryNames.swift

This file was deleted.

30 changes: 13 additions & 17 deletions Sources/X509/Verifier/RFC5280/NameConstraintsPolicy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ struct NameConstraintsPolicy: VerifierPolicy, Sendable {
//
// Some notes:
//
// - RFC 5280 says we MUST validate directoryName constraints, and SHOULD validate rfc822Name,
// URI, dNSName, and iPAddress constraints.
// - RFC 5280 says we MUST validate directoryName constraints, and SHOULD validate rfc822Name, URI, dNSName, and
// iPAddress constraints. However, proper directoryName constraint validation requires a complex comparison
// algorithm. Most implementations skip that and just compare the distinguished names by exact equality. As
// such, we deliberately do not validate directoryName constraints at all: if a certificate's nameConstraints
// extension contains a directoryName subtree, we reject the chain.
// - If there's a constraint we don't support and can't validate, we MUST reject the cert.
//
// Our algorithm is recursive: starting from the root and moving towards the leaf, for each CA
Expand Down Expand Up @@ -114,13 +117,10 @@ struct NameConstraintsPolicy: VerifierPolicy, Sendable {
// For excluded trees, if _any_ match then the name is forbidden.
for excludedSubtree in excludedSubtrees {
switch (excludedSubtree, name) {
case (.directoryName(let constraint), .directoryName(let presentedName)):
if directoryNameMatchesConstraint(directoryName: presentedName, constraint: constraint) {
return .failsToMeetPolicy(
reason:
"RFC5280Policy: directoryName \(presentedName) is excluded by \(excludedSubtree) in name constraints"
)
}
case (.directoryName, .directoryName):
// We immediately reject the chain if there is a directoryName name constraint involved: correct
// validation requires the full RFC 5280 comparison algorithm which we currently do not implement.
return .failsToMeetPolicy(reason: "RFC5280Policy: directoryName name constraints are not supported.")
case (.dnsName(let constraint), .dnsName(let presentedName)):
if dnsNameMatchesConstraint(dnsName: presentedName.utf8, constraint: constraint.utf8) {
return .failsToMeetPolicy(
Expand Down Expand Up @@ -171,14 +171,10 @@ struct NameConstraintsPolicy: VerifierPolicy, Sendable {

for permittedSubtree in permittedSubtrees {
switch (permittedSubtree, name) {
case (.directoryName(let constraint), .directoryName(let presentedName)):
evaluatedAtLeastOneConstraint = true

if directoryNameMatchesConstraint(directoryName: presentedName, constraint: constraint) {
// This is a match, we're good.
return .meetsPolicy
}

case (.directoryName, .directoryName):
// We immediately reject the chain if there is a directoryName name constraint involved: correct
// validation requires the full RFC 5280 comparison algorithm which we currently do not implement.
return .failsToMeetPolicy(reason: "RFC5280Policy: directoryName name constraints are not supported.")
case (.dnsName(let constraint), .dnsName(let presentedName)):
evaluatedAtLeastOneConstraint = true

Expand Down
16 changes: 0 additions & 16 deletions Tests/X509Tests/NameConstraintsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,6 @@ final class NameConstraintsTests: XCTestCase {
},
]

func testDirectoryNameMatches() throws {
// The key here is that a distinguished name only matches a constraint if they're equal.
for firstName in NameConstraintsTests.names {
for secondName in NameConstraintsTests.names {
XCTAssertEqual(
NameConstraintsPolicy.directoryNameMatchesConstraint(
directoryName: firstName,
constraint: secondName
),
firstName == secondName,
"Expected directory name match to be \(firstName == secondName) for \(firstName) and \(secondName)"
)
}
}
}

func testLazyProperties() {
struct NameConstraintsPropertyValue {
var property: PartialKeyPath<NameConstraints>
Expand Down
Loading
Loading