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 }