Esempio n. 1
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;
}
Esempio n. 2
0
QSslCertificate AccessCert::cert()
{
#ifdef Q_OS_MAC
	SecIdentityRef identity = 0;
	OSStatus err = SecIdentityCopyPreference( CFSTR("ocsp.sk.ee"), 0, 0, &identity );
	if( !identity )
		return QSslCertificate();

	SecCertificateRef certref = 0;
	err = SecIdentityCopyCertificate( identity, &certref );
	CFRelease( identity );
	if( !certref )
		return QSslCertificate();

	CFDataRef certdata = SecCertificateCopyData( certref );
	CFRelease( certref );
	if( !certdata )
		return QSslCertificate();

	QSslCertificate cert(
		QByteArray( (const char*)CFDataGetBytePtr( certdata ), CFDataGetLength( certdata ) ), QSsl::Der );
	CFRelease( certdata );
	return cert;
#else
	return PKCS12Certificate::fromPath(
		Application::confValue( Application::PKCS12Cert ).toString(),
		Application::confValue( Application::PKCS12Pass ).toString() ).certificate();
#endif
}
static carray * mailstream_low_cfstream_get_certificate_chain(mailstream_low * s)
{
#if HAVE_CFNETWORK
  struct mailstream_cfstream_data * cfstream_data;
  unsigned int i;
  carray * result;
  
  cfstream_data = (struct mailstream_cfstream_data *) s->data;
  SecTrustRef secTrust = (SecTrustRef)CFReadStreamCopyProperty(cfstream_data->readStream, kCFStreamPropertySSLPeerTrust);
  if (secTrust == NULL)
    return NULL;
  
  CFIndex count = SecTrustGetCertificateCount(secTrust);
  
  result = carray_new(4);
  for(i = 0 ; i < count ; i ++) {
    SecCertificateRef cert = (SecCertificateRef) SecTrustGetCertificateAtIndex(secTrust, i);
    CFDataRef data = SecCertificateCopyData(cert);
    CFIndex length = CFDataGetLength(data);
    const UInt8 * bytes = CFDataGetBytePtr(data);
    MMAPString * str = mmap_string_sized_new(length);
    mmap_string_append_len(str, (char*) bytes, length);
    carray_add(result, str, NULL);
    CFRelease(data);
  }
  
  CFRelease(secTrust);
  
  return result;
#else
  return NULL;
#endif
}
Esempio n. 4
0
static int stransport_certificate(git_cert **out, git_stream *stream)
{
	stransport_stream *st = (stransport_stream *) stream;
	SecTrustRef trust = NULL;
	SecCertificateRef sec_cert;
	OSStatus ret;

	if ((ret = SSLCopyPeerTrust(st->ctx, &trust)) != noErr)
		return stransport_error(ret);

	sec_cert = SecTrustGetCertificateAtIndex(trust, 0);
	st->der_data = SecCertificateCopyData(sec_cert);
	CFRelease(trust);

	if (st->der_data == NULL) {
		giterr_set(GITERR_SSL, "retrieved invalid certificate data");
		return -1;
	}

	st->cert_info.parent.cert_type = GIT_CERT_X509;
	st->cert_info.data = (void *) CFDataGetBytePtr(st->der_data);
	st->cert_info.len = CFDataGetLength(st->der_data);

	*out = (git_cert *)&st->cert_info;
	return 0;
}
Esempio n. 5
0
static CFDictionaryRef
SecItemCopyAttributeDictionary(CFTypeRef ref) {
	CFDictionaryRef refDictionary = NULL;
	CFTypeID typeID = CFGetTypeID(ref);
	if (typeID == SecKeyGetTypeID()) {
		refDictionary = SecKeyCopyAttributeDictionary((SecKeyRef)ref);
	} else if (typeID == SecCertificateGetTypeID()) {
		refDictionary =
			SecCertificateCopyAttributeDictionary((SecCertificateRef)ref);
	} else if (typeID == SecIdentityGetTypeID()) {
        assert(false);
        SecIdentityRef identity = (SecIdentityRef)ref;
        SecCertificateRef cert = NULL;
        SecKeyRef key = NULL;
        if (!SecIdentityCopyCertificate(identity, &cert) &&
            !SecIdentityCopyPrivateKey(identity, &key)) 
        {
            CFDataRef data = SecCertificateCopyData(cert);
            CFDictionaryRef key_dict = SecKeyCopyAttributeDictionary(key);
            
            if (key_dict && data) {
                refDictionary = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, key_dict);
                CFDictionarySetValue((CFMutableDictionaryRef)refDictionary, 
                    CFSTR(CERTIFICATE_DATA_COLUMN_LABEL), data);
            }
            CFReleaseNull(key_dict);
            CFReleaseNull(data);
        }
        CFReleaseNull(cert);
        CFReleaseNull(key);
    } else {
		refDictionary = NULL;
	}
	return refDictionary;
}
Esempio n. 6
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;
}
Esempio n. 7
0
CertDataRef createCertDataFromCertificate(SecCertificateRef certificate)
{
  CertDataRef pCertData = (CertDataRef)malloc(sizeof(CertData));
  pCertData->subject = GetFieldsFromCertificate(certificate, kSecOIDX509V1SubjectName);
  pCertData->issuer = GetFieldsFromCertificate(certificate, kSecOIDX509V1IssuerName);

  CFDataRef data = SecCertificateCopyData(certificate);
  if (data == NULL)
    {
      warnx("SecCertificateCopyData() returned NULL");
      destroyCertData(pCertData);
      return NULL;
    }

  unsigned char sha1[CC_SHA1_DIGEST_LENGTH];
  CC_SHA1(CFDataGetBytePtr(data), CFDataGetLength(data), sha1);
  pCertData->sha1 = createHexString(sha1, CC_SHA1_DIGEST_LENGTH);

  unsigned char md5[CC_MD5_DIGEST_LENGTH];
  CC_MD5(CFDataGetBytePtr(data), CFDataGetLength(data), md5);
  pCertData->md5 = createHexString((unsigned char*)md5, CC_MD5_DIGEST_LENGTH);

  CFDataRef serial = SecCertificateCopySerialNumber(certificate, NULL);
  pCertData->serial = createHexString((unsigned char *)CFDataGetBytePtr(serial), CFDataGetLength(serial));
  CFRelease(serial);

  return pCertData;
}
Esempio n. 8
0
std::string genSHA1ForCertificate(const SecCertificateRef& ca) {
  CFDataRef ca_data;

  // Access raw data, hash and release.
  ca_data = SecCertificateCopyData(ca);
  auto digest = hashFromBuffer(
      HASH_TYPE_SHA1, CFDataGetBytePtr(ca_data), CFDataGetLength(ca_data));
  CFRelease(ca_data);
  return digest;
}
int SecFDERecoveryWrapCRSKWithPubKey(const uint8_t *crsk, size_t crskLen, 
	SecCertificateRef certificateRef, FVPrivateKeyHeader *outHeader)
{
	BEGIN_SECAPI

	CssmData inBlob((unsigned char *)crsk, (size_t)crskLen);
	Required(certificateRef);
	CFRef<CFDataRef> certificateData(SecCertificateCopyData(certificateRef));
	encodePrivateKeyHeader(inBlob, certificateData, Required(outHeader));

	END_SECAPI
}
Esempio n. 10
0
  virtual void SetUp() {
    std::string raw;
    CFDataRef data;

    raw = base64Decode(getCACertificateContent());
    data =
        CFDataCreate(nullptr, (const UInt8 *)raw.c_str(), (CFIndex)raw.size());
    cert = SecCertificateCreateWithData(nullptr, data);
    cert_der_data = SecCertificateCopyData(cert);
    auto bytes = CFDataGetBytePtr(cert_der_data);
    x_cert = d2i_X509(nullptr, &bytes, CFDataGetLength(cert_der_data));

    CFRelease(data);
  }
