mackms: support subject DN components in certificate URIs#1073
Draft
joshdrake wants to merge 2 commits into
Draft
mackms: support subject DN components in certificate URIs#1073joshdrake wants to merge 2 commits into
joshdrake wants to merge 2 commits into
Conversation
Support selecting certificates in the Apple Keychain by subject distinguished name components using the new "cn", "o", "ou", "l", "st", and "c" URI attributes, e.g. "mackms:cn=My+Cert;ou=Engineering". The keychain cannot match individual subject components, and it stores normalized (partially uppercased) subject values, so the components are used to filter the parsed certificates after retrieving the candidates from the keychain. All the given components must match using exact, case-sensitive comparisons, and the multi-valued components can be repeated, requiring every value to be present in the subject. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P3Nxd2zBbULcRAG6HrzQgR
When subject components ("cn", "o", "ou", "l", "st", "c") are present in
the URI, find the matching certificate first, using the same selection
rules as LoadCertificate, and delete it by its serial number and, when
available, its subject key identifier.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P3Nxd2zBbULcRAG6HrzQgR
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds subject distinguished name components —
cn,o,ou,l,st,c— to the mackms certificate URI vocabulary, so certificates can be selected by subject inLoadCertificate,LoadCertificateChain, andDeleteCertificate:Constraint: subject matching happens in Go — we have to enumerate certificates
The Apple keychain cannot do this filtering for us:
kSecMatchSubjectContainsis a substring match over the whole subject and only works on legacy file-based keychains, not the data protection keychain.kSecAttrSubject/kSecAttrIssuerhold the entire name as an Apple-normalized (partially uppercased) DER blob. They are read-only, system-derived, exact-match columns, and there is no public API to produce the normalized bytes from user-supplied strings — theSecCertificateCopyNormalized*SequenceAPIs all require aSecCertificateRefin hand. The existing comment inLoadCertificateChainalready rejectscert.RawIssuer/RawSubjectmatching for this reason.So when a URI contains subject components, mackms fetches the candidates (
kSecMatchLimitAll), parses every candidate withx509.ParseCertificate, and matches the components againstcert.Subjectin Go.labeland/orserialin the same URI still narrow the keychain query natively first; a pure-DN query likemackms:ou=Engineeringenumerates and parses every certificate in the keychain. That's fine at keychain scale (tens to a few hundred items), but combining withlabelis recommended, and the docs say so. This mirrors what capi does on Windows, wherecnis matched in Go while iterating a native issuer-search cursor.Semantics
cnis single-valued;o/ou/l/st/ccan be repeated, and every given value must be present in the certificate subject (subset match on multi-valued RDNs).LoadCertificateChain: components select the leaf only; intermediates are still located via the authority key identifier.DeleteCertificate: with subject components present, the certificate is located first (same rules asLoadCertificate) and then deleted by serial number plus, when available, subject key identifier. Still deletes at most one certificate.Behavior change
Subject component attributes in certificate URIs were previously ignored; now they filter. For example,
mackms:label=x;cn=yused to load by label alone and can now return not found, andmackms:cn=yused to fail with "label or serial is required" and now performs a lookup.Testing
Test_parseCertURI(first unit coverage for this function),Test_certAttributes_hasSubjectQuery, andTest_certAttributes_matchesSubject— pure, no keychain access.TestMacKMS_LoadCertificate_bySubjectandTestMacKMS_DeleteCertificate_bySubject(including a no-SKID self-signed cert for the serial-only delete path), plus subject cases inTestMacKMS_LoadCertificateChain.gofmt,go build ./...,go vet, and thekms/uri/kms/platform/kms/apiv1tests. The package still needsgo test ./kms/mackms/...on a Mac before this merges — keeping as draft until that run happens.Possible follow-ups (out of scope)
issuer-cn, …) for disambiguating same-subject certs from different CAs.kSecAttrSubject == SecCertificateCopyNormalizedIssuerSequence(child)(macOS 10.12.4+) as an alternative to the SKID walk — with a cert in hand the framework computes the normalized bytes, so no reimplementation is needed;kSecAttrIssueris an indexed primary-key column, making this the one place issuer-based keychain-side narrowing is legitimate.🤖 Generated with Claude Code
https://claude.ai/code/session_01P3Nxd2zBbULcRAG6HrzQgR