CFDateRef GetDateFieldFromCertificate(SecCertificateRef certificate, CFTypeRef oid) { const void *keys[] = { oid }; CFDictionaryRef dict = NULL; CFErrorRef error; CFDateRef date = NULL; CFArrayRef keySelection = CFArrayCreate(NULL, keys , sizeof(keys)/sizeof(keys[0]), &kCFTypeArrayCallBacks); dict = SecCertificateCopyValues(certificate, keySelection, &error); if (dict == NULL) { printErrorMsg("GetDateFieldFromCertificate: SecCertificateCopyValues", error); goto release_ks; } CFDictionaryRef vals = dict ? CFDictionaryGetValue(dict, oid) : NULL; CFNumberRef vals2 = vals ? CFDictionaryGetValue(vals, kSecPropertyKeyValue) : NULL; if (vals2 == NULL) goto release_dict; CFAbsoluteTime validityNotBefore; if (CFNumberGetValue(vals2, kCFNumberDoubleType, &validityNotBefore)) date = CFDateCreate(kCFAllocatorDefault,validityNotBefore); release_dict: CFRelease(dict); release_ks: CFRelease(keySelection); return date; }
CFArrayRef GetFieldsFromCertificate(SecCertificateRef certificate, CFTypeRef oid) { CFMutableArrayRef fields = CFArrayCreateMutable(NULL, 0, NULL); CertNameRef pCertName = createCertName(); const void* keys[] = { oid, }; CFDictionaryRef dict; CFErrorRef error; CFArrayRef keySelection = CFArrayCreate(NULL, keys , 1, NULL); dict = SecCertificateCopyValues(certificate, keySelection, &error); if (dict == NULL) { printErrorMsg("GetFieldsFromCertificate: SecCertificateCopyValues", error); CFRelease(keySelection); CFRelease(fields); destroyCertName(pCertName); return NULL; } CFDictionaryRef vals = CFDictionaryGetValue(dict, oid); CFArrayRef vals2 = vals ? CFDictionaryGetValue(vals, kSecPropertyKeyValue) : NULL; if (vals2) { for(int i = 0; i < CFArrayGetCount(vals2); i++) { CFDictionaryRef subDict = CFArrayGetValueAtIndex(vals2, i); CFStringRef label = CFDictionaryGetValue(subDict, kSecPropertyKeyLabel); CFStringRef value = CFDictionaryGetValue(subDict, kSecPropertyKeyValue); if (CFStringCompare(label, kSecOIDEmailAddress, 0) == kCFCompareEqualTo) CFArrayAppendValue((CFMutableArrayRef)pCertName->emailAddress, value); else if (CFStringCompare(label, kSecOIDCountryName, 0) == kCFCompareEqualTo) CFArrayAppendValue((CFMutableArrayRef)pCertName->countryName, value); else if (CFStringCompare(label, kSecOIDOrganizationName, 0) == kCFCompareEqualTo) CFArrayAppendValue((CFMutableArrayRef)pCertName->organization, value); else if (CFStringCompare(label, kSecOIDOrganizationalUnitName, 0) == kCFCompareEqualTo) CFArrayAppendValue((CFMutableArrayRef)pCertName->organizationalUnit, value); else if (CFStringCompare(label, kSecOIDCommonName, 0) == kCFCompareEqualTo) CFArrayAppendValue((CFMutableArrayRef)pCertName->commonName, value); else if (CFStringCompare(label, kSecOIDDescription, 0) == kCFCompareEqualTo) CFArrayAppendValue((CFMutableArrayRef)pCertName->description, value); else if (CFStringCompare(label, kSecOIDStateProvinceName, 0) == kCFCompareEqualTo) CFArrayAppendValue((CFMutableArrayRef)pCertName->stateName, value); else if (CFStringCompare(label, kSecOIDLocalityName, 0) == kCFCompareEqualTo) CFArrayAppendValue((CFMutableArrayRef)pCertName->localityName, value); } CFArrayAppendValue(fields, pCertName); } CFRelease(dict); CFRelease(keySelection); return fields; }
CFDataRef CreatePropertyFromCertificate(const SecCertificateRef& cert, const CFTypeRef& oid) { // Set the list of attributes. auto keys = CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks); CFArrayAppendValue(keys, oid); // SecCertificateOIDs.h // Request dictionary of dictionaries (one for each attribute). auto certificate_values = SecCertificateCopyValues(cert, keys, nullptr); CFRelease(keys); if (!CFDictionaryContainsKey(certificate_values, oid)) { // Certificate does not have the requested property. CFRelease(certificate_values); return nullptr; } auto values = (CFDictionaryRef)CFDictionaryGetValue(certificate_values, oid); if (!CFDictionaryContainsKey(values, kSecPropertyKeyValue)) { // Odd, there was not value in the property result. CFRelease(certificate_values); return nullptr; } // Create copy of the property value, which is an index to owned dict. auto property = (CFDataRef)CFDictionaryGetValue(values, kSecPropertyKeyValue); if (CFGetTypeID(property) == CFArrayGetTypeID()) { property = (CFDataRef)CFArrayCreateCopy(nullptr, (CFArrayRef)property); } else if (CFGetTypeID(property) == CFNumberGetTypeID()) { property = (CFDataRef)CFNumberCreateCopy((CFNumberRef)property); } else { property = nullptr; } // Release and give the caller control of the property. CFRelease(certificate_values); return property; }
char * _mongoc_secure_transport_RFC2253_from_cert (SecCertificateRef cert) { CFTypeRef value; bson_string_t *retval; CFTypeRef subject_name; CFDictionaryRef cert_dict; cert_dict = SecCertificateCopyValues (cert, NULL, NULL); if (!cert_dict) { return NULL; } subject_name = CFDictionaryGetValue (cert_dict, kSecOIDX509V1SubjectName); if (!subject_name) { CFRelease (cert_dict); return NULL; } subject_name = CFDictionaryGetValue (subject_name, kSecPropertyKeyValue); if (!subject_name) { CFRelease (cert_dict); return NULL; } retval = bson_string_new ("");; value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDCommonName); _bson_append_cftyperef (retval, "CN=", value); value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDOrganizationalUnitName); if (value) { /* Can be either one unit name, or array of unit names */ if (CFGetTypeID(value) == CFStringGetTypeID()) { _bson_append_cftyperef (retval, ",OU=", value); } else if (CFGetTypeID(value) == CFArrayGetTypeID()) { CFIndex len = CFArrayGetCount(value); if (len > 0) { _bson_append_cftyperef (retval, ",OU=", CFArrayGetValueAtIndex(value, 0)); } if (len > 1) { _bson_append_cftyperef (retval, ",", CFArrayGetValueAtIndex(value, 1)); } if (len > 2) { _bson_append_cftyperef (retval, ",", CFArrayGetValueAtIndex(value, 2)); } } } value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDOrganizationName); _bson_append_cftyperef (retval, ",O=", value); value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDLocalityName); _bson_append_cftyperef (retval, ",L=", value); value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDStateProvinceName); _bson_append_cftyperef (retval, ",ST=", value); value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDCountryName); _bson_append_cftyperef (retval, ",C=", value); /* This seems rarely used */ value = _mongoc_secure_transport_dict_get (subject_name, kSecOIDStreetAddress); _bson_append_cftyperef (retval, ",STREET", value); CFRelease (cert_dict); return bson_string_free (retval, false); }