static void encodeCertificateChain(Encoder& encoder, CFArrayRef certificateChain)
{
    CFIndex size = CFArrayGetCount(certificateChain);
    Vector<CFTypeRef, 32> values(size);

    CFArrayGetValues(certificateChain, CFRangeMake(0, size), values.data());

    encoder << static_cast<uint64_t>(size);

    for (CFIndex i = 0; i < size; ++i) {
        ASSERT(values[i]);
        ASSERT(CFGetTypeID(values[i]) == SecCertificateGetTypeID());

        auto data = adoptCF(SecCertificateCopyData((SecCertificateRef)values[i]));
        encodeCFData(encoder, data.get());
    }
}
Esempio n. 12
0
static value cert_load_defaults(){
#if defined(NEKO_WINDOWS)
	value v;
	HCERTSTORE store;
	PCCERT_CONTEXT cert;
	mbedtls_x509_crt *chain = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt));
	mbedtls_x509_crt_init( chain );
	if( store = CertOpenSystemStore(0, (LPCSTR)"Root") ){
		cert = NULL;
		while( cert = CertEnumCertificatesInStore(store, cert) )
			mbedtls_x509_crt_parse_der( chain, (unsigned char *)cert->pbCertEncoded, cert->cbCertEncoded );
		CertCloseStore(store, 0);
	}
	v = alloc_abstract(k_cert, chain);
	val_gc(v,free_cert);
	return v;
