MYKeychain-iPhone.m
changeset 25 38c3c3923e1f
parent 23 39fec79de6e8
child 26 d9c2a06d4e4e
     1.1 --- a/MYKeychain-iPhone.m	Sun Jun 07 21:53:56 2009 -0700
     1.2 +++ b/MYKeychain-iPhone.m	Wed Jun 10 09:02:18 2009 -0700
     1.3 @@ -220,6 +220,22 @@
     1.4  }
     1.5  
     1.6  
     1.7 +- (BOOL) _verifyPublicKeyRef: (MYKeychainItemRef)itemRef {
     1.8 +    // Enumerating the keychain sometimes returns public-key refs that give not-found errors
     1.9 +    // when you try to use them for anything. As a workaround, detect these early on before
    1.10 +    // even creating a MYPublicKey:
    1.11 +    NSDictionary *info = $dict({(id)kSecValueRef, (id)itemRef},
    1.12 +    {(id)kSecReturnAttributes, $true});
    1.13 +    CFDictionaryRef attrs = NULL;
    1.14 +    OSStatus err = SecItemCopyMatching((CFDictionaryRef)info, (CFTypeRef*)&attrs);
    1.15 +    if (attrs) CFRelease(attrs);
    1.16 +    if (err == errSecItemNotFound) {
    1.17 +        Log(@"MYKeyEnumerator: Ignoring bogus(?) key with ref %p", itemRef);
    1.18 +        return NO;
    1.19 +    } else
    1.20 +        return YES;
    1.21 +}        
    1.22 +
    1.23  - (id) nextObject {
    1.24      if (!_results)
    1.25          return nil;
    1.26 @@ -229,7 +245,8 @@
    1.27          if (_itemClass == kSecAttrKeyClassPrivate) {
    1.28              _currentObject = [[MYPrivateKey alloc] initWithKeyRef: (SecKeyRef)found];
    1.29          } else if (_itemClass == kSecAttrKeyClassPublic) {
    1.30 -            _currentObject = [[MYPublicKey alloc] initWithKeyRef: (SecKeyRef)found];
    1.31 +            if ([self _verifyPublicKeyRef: found])
    1.32 +                _currentObject = [[MYPublicKey alloc] initWithKeyRef: (SecKeyRef)found];
    1.33          } else if (_itemClass == kSecAttrKeyClassSymmetric) {
    1.34              _currentObject = [[MYSymmetricKey alloc] initWithKeyRef: (SecKeyRef)found];
    1.35          } else if (_itemClass == kSecClassCertificate) {