sto usando questo codice per elencare tutte le chiavi private e ottenere alcune informazioni su di loro, utilizzando API framework di sicurezza di Apple:SecKeychainItemCopyContents in segfault su chiavi private
int main(int argc, const char * argv[]) {
const void *keys[] = { kSecClass, kSecReturnRef, kSecMatchLimit, kSecAttrKeyClass};
const void *values[] = { kSecClassKey, kCFBooleanTrue, kSecMatchLimitAll, kSecAttrKeyClassPrivate};
CFDictionaryRef searchDict = CFDictionaryCreate(
NULL,
keys, values, sizeof(keys)/sizeof(keys[0]),
NULL, NULL
);
checkAlloc(searchDict);
CFArrayRef items;
check(SecItemCopyMatching(searchDict, (CFTypeRef *)&items));
for(int i=0; i<CFArrayGetCount(items); i++) {
SecKeychainItemRef item = (SecKeychainItemRef) CFArrayGetValueAtIndex(items, i);
CFShow((CFTypeRef)item);
SecItemClass cls;
SecKeychainAttributeList attrs;
UInt32 dataLen;
void* data;
check(SecKeychainItemCopyContent(item, &cls, &attrs, &dataLen, &data));
printf("Key: %d\n", (int)dataLen);
check(SecKeychainItemFreeContent(&attrs, data));
}
CFRelease(items);
CFRelease(searchDict);
return 0;
}
La chiamata alla SecKeychainItemCopyContent
segfaults, anche se nessuno di i puntatori che ho passato non sono validi.
Le CFShow
stampa linee simili a <SecKey 0x7fb4d9d01420 [0x7fff74790ed0]>
, quindi item
dovrebbe essere un SecKeyRef
, ma il documentation for it dice che è OK per utilizzare un SecKeyRef
come SecKeychainItemRef
se la chiave è in un portachiavi. Tuttavia, non vedo alcuna funzione per trovare se la chiave è in un portachiavi, quindi non posso convalidare che le chiavi restituite possano essere utilizzate come tali.
Cosa sto facendo di sbagliato qui?
Il secondo esempio è errato perché si tenta di stampare 'dataLen' prima che sia inizializzato. Non vedo come azzerare 'attrs' prima di passarlo farà la differenza, dato che' SecKeychainItemCopyContent' dovrebbe scrivere solo su di esso e non ha motivo di dereferenziare il puntatore 'attr'. –