14

In order to send and receive encrypted messages from/to the iPhone I need to read a public key (server's public key) PEM file and create a SecKeyRef (later I could even store it on the keychain in order not to create it again).

This is my current workflow:

  1. On the server: Create a P12 file with the user's certificate and private key. Store the user's public key on the server's keychain.
  2. On the iPhone: Retrieve the P12 file from the server, use the password to open it and store the private key on the keychain.
  3. On the iPhone: Retrieve a PEM file with the server's public key from the server. Create a SecKeyRef and store it on the keychain
  4. On the iPhone: use both keys to send/receive encrypted messages to/from the server.
  5. Live happily ever after.

I'm having problems with 3, as I cannot create a SecKeyRef from the PEM file data. I cannot find any documentation on how to do it, Did anybody had the same problem? Any hints? As I cannot find any code examples or documentation on this it feels that I'm doing something wrong...

thanks!

pgb
  • 24,813
  • 12
  • 83
  • 113
TehJabbit
  • 239
  • 1
  • 2
  • 8
  • Can you please tell me how can I store and retrieve the keys? How to refer to the stored keys in the keychain? I have nearly the same scenario like you. I want to generate the key pair in iPhone and store in the keychain. Then later wanna retrieve it. I know how generate but could not successfully store and retrieve from keychain. – karim Aug 19 '10 at 15:59
  • I mostly have a problem with 5. ... :sad noises: ... – vatbub Aug 06 '21 at 08:52

1 Answers1

7

You should be able to interpret a DER encoded pem and get a cert using SecCertificateCreateWithData() from which you can then extract a key;

NSData *myCertData = ....;

SecCertificateRef cert = SecCertificateCreateWithData (kCFAllocatorDefault, myCertData); 
CFArrayRef certs = CFArrayCreate(kCFAllocatorDefault, (const void **) &cert, 1, NULL); 

SecTrustRef trust;
SecTrustCreateWithCertificates(certs, policy, &trust);
SecTrustResultType trustResult;
SecTrustEvaluate(trust, &trustResult);
SecKeyRef pub_key_leaf = SecTrustCopyPublicKey(trust);
Louis Gerbarg
  • 43,356
  • 8
  • 80
  • 90
  • 1
    Thanks! Do you know which keys/values should I use to store/retrieve this key from the keychain using SecItemAdd/SecItemCopyMatching? – TehJabbit Oct 28 '09 at 10:52
  • 3
    How do I create a policy object? the code snippet does not mention anything about policy? – futureelite7 Jan 22 '10 at 10:52
  • 2
    How did we get this myCertData? Say I have a pub.pem file generated from openssl command, then shall I use this code: NSData *myCertData = [[NSData alloc] initWithContentsOfFile:@"public.pem"]; ? – Devarshi May 16 '14 at 19:54
  • One way to create a policy file: SecPolicyRef policy = SecPolicyCreateBasicX509(); – Isaac Paul Sep 03 '14 at 23:29
  • myCertData is NSData*, but SecCertificateCreateWithData expects CFDataRef. CFDataRef myCertDataRef = (__bridge CFDataRef) myCertData; – Chuck Krutsinger Jan 20 '15 at 15:38