Skip to content

Commit

Permalink
crypto/x509: load all trusted certs on darwin (cgo)
Browse files Browse the repository at this point in the history
The current implementation ignores certs wherein the
Subject does not match the Issuer. An example of where
this causes issue is an enterprise environment with
intermediate CAs. In this case, the issuer is separate
(and may be loaded) but the intermediate is ignored.
A TLS handshake that does not include the intermediate
cert would then fail with an untrusted error in Go.

On other platforms (darwin-nocgo included), all trusted
certs are loaded and accepted reguardless of
Subject/Issuer names.

This change removes the Subject/Issuer name-matching
restriction of certificates when trustAsRoot is set,
allowing all trusted certs to be loaded on darwin (cgo).

Refs golang#16532

Change-Id: I451e929588f8911892be6bdc2143d0799363c5f8
  • Loading branch information
mastercactapus committed Jun 25, 2017
1 parent b4dd1d9 commit 1bc5a0b
Showing 1 changed file with 30 additions and 16 deletions.
46 changes: 30 additions & 16 deletions src/crypto/x509/root_cgo_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
}
// We only want trusted certs.
int untrusted = 0;
int trustAsRoot = 0;
int trustRoot = 0;
if (i != 0) {
// Certs found in the system domain are always trusted. If the user
// configures "Never Trust" on such a cert, it will also be found in the
Expand Down Expand Up @@ -152,28 +154,37 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
// TODO: The rest of the dictionary specifies conditions for evaluation.
if (result == kSecTrustSettingsResultDeny) {
untrusted = 1;
} else if (result == kSecTrustSettingsResultTrustAsRoot) {
trustAsRoot = 1;
} else if (result == kSecTrustSettingsResultTrustRoot) {
trustRoot = 1;
}
}
}
CFRelease(trustSettings);
} else {
trustAsRoot = 1;
}
// We only want to add Root CAs, so make sure Subject and Issuer Name match
CFDataRef subjectName = SecCertificateCopyNormalizedSubjectContent(cert, &errRef);
if (errRef != NULL) {
CFRelease(errRef);
continue;
}
CFDataRef issuerName = SecCertificateCopyNormalizedIssuerContent(cert, &errRef);
if (errRef != NULL) {
if (!trustAsRoot) {
// We only want to add Root CAs, so make sure Subject and Issuer Name match
CFDataRef subjectName = SecCertificateCopyNormalizedSubjectContent(cert, &errRef);
if (errRef != NULL) {
CFRelease(errRef);
continue;
}
CFDataRef issuerName = SecCertificateCopyNormalizedIssuerContent(cert, &errRef);
if (errRef != NULL) {
CFRelease(subjectName);
CFRelease(errRef);
continue;
}
Boolean equal = CFEqual(subjectName, issuerName);
CFRelease(subjectName);
CFRelease(errRef);
continue;
}
Boolean equal = CFEqual(subjectName, issuerName);
CFRelease(subjectName);
CFRelease(issuerName);
if (!equal) {
continue;
CFRelease(issuerName);
if (!equal) {
continue;
}
}
// Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport.
Expand All @@ -185,6 +196,9 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
}
if (data != NULL) {
if (!trustRoot && !trustAsRoot) {
untrusted = 1;
}
CFMutableDataRef appendTo = untrusted ? combinedUntrustedData : combinedData;
CFDataAppendBytes(appendTo, CFDataGetBytePtr(data), CFDataGetLength(data));
CFRelease(data);
Expand Down

0 comments on commit 1bc5a0b

Please sign in to comment.