OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArrayRef *items)
{
    pkcs12_context context = {};
    SecAsn1CoderCreate(&context.coder);
    if (options)
        context.passphrase = CFDictionaryGetValue(options, kSecImportExportPassphrase);
    context.items = CFDictionaryCreateMutable(kCFAllocatorDefault, 
        0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    int status = p12decode(&context, pkcs12_data);
    if (!status) {
        CFMutableArrayRef certs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        CFDictionaryApplyFunction(context.items, collect_certs, certs);

        CFMutableArrayRef identities = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
        build_trust_chains_context a_build_trust_chains_context = { identities, certs };
        CFDictionaryApplyFunction(context.items, build_trust_chains, &a_build_trust_chains_context);
        CFReleaseSafe(certs);
        
        /* ignoring certs that weren't picked up as part of the certchain for found keys */
        
        *items = identities;
    }

    CFReleaseSafe(context.items);
    SecAsn1CoderRelease(context.coder);
    
    switch (status) {
    case p12_noErr: return noErr;
    case p12_passwordErr: return errSecAuthFailed;
    case p12_decodeErr: return errSecDecode;
    default: return errSecInternal;
    };
    return noErr;
}
示例#2
0
static void
securityd_server_trust_evaluate_done(const void *userData,
    SecCertificatePathRef chain, CFArrayRef details, CFDictionaryRef info,
    SecTrustResultType result) {
    struct securityd_server_trust_evaluation_context *tec =
        (struct securityd_server_trust_evaluation_context *)userData;

    /* @@@ This code snippit is also in SecTrustServer.c.  I'd factor it,
       but a better fix would be to change the interfaces here to not use
       single in/out args and do all the argument munging in server.c
       and client.c. */
    CFDictionaryRef args_out;
    CFNumberRef resultNumber = NULL;
    CFArrayRef chain_certs = NULL;
    /* Proccess outgoing results. */
    resultNumber = CFNumberCreate(NULL, kCFNumberSInt32Type, &result);
    chain_certs = SecCertificatePathCopyArray(chain);
    const void *out_keys[] = { kSecTrustChainKey, kSecTrustDetailsKey,
        kSecTrustInfoKey, kSecTrustResultKey };
    const void *out_values[] = { chain_certs, details, info, resultNumber };
    args_out = (CFTypeRef)CFDictionaryCreate(kCFAllocatorDefault, out_keys,
        out_values, sizeof(out_keys) / sizeof(*out_keys),
        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFReleaseSafe(chain_certs);
    CFReleaseSafe(resultNumber);

    /* Send back the response to the client. */
    securityd_server_send_reply(tec->reply, tec->request_id, noErr, args_out);

    free(tec);
}
示例#3
0
static int tls_create_trust_from_certs(const SSLCertificate *cert, SecTrustRef *trustRef)
{
    int err;
    CFMutableArrayRef certArray = NULL;
    CFDataRef certData = NULL;
    SecCertificateRef cfCert = NULL;

    if(cert==NULL) {
        test_printf("No certs, do not create SecTrustRef\n");
        *trustRef = NULL;
        return 0;
    }

    certArray = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    while(cert) {
        base64_dump(cert->derCert, "CERTIFICATE");
        require_action((certData = CFDataCreate(kCFAllocatorDefault, cert->derCert.data, cert->derCert.length)), out, err = errSecAllocate);
        require_action((cfCert = SecCertificateCreateWithData(kCFAllocatorDefault, certData)), out, err = errSecAllocate);
        CFArrayAppendValue(certArray, cfCert);
        CFReleaseNull(cfCert);
        CFReleaseNull(certData);
        cert=cert->next;
    }

    require_noerr((err=SecTrustCreateWithCertificates(certArray, NULL, trustRef)), out);

out:
    CFReleaseSafe(certData);
    CFReleaseSafe(cfCert);
    CFReleaseSafe(certArray);

    return err;
}
示例#4
0
/* Return the first certificate reference from the supplied array
 * whose data matches the given certificate, or NULL if none match.
 */
static
SecCertificateRef
sslGetMatchingCertInArray(
	SecCertificateRef	certRef,
	CFArrayRef			certArray)
{
	SecCertificateRef matchedCert = NULL;

	if (certRef == NULL || certArray == NULL) {
		return NULL;
	}

	CFDataRef certData = SecCertificateCopyData(certRef);
	if (certData) {
		CFIndex idx, count = CFArrayGetCount(certArray);
		for(idx=0; idx<count; idx++) {
			SecCertificateRef aCert = (SecCertificateRef)CFArrayGetValueAtIndex(certArray, idx);
			CFDataRef aData = SecCertificateCopyData(aCert);
			if (aData && CFEqual(aData, certData)) {
				matchedCert = aCert;
			}
			CFReleaseSafe(aData);
			if (matchedCert)
				break;
		}
		CFReleaseSafe(certData);
	}

    return matchedCert;
}
static void
SecTrustServerEvaluateDone(const void *userData,
    SecCertificatePathRef chain, CFArrayRef details, CFDictionaryRef info,
    SecTrustResultType result) {
    struct SecTrustEvaluationContext *tec =
        (struct SecTrustEvaluationContext *)userData;

    /* @@@ This code snippit is also in server.c.  I'd factor it, but a better
       fix would be to chage the interfaces here to not use single in/out args
       and do all the argument munging in server.c and client.c. */
    CFDictionaryRef args_out;
    CFNumberRef resultNumber = NULL;
    CFArrayRef chain_certs = NULL;
    /* Proccess outgoing results. */
    resultNumber = CFNumberCreate(NULL, kCFNumberSInt32Type, &result);
    chain_certs = SecCertificatePathCopyArray(chain);
    const void *out_keys[] = { kSecTrustChainKey, kSecTrustDetailsKey,
        kSecTrustInfoKey, kSecTrustResultKey };
    const void *out_values[] = { chain_certs, details, info, resultNumber };
    args_out = (CFTypeRef)CFDictionaryCreate(kCFAllocatorDefault, out_keys,
        out_values, sizeof(out_keys) / sizeof(*out_keys),
        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFReleaseSafe(chain_certs);
    CFReleaseSafe(resultNumber);

    /* Return the final result. */
    tec->args_out = args_out;
    if (tec->running) {
        /* Stop the runloop in SecTrustServerEvaluate if it is running. */
        CFRunLoopStop(CFRunLoopGetCurrent());
    }
}
OSStatus SecECKeyGeneratePair(CFDictionaryRef parameters,
                              SecKeyRef *publicKey, SecKeyRef *privateKey) {
    OSStatus status = errSecParam;

    CFAllocatorRef allocator = NULL; /* @@@ get from parameters. */
    SecKeyRef pubKey = NULL;

    SecKeyRef privKey = SecKeyCreate(allocator, &kSecECPrivateKeyDescriptor,
                                     (const void*) parameters, 0, kSecGenerateKey);

    require(privKey, errOut);

    /* Create SecKeyRef's from the pkcs1 encoded keys. */
    pubKey = SecKeyCreate(allocator, &kSecECPublicKeyDescriptor,
                                    privKey->key, 0, kSecExtractPublicFromPrivate);

    require(pubKey, errOut);

    if (publicKey) {
        *publicKey = pubKey;
        pubKey = NULL;
    }
    if (privateKey) {
        *privateKey = privKey;
        privKey = NULL;
    }

    status = errSecSuccess;

errOut:
    CFReleaseSafe(pubKey);
    CFReleaseSafe(privKey);

    return status;
}
static FILE *
open_bundle(const char * path, const char * mode)
{
    char full_path[1024] = {};
    CFStringRef path_cfstring = NULL;
    CFURLRef path_url = NULL;
    CFBundleRef bundle = NULL;
    CFURLRef exec = NULL;

    path_cfstring = CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path);
    require_quiet(path_cfstring, out);
    path_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_cfstring, kCFURLPOSIXPathStyle, true);
    require_quiet(path_url, out);
	bundle =  CFBundleCreate(kCFAllocatorDefault, path_url);
    require_quiet(bundle, out);
    exec = CFBundleCopyExecutableURL(bundle);
    require(exec, out);
    require(CFURLGetFileSystemRepresentation(exec, true, (uint8_t*)full_path, sizeof(full_path)), out);
out:
    CFReleaseSafe(path_cfstring);
    CFReleaseSafe(path_url);
    CFReleaseSafe(bundle);
    CFReleaseSafe(exec);

    return fopen(full_path, "r");
}
示例#8
0
CFArrayRef SecCreateSignedCertificateTimestampsArrayFromSerializedSCTList(const uint8_t *p, size_t listLen)
{
    size_t encodedListLen;
    CFMutableArrayRef sctArray = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    require_quiet(sctArray, out);

    require(listLen > 2 , out);
    encodedListLen = SSLDecodeSize(p); p+=2; listLen-=2;

    require(encodedListLen==listLen, out);

    while (listLen > 0)
    {
        size_t itemLen;
        require(listLen >= 2, out);
        itemLen = SSLDecodeSize(p); p += 2; listLen-=2;
        require(itemLen <= listLen, out);
        CFDataRef sctData = CFDataCreate(kCFAllocatorDefault, p, itemLen);
        p += itemLen; listLen -= itemLen;
        require(sctData, out);
        CFArrayAppendValue(sctArray, sctData);
        CFReleaseSafe(sctData);
    }

    return sctArray;

out:
    CFReleaseSafe(sctArray);
    return NULL;
}
static void testRSAKeyDesc()
{   
    SecKeyRef pubKey = NULL;
    CFStringRef pubRef = NULL;
    long pubLength = 0;
    	
    pubKey = SecKeyCreateRSAPublicKey(kCFAllocatorDefault, rsaPubKey, sizeof(rsaPubKey), kSecKeyEncodingBytes);
    require_quiet( pubKey, fail);
    
    pubRef = CFCopyDescription(pubKey);
    require_quiet(pubRef, fail);
    
    pubLength = CFStringGetLength(pubRef)+1;
    char *publicDescription = (char*)malloc(pubLength);
    require_quiet(publicDescription != NULL, fail);

    if(false == CFStringGetCString(pubRef, publicDescription, pubLength, kCFStringEncodingUTF8))
    {
	free(publicDescription);
	goto fail;
    }
    
    ok_status(strncmp(rsaKeyDescription, publicDescription, strlen(rsaKeyDescription)-17), "rsa key descriptions don't match: %s %s", rsaKeyDescription, publicDescription);
    free(publicDescription);

fail:
    CFReleaseSafe(pubRef);
    CFReleaseSafe(pubKey);
        
}
static void asynchttp_timer_proc(asynchttp_t *http) {
    CFStringRef req_meth = http->request ? CFHTTPMessageCopyRequestMethod(http->request) : NULL;
    CFURLRef req_url = http->request ? CFHTTPMessageCopyRequestURL(http->request) : NULL;
    secnotice("http", "Timeout during %@ %@.", req_meth, req_url);
    CFReleaseSafe(req_url);
    CFReleaseSafe(req_meth);
    asynchttp_complete(http);
}
static void test_add_managedconfiguration_item(void) {
    CFMutableDictionaryRef query = test_create_managedconfiguration_query();
    const char *v_data = "public managedconfiguration password history data";
    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
    CFDictionaryAddValue(query, kSecValueData, pwdata);
    ok_status(SecItemAdd(query, NULL), "test_add_managedconfiguration_item");
    CFReleaseSafe(pwdata);
    CFReleaseSafe(query);
}
static void test_add_lockdown_identity_items(void) {
    CFMutableDictionaryRef query = test_create_lockdown_identity_query();
    const char *v_data = "lockdown identity data (which should be a cert + key)";
    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
    CFDictionaryAddValue(query, kSecValueData, pwdata);
    ok_status(SecItemAdd(query, NULL), "test_add_lockdown_identity_items");
    CFReleaseSafe(pwdata);
    CFReleaseSafe(query);
}
示例#13
0
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;
}
示例#14
0
static CF_RETURNS_RETAINED CFDictionaryRef SecKeyGenerateAttributeDictionaryFor(SecKeyRef key,
                                                                                CFTypeRef keyType,
                                                                                CFDataRef privateBlob)
{
	CFAllocatorRef allocator = CFGetAllocator(key);
	DICT_DECLARE(25);
	CFDataRef pubKeyDigest = NULL, pubKeyBlob = NULL;
	CFDictionaryRef dict = NULL;
    
    size_t sizeValue = SecKeyGetSize(key, kSecKeyKeySizeInBits);
    CFNumberRef sizeInBits = CFNumberCreate(allocator, kCFNumberLongType, &sizeValue);
    
	/* encode the public key. */
    require_noerr(SecKeyCopyPublicBytes(key, &pubKeyBlob), errOut);
    require(pubKeyBlob, errOut);
    
	/* Calculate the digest of the public key. */
	require(pubKeyDigest = SecSHA1DigestCreate(allocator,
                                               CFDataGetBytePtr(pubKeyBlob), CFDataGetLength(pubKeyBlob)),
			errOut);
    
	DICT_ADDPAIR(kSecClass, kSecClassKey);
	DICT_ADDPAIR(kSecAttrKeyClass, privateBlob ? kSecAttrKeyClassPrivate : kSecAttrKeyClassPublic);
	DICT_ADDPAIR(kSecAttrApplicationLabel, pubKeyDigest);
	DICT_ADDPAIR(kSecAttrIsPermanent, kCFBooleanTrue);
	DICT_ADDPAIR(kSecAttrIsPrivate, kCFBooleanTrue);
	DICT_ADDPAIR(kSecAttrIsModifiable, kCFBooleanTrue);
	DICT_ADDPAIR(kSecAttrKeyType, keyType);
	DICT_ADDPAIR(kSecAttrKeySizeInBits, sizeInBits);
	DICT_ADDPAIR(kSecAttrEffectiveKeySize, sizeInBits);
	DICT_ADDPAIR(kSecAttrIsSensitive, kCFBooleanFalse);
	DICT_ADDPAIR(kSecAttrWasAlwaysSensitive, kCFBooleanFalse);
	DICT_ADDPAIR(kSecAttrIsExtractable, kCFBooleanTrue);
	DICT_ADDPAIR(kSecAttrWasNeverExtractable, kCFBooleanFalse);
	DICT_ADDPAIR(kSecAttrCanEncrypt, kCFBooleanFalse);
	DICT_ADDPAIR(kSecAttrCanDecrypt, kCFBooleanTrue);
	DICT_ADDPAIR(kSecAttrCanDerive, kCFBooleanTrue);
	DICT_ADDPAIR(kSecAttrCanSign, kCFBooleanTrue);
	DICT_ADDPAIR(kSecAttrCanVerify, kCFBooleanFalse);
	DICT_ADDPAIR(kSecAttrCanSignRecover, kCFBooleanFalse);
	DICT_ADDPAIR(kSecAttrCanVerifyRecover, kCFBooleanFalse);
	DICT_ADDPAIR(kSecAttrCanWrap, kCFBooleanFalse);
	DICT_ADDPAIR(kSecAttrCanUnwrap, kCFBooleanTrue);
	DICT_ADDPAIR(kSecValueData, privateBlob ? privateBlob : pubKeyBlob);
    dict = DICT_CREATE(allocator);
    
errOut:
	// @@@ Zero out key material.
	CFReleaseSafe(pubKeyDigest);
	CFReleaseSafe(pubKeyBlob);
	CFReleaseSafe(sizeInBits);
    
	return dict;
}
SOSCoderRef SOSCoderCreateFromData(CFDataRef exportedData, CFErrorRef *error) {
    
    SOSCoderRef p = calloc(1, sizeof(struct __OpaqueSOSCoder));
    
    const uint8_t *der = CFDataGetBytePtr(exportedData);
    const uint8_t *der_end = der + CFDataGetLength(exportedData);
    
    CFDataRef otr_data = NULL;

    ccder_tag tag;
    require(ccder_decode_tag(&tag, der, der_end),fail);

    switch (tag) {
        case CCDER_OCTET_STRING: // TODO: this code is safe to delete?
        {
            der = der_decode_data(kCFAllocatorDefault, 0, &otr_data, error, der, der_end);
            p->waitingForDataPacket = false;
        }
        break;
        
        case CCDER_CONSTRUCTED_SEQUENCE:
        {
            const uint8_t *sequence_end = NULL;
            der = ccder_decode_sequence_tl(&sequence_end, der, der_end);
            
            require_action_quiet(sequence_end == der_end, fail, SecCFDERCreateError(kSOSErrorDecodeFailure, CFSTR("Extra data in SOS coder"), NULL, error));
            
            der = der_decode_data(kCFAllocatorDefault, 0, &otr_data, error, der, sequence_end);
            der = der_decode_bool(&p->waitingForDataPacket, der, sequence_end);
            if (der != sequence_end) { // optionally a pending response
                der = der_decode_data(kCFAllocatorDefault, 0, &p->pendingResponse, error, der, sequence_end);
            }
        }
        break;
        
        default:
            SecCFDERCreateError(kSOSErrorDecodeFailure, CFSTR("Unsupported SOS Coder DER"), NULL, error);
            goto fail;
    }

    require(der, fail);
    
    p->sessRef = SecOTRSessionCreateFromData(NULL, otr_data);
    require(p->sessRef, fail);

    CFReleaseSafe(otr_data);
    return p;
        
fail:
    SOSCoderDispose(p);
    CFReleaseSafe(otr_data);
    return NULL;
}
示例#16
0
bool SOSTransportMessageSendMessageIfNeeded(SOSTransportMessageRef transport, CFStringRef circle_id, CFStringRef peer_id, CFErrorRef *error) {
    
    SOSEnginePeerMessageSentBlock sent = NULL;
    CFDataRef message_to_send = NULL;
    bool ok = false;
    SOSPeerRef peer = SOSPeerCreateWithEngine(SOSTransportMessageGetEngine(transport), peer_id);
    CFDataRef coderData = SOSEngineGetCoderData(SOSTransportMessageGetEngine(transport), peer_id);
    require(coderData, fail);
    
    SOSCoderRef coder = SOSCoderCreateFromData(coderData, error);
    require(coder, fail);
    SOSPeerSetCoder(peer, coder);
    
    ok = SOSPeerCoderSendMessageIfNeeded(peer, &message_to_send, circle_id, peer_id, &sent, error);
    coder = SOSPeerGetCoder(peer);
    
    if (message_to_send)    {
        CFDictionaryRef peer_dict = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
                                                                 peer_id, message_to_send,
                                                                 NULL);
        CFDictionaryRef circle_peers = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
                                                                    circle_id, peer_dict,
                                                                    NULL);
        
        ok = ok && SOSTransportMessageSendMessages(transport, circle_peers, error);
        
        SOSPeerCoderConsume(&sent, ok);
        
        CFReleaseSafe(peer_dict);
        CFReleaseSafe(circle_peers);
    }
    
    
    Block_release(sent);
    
    
    CFReleaseSafe(message_to_send);
    
    coderData = SOSCoderCopyDER(coder, error);
    
    if(!SOSEngineSetCoderData(SOSTransportMessageGetEngine(transport), peer_id, coderData, error)){
        secerror("SOSTransportMessageSendMessageIfNeeded, Could not save peer state");
    }
    CFReleaseNull(coderData);
    
    if (coder)
        SOSCoderDispose(coder);
    
