I wanted to use the SecCertificateCopyValues
function but could not find the correct certificate OID.
https://developer.apple.com/documentation/security/certificate_key_and_trust_services/certificates/certificate_oids?language=objc
Should I have used some other function?
Yes, you should use SecCertificateCopyValues
. In this returned dictionary, search for kSecOIDX509V1IssuerName
from the Apple documentation link you mentioned. In the documentation of SecCertificateCopyValues there is mentioned, that
Each entry in this dictionary is itself a dictionary with the keys described in Certificate Property Keys.
So, for example, to get the common name of the issuer, you would:
To create a distinguished name you can check for different keys.
If you have an OID, you can look at the corresponding constant in Apple's open source certificate values and add to the code to get the values you are interested in:
In code, this might look like this:
static CFStringRef createDistinguishedName(CFDictionaryRef certValues, CFStringRef key) {
CFDictionaryRef dict = CFDictionaryGetValue(certValues, key);
CFArrayRef values = CFDictionaryGetValue(dict, kSecPropertyKeyValue);
CFMutableStringRef dn = CFStringCreateMutableCopy(NULL, 0, CFSTR(""));
CFStringRef keys[] = { kSecOIDCommonName, kSecOIDOrganizationName, kSecOIDOrganizationalUnitName, kSecOIDLocalityName, kSecOIDStateProvinceName, kSecOIDCountryName, kSecOIDSerialNumber, kSecOIDEmailAddress};
CFStringRef txt[] = { CFSTR("CN"), CFSTR("O"), CFSTR("OU"), CFSTR("L"), CFSTR("S"), CFSTR("C"), CFSTR("SERIALNUMBER"), CFSTR("MAIL")};
bool appendComa = false;
for(int i = 0; i < CFArrayGetCount(values); i++) {
CFDictionaryRef subDict = CFArrayGetValueAtIndex(values, i);
CFStringRef labelVal = CFDictionaryGetValue(subDict, kSecPropertyKeyLabel);
for(int k = 0; k < sizeof(keys)/sizeof(keys[0]); k++) {
if (kCFCompareEqualTo == CFStringCompare(labelVal, keys[k], 0)) {
if (appendComa)
CFStringAppend(dn, CFSTR(", "));
CFStringAppend(dn, txt[k]);
CFStringAppend(dn, CFSTR("="));
CFStringAppend(dn, CFDictionaryGetValue(subDict, kSecPropertyKeyValue));
appendComa = true;
}
}
}
return dn;
}
It can be called like this:
void printDN(CFDataRef certData) {
SecCertificateRef certRef = SecCertificateCreateWithData(NULL, certData);
CFDictionaryRef certValues = SecCertificateCopyValues(certRef, nil, nil);
CFStringRef dn = createDistinguishedName(certValues, kSecOIDX509V1IssuerName);
CFShow(dn);
CFRelease(dn);
CFRelease(certValues);
CFRelease(certRef);
}
A sample certificate from here would result in the following string:
C=JP, S=Tokyo, L=Chuo-ku, O=Frank4DD, OU=WebCert Support, CN=Frank4DD Web CA, MAIL=support@frank4dd.com