in aws_signing_helper/cert_store_signer_darwin.go [47:116]
func GetMatchingCertsAndIdentity(certIdentifier CertIdentifier) ([]C.SecIdentityRef, []C.SecCertificateRef, []CertificateContainer, error) {
queryMap := map[C.CFTypeRef]C.CFTypeRef{
C.CFTypeRef(C.kSecClass): C.CFTypeRef(C.kSecClassIdentity),
C.CFTypeRef(C.kSecReturnRef): C.CFTypeRef(C.kCFBooleanTrue),
C.CFTypeRef(C.kSecMatchLimit): C.CFTypeRef(C.kSecMatchLimitAll),
}
query := mapToCFDictionary(queryMap)
if query == 0 {
return nil, nil, nil, errors.New("error creating CFDictionary")
}
defer C.CFRelease(C.CFTypeRef(query))
var absResult C.CFTypeRef
if err := osStatusError(C.SecItemCopyMatching(query, &absResult)); err != nil {
if err == errSecItemNotFound {
return nil, nil, nil, errors.New("unable to find matching identity in cert store")
}
return nil, nil, nil, err
}
defer C.CFRelease(C.CFTypeRef(absResult))
aryResult := C.CFArrayRef(absResult)
// identRefs aren't owned by us initially
numIdentRefs := C.CFArrayGetCount(aryResult)
identRefs := make([]C.CFTypeRef, numIdentRefs)
C.CFArrayGetValues(aryResult, C.CFRange{0, numIdentRefs}, (*unsafe.Pointer)(unsafe.Pointer(&identRefs[0])))
var certContainers []CertificateContainer
var certRefs []C.SecCertificateRef
var outputIdentRefs []C.SecIdentityRef
var isMatch bool
certContainerIndex := 0
for _, curIdentRef := range identRefs {
curCertRef, err := getCertRef(C.SecIdentityRef(curIdentRef))
if err != nil {
return nil, nil, nil, errors.New("unable to get cert ref")
}
curCert, err := exportCertRef(curCertRef)
if err != nil {
if Debug {
log.Printf("unable to parse certificate with error (%s) - skipping\n", err)
}
goto nextIteration
}
// Find whether there is a matching certificate
isMatch = certMatches(certIdentifier, *curCert)
if isMatch {
certContainers = append(certContainers, CertificateContainer{certContainerIndex, curCert, ""})
certContainerIndex += 1
// Assign to certRef and identRef at most once in the loop
// Both values are only useful if there is exactly one match in the certificate store
// When creating a signer, there has to be exactly one matching certificate
certRefs = append(certRefs, curCertRef)
// Note that only the SecIdentityRef needs to be retained since it was neither created nor copied
C.CFRetain(C.CFTypeRef(curIdentRef))
outputIdentRefs = append(outputIdentRefs, C.SecIdentityRef(curIdentRef))
}
nextIteration:
}
if Debug {
log.Printf("found %d matching identities\n", len(certContainers))
}
// It's the caller's responsibility to release each SecIdentityRef after use.
return outputIdentRefs, certRefs, certContainers, nil
}