Create p12 identity from pem cert string & private key during iOS runtime

I have a unique need here and hope there is someone out there that might be of help. There is a backend server that will send an x509 certificate and private key (as strings) after the mobile apps on-boarding process.

Additionally, the app includes an AWS SDK that is used to talk to their IoT system. This SDK requires PKCS12 certificate format to pass authentication. (I believe the common method is to have bundled the cert into the app which is not an option for me here sadly)

I suspect it may be possible to use some openSSL iOS framework to do this conversion at runtime but have not personally tried it yet as my go-to is usually trying things first with Apples APIs.

So my question becomes is there a way to meet this requirement using any of the security APIs or other APIs that apple has like swift-nio-ssl? Thank you very much for your time.

Best, Michael

Answered by DTS Engineer in 791388022

This is something you should escalate via the support channel for that SDK. My best guess is that:

  • They’re confusing certificate and digital identity, meaning that the certificateId parameter actually identifies the digital identity in your keychain.

  • They’re expecting your to import the identity into your keychain and then pass in some identifier for that, like the name in the digital identity’s certificate, or perhaps a hash of it, or perhaps a keychain persistent reference.

However, that’s just speculation. Unless this code in open source — in which case you can trace the code to find out how its using this parameter — the only reliable option is to ask the authors.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I can confirm that the iOS SDK has no API that’ll export a digital identity to a PKCS#12 blob.

My general advice is that SDK authors should accept an identity object (SecIdentity) which avoids the requirement for this. This is, for example, how URLSession works.

If you’re working with an SDK that requires a PKCS#12 blob then you’ll need to find a third-party library to do this export. I’ve never gone looking for such a library, so I can’t offer concrete advice on that front.

It’s possible that Swift Certificates might have code for this. If not, you could certainly build it from SwiftASN1. However, that’s not an easy path to walk.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Whoa, Quinn responded to this! That is very helpful, thank you for taking the time to reply.

The iOS demos for this needed AWS SDK demonstrated calling two functions. One to import the bundled p12 and another to connect to the IoT service. That connect strikes me as interesting given your advice around the SecIdentity. Their documentation on that is as follows.

/**
 Initialises the MQTT session and connects to AWS IoT using certificate-based mutual authentication

 @return true if initialise finished with success

 @param clientId The Client Identifier identifies the Client to the Server.

 @param cleanSession specifies if the server should discard previous session information.

 @param certificateId contains the ID of the certificate to use in the connection; must be in the keychain
 
 @param callback When new mqtt session status is received callback will be called with new connection status.

 */
- (BOOL)connectWithClientId:(NSString *)clientId
               cleanSession:(BOOL)cleanSession
              certificateId:(NSString *)certificateId
             statusCallback:(void (^)(AWSIoTMQTTStatus status))callback;

I'm speculating that "certificateId" parameter may be the kSecValueRef of the identity they imported...

I am wondering if I might be able to turn our servers pem cert string into DER-encoded data and then create a SecIdentity in Keychain by combining it with the private key to use in Amazon's connect function. (https://developer.apple.com/documentation/security/certificate_key_and_trust_services/certificates/getting_a_certificate)

Can you see any pitfalls with this approach that I should be aware of? Is that even possible lol

This is something you should escalate via the support channel for that SDK. My best guess is that:

  • They’re confusing certificate and digital identity, meaning that the certificateId parameter actually identifies the digital identity in your keychain.

  • They’re expecting your to import the identity into your keychain and then pass in some identifier for that, like the name in the digital identity’s certificate, or perhaps a hash of it, or perhaps a keychain persistent reference.

However, that’s just speculation. Unless this code in open source — in which case you can trace the code to find out how its using this parameter — the only reliable option is to ask the authors.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Create p12 identity from pem cert string & private key during iOS runtime
 
 
Q