static void SecSystemAnchorSourceInit(void) { SecSystemAnchorSourceRef result = (SecSystemAnchorSourceRef) malloc(sizeof(*result)); result->base.copyParents = SecSystemAnchorSourceCopyParents; result->base.contains = SecSystemAnchorSourceContains; CFDataRef xmlData = SecFrameworkCopyResourceContents( CFSTR("SystemAnchors"), CFSTR("plist"), NULL); CFPropertyListRef plist = CFPropertyListCreateFromXMLData( kCFAllocatorDefault, xmlData, kCFPropertyListImmutable, NULL); if (plist) { if (CFGetTypeID(plist) == CFDictionaryGetTypeID()) { result->digests = (CFSetRef)plist; } else { secwarning("SystemAnchors plist is wrong type."); CFRelease(plist); } } if (!result->digests) { result->digests = CFSetCreate(kCFAllocatorDefault, NULL, 0, &kCFTypeSetCallBacks); } kSecSystemAnchorSource = (SecCertificateSourceRef)result; }
static SecTrustStoreRef SecTrustStoreCreate(const char *db_name, bool create) { SecTrustStoreRef ts; int s3e; require(ts = (SecTrustStoreRef)malloc(sizeof(struct __SecTrustStore)), errOut); ts->queue = dispatch_queue_create("truststore", DISPATCH_QUEUE_SERIAL); require_noerr(s3e = sec_sqlite3_open(db_name, &ts->s3h, create), errOut); s3e = sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL), &ts->copyParents, NULL); if (create && s3e == SQLITE_ERROR) { /* sqlite3_prepare returns SQLITE_ERROR if the table we are compiling this statement for doesn't exist. */ char *errmsg = NULL; s3e = sqlite3_exec(ts->s3h, "CREATE TABLE tsettings(" "sha1 BLOB NOT NULL DEFAULT ''," "subj BLOB NOT NULL DEFAULT ''," "tset BLOB," "data BLOB," "PRIMARY KEY(sha1)" ");" "CREATE INDEX isubj ON tsettings(subj);" , NULL, NULL, &errmsg); if (errmsg) { secwarning("CREATE TABLE cert: %s", errmsg); sqlite3_free(errmsg); } require_noerr(s3e, errOut); s3e = sqlite3_prepare(ts->s3h, copyParentsSQL, sizeof(copyParentsSQL), &ts->copyParents, NULL); } require_noerr(s3e, errOut); require_noerr(s3e = sqlite3_prepare(ts->s3h, containsSQL, sizeof(containsSQL), &ts->contains, NULL), errOut); if (SecTrustStoreCountAll(ts) == 0) { ts->containsSettings = false; } else { /* In the error case where SecTrustStoreCountAll returns a negative result, * we'll pretend there are contents in the trust store so that we still do * DB operations */ ts->containsSettings = true; } return ts; errOut: if (ts) { sqlite3_close(ts->s3h); dispatch_release_safe(ts->queue); free(ts); } return NULL; }
static bool getBoolForKey(CFDictionaryRef dict, CFStringRef key, bool default_value) { CFTypeRef value = CFDictionaryGetValue(dict, key); if (value) { if (CFGetTypeID(value) == CFBooleanGetTypeID()) { return CFBooleanGetValue(value); } else { secwarning("Value %@ for key %@ is not bool", value, key); } } return default_value; }
static OSStatus SecRSAPrivateKeyInit(SecKeyRef key, const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) { OSStatus result = errSecParam; ccrsa_full_ctx_t fullkey; fullkey.full = key->key; // Set maximum size for parsers ccrsa_ctx_n(fullkey) = ccn_nof(kMaximumRSAKeyBits); switch (encoding) { case kSecKeyEncodingBytes: // Octets is PKCS1 case kSecKeyEncodingPkcs1: result = ccrsa_full_decode(fullkey, keyDataLength, keyData); break; case kSecGenerateKey: { CFDictionaryRef parameters = (CFDictionaryRef) keyData; CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits); CFIndex keyLengthInBits = getIntValue(ksize); if (keyLengthInBits < 256 || keyLengthInBits > kMaximumRSAKeyBits) { secwarning("Invalid or missing key size in: %@", parameters); return errSecKeySizeNotAllowed; } /* TODO: Add support for kSecPublicExponent parameter. */ static uint8_t e[] = { 0x01, 0x00, 0x01 }; // Default is 65537 if (!ccrsa_generate_key(keyLengthInBits, fullkey.full, sizeof(e), e, ccrng_seckey)) result = errSecSuccess; break; } default: break; } return result; }
static OSStatus SecECPrivateKeyInit(SecKeyRef key, const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) { ccec_full_ctx_t fullkey; fullkey.hdr = key->key; OSStatus err = errSecParam; switch (encoding) { case kSecKeyEncodingPkcs1: { /* TODO: DER import size (and thus cp), pub.x, pub.y and k. */ //err = ecc_import(keyData, keyDataLength, fullkey); /* DER != PKCS#1, but we'll go along with it */ ccoid_t oid; size_t n; ccec_const_cp_t cp; require_noerr(ccec_der_import_priv_keytype(keyDataLength, keyData, &oid, &n), abort); cp = ccec_cp_for_oid(oid); if (cp.zp == NULL) { cp = ccec_curve_for_length_lookup(n * 8 /* bytes -> bits */, ccec_cp_192(), ccec_cp_224(), ccec_cp_256(), ccec_cp_384(), ccec_cp_521(), NULL); } require_action(cp.zp != NULL, abort, err = errSecDecode); ccec_ctx_init(cp, fullkey); require_noerr(ccec_der_import_priv(cp, keyDataLength, keyData, fullkey), abort); err = errSecSuccess; break; } case kSecKeyEncodingBytes: { ccec_const_cp_t cp = getCPForPrivateSize(keyDataLength); require(cp.zp != NULL, abort); ccec_ctx_init(cp, fullkey); size_t pubSize = ccec_export_pub_size(fullkey); require(pubSize < (size_t) keyDataLength, abort); require_noerr_action(ccec_import_pub(cp, pubSize, keyData, fullkey), abort, err = errSecDecode); keyData += pubSize; keyDataLength -= pubSize; cc_unit *k = ccec_ctx_k(fullkey); require_noerr_action(ccn_read_uint(ccec_ctx_n(fullkey), k, keyDataLength, keyData), abort, err = errSecDecode); err = errSecSuccess; break; } case kSecGenerateKey: { CFDictionaryRef parameters = (CFDictionaryRef) keyData; CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits); CFIndex keyLengthInBits = getIntValue(ksize); ccec_const_cp_t cp = ccec_get_cp(keyLengthInBits); if (!cp.zp) { secwarning("Invalid or missing key size in: %@", parameters); return errSecKeySizeNotAllowed; } if (!ccec_generate_key(cp, ccrng_seckey, fullkey)) err = errSecSuccess; break; } default: break; } abort: return err; }