fail:
    CFReleaseNull(peer);
    return ok;
}
示例#17
0
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);
}
示例#18
0
static
int mySSLPrivKeyRSA_sign(void *key, tls_hash_algorithm hash, const uint8_t *plaintext, size_t plaintextLen, uint8_t *sig, size_t *sigLen)
{
    SecKeyRef keyRef = key;
    SecKeyAlgorithm algo;
    switch (hash) {
        case tls_hash_algorithm_None:
            return SecKeyRawSign(keyRef, kSecPaddingPKCS1, plaintext, plaintextLen, sig, sigLen);
        case tls_hash_algorithm_SHA1:
            algo = kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1;
            break;
        case tls_hash_algorithm_SHA256:
            algo = kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA256;
            break;
        case tls_hash_algorithm_SHA384:
            algo = kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA384;
            break;
        case tls_hash_algorithm_SHA512:
            algo = kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512;
            break;
        default:
            /* Unsupported hash - Internal error */
            return errSSLInternal;
    }

    int err = errSSLInternal;
    CFDataRef signature = NULL;
    CFDataRef data = NULL;

    data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, plaintext, plaintextLen, kCFAllocatorNull);
    require(data, errOut);
    signature = SecKeyCreateSignature(keyRef, algo, data , NULL);
    require(signature, errOut);

    CFIndex len = CFDataGetLength(signature);
    const uint8_t *p = CFDataGetBytePtr(signature);

    require(p, errOut);
    require(len>=*sigLen, errOut);

    memcpy(sig, p, len);
    *sigLen = len;
    err = noErr;

