Need help importing public keys into iOS Keychain
Need help importing public keys into iOS Keychain
- Subject: Need help importing public keys into iOS Keychain
- From: Jens Alfke <email@hidden>
- Date: Thu, 18 Aug 2011 13:38:29 -0700
{Apologies for the slightly off-topic post, but the apple-cdsa list has been pretty dead for a long time, and I’m not confident I’ll get any answer there, so I’m cross-posting here too. And I think it’s not too unlikely that some people here who develop on iOS have done some Keychain stuff with public keys.}
I’m stymied by the simple(?) task of importing a public key from external data into the iOS Keychain. I’m able to get a SecKeyRef, but it isn’t good for anything — if I try to access its key data or attributes, for example, I just get back an errSecItemNotFound.
I’ve boiled it down to the following test case. The file “publicKey” contains 140 bytes of data, a previously-generated 1024-bit RSA public key stored in BSAFE format. The failure is on the second-to-last line — the call to SecItemCopyMatching to get the key’s data returns errSecItemNotFound, despite being given a valid SecKeyRef. (And that call works fine when given a key that was locally generated by SecKeyGeneratePair, so I believe the code is correct.)
I’ve looked at CryptoExercise; in fact that’s where most of this code comes from. Any clues? I’m stumped. (And no, I never got this kind of stuff to work in MYCrypto either. If I figure it out now, I promise to put the fix there too.)
—Jens
void TestRawKeyImport(void) {
NSData* keyData = [NSData dataWithContentsOfFile: @"publicKey"];
// Import the key:
// NOTE: kSecReturnRef doesn't work -- returns noErr but the ref is NULL.
NSMutableDictionary* attrs = [NSMutableDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassKey, (id)kSecClass,
(id)kSecAttrKeyTypeRSA, (id)kSecAttrKeyType,
(id)kSecAttrKeyClassPublic, (id)kSecAttrKeyClass,
keyData, (id)kSecValueData,
(id)kCFBooleanTrue, (id)kSecReturnPersistentRef,
nil];
CFTypeRef keyPersistentRef;
OSStatus err = SecItemAdd((CFDictionaryRef)attrs, &keyPersistentRef);
NSCAssert(!err, @"Error %i from SecItemAdd", err);
NSCAssert(keyPersistentRef != NULL, @"Invalid keyPersistentRef");
// Next convert the persistent ref into a regular one:
SecKeyRef keyRef;
NSMutableDictionary* query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
(id)keyPersistentRef, (id)kSecValuePersistentRef,
(id)kCFBooleanTrue, (id)kSecReturnRef,
nil];
err = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef*)&keyRef);
NSCAssert(!err, @"Error %i from 1st SecItemCopyMatching", err);
NSCAssert(keyRef != NULL, @"Invalid keyRef");
// Now get the key's data back:
query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassKey, (id)kSecClass,
(id)kSecAttrKeyTypeRSA, (id)kSecAttrKeyType,
(id)kSecAttrKeyClassPublic, (id)kSecAttrKeyClass,
(id)keyRef, (id)kSecValueRef,
(id)kCFBooleanTrue, (id)kSecReturnData,
nil];
NSData* data;
err = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef*)&data);
NSCAssert(!err, @"Error %i from 2nd SecItemCopyMatching", err);
NSCAssert([data isEqual: keyData], @"Data mismatch");
}
PS: Here’s the base64-encoded contents of the “publicKey” file:
MIGJAoGBANpR07kU+2zqGZ9Q/YdOHrCPY2q+0JOpTUrYNs8wxLAzjWlq1xhOj4+hDgpF9b5uMEi47b7JnZ90gR5egdDAPIBoMBt3ft60udrLaVlxmjijAwCVjrP/eS0/K0Of8mKseVnoJYGnP7KUxVeQpfZWndIL8VFsw+Nx+zLG2JsezB9TAgMBAAE=
And here’s a hex dump:
00000000 30 81 89 02 81 81 00 da 51 d3 b9 14 fb 6c ea 19 |0.......Q....l..|
00000010 9f 50 fd 87 4e 1e b0 8f 63 6a be d0 93 a9 4d 4a |.P..N...cj....MJ|
00000020 d8 36 cf 30 c4 b0 33 8d 69 6a d7 18 4e 8f 8f a1 |.6.0..3.ij..N...|
00000030 0e 0a 45 f5 be 6e 30 48 b8 ed be c9 9d 9f 74 81 |..E..n0H......t.|
00000040 1e 5e 81 d0 c0 3c 80 68 30 1b 77 7e de b4 b9 da |.^...<.h0.w~....|
00000050 cb 69 59 71 9a 38 a3 03 00 95 8e b3 ff 79 2d 3f |.iYq.8.......y-?|
00000060 2b 43 9f f2 62 ac 79 59 e8 25 81 a7 3f b2 94 c5 |+C..b.yY.%..?...|
00000070 57 90 a5 f6 56 9d d2 0b f1 51 6c c3 e3 71 fb 32 |W...V....Ql..q.2|
00000080 c6 d8 9b 1e cc 1f 53 02 03 01 00 01 |......S.....|_______________________________________________
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