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