errOut:
    CFReleaseSafe(data);
    CFReleaseSafe(signature);
    return err;
}
示例#19
0
//
// Returns a malloced array of CSSM_RETURN values, with the length in numStatusCodes,
// for the certificate specified by chain index in the given SecTrustRef.
//
// To match legacy behavior, the array actually allocates one element more than the
// value of numStatusCodes; if the certificate is revoked, the additional element
// at the end contains the CrlReason value.
//
// Caller must free the returned pointer.
//
static CSSM_RETURN *copyCssmStatusCodes(SecTrustRef trust,
	unsigned int index, unsigned int *numStatusCodes)
{
	if (!trust || !numStatusCodes) {
		return NULL;
	}
	*numStatusCodes = 0;
	CFArrayRef details = SecTrustCopyFilteredDetails(trust);
	CFIndex chainLength = (details) ? CFArrayGetCount(details) : 0;
	if (!(index < chainLength)) {
		CFReleaseSafe(details);
		return NULL;
	}
	CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, index);
	CFIndex ix, detailCount = CFDictionaryGetCount(detail);
	*numStatusCodes = (unsigned int)detailCount;

	// Allocate one more entry than we need; this is used to store a CrlReason
	// at the end of the array.
	CSSM_RETURN *statusCodes = (CSSM_RETURN*)malloc((detailCount+1) * sizeof(CSSM_RETURN));
	statusCodes[*numStatusCodes] = 0;

	const unsigned int resultmaplen = sizeof(cssmresultmap) / sizeof(resultmap_entry_t);
	const void *keys[detailCount];
	CFDictionaryGetKeysAndValues(detail, &keys[0], NULL);
	for (ix = 0; ix < detailCount; ix++) {
		CFStringRef key = (CFStringRef)keys[ix];
		CSSM_RETURN statusCode = CSSM_OK;
		for (unsigned int mapix = 0; mapix < resultmaplen; mapix++) {
			CFStringRef str = (CFStringRef) cssmresultmap[mapix].checkstr;
			if (CFStringCompare(str, key, 0) == kCFCompareEqualTo) {
				statusCode = (CSSM_RETURN) cssmresultmap[mapix].resultcode;
				break;
			}
		}
		if (statusCode == CSSMERR_TP_CERT_REVOKED) {
			SInt32 reason;
			CFNumberRef number = (CFNumberRef)CFDictionaryGetValue(detail, key);
			if (number && CFNumberGetValue(number, kCFNumberSInt32Type, &reason)) {
				statusCodes[*numStatusCodes] = (CSSM_RETURN)reason;
			}
		}
		statusCodes[ix] = statusCode;
	}

	CFReleaseSafe(details);
	return statusCodes;
}
bool SOSAccountPublishCloudParameters(SOSAccountRef account, CFErrorRef* error){
    bool success = false;
    CFIndex cloud_der_len = der_sizeof_cloud_parameters(
                                                        account->user_public,
                                                        account->user_key_parameters,
                                                        error);
    CFMutableDataRef cloudParameters =
    CFDataCreateMutableWithScratch(kCFAllocatorDefault, cloud_der_len);
    
    if (der_encode_cloud_parameters(account->user_public, account->user_key_parameters, error,
                                    CFDataGetMutableBytePtr(cloudParameters),
                                    CFDataGetMutablePastEndPtr(cloudParameters)) != NULL) {

        CFErrorRef changeError = NULL;
        if (SOSTrasnportKeyParameterPublishCloudParameters(account->key_transport, cloudParameters, error)) {
            success = true;
        } else {
            SOSCreateErrorWithFormat(kSOSErrorSendFailure, changeError, error, NULL,
                                     CFSTR("update parameters key failed [%@]"), cloudParameters);
        }
        CFReleaseSafe(changeError);
    } else {
        SOSCreateError(kSOSErrorEncodeFailure, CFSTR("Encoding parameters failed"), NULL, error);
    }
    
    CFReleaseNull(cloudParameters);
    
    return success;
}
示例#21
0
OSStatus SecTrustStoreSetTrustSettings(SecTrustStoreRef ts,
	SecCertificateRef certificate,
    CFTypeRef trustSettingsDictOrArray) {
    CFDataRef certificateData = NULL;
    OSStatus status = errSecParam;

    if (gSecurityd) {
        status = gSecurityd->sec_trust_store_set_trust_settings(ts, certificate, trustSettingsDictOrArray);
    } else {
        require(ts == (SecTrustStoreRef)kSecTrustStoreUserName, errOut);
        require(certificateData = SecCertificateCopyData(certificate), errOut);
        const void *values[] = {
            (const void *)certificateData,
            (const void *)trustSettingsDictOrArray
        };
        CFArrayRef in = CFArrayCreate(kCFAllocatorDefault, values,
            (trustSettingsDictOrArray ? 2 : 1), &kCFTypeArrayCallBacks);
        if (in) {
            status = ServerCommandSendReceive(sec_trust_store_set_trust_settings_id, in, NULL);
            CFRelease(in);
        } else {
            status = errSecAllocate;
        }
    }

errOut:
    CFReleaseSafe(certificateData);
	return status;
}
示例#22
0
/********************************************************
 *********** SecItemCertificateSource object ************
 ********************************************************/
