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/SecPolicyPriv.h>
38 #include <Security/oidsalg.h>
39 #include <Security/cssmapi.h>
40 #include <Security/oidscert.h>
41 #include <Security/oidscert.h>
42 #include <utilities/SecCFWrappers.h>
45 /* for errKCDuplicateItem */
46 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
50 #define dprintf(args...) fprintf(stderr, args)
52 #define dprintf(args...)
56 * Normalize a Printable String. Per RFC2459 (4.1.2.4), printable strings are case
57 * insensitive and we're supposed to ignore leading and trailing
58 * whitespace, and collapse multiple whitespace characters into one.
61 CERT_NormalizeString(CSSM_DATA_PTR string
)
63 char *pD
, *pCh
, *pEos
;
68 pD
= pCh
= (char *)string
->Data
;
69 pEos
= pCh
+ string
->Length
- 1;
71 /* Strip trailing NULL terminators */
75 /* Remove trailing spaces */
79 /* Point to one past last non-space character */
82 /* skip all leading whitespace */
83 while(isspace(*pCh
) && (pCh
< pEos
))
86 /* Eliminate multiple whitespace and convent to upper case.
87 * pCh points to first non-white char.
88 * pD still points to start of string. */
95 /* skip 'til next nonwhite */
96 while(isspace(*pCh
) && (pCh
< pEos
))
101 string
->Length
= pD
- (char *)string
->Data
;
105 * Normalize an RDN. Per RFC2459 (4.1.2.4), printable strings are case
106 * insensitive and we're supposed to ignore leading and trailing
107 * whitespace, and collapse multiple whitespace characters into one.
109 * Incoming NSS_Name is assumed to be entirely within specifed coder's
110 * address space; we'll be munging some of that and possibly replacing
111 * some pointers with others allocated from the same space.
114 CERT_NormalizeX509NameNSS(NSS_Name
*nssName
)
118 for (rdn
= *nssName
->rdns
; rdn
; ++rdn
)
121 for (attr
= *rdn
->atvs
; attr
; ++attr
)
124 * attr->value is an ASN_ANY containing an encoded
125 * string. We only normalize Prinatable String types.
126 * If we find one, decode it, normalize it, encode the
127 * result, and put the encoding back in attr->value.
128 * We temporarily "leak" the original string, which only
129 * has a lifetime of the incoming SecNssCoder.
131 NSS_TaggedItem
*attrVal
= &attr
->value
;
132 if(attrVal
->tag
!= SEC_ASN1_PRINTABLE_STRING
)
135 CERT_NormalizeString(&attrVal
->item
);
140 SecCertificateRef
CERT_FindCertByNicknameOrEmailAddr(SecKeychainRef keychainOrArray
, char *name
)
142 SecCertificateRef certificate
;
143 OSStatus status
=SecCertificateFindByEmail(keychainOrArray
,name
,&certificate
);
144 return status
==noErr
?certificate
:NULL
;
147 SecPublicKeyRef
SECKEY_CopyPublicKey(SecPublicKeyRef pubKey
)
153 void SECKEY_DestroyPublicKey(SecPublicKeyRef pubKey
)
158 SecPublicKeyRef
SECKEY_CopyPrivateKey(SecPublicKeyRef privKey
)
164 void SECKEY_DestroyPrivateKey(SecPublicKeyRef privKey
)
169 void CERT_DestroyCertificate(SecCertificateRef cert
)
174 SecCertificateRef
CERT_DupCertificate(SecCertificateRef cert
)
180 SecIdentityRef
CERT_FindIdentityByUsage(SecKeychainRef keychainOrArray
,
181 char *nickname
, SECCertUsage usage
, Boolean validOnly
, void *proto_win
)
183 SecIdentityRef identityRef
= NULL
;
184 SecCertificateRef cert
= CERT_FindCertByNicknameOrEmailAddr(keychainOrArray
, nickname
);
188 SecIdentityCreateWithCertificate(keychainOrArray
, cert
, &identityRef
);
194 SecCertificateRef
CERT_FindUserCertByUsage(SecKeychainRef keychainOrArray
,
195 char *nickname
,SECCertUsage usage
,Boolean validOnly
,void *proto_win
)
197 SecItemClass itemClass
= kSecCertificateItemClass
;
198 SecKeychainSearchRef searchRef
;
199 SecKeychainItemRef itemRef
= NULL
;
201 SecKeychainAttribute attrs
[1];
202 const char *serialNumber
= "12345678";
203 // const SecKeychainAttributeList attrList;
205 attrs
[0].tag
= kSecLabelItemAttr
;
206 attrs
[0].length
= strlen(nickname
)+1;
207 attrs
[0].data
= nickname
;
209 attrs
[0].tag
= kSecSerialNumberItemAttr
;
210 attrs
[0].length
= (UInt32
)strlen(serialNumber
)+1;
211 attrs
[0].data
= (uint8
*)serialNumber
;
213 SecKeychainAttributeList attrList
= { 0, attrs
};
215 status
= SecKeychainSearchCreateFromAttributes(keychainOrArray
,itemClass
,&attrList
,&searchRef
);
218 printf("CERT_FindUserCertByUsage: SecKeychainSearchCreateFromAttributes:%d",(int)status
);
221 status
= SecKeychainSearchCopyNext(searchRef
,&itemRef
);
223 printf("CERT_FindUserCertByUsage: SecKeychainSearchCopyNext:%d",(int)status
);
224 CFRelease(searchRef
);
225 return (SecCertificateRef
)itemRef
;
229 startNewClass(X509Certificate)
230 CertType, kSecCertTypeItemAttr, "CertType", 0, NULL, UINT32)
231 CertEncoding, kSecCertEncodingItemAttr, "CertEncoding", 0, NULL, UINT32)
232 PrintName, kSecLabelItemAttr, "PrintName", 0, NULL, BLOB)
233 Alias, kSecAlias, "Alias", 0, NULL, BLOB)
234 Subject, kSecSubjectItemAttr, "Subject", 0, NULL, BLOB)
235 Issuer, kSecIssuerItemAttr, "Issuer", 0, NULL, BLOB)
236 SerialNumber, kSecSerialNumberItemAttr, "SerialNumber", 0, NULL, BLOB)
237 SubjectKeyIdentifier, kSecSubjectKeyIdentifierItemAttr, "SubjectKeyIdentifier", 0, NULL, BLOB)
238 PublicKeyHash, kSecPublicKeyHashItemAttr, "PublicKeyHash", 0, NULL, BLOB)
242 CFArrayRef
CERT_CertChainFromCert(SecCertificateRef cert
, SECCertUsage usage
, Boolean includeRoot
, Boolean mustIncludeRoot
)
244 SecPolicyRef policy
= NULL
;
245 CFArrayRef wrappedCert
= NULL
;
246 SecTrustRef trust
= NULL
;
247 CFMutableArrayRef certs
= NULL
;
254 policy
= SecPolicyCreateBasicX509();
259 wrappedCert
= CERT_CertListFromCert(cert
);
260 status
= SecTrustCreateWithCertificates(wrappedCert
, policy
, &trust
);
265 /* SecTrustEvaluate will build us the best chain available using its heuristics.
266 * We'll ignore the trust result. */
267 SecTrustResultType result
;
268 status
= SecTrustEvaluate(trust
, &result
);
272 CFIndex idx
, count
= SecTrustGetCertificateCount(trust
);
274 /* If we weren't able to build a chain to a self-signed cert, warn. */
275 Boolean isSelfSigned
= false;
276 SecCertificateRef lastCert
= SecTrustGetCertificateAtIndex(trust
, count
- 1);
277 if (lastCert
&& (0 == SecCertificateIsSelfSigned(lastCert
, &isSelfSigned
)) && !isSelfSigned
) {
278 CFStringRef commonName
= NULL
;
279 (void)SecCertificateCopyCommonName(cert
, &commonName
);
280 fprintf(stderr
, "Warning: unable to build chain to self-signed root for signer \"%s\"\n",
281 commonName
? CFStringGetCStringPtr(commonName
, kCFStringEncodingUTF8
) : "");
282 if (commonName
) { CFRelease(commonName
); }
284 // we don't have a root, so if the caller required one, fail
285 if (mustIncludeRoot
) {
286 status
= errSecCreateChainFailed
;
290 /* We don't drop the root if there is only 1 certificate in the chain. */
291 if (isSelfSigned
&& !includeRoot
&& count
> 1) {
295 certs
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
296 for(idx
= 0; idx
< count
; idx
++) {
297 CFArrayAppendValue(certs
, SecTrustGetCertificateAtIndex(trust
, idx
));
301 if (policy
) { CFRelease(policy
); }
302 if (wrappedCert
) { CFRelease(wrappedCert
); }
303 if (trust
) { CFRelease(trust
); }
304 if (certs
&& status
) {
312 CFArrayRef
CERT_CertListFromCert(SecCertificateRef cert
)
314 const void *value
= cert
;
315 return cert
? CFArrayCreate(NULL
, &value
, 1, &kCFTypeArrayCallBacks
) : NULL
;
318 CFArrayRef
CERT_DupCertList(CFArrayRef oldList
)
324 // Extract a public key object from a SubjectPublicKeyInfo
325 SecPublicKeyRef
CERT_ExtractPublicKey(SecCertificateRef cert
)
327 return SecCertificateCopyKey(cert
);
330 SECStatus
CERT_CheckCertUsage (SecCertificateRef cert
,unsigned char usage
)
333 // @@@ It's all good, it's ok.
337 // Find a certificate in the database by a email address
338 // "emailAddr" is the email address to look up
339 SecCertificateRef
CERT_FindCertByEmailAddr(SecKeychainRef keychainOrArray
, char *emailAddr
)
345 // Find a certificate in the database by a DER encoded certificate
346 // "derCert" is the DER encoded certificate
347 SecCertificateRef
CERT_FindCertByDERCert(SecKeychainRef keychainOrArray
, const SECItem
*derCert
)
349 // @@@ Technically this should look though keychainOrArray for a cert matching this one I guess.
350 SecCertificateRef cert
= NULL
;
353 rv
= SecCertificateCreateFromData(derCert
, CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
, &cert
);
356 PORT_SetError(SEC_ERROR_NO_EMAIL_CERT
);
364 int CERT_CompareCssmData(const CSSM_DATA
*d1
, const CSSM_DATA
*d2
)
366 if((d1
== NULL
) || (d2
== NULL
)) {
369 if(d1
->Length
!= d2
->Length
) {
372 if(memcmp(d1
->Data
, d2
->Data
, d1
->Length
)) {
378 // Generate a certificate key from the issuer and serialnumber, then look it up in the database.
379 // Return the cert if found. "issuerAndSN" is the issuer and serial number to look for
380 SecCertificateRef
CERT_FindCertByIssuerAndSN (CFTypeRef keychainOrArray
,
381 CSSM_DATA_PTR
*rawCerts
, CFArrayRef certList
, PRArenaPool
*pl
, const SecCmsIssuerAndSN
*issuerAndSN
)
383 SecCertificateRef certificate
= NULL
;
384 int numRawCerts
= SecCmsArrayCount((void **)rawCerts
);
389 * First search the rawCerts array.
391 for(dex
=0; dex
<numRawCerts
; dex
++) {
392 ortn
= SecCertificateCreateFromData(rawCerts
[dex
],
393 CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
,
398 SecCmsIssuerAndSN
*isn
= CERT_GetCertIssuerAndSN(pl
, certificate
);
400 CFRelease(certificate
);
403 if(!CERT_CompareCssmData(&isn
->derIssuer
, &issuerAndSN
->derIssuer
)) {
404 CFRelease(certificate
);
407 if(!CERT_CompareCssmData(&isn
->serialNumber
, &issuerAndSN
->serialNumber
)) {
408 CFRelease(certificate
);
412 dprintf("CERT_FindCertByIssuerAndSN: found cert %p\n", certificate
);
416 /* Search the user-added certList */
417 if (certList
&& CFArrayGetCount(certList
)) {
418 CFIndex c
, count
= CFArrayGetCount(certList
);
419 for (c
= 0; c
< count
; c
++) {
420 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(certList
, c
);
421 SecCmsIssuerAndSN
*isn
= CERT_GetCertIssuerAndSN(pl
, cert
);
425 if(!CERT_CompareCssmData(&isn
->derIssuer
, &issuerAndSN
->derIssuer
)) {
428 if(!CERT_CompareCssmData(&isn
->serialNumber
, &issuerAndSN
->serialNumber
)) {
434 if (certificate
) { return certificate
; }
437 /* now search keychain(s) */
438 OSStatus status
= SecCertificateFindByIssuerAndSN(keychainOrArray
, &issuerAndSN
->derIssuer
,
439 &issuerAndSN
->serialNumber
, &certificate
);
442 PORT_SetError(SEC_ERROR_NO_EMAIL_CERT
);
449 SecCertificateRef
CERT_FindCertBySubjectKeyID (CFTypeRef keychainOrArray
,
450 CSSM_DATA_PTR
*rawCerts
, CFArrayRef certList
, const SECItem
*subjKeyID
)
452 SecCertificateRef certificate
= NULL
;
453 int numRawCerts
= SecCmsArrayCount((void **)rawCerts
);
459 * First search the rawCerts array.
461 for(dex
=0; dex
<numRawCerts
; dex
++) {
463 ortn
= SecCertificateCreateFromData(rawCerts
[dex
],
464 CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
,
469 if(CERT_FindSubjectKeyIDExtension(certificate
, &skid
)) {
470 CFRelease(certificate
);
474 match
= CERT_CompareCssmData(subjKeyID
, &skid
);
475 SECITEM_FreeItem(&skid
, PR_FALSE
);
480 CFRelease(certificate
);
483 /* Search the user-added certList */
484 if (certList
&& CFArrayGetCount(certList
)) {
485 CFDataRef subjectkeyid
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, subjKeyID
->Data
, subjKeyID
->Length
, kCFAllocatorNull
);
486 CFIndex c
, count
= CFArrayGetCount(certList
);
487 for (c
= 0; c
< count
; c
++) {
488 SecCertificateRef cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(certList
, c
);
489 CFDataRef skid
= (cert
) ? SecCertificateGetSubjectKeyID(cert
) : NULL
;
490 if (skid
&& CFEqual(skid
, subjectkeyid
)) {
496 if (subjectkeyid
) { CFRelease(subjectkeyid
); };
497 if (certificate
) { return certificate
; }
500 /* now search keychain(s) */
501 OSStatus status
= SecCertificateFindBySubjectKeyID(keychainOrArray
,subjKeyID
,&certificate
);
504 PORT_SetError(SEC_ERROR_NO_EMAIL_CERT
);
511 static SecIdentityRef
512 CERT_FindIdentityByCertificate (CFTypeRef keychainOrArray
, SecCertificateRef CF_CONSUMED certificate
)
514 SecIdentityRef identity
= NULL
;
515 SecIdentityCreateWithCertificate(keychainOrArray
, certificate
, &identity
);
517 PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT
);
519 CFRelease(certificate
);
526 CERT_FindIdentityByIssuerAndSN (CFTypeRef keychainOrArray
, const SecCmsIssuerAndSN
*issuerAndSN
)
528 SecCertificateRef certificate
= CERT_FindCertByIssuerAndSN(keychainOrArray
, NULL
, NULL
, NULL
, issuerAndSN
);
532 return CERT_FindIdentityByCertificate(keychainOrArray
, certificate
);
536 CERT_FindIdentityBySubjectKeyID (CFTypeRef keychainOrArray
, const SECItem
*subjKeyID
)
538 SecCertificateRef certificate
= CERT_FindCertBySubjectKeyID(keychainOrArray
, NULL
, NULL
, subjKeyID
);
542 return CERT_FindIdentityByCertificate(keychainOrArray
, certificate
);
545 // find the smime symmetric capabilities profile for a given cert
546 SECItem
*CERT_FindSMimeProfile(SecCertificateRef cert
)
551 // Return the decoded value of the subjectKeyID extension. The caller should
552 // free up the storage allocated in retItem->data.
553 SECStatus
CERT_FindSubjectKeyIDExtension (SecCertificateRef cert
, SECItem
*retItem
)
555 CSSM_DATA_PTR fieldValue
= NULL
;
557 CSSM_X509_EXTENSION
*extp
;
558 CE_SubjectKeyID
*skid
;
560 ortn
= SecCertificateCopyFirstFieldValue(cert
, &CSSMOID_SubjectKeyIdentifier
,
562 if(ortn
|| (fieldValue
== NULL
)) {
563 /* this cert doesn't have that extension */
566 extp
= (CSSM_X509_EXTENSION
*)fieldValue
->Data
;
567 skid
= (CE_SubjectKeyID
*)extp
->value
.parsedValue
;
568 retItem
->Data
= (uint8
*)PORT_Alloc(skid
->Length
);
569 retItem
->Length
= skid
->Length
;
570 memmove(retItem
->Data
, skid
->Data
, retItem
->Length
);
571 SecCertificateReleaseFirstFieldValue(cert
, &CSSMOID_SubjectKeyIdentifier
,
576 // Extract the issuer and serial number from a certificate
577 SecCmsIssuerAndSN
*CERT_GetCertIssuerAndSN(PRArenaPool
*pl
, SecCertificateRef cert
)
579 SecCmsIssuerAndSN
*certIssuerAndSN
;
582 mark
= PORT_ArenaMark(pl
);
583 CFDataRef issuer_data
= SecCertificateCopyIssuerSequence(cert
);
584 CFDataRef serial_data
= SecCertificateCopySerialNumberData(cert
, NULL
);
585 if (!issuer_data
|| !serial_data
) {
589 SecAsn1Item serialNumber
= {
590 .Length
= CFDataGetLength(serial_data
),
591 .Data
= (uint8_t *)CFDataGetBytePtr(serial_data
)
593 SecAsn1Item issuer
= {
594 .Length
= CFDataGetLength(issuer_data
),
595 .Data
= (uint8_t *)CFDataGetBytePtr(issuer_data
)
598 /* Allocate the SecCmsIssuerAndSN struct. */
599 certIssuerAndSN
= (SecCmsIssuerAndSN
*)PORT_ArenaZAlloc (pl
, sizeof(SecCmsIssuerAndSN
));
600 if (certIssuerAndSN
== NULL
) {
604 /* Copy the issuer. */
605 certIssuerAndSN
->derIssuer
.Data
= (uint8_t *) PORT_ArenaAlloc(pl
, issuer
.Length
);
606 if (!certIssuerAndSN
->derIssuer
.Data
) {
609 PORT_Memcpy(certIssuerAndSN
->derIssuer
.Data
, issuer
.Data
, issuer
.Length
);
610 certIssuerAndSN
->derIssuer
.Length
= issuer
.Length
;
612 /* Copy the serialNumber. */
613 certIssuerAndSN
->serialNumber
.Data
= (uint8_t *) PORT_ArenaAlloc(pl
, serialNumber
.Length
);
614 if (!certIssuerAndSN
->serialNumber
.Data
) {
617 PORT_Memcpy(certIssuerAndSN
->serialNumber
.Data
, serialNumber
.Data
, serialNumber
.Length
);
618 certIssuerAndSN
->serialNumber
.Length
= serialNumber
.Length
;
620 CFRelease(serial_data
);
621 CFRelease(issuer_data
);
623 PORT_ArenaUnmark(pl
, mark
);
624 return certIssuerAndSN
;
627 CFReleaseNull(serial_data
);
628 CFReleaseNull(issuer_data
);
629 PORT_ArenaRelease(pl
, mark
);
630 PORT_SetError(SEC_INTERNAL_ONLY
);
635 // import a collection of certs into the temporary or permanent cert database
636 SECStatus
CERT_ImportCerts(SecKeychainRef keychain
, SECCertUsage usage
, unsigned int ncerts
,
637 SECItem
**derCerts
, SecCertificateRef
**retCerts
, Boolean keepCerts
, Boolean caOnly
, char *nickname
)
639 OSStatus rv
= SECFailure
;
640 SecCertificateRef cert
;
643 // @@@ Do something with caOnly and nickname
644 if (caOnly
|| nickname
)
647 for (ci
= 0; ci
< ncerts
; ++ci
)
649 rv
= SecCertificateCreateFromData(derCerts
[ci
], CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
, &cert
);
654 rv
= SecCertificateAddToKeychain(cert
, keychain
);
657 if (rv
== errKCDuplicateItem
)
679 SECStatus
CERT_SaveSMimeProfile(SecCertificateRef cert
, SECItem
*emailProfile
,SECItem
*profileTime
)
681 fprintf(stderr
, "WARNING: CERT_SaveSMimeProfile unimplemented\n");
685 // Check the hostname to make sure that it matches the shexp that
686 // is given in the common name of the certificate.
687 SECStatus
CERT_VerifyCertName(SecCertificateRef cert
, const char *hostname
)
689 fprintf(stderr
, "WARNING: CERT_VerifyCertName unimplemented\n");
694 ** OLD OBSOLETE FUNCTIONS with enum SECCertUsage - DO NOT USE FOR NEW CODE
695 ** verify a certificate by checking validity times against a certain time,
696 ** that we trust the issuer, and that the signature on the certificate is
698 ** "cert" the certificate to verify
699 ** "checkSig" only check signatures if true
702 CERT_VerifyCert(SecKeychainRef keychainOrArray
, SecCertificateRef cert
,
703 const CSSM_DATA_PTR
*otherCerts
, /* intermediates */
704 CFTypeRef policies
, CFAbsoluteTime stime
, SecTrustRef
*trustRef
)
706 CFMutableArrayRef certificates
= NULL
;
707 SecTrustRef trust
= NULL
;
709 int numOtherCerts
= SecCmsArrayCount((void **)otherCerts
);
713 * Certs to evaluate: first the leaf - our cert - then all the rest we know
714 * about. It's OK for otherCerts to contain a copy of the leaf.
716 certificates
= CFArrayCreateMutable(NULL
, numOtherCerts
+ 1, &kCFTypeArrayCallBacks
);
717 CFArrayAppendValue(certificates
, cert
);
718 for(dex
=0; dex
<numOtherCerts
; dex
++) {
719 SecCertificateRef intCert
;
721 rv
= SecCertificateCreateFromData(otherCerts
[dex
],
722 CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
,
727 CFArrayAppendValue(certificates
, intCert
);
730 rv
= SecTrustCreateWithCertificates(certificates
, policies
, &trust
);
731 CFRelease(certificates
);
736 rv
= SecTrustSetKeychains(trust
, keychainOrArray
);
740 CFDateRef verifyDate
= CFDateCreate(NULL
, stime
);
741 rv
= SecTrustSetVerifyDate(trust
, verifyDate
);
742 CFRelease(verifyDate
);
752 SecTrustResultType result
;
753 /* The caller doesn't want a SecTrust object, so let's evaluate it for them. */
754 rv
= SecTrustEvaluate(trust
, &result
);
760 case kSecTrustResultProceed
:
761 case kSecTrustResultUnspecified
:
762 /* TP Verification succeeded and there was either a UserTurst entry
763 telling us to procceed, or no user trust setting was specified. */
767 PORT_SetError(SEC_ERROR_UNTRUSTED_CERT
);
776 #if 0 /* debugging */
777 syslog(LOG_ERR
, "CERT_VerifyCert has failed with %d (input policies and output trust follow)",
779 if (policies
) CFShow(policies
);
780 if (trust
) CFShow(trust
);
785 CFRelease(certificates
);
790 CERT_PolicyForCertUsage(SECCertUsage certUsage
)
792 SecPolicyRef policy
= NULL
;
796 case certUsageSSLServerWithStepUp
:
798 case certUsageVerifyCA
:
802 case certUsageSSLClient
:
803 policy
= SecPolicyCreateSSL(false, NULL
);
805 case certUsageSSLServer
:
806 policy
= SecPolicyCreateSSL(true, NULL
);
808 case certUsageStatusResponder
:
809 policy
= SecPolicyCreateOCSPSigner();
811 case certUsageObjectSigner
:
812 case certUsageProtectedObjectSigner
:
813 case certUsageUserCertImport
:
814 case certUsageEmailSigner
:
815 case certUsageEmailRecipient
:
816 policy
= SecPolicyCreateBasicX509();