#elif defined(NEKO_MAC)
	CFMutableDictionaryRef search;
	CFArrayRef result;
	SecKeychainRef keychain;
	SecCertificateRef item;
	CFDataRef dat;
	value v;
	mbedtls_x509_crt *chain = NULL;

	// Load keychain
	if( SecKeychainOpen("/System/Library/Keychains/SystemRootCertificates.keychain",&keychain) != errSecSuccess )
		return val_null;

	// Search for certificates
	search = CFDictionaryCreateMutable( NULL, 0, NULL, NULL );
	CFDictionarySetValue( search, kSecClass, kSecClassCertificate );
	CFDictionarySetValue( search, kSecMatchLimit, kSecMatchLimitAll );
	CFDictionarySetValue( search, kSecReturnRef, kCFBooleanTrue );
	CFDictionarySetValue( search, kSecMatchSearchList, CFArrayCreate(NULL, (const void **)&keychain, 1, NULL) );
	if( SecItemCopyMatching( search, (CFTypeRef *)&result ) == errSecSuccess ){
		CFIndex n = CFArrayGetCount( result );
		for( CFIndex i = 0; i < n; i++ ){
			item = (SecCertificateRef)CFArrayGetValueAtIndex( result, i );

			// Get certificate in DER format
			dat = SecCertificateCopyData( item );
			if( dat ){
				if( chain == NULL ){
					chain = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt));
					mbedtls_x509_crt_init( chain );
				}
				mbedtls_x509_crt_parse_der( chain, (unsigned char *)CFDataGetBytePtr(dat), CFDataGetLength(dat) );
				CFRelease( dat );
			}
		}
	}
	CFRelease(keychain);
	if( chain != NULL ){
		v = alloc_abstract(k_cert, chain);
		val_gc(v,free_cert);
		return v;
	}else{
		return val_null;
	}
#else
	return val_null;