static bool SecItemCertificateSourceCopyParents(
	SecCertificateSourceRef source, SecCertificateRef certificate,
        void *context, SecCertificateSourceParents callback) {
    /* FIXME: Search for things other than just subject of our issuer if we
       have a subjectID or authorityKeyIdentifier. */
    CFDataRef normalizedIssuer =
        SecCertificateGetNormalizedIssuerContent(certificate);
    const void *keys[] = {
        kSecClass,
        kSecReturnRef,
        kSecMatchLimit,
        kSecAttrSubject
    },
    *values[] = {
        kSecClassCertificate,
        kCFBooleanTrue,
        kSecMatchLimitAll,
        normalizedIssuer
    };
    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, 4,
		NULL, NULL);
    CFTypeRef results = NULL;
    /* We can make this async or run this on a queue now easily. */
    OSStatus status = SecItemCopyMatching(query, &results);
    CFRelease(query);
    if (status) {
		secdebug("trust", "SecItemCopyMatching status: %lu", status);
    }
    callback(context, results);
    CFReleaseSafe(results);
    return true;
}
示例#23
0
OSStatus
sslCreateSecTrust(
	SSLContext				*ctx,
    SecTrustRef             *pTrust)	/* RETURNED */
{
	OSStatus status = errSecAllocate;
	SecTrustRef trust = NULL;

    require_noerr(status = tls_helper_create_peer_trust(ctx->hdsk, ctx->protocolSide==kSSLServerSide, &trust), errOut);

	/* If we have trustedAnchors we set them here. */
    if (trust && ctx->trustedCerts) {
        require_noerr(status = SecTrustSetAnchorCertificates(trust, ctx->trustedCerts), errOut);
        require_noerr(status = SecTrustSetAnchorCertificatesOnly(trust, ctx->trustedCertsOnly), errOut);
    }

    status = errSecSuccess;

errOut:
    if(status != noErr) {
        CFReleaseSafe(trust);
        *pTrust = NULL;
    } else {
        *pTrust = trust;
    }

	return status;
}
CFErrorRef SecCreateCFErrorWithXPCObject(xpc_object_t xpc_error)
{
    CFErrorRef result = NULL;

    if (xpc_get_type(xpc_error) == XPC_TYPE_DICTIONARY) {
        CFStringRef domain = NULL;

        const char * domain_string = xpc_dictionary_get_string(xpc_error, kDomainKey);
        if (domain_string != NULL) {
            domain = CFStringCreateWithCString(kCFAllocatorDefault, domain_string, kCFStringEncodingUTF8);
        } else {
            domain = sSecXPCErrorDomain;
            CFRetain(domain);
        }
        CFIndex code = (CFIndex) xpc_dictionary_get_int64(xpc_error, kCodeKey);

        const char *description = xpc_dictionary_get_string(xpc_error, kDescriptionKey);

        SecCFCreateErrorWithFormat(code, domain, NULL, &result, NULL, CFSTR("Remote error : %s"), description);

        CFReleaseSafe(domain);
    } else {
        SecCFCreateErrorWithFormat(kSecXPCErrorUnexpectedType, sSecXPCErrorDomain, NULL, &result, NULL, CFSTR("Remote error not dictionary!: %@"), xpc_error);
    }
    return result;
}
// Start OTR negotiation if we haven't already done so.
SOSCoderStatus
SOSCoderStart(SOSCoderRef coder, CFErrorRef *error) {
    CFMutableStringRef action = CFStringCreateMutable(kCFAllocatorDefault, 0);
    CFStringRef beginState = NULL;
    SOSCoderStatus result = kSOSCoderFailure;
    CFMutableDataRef startPacket = NULL;

    require_action_quiet(coder->sessRef, coderFailure, CFStringAppend(action, CFSTR("*** no otr session ***")));
    beginState = CFCopyDescription(coder->sessRef);
    require_action_quiet(!coder->waitingForDataPacket, negotiatingOut, CFStringAppend(action, CFSTR("waiting for peer to send first data packet")));
    require_action_quiet(!SecOTRSGetIsReadyForMessages(coder->sessRef), coderFailure, CFStringAppend(action, CFSTR("otr session ready"));
                         result = kSOSCoderDataReturned);
    require_action_quiet(SecOTRSGetIsIdle(coder->sessRef), negotiatingOut, CFStringAppend(action, CFSTR("otr negotiating already")));
    require_action_quiet(startPacket = CFDataCreateMutable(kCFAllocatorDefault, 0), coderFailure, SOSCreateError(kSOSErrorAllocationFailure, CFSTR("alloc failed"), NULL, error));
    require_quiet(SOSOTRSAppendStartPacket(coder->sessRef, startPacket, error), coderFailure);
    CFRetainAssign(coder->pendingResponse, startPacket);

negotiatingOut:
    result = kSOSCoderNegotiating;
coderFailure:
    // Uber state log
    if (result == kSOSCoderFailure && error && *error)
        CFStringAppendFormat(action, NULL, CFSTR(" %@"), *error);
    secnotice("coder", "%@ %s %@ %@ returned %s", beginState,
              SecOTRPacketTypeString(startPacket), action, coder->sessRef, SOSCoderString(result));
    CFReleaseNull(startPacket);
    CFReleaseSafe(beginState);
    CFRelease(action);

    return result;

}
示例#26
0
bool SecCAIssuerCopyParents(SecCertificateRef certificate, dispatch_queue_t queue,
    void *context, void (*callback)(void *, CFArrayRef)) {
    CFArrayRef issuers = SecCertificateGetCAIssuers(certificate);
    if (!issuers) {
        /* certificate has no caissuer urls, we're done. */
        callback(context, NULL);
        return true;
    }

    CFArrayRef parents = SecCAIssuerRequestCacheCopyParents(certificate, issuers);
    if (parents) {
        callback(context, parents);
        CFReleaseSafe(parents);
        return true;
    }

    /* Cache miss, let's issue a network request. */
    SecCAIssuerRequestRef request =
        (SecCAIssuerRequestRef)calloc(1, sizeof(*request));
    request->http.queue = queue;
    request->http.completed = SecCAIssuerRequestCompleted;
    CFRetain(certificate);
    request->certificate = certificate;
    request->issuers = issuers;
    request->issuerIX = 0;
    request->context = context;
    request->callback = callback;

    return SecCAIssuerRequestIssue(request);
}
/* Create a URI suitable for use in an http GET request, will return NULL if
   the length would exceed 255 bytes. */
