* Framework and CSSM
*/
-#include <Security/SecBase.h>
+#include "config.h"
+
#include <Security/SecCertificate.h>
#include <Security/SecPolicy.h>
+#include <Security/SecTrust.h>
+#include <Security/SecKeyPriv.h>
#include <Security/SecIdentity.h>
+#include <Security/SecItem.h>
+#include <TargetConditionals.h>
+#include <Security/SecItemPriv.h>
+#ifndef HAVE_OPENSSL
+#include <Security/SecTrustPriv.h>
+#include <Security/SecPolicyPriv.h>
+#include <Security/SecCertificatePriv.h>
+#else
+#include <Security/SecBase.h>
#include <Security/SecIdentityPriv.h>
-#include <Security/SecIdentitySearch.h>
-#include <Security/SecKeychain.h>
-#include <Security/SecKeychainItem.h>
-#include <Security/SecKeychainItemPriv.h>
-#include <Security/SecKey.h>
+#include <Security/SecCertificateOIDs.h>
#include <Security/SecKeyPriv.h>
-#include <Security/SecTrust.h>
#include <Security/oidsalg.h>
#include <Security/cssmapi.h>
#include <Security/SecPolicySearch.h>
+#endif
#include <CoreFoundation/CoreFoundation.h>
+#if !TARGET_OS_EMBEDDED
+#include <Security/SecIdentitySearch.h>
+#include <Security/SecKeychain.h>
+#include <Security/SecKeychainItem.h>
+#include <Security/SecKeychainItemPriv.h>
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+#endif
#include "plog.h"
#include "debug.h"
#include "misc.h"
+#include "oakley.h"
+#include "gcmalloc.h"
+
#include "crypto_cssm.h"
+static OSStatus EvaluateCert(SecCertificateRef evalCertArray[], CFIndex evalCertArrayNumValues, CFTypeRef policyRef, SecKeyRef *publicKeyRef);
+
+
+
+static SecPolicyRef
+crypto_cssm_x509cert_get_SecPolicyRef (CFStringRef hostname)
+{
+ SecPolicyRef policyRef = NULL;
+ CFDictionaryRef properties = NULL;
+ const void *key[] = { kSecPolicyName };
+ const void *value[] = { hostname };
+
+ if (hostname) {
+ properties = CFDictionaryCreate(NULL, key, value, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ if (properties == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "unable to create dictionary for policy properties.\n");
+ }
+ }
+ policyRef = SecPolicyCreateWithProperties(kSecPolicyAppleIPsec, properties);
+ if (properties)
+ CFRelease(properties);
+ return policyRef;
+}
-static OSStatus FindPolicy(const CSSM_OID *policyOID, SecPolicyRef *policyRef);
-static OSStatus EvaluateCert(SecCertificateRef cert, CFTypeRef policyRef);
-static OSStatus CopySystemKeychain(SecKeychainRef *keychainRef);
-static const char *GetSecurityErrorString(OSStatus err);
+SecCertificateRef
+crypto_cssm_x509cert_CreateSecCertificateRef (vchar_t *cert)
+{
+ SecCertificateRef certRef = NULL;
+ CFDataRef cert_data = CFDataCreateWithBytesNoCopy(NULL, (uint8_t*)cert->v, cert->l, kCFAllocatorNull);
+ if (cert_data) {
+ certRef = SecCertificateCreateWithData(NULL, cert_data);
+ CFRelease(cert_data);
+ }
+
+ if (certRef == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "unable to get a certifcate reference.\n");
+ }
+ return certRef;
+}
+
+/* HACK!!! - temporary until this prototype gets moved */
+extern CFDataRef SecCertificateCopySubjectSequence( SecCertificateRef certificate);
+
+CFDataRef
+crypto_cssm_CopySubjectSequence(SecCertificateRef certRef)
+{
+ CFDataRef subject = NULL;
+
+ subject = SecCertificateCopySubjectSequence(certRef);
+ return subject;
+
+}
+
+
+cert_status_t
+crypto_cssm_check_x509cert_dates (SecCertificateRef certificateRef)
+{
+ cert_status_t certStatus = CERT_STATUS_OK;
+#ifndef HAVE_OPENSSL
+ CFAbsoluteTime timeNow = 0;
+ CFAbsoluteTime notvalidbeforedate = 0;
+ CFAbsoluteTime notvalidafterdate = 0;
+ CFDateRef nowcfdatedata = NULL;
+ CFDateRef notvalidbeforedatedata = NULL;
+ CFDateRef notvalidafterdatedata = NULL;
+ CFArrayRef certProparray = NULL;
+
+ if ((timeNow = CFAbsoluteTimeGetCurrent())) {
+ if (SecCertificateIsValid(certificateRef, timeNow)) {
+ plog(ASL_LEVEL_NOTICE, "Certificate expiration date is OK\n");
+ certStatus = CERT_STATUS_OK;
+ } else {
+ nowcfdatedata = CFDateCreate( NULL, timeNow);
+
+ if ((notvalidbeforedate = SecCertificateNotValidBefore(certificateRef))) {
+ notvalidbeforedatedata = CFDateCreate(NULL, notvalidbeforedate);
+ }
+
+ if ((notvalidafterdate = SecCertificateNotValidAfter(certificateRef))) {
+ notvalidafterdatedata = CFDateCreate(NULL, notvalidafterdate);
+ }
+
+ int year = 0;
+ int month = 0;
+ int day = 0;
+ int hour = 0;
+ int minute = 0;
+ CFCalendarRef calendar = CFCalendarCreateWithIdentifier(kCFAllocatorDefault, kCFGregorianCalendar);
+ if (calendar)
+ {
+ if (notvalidbeforedate) {
+ CFCalendarDecomposeAbsoluteTime(calendar, notvalidbeforedate, "yMdHm", &year, &month, &day, &hour, &minute);
+ plog(ASL_LEVEL_DEBUG, "Certificate not valid before yr %d, mon %d, days %d, hours %d, min %d\n", year, month, day, hour, minute);
+ }
+
+ if (notvalidafterdate) {
+ CFCalendarDecomposeAbsoluteTime(calendar, notvalidafterdate, "yMdHm", &year, &month, &day, &hour, &minute);
+ plog(ASL_LEVEL_DEBUG, "Certificate not valid after yr %d, mon %d, days %d, hours %d, min %d\n", year, month, day, hour, minute);
+ }
+ CFRelease(calendar);
+ }
+
+ if (nowcfdatedata != NULL) {
+ if (notvalidbeforedatedata && CFDateCompare(nowcfdatedata, notvalidbeforedatedata, NULL) == kCFCompareLessThan){
+ plog(ASL_LEVEL_ERR,
+ "current time before valid time\n");
+ certStatus = CERT_STATUS_PREMATURE;
+ } else if (notvalidafterdatedata && (CFDateCompare( nowcfdatedata, notvalidafterdatedata, NULL ) == kCFCompareGreaterThan)){
+ plog(ASL_LEVEL_ERR,
+ "current time after valid time\n");
+ certStatus = CERT_STATUS_EXPIRED;
+ }
+ }
+ }
+ } else {
+ plog(ASL_LEVEL_ERR, "CFAbsoluteTimeGetCurrent() failed");
+ certStatus = CERT_STATUS_INVALID;
+ }
+
+ if (notvalidbeforedatedata)
+ CFRelease(notvalidbeforedatedata);
+ if (notvalidafterdatedata)
+ CFRelease(notvalidafterdatedata);
+ if (certProparray)
+ CFRelease(certProparray);
+ if (nowcfdatedata)
+ CFRelease(nowcfdatedata);
+#endif
+ return certStatus;
+}
/*
* Verify cert using security framework
*/
-int crypto_cssm_check_x509cert(vchar_t *cert)
+int crypto_cssm_check_x509cert (cert_t *hostcert, cert_t *certchain, CFStringRef hostname, SecKeyRef *publicKeyRef)
{
+ cert_t *p;
+ cert_status_t certStatus = 0;
OSStatus status;
- SecCertificateRef certRef = 0;
- CSSM_DATA certData;
- CSSM_OID ourPolicyOID = CSSMOID_APPLE_TP_IP_SEC;
- SecPolicyRef policyRef = 0;
-
- // create cert ref
- certData.Length = cert->l;
- certData.Data = (uint8 *)cert->v;
- status = SecCertificateCreateFromData(&certData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER,
- &certRef);
- if (status != noErr)
- goto end;
+ CFIndex certArrayRefNumValues = 0;
+ CFIndex n = 0;
+ int certArraySiz;
+ SecCertificateRef *certArrayRef = NULL;
+ SecPolicyRef policyRef = crypto_cssm_x509cert_get_SecPolicyRef(hostname);
- // get our policy object
- status = FindPolicy(&ourPolicyOID, &policyRef);
- if (status != noErr)
- goto end;
-
- // setup policy options ???
- // no options used at present - verification of subjectAltName fields, etc.
- // are done elsewhere in racoon in oakley_check_certid()
+ if (!hostcert || !certchain) {
+ return -1;
+ }
+
+ // find the total number of certs
+ for (p = certchain; p; p = p->chain, n++);
+ if (n> 1) {
+ plog(ASL_LEVEL_DEBUG,
+ "%s: checking chain of %d certificates.\n", __FUNCTION__, (int)n);
+ }
+
+ certArraySiz = n * sizeof(CFTypeRef);
+ certArrayRef = CFAllocatorAllocate(NULL, certArraySiz, 0);
+ if (!certArrayRef) {
+ return -1;
+ }
+ bzero(certArrayRef, certArraySiz);
+ if ((certArrayRef[certArrayRefNumValues] = crypto_cssm_x509cert_CreateSecCertificateRef(&hostcert->cert))) {
+ /* don't overwrite any pending status */
+ if (!hostcert->status) {
+ hostcert->status = crypto_cssm_check_x509cert_dates(certArrayRef[certArrayRefNumValues]);
+ if (hostcert->status) {
+ plog(ASL_LEVEL_ERR,
+ "host certificate failed date verification: %d.\n", hostcert->status);
+ certStatus = hostcert->status;
+ }
+ }
+ certArrayRefNumValues++;
+ }
+ for (p = certchain; p && certArrayRefNumValues < n; p = p->chain) {
+ if (p != hostcert) {
+ if ((certArrayRef[certArrayRefNumValues] = crypto_cssm_x509cert_CreateSecCertificateRef(&p->cert))) {
+ /* don't overwrite any pending status */
+ if (!p->status) {
+ p->status = crypto_cssm_check_x509cert_dates(certArrayRef[certArrayRefNumValues]);
+ if (p->status) {
+ plog(ASL_LEVEL_ERR,
+ "other certificate in chain failed date verification: %d.\n", p->status);
+ if (!certStatus) {
+ certStatus = p->status;
+ }
+ }
+ }
+ certArrayRefNumValues++;
+ }
+ }
+ }
// evaluate cert
- status = EvaluateCert(certRef, policyRef);
+ status = EvaluateCert(certArrayRef, certArrayRefNumValues, policyRef, publicKeyRef);
+ while (certArrayRefNumValues) {
+ CFRelease(certArrayRef[--certArrayRefNumValues]);
+ }
+ CFAllocatorDeallocate(NULL, certArrayRef);
-end:
-
- if (certRef)
- CFRelease(certRef);
if (policyRef)
CFRelease(policyRef);
if (status != noErr && status != -1) {
- plog(LLV_ERROR, LOCATION, NULL,
- "error %d %s.\n", status, GetSecurityErrorString(status));
+ plog(ASL_LEVEL_ERR,
+ "check_x509cert error %d %s.\n", (int)status, GetSecurityErrorString(status));
+ status = -1;
+ } else if (certStatus == CERT_STATUS_PREMATURE || certStatus == CERT_STATUS_EXPIRED) {
status = -1;
- }
+ }
return status;
+
+}
+
+int crypto_cssm_verify_x509sign(SecKeyRef publicKeyRef, vchar_t *hash, vchar_t *signature, Boolean useSHA1)
+{
+ return SecKeyRawVerify(publicKeyRef, useSHA1 ? kSecPaddingPKCS1SHA1 : kSecPaddingPKCS1, (uint8_t*)hash->v, hash->l, (uint8_t*)signature->v, signature->l);
}
/*
vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash)
{
- OSStatus status;
- SecCertificateRef certificateRef = NULL;
+ OSStatus status = -1;
SecIdentityRef identityRef = NULL;
- SecIdentitySearchRef idSearchRef = NULL;
- SecKeychainRef keychainRef = NULL;
SecKeyRef privateKeyRef = NULL;
- const CSSM_KEY *cssmKey = NULL;
- CSSM_CSP_HANDLE cspHandle = nil;
- CSSM_CC_HANDLE cssmContextHandle = nil;
- const CSSM_ACCESS_CREDENTIALS *credentials = NULL;
- //CSSM_SIZE bytesEncrypted = 0; //%%%%HWR fix this - need new headers on Leopard
- uint32 bytesEncrypted = 0;
- CSSM_DATA clearData;
- CSSM_DATA cipherData;
- CSSM_DATA remData;
- CSSM_CONTEXT_ATTRIBUTE newAttr;
vchar_t *sig = NULL;
- remData.Length = 0;
- remData.Data = 0;
- if (persistentCertRef) {
- // get cert from keychain
- status = SecKeychainItemCopyFromPersistentReference(persistentCertRef, (SecKeychainItemRef*)&certificateRef);
- if (status != noErr)
- goto end;
-
- // get keychain ref where cert is contained
- status = SecKeychainItemCopyKeychain((SecKeychainItemRef)certificateRef, &keychainRef);
- if (status != noErr)
- goto end;
-
- // get identity from the certificate
- status = SecIdentityCreateWithCertificate(keychainRef, certificateRef, &identityRef);
- if (status != noErr)
- goto end;
-
- } else {
- // copy system keychain
- status = CopySystemKeychain(&keychainRef);
- if (status != noErr)
- goto end;
-
- // serach for first identity in system keychain
- status = SecIdentitySearchCreate(keychainRef, CSSM_KEYUSE_SIGN, &idSearchRef);
- if (status != noErr)
- goto end;
-
- status = SecIdentitySearchCopyNext(idSearchRef, &identityRef);
- if (status != noErr)
- goto end;
-
- // get certificate from identity
- status = SecIdentityCopyCertificate(identityRef, &certificateRef);
- if (status != noErr)
- goto end;
- }
+ CFDictionaryRef persistFind = NULL;
+ const void *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef, kSecClass,
+#if TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+ kSecUseSystemKeychain,
+#endif
+ };
+ const void *values_persist[] = { kCFBooleanTrue, persistentCertRef, kSecClassIdentity,
+#if TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+ kCFBooleanTrue,
+#endif
+ };
+
+#define SIG_BUF_SIZE 1024
-
- // get private key from identity
- status = SecIdentityCopyPrivateKey(identityRef, &privateKeyRef);
- if (status != noErr)
- goto end;
-
- // get CSSM_KEY pointer from key ref
- status = SecKeyGetCSSMKey(privateKeyRef, &cssmKey);
- if (status != noErr)
+ /* find identity by persistent ref */
+ persistFind = CFDictionaryCreate(NULL, keys_persist, values_persist,
+ (sizeof(keys_persist) / sizeof(*keys_persist)), NULL, NULL);
+ if (persistFind == NULL)
goto end;
-
- // get CSSM CSP handle
- status = SecKeychainGetCSPHandle(keychainRef, &cspHandle);
- if (status != noErr)
- goto end;
-
- // create CSSM credentials to unlock private key for encryption - no UI to be used
- status = SecKeyGetCredentials(privateKeyRef, CSSM_ACL_AUTHORIZATION_ENCRYPT,
- kSecCredentialTypeNoUI, &credentials);
- if (status != noErr)
- goto end;
-
- // create asymmetric context for encryption
- status = CSSM_CSP_CreateAsymmetricContext(cspHandle, CSSM_ALGID_RSA, credentials, cssmKey,
- CSSM_PADDING_PKCS1, &cssmContextHandle);
+
+ status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef);
if (status != noErr)
goto end;
- // add mode attribute to use private key for encryption
- newAttr.AttributeType = CSSM_ATTRIBUTE_MODE;
- newAttr.AttributeLength = sizeof(uint32);
- newAttr.Attribute.Data = (CSSM_DATA_PTR)CSSM_ALGMODE_PRIVATE_KEY;
- status = CSSM_UpdateContextAttributes(cssmContextHandle, 1, &newAttr);
- if(status != noErr)
- goto end;
-
- // and finally - encrypt data
- clearData.Length = hash->l;
- clearData.Data = (uint8 *)hash->v;
- cipherData.Length = 0;
- cipherData.Data = NULL;
- status = CSSM_EncryptData(cssmContextHandle, &clearData, 1, &cipherData, 1, &bytesEncrypted,
- &remData);
+ status = SecIdentityCopyPrivateKey(identityRef, &privateKeyRef);
if (status != noErr)
goto end;
-
- if (remData.Length != 0) { // something didn't go right - should be zero
- status = -1;
- plog(LLV_ERROR, LOCATION, NULL,
- "unencrypted data remaining after encrypting hash.\n");
- goto end;
- }
// alloc buffer for result
- sig = vmalloc(0);
+ sig = vmalloc(SIG_BUF_SIZE);
if (sig == NULL)
goto end;
-
- sig->l = cipherData.Length;
- sig->v = (caddr_t)cipherData.Data;
+
+ status = SecKeyRawSign(privateKeyRef, kSecPaddingPKCS1, (uint8_t*)hash->v,
+ hash->l, (uint8_t*)sig->v, &sig->l);
+
end:
- if (certificateRef)
- CFRelease(certificateRef);
- if (keychainRef)
- CFRelease(keychainRef);
if (identityRef)
CFRelease(identityRef);
if (privateKeyRef)
CFRelease(privateKeyRef);
- if (idSearchRef)
- CFRelease(idSearchRef);
- if (cssmContextHandle)
- CSSM_DeleteContext(cssmContextHandle);
+
+ if (persistFind)
+ CFRelease(persistFind);
+
if (status != noErr) {
if (sig) {
vfree(sig);
}
if (status != noErr && status != -1) {
- plog(LLV_ERROR, LOCATION, NULL,
- "error %d %s.\n", status, GetSecurityErrorString(status));
+ plog(ASL_LEVEL_ERR,
+ "getsign error %d %s.\n", (int)status, GetSecurityErrorString(status));
status = -1;
}
return sig;
/*
* Retrieve a cert from the keychain
*/
-vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef)
+vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef,
+ cert_status_t *certStatus)
{
- OSStatus status;
- CSSM_DATA cssmData;
+ OSStatus status = -1;
vchar_t *cert = NULL;
+ SecCertificateRef certificateRef = NULL;
+ CFDictionaryRef persistFind = NULL;
+ size_t dataLen;
+ CFDataRef certData = NULL;
SecIdentityRef identityRef = NULL;
- SecIdentitySearchRef idSearchRef = NULL;
- SecKeychainRef keychainRef = NULL;
- SecCertificateRef certificateRef = NULL;
-
+ const void *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef, kSecClass,
+#if TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+ kSecUseSystemKeychain,
+#endif
+ };
+ const void *values_persist[] = { kCFBooleanTrue, persistentCertRef, kSecClassIdentity,
+#if TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+ kCFBooleanTrue,
+#endif
+ };
+
+ /* find identity by persistent ref */
+ persistFind = CFDictionaryCreate(NULL, keys_persist, values_persist,
+ (sizeof(keys_persist) / sizeof(*keys_persist)), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ if (persistFind == NULL)
+ goto end;
+
+ status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef);
+ if (status != noErr)
+ goto end;
- // get cert ref
- if (persistentCertRef) {
- status = SecKeychainItemCopyFromPersistentReference(persistentCertRef, (SecKeychainItemRef*)&certificateRef);
- if (status != noErr)
- goto end;
- } else {
- // copy system keychain
- status = CopySystemKeychain(&keychainRef);
- if (status != noErr)
- goto end;
-
- // find first identity in system keychain
- status = SecIdentitySearchCreate(keychainRef, CSSM_KEYUSE_SIGN, &idSearchRef);
- if (status != noErr)
- goto end;
-
- status = SecIdentitySearchCopyNext(idSearchRef, &identityRef);
- if (status != noErr)
- goto end;
-
- // get certificate from identity
- status = SecIdentityCopyCertificate(identityRef, &certificateRef);
- if (status != noErr)
- goto end;
-
- }
-
- // get certificate data
- cssmData.Length = 0;
- cssmData.Data = NULL;
- status = SecCertificateGetData(certificateRef, &cssmData);
+ status = SecIdentityCopyCertificate(identityRef, &certificateRef);
if (status != noErr)
goto end;
-
- if (cssmData.Length == 0)
+
+ certData = SecCertificateCopyData(certificateRef);
+ if (certData == NULL)
+ goto end;
+
+ dataLen = CFDataGetLength(certData);
+ if (dataLen == 0)
goto end;
- cert = vmalloc(cssmData.Length);
+ cert = vmalloc(dataLen);
if (cert == NULL)
goto end;
- // cssmData struct just points to the data
- // data must be copied to be returned
- memcpy(cert->v, cssmData.Data, cssmData.Length);
+ CFDataGetBytes(certData, CFRangeMake(0, dataLen), (uint8_t*)cert->v);
+
+ // verify expiry or missing fields
+ if (certStatus) {
+ *certStatus = crypto_cssm_check_x509cert_dates(certificateRef);
+ }
end:
+ if (identityRef)
+ CFRelease(identityRef);
if (certificateRef)
CFRelease(certificateRef);
- if (identityRef)
- CFRelease(identityRef);
- if (idSearchRef)
- CFRelease(idSearchRef);
- if (keychainRef)
- CFRelease(keychainRef);
-
+ if (persistFind)
+ CFRelease(persistFind);
+ if (certData)
+ CFRelease(certData);
+
if (status != noErr && status != -1) {
- plog(LLV_ERROR, LOCATION, NULL,
- "error %d %s.\n", status, GetSecurityErrorString(status));
+ plog(ASL_LEVEL_ERR,
+ "get_x509cert error %d %s.\n", (int)status, GetSecurityErrorString(status));
status = -1;
}
return cert;
}
-
-/*
- * Find a policy ref by OID
- */
-static OSStatus FindPolicy(const CSSM_OID *policyOID, SecPolicyRef *policyRef)
-{
-
- OSStatus status;
- SecPolicySearchRef searchRef = nil;
-
- status = SecPolicySearchCreate(CSSM_CERT_X_509v3, policyOID, NULL, &searchRef);
- if (status != noErr)
- goto end;
-
- status = SecPolicySearchCopyNext(searchRef, policyRef);
-
-end:
- if (searchRef)
- CFRelease(searchRef);
-
- if (status != noErr) {
- plog(LLV_ERROR, LOCATION, NULL,
- "error %d %s.\n", status, GetSecurityErrorString(status));
- status = -1;
- }
- return status;
-}
-
-
/*
* Evaluate the trust of a cert using the policy provided
*/
-static OSStatus EvaluateCert(SecCertificateRef cert, CFTypeRef policyRef)
+static OSStatus EvaluateCert(SecCertificateRef evalCertArray[], CFIndex evalCertArrayNumValues, CFTypeRef policyRef, SecKeyRef *publicKeyRef)
{
OSStatus status;
SecTrustRef trustRef = 0;
SecTrustResultType evalResult;
+
+ CFArrayRef errorStrings;
- SecCertificateRef evalCertArray[1] = { cert };
-
- CFArrayRef cfCertRef = CFArrayCreate((CFAllocatorRef) NULL, (void*)evalCertArray, 1,
- &kCFTypeArrayCallBacks);
+ CFArrayRef cfCertRef = CFArrayCreate((CFAllocatorRef) NULL, (void*)evalCertArray, evalCertArrayNumValues,
+ &kCFTypeArrayCallBacks);
if (!cfCertRef) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"unable to create CFArray.\n");
return -1;
}
status = SecTrustCreateWithCertificates(cfCertRef, policyRef, &trustRef);
if (status != noErr)
goto end;
-
+
status = SecTrustEvaluate(trustRef, &evalResult);
if (status != noErr)
goto end;
if (evalResult != kSecTrustResultProceed && evalResult != kSecTrustResultUnspecified) {
- plog(LLV_ERROR, LOCATION, NULL,
- "error evaluating certificate.\n");
+ plog(ASL_LEVEL_ERR, "Error evaluating certificate.\n");
+
+ switch (evalResult) {
+ case kSecTrustResultInvalid:
+ plog(ASL_LEVEL_DEBUG, "eval result = kSecTrustResultInvalid.\n");
+ break;
+ case kSecTrustResultProceed:
+ plog(ASL_LEVEL_DEBUG, "eval result = kSecTrustResultProceed.\n");
+ break;
+ case kSecTrustResultDeny:
+ plog(ASL_LEVEL_DEBUG, "eval result = kSecTrustResultDeny.\n");
+ break;
+ case kSecTrustResultUnspecified:
+ plog(ASL_LEVEL_DEBUG, "eval result = kSecTrustResultUnspecified.\n");
+ break;
+ case kSecTrustResultRecoverableTrustFailure:
+ plog(ASL_LEVEL_DEBUG, "eval result = kSecTrustResultRecoverableTrustFailure.\n");
+ break;
+ case kSecTrustResultFatalTrustFailure:
+ plog(ASL_LEVEL_DEBUG, "eval result = kSecTrustResultFatalTrustFailure.\n");
+ break;
+ case kSecTrustResultOtherError:
+ plog(ASL_LEVEL_DEBUG, "eval result = kSecTrustResultOtherError.\n");
+ break;
+ default:
+ plog(ASL_LEVEL_DEBUG, "eval result unknown: value = %d.\n", (int)evalResult);
+ break;
+ }
+
+ errorStrings = SecTrustCopyProperties(trustRef);
+ if (errorStrings) {
+
+ CFDictionaryRef dict;
+ CFStringRef val;
+ const char *str;
+ CFIndex count, maxcount = CFArrayGetCount(errorStrings);
+
+ plog(ASL_LEVEL_ERR, "---------------Returned error strings: ---------------.\n");
+ for (count = 0; count < maxcount; count++) {
+ dict = CFArrayGetValueAtIndex(errorStrings, count);
+ if (dict && (CFGetTypeID(dict) == CFDictionaryGetTypeID())) {
+ val = CFDictionaryGetValue(dict, kSecPropertyKeyType);
+ if (val && (CFGetTypeID(val) == CFStringGetTypeID())) {
+ str = CFStringGetCStringPtr(val, kCFStringEncodingMacRoman);
+ if (str)
+ plog(ASL_LEVEL_ERR, "type = %s.\n", str);
+ }
+ val = CFDictionaryGetValue(dict, kSecPropertyKeyValue);
+ if (val && (CFGetTypeID(val) == CFStringGetTypeID())) {
+ str = CFStringGetCStringPtr(val, kCFStringEncodingMacRoman);
+ if (str)
+ plog(ASL_LEVEL_ERR, "value = %s.\n", str);
+ }
+ }
+ }
+ plog(ASL_LEVEL_ERR, "-----------------------------------------------------.\n");
+ CFRelease(errorStrings);
+ }
+
status = -1;
+ goto end;
}
+ /* get and return the public key */
+ *publicKeyRef = SecTrustCopyPublicKey(trustRef);
end:
if (cfCertRef)
CFRelease(trustRef);
if (status != noErr && status != -1) {
- plog(LLV_ERROR, LOCATION, NULL,
- "error %d %s.\n", status, GetSecurityErrorString(status));
- status = -1;
- }
- return status;
-}
-
-
-/*
- * Copy the system keychain
- */
-static OSStatus CopySystemKeychain(SecKeychainRef *keychainRef)
-{
-
- OSStatus status;
-
- status = SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem);
- if (status != noErr)
- goto end;
-
- status = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, keychainRef);
-
-end:
-
- if (status != noErr) {
- plog(LLV_ERROR, LOCATION, NULL,
- "error %d %s.\n", status, GetSecurityErrorString(status));
+ plog(ASL_LEVEL_ERR,
+ "EvaluateCert error %d %s.\n", (int)status, GetSecurityErrorString(status));
status = -1;
}
return status;
-
}
-
/*
* Return string representation of Security-related OSStatus.
*/
switch(err) {
case noErr:
return "noErr";
- case memFullErr:
+
+ /* SecBase.h: */
+ case errSecNotAvailable:
+ return "errSecNotAvailable";
+
+#if !TARGET_OS_EMBEDDED
+ case memFullErr:
return "memFullErr";
case paramErr:
return "paramErr";
case unimpErr:
return "unimpErr";
-
- /* SecBase.h: */
- case errSecNotAvailable:
- return "errSecNotAvailable";
+#endif
+
+#ifndef HAVE_OPENSSL
+ /* SecBase.h: */
case errSecReadOnly:
return "errSecReadOnly";
case errSecAuthFailed:
return "errSecDuplicateCallback";
case errSecInvalidCallback:
return "errSecInvalidCallback";
- case errSecDuplicateItem:
- return "errSecDuplicateItem";
- case errSecItemNotFound:
- return "errSecItemNotFound";
case errSecBufferTooSmall:
return "errSecBufferTooSmall";
case errSecDataTooLarge:
return "errSecNoAccessForItem";
case errSecInvalidOwnerEdit:
return "errSecInvalidOwnerEdit";
+#endif
+ case errSecDuplicateItem:
+ return "errSecDuplicateItem";
+ case errSecItemNotFound:
+ return "errSecItemNotFound";
default:
return "<unknown>";
}