2 * Copyright (c) 2002-2004,2011-2012,2014-2017 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * TrustRevocation.cpp - private revocation policy manipulation
28 #include <security_keychain/Trust.h>
29 #include <security_utilities/cfutilities.h>
30 #include <security_utilities/simpleprefs.h>
31 #include <CoreFoundation/CFData.h>
32 #include "SecBridge.h"
33 #include <Security/cssmapplePriv.h>
34 #include <Security/oidsalg.h>
37 * These may go into an SPI header for the SecTrust object.
40 /* this revocation policy disabled */
42 /* try, but tolerate inability to complete */
44 /* require successful revocation check if certificate indicates
45 * the policy is supported */
46 kSecRequireIfPresentInCertificate
,
47 /* require for every cert */
48 kSecRequireForAllCertificates
49 } SecRevocationPolicyStyle
;
51 using namespace KeychainCore
;
54 * Given an app-specified array of Policies, determine if at least one of them
55 * matches the given policy OID.
57 bool Trust::policySpecified(CFArrayRef policies
, const CSSM_OID
&inOid
)
59 if(policies
== NULL
) {
62 CFIndex numPolicies
= CFArrayGetCount(policies
);
63 for(CFIndex dex
=0; dex
<numPolicies
; dex
++) {
64 SecPolicyRef secPol
= (SecPolicyRef
)CFArrayGetValueAtIndex(policies
, dex
);
65 SecPointer
<Policy
> pol
= Policy::required(SecPolicyRef(secPol
));
66 const CssmOid
&oid
= pol
->oid();
67 if(oid
== CssmOid::overlay(inOid
)) {
75 * Given an app-specified array of Policies, determine if at least one of them
76 * is an explicit revocation policy.
78 bool Trust::revocationPolicySpecified(CFArrayRef policies
)
80 if(policies
== NULL
) {
83 CFIndex numPolicies
= CFArrayGetCount(policies
);
84 for(CFIndex dex
=0; dex
<numPolicies
; dex
++) {
85 SecPolicyRef secPol
= (SecPolicyRef
)CFArrayGetValueAtIndex(policies
, dex
);
86 SecPointer
<Policy
> pol
= Policy::required(SecPolicyRef(secPol
));
87 const CssmOid
&oid
= pol
->oid();
88 if(oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
)) {
91 if(oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
)) {
99 * Replace a unified revocation policy instance in the mPolicies array
100 * with specific instances of the OCSP and/or CRL policies which the TP
101 * module understands. Returns a (possibly) modified copy of the mPolicies
102 * array, which the caller is responsible for releasing.
104 CFMutableArrayRef
Trust::convertRevocationPolicy(
112 CFIndex numPolicies
= CFArrayGetCount(mPolicies
);
113 CFAllocatorRef allocator
= CFGetAllocator(mPolicies
);
114 CFMutableArrayRef policies
= CFArrayCreateMutableCopy(allocator
, numPolicies
, mPolicies
);
115 SecPolicyRef revPolicy
= NULL
;
116 for(CFIndex dex
=0; dex
<numPolicies
; dex
++) {
117 SecPolicyRef secPol
= (SecPolicyRef
)CFArrayGetValueAtIndex(policies
, dex
);
118 SecPointer
<Policy
> pol
= Policy::required(SecPolicyRef(secPol
));
119 const CssmOid
&oid
= pol
->oid();
120 if(oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION
)) {
123 CFRelease(revPolicy
);
125 CFArrayRemoveValueAtIndex(policies
, dex
--);
134 SecPointer
<Policy
> ocspPolicy
;
135 SecPointer
<Policy
> crlPolicy
;
137 // fetch policy value
138 CFOptionFlags policyFlags
= kSecRevocationUseAnyAvailableMethod
;
139 CSSM_DATA policyValue
= { 0, NULL
};
141 policyValue
= Policy::required(revPolicy
)->value();
144 policyValue
.Data
= NULL
;
146 if (policyValue
.Data
) {
147 policyFlags
= (CFOptionFlags
) *((CFOptionFlags
*)policyValue
.Data
);
149 if (mNetworkPolicy
== useNetworkDisabled
) {
150 policyFlags
= 0 | kSecRevocationNetworkAccessDisabled
;
152 CFRelease(revPolicy
); // all done with this policy reference
154 if (policyFlags
& kSecRevocationOCSPMethod
) {
155 /* cook up a new Policy object */
156 ocspPolicy
= new Policy(mTP
, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
));
157 CSSM_APPLE_TP_OCSP_OPT_FLAGS ocspFlags
= CSSM_TP_ACTION_OCSP_SUFFICIENT
;
158 if (policyFlags
& kSecRevocationRequirePositiveResponse
) {
159 ocspFlags
|= CSSM_TP_ACTION_OCSP_REQUIRE_IF_RESP_PRESENT
;
161 CSSM_APPLE_TP_OCSP_OPTIONS opts
;
162 memset(&opts
, 0, sizeof(opts
));
163 opts
.Version
= CSSM_APPLE_TP_OCSP_OPTS_VERSION
;
164 opts
.Flags
= ocspFlags
;
166 /* Policy manages its own copy of this data */
167 CSSM_DATA optData
= {sizeof(opts
), (uint8
*)&opts
};
168 ocspPolicy
->value() = optData
;
170 /* Policies array retains the Policy object */
171 CFArrayAppendValue(policies
, ocspPolicy
->handle(false));
174 if (policyFlags
& kSecRevocationCRLMethod
) {
175 /* cook up a new Policy object */
176 crlPolicy
= new Policy(mTP
, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
));
177 CSSM_APPLE_TP_CRL_OPT_FLAGS crlFlags
= 0;
178 if (policyFlags
& kSecRevocationRequirePositiveResponse
) {
179 crlFlags
|= CSSM_TP_ACTION_REQUIRE_CRL_IF_PRESENT
;
181 CSSM_APPLE_TP_CRL_OPTIONS opts
;
182 memset(&opts
, 0, sizeof(opts
));
183 opts
.Version
= CSSM_APPLE_TP_CRL_OPTS_VERSION
;
184 opts
.CrlFlags
= crlFlags
;
186 /* Policy manages its own copy of this data */
187 CSSM_DATA optData
= {sizeof(opts
), (uint8
*)&opts
};
188 crlPolicy
->value() = optData
;
190 /* Policies array retains the Policy object */
191 CFArrayAppendValue(policies
, crlPolicy
->handle(false));
197 static SecRevocationPolicyStyle
parseRevStyle(CFStringRef val
)
199 if(CFEqual(val
, kSecRevocationOff
)) {
202 else if(CFEqual(val
, kSecRevocationBestAttempt
)) {
203 return kSecBestAttempt
;
205 else if(CFEqual(val
, kSecRevocationRequireIfPresent
)) {
206 return kSecRequireIfPresentInCertificate
;
208 else if(CFEqual(val
, kSecRevocationRequireForAll
)) {
209 return kSecRequireForAllCertificates
;
216 CFDictionaryRef
Trust::defaultRevocationSettings()
219 defaults read ~/Library/Preferences/com.apple.security.revocation
221 CRLStyle = BestAttempt;
222 CRLSufficientPerCert = 1;
223 OCSPStyle = BestAttempt;
224 OCSPSufficientPerCert = 1;
225 RevocationFirst = OCSP;
228 const void *keys
[] = {
229 kSecRevocationCrlStyle
,
230 kSecRevocationCRLSufficientPerCert
,
231 kSecRevocationOcspStyle
,
232 kSecRevocationOCSPSufficientPerCert
,
233 kSecRevocationWhichFirst
235 const void *values
[] = {
236 kSecRevocationBestAttempt
,
238 kSecRevocationBestAttempt
,
240 kSecRevocationOcspFirst
243 return CFDictionaryCreate(kCFAllocatorDefault
, keys
,
244 values
, sizeof(keys
) / sizeof(*keys
),
245 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
248 CFMutableArrayRef
Trust::addPreferenceRevocationPolicies(
249 bool ocspEnabledOnBestAttempt
,
250 bool crlEnabledOnBestAttempt
,
256 Dictionary
* pd
= NULL
;
257 CFDictionaryRef tempDict
= defaultRevocationSettings();
258 if (tempDict
== NULL
) {
261 pd
= new Dictionary(tempDict
);
264 auto_ptr
<Dictionary
> prefsDict(pd
);
269 SecRevocationPolicyStyle ocspStyle
= kSecBestAttempt
;
270 SecRevocationPolicyStyle crlStyle
= kSecBestAttempt
;
271 SecPointer
<Policy
> ocspPolicy
;
272 SecPointer
<Policy
> crlPolicy
;
274 /* Are any revocation policies enabled? */
275 val
= prefsDict
->getStringValue(kSecRevocationOcspStyle
);
277 ocspStyle
= parseRevStyle(val
);
278 if(ocspStyle
!= kSecDisabled
) {
281 if(ocspStyle
== kSecBestAttempt
) {
282 doOcsp
= ocspEnabledOnBestAttempt
;
285 val
= prefsDict
->getStringValue(kSecRevocationCrlStyle
);
287 crlStyle
= parseRevStyle(val
);
288 if(crlStyle
!= kSecDisabled
) {
291 if(crlStyle
== kSecBestAttempt
) {
292 doCrl
= crlEnabledOnBestAttempt
;
296 if(!doCrl
&& !doOcsp
) {
300 /* which policy first? */
301 bool ocspFirst
= true; // default if both present
302 if(doCrl
&& doOcsp
) {
303 val
= prefsDict
->getStringValue(kSecRevocationWhichFirst
);
304 if((val
!= NULL
) && CFEqual(val
, kSecRevocationCrlFirst
)) {
309 /* Must have at least one caller-specified policy
310 * (if they didn't specify any, it's a no-op evaluation, and if they wanted
311 * revocation checking only, that policy would already be in mPolicies) */
312 if (!mPolicies
|| !CFArrayGetCount(mPolicies
))
315 /* We're adding something to mPolicies, so make a copy we can work with */
316 CFMutableArrayRef policies
= CFArrayCreateMutableCopy(NULL
, 0, mPolicies
);
317 if(policies
== NULL
) {
318 throw std::bad_alloc();
322 /* Cook up a new Policy object */
323 ocspPolicy
= new Policy(mTP
, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
));
324 CSSM_APPLE_TP_OCSP_OPTIONS opts
;
325 memset(&opts
, 0, sizeof(opts
));
326 opts
.Version
= CSSM_APPLE_TP_OCSP_OPTS_VERSION
;
328 /* Now fill in the OCSP-related blanks */
333 case kSecBestAttempt
:
334 /* default, nothing to set */
336 case kSecRequireIfPresentInCertificate
:
337 opts
.Flags
|= CSSM_TP_ACTION_OCSP_REQUIRE_IF_RESP_PRESENT
;
339 case kSecRequireForAllCertificates
:
340 opts
.Flags
|= CSSM_TP_ACTION_OCSP_REQUIRE_PER_CERT
;
344 if(prefsDict
->getBoolValue(kSecRevocationOCSPSufficientPerCert
)) {
345 opts
.Flags
|= CSSM_TP_ACTION_OCSP_SUFFICIENT
;
348 val
= prefsDict
->getStringValue(kSecOCSPLocalResponder
);
350 CFDataRef cfData
= CFStringCreateExternalRepresentation(NULL
,
351 val
, kCFStringEncodingUTF8
, 0);
352 CFIndex len
= CFDataGetLength(cfData
);
353 opts
.LocalResponder
= (CSSM_DATA_PTR
)alloc
.malloc(sizeof(CSSM_DATA
));
354 opts
.LocalResponder
->Data
= (uint8
*)alloc
.malloc(len
);
355 opts
.LocalResponder
->Length
= len
;
356 memmove(opts
.LocalResponder
->Data
, CFDataGetBytePtr(cfData
), len
);
360 /* Policy manages its own copy of this data */
361 CSSM_DATA optData
= {sizeof(opts
), (uint8
*)&opts
};
362 ocspPolicy
->value() = optData
;
367 /* Cook up a new Policy object */
368 crlPolicy
= new Policy(mTP
, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
));
369 CSSM_APPLE_TP_CRL_OPTIONS opts
;
370 memset(&opts
, 0, sizeof(opts
));
371 opts
.Version
= CSSM_APPLE_TP_CRL_OPTS_VERSION
;
373 /* Now fill in the CRL-related blanks */
374 opts
.CrlFlags
= CSSM_TP_ACTION_FETCH_CRL_FROM_NET
; // default true
379 case kSecBestAttempt
:
380 /* default, nothing to set */
382 case kSecRequireIfPresentInCertificate
:
383 opts
.CrlFlags
|= CSSM_TP_ACTION_REQUIRE_CRL_IF_PRESENT
;
385 case kSecRequireForAllCertificates
:
386 opts
.CrlFlags
|= CSSM_TP_ACTION_REQUIRE_CRL_PER_CERT
;
389 if(prefsDict
->getBoolValue(kSecRevocationCRLSufficientPerCert
)) {
390 opts
.CrlFlags
|= CSSM_TP_ACTION_CRL_SUFFICIENT
;
393 /* Policy manages its own copy of this data */
394 CSSM_DATA optData
= {sizeof(opts
), (uint8
*)&opts
};
395 crlPolicy
->value() = optData
;
399 /* append in order */
403 /* these SecCFObject go away when the policies array does */
404 CFArrayAppendValue(policies
, ocspPolicy
->handle(false));
405 CFArrayAppendValue(policies
, crlPolicy
->handle(false));
408 CFArrayAppendValue(policies
, crlPolicy
->handle(false));
409 CFArrayAppendValue(policies
, ocspPolicy
->handle(false));
413 CFArrayAppendValue(policies
, ocspPolicy
->handle(false));
418 CFArrayAppendValue(policies
, crlPolicy
->handle(false));
424 * Called when we created the last numAdded Policies in the specified Policy array
425 * (only frees the policy data associated with the extra policies that we inserted;
426 * this does not free the policies array itself.)
428 void Trust::freeAddedRevocationPolicyData(
433 uint32 numPolicies
= (uint32
)CFArrayGetCount(policies
);
434 if(numPolicies
< numAdded
) {
435 /* should never happen - throw? */
439 for(unsigned dex
=numPolicies
-numAdded
; dex
<numPolicies
; dex
++) {
440 SecPolicyRef secPol
= (SecPolicyRef
)CFArrayGetValueAtIndex(policies
, dex
);
441 //SecPointer<Policy> pol = Policy::required(SecPolicyRef(secPol));
442 Policy
*pol
= Policy::required(secPol
);
443 const CssmOid
&oid
= pol
->oid(); // required
444 const CssmData
&optData
= pol
->value(); // optional
447 if(oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
)) {
448 /* currently no CRL-specific policy data */
450 else if(oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
)) {
451 CSSM_APPLE_TP_OCSP_OPTIONS
*opts
= (CSSM_APPLE_TP_OCSP_OPTIONS
*)optData
.Data
;
452 if(opts
->LocalResponder
!= NULL
) {
453 if(opts
->LocalResponder
->Data
!= NULL
) {
454 alloc
.free(opts
->LocalResponder
->Data
);
456 alloc
.free(opts
->LocalResponder
);
459 // managed by Policy alloc.free(optData.Data);
465 * Comparator function to correctly order revocation policies.
467 static CFComparisonResult
compareRevocationPolicies(
472 SecPointer
<Policy
> pol1
= Policy::required(SecPolicyRef(policy1
));
473 SecPointer
<Policy
> pol2
= Policy::required(SecPolicyRef(policy2
));
474 const CssmOid
&oid1
= pol1
->oid();
475 const CssmOid
&oid2
= pol2
->oid();
477 return kCFCompareEqualTo
;
479 bool ocspFirst
= true;
480 if(context
!= NULL
&& CFEqual((CFBooleanRef
)context
, kCFBooleanFalse
)) {
483 const CssmOid lastRevocationOid
= (ocspFirst
) ?
484 CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
) :
485 CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
);
486 const CssmOid firstRevocationOid
= (ocspFirst
) ?
487 CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
) :
488 CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
);
489 if(oid1
== lastRevocationOid
) {
490 /* should be ordered last, after all other policies */
491 return kCFCompareGreaterThan
;
493 if(oid1
== firstRevocationOid
) {
494 /* should be ordered after any policy except lastRevocationOid */
495 if(oid2
== lastRevocationOid
) {
496 return kCFCompareLessThan
;
498 return kCFCompareGreaterThan
;
500 /* normal policy in first position, anything else in second position */
501 return kCFCompareLessThan
;
505 * This method reorders any revocation policies which may be present
506 * in the provided array so they are at the end and evaluated last.
508 void Trust::orderRevocationPolicies(
509 CFMutableArrayRef policies
)
511 if(!policies
|| CFGetTypeID(policies
) != CFArrayGetTypeID()) {
514 /* check revocation prefs to determine which policy goes first */
515 CFBooleanRef ocspFirst
= kCFBooleanTrue
;
517 CFShow(policies
); // before sort
518 CFArraySortValues(policies
, CFRangeMake(0, CFArrayGetCount(policies
)), compareRevocationPolicies
, (void*)ocspFirst
);
519 CFShow(policies
); // after sort, to see what changed
520 // check that policy order is what we expect
521 CFIndex numPolicies
= CFArrayGetCount(policies
);
522 for(CFIndex dex
=0; dex
<numPolicies
; dex
++) {
523 SecPolicyRef secPol
= (SecPolicyRef
)CFArrayGetValueAtIndex(policies
, dex
);
524 SecPointer
<Policy
> pol
= Policy::required(SecPolicyRef(secPol
));
525 const CssmOid
&oid
= pol
->oid();
526 if(oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
)) {
527 CFStringRef s
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("idx %d = OCSP"), dex
);
531 else if(oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
)) {
532 CFStringRef s
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("idx %d = CRL"), dex
);
537 CFStringRef s
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("idx %d = normal"), dex
);
543 CFArraySortValues(policies
, CFRangeMake(0, CFArrayGetCount(policies
)), compareRevocationPolicies
, (void*)ocspFirst
);
548 * This method returns a copy of the mPolicies array which ensures that
549 * revocation checking (preferably OCSP, otherwise CRL) will be attempted.
551 * If OCSP is already in the mPolicies array, this makes sure the
552 * CSSM_TP_ACTION_OCSP_REQUIRE_IF_RESP_PRESENT and CSSM_TP_ACTION_OCSP_SUFFICIENT
553 * flags are set. If it's not already in the array, a new policy object is added.
555 * If CRL is already in the mPolicies array, this makes sure the
556 * CSSM_TP_ACTION_FETCH_CRL_FROM_NET and CSSM_TP_ACTION_CRL_SUFFICIENT flags are
557 * set. If it's not already in the array, a new policy object is added.
559 * Caller is responsible for releasing the returned policies array.
561 CFMutableArrayRef
Trust::forceRevocationPolicies(
568 SecPointer
<Policy
> ocspPolicy
;
569 SecPointer
<Policy
> crlPolicy
;
570 CSSM_APPLE_TP_OCSP_OPT_FLAGS ocspFlags
;
571 CSSM_APPLE_TP_CRL_OPT_FLAGS crlFlags
;
572 bool hasOcspPolicy
= false;
573 bool hasCrlPolicy
= false;
576 ocspFlags
= CSSM_TP_ACTION_OCSP_SUFFICIENT
;
577 crlFlags
= CSSM_TP_ACTION_FETCH_CRL_FROM_NET
| CSSM_TP_ACTION_CRL_SUFFICIENT
;
578 if (requirePerCert
) {
579 ocspFlags
|= CSSM_TP_ACTION_OCSP_REQUIRE_IF_RESP_PRESENT
;
580 crlFlags
|= CSSM_TP_ACTION_REQUIRE_CRL_IF_PRESENT
;
583 CFIndex numPolicies
= (mPolicies
) ? CFArrayGetCount(mPolicies
) : 0;
584 for(CFIndex dex
=0; dex
<numPolicies
; dex
++) {
585 SecPolicyRef secPol
= (SecPolicyRef
)CFArrayGetValueAtIndex(mPolicies
, dex
);
586 SecPointer
<Policy
> pol
= Policy::required(SecPolicyRef(secPol
));
587 const CssmOid
&oid
= pol
->oid();
588 const CssmData
&optData
= pol
->value();
589 if(oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
)) {
590 // make sure OCSP options are set correctly
591 CSSM_APPLE_TP_OCSP_OPTIONS
*opts
= (CSSM_APPLE_TP_OCSP_OPTIONS
*)optData
.Data
;
593 opts
->Flags
|= ocspFlags
;
595 CSSM_APPLE_TP_OCSP_OPTIONS newOpts
;
596 memset(&newOpts
, 0, sizeof(newOpts
));
597 newOpts
.Version
= CSSM_APPLE_TP_OCSP_OPTS_VERSION
;
598 newOpts
.Flags
= ocspFlags
;
599 CSSM_DATA optData
= {sizeof(newOpts
), (uint8
*)&newOpts
};
600 pol
->value() = optData
;
602 hasOcspPolicy
= true;
604 else if(oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
)) {
605 // make sure CRL options are set correctly
606 CSSM_APPLE_TP_CRL_OPTIONS
*opts
= (CSSM_APPLE_TP_CRL_OPTIONS
*)optData
.Data
;
608 opts
->CrlFlags
|= crlFlags
;
610 CSSM_APPLE_TP_CRL_OPTIONS newOpts
;
611 memset(&newOpts
, 0, sizeof(newOpts
));
612 newOpts
.Version
= CSSM_APPLE_TP_CRL_OPTS_VERSION
;
613 newOpts
.CrlFlags
= crlFlags
;
614 CSSM_DATA optData
= {sizeof(newOpts
), (uint8
*)&newOpts
};
615 pol
->value() = optData
;
621 /* We're potentially adding something to mPolicies, so make a copy we can work with */
622 CFMutableArrayRef policies
= CFArrayCreateMutableCopy(NULL
, 0, mPolicies
);
623 if(policies
== NULL
) {
624 throw std::bad_alloc();
627 if(!hasOcspPolicy
&& ocspEnabled
) {
628 /* Cook up a new Policy object */
629 ocspPolicy
= new Policy(mTP
, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
));
630 CSSM_APPLE_TP_OCSP_OPTIONS opts
;
631 memset(&opts
, 0, sizeof(opts
));
632 opts
.Version
= CSSM_APPLE_TP_OCSP_OPTS_VERSION
;
633 opts
.Flags
= ocspFlags
;
635 /* Policy manages its own copy of the options data */
636 CSSM_DATA optData
= {sizeof(opts
), (uint8
*)&opts
};
637 ocspPolicy
->value() = optData
;
639 /* Policies array retains the Policy object */
640 CFArrayAppendValue(policies
, ocspPolicy
->handle(false));
644 if(!hasCrlPolicy
&& crlEnabled
) {
645 /* Cook up a new Policy object */
646 crlPolicy
= new Policy(mTP
, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
));
647 CSSM_APPLE_TP_CRL_OPTIONS opts
;
648 memset(&opts
, 0, sizeof(opts
));
649 opts
.Version
= CSSM_APPLE_TP_CRL_OPTS_VERSION
;
650 opts
.CrlFlags
= crlFlags
;
652 /* Policy manages its own copy of this data */
653 CSSM_DATA optData
= {sizeof(opts
), (uint8
*)&opts
};
654 crlPolicy
->value() = optData
;
656 /* Policies array retains the Policy object */
657 CFArrayAppendValue(policies
, crlPolicy
->handle(false));