github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/crypto/x509/internal/macos/security.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 //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 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 const ( 55 // various macOS error codes that can be returned from 56 // SecTrustEvaluateWithError that we can map to Go cert 57 // verification error types. 58 ErrSecCertificateExpired = -67818 59 ErrSecHostNameMismatch = -67602 60 ErrSecNotTrusted = -67843 61 ) 62 63 type OSStatus struct { 64 call string 65 status int32 66 } 67 68 func (s OSStatus) Error() string { 69 return s.call + " error: " + strconv.Itoa(int(s.status)) 70 } 71 72 // Dictionary keys are defined as build-time strings with CFSTR, but the Go 73 // linker's internal linking mode can't handle CFSTR relocations. Create our 74 // own dynamic strings instead and just never release them. 75 // 76 // Note that this might be the only thing that can break over time if 77 // these values change, as the ABI arguably requires using the strings 78 // pointed to by the symbols, not values that happen to be equal to them. 79 80 var SecTrustSettingsResultKey = StringToCFString("kSecTrustSettingsResult") 81 var SecTrustSettingsPolicy = StringToCFString("kSecTrustSettingsPolicy") 82 var SecTrustSettingsPolicyString = StringToCFString("kSecTrustSettingsPolicyString") 83 var SecPolicyOid = StringToCFString("SecPolicyOid") 84 var SecPolicyAppleSSL = StringToCFString("1.2.840.113635.100.1.3") // defined by POLICYMACRO 85 86 var ErrNoTrustSettings = errors.New("no trust settings found") 87 88 const errSecNoTrustSettings = -25263 89 90 //go:cgo_import_dynamic x509_SecTrustSettingsCopyCertificates SecTrustSettingsCopyCertificates "/System/Library/Frameworks/Security.framework/Versions/A/Security" 91 92 func SecTrustSettingsCopyCertificates(domain SecTrustSettingsDomain) (certArray CFRef, err error) { 93 ret := syscall(abi.FuncPCABI0(x509_SecTrustSettingsCopyCertificates_trampoline), uintptr(domain), 94 uintptr(unsafe.Pointer(&certArray)), 0, 0, 0, 0) 95 if int32(ret) == errSecNoTrustSettings { 96 return 0, ErrNoTrustSettings 97 } else if ret != 0 { 98 return 0, OSStatus{"SecTrustSettingsCopyCertificates", int32(ret)} 99 } 100 return certArray, nil 101 } 102 func x509_SecTrustSettingsCopyCertificates_trampoline() 103 104 const errSecItemNotFound = -25300 105 106 //go:cgo_import_dynamic x509_SecTrustSettingsCopyTrustSettings SecTrustSettingsCopyTrustSettings "/System/Library/Frameworks/Security.framework/Versions/A/Security" 107 108 func SecTrustSettingsCopyTrustSettings(cert CFRef, domain SecTrustSettingsDomain) (trustSettings CFRef, err error) { 109 ret := syscall(abi.FuncPCABI0(x509_SecTrustSettingsCopyTrustSettings_trampoline), uintptr(cert), uintptr(domain), 110 uintptr(unsafe.Pointer(&trustSettings)), 0, 0, 0) 111 if int32(ret) == errSecItemNotFound { 112 return 0, ErrNoTrustSettings 113 } else if ret != 0 { 114 return 0, OSStatus{"SecTrustSettingsCopyTrustSettings", int32(ret)} 115 } 116 return trustSettings, nil 117 } 118 func x509_SecTrustSettingsCopyTrustSettings_trampoline() 119 120 //go:cgo_import_dynamic x509_SecTrustCreateWithCertificates SecTrustCreateWithCertificates "/System/Library/Frameworks/Security.framework/Versions/A/Security" 121 122 func SecTrustCreateWithCertificates(certs CFRef, policies CFRef) (CFRef, error) { 123 var trustObj CFRef 124 ret := syscall(abi.FuncPCABI0(x509_SecTrustCreateWithCertificates_trampoline), uintptr(certs), uintptr(policies), 125 uintptr(unsafe.Pointer(&trustObj)), 0, 0, 0) 126 if int32(ret) != 0 { 127 return 0, OSStatus{"SecTrustCreateWithCertificates", int32(ret)} 128 } 129 return trustObj, nil 130 } 131 func x509_SecTrustCreateWithCertificates_trampoline() 132 133 //go:cgo_import_dynamic x509_SecCertificateCreateWithData SecCertificateCreateWithData "/System/Library/Frameworks/Security.framework/Versions/A/Security" 134 135 func SecCertificateCreateWithData(b []byte) (CFRef, error) { 136 data := BytesToCFData(b) 137 defer CFRelease(data) 138 ret := syscall(abi.FuncPCABI0(x509_SecCertificateCreateWithData_trampoline), kCFAllocatorDefault, uintptr(data), 0, 0, 0, 0) 139 // Returns NULL if the data passed in the data parameter is not a valid 140 // DER-encoded X.509 certificate. 141 if ret == 0 { 142 return 0, errors.New("SecCertificateCreateWithData: invalid certificate") 143 } 144 return CFRef(ret), nil 145 } 146 func x509_SecCertificateCreateWithData_trampoline() 147 148 //go:cgo_import_dynamic x509_SecPolicyCreateSSL SecPolicyCreateSSL "/System/Library/Frameworks/Security.framework/Versions/A/Security" 149 150 func SecPolicyCreateSSL(name string) (CFRef, error) { 151 var hostname CFString 152 if name != "" { 153 hostname = StringToCFString(name) 154 defer CFRelease(CFRef(hostname)) 155 } 156 ret := syscall(abi.FuncPCABI0(x509_SecPolicyCreateSSL_trampoline), 1 /* true */, uintptr(hostname), 0, 0, 0, 0) 157 if ret == 0 { 158 return 0, OSStatus{"SecPolicyCreateSSL", int32(ret)} 159 } 160 return CFRef(ret), nil 161 } 162 func x509_SecPolicyCreateSSL_trampoline() 163 164 //go:cgo_import_dynamic x509_SecTrustSetVerifyDate SecTrustSetVerifyDate "/System/Library/Frameworks/Security.framework/Versions/A/Security" 165 166 func SecTrustSetVerifyDate(trustObj CFRef, dateRef CFRef) error { 167 ret := syscall(abi.FuncPCABI0(x509_SecTrustSetVerifyDate_trampoline), uintptr(trustObj), uintptr(dateRef), 0, 0, 0, 0) 168 if int32(ret) != 0 { 169 return OSStatus{"SecTrustSetVerifyDate", int32(ret)} 170 } 171 return nil 172 } 173 func x509_SecTrustSetVerifyDate_trampoline() 174 175 //go:cgo_import_dynamic x509_SecTrustEvaluate SecTrustEvaluate "/System/Library/Frameworks/Security.framework/Versions/A/Security" 176 177 func SecTrustEvaluate(trustObj CFRef) (CFRef, error) { 178 var result CFRef 179 ret := syscall(abi.FuncPCABI0(x509_SecTrustEvaluate_trampoline), uintptr(trustObj), uintptr(unsafe.Pointer(&result)), 0, 0, 0, 0) 180 if int32(ret) != 0 { 181 return 0, OSStatus{"SecTrustEvaluate", int32(ret)} 182 } 183 return CFRef(result), nil 184 } 185 func x509_SecTrustEvaluate_trampoline() 186 187 //go:cgo_import_dynamic x509_SecTrustGetResult SecTrustGetResult "/System/Library/Frameworks/Security.framework/Versions/A/Security" 188 189 func SecTrustGetResult(trustObj CFRef, result CFRef) (CFRef, CFRef, error) { 190 var chain, info CFRef 191 ret := syscall(abi.FuncPCABI0(x509_SecTrustGetResult_trampoline), uintptr(trustObj), uintptr(unsafe.Pointer(&result)), 192 uintptr(unsafe.Pointer(&chain)), uintptr(unsafe.Pointer(&info)), 0, 0) 193 if int32(ret) != 0 { 194 return 0, 0, OSStatus{"SecTrustGetResult", int32(ret)} 195 } 196 return chain, info, nil 197 } 198 func x509_SecTrustGetResult_trampoline() 199 200 //go:cgo_import_dynamic x509_SecTrustEvaluateWithError SecTrustEvaluateWithError "/System/Library/Frameworks/Security.framework/Versions/A/Security" 201 202 func SecTrustEvaluateWithError(trustObj CFRef) (int, error) { 203 var errRef CFRef 204 ret := syscall(abi.FuncPCABI0(x509_SecTrustEvaluateWithError_trampoline), uintptr(trustObj), uintptr(unsafe.Pointer(&errRef)), 0, 0, 0, 0) 205 if int32(ret) != 1 { 206 errStr := CFErrorCopyDescription(errRef) 207 err := errors.New(CFStringToString(errStr)) 208 errCode := CFErrorGetCode(errRef) 209 CFRelease(errRef) 210 CFRelease(errStr) 211 return errCode, err 212 } 213 return 0, nil 214 } 215 func x509_SecTrustEvaluateWithError_trampoline() 216 217 //go:cgo_import_dynamic x509_SecTrustGetCertificateCount SecTrustGetCertificateCount "/System/Library/Frameworks/Security.framework/Versions/A/Security" 218 219 func SecTrustGetCertificateCount(trustObj CFRef) int { 220 ret := syscall(abi.FuncPCABI0(x509_SecTrustGetCertificateCount_trampoline), uintptr(trustObj), 0, 0, 0, 0, 0) 221 return int(ret) 222 } 223 func x509_SecTrustGetCertificateCount_trampoline() 224 225 //go:cgo_import_dynamic x509_SecTrustGetCertificateAtIndex SecTrustGetCertificateAtIndex "/System/Library/Frameworks/Security.framework/Versions/A/Security" 226 227 func SecTrustGetCertificateAtIndex(trustObj CFRef, i int) (CFRef, error) { 228 ret := syscall(abi.FuncPCABI0(x509_SecTrustGetCertificateAtIndex_trampoline), uintptr(trustObj), uintptr(i), 0, 0, 0, 0) 229 if ret == 0 { 230 return 0, OSStatus{"SecTrustGetCertificateAtIndex", int32(ret)} 231 } 232 return CFRef(ret), nil 233 } 234 func x509_SecTrustGetCertificateAtIndex_trampoline() 235 236 //go:cgo_import_dynamic x509_SecCertificateCopyData SecCertificateCopyData "/System/Library/Frameworks/Security.framework/Versions/A/Security" 237 238 func SecCertificateCopyData(cert CFRef) ([]byte, error) { 239 ret := syscall(abi.FuncPCABI0(x509_SecCertificateCopyData_trampoline), uintptr(cert), 0, 0, 0, 0, 0) 240 if ret == 0 { 241 return nil, errors.New("x509: invalid certificate object") 242 } 243 b := CFDataToSlice(CFRef(ret)) 244 CFRelease(CFRef(ret)) 245 return b, nil 246 } 247 func x509_SecCertificateCopyData_trampoline()