/* 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; }
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 }
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; }
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; }
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; }
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; }
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 }
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()); } }
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()); }
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); }
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; }
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 }