Skip to content

Commit ff60da6

Browse files
committed
crypto/x509: use Go 1.6 implementation for FetchPEMRoots for OS X 10.8
Conservative fix for the OS X 10.8 crash. We can unify them back together during the Go 1.8 dev cycle. Fixes #16473 Change-Id: If07228deb2be36093dd324b3b3bcb31c23a95035 Reviewed-on: https://go-review.googlesource.com/25233 Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Andrew Gerrand <[email protected]>
1 parent 8876061 commit ff60da6

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

src/crypto/x509/root_cgo_darwin.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,48 @@ package x509
1313
#include <CoreFoundation/CoreFoundation.h>
1414
#include <Security/Security.h>
1515
16+
// FetchPEMRoots_MountainLion is the version of FetchPEMRoots from Go 1.6
17+
// which still works on OS X 10.8 (Mountain Lion).
18+
// It lacks support for admin & user cert domains.
19+
// See golang.org/issue/16473
20+
int FetchPEMRoots_MountainLion(CFDataRef *pemRoots) {
21+
if (pemRoots == NULL) {
22+
return -1;
23+
}
24+
CFArrayRef certs = NULL;
25+
OSStatus err = SecTrustCopyAnchorCertificates(&certs);
26+
if (err != noErr) {
27+
return -1;
28+
}
29+
CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
30+
int i, ncerts = CFArrayGetCount(certs);
31+
for (i = 0; i < ncerts; i++) {
32+
CFDataRef data = NULL;
33+
SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, i);
34+
if (cert == NULL) {
35+
continue;
36+
}
37+
// Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport.
38+
// Once we support weak imports via cgo we should prefer that, and fall back to this
39+
// for older systems.
40+
err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
41+
if (err != noErr) {
42+
continue;
43+
}
44+
if (data != NULL) {
45+
CFDataAppendBytes(combinedData, CFDataGetBytePtr(data), CFDataGetLength(data));
46+
CFRelease(data);
47+
}
48+
}
49+
CFRelease(certs);
50+
*pemRoots = combinedData;
51+
return 0;
52+
}
53+
54+
#ifndef kCFCoreFoundationVersionNumber10_9
55+
#define kCFCoreFoundationVersionNumber10_9 855.11
56+
#endif
57+
1658
// FetchPEMRoots fetches the system's list of trusted X.509 root certificates.
1759
//
1860
// On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root
@@ -21,6 +63,10 @@ package x509
2163
// Note: The CFDataRef returned in pemRoots must be released (using CFRelease) after
2264
// we've consumed its content.
2365
int FetchPEMRoots(CFDataRef *pemRoots) {
66+
if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber10_9) {
67+
return FetchPEMRoots_MountainLion(pemRoots);
68+
}
69+
2470
// Get certificates from all domains, not just System, this lets
2571
// the user add CAs to their "login" keychain, and Admins to add
2672
// to the "System" keychain

0 commit comments

Comments
 (0)