github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/crypto/x509/internal/macos/corefoundation.go (about)

     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  // +build darwin,!ios
     6  
     7  // Package macOS provides cgo-less wrappers for Core Foundation and
     8  // Security.framework, similarly to how package syscall provides access to
     9  // libSystem.dylib.
    10  package macOS
    11  
    12  import (
    13  	"errors"
    14  	"reflect"
    15  	"runtime"
    16  	"unsafe"
    17  )
    18  
    19  // Core Foundation linker flags for the external linker. See Issue 42459.
    20  //go:cgo_ldflag "-framework"
    21  //go:cgo_ldflag "CoreFoundation"
    22  
    23  // CFRef is an opaque reference to a Core Foundation object. It is a pointer,
    24  // but to memory not owned by Go, so not an unsafe.Pointer.
    25  type CFRef uintptr
    26  
    27  // CFDataToSlice returns a copy of the contents of data as a bytes slice.
    28  func CFDataToSlice(data CFRef) []byte {
    29  	length := CFDataGetLength(data)
    30  	ptr := CFDataGetBytePtr(data)
    31  	src := (*[1 << 20]byte)(unsafe.Pointer(ptr))[:length:length]
    32  	out := make([]byte, length)
    33  	copy(out, src)
    34  	return out
    35  }
    36  
    37  type CFString CFRef
    38  
    39  const kCFAllocatorDefault = 0
    40  const kCFStringEncodingUTF8 = 0x08000100
    41  
    42  //go:linkname x509_CFStringCreateWithBytes x509_CFStringCreateWithBytes
    43  //go:cgo_import_dynamic x509_CFStringCreateWithBytes CFStringCreateWithBytes "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
    44  
    45  // StringToCFString returns a copy of the UTF-8 contents of s as a new CFString.
    46  func StringToCFString(s string) CFString {
    47  	p := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&s)).Data)
    48  	ret := syscall(funcPC(x509_CFStringCreateWithBytes_trampoline), kCFAllocatorDefault, uintptr(p),
    49  		uintptr(len(s)), uintptr(kCFStringEncodingUTF8), 0 /* isExternalRepresentation */, 0)
    50  	runtime.KeepAlive(p)
    51  	return CFString(ret)
    52  }
    53  func x509_CFStringCreateWithBytes_trampoline()
    54  
    55  //go:linkname x509_CFDictionaryGetValueIfPresent x509_CFDictionaryGetValueIfPresent
    56  //go:cgo_import_dynamic x509_CFDictionaryGetValueIfPresent CFDictionaryGetValueIfPresent "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
    57  
    58  func CFDictionaryGetValueIfPresent(dict CFRef, key CFString) (value CFRef, ok bool) {
    59  	ret := syscall(funcPC(x509_CFDictionaryGetValueIfPresent_trampoline), uintptr(dict), uintptr(key),
    60  		uintptr(unsafe.Pointer(&value)), 0, 0, 0)
    61  	if ret == 0 {
    62  		return 0, false
    63  	}
    64  	return value, true
    65  }
    66  func x509_CFDictionaryGetValueIfPresent_trampoline()
    67  
    68  const kCFNumberSInt32Type = 3
    69  
    70  //go:linkname x509_CFNumberGetValue x509_CFNumberGetValue
    71  //go:cgo_import_dynamic x509_CFNumberGetValue CFNumberGetValue "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
    72  
    73  func CFNumberGetValue(num CFRef) (int32, error) {
    74  	var value int32
    75  	ret := syscall(funcPC(x509_CFNumberGetValue_trampoline), uintptr(num), uintptr(kCFNumberSInt32Type),
    76  		uintptr(unsafe.Pointer(&value)), 0, 0, 0)
    77  	if ret == 0 {
    78  		return 0, errors.New("CFNumberGetValue call failed")
    79  	}
    80  	return value, nil
    81  }
    82  func x509_CFNumberGetValue_trampoline()
    83  
    84  //go:linkname x509_CFDataGetLength x509_CFDataGetLength
    85  //go:cgo_import_dynamic x509_CFDataGetLength CFDataGetLength "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
    86  
    87  func CFDataGetLength(data CFRef) int {
    88  	ret := syscall(funcPC(x509_CFDataGetLength_trampoline), uintptr(data), 0, 0, 0, 0, 0)
    89  	return int(ret)
    90  }
    91  func x509_CFDataGetLength_trampoline()
    92  
    93  //go:linkname x509_CFDataGetBytePtr x509_CFDataGetBytePtr
    94  //go:cgo_import_dynamic x509_CFDataGetBytePtr CFDataGetBytePtr "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
    95  
    96  func CFDataGetBytePtr(data CFRef) uintptr {
    97  	ret := syscall(funcPC(x509_CFDataGetBytePtr_trampoline), uintptr(data), 0, 0, 0, 0, 0)
    98  	return ret
    99  }
   100  func x509_CFDataGetBytePtr_trampoline()
   101  
   102  //go:linkname x509_CFArrayGetCount x509_CFArrayGetCount
   103  //go:cgo_import_dynamic x509_CFArrayGetCount CFArrayGetCount "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
   104  
   105  func CFArrayGetCount(array CFRef) int {
   106  	ret := syscall(funcPC(x509_CFArrayGetCount_trampoline), uintptr(array), 0, 0, 0, 0, 0)
   107  	return int(ret)
   108  }
   109  func x509_CFArrayGetCount_trampoline()
   110  
   111  //go:linkname x509_CFArrayGetValueAtIndex x509_CFArrayGetValueAtIndex
   112  //go:cgo_import_dynamic x509_CFArrayGetValueAtIndex CFArrayGetValueAtIndex "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
   113  
   114  func CFArrayGetValueAtIndex(array CFRef, index int) CFRef {
   115  	ret := syscall(funcPC(x509_CFArrayGetValueAtIndex_trampoline), uintptr(array), uintptr(index), 0, 0, 0, 0)
   116  	return CFRef(ret)
   117  }
   118  func x509_CFArrayGetValueAtIndex_trampoline()
   119  
   120  //go:linkname x509_CFEqual x509_CFEqual
   121  //go:cgo_import_dynamic x509_CFEqual CFEqual "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
   122  
   123  func CFEqual(a, b CFRef) bool {
   124  	ret := syscall(funcPC(x509_CFEqual_trampoline), uintptr(a), uintptr(b), 0, 0, 0, 0)
   125  	return ret == 1
   126  }
   127  func x509_CFEqual_trampoline()
   128  
   129  //go:linkname x509_CFRelease x509_CFRelease
   130  //go:cgo_import_dynamic x509_CFRelease CFRelease "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
   131  
   132  func CFRelease(ref CFRef) {
   133  	syscall(funcPC(x509_CFRelease_trampoline), uintptr(ref), 0, 0, 0, 0, 0)
   134  }
   135  func x509_CFRelease_trampoline()
   136  
   137  // syscall is implemented in the runtime package (runtime/sys_darwin.go)
   138  func syscall(fn, a1, a2, a3, a4, a5, a6 uintptr) uintptr
   139  
   140  // funcPC returns the entry point for f. See comments in runtime/proc.go
   141  // for the function of the same name.
   142  //go:nosplit
   143  func funcPC(f func()) uintptr {
   144  	return **(**uintptr)(unsafe.Pointer(&f))
   145  }