選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

96 行
2.8 KiB

  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. package tls
  5. /*
  6. // Note: We disable -Werror here because the code in this file uses a deprecated API to stay
  7. // compatible with both Mac OS X 10.6 and 10.7. Using a deprecated function on Darwin generates
  8. // a warning.
  9. #cgo CFLAGS: -Wno-error -Wno-deprecated-declarations
  10. #cgo LDFLAGS: -framework CoreFoundation -framework Security
  11. #include <CoreFoundation/CoreFoundation.h>
  12. #include <Security/Security.h>
  13. // FetchPEMRoots fetches the system's list of trusted X.509 root certificates.
  14. //
  15. // On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root
  16. // certificates of the system. On failure, the function returns -1.
  17. //
  18. // Note: The CFDataRef returned in pemRoots must be released (using CFRelease) after
  19. // we've consumed its content.
  20. int FetchPEMRoots(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. // SecKeychainImportExport is deprecated in >= OS X 10.7, and has been replaced by
  38. // SecItemExport. If we're built on a host with a Lion SDK, this code gets conditionally
  39. // included in the output, also for binaries meant for 10.6.
  40. //
  41. // To make sure that we run on both Mac OS X 10.6 and 10.7 we use weak linking
  42. // and check whether SecItemExport is available before we attempt to call it. On
  43. // 10.6, this won't be the case, and we'll fall back to calling SecKeychainItemExport.
  44. #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
  45. if (SecItemExport) {
  46. err = SecItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
  47. if (err != noErr) {
  48. continue;
  49. }
  50. } else
  51. #endif
  52. if (data == NULL) {
  53. err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data);
  54. if (err != noErr) {
  55. continue;
  56. }
  57. }
  58. if (data != NULL) {
  59. CFDataAppendBytes(combinedData, CFDataGetBytePtr(data), CFDataGetLength(data));
  60. CFRelease(data);
  61. }
  62. }
  63. CFRelease(certs);
  64. *pemRoots = combinedData;
  65. return 0;
  66. }
  67. */
  68. import "C"
  69. import (
  70. "crypto/x509"
  71. "unsafe"
  72. )
  73. func initDefaultRoots() {
  74. roots := x509.NewCertPool()
  75. var data C.CFDataRef = nil
  76. err := C.FetchPEMRoots(&data)
  77. if err != -1 {
  78. defer C.CFRelease(C.CFTypeRef(data))
  79. buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
  80. roots.AppendCertsFromPEM(buf)
  81. }
  82. varDefaultRoots = roots
  83. }