Source file src/crypto/x509/internal/macos/security.go

     1  // Copyright 2020 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  
     5  //go:build darwin
     6  
     7  package macOS
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"internal/abi"
    13  	"strconv"
    14  	"unsafe"
    15  )
    16  
    17  // Security.framework linker flags for the external linker. See Issue 42459.
    18  //go:cgo_ldflag "-framework"
    19  //go:cgo_ldflag "Security"
    20  
    21  // Based on https://opensource.apple.com/source/Security/Security-59306.41.2/base/Security.h
    22  
    23  type SecTrustSettingsResult int32
    24  
    25  const (
    26  	SecTrustSettingsResultInvalid SecTrustSettingsResult = iota
    27  	SecTrustSettingsResultTrustRoot
    28  	SecTrustSettingsResultTrustAsRoot
    29  	SecTrustSettingsResultDeny
    30  	SecTrustSettingsResultUnspecified
    31  )
    32  
    33  type SecTrustResultType int32
    34  
    35  const (
    36  	SecTrustResultInvalid SecTrustResultType = iota
    37  	SecTrustResultProceed
    38  	SecTrustResultConfirm // deprecated
    39  	SecTrustResultDeny
    40  	SecTrustResultUnspecified
    41  	SecTrustResultRecoverableTrustFailure
    42  	SecTrustResultFatalTrustFailure
    43  	SecTrustResultOtherError
    44  )
    45  
    46  type SecTrustSettingsDomain int32
    47  
    48  const (
    49  	SecTrustSettingsDomainUser SecTrustSettingsDomain = iota
    50  	SecTrustSettingsDomainAdmin
    51  	SecTrustSettingsDomainSystem
    52  )
    53  
    54  type OSStatus struct {
    55  	call   string
    56  	status int32
    57  }
    58  
    59  func (s OSStatus) Error() string {
    60  	return s.call + " error: " + strconv.Itoa(int(s.status))
    61  }
    62  
    63  // Dictionary keys are defined as build-time strings with CFSTR, but the Go
    64  // linker's internal linking mode can't handle CFSTR relocations. Create our
    65  // own dynamic strings instead and just never release them.
    66  //
    67  // Note that this might be the only thing that can break over time if
    68  // these values change, as the ABI arguably requires using the strings
    69  // pointed to by the symbols, not values that happen to be equal to them.
    70  
    71  var SecTrustSettingsResultKey = StringToCFString("kSecTrustSettingsResult")
    72  var SecTrustSettingsPolicy = StringToCFString("kSecTrustSettingsPolicy")
    73  var SecTrustSettingsPolicyString = StringToCFString("kSecTrustSettingsPolicyString")
    74  var SecPolicyOid = StringToCFString("SecPolicyOid")
    75  var SecPolicyAppleSSL = StringToCFString("1.2.840.113635.100.1.3") // defined by POLICYMACRO
    76  
    77  var ErrNoTrustSettings = errors.New("no trust settings found")
    78  
    79  const errSecNoTrustSettings = -25263
    80  
    81  //go:cgo_import_dynamic x509_SecTrustSettingsCopyCertificates SecTrustSettingsCopyCertificates "/System/Library/Frameworks/Security.framework/Versions/A/Security"
    82  
    83  func SecTrustSettingsCopyCertificates(domain SecTrustSettingsDomain) (certArray CFRef, err error) {
    84  	ret := syscall(abi.FuncPCABI0(x509_SecTrustSettingsCopyCertificates_trampoline), uintptr(domain),
    85  		uintptr(unsafe.Pointer(&certArray)), 0, 0, 0, 0)
    86  	if int32(ret) == errSecNoTrustSettings {
    87  		return 0, ErrNoTrustSettings
    88  	} else if ret != 0 {
    89  		return 0, OSStatus{"SecTrustSettingsCopyCertificates", int32(ret)}
    90  	}
    91  	return certArray, nil
    92  }
    93  func x509_SecTrustSettingsCopyCertificates_trampoline()
    94  
    95  const errSecItemNotFound = -25300
    96  
    97  //go:cgo_import_dynamic x509_SecTrustSettingsCopyTrustSettings SecTrustSettingsCopyTrustSettings "/System/Library/Frameworks/Security.framework/Versions/A/Security"
    98  
    99  func SecTrustSettingsCopyTrustSettings(cert CFRef, domain SecTrustSettingsDomain) (trustSettings CFRef, err error) {
   100  	ret := syscall(abi.FuncPCABI0(x509_SecTrustSettingsCopyTrustSettings_trampoline), uintptr(cert), uintptr(domain),
   101  		uintptr(unsafe.Pointer(&trustSettings)), 0, 0, 0)
   102  	if int32(ret) == errSecItemNotFound {
   103  		return 0, ErrNoTrustSettings
   104  	} else if ret != 0 {
   105  		return 0, OSStatus{"SecTrustSettingsCopyTrustSettings", int32(ret)}
   106  	}
   107  	return trustSettings, nil
   108  }
   109  func x509_SecTrustSettingsCopyTrustSettings_trampoline()
   110  
   111  //go:cgo_import_dynamic x509_SecPolicyCopyProperties SecPolicyCopyProperties "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   112  
   113  func SecPolicyCopyProperties(policy CFRef) CFRef {
   114  	ret := syscall(abi.FuncPCABI0(x509_SecPolicyCopyProperties_trampoline), uintptr(policy), 0, 0, 0, 0, 0)
   115  	return CFRef(ret)
   116  }
   117  func x509_SecPolicyCopyProperties_trampoline()
   118  
   119  //go:cgo_import_dynamic x509_SecTrustCreateWithCertificates SecTrustCreateWithCertificates "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   120  
   121  func SecTrustCreateWithCertificates(certs CFRef, policies CFRef) (CFRef, error) {
   122  	var trustObj CFRef
   123  	ret := syscall(abi.FuncPCABI0(x509_SecTrustCreateWithCertificates_trampoline), uintptr(certs), uintptr(policies),
   124  		uintptr(unsafe.Pointer(&trustObj)), 0, 0, 0)
   125  	if int32(ret) != 0 {
   126  		return 0, OSStatus{"SecTrustCreateWithCertificates", int32(ret)}
   127  	}
   128  	return trustObj, nil
   129  }
   130  func x509_SecTrustCreateWithCertificates_trampoline()
   131  
   132  //go:cgo_import_dynamic x509_SecCertificateCreateWithData SecCertificateCreateWithData "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   133  
   134  func SecCertificateCreateWithData(b []byte) CFRef {
   135  	data := BytesToCFData(b)
   136  	ret := syscall(abi.FuncPCABI0(x509_SecCertificateCreateWithData_trampoline), kCFAllocatorDefault, uintptr(data), 0, 0, 0, 0)
   137  	CFRelease(data)
   138  	return CFRef(ret)
   139  }
   140  func x509_SecCertificateCreateWithData_trampoline()
   141  
   142  //go:cgo_import_dynamic x509_SecPolicyCreateSSL SecPolicyCreateSSL "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   143  
   144  func SecPolicyCreateSSL(name string) CFRef {
   145  	var hostname CFString
   146  	if name != "" {
   147  		hostname = StringToCFString(name)
   148  		defer CFRelease(CFRef(hostname))
   149  	}
   150  	ret := syscall(abi.FuncPCABI0(x509_SecPolicyCreateSSL_trampoline), 1 /* true */, uintptr(hostname), 0, 0, 0, 0)
   151  	return CFRef(ret)
   152  }
   153  func x509_SecPolicyCreateSSL_trampoline()
   154  
   155  //go:cgo_import_dynamic x509_SecTrustSetVerifyDate SecTrustSetVerifyDate "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   156  
   157  func SecTrustSetVerifyDate(trustObj CFRef, dateRef CFRef) error {
   158  	ret := syscall(abi.FuncPCABI0(x509_SecTrustSetVerifyDate_trampoline), uintptr(trustObj), uintptr(dateRef), 0, 0, 0, 0)
   159  	if int32(ret) != 0 {
   160  		return OSStatus{"SecTrustSetVerifyDate", int32(ret)}
   161  	}
   162  	return nil
   163  }
   164  func x509_SecTrustSetVerifyDate_trampoline()
   165  
   166  //go:cgo_import_dynamic x509_SecTrustEvaluate SecTrustEvaluate "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   167  
   168  func SecTrustEvaluate(trustObj CFRef) (CFRef, error) {
   169  	var result CFRef
   170  	ret := syscall(abi.FuncPCABI0(x509_SecTrustEvaluate_trampoline), uintptr(trustObj), uintptr(unsafe.Pointer(&result)), 0, 0, 0, 0)
   171  	if int32(ret) != 0 {
   172  		return 0, OSStatus{"SecTrustEvaluate", int32(ret)}
   173  	}
   174  	return CFRef(result), nil
   175  }
   176  func x509_SecTrustEvaluate_trampoline()
   177  
   178  //go:cgo_import_dynamic x509_SecTrustGetResult SecTrustGetResult "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   179  
   180  func SecTrustGetResult(trustObj CFRef, result CFRef) (CFRef, CFRef, error) {
   181  	var chain, info CFRef
   182  	ret := syscall(abi.FuncPCABI0(x509_SecTrustGetResult_trampoline), uintptr(trustObj), uintptr(unsafe.Pointer(&result)),
   183  		uintptr(unsafe.Pointer(&chain)), uintptr(unsafe.Pointer(&info)), 0, 0)
   184  	if int32(ret) != 0 {
   185  		return 0, 0, OSStatus{"SecTrustGetResult", int32(ret)}
   186  	}
   187  	return chain, info, nil
   188  }
   189  func x509_SecTrustGetResult_trampoline()
   190  
   191  //go:cgo_import_dynamic x509_SecTrustEvaluateWithError SecTrustEvaluateWithError "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   192  
   193  func SecTrustEvaluateWithError(trustObj CFRef) error {
   194  	var errRef CFRef
   195  	ret := syscall(abi.FuncPCABI0(x509_SecTrustEvaluateWithError_trampoline), uintptr(trustObj), uintptr(unsafe.Pointer(&errRef)), 0, 0, 0, 0)
   196  	if int32(ret) != 1 {
   197  		errStr := CFErrorCopyDescription(errRef)
   198  		err := fmt.Errorf("x509: %s", CFStringToString(errStr))
   199  		CFRelease(errRef)
   200  		CFRelease(errStr)
   201  		return err
   202  	}
   203  	return nil
   204  }
   205  func x509_SecTrustEvaluateWithError_trampoline()
   206  
   207  //go:cgo_import_dynamic x509_SecTrustGetCertificateCount SecTrustGetCertificateCount "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   208  
   209  func SecTrustGetCertificateCount(trustObj CFRef) int {
   210  	ret := syscall(abi.FuncPCABI0(x509_SecTrustGetCertificateCount_trampoline), uintptr(trustObj), 0, 0, 0, 0, 0)
   211  	return int(ret)
   212  }
   213  func x509_SecTrustGetCertificateCount_trampoline()
   214  
   215  //go:cgo_import_dynamic x509_SecTrustGetCertificateAtIndex SecTrustGetCertificateAtIndex "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   216  
   217  func SecTrustGetCertificateAtIndex(trustObj CFRef, i int) CFRef {
   218  	ret := syscall(abi.FuncPCABI0(x509_SecTrustGetCertificateAtIndex_trampoline), uintptr(trustObj), uintptr(i), 0, 0, 0, 0)
   219  	return CFRef(ret)
   220  }
   221  func x509_SecTrustGetCertificateAtIndex_trampoline()
   222  
   223  //go:cgo_import_dynamic x509_SecCertificateCopyData SecCertificateCopyData "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   224  
   225  func SecCertificateCopyData(cert CFRef) ([]byte, error) {
   226  	ret := syscall(abi.FuncPCABI0(x509_SecCertificateCopyData_trampoline), uintptr(cert), 0, 0, 0, 0, 0)
   227  	if ret == 0 {
   228  		return nil, errors.New("x509: invalid certificate object")
   229  	}
   230  	b := CFDataToSlice(CFRef(ret))
   231  	CFRelease(CFRef(ret))
   232  	return b, nil
   233  }
   234  func x509_SecCertificateCopyData_trampoline()
   235  

View as plain text