/* Test basic add delete update copy matching stuff. */ static void tests(void) { SecTrustRef trust; SecCertificateRef cert0, cert1; isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), NULL, "create cert0"); isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), NULL, "create cert1"); const void *v_certs[] = { cert0, cert1 }; SecPolicyRef policy = SecPolicyCreateSSL(false, CFSTR("store.apple.com")); CFArrayRef certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), NULL); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust"); /* Jan 1st 2006. */ CFDateRef date = CFDateCreate(NULL, 157680000.0); ok_status(SecTrustSetVerifyDate(trust, date), "set date"); SecTrustResultType trustResult; ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); CFDataRef exceptions; ok(exceptions = SecTrustCopyExceptions(trust), "create an exceptions"); ok(SecTrustSetExceptions(trust, exceptions), "set exceptions"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed"); CFReleaseSafe(trust); CFReleaseSafe(policy); policy = SecPolicyCreateSSL(false, CFSTR("badstore.apple.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust with hostname mismatch"); ok_status(SecTrustSetVerifyDate(trust, date), "set date"); ok(SecTrustSetExceptions(trust, exceptions), "set old exceptions"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); CFReleaseSafe(exceptions); ok(exceptions = SecTrustCopyExceptions(trust), "create a new exceptions"); ok(SecTrustSetExceptions(trust, exceptions), "set exceptions"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed"); CFReleaseSafe(trust); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust"); ok_status(SecTrustSetVerifyDate(trust, date), "set date"); ok(SecTrustSetExceptions(trust, exceptions), "set exceptions"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed"); CFArrayRef anchors = CFArrayCreate(kCFAllocatorDefault, NULL, 0, &kCFTypeArrayCallBacks); ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set empty anchor list"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); ok_status(SecTrustSetAnchorCertificatesOnly(trust, false), "trust passed in anchors and system anchors"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultProceed, "trust is now kSecTrustResultProceed"); ok_status(SecTrustSetAnchorCertificatesOnly(trust, true), "only trust passed in anchors (default)"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure again"); CFReleaseSafe(exceptions); ok(exceptions = SecTrustCopyExceptions(trust), "create a new exceptions"); ok(SecTrustSetExceptions(trust, exceptions), "set exceptions"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed"); CFReleaseSafe(date); date = CFDateCreate(NULL, 667680000.0); ok_status(SecTrustSetVerifyDate(trust, date), "set date to far future so certs are expired"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); CFReleaseSafe(anchors); CFReleaseSafe(exceptions); CFReleaseSafe(trust); CFReleaseSafe(policy); CFReleaseSafe(certs); CFReleaseSafe(cert0); CFReleaseSafe(cert1); CFReleaseSafe(date); }
SecPolicyRef SecPolicyCreateAppleSSLService(CFStringRef hostname) { // SSL server, pinned to an Apple intermediate SecPolicyRef policy = SecPolicyCreateSSL(true, hostname); if (policy) { // change options for policy evaluation char *strbuf = NULL; const char *hostnamestr = NULL; if (hostname) { hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8); if (hostnamestr == NULL) { CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname), kCFStringEncodingUTF8) + 1; strbuf = (char *)malloc(maxLen); if (CFStringGetCString(hostname, strbuf, maxLen, kCFStringEncodingUTF8)) { hostnamestr = strbuf; } } } uint32 hostnamelen = (hostnamestr) ? (uint32)strlen(hostnamestr) : 0; uint32 flags = 0x00000002; // 2nd-lowest bit set to require Apple intermediate pin CSSM_APPLE_TP_SSL_OPTIONS opts = {CSSM_APPLE_TP_SSL_OPTS_VERSION, hostnamelen, hostnamestr, flags}; CSSM_DATA data = {sizeof(opts), (uint8*)&opts}; SecPolicySetValue(policy, &data); } return policy; }
bool verify_X509_cert_chain(const std::vector<std::string> &certChain, const std::string &hostName) { // Build up CFArrayRef with all the certificates. // All this code is basically just to get into the correct structures for the Apple APIs. // Copies are avoided whenever possible. std::vector<cf_ref<SecCertificateRef>> certs; for(const auto & certBuf : certChain) { cf_ref<CFDataRef> certDataRef = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const unsigned char*>(certBuf.c_str()), certBuf.size(), kCFAllocatorNull); if(certDataRef.get() == nullptr) { return false; } cf_ref<SecCertificateRef> certObj = SecCertificateCreateWithData(nullptr, certDataRef.get()); if(certObj.get() == nullptr) { return false; } certs.push_back(std::move(certObj)); } cf_ref<CFArrayRef> certsArray = CFArrayCreate(kCFAllocatorDefault, const_cast<const void **>(reinterpret_cast<void **>(&certs[0])), certs.size(), nullptr); if(certsArray.get() == nullptr) { return false; } // Create trust management object with certificates and SSL policy. // Note: SecTrustCreateWithCertificates expects the certificate to be // verified is the first element. cf_ref<CFStringRef> cfHostName = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, hostName.c_str(), kCFStringEncodingASCII, kCFAllocatorNull); if(cfHostName.get() == nullptr) { return false; } cf_ref<SecPolicyRef> policy = SecPolicyCreateSSL(true /* client side */, cfHostName.get()); cf_ref<SecTrustRef> trust; OSStatus status = SecTrustCreateWithCertificates(certsArray.get(), policy.get(), &trust.get()); if(status == noErr) { // Perform actual certificate verification. SecTrustResultType trustResult; status = SecTrustEvaluate(trust.get(), &trustResult); if(status == noErr && (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed)) { return true; } } return false; }
OSStatus sslCreateSecTrust( SSLContext *ctx, CFArrayRef certChain, bool arePeerCerts, SecTrustRef *pTrust) /* RETURNED */ { OSStatus status = memFullErr; CFStringRef peerDomainName = NULL; CFTypeRef policies = NULL; SecTrustRef trust = NULL; if (CFArrayGetCount(certChain) == 0) { status = errSSLBadCert; goto errOut; } if (arePeerCerts) { if (ctx->peerDomainNameLen && ctx->peerDomainName) { CFIndex len = ctx->peerDomainNameLen; if (ctx->peerDomainName[len - 1] == 0) { len--; //secwarning("peerDomainName is zero terminated!"); } /* @@@ Double check that this is the correct encoding. */ require(peerDomainName = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)ctx->peerDomainName, len, kCFStringEncodingUTF8, false), errOut); } } /* If we are the client, our peer certificates must satisfy the ssl server policy. */ bool server = ctx->protocolSide == kSSLClientSide; require(policies = SecPolicyCreateSSL(server, peerDomainName), errOut); require_noerr(status = SecTrustCreateWithCertificates(certChain, policies, &trust), errOut); /* If we have trustedAnchors we set them here. */ if (ctx->trustedCerts) { require_noerr(status = SecTrustSetAnchorCertificates(trust, ctx->trustedCerts), errOut); require_noerr(status = SecTrustSetAnchorCertificatesOnly(trust, ctx->trustedCertsOnly), errOut); } status = noErr; errOut: CFReleaseSafe(peerDomainName); CFReleaseSafe(policies); *pTrust = trust; return status; }
static CFArrayRef /* O - Array of certificates */ copy_cdsa_certificate( cupsd_client_t *con) /* I - Client connection */ { OSStatus err; /* Error info */ SecKeychainRef keychain = NULL;/* Keychain reference */ SecIdentitySearchRef search = NULL; /* Search reference */ SecIdentityRef identity = NULL;/* Identity */ CFArrayRef certificates = NULL; /* Certificate array */ SecPolicyRef policy = NULL; /* Policy ref */ CFStringRef servername = NULL; /* Server name */ CFMutableDictionaryRef query = NULL; /* Query qualifiers */ CFArrayRef list = NULL; /* Keychain list */ # if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) char localname[1024];/* Local hostname */ # endif /* HAVE_DNSSD || HAVE_AVAHI */ cupsdLogMessage(CUPSD_LOG_DEBUG, "copy_cdsa_certificate: Looking for certs for \"%s\".", con->servername); if ((err = SecKeychainOpen(ServerCertificate, &keychain))) { cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot open keychain \"%s\" - %s (%d)", ServerCertificate, cssmErrorString(err), (int)err); goto cleanup; } servername = CFStringCreateWithCString(kCFAllocatorDefault, con->servername, kCFStringEncodingUTF8); policy = SecPolicyCreateSSL(1, servername); if (servername) CFRelease(servername); if (!policy) { cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference"); goto cleanup; } if (!(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks))) { cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create query dictionary"); goto cleanup; } list = CFArrayCreate(kCFAllocatorDefault, (const void **)&keychain, 1, &kCFTypeArrayCallBacks); CFDictionaryAddValue(query, kSecClass, kSecClassIdentity); CFDictionaryAddValue(query, kSecMatchPolicy, policy); CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue); CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne); CFDictionaryAddValue(query, kSecMatchSearchList, list); CFRelease(list); err = SecItemCopyMatching(query, (CFTypeRef *)&identity); # if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) if (err && DNSSDHostName) { /* * Search for the connection server name failed; try the DNS-SD .local * hostname instead... */ snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName); cupsdLogMessage(CUPSD_LOG_DEBUG, "copy_cdsa_certificate: Looking for certs for \"%s\".", localname); servername = CFStringCreateWithCString(kCFAllocatorDefault, localname, kCFStringEncodingUTF8); CFRelease(policy); policy = SecPolicyCreateSSL(1, servername); if (servername) CFRelease(servername); if (!policy) { cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference"); goto cleanup; } CFDictionarySetValue(query, kSecMatchPolicy, policy); err = SecItemCopyMatching(query, (CFTypeRef *)&identity); } # endif /* HAVE_DNSSD || HAVE_AVAHI */ if (err) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Cannot find signing key in keychain \"%s\": %s (%d)", ServerCertificate, cssmErrorString(err), (int)err); goto cleanup; } if (CFGetTypeID(identity) != SecIdentityGetTypeID()) { cupsdLogMessage(CUPSD_LOG_ERROR, "SecIdentity CFTypeID failure."); goto cleanup; } if ((certificates = CFArrayCreate(NULL, (const void **)&identity, 1, &kCFTypeArrayCallBacks)) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create certificate array"); goto cleanup; } cleanup : if (keychain) CFRelease(keychain); if (search) CFRelease(search); if (identity) CFRelease(identity); if (policy) CFRelease(policy); if (query) CFRelease(query); return (certificates); }
bool mailcore::checkCertificate(mailstream * stream, String * hostname) { #if __APPLE__ bool result = false; CFStringRef hostnameCFString; SecPolicyRef policy; CFMutableArrayRef certificates; SecTrustRef trust = NULL; SecTrustResultType trustResult; OSStatus status; carray * cCerts = mailstream_get_certificate_chain(stream); if (cCerts == NULL) { fprintf(stderr, "warning: No certificate chain retrieved"); goto err; } hostnameCFString = CFStringCreateWithCharacters(NULL, (const UniChar *) hostname->unicodeCharacters(), hostname->length()); policy = SecPolicyCreateSSL(true, hostnameCFString); certificates = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for(unsigned int i = 0 ; i < carray_count(cCerts) ; i ++) { MMAPString * str; str = (MMAPString *) carray_get(cCerts, i); CFDataRef data = CFDataCreate(NULL, (const UInt8 *) str->str, (CFIndex) str->len); SecCertificateRef cert = SecCertificateCreateWithData(NULL, data); CFArrayAppendValue(certificates, cert); CFRelease(data); CFRelease(cert); } static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // The below API calls are not thread safe. We're making sure not to call the concurrently. pthread_mutex_lock(&lock); status = SecTrustCreateWithCertificates(certificates, policy, &trust); if (status != noErr) { pthread_mutex_unlock(&lock); goto free_certs; } status = SecTrustEvaluate(trust, &trustResult); if (status != noErr) { pthread_mutex_unlock(&lock); goto free_certs; } pthread_mutex_unlock(&lock); switch (trustResult) { case kSecTrustResultUnspecified: case kSecTrustResultProceed: // certificate chain is ok result = true; break; default: // certificate chain is invalid break; } CFRelease(trust); free_certs: CFRelease(certificates); mailstream_certificate_chain_free(cCerts); CFRelease(policy); CFRelease(hostnameCFString); err: return result; #else bool result = false; X509_STORE * store = NULL; X509_STORE_CTX * storectx = NULL; STACK_OF(X509) * certificates = NULL; #if defined(ANDROID) || defined(__ANDROID__) DIR * dir = NULL; struct dirent * ent = NULL; FILE * f = NULL; #endif int status; carray * cCerts = mailstream_get_certificate_chain(stream); if (cCerts == NULL) { fprintf(stderr, "warning: No certificate chain retrieved"); goto err; } store = X509_STORE_new(); if (store == NULL) { goto free_certs; } #ifdef _MSC_VER HCERTSTORE systemStore = CertOpenSystemStore(NULL, L"ROOT"); PCCERT_CONTEXT previousCert = NULL; while (1) { PCCERT_CONTEXT nextCert = CertEnumCertificatesInStore(systemStore, previousCert); if (nextCert == NULL) { break; } X509 * openSSLCert = d2i_X509(NULL, (const unsigned char **)&nextCert->pbCertEncoded, nextCert->cbCertEncoded); if (openSSLCert != NULL) { X509_STORE_add_cert(store, openSSLCert); X509_free(openSSLCert); } previousCert = nextCert; } CertCloseStore(systemStore, 0); #elif defined(ANDROID) || defined(__ANDROID__) dir = opendir("/system/etc/security/cacerts"); while (ent = readdir(dir)) { if (ent->d_name[0] == '.') { continue; } char filename[1024]; snprintf(filename, sizeof(filename), "/system/etc/security/cacerts/%s", ent->d_name); f = fopen(filename, "rb"); if (f != NULL) { X509 * cert = PEM_read_X509(f, NULL, NULL, NULL); if (cert != NULL) { X509_STORE_add_cert(store, cert); X509_free(cert); } fclose(f); } } closedir(dir); #endif status = X509_STORE_set_default_paths(store); if (status != 1) { printf("Error loading the system-wide CA certificates"); } certificates = sk_X509_new_null(); for(unsigned int i = 0 ; i < carray_count(cCerts) ; i ++) { MMAPString * str; str = (MMAPString *) carray_get(cCerts, i); if (str == NULL) { goto free_certs; } BIO *bio = BIO_new_mem_buf((void *) str->str, str->len); X509 *certificate = d2i_X509_bio(bio, NULL); BIO_free(bio); if (!sk_X509_push(certificates, certificate)) { goto free_certs; } } storectx = X509_STORE_CTX_new(); if (storectx == NULL) { goto free_certs; } status = X509_STORE_CTX_init(storectx, store, sk_X509_value(certificates, 0), certificates); if (status != 1) { goto free_certs; } status = X509_verify_cert(storectx); if (status == 1) { result = true; } free_certs: mailstream_certificate_chain_free(cCerts); if (certificates != NULL) { sk_X509_pop_free((STACK_OF(X509) *) certificates, X509_free); }
SecPolicyRef SecPolicyCreateAppleMMCSService(CFStringRef hostname) { return SecPolicyCreateSSL(true, hostname); }
/* Test basic add delete update copy matching stuff. */ static void tests(void) { SecTrustRef trust; SecCertificateRef cert0, cert1; isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), NULL, "create cert0"); isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), NULL, "create cert1"); const void *v_certs[] = { cert0, cert1 }; SecPolicyRef policy = SecPolicyCreateSSL(false, NULL); CFArrayRef certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), NULL); /* SecTrustCreateWithCertificates using single cert. */ ok_status(SecTrustCreateWithCertificates(cert0, policy, &trust), "create trust with single cert0"); is(SecTrustGetCertificateCount(trust), 1, "cert count is 1"); is(SecTrustGetCertificateAtIndex(trust, 0), cert0, "cert 0 is leaf"); CFReleaseNull(trust); /* SecTrustCreateWithCertificates failures. */ is_status(SecTrustCreateWithCertificates(kCFBooleanTrue, policy, &trust), errSecParam, "create trust with boolean instead of cert"); is_status(SecTrustCreateWithCertificates(cert0, kCFBooleanTrue, &trust), errSecParam, "create trust with boolean instead of policy"); /* SecTrustCreateWithCertificates using array of certs. */ ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust"); /* NOTE: prior to <rdar://11810677 SecTrustGetCertificateCount would return 1 at this point. * Now, however, we do an implicit SecTrustEvaluate to build the chain if it has not yet been * evaluated, so we now expect the full chain length. */ is(SecTrustGetCertificateCount(trust), 3, "cert count is 3"); is(SecTrustGetCertificateAtIndex(trust, 0), cert0, "cert 0 is leaf"); /* Jan 1st 2006. */ CFDateRef date = CFDateCreate(NULL, 157680000.0); ok_status(SecTrustSetVerifyDate(trust, date), "set date"); is(SecTrustGetVerifyTime(trust), 157680000.0, "get date"); SecTrustResultType trustResult; SKIP: { #ifdef NO_SERVER skip("Can't fail to connect to securityd in NO_SERVER mode", 4, false); #endif // Test Restore OS environment SecServerSetMachServiceName("com.apple.security.doesn't-exist"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust without securityd running"); is_status(trustResult, kSecTrustResultInvalid, "trustResult is kSecTrustResultInvalid"); is(SecTrustGetCertificateCount(trust), 1, "cert count is 1 without securityd running"); SecKeyRef pubKey = NULL; ok(pubKey = SecTrustCopyPublicKey(trust), "copy public key without securityd running"); CFReleaseNull(pubKey); SecServerSetMachServiceName(NULL); // End of Restore OS environment tests } ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultUnspecified, "trustResult is kSecTrustResultUnspecified"); is(SecTrustGetCertificateCount(trust), 3, "cert count is 3"); CFDataRef c0_serial = CFDataCreate(NULL, _c0_serial, sizeof(_c0_serial)); CFDataRef serial; ok(serial = SecCertificateCopySerialNumber(cert0), "copy cert0 serial"); ok(CFEqual(c0_serial, serial), "serial matches"); CFArrayRef anchors = CFArrayCreate(NULL, (const void **)&cert1, 1, &kCFTypeArrayCallBacks); ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); is(SecTrustGetCertificateCount(trust), 2, "cert count is 2"); CFReleaseSafe(anchors); anchors = CFArrayCreate(NULL, NULL, 0, NULL); ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set empty anchors list"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); ok_status(SecTrustSetAnchorCertificatesOnly(trust, false), "trust passed in anchors and system anchors"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); ok_status(SecTrustSetAnchorCertificatesOnly(trust, true), "only trust passed in anchors (default)"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); /* Test cert_1 intermididate from the keychain. */ CFReleaseSafe(trust); ok_status(SecTrustCreateWithCertificates(cert0, policy, &trust), "create trust with single cert0"); ok_status(SecTrustSetVerifyDate(trust, date), "set date"); // Add cert1 CFDictionaryRef query = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, kSecClass, kSecClassCertificate, kSecValueRef, cert1, NULL); ok_status(SecItemAdd(query, NULL), "add cert1 to keychain"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); // Cleanup added cert1. ok_status(SecItemDelete(query), "remove cert1 from keychain"); CFReleaseSafe(query); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); is(SecTrustGetCertificateCount(trust), 3, "cert count is 3"); /* Set certs to be the xedge2 leaf. */ CFReleaseSafe(certs); const void *cert_xedge2; isnt(cert_xedge2 = SecCertificateCreateWithBytes(NULL, xedge2_certificate, sizeof(xedge2_certificate)), NULL, "create cert_xedge2"); certs = CFArrayCreate(NULL, &cert_xedge2, 1, NULL); CFReleaseSafe(trust); CFReleaseSafe(policy); CFReleaseSafe(date); bool server = true; policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for ssl server xedge2.apple.com"); /* Jan 1st 2009. */ date = CFDateCreate(NULL, 252288000.0); ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); CFReleaseSafe(trust); CFReleaseSafe(policy); server = false; policy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for ssl client xedge2.apple.com"); ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); CFReleaseSafe(trust); CFReleaseSafe(policy); server = true; policy = SecPolicyCreateIPSec(server, CFSTR("xedge2.apple.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for ip server xedge2.apple.com"); ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust"); #if 0 /* Although this shouldn't be a valid ipsec cert, since we no longer check for ekus in the ipsec policy it is. */ is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); #else is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); #endif CFReleaseSafe(trust); CFReleaseSafe(policy); server = true; policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for ssl server nowhere.com"); SecPolicyRef replacementPolicy = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com")); SecTrustSetPolicies(trust, replacementPolicy); CFReleaseSafe(replacementPolicy); ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); CFReleaseSafe(trust); CFReleaseSafe(policy); server = true; policy = SecPolicyCreateSSL(server, CFSTR("nowhere.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for ssl server nowhere.com"); SecPolicyRef replacementPolicy2 = SecPolicyCreateSSL(server, CFSTR("xedge2.apple.com")); CFArrayRef replacementPolicies = CFArrayCreate(kCFAllocatorDefault, (CFTypeRef*)&replacementPolicy2, 1, &kCFTypeArrayCallBacks); SecTrustSetPolicies(trust, replacementPolicies); CFReleaseSafe(replacementPolicy2); CFReleaseSafe(replacementPolicies); ok_status(SecTrustSetVerifyDate(trust, date), "set xedge2 trust date to Jan 1st 2009"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate xedge2 trust"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); /* Test self signed ssl cert with cert itself set as anchor. */ CFReleaseSafe(trust); CFReleaseSafe(policy); CFReleaseSafe(certs); CFReleaseSafe(date); const void *garthc2; server = true; isnt(garthc2 = SecCertificateCreateWithBytes(NULL, garthc2_certificate, sizeof(garthc2_certificate)), NULL, "create garthc2"); certs = CFArrayCreate(NULL, &garthc2, 1, NULL); policy = SecPolicyCreateSSL(server, CFSTR("garthc2.apple.com")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for ip server garthc2.apple.com"); date = CFDateCreate(NULL, 269568000.0); ok_status(SecTrustSetVerifyDate(trust, date), "set garthc2 trust date to Aug 2009"); ok_status(SecTrustSetAnchorCertificates(trust, certs), "set garthc2 as anchor"); ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate self signed cert with cert as anchor"); is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); CFReleaseSafe(garthc2); CFReleaseSafe(cert_xedge2); CFReleaseSafe(anchors); CFReleaseSafe(trust); CFReleaseSafe(serial); CFReleaseSafe(c0_serial); CFReleaseSafe(policy); CFReleaseSafe(certs); CFReleaseSafe(cert0); CFReleaseSafe(cert1); CFReleaseSafe(date); /* Test prt_forest_fi */ const void *prt_forest_fi; isnt(prt_forest_fi = SecCertificateCreateWithBytes(NULL, prt_forest_fi_certificate, sizeof(prt_forest_fi_certificate)), NULL, "create prt_forest_fi"); isnt(certs = CFArrayCreate(NULL, &prt_forest_fi, 1, NULL), NULL, "failed to create cert array"); policy = SecPolicyCreateSSL(false, CFSTR("owa.prt-forest.fi")); ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust for ip client owa.prt-forest.fi"); date = CFDateCreate(NULL, 391578321.0); ok_status(SecTrustSetVerifyDate(trust, date), "set owa.prt-forest.fi trust date to May 2013"); SecKeyRef pubkey = SecTrustCopyPublicKey(trust); is(pubkey, NULL, "pubkey returned"); CFReleaseSafe(certs); CFReleaseNull(prt_forest_fi); CFReleaseNull(policy); CFReleaseNull(trust); CFReleaseNull(pubkey); CFReleaseNull(date); }