root_darwin.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build darwin,cgo
  5. package x509
  6. /*
  7. #cgo CFLAGS: -mmacosx-version-min=10.6 -D__MAC_OS_X_VERSION_MAX_ALLOWED=1060
  8. #cgo LDFLAGS: -framework CoreFoundation -framework Security
  9. #include <CoreFoundation/CoreFoundation.h>
  10. #include <Security/Security.h>
  11. // FetchPEMRootsCTX509 fetches the system's list of trusted X.509 root certificates.
  12. //
  13. // On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root
  14. // certificates of the system. On failure, the function returns -1.
  15. //
  16. // Note: The CFDataRef returned in pemRoots must be released (using CFRelease) after
  17. // we've consumed its content.
  18. int FetchPEMRootsCTX509(CFDataRef *pemRoots) {
  19. if (pemRoots == NULL) {
  20. return -1;
  21. }
  22. CFArrayRef certs = NULL;
  23. OSStatus err = SecTrustCopyAnchorCertificates(&certs);
  24. if (err != noErr) {
  25. return -1;
  26. }
  27. CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
  28. int i, ncerts = CFArrayGetCount(certs);
  29. for (i = 0; i < ncerts; i++) {
  30. CFDataRef data = NULL;
  31. SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, i);
  32. if (cert == NULL) {
  33. continue;
  34. }
  35. // Note: SecKeychainItemExport is deprecated as of 10.7 in favor of SecItemExport.
  36. // Once we support weak imports via cgo we should prefer that, and fall back to this
  37. // for older systems.
  38. err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
  39. if (err != noErr) {
  40. continue;
  41. }
  42. if (data != NULL) {
  43. CFDataAppendBytes(combinedData, CFDataGetBytePtr(data), CFDataGetLength(data));
  44. CFRelease(data);
  45. }
  46. }
  47. CFRelease(certs);
  48. *pemRoots = combinedData;
  49. return 0;
  50. }
  51. */
  52. import "C"
  53. import "unsafe"
  54. func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
  55. return nil, nil
  56. }
  57. func initSystemRoots() {
  58. roots := NewCertPool()
  59. var data C.CFDataRef = nil
  60. err := C.FetchPEMRootsCTX509(&data)
  61. if err == -1 {
  62. return
  63. }
  64. defer C.CFRelease(C.CFTypeRef(data))
  65. buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
  66. roots.AppendCertsFromPEM(buf)
  67. systemRoots = roots
  68. }