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  	"internal/abi"
    12  	"strconv"
    13  	"unsafe"
    14  )
    15  
    16  // Security.framework linker flags for the external linker. See Issue 42459.
    17  //
    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  const (
    24  	// various macOS error codes that can be returned from
    25  	// SecTrustEvaluateWithError that we can map to Go cert
    26  	// verification error types.
    27  	ErrSecCertificateExpired = -67818
    28  	ErrSecHostNameMismatch   = -67602
    29  	ErrSecNotTrusted         = -67843
    30  )
    31  
    32  type OSStatus struct {
    33  	call   string
    34  	status int32
    35  }
    36  
    37  func (s OSStatus) Error() string {
    38  	return s.call + " error: " + strconv.Itoa(int(s.status))
    39  }
    40  
    41  //go:cgo_import_dynamic x509_SecTrustCreateWithCertificates SecTrustCreateWithCertificates "/System/Library/Frameworks/Security.framework/Versions/A/Security"
    42  
    43  func SecTrustCreateWithCertificates(certs CFRef, policies CFRef) (CFRef, error) {
    44  	var trustObj CFRef
    45  	ret := syscall(abi.FuncPCABI0(x509_SecTrustCreateWithCertificates_trampoline), uintptr(certs), uintptr(policies),
    46  		uintptr(unsafe.Pointer(&trustObj)), 0, 0, 0)
    47  	if int32(ret) != 0 {
    48  		return 0, OSStatus{"SecTrustCreateWithCertificates", int32(ret)}
    49  	}
    50  	return trustObj, nil
    51  }
    52  func x509_SecTrustCreateWithCertificates_trampoline()
    53  
    54  //go:cgo_import_dynamic x509_SecCertificateCreateWithData SecCertificateCreateWithData "/System/Library/Frameworks/Security.framework/Versions/A/Security"
    55  
    56  func SecCertificateCreateWithData(b []byte) (CFRef, error) {
    57  	data := BytesToCFData(b)
    58  	defer CFRelease(data)
    59  	ret := syscall(abi.FuncPCABI0(x509_SecCertificateCreateWithData_trampoline), kCFAllocatorDefault, uintptr(data), 0, 0, 0, 0)
    60  	// Returns NULL if the data passed in the data parameter is not a valid
    61  	// DER-encoded X.509 certificate.
    62  	if ret == 0 {
    63  		return 0, errors.New("SecCertificateCreateWithData: invalid certificate")
    64  	}
    65  	return CFRef(ret), nil
    66  }
    67  func x509_SecCertificateCreateWithData_trampoline()
    68  
    69  //go:cgo_import_dynamic x509_SecPolicyCreateSSL SecPolicyCreateSSL "/System/Library/Frameworks/Security.framework/Versions/A/Security"
    70  
    71  func SecPolicyCreateSSL(name string) (CFRef, error) {
    72  	var hostname CFString
    73  	if name != "" {
    74  		hostname = StringToCFString(name)
    75  		defer CFRelease(CFRef(hostname))
    76  	}
    77  	ret := syscall(abi.FuncPCABI0(x509_SecPolicyCreateSSL_trampoline), 1 /* true */, uintptr(hostname), 0, 0, 0, 0)
    78  	if ret == 0 {
    79  		return 0, OSStatus{"SecPolicyCreateSSL", int32(ret)}
    80  	}
    81  	return CFRef(ret), nil
    82  }
    83  func x509_SecPolicyCreateSSL_trampoline()
    84  
    85  //go:cgo_import_dynamic x509_SecTrustSetVerifyDate SecTrustSetVerifyDate "/System/Library/Frameworks/Security.framework/Versions/A/Security"
    86  
    87  func SecTrustSetVerifyDate(trustObj CFRef, dateRef CFRef) error {
    88  	ret := syscall(abi.FuncPCABI0(x509_SecTrustSetVerifyDate_trampoline), uintptr(trustObj), uintptr(dateRef), 0, 0, 0, 0)
    89  	if int32(ret) != 0 {
    90  		return OSStatus{"SecTrustSetVerifyDate", int32(ret)}
    91  	}
    92  	return nil
    93  }
    94  func x509_SecTrustSetVerifyDate_trampoline()
    95  
    96  //go:cgo_import_dynamic x509_SecTrustEvaluate SecTrustEvaluate "/System/Library/Frameworks/Security.framework/Versions/A/Security"
    97  
    98  func SecTrustEvaluate(trustObj CFRef) (CFRef, error) {
    99  	var result CFRef
   100  	ret := syscall(abi.FuncPCABI0(x509_SecTrustEvaluate_trampoline), uintptr(trustObj), uintptr(unsafe.Pointer(&result)), 0, 0, 0, 0)
   101  	if int32(ret) != 0 {
   102  		return 0, OSStatus{"SecTrustEvaluate", int32(ret)}
   103  	}
   104  	return CFRef(result), nil
   105  }
   106  func x509_SecTrustEvaluate_trampoline()
   107  
   108  //go:cgo_import_dynamic x509_SecTrustEvaluateWithError SecTrustEvaluateWithError "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   109  
   110  func SecTrustEvaluateWithError(trustObj CFRef) (int, error) {
   111  	var errRef CFRef
   112  	ret := syscall(abi.FuncPCABI0(x509_SecTrustEvaluateWithError_trampoline), uintptr(trustObj), uintptr(unsafe.Pointer(&errRef)), 0, 0, 0, 0)
   113  	if int32(ret) != 1 {
   114  		errStr := CFErrorCopyDescription(errRef)
   115  		err := errors.New(CFStringToString(errStr))
   116  		errCode := CFErrorGetCode(errRef)
   117  		CFRelease(errRef)
   118  		CFRelease(errStr)
   119  		return errCode, err
   120  	}
   121  	return 0, nil
   122  }
   123  func x509_SecTrustEvaluateWithError_trampoline()
   124  
   125  //go:cgo_import_dynamic x509_SecCertificateCopyData SecCertificateCopyData "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   126  
   127  func SecCertificateCopyData(cert CFRef) ([]byte, error) {
   128  	ret := syscall(abi.FuncPCABI0(x509_SecCertificateCopyData_trampoline), uintptr(cert), 0, 0, 0, 0, 0)
   129  	if ret == 0 {
   130  		return nil, errors.New("x509: invalid certificate object")
   131  	}
   132  	b := CFDataToSlice(CFRef(ret))
   133  	CFRelease(CFRef(ret))
   134  	return b, nil
   135  }
   136  func x509_SecCertificateCopyData_trampoline()
   137  
   138  //go:cgo_import_dynamic x509_SecTrustCopyCertificateChain SecTrustCopyCertificateChain "/System/Library/Frameworks/Security.framework/Versions/A/Security"
   139  
   140  func SecTrustCopyCertificateChain(trustObj CFRef) (CFRef, error) {
   141  	ret := syscall(abi.FuncPCABI0(x509_SecTrustCopyCertificateChain_trampoline), uintptr(trustObj), 0, 0, 0, 0, 0)
   142  	if ret == 0 {
   143  		return 0, OSStatus{"SecTrustCopyCertificateChain", int32(ret)}
   144  	}
   145  	return CFRef(ret), nil
   146  }
   147  func x509_SecTrustCopyCertificateChain_trampoline()
   148  

View as plain text