// openssl x509 -inform der -outform pem -in public_key.der -out public_key.pem
// openssl pkcs12 -export -in public_key.pem -inkey private_key.pem -out private_key.p12
NSDictionary *info = [NSDictionary new];
[self getX509InfoWithName:@"your-cert.p12" password:@"cert-password" info:&info];
NSLog(@"X509 Infos: %@", info);
#pragma mark - X509
- (void)getX509InfoWithName:(NSString*)certificateName password:(NSString*)password info:(NSDictionary**)info
{
NSString *p12Path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:certificateName];
NSData *p12Data = [[NSData alloc] initWithContentsOfFile:p12Path];
CFStringRef p12Password = (__bridge CFStringRef)password;
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { p12Password };
CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef p12Items;
OSStatus result = SecPKCS12Import((__bridge CFDataRef)p12Data, optionsDictionary, &p12Items);
CFRelease(optionsDictionary);
if(result == noErr) {
NSDictionary *item = (NSDictionary*)CFArrayGetValueAtIndex(p12Items, 0);
SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex((__bridge CFArrayRef)[item objectForKey:(__bridge NSString*)kSecImportItemCertChain], 0);
*info = [self dictionaryFromCerificateWithLongDescription:cert];
}
}
- (NSDictionary*)dictionaryFromCerificateWithLongDescription:(SecCertificateRef)certificateRef {
NSMutableDictionary *dict = [NSMutableDictionary new];
if (certificateRef == NULL)
return dict;
#if TARGET_OS_MAC
const void *keys[] = { kSecOIDX509V1SubjectName, kSecOIDX509V1IssuerName, kSecOIDX509V1SerialNumber, kSecOIDX509V1Signature };
CFArrayRef keySelection = CFArrayCreate(NULL, keys , sizeof(keys)/sizeof(keys[0]), &kCFTypeArrayCallBacks);
CFErrorRef error;
CFDictionaryRef vals = SecCertificateCopyValues(certificateRef, keySelection, &error);
for(int i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) {
CFDictionaryRef dict_values = CFDictionaryGetValue(vals, keys[i]);
CFStringRef label = CFDictionaryGetValue(dict_values, kSecPropertyKeyLabel);
if (CFEqual(label, CFSTR("Serial Number"))) {
CFStringRef value = CFDictionaryGetValue(dict_values, kSecPropertyKeyValue);
if (value == NULL)
continue;
[dict setObject:(__bridge NSString*)(value) forKey:(__bridge NSString*)label];
} else if (CFEqual(label, CFSTR("Signature"))) {
CFDataRef value = CFDictionaryGetValue(dict_values, kSecPropertyKeyValue);
if (value == NULL)
continue;
[dict setObject:(__bridge NSData*)(value) forKey:(__bridge NSString*)label];
} else {
CFArrayRef values = CFDictionaryGetValue(dict_values, kSecPropertyKeyValue);
if (values == NULL)
continue;
[dict setObject:[self dictionaryFromDNwithSubjectName:values] forKey:(__bridge NSString*)label];
}
}
CFRelease(vals);
#endif
return dict;
}
- (NSDictionary*)dictionaryFromDNwithSubjectName:(CFArrayRef)array {
NSMutableDictionary *dict = [NSMutableDictionary new];
#if TARGET_OS_MAC
const void *keys[] = { kSecOIDCommonName, kSecOIDEmailAddress, kSecOIDOrganizationalUnitName, kSecOIDOrganizationName, kSecOIDLocalityName, kSecOIDStateProvinceName, kSecOIDCountryName };
NSArray *labels = [NSArray arrayWithObjects:@"CN", @"E", @"OU", @"O", @"L", @"S", @"C", @"E", nil];
for(int i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) {
for (CFIndex n = 0 ; n < CFArrayGetCount(array); n++) {
CFDictionaryRef dict_values = CFArrayGetValueAtIndex(array, n);
if (CFGetTypeID(dict_values) != CFDictionaryGetTypeID())
continue;
CFTypeRef dictkey = CFDictionaryGetValue(dict_values, kSecPropertyKeyLabel);
if (!CFEqual(dictkey, keys[i]))
continue;
CFStringRef str = (CFStringRef) CFDictionaryGetValue(dict_values, kSecPropertyKeyValue);
[dict setObject:(__bridge NSString*)str forKey:labels[i]];
}
}
#endif
return dict;
}