2009-07-27 3 views
5

Я пытаюсь получить атрибуты элемента keychain. Этот код должен искать все доступные атрибуты, а затем распечатывать их теги и содержимое.Получение атрибутов объектов связки ключей

Согласно the docs, я должен видеть теги типа 'cdat', но вместо этого они выглядят как индекс (т. Е. Первый тег равен 0, а следующий - 1). Это делает его довольно бесполезным, так как я не могу сказать, какой атрибут является тем, который я ищу.

SecItemClass itemClass; 
    SecKeychainItemCopyAttributesAndData(itemRef, NULL, &itemClass, NULL, NULL, NULL); 

    SecKeychainRef keychainRef; 
    SecKeychainItemCopyKeychain(itemRef, &keychainRef); 

    SecKeychainAttributeInfo *attrInfo; 
    SecKeychainAttributeInfoForItemID(keychainRef, itemClass, &attrInfo); 

    SecKeychainAttributeList *attributes; 
    SecKeychainItemCopyAttributesAndData(itemRef, attrInfo, NULL, &attributes, 0, NULL); 

    for (int i = 0; i < attributes->count; i ++) 
    { 
     SecKeychainAttribute attr = attributes->attr[i]; 
     NSLog(@"%08x %@", attr.tag, [NSData dataWithBytes:attr.data length:attr.length]); 
    } 

    SecKeychainFreeAttributeInfo(attrInfo); 
    SecKeychainItemFreeAttributesAndData(attributes, NULL); 
    CFRelease(itemRef); 
    CFRelease(keychainRef); 

ответ

1

Я думаю, что документация ведет к путанице.

Число, которое я вижу, выглядит keychain item attribute constants for keys.

Однако SecKeychainItemCopyAttributesAndData возвращает структуру SecKeychainAttributeList, которая содержит массив SecKeychainAttributes. От TFD:

tag 4-байтовый атрибут тега. См. «Константы атрибута элемента привязки ключей» для допустимых типов атрибутов.

Константы атрибута (разновидности «для ключей») представляют собой 4-значные значения, которые я ожидал увидеть.

3

Здесь вы должны сделать две вещи. Во-первых, вам нужно обрабатывать «общие» itemClasses перед вызовом SecKeychainAttributeInfoForItemID ...

switch (itemClass) 
{ 
    case kSecInternetPasswordItemClass: 
     itemClass = CSSM_DL_DB_RECORD_INTERNET_PASSWORD; 
     break; 
    case kSecGenericPasswordItemClass: 
     itemClass = CSSM_DL_DB_RECORD_GENERIC_PASSWORD; 
     break; 
    case kSecAppleSharePasswordItemClass: 
     itemClass = CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD; 
     break; 
    default: 
     // No action required 
} 

Во-вторых, вам нужно преобразовать attr.tag из FourCharCode в строку, т.е.

NSLog(@"%c%c%c%c %@", 
    ((char *)&attr.tag)[3], 
    ((char *)&attr.tag)[2], 
    ((char *)&attr.tag)[1], 
    ((char *)&attr.tag)[0], 
    [[[NSString alloc] 
     initWithData:[NSData dataWithBytes:attr.data length:attr.length] 
     encoding:NSUTF8StringEncoding] 
    autorelease]]); 

Обратите внимание, что я также выводил данные как строку - это почти всегда кодированные UTF8 данные.

+0

Спасибо, что объяснили, как обрабатывать общие классы элементов. Документация для 'SecKeychainAttributeInfoForItemID' оставляет желать лучшего. –

Смежные вопросы