#endif
}
void encode(ArgumentEncoder* encoder, SecCertificateRef certificate)
{
    RetainPtr<CFDataRef> data(AdoptCF, SecCertificateCopyData(certificate));
    encode(encoder, data.get());
}
Esempio n. 14
0
static void tests(void)
{
    SecKeyRef phone_publicKey = NULL, phone_privateKey = NULL;
    SecKeyRef ca_publicKey = NULL, ca_privateKey = NULL;

    int keysize = 2048;
    CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize);
    const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
    const void *keygen_vals[] = { kSecAttrKeyTypeRSA, key_size_num };
    CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault,
        keygen_keys, keygen_vals, array_size(keygen_vals),
        &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
    CFReleaseNull(key_size_num);

    CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFDictionarySetValue(subject_alt_names, CFSTR("dnsname"), CFSTR("xey.nl"));

    int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment;
    CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage);

    CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions };
    const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions };
    CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault,
        key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} };
    SecATV c[]  = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} };
    SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} };
    SecATV l[]  = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} };
    SecATV o[]  = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} };
    SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} };

    SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL };

    ok_status(SecKeyGeneratePair(parameters, &phone_publicKey, &phone_privateKey), "generate key pair");
    ok_status(SecKeyGeneratePair(parameters, &ca_publicKey, &ca_privateKey), "generate key pair");

    int self_key_usage = kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign;
    CFNumberRef self_key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &self_key_usage);
    int path_len = 0;
    CFNumberRef path_len_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &path_len);
    const void *self_key[] = { kSecCertificateKeyUsage, kSecCSRBasicContraintsPathLen };
    const void *self_val[] = { self_key_usage_num, path_len_num };
    CFDictionaryRef self_signed_parameters = CFDictionaryCreate(kCFAllocatorDefault,
        self_key, self_val, array_size(self_key), NULL, NULL);

    const void * ca_o[] = { kSecOidOrganization, CFSTR("Apple Inc.") };
    const void * ca_cn[] = { kSecOidCommonName, CFSTR("Root CA") };
    CFArrayRef ca_o_dn = CFArrayCreate(kCFAllocatorDefault, ca_o, 2, NULL);
    CFArrayRef ca_cn_dn = CFArrayCreate(kCFAllocatorDefault, ca_cn, 2, NULL);
    const void *ca_dn_array[2];
    ca_dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_o_dn, 1, NULL);
    ca_dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_cn_dn, 1, NULL);
    CFArrayRef ca_rdns = CFArrayCreate(kCFAllocatorDefault, ca_dn_array, 2, NULL);

    SecCertificateRef ca_cert = SecGenerateSelfSignedCertificate(ca_rdns,
        self_signed_parameters, ca_publicKey, ca_privateKey);
	SecCertificateRef ca_cert_phone_key =
		SecGenerateSelfSignedCertificate(ca_rdns, self_signed_parameters, phone_publicKey, phone_privateKey);

	CFReleaseSafe(self_signed_parameters);
    CFReleaseSafe(self_key_usage_num);
    CFReleaseSafe(path_len_num);
    CFReleaseNull(ca_o_dn);
    CFReleaseNull(ca_cn_dn);
    CFReleaseNull(ca_dn_array[0]);
    CFReleaseNull(ca_dn_array[1]);
    CFReleaseNull(ca_rdns);

    isnt(ca_cert, NULL, "got back a cert");
    ok(SecCertificateIsSelfSignedCA(ca_cert), "cert is self-signed ca cert");
    isnt(ca_cert_phone_key, NULL, "got back a cert");
    ok(SecCertificateIsSelfSignedCA(ca_cert_phone_key), "cert is self-signed ca cert");
    CFDataRef data = SecCertificateCopyData(ca_cert);
    //write_data("/tmp/ca_cert.der", data);
    CFReleaseSafe(data);

    SecIdentityRef ca_identity = SecIdentityCreate(kCFAllocatorDefault, ca_cert, ca_privateKey);
	SecIdentityRef ca_identity_phone_key = SecIdentityCreate(kCFAllocatorDefault, ca_cert_phone_key, phone_privateKey);
    isnt(ca_identity, NULL, "got a identity");
    isnt(ca_identity_phone_key, NULL, "got a identity");
    CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL);
    ok_status(SecItemAdd(dict, NULL), "add ca identity");
    CFReleaseSafe(dict);
