示例#1
0
      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());
}
示例#3
0
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);
}
示例#6
0
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);
}
示例#10
0
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;
}