static CFURLRef createGetURL(CFURLRef responder, CFDataRef request) {
    CFURLRef getURL = NULL;
    CFMutableDataRef base64Request = NULL;
    CFStringRef base64RequestString = NULL;
    CFStringRef peRequest = NULL;
    CFIndex base64Len;

    base64Len = SecBase64Encode(NULL, CFDataGetLength(request), NULL, 0);
    /* Don't bother doing all the work below if we know the end result will
       exceed 255 bytes (minus one for the '/' separator makes 254). */
    if (base64Len + CFURLGetBytes(responder, NULL, 0) > 254)
        return NULL;

    require(base64Request = CFDataCreateMutable(kCFAllocatorDefault,
        base64Len), errOut);
    CFDataSetLength(base64Request, base64Len);
    SecBase64Encode(CFDataGetBytePtr(request), CFDataGetLength(request),
        (char *)CFDataGetMutableBytePtr(base64Request), base64Len);
    require(base64RequestString = CFStringCreateWithBytes(kCFAllocatorDefault,
        CFDataGetBytePtr(base64Request), base64Len, kCFStringEncodingUTF8,
        false), errOut);
    require(peRequest = CFURLCreateStringByAddingPercentEscapes(
        kCFAllocatorDefault, base64RequestString, NULL, CFSTR("+/="),
        kCFStringEncodingUTF8), errOut);
#if 1
    CFStringRef urlString = CFURLGetString(responder);
    CFStringRef fullURL;
    if (CFStringHasSuffix(urlString, CFSTR("/"))) {
        fullURL = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
            CFSTR("%@%@"), urlString, peRequest);
    } else {
        fullURL = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
            CFSTR("%@/%@"), urlString, peRequest);
    }
    getURL = CFURLCreateWithString(kCFAllocatorDefault, fullURL, NULL);
    CFRelease(fullURL);
