2 * Copyright (c) 2003,2011-2012,2014 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@
29 #include <security_asn1/secerr.h>
30 #include <Security/SecKeychain.h>
31 #include <Security/SecKeychainItem.h>
32 #include <Security/SecKeychainSearch.h>
33 #include <Security/SecIdentity.h>
34 #include <Security/SecIdentityPriv.h>
35 #include <Security/SecIdentitySearch.h>
36 #include <Security/SecCertificatePriv.h>
37 #include <Security/SecPolicySearch.h>
38 #include <Security/oidsalg.h>
39 #include <Security/cssmapi.h>
40 #include <Security/oidscert.h>
41 #include <Security/oidscert.h>
44 /* for errKCDuplicateItem */
45 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
49 #define dprintf(args...) fprintf(stderr, args)
51 #define dprintf(args...)
54 /* @@@ Remove this once it's back in the appropriate header. */
55 static const uint8 X509V1IssuerNameStd
[] = {INTEL_X509V3_CERT_R08
, 23};
56 static const CSSM_OID OID_X509V1IssuerNameStd
= {INTEL_X509V3_CERT_R08_LENGTH
+1, (uint8
*)X509V1IssuerNameStd
};
59 * Normalize a Printable String. Per RFC2459 (4.1.2.4), printable strings are case
60 * insensitive and we're supposed to ignore leading and trailing
61 * whitespace, and collapse multiple whitespace characters into one.
64 CERT_NormalizeString(CSSM_DATA_PTR string
)
66 char *pD
, *pCh
, *pEos
;
71 pD
= pCh
= (char *)string
->Data
;
72 pEos
= pCh
+ string
->Length
- 1;
74 /* Strip trailing NULL terminators */
78 /* Remove trailing spaces */
82 /* Point to one past last non-space character */
85 /* skip all leading whitespace */
86 while(isspace(*pCh
) && (pCh
< pEos
))
89 /* Eliminate multiple whitespace and convent to upper case.
90 * pCh points to first non-white char.
91 * pD still points to start of string. */
98 /* skip 'til next nonwhite */
99 while(isspace(*pCh
) && (pCh
< pEos
))
104 string
->Length
= pD
- (char *)string
->Data
;
108 * Normalize an RDN. Per RFC2459 (4.1.2.4), printable strings are case
109 * insensitive and we're supposed to ignore leading and trailing
110 * whitespace, and collapse multiple whitespace characters into one.
112 * Incoming NSS_Name is assumed to be entirely within specifed coder's
113 * address space; we'll be munging some of that and possibly replacing
114 * some pointers with others allocated from the same space.
117 CERT_NormalizeX509NameNSS(NSS_Name
*nssName
)
121 for (rdn
= *nssName
->rdns
; rdn
; ++rdn
)
124 for (attr
= *rdn
->atvs
; attr
; ++attr
)
127 * attr->value is an ASN_ANY containing an encoded
128 * string. We only normalize Prinatable String types.
129 * If we find one, decode it, normalize it, encode the
130 * result, and put the encoding back in attr->value.
131 * We temporarily "leak" the original string, which only
132 * has a lifetime of the incoming SecNssCoder.
134 NSS_TaggedItem
*attrVal
= &attr
->value
;
135 if(attrVal
->tag
!= SEC_ASN1_PRINTABLE_STRING
)
138 CERT_NormalizeString(&attrVal
->item
);
143 SecCertificateRef
CERT_FindCertByNicknameOrEmailAddr(SecKeychainRef keychainOrArray
, char *name
)
145 SecCertificateRef certificate
;
146 OSStatus status
=SecCertificateFindByEmail(keychainOrArray
,name
,&certificate
);
147 return status
==noErr
?certificate
:NULL
;
150 SecPublicKeyRef
SECKEY_CopyPublicKey(SecPublicKeyRef pubKey
)
156 void SECKEY_DestroyPublicKey(SecPublicKeyRef pubKey
)
161 SecPublicKeyRef
SECKEY_CopyPrivateKey(SecPublicKeyRef privKey
)
167 void SECKEY_DestroyPrivateKey(SecPublicKeyRef privKey
)
172 void CERT_DestroyCertificate(SecCertificateRef cert
)
177 SecCertificateRef
CERT_DupCertificate(SecCertificateRef cert
)
183 SecIdentityRef
CERT_FindIdentityByUsage(SecKeychainRef keychainOrArray
,
184 char *nickname
, SECCertUsage usage
, Boolean validOnly
, void *proto_win
)
186 SecIdentityRef identityRef
= NULL
;
187 SecCertificateRef cert
= CERT_FindCertByNicknameOrEmailAddr(keychainOrArray
, nickname
);
191 SecIdentityCreateWithCertificate(keychainOrArray
, cert
, &identityRef
);
197 SecCertificateRef
CERT_FindUserCertByUsage(SecKeychainRef keychainOrArray
,
198 char *nickname
,SECCertUsage usage
,Boolean validOnly
,void *proto_win
)
200 SecItemClass itemClass
= kSecCertificateItemClass
;
201 SecKeychainSearchRef searchRef
;
202 SecKeychainItemRef itemRef
= NULL
;
204 SecKeychainAttribute attrs
[1];
205 const char *serialNumber
= "12345678";
206 // const SecKeychainAttributeList attrList;
208 attrs
[0].tag
= kSecLabelItemAttr
;
209 attrs
[0].length
= strlen(nickname
)+1;
210 attrs
[0].data
= nickname
;
212 attrs
[0].tag
= kSecSerialNumberItemAttr
;
213 attrs
[0].length
= (UInt32
)strlen(serialNumber
)+1;
214 attrs
[0].data
= (uint8
*)serialNumber
;
216 SecKeychainAttributeList attrList
= { 0, attrs
};
218 status
= SecKeychainSearchCreateFromAttributes(keychainOrArray
,itemClass
,&attrList
,&searchRef
);
221 printf("CERT_FindUserCertByUsage: SecKeychainSearchCreateFromAttributes:%d",(int)status
);
224 status
= SecKeychainSearchCopyNext(searchRef
,&itemRef
);
226 printf("CERT_FindUserCertByUsage: SecKeychainSearchCopyNext:%d",(int)status
);
227 CFRelease(searchRef
);
228 return (SecCertificateRef
)itemRef
;
232 startNewClass(X509Certificate)
233 CertType, kSecCertTypeItemAttr, "CertType", 0, NULL, UINT32)
234 CertEncoding, kSecCertEncodingItemAttr, "CertEncoding", 0, NULL, UINT32)
235 PrintName, kSecLabelItemAttr, "PrintName", 0, NULL, BLOB)
236 Alias, kSecAlias, "Alias", 0, NULL, BLOB)
237 Subject, kSecSubjectItemAttr, "Subject", 0, NULL, BLOB)
238 Issuer, kSecIssuerItemAttr, "Issuer", 0, NULL, BLOB)
239 SerialNumber, kSecSerialNumberItemAttr, "SerialNumber", 0, NULL, BLOB)
240 SubjectKeyIdentifier, kSecSubjectKeyIdentifierItemAttr, "SubjectKeyIdentifier", 0, NULL, BLOB)
241 PublicKeyHash, kSecPublicKeyHashItemAttr, "PublicKeyHash", 0, NULL, BLOB)
245 CFArrayRef
CERT_CertChainFromCert(SecCertificateRef cert
, SECCertUsage usage
, Boolean includeRoot
)
247 SecPolicySearchRef searchRef
= NULL
;
248 SecPolicyRef policy
= NULL
;
249 CFArrayRef wrappedCert
= NULL
;
250 SecTrustRef trust
= NULL
;
251 CFArrayRef certChain
= NULL
;
252 CSSM_TP_APPLE_EVIDENCE_INFO
*statusChain
;
253 CFDataRef actionData
= NULL
;
259 status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, &CSSMOID_APPLE_X509_BASIC
, NULL
, &searchRef
);
262 status
= SecPolicySearchCopyNext(searchRef
, &policy
);
266 wrappedCert
= CERT_CertListFromCert(cert
);
267 status
= SecTrustCreateWithCertificates(wrappedCert
, policy
, &trust
);
271 /* Tell SecTrust that we don't care if any certs in the chain have expired,
272 nor do we want to stop when encountering a cert with a trust setting;
273 we always want to build the full chain.
275 CSSM_APPLE_TP_ACTION_DATA localActionData
= {
276 CSSM_APPLE_TP_ACTION_VERSION
,
277 CSSM_TP_ACTION_ALLOW_EXPIRED
| CSSM_TP_ACTION_ALLOW_EXPIRED_ROOT
279 actionData
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, (const UInt8
*)&localActionData
, sizeof(localActionData
), kCFAllocatorNull
);
283 status
= SecTrustSetParameters(trust
, CSSM_TP_ACTION_DEFAULT
, actionData
);
287 status
= SecTrustEvaluate(trust
, NULL
);
291 status
= SecTrustGetResult(trust
, NULL
, &certChain
, &statusChain
);
295 /* We don't drop the root if there is only 1 (self signed) certificate in the chain. */
296 if (!includeRoot
&& CFArrayGetCount(certChain
) > 1)
298 CFMutableArrayRef subChain
= CFArrayCreateMutableCopy(NULL
, 0, certChain
);
299 CFRelease(certChain
);
300 certChain
= subChain
;
302 CFArrayRemoveValueAtIndex(subChain
, CFArrayGetCount(subChain
) - 1);
307 CFRelease(searchRef
);
311 CFRelease(wrappedCert
);
315 CFRelease(actionData
);
316 if (certChain
&& status
)
318 CFRelease(certChain
);
325 CFArrayRef
CERT_CertListFromCert(SecCertificateRef cert
)
327 const void *value
= cert
;
328 return cert
? CFArrayCreate(NULL
, &value
, 1, &kCFTypeArrayCallBacks
) : NULL
;
331 CFArrayRef
CERT_DupCertList(CFArrayRef oldList
)
337 // Extract a public key object from a SubjectPublicKeyInfo
338 SecPublicKeyRef
CERT_ExtractPublicKey(SecCertificateRef cert
)
340 SecPublicKeyRef keyRef
= NULL
;
341 SecCertificateCopyPublicKey(cert
,&keyRef
);
345 SECStatus
CERT_CheckCertUsage (SecCertificateRef cert
,unsigned char usage
)
348 // @@@ It's all good, it's ok.
352 // Find a certificate in the database by a email address
353 // "emailAddr" is the email address to look up
354 SecCertificateRef
CERT_FindCertByEmailAddr(SecKeychainRef keychainOrArray
, char *emailAddr
)
360 // Find a certificate in the database by a DER encoded certificate
361 // "derCert" is the DER encoded certificate
362 SecCertificateRef
CERT_FindCertByDERCert(SecKeychainRef keychainOrArray
, const SECItem
*derCert
)
364 // @@@ Technically this should look though keychainOrArray for a cert matching this one I guess.
365 SecCertificateRef cert
= NULL
;
368 rv
= SecCertificateCreateFromData(derCert
, CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
, &cert
);
371 PORT_SetError(SEC_ERROR_NO_EMAIL_CERT
);
379 static int compareCssmData(
383 if((d1
== NULL
) || (d2
== NULL
)) {
386 if(d1
->Length
!= d2
->Length
) {
389 if(memcmp(d1
->Data
, d2
->Data
, d1
->Length
)) {
395 // Generate a certificate key from the issuer and serialnumber, then look it up in the database.
396 // Return the cert if found. "issuerAndSN" is the issuer and serial number to look for
397 SecCertificateRef
CERT_FindCertByIssuerAndSN (CFTypeRef keychainOrArray
,
398 CSSM_DATA_PTR
*rawCerts
, PRArenaPool
*pl
, const SecCmsIssuerAndSN
*issuerAndSN
)
400 SecCertificateRef certificate
;
401 int numRawCerts
= SecCmsArrayCount((void **)rawCerts
);
406 * First search the rawCerts array.
408 for(dex
=0; dex
<numRawCerts
; dex
++) {
409 ortn
= SecCertificateCreateFromData(rawCerts
[dex
],
410 CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
,
415 SecCmsIssuerAndSN
*isn
= CERT_GetCertIssuerAndSN(pl
, certificate
);
417 CFRelease(certificate
);
420 if(!compareCssmData(&isn
->derIssuer
, &issuerAndSN
->derIssuer
)) {
421 CFRelease(certificate
);
424 if(!compareCssmData(&isn
->serialNumber
, &issuerAndSN
->serialNumber
)) {
425 CFRelease(certificate
);
429 dprintf("CERT_FindCertByIssuerAndSN: found cert %p\n", certificate
);
433 /* now search keychain(s) */
434 OSStatus status
= SecCertificateFindByIssuerAndSN(keychainOrArray
, &issuerAndSN
->derIssuer
,
435 &issuerAndSN
->serialNumber
, &certificate
);
438 PORT_SetError(SEC_ERROR_NO_EMAIL_CERT
);
445 SecCertificateRef
CERT_FindCertBySubjectKeyID (CFTypeRef keychainOrArray
,
446 CSSM_DATA_PTR
*rawCerts
, const SECItem
*subjKeyID
)
448 SecCertificateRef certificate
;
449 int numRawCerts
= SecCmsArrayCount((void **)rawCerts
);
455 * First search the rawCerts array.
457 for(dex
=0; dex
<numRawCerts
; dex
++) {
459 ortn
= SecCertificateCreateFromData(rawCerts
[dex
],
460 CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
,
465 if(CERT_FindSubjectKeyIDExtension(certificate
, &skid
)) {
466 CFRelease(certificate
);
470 match
= compareCssmData(subjKeyID
, &skid
);
471 SECITEM_FreeItem(&skid
, PR_FALSE
);
476 CFRelease(certificate
);
479 /* now search keychain(s) */
480 OSStatus status
= SecCertificateFindBySubjectKeyID(keychainOrArray
,subjKeyID
,&certificate
);
483 PORT_SetError(SEC_ERROR_NO_EMAIL_CERT
);
490 static SecIdentityRef
491 CERT_FindIdentityByCertificate (CFTypeRef keychainOrArray
, SecCertificateRef certificate
)
493 SecIdentityRef identity
= NULL
;
494 SecIdentityCreateWithCertificate(keychainOrArray
, certificate
, &identity
);
496 PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT
);
502 CERT_FindIdentityByIssuerAndSN (CFTypeRef keychainOrArray
, const SecCmsIssuerAndSN
*issuerAndSN
)
504 SecCertificateRef certificate
= CERT_FindCertByIssuerAndSN(keychainOrArray
, NULL
, NULL
, issuerAndSN
);
508 return CERT_FindIdentityByCertificate(keychainOrArray
, certificate
);
512 CERT_FindIdentityBySubjectKeyID (CFTypeRef keychainOrArray
, const SECItem
*subjKeyID
)
514 SecCertificateRef certificate
= CERT_FindCertBySubjectKeyID(keychainOrArray
, NULL
, subjKeyID
);
518 return CERT_FindIdentityByCertificate(keychainOrArray
, certificate
);
521 // find the smime symmetric capabilities profile for a given cert
522 SECItem
*CERT_FindSMimeProfile(SecCertificateRef cert
)
527 // Return the decoded value of the subjectKeyID extension. The caller should
528 // free up the storage allocated in retItem->data.
529 SECStatus
CERT_FindSubjectKeyIDExtension (SecCertificateRef cert
, SECItem
*retItem
)
531 CSSM_DATA_PTR fieldValue
= NULL
;
533 CSSM_X509_EXTENSION
*extp
;
534 CE_SubjectKeyID
*skid
;
536 ortn
= SecCertificateCopyFirstFieldValue(cert
, &CSSMOID_SubjectKeyIdentifier
,
538 if(ortn
|| (fieldValue
== NULL
)) {
539 /* this cert doesn't have that extension */
542 extp
= (CSSM_X509_EXTENSION
*)fieldValue
->Data
;
543 skid
= (CE_SubjectKeyID
*)extp
->value
.parsedValue
;
544 retItem
->Data
= (uint8
*)PORT_Alloc(skid
->Length
);
545 retItem
->Length
= skid
->Length
;
546 memmove(retItem
->Data
, skid
->Data
, retItem
->Length
);
547 SecCertificateReleaseFirstFieldValue(cert
, &CSSMOID_SubjectKeyIdentifier
,
552 // Extract the issuer and serial number from a certificate
553 SecCmsIssuerAndSN
*CERT_GetCertIssuerAndSN(PRArenaPool
*pl
, SecCertificateRef cert
)
556 SecCmsIssuerAndSN
*certIssuerAndSN
;
557 SecCertificateRef certRef
;
558 SecCertificateRef itemImplRef
= NULL
;
559 CSSM_CL_HANDLE clHandle
;
560 CSSM_DATA_PTR serialNumber
= 0;
561 CSSM_DATA_PTR issuer
= 0;
562 CSSM_DATA certData
= {};
563 CSSM_HANDLE resultsHandle
= 0;
564 uint32 numberOfFields
= 0;
568 mark
= PORT_ArenaMark(pl
);
570 /* Retain input cert and get pointer to its data */
571 certRef
= (SecCertificateRef
)((cert
) ? CFRetain(cert
) : NULL
);
572 status
= SecCertificateGetData(certRef
, &certData
);
576 // Convert unified input certRef to itemImpl instance.
577 // note: must not release this instance while we're using its CL handle!
578 itemImplRef
= SecCertificateCreateItemImplInstance(cert
);
579 status
= SecCertificateGetCLHandle_legacy(itemImplRef
, &clHandle
);
581 status
= SecCertificateGetCLHandle(certRef
, &clHandle
);
586 /* Get the issuer from the cert. */
587 result
= CSSM_CL_CertGetFirstFieldValue(clHandle
, &certData
,
588 &OID_X509V1IssuerNameStd
, &resultsHandle
, &numberOfFields
, &issuer
);
590 if (result
|| numberOfFields
< 1)
592 result
= CSSM_CL_CertAbortQuery(clHandle
, resultsHandle
);
596 /* Get the serialNumber from the cert. */
597 result
= CSSM_CL_CertGetFirstFieldValue(clHandle
, &certData
,
598 &CSSMOID_X509V1SerialNumber
, &resultsHandle
, &numberOfFields
, &serialNumber
);
599 if (result
|| numberOfFields
< 1)
601 result
= CSSM_CL_CertAbortQuery(clHandle
, resultsHandle
);
605 /* Allocate the SecCmsIssuerAndSN struct. */
606 certIssuerAndSN
= (SecCmsIssuerAndSN
*)PORT_ArenaZAlloc (pl
, sizeof(SecCmsIssuerAndSN
));
607 if (certIssuerAndSN
== NULL
)
610 /* Copy the issuer. */
611 certIssuerAndSN
->derIssuer
.Data
= (uint8
*) PORT_ArenaAlloc(pl
, issuer
->Length
);
612 if (!certIssuerAndSN
->derIssuer
.Data
)
614 PORT_Memcpy(certIssuerAndSN
->derIssuer
.Data
, issuer
->Data
, issuer
->Length
);
615 certIssuerAndSN
->derIssuer
.Length
= issuer
->Length
;
617 /* Copy the serialNumber. */
618 certIssuerAndSN
->serialNumber
.Data
= (uint8
*) PORT_ArenaAlloc(pl
, serialNumber
->Length
);
619 if (!certIssuerAndSN
->serialNumber
.Data
)
621 PORT_Memcpy(certIssuerAndSN
->serialNumber
.Data
, serialNumber
->Data
, serialNumber
->Length
);
622 certIssuerAndSN
->serialNumber
.Length
= serialNumber
->Length
;
624 PORT_ArenaUnmark(pl
, mark
);
626 CSSM_CL_FreeFieldValue(clHandle
, &CSSMOID_X509V1SerialNumber
, serialNumber
);
627 CSSM_CL_FreeFieldValue(clHandle
, &OID_X509V1IssuerNameStd
, issuer
);
630 CFRelease(itemImplRef
);
634 return certIssuerAndSN
;
637 PORT_ArenaRelease(pl
, mark
);
640 CSSM_CL_FreeFieldValue(clHandle
, &CSSMOID_X509V1SerialNumber
, serialNumber
);
642 CSSM_CL_FreeFieldValue(clHandle
, &OID_X509V1IssuerNameStd
, issuer
);
644 CFRelease(itemImplRef
);
648 PORT_SetError(SEC_INTERNAL_ONLY
);
652 // import a collection of certs into the temporary or permanent cert database
653 SECStatus
CERT_ImportCerts(SecKeychainRef keychain
, SECCertUsage usage
, unsigned int ncerts
,
654 SECItem
**derCerts
, SecCertificateRef
**retCerts
, Boolean keepCerts
, Boolean caOnly
, char *nickname
)
656 OSStatus rv
= SECFailure
;
657 SecCertificateRef cert
;
660 // @@@ Do something with caOnly and nickname
661 if (caOnly
|| nickname
)
664 for (ci
= 0; ci
< ncerts
; ++ci
)
666 rv
= SecCertificateCreateFromData(derCerts
[ci
], CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
, &cert
);
671 rv
= SecCertificateAddToKeychain(cert
, keychain
);
674 if (rv
== errKCDuplicateItem
)
696 SECStatus
CERT_SaveSMimeProfile(SecCertificateRef cert
, SECItem
*emailProfile
,SECItem
*profileTime
)
698 fprintf(stderr
, "WARNING: CERT_SaveSMimeProfile unimplemented\n");
702 // Check the hostname to make sure that it matches the shexp that
703 // is given in the common name of the certificate.
704 SECStatus
CERT_VerifyCertName(SecCertificateRef cert
, const char *hostname
)
706 fprintf(stderr
, "WARNING: CERT_VerifyCertName unimplemented\n");
711 ** OLD OBSOLETE FUNCTIONS with enum SECCertUsage - DO NOT USE FOR NEW CODE
712 ** verify a certificate by checking validity times against a certain time,
713 ** that we trust the issuer, and that the signature on the certificate is
715 ** "cert" the certificate to verify
716 ** "checkSig" only check signatures if true
719 CERT_VerifyCert(SecKeychainRef keychainOrArray
, SecCertificateRef cert
,
720 const CSSM_DATA_PTR
*otherCerts
, /* intermediates */
721 CFTypeRef policies
, CFAbsoluteTime stime
, SecTrustRef
*trustRef
)
723 CFMutableArrayRef certificates
= NULL
;
724 SecTrustRef trust
= NULL
;
726 int numOtherCerts
= SecCmsArrayCount((void **)otherCerts
);
730 * Certs to evaluate: first the leaf - our cert - then all the rest we know
731 * about. It's OK for otherCerts to contain a copy of the leaf.
733 certificates
= CFArrayCreateMutable(NULL
, numOtherCerts
+ 1, &kCFTypeArrayCallBacks
);
734 CFArrayAppendValue(certificates
, cert
);
735 for(dex
=0; dex
<numOtherCerts
; dex
++) {
736 SecCertificateRef intCert
;
738 rv
= SecCertificateCreateFromData(otherCerts
[dex
],
739 CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
,
744 CFArrayAppendValue(certificates
, intCert
);
747 rv
= SecTrustCreateWithCertificates(certificates
, policies
, &trust
);
748 CFRelease(certificates
);
753 rv
= SecTrustSetKeychains(trust
, keychainOrArray
);
757 CFDateRef verifyDate
= CFDateCreate(NULL
, stime
);
758 rv
= SecTrustSetVerifyDate(trust
, verifyDate
);
759 CFRelease(verifyDate
);
769 SecTrustResultType result
;
770 /* The caller doesn't want a SecTrust object, so let's evaluate it for them. */
771 rv
= SecTrustEvaluate(trust
, &result
);
777 case kSecTrustResultProceed
:
778 case kSecTrustResultUnspecified
:
779 /* TP Verification succeeded and there was either a UserTurst entry
780 telling us to procceed, or no user trust setting was specified. */
784 PORT_SetError(SEC_ERROR_UNTRUSTED_CERT
);
793 #if 0 /* debugging */
794 syslog(LOG_ERR
, "CERT_VerifyCert has failed with %d (input policies and output trust follow)",
796 if (policies
) CFShow(policies
);
797 if (trust
) CFShow(trust
);
802 CFRelease(certificates
);
807 CERT_PolicyForCertUsage(SECCertUsage certUsage
)
809 SecPolicySearchRef search
= NULL
;
810 SecPolicyRef policy
= NULL
;
811 const CSSM_OID
*policyOID
;
816 case certUsageSSLServerWithStepUp
:
818 case certUsageVerifyCA
:
822 case certUsageSSLClient
:
823 case certUsageSSLServer
:
824 policyOID
= &CSSMOID_APPLE_TP_SSL
;
826 case certUsageUserCertImport
:
827 policyOID
= &CSSMOID_APPLE_TP_CSR_GEN
;
829 case certUsageStatusResponder
:
830 policyOID
= &CSSMOID_APPLE_TP_REVOCATION_OCSP
;
832 case certUsageObjectSigner
:
833 case certUsageProtectedObjectSigner
:
834 policyOID
= &CSSMOID_APPLE_ISIGN
;
836 case certUsageEmailSigner
:
837 case certUsageEmailRecipient
:
838 policyOID
= &CSSMOID_APPLE_X509_BASIC
;
843 rv
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, policyOID
, NULL
, &search
);
847 rv
= SecPolicySearchCopyNext(search
, &policy
);
852 if(search
) CFRelease(search
);