+
+
+
+
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecKey.h>
+
+SecKeyRef create_private_key_from_der(bool ecdsa, const unsigned char *pkey_der, size_t pkey_der_len)
+{
+ SecKeyRef privKey;
+ CFErrorRef error = NULL;
+ CFDataRef keyData = CFDataCreate(kCFAllocatorDefault, pkey_der, pkey_der_len);
+ CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
+ CFDictionarySetValue(parameters, kSecAttrKeyType, ecdsa?kSecAttrKeyTypeECSECPrimeRandom:kSecAttrKeyTypeRSA);
+ CFDictionarySetValue(parameters, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
+ privKey = SecKeyCreateWithData(keyData, parameters, &error);
+ CFReleaseNull(keyData);
+ CFReleaseNull(parameters);
+ CFReleaseNull(error);
+ return privKey;
+}
+
+CFArrayRef chain_from_der(bool ecdsa, const unsigned char *pkey_der, size_t pkey_der_len, const unsigned char *cert_der, size_t cert_der_len)
+{
+ SecKeyRef pkey = NULL;
+ SecCertificateRef cert = NULL;
+ SecIdentityRef ident = NULL;
+ CFArrayRef items = NULL;
+
+ require(pkey = create_private_key_from_der(ecdsa, pkey_der, pkey_der_len), errOut);
+ require(cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, cert_der, cert_der_len), errOut);
+ require(ident = SecIdentityCreate(kCFAllocatorDefault, cert, pkey), errOut);
+ require(items = CFArrayCreate(kCFAllocatorDefault, (const void **)&ident, 1, &kCFTypeArrayCallBacks), errOut);
+
+errOut:
+ CFReleaseSafe(pkey);
+ CFReleaseSafe(cert);
+ CFReleaseSafe(ident);
+ return items;
+}
+