Certificate_Store_MacOS_Impl() : m_policy(SecPolicyCreateBasicX509()), m_system_roots(nullptr), m_system_chain(nullptr), m_keychains(nullptr) { check_success(SecKeychainOpen(system_roots, &m_system_roots.get()), "open system root certificates"); check_success(SecKeychainOpen(system_keychain, &m_system_chain.get()), "open system keychain"); check_notnull(m_system_roots, "open system root certificate chain"); check_notnull(m_system_chain, "open system certificate chain"); // m_keychains is merely a convenience list view into all open keychain // objects. This list is required in prepareQuery(). std::array<const void*, 2> keychains{{ m_system_roots.get(), m_system_chain.get() }}; m_keychains.assign( CFArrayCreate(kCFAllocatorDefault, keychains.data(), keychains.size(), &kCFTypeArrayCallBacks)); check_notnull(m_keychains, "initialize keychain array"); }
static CFTypeRef installerPolicy() { CFRef<SecPolicyRef> base = SecPolicyCreateBasicX509(); CFRef<SecPolicyRef> crl = makeCRLPolicy(); CFRef<SecPolicyRef> ocsp = makeOCSPPolicy(); return makeCFArray(3, base.get(), crl.get(), ocsp.get()); }
SecPolicyRef AppleCryptoNative_X509ChainCreateDefaultPolicy() { // Disable on macOS 10.11 and lower due to segfaults within Security.framework. if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber10_12) return NULL; return SecPolicyCreateBasicX509(); }
static void tests(void) { SecPolicyRef basicPolicy = SecPolicyCreateBasicX509(); /* Run the tests. */ runCertificateTestForDirectory(basicPolicy, CFSTR("nist-certs"), NULL); CFReleaseSafe(basicPolicy); }
static void build_trust_chains(const void *key, const void *value, void *context) { CFMutableDictionaryRef identity_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); SecKeyRef private_key = NULL; SecCertificateRef cert = NULL; SecIdentityRef identity = NULL; SecPolicyRef policy = NULL; CFMutableArrayRef cert_chain = NULL, eval_chain = NULL; SecTrustRef trust = NULL; build_trust_chains_context * a_build_trust_chains_context = (build_trust_chains_context*)context; CFDataRef key_bytes = CFDictionaryGetValue(value, CFSTR("key")); require(key_bytes, out); CFDataRef cert_bytes = CFDictionaryGetValue(value, CFSTR("cert")); require(cert_bytes, out); /* p12import only passes up rsa keys */ require (private_key = SecKeyCreateRSAPrivateKey(kCFAllocatorDefault, CFDataGetBytePtr(key_bytes), CFDataGetLength(key_bytes), kSecKeyEncodingPkcs1), out); require(cert = SecCertificateCreateWithData(kCFAllocatorDefault, cert_bytes), out); require(identity = SecIdentityCreate(kCFAllocatorDefault, cert, private_key), out); CFDictionarySetValue(identity_dict, kSecImportItemIdentity, identity); eval_chain = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); require(eval_chain, out); CFArrayAppendValue(eval_chain, cert); CFRange all_certs = { 0, CFArrayGetCount(a_build_trust_chains_context->certs) }; CFArrayAppendArray(eval_chain, a_build_trust_chains_context->certs, all_certs); require(policy = SecPolicyCreateBasicX509(), out); SecTrustResultType result; SecTrustCreateWithCertificates(eval_chain, policy, &trust); require(trust, out); SecTrustEvaluate(trust, &result); CFDictionarySetValue(identity_dict, kSecImportItemTrust, trust); require(cert_chain = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks), out); CFIndex cert_chain_length = SecTrustGetCertificateCount(trust); int i; for (i = 0; i < cert_chain_length; i++) CFArrayAppendValue(cert_chain, SecTrustGetCertificateAtIndex(trust, i)); CFDictionarySetValue(identity_dict, kSecImportItemCertChain, cert_chain); CFArrayAppendValue(a_build_trust_chains_context->identities, identity_dict); out: CFReleaseSafe(identity_dict); CFReleaseSafe(identity); CFReleaseSafe(private_key); CFReleaseSafe(cert); CFReleaseSafe(policy); CFReleaseSafe(cert_chain); CFReleaseSafe(eval_chain); CFReleaseSafe(trust); }
int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size) { CMSDecoderRef decoder = NULL; CMSSignerStatus signer_status = 0; CFDataRef message_out = NULL; SecPolicyRef trust_policy = NULL; OSStatus status = noErr; OSStatus verify_status = noErr; size_t signer_count = 0; size_t i = 0; int32_t err = MZ_SIGN_ERROR; if (message == NULL || signature == NULL) return MZ_PARAM_ERROR; status = CMSDecoderCreate(&decoder); if (status == errSecSuccess) status = CMSDecoderUpdateMessage(decoder, signature, signature_size); if (status == errSecSuccess) status = CMSDecoderFinalizeMessage(decoder); if (status == errSecSuccess) trust_policy = SecPolicyCreateBasicX509(); if (status == errSecSuccess && trust_policy) { CMSDecoderGetNumSigners(decoder, &signer_count); if (signer_count > 0) err = MZ_OK; for (i = 0; i < signer_count; i += 1) { status = CMSDecoderCopySignerStatus(decoder, i, trust_policy, TRUE, &signer_status, NULL, &verify_status); if (status != errSecSuccess || verify_status != 0 || signer_status != kCMSSignerValid) { err = MZ_SIGN_ERROR; break; } } } if (err == MZ_OK) { status = CMSDecoderCopyContent(decoder, &message_out); if ((status != errSecSuccess) || (CFDataGetLength(message_out) != message_size) || (memcmp(message, CFDataGetBytePtr(message_out), message_size) != 0)) err = MZ_SIGN_ERROR; } if (trust_policy) CFRelease(trust_policy); if (decoder) CFRelease(decoder); return err; }
static void tests(void) { CFDataRef attached_signed_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, attached_signed_data_der, attached_signed_data_der_len, kCFAllocatorNull); CFDataRef detached_signed_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, detached_signed_data_der, detached_signed_data_der_len, kCFAllocatorNull); CFDataRef attached_no_data_signed_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, attached_no_data_signed_data_der, attached_no_data_signed_data_der_len, kCFAllocatorNull); CFDataRef detached_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, detached_content, detached_content_len, kCFAllocatorNull); CFDataRef no_data = CFDataCreate(kCFAllocatorDefault, NULL, 0); SecPolicyRef policy = SecPolicyCreateBasicX509(); SecTrustRef trust = NULL; ok_status(SecCMSVerifyCopyDataAndAttributes(attached_signed_data, NULL, policy, &trust, NULL, NULL), "verify attached data"); CFRelease(trust); ok_status(SecCMSVerifyCopyDataAndAttributes(detached_signed_data, detached_data, policy, &trust, NULL, NULL), "verify detached data"); CFRelease(trust); ok_status(SecCMSVerifyCopyDataAndAttributes(attached_no_data_signed_data, NULL, policy, &trust, NULL, NULL), "verify attached no data"); CFRelease(trust); ok_status(SecCMSVerifyCopyDataAndAttributes(attached_no_data_signed_data, no_data, policy, &trust, NULL, NULL), "verify attached no data"); CFRelease(trust); SecCertificateRef cert = NULL; SecKeyRef privKey = NULL; SecIdentityRef identity = NULL; isnt(cert = SecCertificateCreateWithBytes(NULL, signer_der, signer_der_len), NULL, "create certificate"); isnt(privKey = SecKeyCreateRSAPrivateKey(NULL, privkey_der, privkey_der_len, kSecKeyEncodingPkcs1), NULL, "create private key"); isnt(identity = SecIdentityCreate(NULL, cert, privKey), NULL, "create identity"); CFReleaseSafe(privKey); CFMutableDataRef cms_data = CFDataCreateMutable(kCFAllocatorDefault, 0); ok_status(SecCMSCreateSignedData(identity, detached_data, NULL, NULL, cms_data), "create attached data"); //write_data("/var/tmp/attached", cms_data); CFDataSetLength(cms_data, 0); CFDictionaryRef detached_cms_dict = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&kSecCMSSignDetached, (const void **)&kCFBooleanTrue, 1, NULL, NULL); ok_status(SecCMSCreateSignedData(identity, detached_data, detached_cms_dict, NULL, cms_data), "create attached data"); CFRelease(detached_cms_dict); //write_data("/var/tmp/detached", cms_data); CFDataSetLength(cms_data, 0); ok_status(SecCMSCreateSignedData(identity, NULL, NULL, NULL, cms_data), "create attached data"); //write_data("/var/tmp/empty_attached", cms_data); CFReleaseSafe(cms_data); CFReleaseSafe(cert); CFReleaseNull(identity); CFRelease(attached_signed_data); CFRelease(detached_signed_data); CFRelease(attached_no_data_signed_data); CFRelease(detached_data); CFRelease(no_data); CFRelease(policy); }
static void tests(void) { CFErrorRef error = NULL; CFDataRef testData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)testbytes, testbytes_size, kCFAllocatorNull); SecCertificateRef cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, public_cert_der, sizeof(public_cert_der)); CFArrayRef certInArray = CFArrayCreateForCFTypes(kCFAllocatorDefault, cert, NULL); SecKeyRef full_key = SecKeyCreateECPrivateKey(kCFAllocatorDefault, private_key_der, sizeof(private_key_der), kSecKeyEncodingPkcs1); SecTrustRef trust = NULL; SecPolicyRef basic = SecPolicyCreateBasicX509(); OSStatus status = SecTrustCreateWithCertificates(cert, basic, &trust); ok_status(status, "created"); CFReleaseNull(basic); status = SecTrustSetAnchorCertificates(trust, certInArray); ok_status(status, "Anchors"); SecTrustResultType result; status = SecTrustEvaluate(trust, &result); ok_status(status, "Trust evaluation"); is(result, (SecTrustResultType)kSecTrustResultUnspecified, "Trust result"); CFDataRef encrypted = SecCopyEncryptedToServer(trust, testData, &error); ok(encrypted != NULL, "Encrypt to server (%@)", error); CFReleaseNull(error); ok(!CFEqualSafe(testData, encrypted), "encrypted different"); CFDataRef decrypted = SecCopyDecryptedForServer(full_key, encrypted, &error); ok(decrypted != NULL, "Decrypt from server (%@)", error); ok(CFEqualSafe(testData, decrypted), "round trip"); CFReleaseNull(cert); CFReleaseNull(certInArray); CFReleaseNull(trust); CFReleaseNull(testData); CFReleaseNull(encrypted); CFReleaseNull(decrypted); }
static OSStatus _EAPSecIdentityCreateCertificateTrustChain(SecIdentityRef identity, CFArrayRef * ret_chain) { SecCertificateRef cert = NULL; CFArrayRef certs; SecPolicyRef policy = NULL; OSStatus status; SecTrustRef trust = NULL; SecTrustResultType trust_result; *ret_chain = NULL; ok(policy = SecPolicyCreateBasicX509(), "SecPolicyCreateBasicX509"); ok_status(status = SecIdentityCopyCertificate(identity, &cert), "SecIdentityCopyCertificate"); certs = CFArrayCreate(NULL, (const void **)&cert, 1, &kCFTypeArrayCallBacks); CFReleaseNull(cert); ok_status(status = SecTrustCreateWithCertificates(certs, policy, &trust), "SecTrustCreateWithCertificates"); CFReleaseNull(certs); ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate"); { CFMutableArrayRef array; CFIndex count = SecTrustGetCertificateCount(trust); CFIndex i; isnt(count, 0, "SecTrustGetCertificateCount is nonzero"); array = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks); for (i = 0; i < count; i++) { SecCertificateRef s; s = SecTrustGetCertificateAtIndex(trust, i); CFArrayAppendValue(array, s); } *ret_chain = array; } CFReleaseNull(trust); CFReleaseNull(policy); return (status); }
OSStatus parseIncomingCerts( SSLContext *ctx, CFArrayRef certs, CFArrayRef *destCertChain, /* &ctx->{localCertChain,encryptCertChain} */ SSLPubKey **sslPubKey, /* &ctx->signingPubKey, etc. */ SSLPrivKey **sslPrivKey, /* &ctx->signingPrivKeyRef, etc. */ CFIndex *signerAlg) /* optional */ { OSStatus ortn; CFIndex ix, numCerts; SecIdentityRef identity; CFMutableArrayRef certChain = NULL; /* Retained */ SecCertificateRef leafCert = NULL; /* Retained */ SecKeyRef pubKey = NULL; /* Retained */ SecKeyRef privKey = NULL; /* Retained */ SecTrustRef trust = NULL; /* Retained */ SecTrustResultType trustResult; assert(ctx != NULL); assert(destCertChain != NULL); /* though its referent may be NULL */ assert(sslPubKey != NULL); assert(sslPrivKey != NULL); if (certs == NULL) { sslErrorLog("parseIncomingCerts: NULL incoming cert array\n"); ortn = errSSLBadCert; goto errOut; } numCerts = CFArrayGetCount(certs); if (numCerts == 0) { sslErrorLog("parseIncomingCerts: empty incoming cert array\n"); ortn = errSSLBadCert; goto errOut; } /* * Certs[0] is an SecIdentityRef from which we extract subject cert, * privKey, pubKey. * * 1. ensure the first element is a SecIdentityRef. */ identity = (SecIdentityRef)CFArrayGetValueAtIndex(certs, 0); if (identity == NULL) { sslErrorLog("parseIncomingCerts: bad cert array (1)\n"); ortn = paramErr; goto errOut; } if (CFGetTypeID(identity) != SecIdentityGetTypeID()) { sslErrorLog("parseIncomingCerts: bad cert array (2)\n"); ortn = paramErr; goto errOut; } /* * 2. Extract cert, keys and convert to local format. */ ortn = SecIdentityCopyCertificate(identity, &leafCert); if (ortn) { sslErrorLog("parseIncomingCerts: bad cert array (3)\n"); goto errOut; } /* Fetch private key from identity */ ortn = SecIdentityCopyPrivateKey(identity, &privKey); if (ortn) { sslErrorLog("parseIncomingCerts: SecIdentityCopyPrivateKey err %d\n", (int)ortn); goto errOut; } /* Convert the input array of SecIdentityRef at the start to an array of all certificates. */ certChain = CFArrayCreateMutable(kCFAllocatorDefault, numCerts, &kCFTypeArrayCallBacks); if (!certChain) { ortn = memFullErr; goto errOut; } CFArrayAppendValue(certChain, leafCert); for (ix = 1; ix < numCerts; ++ix) { SecCertificateRef intermediate = (SecCertificateRef)CFArrayGetValueAtIndex(certs, ix); if (intermediate == NULL) { sslErrorLog("parseIncomingCerts: bad cert array (5)\n"); ortn = paramErr; goto errOut; } if (CFGetTypeID(intermediate) != SecCertificateGetTypeID()) { sslErrorLog("parseIncomingCerts: bad cert array (6)\n"); ortn = paramErr; goto errOut; } CFArrayAppendValue(certChain, intermediate); } /* Obtain public key from cert */ #if TARGET_OS_IOS ortn = SecTrustCreateWithCertificates(certChain, NULL, &trust); #else { SecPolicyRef policy = SecPolicyCreateBasicX509(); ortn = SecTrustCreateWithCertificates(certChain, policy, &trust); CFReleaseSafe(policy); if (!ortn) { /* We are only interested in getting the public key from the leaf * cert here, so for best performance, don't try to build a chain * or search any keychains. */ CFArrayRef emptyArray = CFArrayCreate(NULL, NULL, 0, NULL); (void)SecTrustSetAnchorCertificates(trust, emptyArray); (void)SecTrustSetKeychains(trust, emptyArray); CFReleaseSafe(emptyArray); } } #endif if (ortn) { sslErrorLog("parseIncomingCerts: SecTrustCreateWithCertificates err %d\n", (int)ortn); goto errOut; } ortn = SecTrustEvaluate(trust, &trustResult); if (ortn) { sslErrorLog("parseIncomingCerts: SecTrustEvaluate err %d\n", (int)ortn); goto errOut; } pubKey = SecTrustCopyPublicKey(trust); if (pubKey == NULL) { sslErrorLog("parseIncomingCerts: SecTrustCopyPublicKey failed\n"); ortn = -67712; // errSecInvalidKeyRef goto errOut; } /* SUCCESS */ errOut: CFReleaseSafe(trust); CFReleaseSafe(leafCert); CFReleaseSafe(*destCertChain); sslFreePubKey(sslPubKey); sslFreePrivKey(sslPrivKey); if (ortn) { CFReleaseSafe(certChain); CFReleaseSafe(pubKey); CFReleaseSafe(privKey); *destCertChain = NULL; } else { *destCertChain = certChain; *sslPubKey = (SSLPubKey*)pubKey; *sslPrivKey = (SSLPrivKey*)privKey; } return ortn; }