#else
    getURL = CFURLCreateWithString(kCFAllocatorDefault, peRequest, responder);
#endif

errOut:
    CFReleaseSafe(base64Request);
    CFReleaseSafe(base64RequestString);
    CFReleaseSafe(peRequest);

    return getURL;
}
示例#28
0
static OSStatus
DER_UTCTimeToCFDate(const SecAsn1Item * utcTime, CFAbsoluteTime *date)
{
    char *string = (char *)utcTime->Data;
    int year, month, mday, hour, minute, second, hourOff, minOff;

    /* Verify time is formatted properly and capture information */
    second = 0;
    hourOff = 0;
    minOff = 0;
    CAPTURE(year,string+0,loser);
    if (year < 50) {
        /* ASSUME that year # is in the 2000's, not the 1900's */
        year += 2000;
    } else {
        year += 1900;
    }
    CAPTURE(month,string+2,loser);
    if ((month == 0) || (month > 12)) goto loser;
    CAPTURE(mday,string+4,loser);
    if ((mday == 0) || (mday > 31)) goto loser;
    CAPTURE(hour,string+6,loser);
    if (hour > 23) goto loser;
    CAPTURE(minute,string+8,loser);
    if (minute > 59) goto loser;
    if (ISDIGIT(string[10])) {
        CAPTURE(second,string+10,loser);
        if (second > 59) goto loser;
        string += 2;
    }
    if (string[10] == '+') {
        CAPTURE(hourOff,string+11,loser);
        if (hourOff > 23) goto loser;
        CAPTURE(minOff,string+13,loser);
        if (minOff > 59) goto loser;
    } else if (string[10] == '-') {
        CAPTURE(hourOff,string+11,loser);
        if (hourOff > 23) goto loser;
        hourOff = -hourOff;
        CAPTURE(minOff,string+13,loser);
        if (minOff > 59) goto loser;
        minOff = -minOff;
    } else if (string[10] != 'Z') {
        goto loser;
    }

    if (hourOff == 0 && minOff == 0) {
        *date = CFAbsoluteTimeForGregorianZuluMoment(year, month, mday, hour, minute, second);
    } else {
        CFTimeZoneRef tz = CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, (hourOff * 60 + minOff) * 60);
        *date = CFAbsoluteTimeForGregorianMoment(tz, year, month, mday, hour, minute, second);
        CFReleaseSafe(tz);
    }

    return SECSuccess;

loser:
    return SECFailure;
}
示例#29
0
static void SOSTransportMessageDestroy(CFTypeRef aObj){
    SOSTransportMessageRef transport = (SOSTransportMessageRef) aObj;
    
    if (transport->destroy)
        transport->destroy(transport);
    
    CFReleaseSafe(transport->account);
}
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);
}