Reputation: 33192
I have some C++ code that uses the Apple Secure Transport and Keychain APIs to create an SSL/TLS server (CLI). The code is already able to load the server cert by a user-provided finger-print from the existing keychain.
However, for compatibility reasons, I'd like to enable the server to also load a cert + key (PEM) from a user-provided set of files.
To be clear: I do not want to import the file into the user's keychain, but instead just use it in that "session".
Basically, fill in the XXX:
bool AppleTLSContext::addCredentialFile(const std::string& certfile,
const std::string& keyfile)
{
if (tryAsFingerprint(certfile)) {
return true;
}
// XXX
}
It seems one can use SecItemImport
and/or SecKeychainItemCreateFromContent
to import the cert/key into a throw-away keychain with a random password.
SecKeychainCreate
does require a path)I'm looking for a solution that will run at least on OSX 10.6+ once compiled (#ifdef
s are OK).
Upvotes: 0
Views: 603
Reputation: 338
If both files can be clubbed and converted into pkcs 12 format then SecPKCS12Import method can be used.
But SecPKCS12Import does not work properly in root context. I do not know reason of this misbehaviour.
OSStatus extractIdentityAndTrust(CFDataRef inPKCS12Data,
SecIdentityRef *outIdentity,
SecTrustRef *outTrust,
CFStringRef keyPassword)
{
OSStatus securityError = errSecSuccess;
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { keyPassword };
CFDictionaryRef optionsDictionary = NULL;
optionsDictionary = CFDictionaryCreate(
NULL, keys,
values, (keyPassword ? 1 : 0),
NULL, NULL);
CFArrayRef items = NULL;
securityError = SecPKCS12Import(inPKCS12Data,
optionsDictionary,
&items);
if (securityError == 0)
{
CFDictionaryRef myIdentityAndTrust = (CFDictionaryRef)CFArrayGetValueAtIndex (items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue (myIdentityAndTrust,
kSecImportItemIdentity);
CFRetain(tempIdentity);
*outIdentity = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
CFRetain(tempTrust);
*outTrust = (SecTrustRef)tempTrust;
}
if (optionsDictionary)
CFRelease(optionsDictionary);
if (items)
CFRelease(items);
return securityError;
}
Anand
Upvotes: 1