#if TARGET_OS_IPHONE
    TODO: {
        todo("Adding a cert with the same issuer/serial but a different key should return something other than errSecDuplicateItem");
#else
    {
#endif
        dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity_phone_key, 1, NULL, NULL);
        is_status(errSecDuplicateItem, SecItemAdd(dict, NULL), "add ca identity");
        CFReleaseSafe(dict);
    }

    CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, NULL, phone_publicKey, phone_privateKey);
    isnt(csr, NULL, "got back a csr");
    CFReleaseNull(csr);

	//dict[kSecSubjectAltName, dict[ntPrincipalName, "*****@*****.**"]]
	CFStringRef nt_princ_name_val = CFSTR("*****@*****.**");
	CFStringRef nt_princ_name_key = CFSTR("ntPrincipalName");
	CFDictionaryRef nt_princ = CFDictionaryCreate(NULL, (const void **)&nt_princ_name_key, (const void **)&nt_princ_name_val, 1, NULL, NULL);
	CFDictionaryRef params = CFDictionaryCreate(NULL, (const void **)&kSecSubjectAltName, (const void **)&nt_princ, 1, NULL, NULL);

    csr = SecGenerateCertificateRequestWithParameters(atvs_phone, params, phone_publicKey, phone_privateKey);
    isnt(csr, NULL, "got back a csr");
	//write_data("/var/tmp/csr-nt-princ", csr);
    CFReleaseNull(csr);
	CFReleaseNull(params);
	CFReleaseNull(nt_princ);

    csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, phone_publicKey, phone_privateKey);
    isnt(csr, NULL, "csr w/ params");
    //write_data("/tmp/csr", csr);
    CFDataRef subject, extensions;
    CFStringRef challenge;
    ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr");
    CFReleaseNull(csr);

    uint8_t serialno_byte = 42;
    CFDataRef serialno = CFDataCreate(kCFAllocatorDefault, &serialno_byte, sizeof(serialno_byte));
    SecCertificateRef cert = SecIdentitySignCertificate(ca_identity, serialno,
        phone_publicKey, subject, extensions);
    data = SecCertificateCopyData(cert);
    //write_data("/tmp/iphone_cert.der", data);
    CFReleaseNull(data);
    CFReleaseNull(subject);
    CFReleaseNull(extensions);
    CFReleaseNull(challenge);

    const void * email[] = { CFSTR("1.2.840.113549.1.9.1"), CFSTR("*****@*****.**") };
    const void * cn[] = { CFSTR("2.5.4.3"), CFSTR("S/MIME Baby") };
    CFArrayRef email_dn = CFArrayCreate(kCFAllocatorDefault, email, 2, NULL);
    CFArrayRef cn_dn = CFArrayCreate(kCFAllocatorDefault, cn, 2, NULL);
    const void *dn_array[2];
    dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&email_dn, 1, NULL);
    dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&cn_dn, 1, NULL);
    CFArrayRef rdns = CFArrayCreate(kCFAllocatorDefault, dn_array, 2, NULL);
    CFDictionarySetValue(subject_alt_names, CFSTR("rfc822name"), CFSTR("*****@*****.**"));

    uint8_t random_extension_data[] = { 0xde, 0xad, 0xbe, 0xef };
    CFDataRef random_extension_value = CFDataCreate(kCFAllocatorDefault, random_extension_data, sizeof(random_extension_data));
    CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.2"), random_extension_value);  // APPLE_FDR_ACCESS_OID
    CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.3"), CFSTR("that guy"));  // APPLE_FDR_CLIENT_IDENTIFIER_OID
    CFReleaseNull(random_extension_value);

    csr = SecGenerateCertificateRequest(rdns, csr_parameters, phone_publicKey, phone_privateKey);
    isnt(csr, NULL, "csr w/ params");
    //write_data("/tmp/csr_neu", csr);
    CFReleaseNull(csr);
    CFReleaseNull(subject_alt_names);
    CFDictionaryRemoveAllValues(random_extensions);

#if TARGET_OS_IPHONE
    CFDataRef scep_request = SecSCEPGenerateCertificateRequest(rdns,
        csr_parameters, phone_publicKey, phone_privateKey, NULL, ca_cert);
    isnt(scep_request, NULL, "got scep blob");
    //write_data("/tmp/scep_request.der", scep_request);
#endif

    CFReleaseNull(email_dn);
    CFReleaseNull(cn_dn);
    CFReleaseNull(dn_array[0]);
    CFReleaseNull(dn_array[1]);
    CFReleaseNull(rdns);

