2015-06-24 9 views
5

मैं सभी निजी कुंजी की सूची और उनके बारे में कुछ जानकारी मिल, एप्पल के सुरक्षा तंत्र का एपीआई का उपयोग कर के लिए इस कोड का उपयोग कर रहा:SecKeychainItemCopyContents निजी कुंजी पर segfaulting है

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; 
} 

SecKeychainItemCopyContent segfaults करने के लिए कॉल, यहां तक ​​कि में से कोई भी, हालांकि जिन पॉइंटर्स में मैं गुजर रहा हूं वे अमान्य हैं।

CFShow प्रिंट <SecKey 0x7fb4d9d01420 [0x7fff74790ed0]> के समान लाइनों, इसलिए item एक SecKeyRef होना चाहिए, लेकिन documentation for it कहना है कि यह करता है, तो कुंजी एक-चेन में एक SecKeyRef एक SecKeychainItemRef के रूप में उपयोग करने के लिए ठीक है। हालांकि, मुझे यह पता लगाने के लिए कोई फ़ंक्शन नहीं दिख रहा है कि कुंजी कुंजीपटल में है या नहीं, इसलिए मैं मान्य नहीं कर सकता कि लौटाई गई चाबियाँ इस तरह उपयोग की जा सकती हैं।

मैं यहाँ क्या गलत कर रहा हूं?

उत्तर

0

डेटा और/या विशेषताओं को देखते हुए कीचेन आइटम में संग्रहीत कॉपी करने के समारोह SecKeychainItemCopyContent() 3 पैरामीटर प्रकार की तरह साथ SecKeychainAttributeList *attrList है,

struct SecKeychainAttributeList 
    { 
    UInt32 count; 
    SecKeychainAttribute *attr; 
    }; 

इस में/बाहर परम attrList के लिए: इनपुट पर, यह उन विशेषताओं की सूची है जिन्हें आप पुनर्प्राप्त करने का अनुरोध करते हैं। आउटपुट पर, गुण भर दिए जाते हैं। NULL पास करें यदि किसी भी विशेषता को पुनर्प्राप्त करने की आवश्यकता नहीं है, या आपको एक विशेषता सूची पास करने की आवश्यकता है। यह तर्कों में इन दो निर्दिष्ट पासों में से एक होना चाहिए। इसे छोड़ दें uninitialized समस्या पैदा कर सकता है, जैसे segfaulting।

तो, कृपया इस तरह प्रयास करें, इसे अच्छी तरह से काम करना चाहिए।

SecKeychainAttributeList attrs = {0, NULL}; 
//... 
check(SecKeychainItemCopyContent(item, &cls, &attrs, &dataLen, &data)); 

या

//SecKeychainAttributeList attrs ; 
//... 
check(SecKeychainItemCopyContent(item, &cls, NULL, &dataLen, &data)); 
printf("Key: %d\n", (int)dataLen); 
check(SecKeychainItemFreeContent(NULL, data)); 

मामले में गुण सूची प्राप्त करने की जरूरत थी, नमूना कोड इस प्रकार हो सकता है,

SecKeychainAttributeList xlist; 
SecKeychainAttribute outList[] = 
{ 
    {kSecAddressItemAttr,}, 
    {kSecAccountItemAttr,}, 
    {kSecVolumeItemAttr,}, 
    {kSecProtocolItemAttr} 
}; 

xlist.count = sizeof(outList)/sizeof(outList[0]); 
xlist.attr = outList; 

//... 
err = SecKeychainItemCopyContent (itemRef, nil, &xlist, &len, &outData); 
//... 
+0

दूसरा उदाहरण गलत है क्योंकि आप प्रारंभ होने से पहले 'डेटालेन' प्रिंट करने का प्रयास करते हैं। मैं नहीं देखता कि इसमें प्रवेश करने से पहले शून्य-एंटर्स 'एटर्स' कैसे एक फर्क पड़ेगा, क्योंकि 'सेककेकेन इटैमकॉपीकंटेंट' केवल इसे लिखना चाहिए और 'attr' पॉइंटर को कम करने का कोई कारण नहीं है। –

1

जाहिर है, SecKeychainAttributeList पैरामीटर न सिर्फ एक है उत्पादन। यह एक इनपुट भी है जिसमें प्राप्त करने के गुण हैं।

SecKeychainAttributeList अनियंत्रित attrs->attr पॉइंटर और क्रैश किए गए। पॉइंटर को NULL पर प्रारंभ करने से समस्या ठीक हो जाती है।

संबंधित मुद्दे