/ OSX / libsecurity_keychain / lib / CertificateValues.cpp
CertificateValues.cpp
  1  /*
  2   * Copyright (c) 2002-2017 Apple Inc. All Rights Reserved.
  3   *
  4   * @APPLE_LICENSE_HEADER_START@
  5   *
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. Please obtain a copy of the License at
 10   * http://www.opensource.apple.com/apsl/ and read it before using this
 11   * file.
 12   *
 13   * The Original Code and all software distributed under the License are
 14   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 15   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 16   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 18   * Please see the License for the specific language governing rights and
 19   * limitations under the License.
 20   *
 21   * @APPLE_LICENSE_HEADER_END@
 22   */
 23  
 24  //
 25  // CertificateValues.cpp
 26  //
 27  #include <security_keychain/Certificate.h>
 28  #include <Security/oidscert.h>
 29  #include <Security/oidsattr.h>
 30  #include <Security/SecCertificate.h>
 31  #include <Security/SecCertificatePriv.h>
 32  #include "SecCertificateOIDs.h"
 33  #include "CertificateValues.h"
 34  #include <CoreFoundation/CFNumber.h>
 35  
 36  // SecCertificateInternal.h cannot be included in this file, due to its
 37  // use of types which are not resolved in our macOS-only library.
 38  //
 39  extern "C" CFArrayRef SecCertificateCopyLegacyProperties(SecCertificateRef certificate);
 40  extern "C" void appendProperty(CFMutableArrayRef properties, CFStringRef propertyType,
 41      CFStringRef label, CFStringRef localizedLabel, CFTypeRef value);
 42  
 43  extern const CFStringRef __nonnull kSecPropertyKeyType;
 44  extern const CFStringRef __nonnull kSecPropertyKeyLabel;
 45  extern const CFStringRef __nonnull kSecPropertyKeyLocalizedLabel;
 46  extern const CFStringRef __nonnull kSecPropertyKeyValue;
 47  
 48  extern const CFStringRef __nonnull kSecPropertyTypeData;
 49  extern const CFStringRef __nonnull kSecPropertyTypeString;
 50  extern const CFStringRef __nonnull kSecPropertyTypeURL;
 51  extern const CFStringRef __nonnull kSecPropertyTypeDate;
 52  extern const CFStringRef __nonnull kSecPropertyTypeArray;
 53  extern const CFStringRef __nonnull kSecPropertyTypeNumber;
 54  
 55  
 56  #pragma mark ---------- CertificateValues Implementation ----------
 57  
 58  using namespace KeychainCore;
 59  
 60  void addFieldValues(const void *key, const void *value, void *context);
 61  void addPropertyToFieldValues(const void *value, void *context);
 62  void filterFieldValues(const void *key, const void *value, void *context);
 63  void validateKeys(const void *value, void *context);
 64  
 65  CFDictionaryRef CertificateValues::mOIDRemap = NULL;
 66  
 67  typedef struct FieldValueFilterContext
 68  {
 69  	CFMutableDictionaryRef filteredValues;
 70  	CFArrayRef filterKeys;
 71  } FieldValueFilterContext;
 72  
 73  CertificateValues::CertificateValues(SecCertificateRef certificateRef) : mCertificateRef(certificateRef),
 74  	mCertificateData(NULL),
 75  	mCertificateProperties(NULL)
 76  {
 77  	if (mCertificateRef)
 78  		CFRetain(mCertificateRef);
 79  }
 80  
 81  CertificateValues::~CertificateValues() _NOEXCEPT
 82  {
 83  	if (mCertificateProperties)
 84  		CFRelease(mCertificateProperties);
 85  	if (mCertificateData)
 86  		CFRelease(mCertificateData);
 87  	if (mCertificateRef)
 88  		CFRelease(mCertificateRef);
 89  }
 90  
 91  CFArrayRef CertificateValues::copyPropertyValues(CFErrorRef *error)
 92  {
 93  	if (!mCertificateProperties) {
 94  		mCertificateProperties = SecCertificateCopyLegacyProperties(mCertificateRef);
 95  	}
 96  	if (mCertificateProperties) {
 97  		CFRetain(mCertificateProperties);
 98  	}
 99  	else if (error) {
100  		*error = CFErrorCreate(NULL,
101  				kCFErrorDomainOSStatus, errSecInvalidCertificateRef, NULL);
102  	}
103  	return mCertificateProperties;
104  }
105  
106  CFDictionaryRef CertificateValues::copyFieldValues(CFArrayRef keys, CFErrorRef *error)
107  {
108  	if (keys)
109  	{
110  		if (CFGetTypeID(keys)!=CFArrayGetTypeID())
111  			return NULL;
112  		CFRange range = CFRangeMake(0, CFArrayGetCount((CFArrayRef)keys));
113  		bool failed = false;
114  		CFArrayApplyFunction(keys, range, validateKeys, &failed);
115  		if (failed)
116  			return NULL;
117  	}
118  
119  	if (mCertificateData)
120  	{
121  		CFRelease(mCertificateData);
122  		mCertificateData = NULL;
123  	}
124  	if (!mCertificateData)
125  	{
126  		mCertificateData = SecCertificateCopyData(mCertificateRef);	// OK to call, no big lock
127  		if (!mCertificateData)
128  		{
129  			if (error) {
130  				*error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecInvalidCertificateRef, NULL);
131  			}
132  			return NULL;
133  		}
134  	}
135  
136  	SecCertificateRef certificate = SecCertificateCreateWithData(kCFAllocatorDefault, mCertificateData);
137  	if (!certificate)
138  	{
139  		if (error)
140  			*error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecInvalidCertificateGroup, NULL);
141  		return NULL;
142  	}
143  
144  	CFMutableDictionaryRef fieldValues=CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
145  		&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
146  
147  	// Return an array of CFStringRefs representing the common names in the certificates subject if any
148  	CFArrayRef commonNames=SecCertificateCopyCommonNames(certificate);
149  	if (commonNames)
150  	{
151  		CFMutableArrayRef additionalValues = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
152  		appendProperty(additionalValues, kSecPropertyTypeArray, CFSTR("CN"), NULL, commonNames);
153  		CFDictionaryAddValue(fieldValues, kSecOIDCommonName, (CFTypeRef)CFArrayGetValueAtIndex(additionalValues, 0));
154  		CFRelease(commonNames);
155  		CFRelease(additionalValues);
156  	}
157  
158  	// These can exist in the subject alt name or in the subject
159  	CFArrayRef dnsNames=SecCertificateCopyDNSNames(certificate);
160  	if (dnsNames)
161  	{
162  		CFMutableArrayRef additionalValues = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
163  		appendProperty(additionalValues, kSecPropertyTypeArray, CFSTR("DNS"), NULL, dnsNames);
164  		CFDictionaryAddValue(fieldValues, CFSTR("DNSNAMES"), (CFTypeRef)CFArrayGetValueAtIndex(additionalValues, 0));
165  		CFRelease(dnsNames);
166  		CFRelease(additionalValues);
167  	}
168  
169  	CFArrayRef ipAddresses=SecCertificateCopyIPAddresses(certificate);
170  	if (ipAddresses)
171  	{
172  		CFMutableArrayRef additionalValues = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
173  		appendProperty(additionalValues, kSecPropertyTypeArray, CFSTR("IP"), NULL, dnsNames);
174  		CFDictionaryAddValue(fieldValues, CFSTR("IPADDRESSES"), (CFTypeRef)CFArrayGetValueAtIndex(additionalValues, 0));
175  		CFRelease(ipAddresses);
176  		CFRelease(additionalValues);
177  	}
178  
179  	// These can exist in the subject alt name or in the subject
180  	CFArrayRef emailAddrs=SecCertificateCopyRFC822Names(certificate);
181  	if (emailAddrs)
182  	{
183  		CFMutableArrayRef additionalValues = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
184  		appendProperty(additionalValues, kSecPropertyTypeArray, CFSTR("DNS"), NULL, dnsNames);
185  		CFDictionaryAddValue(fieldValues, kSecOIDEmailAddress, (CFTypeRef)CFArrayGetValueAtIndex(additionalValues, 0));
186  		CFRelease(emailAddrs);
187  		CFRelease(additionalValues);
188  	}
189  
190  	CFAbsoluteTime notBefore = SecCertificateNotValidBefore(certificate);
191  	CFNumberRef notBeforeRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &notBefore);
192  	if (notBeforeRef)
193  	{
194  		CFMutableArrayRef additionalValues = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
195  		appendProperty(additionalValues, kSecPropertyTypeNumber, CFSTR("Not Valid Before"), NULL, notBeforeRef);
196  		CFDictionaryAddValue(fieldValues, kSecOIDX509V1ValidityNotBefore, (CFTypeRef)CFArrayGetValueAtIndex(additionalValues, 0));
197  		CFRelease(notBeforeRef);
198  		CFRelease(additionalValues);
199  	}
200  
201  	CFAbsoluteTime notAfter = SecCertificateNotValidAfter(certificate);
202  	CFNumberRef notAfterRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &notAfter);
203  	if (notAfterRef)
204  	{
205  		CFMutableArrayRef additionalValues = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
206  		appendProperty(additionalValues, kSecPropertyTypeNumber, CFSTR("Not Valid After"), NULL, notAfterRef);
207  		CFDictionaryAddValue(fieldValues, kSecOIDX509V1ValidityNotAfter, (CFTypeRef)CFArrayGetValueAtIndex(additionalValues, 0));
208  		CFRelease(notAfterRef);
209  		CFRelease(additionalValues);
210  	}
211  
212  	SecKeyUsage keyUsage=SecCertificateGetKeyUsage(certificate);
213  	CFNumberRef ku = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &keyUsage);
214  	if (ku)
215  	{
216  		CFMutableArrayRef additionalValues = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
217  		appendProperty(additionalValues, kSecPropertyTypeNumber, CFSTR("Key Usage"), NULL, ku);
218  		CFDictionaryAddValue(fieldValues, kSecOIDKeyUsage, (CFTypeRef)CFArrayGetValueAtIndex(additionalValues, 0));
219  		CFRelease(ku);
220  		CFRelease(additionalValues);
221  	}
222  
223  	CFArrayRef ekus = SecCertificateCopyExtendedKeyUsage(certificate);
224  	if (ekus)
225  	{
226  		CFMutableArrayRef additionalValues = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
227  		appendProperty(additionalValues, kSecPropertyTypeArray, CFSTR("Extended Key Usage"), NULL, ekus);
228  		CFDictionaryAddValue(fieldValues, kSecOIDExtendedKeyUsage, (CFTypeRef)CFArrayGetValueAtIndex(additionalValues, 0));
229  		CFRelease(ekus);
230  		CFRelease(additionalValues);
231  	}
232  
233  	// Add all values from properties dictionary
234  	CFArrayRef properties = copyPropertyValues(NULL);
235  	if (properties)
236  	{
237  		CFRange range = CFRangeMake(0, CFArrayGetCount((CFArrayRef)properties));
238  		CFArrayApplyFunction(properties, range, addPropertyToFieldValues, fieldValues);
239  	//	CFDictionaryApplyFunction(properties, addFieldValues, fieldValues);
240  		CFRelease(properties);
241  	}
242  
243  	CFAbsoluteTime verifyTime = CFAbsoluteTimeGetCurrent();
244  	CFMutableArrayRef summaryProperties =
245  		SecCertificateCopySummaryProperties(certificate, verifyTime);
246  	if (summaryProperties)
247  	{
248  		CFRange range = CFRangeMake(0, CFArrayGetCount((CFArrayRef)summaryProperties));
249  		CFArrayApplyFunction(summaryProperties, range, addPropertyToFieldValues, fieldValues);
250  //		CFDictionaryApplyFunction(summaryProperties, addFieldValues, fieldValues);
251  //		CFDictionaryAddValue(fieldValues, CFSTR("summaryProperties"), summaryProperties);
252  		CFRelease(summaryProperties);
253  	}
254  
255  	if (certificate)
256  		CFRelease(certificate);
257  
258  	if (keys==NULL)
259  		return (CFDictionaryRef)fieldValues;
260  
261  	// Otherwise, we need to filter
262  	CFMutableDictionaryRef filteredFieldValues=CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
263  		&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
264  
265  	FieldValueFilterContext fvcontext;
266  	fvcontext.filteredValues = filteredFieldValues;
267  	fvcontext.filterKeys = keys;
268  
269  	CFDictionaryApplyFunction(fieldValues, filterFieldValues, &fvcontext);
270  
271  	CFRelease(fieldValues);
272  	return (CFDictionaryRef)filteredFieldValues;
273  }
274  
275  void validateKeys(const void *value, void *context)
276  {
277  	if (value == NULL || (CFGetTypeID(value)!=CFStringGetTypeID()))
278  		if (context)
279  			*(bool *)context = true;
280  }
281  
282  void filterFieldValues(const void *key, const void *value, void *context)
283  {
284  	// each element of keys is a CFStringRef with an OID, e.g.
285  	// const CFStringRef kSecOIDTitle = CFSTR("2.5.4.12");
286  
287  	CFTypeRef fieldKey = (CFTypeRef)key;
288  	if (fieldKey == NULL || (CFGetTypeID(fieldKey)!=CFStringGetTypeID()) || context==NULL)
289  		return;
290  
291  	FieldValueFilterContext *fvcontext = (FieldValueFilterContext *)context;
292  
293  	CFRange range = CFRangeMake(0, CFArrayGetCount(fvcontext->filterKeys));
294  	CFIndex idx = CFArrayGetFirstIndexOfValue(fvcontext->filterKeys, range, fieldKey);
295  	if (idx != kCFNotFound)
296  		CFDictionaryAddValue(fvcontext->filteredValues, fieldKey, value);
297  }
298  
299  void addFieldValues(const void *key, const void *value, void *context)
300  {
301  	CFMutableDictionaryRef fieldValues = (CFMutableDictionaryRef)context;
302  	CFDictionaryAddValue(fieldValues, key, value);
303  }
304  
305  void addPropertyToFieldValues(const void *value, void *context)
306  {
307  	CFMutableDictionaryRef fieldValues = (CFMutableDictionaryRef)context;
308  	if (CFGetTypeID(value)==CFDictionaryGetTypeID())
309  	{
310  		CFStringRef label = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)value, kSecPropertyKeyLabel);
311  #if 0
312  		CFStringRef typeD = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)value, kSecPropertyKeyType);
313  		CFTypeRef valueD = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)value, kSecPropertyKeyValue);
314  #endif
315  		CFStringRef key = CertificateValues::remapLabelToKey(label);
316  		if (key)
317  			CFDictionaryAddValue(fieldValues, key, value);
318  	}
319  }
320  
321  CFStringRef CertificateValues::remapLabelToKey(CFStringRef label)
322  {
323  	if (!label)
324  		return NULL;
325  
326  	if (!mOIDRemap)
327  	{
328  		CFTypeRef keys[] =
329  		{
330  			CFSTR("Subject Name"),
331  			CFSTR("Normalized Subject Name"),
332  			CFSTR("Issuer Name"),
333  			CFSTR("Normalized Subject Name"),
334  			CFSTR("Version"),
335  			CFSTR("Serial Number"),
336  			CFSTR("Signature Algorithm"),
337  			CFSTR("Subject Unique ID"),
338  			CFSTR("Issuer Unique ID"),
339  			CFSTR("Public Key Algorithm"),
340  			CFSTR("Public Key Data"),
341  			CFSTR("Signature"),
342  			CFSTR("Not Valid Before"),
343  			CFSTR("Not Valid After"),
344  			CFSTR("Expires")
345  		};
346  
347  		CFTypeRef values[] =
348  		{
349  			kSecOIDX509V1SubjectName,
350  			kSecOIDX509V1SubjectNameStd,
351  			kSecOIDX509V1IssuerName,
352  			kSecOIDX509V1IssuerNameStd,
353  			kSecOIDX509V1Version,
354  			kSecOIDX509V1SerialNumber,
355  			kSecOIDX509V1SignatureAlgorithm,	// or CSSMOID_X509V1SignatureAlgorithmTBS?
356  			kSecOIDX509V1CertificateSubjectUniqueId,
357  			kSecOIDX509V1CertificateIssuerUniqueId,
358  			kSecOIDX509V1SubjectPublicKeyAlgorithm,
359  			kSecOIDX509V1SubjectPublicKey,
360  			kSecOIDX509V1Signature,
361  			kSecOIDX509V1ValidityNotBefore,
362  			kSecOIDX509V1ValidityNotAfter,
363  			kSecOIDInvalidityDate
364  		};
365  
366  		mOIDRemap = CFDictionaryCreate(NULL, keys, values,
367  			(sizeof(keys) / sizeof(*keys)), &kCFTypeDictionaryKeyCallBacks,
368  			&kCFTypeDictionaryValueCallBacks);
369  	}
370  
371  	CFTypeRef result = (CFTypeRef)CFDictionaryGetValue(mOIDRemap, label);
372  
373  	return result?(CFStringRef)result:label;
374  }
375  
376  CFDataRef CertificateValues::copySerialNumber(CFErrorRef *error)
377  {
378  	CFDataRef result = NULL;
379  	SecCertificateRef certificate = copySecCertificateRef(error);
380  
381  	if (certificate)
382  	{
383  		result = SecCertificateCopySerialNumberData(certificate, error);
384  		CFRelease(certificate);
385  	}
386  	return result;
387  }
388  
389  CFDataRef CertificateValues::copyNormalizedIssuerContent(CFErrorRef *error)
390  {
391  	CFDataRef result = NULL;
392  	SecCertificateRef certificate = copySecCertificateRef(error);
393  	if (certificate)
394  	{
395  		// this matches the behavior on OS X prior to 10.12, where
396  		// normalized content was actually returned as a sequence.
397  
398  		result = SecCertificateCopyNormalizedIssuerSequence(certificate);
399  		CFRelease(certificate);
400  	}
401  	return result;
402  }
403  
404  CFDataRef CertificateValues::copyNormalizedSubjectContent(CFErrorRef *error)
405  {
406  	CFDataRef result = NULL;
407  	SecCertificateRef certificate = copySecCertificateRef(error);
408  	if (certificate)
409  	{
410  		// this matches the behavior on OS X prior to 10.12, where
411  		// normalized content was actually returned as a sequence.
412  
413  		result = SecCertificateCopyNormalizedSubjectSequence(certificate);
414  		CFRelease(certificate);
415  	}
416  	return result;
417  }
418  
419  CFDataRef CertificateValues::copyIssuerSequence(CFErrorRef *error)
420  {
421  	CFDataRef result = NULL;
422  	SecCertificateRef certificate = copySecCertificateRef(error);
423  	if (certificate)
424  	{
425  		result = SecCertificateCopyIssuerSequence(certificate);
426  		CFRelease(certificate);
427  	}
428  	return result;
429  }
430  
431  CFDataRef CertificateValues::copySubjectSequence(CFErrorRef *error)
432  {
433  	CFDataRef result = NULL;
434  	SecCertificateRef certificate = copySecCertificateRef(error);
435  	if (certificate)
436  	{
437  		result = SecCertificateCopySubjectSequence(certificate);
438  		CFRelease(certificate);
439  	}
440  	return result;
441  }
442  
443  CFStringRef CertificateValues::copyIssuerSummary(CFErrorRef *error)
444  {
445  	CFStringRef result = NULL;
446  	SecCertificateRef certificate = copySecCertificateRef(error);
447  	if (certificate)
448  	{
449  		result = SecCertificateCopyIssuerSummary(certificate);
450  		CFRelease(certificate);
451  	}
452  	return result;
453  }
454  
455  CFStringRef CertificateValues::copySubjectSummary(CFErrorRef *error)
456  {
457  	CFStringRef result = NULL;
458  	SecCertificateRef certificate = copySecCertificateRef(error);
459  	if (certificate)
460  	{
461  		result = SecCertificateCopySubjectSummary(certificate);
462  		CFRelease(certificate);
463  	}
464  	return result;
465  }
466  
467  CFDictionaryRef CertificateValues::copyAttributeDictionary(CFErrorRef *error)
468  {
469  	CFDictionaryRef result = NULL;
470  	SecCertificateRef certificate = copySecCertificateRef(error);
471  	if (certificate)
472  	{
473  		result = SecCertificateCopyAttributeDictionary(certificate);
474  		CFRelease(certificate);
475  	}
476  	return result;
477  }
478  
479  bool CertificateValues::isValid(CFAbsoluteTime verifyTime, CFErrorRef *error)
480  {
481  	bool result = NULL;
482  	SecCertificateRef certificate = copySecCertificateRef(error);
483  	if (certificate)
484  	{
485  		result = SecCertificateIsValid(certificate, verifyTime);
486  		CFRelease(certificate);
487  	}
488  	return result;
489  }
490  
491  CFAbsoluteTime CertificateValues::notValidBefore(CFErrorRef *error)
492  {
493  	CFAbsoluteTime result = 0;
494  	SecCertificateRef certificate = copySecCertificateRef(error);
495  	if (certificate)
496  	{
497  		result = SecCertificateNotValidBefore(certificate);
498  		CFRelease(certificate);
499  	}
500  	return result;
501  }
502  
503  CFAbsoluteTime CertificateValues::notValidAfter(CFErrorRef *error)
504  {
505  	CFAbsoluteTime result = 0;
506  	SecCertificateRef certificate = copySecCertificateRef(error);
507  	if (certificate)
508  	{
509  		result = SecCertificateNotValidAfter(certificate);
510  		CFRelease(certificate);
511  	}
512  	return result;
513  }
514  
515  SecCertificateRef CertificateValues::copySecCertificateRef(CFErrorRef *error)
516  {
517  	// SecCertificateCopyData returns an object created with CFDataCreate, so we
518  	// own it and must release it
519  
520  	if (mCertificateData)
521  	{
522  		CFRelease(mCertificateData);
523  		mCertificateData = NULL;
524  	}
525  
526  	mCertificateData = SecCertificateCopyData(mCertificateRef);	// OK to call, no big lock
527  	if (!mCertificateData)
528  	{
529  		if (error)
530  		{
531  			*error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecInvalidCertificateRef, NULL);
532  		}
533  		return NULL;
534  	}
535  
536  	SecCertificateRef certificate = SecCertificateCreateWithData(kCFAllocatorDefault, mCertificateData);
537  	if (!certificate)
538  	{
539  		if (error)
540  		{
541  			*error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecInvalidCertificateGroup, NULL);
542  		}
543  		return NULL;
544  	}
545  
546  	return certificate;
547  }
548  
549  #pragma mark ---------- OID Constants ----------
550  
551  const CFStringRef kSecOIDADC_CERT_POLICY = CFSTR("1.2.840.113635.100.5.3");
552  const CFStringRef kSecOIDAPPLE_CERT_POLICY = CFSTR("1.2.840.113635.100.5.1");
553  const CFStringRef kSecOIDAPPLE_EKU_CODE_SIGNING = CFSTR("1.2.840.113635.100.4.1");
554  const CFStringRef kSecOIDAPPLE_EKU_CODE_SIGNING_DEV = CFSTR("1.2.840.113635.100.4.1.1");
555  const CFStringRef kSecOIDAPPLE_EKU_ICHAT_ENCRYPTION = CFSTR("1.2.840.113635.100.4.3");
556  const CFStringRef kSecOIDAPPLE_EKU_ICHAT_SIGNING = CFSTR("1.2.840.113635.100.4.2");
557  const CFStringRef kSecOIDAPPLE_EKU_RESOURCE_SIGNING = CFSTR("1.2.840.113635.100.4.1.4");
558  const CFStringRef kSecOIDAPPLE_EKU_SYSTEM_IDENTITY = CFSTR("1.2.840.113635.100.4.4");
559  const CFStringRef kSecOIDAPPLE_EXTENSION = CFSTR("1.2.840.113635.100.6");
560  const CFStringRef kSecOIDAPPLE_EXTENSION_ADC_APPLE_SIGNING = CFSTR("1.2.840.113635.100.6.1.2.0.0");
561  const CFStringRef kSecOIDAPPLE_EXTENSION_ADC_DEV_SIGNING = CFSTR("1.2.840.113635.100.6.1.2.0");
562  const CFStringRef kSecOIDAPPLE_EXTENSION_APPLE_SIGNING = CFSTR("1.2.840.113635.100.6.1.1");
563  const CFStringRef kSecOIDAPPLE_EXTENSION_CODE_SIGNING = CFSTR("1.2.840.113635.100.6.1");
564  const CFStringRef kSecOIDAPPLE_EXTENSION_INTERMEDIATE_MARKER = CFSTR("1.2.840.113635.100.6.2");
565  const CFStringRef kSecOIDAPPLE_EXTENSION_WWDR_INTERMEDIATE = CFSTR("1.2.840.113635.100.6.2.1");
566  const CFStringRef kSecOIDAPPLE_EXTENSION_ITMS_INTERMEDIATE = CFSTR("1.2.840.113635.100.6.2.2");
567  const CFStringRef kSecOIDAPPLE_EXTENSION_AAI_INTERMEDIATE = CFSTR("1.2.840.113635.100.6.2.3");
568  const CFStringRef kSecOIDAPPLE_EXTENSION_APPLEID_INTERMEDIATE = CFSTR("1.2.840.113635.100.6.2.7");
569  const CFStringRef kSecOIDAuthorityInfoAccess = CFSTR("1.3.6.1.5.5.7.1.1");
570  const CFStringRef kSecOIDAuthorityKeyIdentifier = CFSTR("2.5.29.35");
571  const CFStringRef kSecOIDBasicConstraints = CFSTR("2.5.29.19");
572  const CFStringRef kSecOIDBiometricInfo = CFSTR("1.3.6.1.5.5.7.1.2");
573  const CFStringRef kSecOIDCSSMKeyStruct = CFSTR("2.16.840.1.113741.2.1.1.1.20");
574  const CFStringRef kSecOIDCertIssuer = CFSTR("2.5.29.29");
575  const CFStringRef kSecOIDCertificatePolicies = CFSTR("2.5.29.32");
576  const CFStringRef kSecOIDClientAuth = CFSTR("1.3.6.1.5.5.7.3.2");
577  const CFStringRef kSecOIDCollectiveStateProvinceName = CFSTR("2.5.4.8.1");
578  const CFStringRef kSecOIDCollectiveStreetAddress = CFSTR("2.5.4.9.1");
579  const CFStringRef kSecOIDCommonName = CFSTR("2.5.4.3");
580  const CFStringRef kSecOIDCountryName = CFSTR("2.5.4.6");
581  const CFStringRef kSecOIDCrlDistributionPoints = CFSTR("2.5.29.31");
582  const CFStringRef kSecOIDCrlNumber = CFSTR("2.5.29.20");
583  const CFStringRef kSecOIDCrlReason = CFSTR("2.5.29.21");
584  const CFStringRef kSecOIDDOTMAC_CERT_EMAIL_ENCRYPT = CFSTR("1.2.840.113635.100.3.2.3");
585  const CFStringRef kSecOIDDOTMAC_CERT_EMAIL_SIGN = CFSTR("1.2.840.113635.100.3.2.2");
586  const CFStringRef kSecOIDDOTMAC_CERT_EXTENSION = CFSTR("1.2.840.113635.100.3.2");
587  const CFStringRef kSecOIDDOTMAC_CERT_IDENTITY = CFSTR("1.2.840.113635.100.3.2.1");
588  const CFStringRef kSecOIDDOTMAC_CERT_POLICY = CFSTR("1.2.840.113635.100.5.2");
589  const CFStringRef kSecOIDDeltaCrlIndicator = CFSTR("2.5.29.27");
590  const CFStringRef kSecOIDDescription = CFSTR("2.5.4.13");
591  const CFStringRef kSecOIDEKU_IPSec = CFSTR("1.3.6.1.5.5.8.2.2");
592  const CFStringRef kSecOIDEmailAddress = CFSTR("1.2.840.113549.1.9.1");
593  const CFStringRef kSecOIDEmailProtection = CFSTR("1.3.6.1.5.5.7.3.4");
594  const CFStringRef kSecOIDExtendedKeyUsage = CFSTR("2.5.29.37");
595  const CFStringRef kSecOIDExtendedKeyUsageAny = CFSTR("2.5.29.37.0");
596  const CFStringRef kSecOIDExtendedUseCodeSigning = CFSTR("1.3.6.1.5.5.7.3.3");
597  const CFStringRef kSecOIDGivenName = CFSTR("2.5.4.42");
598  const CFStringRef kSecOIDHoldInstructionCode = CFSTR("2.5.29.23");
599  const CFStringRef kSecOIDInvalidityDate = CFSTR("2.5.29.24");
600  const CFStringRef kSecOIDIssuerAltName = CFSTR("2.5.29.18");
601  const CFStringRef kSecOIDIssuingDistributionPoint = CFSTR("2.5.29.28");
602  const CFStringRef kSecOIDIssuingDistributionPoints = CFSTR("2.5.29.28");
603  const CFStringRef kSecOIDKERBv5_PKINIT_KP_CLIENT_AUTH = CFSTR("1.3.6.1.5.2.3.4");
604  const CFStringRef kSecOIDKERBv5_PKINIT_KP_KDC = CFSTR("1.3.6.1.5.2.3.5");
605  const CFStringRef kSecOIDKeyUsage = CFSTR("2.5.29.15");
606  const CFStringRef kSecOIDLocalityName = CFSTR("2.5.4.7");
607  const CFStringRef kSecOIDMS_NTPrincipalName = CFSTR("1.3.6.1.4.1.311.20.2.3");
608  const CFStringRef kSecOIDMicrosoftSGC = CFSTR("1.3.6.1.4.1.311.10.3.3");
609  const CFStringRef kSecOIDNameConstraints = CFSTR("2.5.29.30");
610  const CFStringRef kSecOIDNetscapeCertSequence = CFSTR("2.16.840.1.113730.2.5");
611  const CFStringRef kSecOIDNetscapeCertType = CFSTR("2.16.840.1.113730.1.1");
612  const CFStringRef kSecOIDNetscapeSGC = CFSTR("2.16.840.1.113730.4.1");
613  const CFStringRef kSecOIDOCSPSigning = CFSTR("1.3.6.1.5.5.7.3.9");
614  const CFStringRef kSecOIDOrganizationName = CFSTR("2.5.4.10");
615  const CFStringRef kSecOIDOrganizationalUnitName = CFSTR("2.5.4.11");
616  const CFStringRef kSecOIDPolicyConstraints = CFSTR("2.5.29.36");
617  const CFStringRef kSecOIDPolicyMappings = CFSTR("2.5.29.33");
618  const CFStringRef kSecOIDPrivateKeyUsagePeriod = CFSTR("2.5.29.16");
619  const CFStringRef kSecOIDQC_Statements = CFSTR("1.3.6.1.5.5.7.1.3");
620  const CFStringRef kSecOIDSerialNumber = CFSTR("2.5.4.5");
621  const CFStringRef kSecOIDServerAuth = CFSTR("1.3.6.1.5.5.7.3.1");
622  const CFStringRef kSecOIDStateProvinceName = CFSTR("2.5.4.8");
623  const CFStringRef kSecOIDStreetAddress = CFSTR("2.5.4.9");
624  const CFStringRef kSecOIDSubjectAltName = CFSTR("2.5.29.17");
625  const CFStringRef kSecOIDSubjectDirectoryAttributes = CFSTR("2.5.29.9");
626  const CFStringRef kSecOIDSubjectEmailAddress = CFSTR("2.16.840.1.113741.2.1.1.1.50.3");
627  const CFStringRef kSecOIDSubjectInfoAccess = CFSTR("1.3.6.1.5.5.7.1.11");
628  const CFStringRef kSecOIDSubjectKeyIdentifier = CFSTR("2.5.29.14");
629  const CFStringRef kSecOIDSubjectPicture = CFSTR("2.16.840.1.113741.2.1.1.1.50.2");
630  const CFStringRef kSecOIDSubjectSignatureBitmap = CFSTR("2.16.840.1.113741.2.1.1.1.50.1");
631  const CFStringRef kSecOIDSurname = CFSTR("2.5.4.4");
632  const CFStringRef kSecOIDTimeStamping = CFSTR("1.3.6.1.5.5.7.3.8");
633  const CFStringRef kSecOIDTitle = CFSTR("2.5.4.12");
634  const CFStringRef kSecOIDUseExemptions = CFSTR("2.16.840.1.113741.2.1.1.1.50.4");
635  const CFStringRef kSecOIDX509V1CertificateIssuerUniqueId = CFSTR("2.16.840.1.113741.2.1.1.1.11");
636  const CFStringRef kSecOIDX509V1CertificateSubjectUniqueId = CFSTR("2.16.840.1.113741.2.1.1.1.12");
637  const CFStringRef kSecOIDX509V1IssuerName = CFSTR("2.16.840.1.113741.2.1.1.1.5");
638  const CFStringRef kSecOIDX509V1IssuerNameCStruct = CFSTR("2.16.840.1.113741.2.1.1.1.5.1");
639  const CFStringRef kSecOIDX509V1IssuerNameLDAP = CFSTR("2.16.840.1.113741.2.1.1.1.5.2");
640  const CFStringRef kSecOIDX509V1IssuerNameStd = CFSTR("2.16.840.1.113741.2.1.1.1.23");
641  const CFStringRef kSecOIDX509V1SerialNumber = CFSTR("2.16.840.1.113741.2.1.1.1.3");
642  const CFStringRef kSecOIDX509V1Signature = CFSTR("2.16.840.1.113741.2.1.3.2.2");
643  const CFStringRef kSecOIDX509V1SignatureAlgorithm = CFSTR("2.16.840.1.113741.2.1.3.2.1");
644  const CFStringRef kSecOIDX509V1SignatureAlgorithmParameters = CFSTR("2.16.840.1.113741.2.1.3.2.3");
645  const CFStringRef kSecOIDX509V1SignatureAlgorithmTBS = CFSTR("2.16.840.1.113741.2.1.3.2.10");
646  const CFStringRef kSecOIDX509V1SignatureCStruct = CFSTR("2.16.840.1.113741.2.1.3.2.0.1");
647  const CFStringRef kSecOIDX509V1SignatureStruct = CFSTR("2.16.840.1.113741.2.1.3.2.0");
648  const CFStringRef kSecOIDX509V1SubjectName = CFSTR("2.16.840.1.113741.2.1.1.1.8");
649  const CFStringRef kSecOIDX509V1SubjectNameCStruct = CFSTR("2.16.840.1.113741.2.1.1.1.8.1");
650  const CFStringRef kSecOIDX509V1SubjectNameLDAP = CFSTR("2.16.840.1.113741.2.1.1.1.8.2");
651  const CFStringRef kSecOIDX509V1SubjectNameStd = CFSTR("2.16.840.1.113741.2.1.1.1.22");
652  const CFStringRef kSecOIDX509V1SubjectPublicKey = CFSTR("2.16.840.1.113741.2.1.1.1.10");
653  const CFStringRef kSecOIDX509V1SubjectPublicKeyAlgorithm = CFSTR("2.16.840.1.113741.2.1.1.1.9");
654  const CFStringRef kSecOIDX509V1SubjectPublicKeyAlgorithmParameters = CFSTR("2.16.840.1.113741.2.1.1.1.18");
655  const CFStringRef kSecOIDX509V1SubjectPublicKeyCStruct = CFSTR("2.16.840.1.113741.2.1.1.1.20.1");
656  const CFStringRef kSecOIDX509V1ValidityNotAfter = CFSTR("2.16.840.1.113741.2.1.1.1.7");
657  const CFStringRef kSecOIDX509V1ValidityNotBefore = CFSTR("2.16.840.1.113741.2.1.1.1.6");
658  const CFStringRef kSecOIDX509V1Version = CFSTR("2.16.840.1.113741.2.1.1.1.2");
659  const CFStringRef kSecOIDX509V3Certificate = CFSTR("2.16.840.1.113741.2.1.1.1.1");
660  const CFStringRef kSecOIDX509V3CertificateCStruct = CFSTR("2.16.840.1.113741.2.1.1.1.1.1");
661  const CFStringRef kSecOIDX509V3CertificateExtensionCStruct = CFSTR("2.16.840.1.113741.2.1.1.1.13.1");
662  const CFStringRef kSecOIDX509V3CertificateExtensionCritical = CFSTR("2.16.840.1.113741.2.1.1.1.16");
663  const CFStringRef kSecOIDX509V3CertificateExtensionId = CFSTR("2.16.840.1.113741.2.1.1.1.15");
664  const CFStringRef kSecOIDX509V3CertificateExtensionStruct = CFSTR("2.16.840.1.113741.2.1.1.1.13");
665  const CFStringRef kSecOIDX509V3CertificateExtensionType = CFSTR("2.16.840.1.113741.2.1.1.1.19");
666  const CFStringRef kSecOIDX509V3CertificateExtensionValue = CFSTR("2.16.840.1.113741.2.1.1.1.17");
667  const CFStringRef kSecOIDX509V3CertificateExtensionsCStruct = CFSTR("2.16.840.1.113741.2.1.1.1.21.1");
668  const CFStringRef kSecOIDX509V3CertificateExtensionsStruct = CFSTR("2.16.840.1.113741.2.1.1.1.21");
669  const CFStringRef kSecOIDX509V3CertificateNumberOfExtensions = CFSTR("2.16.840.1.113741.2.1.1.1.14");
670  const CFStringRef kSecOIDX509V3SignedCertificate = CFSTR("2.16.840.1.113741.2.1.1.1.0");
671  const CFStringRef kSecOIDX509V3SignedCertificateCStruct = CFSTR("2.16.840.1.113741.2.1.1.1.0.1");
672  const CFStringRef kSecOIDSRVName = CFSTR("1.3.6.1.5.5.7.8.7");
673