#if TARGET_OS_IPHONE
    CFDataRef scep_reply = SecSCEPCertifyRequest(scep_request, ca_identity, serialno, false);
    isnt(scep_reply, NULL, "produced scep reply");
    //write_data("/tmp/scep_reply.der", scep_reply);

    CFArrayRef issued_certs = NULL;
    ok(issued_certs = SecSCEPVerifyReply(scep_request, scep_reply, ca_cert, NULL), "verify scep reply");

    // take the issued cert and CA cert and pretend it's a RA/CA couple
    CFMutableArrayRef scep_certs = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, issued_certs);
    CFArrayAppendValue(scep_certs, ca_cert);
    SecCertificateRef ca_certificate = NULL, ra_signing_certificate = NULL, ra_encryption_certificate = NULL;

    ok_status(SecSCEPValidateCACertMessage(scep_certs, NULL,
        &ca_certificate, &ra_signing_certificate,
        &ra_encryption_certificate), "pull apart array again");
    ok(CFEqual(ca_cert, ca_certificate), "found ca");
    ok(CFArrayContainsValue(issued_certs, CFRangeMake(0, CFArrayGetCount(issued_certs)), ra_signing_certificate), "found ra");
    ok(!ra_encryption_certificate, "no separate encryption cert");

    CFReleaseSafe(ca_certificate);
    CFReleaseSafe(ra_signing_certificate);
    CFReleaseSafe(scep_certs);

    CFReleaseSafe(scep_request);
    CFReleaseSafe(scep_reply);
    CFReleaseSafe(issued_certs);
#endif

    // cleanups
    dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL);
    ok_status(SecItemDelete(dict), "delete ca identity");
	CFReleaseSafe(dict);
    dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&phone_privateKey, 1, NULL, NULL);
    ok_status(SecItemDelete(dict), "delete phone private key");
	CFReleaseSafe(dict);

    CFReleaseSafe(serialno);

    CFReleaseSafe(cert);
    CFReleaseSafe(ca_identity);
    CFReleaseSafe(ca_cert);
	CFReleaseSafe(ca_identity_phone_key);
	CFReleaseSafe(ca_cert_phone_key);
    CFReleaseSafe(csr_parameters);
    CFReleaseSafe(random_extensions);
    CFReleaseSafe(parameters);
    CFReleaseSafe(ca_publicKey);
    CFReleaseSafe(ca_privateKey);
    CFReleaseSafe(phone_publicKey);
    CFReleaseSafe(phone_privateKey);
}

