I have a p12 file, from which I extract the PrivateKey, PublicKey both as SecKeyRef and the certificate as SecCertificateRef.
The P12 file have a ECDSA PrivateKey that I need to use to sign data (ECC).
So I'm using a suggested library: https://github.com/ricmoo/GMEllipticCurveCrypto
But I need to feed the library with the keys on Base64 or NSData, I can't feed SecKeyRef. I managed to extract the NSData for the publicKey using the methods provided here, it works.
But I can't find any way to convert a SecRefKey that points to a privateKey to NSData. Any ideas on how to do this, OR, sign and verify data in iOS using ECC with SecKeyRefs.
For reference, this method converts the P12 into iOS SecRefs:
- (BOOL)storeDetailsForP12CertificateData:(NSData *)certData password:(NSString*)pass identifier:(NSString*)identifier{
SecKeyRef publicKey, privateKey;
SecCertificateRef certRef;
//Extract keys and Certificate
NSMutableDictionary * options = [[NSMutableDictionary alloc] init];
[options setObject:pass forKey:(id)kSecImportExportPassphrase];
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = SecPKCS12Import((CFDataRef) certData,
(CFDictionaryRef)options, &items);
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
SecIdentityRef identityApp =
(SecIdentityRef)CFDictionaryGetValue(identityDict,
kSecImportItemIdentity);
assert(securityError == noErr);
//get private key
SecIdentityCopyPrivateKey(identityApp, &privateKey);
//get certificate
SecIdentityCopyCertificate(identityApp, &certRef);
//evaluate certificate.
CFArrayRef certs = CFArrayCreate(kCFAllocatorDefault, (const void **) &certRef, 1, NULL);
SecPolicyRef policy = SecPolicyCreateBasicX509();
SecTrustRef trust;
SecTrustCreateWithCertificates(certs, policy, &trust);
(CFRelease(certs));
SecTrustResultType trustResult;
SecTrustEvaluate(trust, &trustResult);
//get publickey
publicKey = SecTrustCopyPublicKey(trust);
//clean memory
(CFRelease(trust));
(CFRelease(policy));
if (!publicKey || !privateKey || !certRef) {
return NO;
} else {
KeyData *details = [[KeyData alloc] init];
details.publicKey = publicKey;
details.privateKey = privateKey;
details.certificate = certRef;
details.fileData = certData;
return YES;
}
}