• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Keychain issues with public key on iOS
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Keychain issues with public key on iOS


  • Subject: Re: Keychain issues with public key on iOS
  • From: Jens Alfke <email@hidden>
  • Date: Fri, 08 Feb 2013 21:35:00 -0800

On Feb 8, 2013, at 1:31 PM, Damien Cooke <email@hidden> wrote:

> I am trying to put a public key into the ios keychain so I can get a SecKeyRef to use to verify a signature.

Oh dear. Any time I have to deal with the iOS keychain APIs I get either enraged or sick to my stomach or both. Seriously.

> So I strip the begin and end markers plus remove all the \n (is this correct?)

And also base64-decode it, right? It definitely won’t work unless you do that too.
(This looks like a PEM-encoded key; to make sure, you could look up the docs on that format. But I think you’ve basically got it right.)

> The SecItemAdd succeeds but I can never get it out again as SecItemCopyMatching always returns null in the ref pointer but returns errSecSuccess so I am really confused.

Yeah, this is a good example of where my rage/ulcer reactions come from. The SecItem API is one of the worst things ever: it’s incredibly vague and under-documented, and just does not seem to behave in reasonable ways or return informative errors.

Here’s some code I have for this purpose. It’s been about a year since I’ve worked with it so I’m no longer clear on all the details.
One thing to note is that the app this is for is using the SHA-1 digest of the key as the “application tag” property for looking up the key afterwards, thus the usage of the digest in the parameters to SecItemAdd.
Also, the weird stuff about converting the persistent ref to a regular one is to work around a bug(?) in the keychain code, where you apparently have to request a persistent ref when adding a new item, but then can’t work with that ref unless you convert it to a regular one.
This code is the boiled-down end product of literally about ten cumulative hours of frustration and experimentation, so it may be messier than it needs to be. If someone knows how to do this more elegantly, I’m all ears.

—Jens

PS: The apple-cdsa list is the appropriate one for talking about this stuff, although I’ve noticed that the Apple engineers there never seem to answer detailed questions about the keychain APIs :-p

    SHA1Digest digest = ComputeSHA1(keyData);  // this is a fn of mine that just calls CommonCrypto
    NSData* digestData = [NSData dataWithBytes: &digest length: sizeof(digest)];

    NSMutableDictionary* attrs = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                  (id)kSecClassKey,        (id)kSecClass,
                                  (id)kSecAttrKeyTypeRSA,  (id)kSecAttrKeyType,
                                  (id)kSecAttrKeyClassPublic, (id)kSecAttrKeyClass,
                                  digestData,              (id)kSecAttrApplicationTag, //????
                                  digestData,              (id)kSecAttrApplicationLabel,
                                  keyData,                 (id)kSecValueData,
                                  (id)kCFBooleanTrue,      (id)kSecReturnPersistentRef,
                                  nil];
    CFTypeRef keyRef = NULL;
    OSStatus err = SecItemAdd((CFDictionaryRef)attrs, &keyRef);
    if (err) {
        if (err != errSecDuplicateItem)
            return err;
        // Already have a key with this digest, so look it up to get its ref:
        [attrs removeObjectForKey: (id)kSecValueData];
        [attrs setObject: digestData forKey: (id)kSecAttrApplicationLabel];//??
        [attrs removeObjectForKey: (id)kSecReturnPersistentRef];
        [attrs setObject: (id)kCFBooleanTrue forKey: (id)kSecReturnRef];
        return SecItemCopyMatching((CFDictionaryRef)attrs, (CFTypeRef*)outPublicKey);
    }

    // Added it -- now convert the persistent ref to a regular one:
    NSMutableDictionary* query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                  (id)kSecClassKey,        (id)kSecClass,
                                  (id)kSecAttrKeyTypeRSA,  (id)kSecAttrKeyType,
                                  digestData,              (id)kSecAttrApplicationTag, //????
                                  //(id)keyRef, (id)kSecValuePersistentRef,
                                  (id)kCFBooleanTrue, (id)kSecReturnRef,
                                  nil];
    //CFRelease(keyRef);
    return SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef*)outPublicKey);

_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden


  • Follow-Ups:
    • Re: Keychain issues with public key on iOS
      • From: Damien Cooke <email@hidden>
References: 
 >Keychain issues with public key on iOS (From: Damien Cooke <email@hidden>)

  • Prev by Date: Re: Timeline control like in ScreenFlow...how i can implement?
  • Next by Date: Managing relationships by fetching related objects within subclass of NSManagedObject
  • Previous by thread: Keychain issues with public key on iOS
  • Next by thread: Re: Keychain issues with public key on iOS
  • Index(es):
    • Date
    • Thread