static void test_ec_csr(void) {
    SecKeyRef ecPublicKey = NULL, ecPrivateKey = NULL;

    int keysize = 256;
    CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize);

    const void *keyParamsKeys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
    const void *keyParamsValues[] = { kSecAttrKeyTypeECSECPrimeRandom,  key_size_num};
    CFDictionaryRef keyParameters = CFDictionaryCreate(NULL, keyParamsKeys, keyParamsValues, 2,
                                                       &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    ok_status(SecKeyGeneratePair(keyParameters, &ecPublicKey, &ecPrivateKey),
              "unable to generate EC key");

    SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} };
    SecATV c[]  = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} };
    SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} };
    SecATV l[]  = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} };
    SecATV o[]  = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} };
    SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} };

    SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL };

    CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFDictionarySetValue(subject_alt_names, CFSTR("dnsname"), CFSTR("xey.nl"));

    int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment;
    CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage);

    CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions };
    const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions };
    CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault,
                                                        key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);


    CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, ecPublicKey, ecPrivateKey);
    isnt(csr, NULL, "csr w/ params");
    //write_data("/tmp/csr", csr);
    CFDataRef subject, extensions;
    CFStringRef challenge;
    ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr");

    CFReleaseNull(csr);
    CFReleaseNull(key_size_num);
    CFReleaseNull(keyParameters);
    CFReleaseNull(ecPublicKey);
    CFReleaseNull(ecPrivateKey);
    CFReleaseNull(subject_alt_names);
    CFReleaseNull(key_usage_num);
    CFReleaseNull(random_extensions);
    CFReleaseNull(csr_parameters);
    CFReleaseNull(subject);
    CFReleaseNull(extensions);
    CFReleaseNull(challenge);
}
Esempio n. 15
0
static int importKeychainToX509_STORE(X509_STORE* verifyStore, char* err, size_t err_len) {
    int status = 1;
    CFArrayRef result = NULL;
    OSStatus osStatus;

    // This copies all the certificates trusted by the system (regardless of what
    // keychain they're
    // attached to) into a CFArray.
    if ((osStatus = SecTrustCopyAnchorCertificates(&result)) != 0) {
        CFStringRef statusString = SecCopyErrorMessageString(osStatus, NULL);
        snprintf(err,
                 err_len,
                 "Error enumerating certificates: %s",
                 CFStringGetCStringPtr(statusString, kCFStringEncodingASCII));
        CFRelease(statusString);
        status = 0;
        goto CLEANUP;
    }

    CFDataRef rawData = NULL;
    X509* x509Cert = NULL;

    for (CFIndex i = 0; i < CFArrayGetCount(result); i++) {
        SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(result, i);

        rawData = SecCertificateCopyData(cert);
        if (!rawData) {
            snprintf(err, err_len, "Error enumerating certificates");
            status = 0;
            goto CLEANUP;
        }
        const uint8_t* rawDataPtr = CFDataGetBytePtr(rawData);

        // Parse an openssl X509 object from each returned certificate
        x509Cert = d2i_X509(NULL, &rawDataPtr, CFDataGetLength(rawData));
        if (!x509Cert) {
            snprintf(err,
                     err_len,
                     "Error parsing X509 certificate from system keychain: %s",
                     ERR_reason_error_string(ERR_peek_last_error()));
            status = 0;
            goto CLEANUP;
        }

        // Add the parsed X509 object to the X509_STORE verification store
        if (X509_STORE_add_cert(verifyStore, x509Cert) != 1) {
            int check_error_status = checkX509_STORE_error(err, err_len);
            if (!check_error_status) {
                status = check_error_status;
                goto CLEANUP;
            }
        }
        CFRelease(rawData);
        rawData = NULL;
        X509_free(x509Cert);
        x509Cert = NULL;
    }

CLEANUP:
    if (result != NULL) {
        CFRelease(result);
    }
    if (rawData != NULL) {
        CFRelease(rawData);
    }
    if (x509Cert != NULL) {
        X509_free(x509Cert);
    }
    return status;
}
static int
keychain_iter_start(hx509_context context,
		    hx509_certs certs, void *data, void **cursor)
{
#ifndef __APPLE_TARGET_EMBEDDED__
    struct ks_keychain *ctx = data;
#endif
    struct iter *iter;

    iter = calloc(1, sizeof(*iter));
    if (iter == NULL) {
	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
	return ENOMEM;
    }

#ifndef __APPLE_TARGET_EMBEDDED__
    if (ctx->anchors) {
        CFArrayRef anchors;
	int ret;
	int i;

	ret = hx509_certs_init(context, "MEMORY:ks-file-create",
			       0, NULL, &iter->certs);
	if (ret) {
	    free(iter);
	    return ret;
	}

	ret = SecTrustCopyAnchorCertificates(&anchors);
	if (ret != 0) {
	    hx509_certs_free(&iter->certs);
	    free(iter);
	    hx509_set_error_string(context, 0, ENOMEM,
				   "Can't get trust anchors from Keychain");
	    return ENOMEM;
	}
	for (i = 0; i < CFArrayGetCount(anchors); i++) {
	    SecCertificateRef cr;
	    hx509_cert cert;
	    CFDataRef dataref;

	    cr = (SecCertificateRef)CFArrayGetValueAtIndex(anchors, i);

	    dataref = SecCertificateCopyData(cr);
	    if (dataref == NULL)
		continue;

	    ret = hx509_cert_init_data(context, CFDataGetBytePtr(dataref), CFDataGetLength(dataref), &cert);
	    CFRelease(dataref);
	    if (ret)
		continue;

	    ret = hx509_certs_add(context, iter->certs, cert);
	    hx509_cert_free(cert);
	}
	CFRelease(anchors);
	if (ret != 0) {
	    hx509_certs_free(&iter->certs);
	    free(iter);
	    hx509_set_error_string(context, 0, ret,
				   "Failed to add cert");
	    return ret;
	}
    }

    if (iter->certs) {
	int ret;
	ret = hx509_certs_start_seq(context, iter->certs, &iter->cursor);
	if (ret) {
	    hx509_certs_free(&iter->certs);
	    free(iter);
	    return ret;
	}
    } else
#endif
    {
	OSStatus ret;
	const void *keys[] = {
	    kSecClass,
	    kSecReturnRef,
	    kSecMatchLimit
	};
	const void *values[] = {
	    kSecClassCertificate,
	    kCFBooleanTrue,
	    kSecMatchLimitAll
	};

	CFDictionaryRef secQuery;

	secQuery = CFDictionaryCreate(NULL, keys, values,
				      sizeof(keys) / sizeof(*keys),
				      &kCFTypeDictionaryKeyCallBacks,
				      &kCFTypeDictionaryValueCallBacks);
	
	ret = SecItemCopyMatching(secQuery, (CFTypeRef *)&iter->search);
	CFRelease(secQuery);
	if (ret) {
	    free(iter);
	    return ENOMEM;
	}
    }

    *cursor = iter;
    return 0;
}
Esempio n. 17
0
static carray * mailstream_low_cfstream_get_certificate_chain(mailstream_low * s)
{
#if HAVE_CFNETWORK
  struct mailstream_cfstream_data * cfstream_data;
  unsigned int i;
  carray * result;
  CFArrayRef certs;
  CFIndex count;
  
  cfstream_data = (struct mailstream_cfstream_data *) s->data;
    
  SecTrustRef secTrust = (SecTrustRef)CFReadStreamCopyProperty(cfstream_data->readStream, kCFStreamPropertySSLPeerTrust);
  if (secTrust) {
      // SecTrustEvaluate() needs to be called before SecTrustGetCertificateCount() in Mac OS X <= 10.8
      SecTrustEvaluate(secTrust, NULL);
      count = SecTrustGetCertificateCount(secTrust);
      result = carray_new(4);
      for(i = 0 ; i < count ; i ++) {
          SecCertificateRef cert = (SecCertificateRef) SecTrustGetCertificateAtIndex(secTrust, i);
          CFDataRef data = SecCertificateCopyData(cert);
          if (data == NULL) {
            carray_free(result);
            CFRelease(secTrust);
            return NULL;
          }
          CFIndex length = CFDataGetLength(data);
          const UInt8 * bytes = CFDataGetBytePtr(data);
          MMAPString * str = mmap_string_sized_new(length);
          mmap_string_append_len(str, (char*) bytes, length);
          carray_add(result, str, NULL);
          CFRelease(data);
      }
      CFRelease(secTrust);
  }
  else {
      certs = CFReadStreamCopyProperty(cfstream_data->readStream, kCFStreamPropertySSLPeerCertificates);
      if (certs) {
          count = CFArrayGetCount(certs);
          result = carray_new(4);
          for(i = 0 ; i < count ; i ++) {
              SecCertificateRef cert = (SecCertificateRef) CFArrayGetValueAtIndex(certs, i);
              CFDataRef data = SecCertificateCopyData(cert);
              if (data == NULL) {
                carray_free(result);
                CFRelease(certs);
                return NULL;
              }
              CFIndex length = CFDataGetLength(data);
              const UInt8 * bytes = CFDataGetBytePtr(data);
              MMAPString * str = mmap_string_sized_new(length);
              mmap_string_append_len(str, (char*) bytes, length);
              carray_add(result, str, NULL);
              CFRelease(data);
          }
          CFRelease(certs);
      }
      else {
          return NULL;
      }
  }
    
  return result;
#else
  return NULL;
#endif
}