Re: Keychain issues with public key on iOS
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