// ===== CFBoolean ===== func convertBoolToCFBoolean(b bool) C.CFBooleanRef { // I don't think the CFBoolean constants have retain counts, // but just in case lets call CFRetain on them if b { return C.CFBooleanRef(C.CFRetain(C.CFTypeRef(C.kCFBooleanTrue))) } return C.CFBooleanRef(C.CFRetain(C.CFTypeRef(C.kCFBooleanFalse))) }
func (di *DeviceInfo) Open() (Device, error) { err := errors.New("device not found") var dev *osxDevice closeDM := iterateDevices(func(device C.IOHIDDeviceRef) bool { if getPath(device) == di.Path { res := C.IOHIDDeviceOpen(device, C.kIOHIDOptionsTypeSeizeDevice) if res == C.kIOReturnSuccess { C.CFRetain(C.CFTypeRef(device)) dev = &osxDevice{osDevice: device} err = nil C.IOHIDDeviceRegisterRemovalCallback(device, (C.IOHIDCallback)(unsafe.Pointer(C.deviceUnpluged)), unsafe.Pointer(dev)) } else { err = ioReturnToErr(res) } return false } return true }) if dev != nil { dev.closeDM = closeDM } return dev, err }
// FindIdentity ... // IMPORTANT: you have to C.CFRelease the returned items (one-by-one)!! // you can use the ReleaseIdentityWithRefList method to do that func FindIdentity(identityLabel string, isFullLabelMatch bool) ([]IdentityWithRefModel, error) { queryDict := C.CFDictionaryCreateMutable(nil, 0, nil, nil) defer C.CFRelease(C.CFTypeRef(queryDict)) C.CFDictionaryAddValue(queryDict, unsafe.Pointer(C.kSecClass), unsafe.Pointer(C.kSecClassIdentity)) C.CFDictionaryAddValue(queryDict, unsafe.Pointer(C.kSecMatchLimit), unsafe.Pointer(C.kSecMatchLimitAll)) C.CFDictionaryAddValue(queryDict, unsafe.Pointer(C.kSecReturnAttributes), unsafe.Pointer(C.kCFBooleanTrue)) C.CFDictionaryAddValue(queryDict, unsafe.Pointer(C.kSecReturnRef), unsafe.Pointer(C.kCFBooleanTrue)) var resultRefs C.CFTypeRef osStatusCode := C.SecItemCopyMatching(queryDict, &resultRefs) if osStatusCode != C.errSecSuccess { return nil, fmt.Errorf("Failed to call SecItemCopyMatch - OSStatus: %d", osStatusCode) } defer C.CFRelease(C.CFTypeRef(resultRefs)) identitiesArrRef := C.CFArrayRef(resultRefs) identitiesCount := C.CFArrayGetCount(identitiesArrRef) if identitiesCount < 1 { return nil, fmt.Errorf("No Identity (certificate + related private key) found in your Keychain!") } log.Debugf("identitiesCount: %d", identitiesCount) // filter the identities, by label retIdentityRefs := []IdentityWithRefModel{} for i := C.CFIndex(0); i < identitiesCount; i++ { aIdentityRef := C.CFArrayGetValueAtIndex(identitiesArrRef, i) log.Debugf("aIdentityRef: %#v", aIdentityRef) aIdentityDictRef := C.CFDictionaryRef(aIdentityRef) log.Debugf("aIdentityDictRef: %#v", aIdentityDictRef) lablCSting := C.CString("labl") defer C.free(unsafe.Pointer(lablCSting)) vrefCSting := C.CString("v_Ref") defer C.free(unsafe.Pointer(vrefCSting)) labl, err := getCFDictValueUTF8String(aIdentityDictRef, C.CFTypeRef(convertCStringToCFString(lablCSting))) if err != nil { return nil, fmt.Errorf("FindIdentity: failed to get 'labl' property: %s", err) } log.Debugf("labl: %#v", labl) if isFullLabelMatch { if labl != identityLabel { continue } } else { if !strings.Contains(labl, identityLabel) { continue } } log.Debugf("Found identity with label: %s", labl) vrefRef, err := getCFDictValueRef(aIdentityDictRef, C.CFTypeRef(convertCStringToCFString(vrefCSting))) if err != nil { return nil, fmt.Errorf("FindIdentity: failed to get 'v_Ref' property: %s", err) } log.Debugf("vrefRef: %#v", vrefRef) // retain the pointer vrefRef = C.CFRetain(vrefRef) // store it retIdentityRefs = append(retIdentityRefs, IdentityWithRefModel{ KeychainRef: vrefRef, Label: labl, }) } return retIdentityRefs, nil }