// // Set an individual trust element // void TrustStore::assign(Certificate *cert, Policy *policy, SecTrustUserSetting trust) { StLock<Mutex> _(mMutex); TrustData trustData = { UserTrustItem::currentVersion, trust }; Keychain defaultKeychain = Keychain::optional(NULL); Keychain trustLocation = defaultKeychain; // default keychain, unless trust entry found StorageManager::KeychainList searchList; globals().storageManager.getSearchList(searchList); if (Item item = findItem(cert, policy, searchList)) { // user has a trust setting in a keychain - modify that trustLocation = item->keychain(); if (trust == kSecTrustResultUnspecified) item->keychain()->deleteItem(item); else item->modifyContent(NULL, sizeof(trustData), &trustData); } else { // no trust entry: make one if (trust != kSecTrustResultUnspecified) { Item item = new UserTrustItem(cert, policy, trustData); if (Keychain location = cert->keychain()) { try { location->add(item); // try the cert's keychain first trustLocation = location; } catch (...) { if (&*location != &*defaultKeychain) defaultKeychain->add(item); // try the default (if it's not the same) } } else { defaultKeychain->add(item); // raw cert - use default keychain } } } // Make sure that the certificate is available in some keychain, // to provide a basis for editing the trust setting that we're assigning. if (cert->keychain() == NULL) { if (cert->findInKeychain(searchList) == NULL) { try { cert->copyTo(trustLocation); // add cert to the trust item's keychain } catch (...) { secdebug("trusteval", "failed to add certificate %p to keychain \"%s\"", cert, trustLocation->name()); try { if (&*trustLocation != &*defaultKeychain) cert->copyTo(defaultKeychain); // try the default (if it's not the same) } catch (...) { // unable to add the certificate secdebug("trusteval", "failed to add certificate %p to keychain \"%s\"", cert, defaultKeychain->name()); } } } } }
// // Retrieve the trust setting for a (certificate, policy) pair. // SecTrustUserSetting TrustStore::find(Certificate *cert, Policy *policy, StorageManager::KeychainList &keychainList) { StLock<Mutex> _(mMutex); if (Item item = findItem(cert, policy, keychainList)) { // Make sure that the certificate is available in some keychain, // to provide a basis for editing the trust setting that we're returning. if (cert->keychain() == NULL) { if (cert->findInKeychain(keychainList) == NULL) { Keychain defaultKeychain = Keychain::optional(NULL); if (Keychain location = item->keychain()) { try { cert->copyTo(location); // add cert to the trust item's keychain } catch (...) { secdebug("trusteval", "failed to add certificate %p to keychain \"%s\"", cert, location->name()); try { if (&*location != &*defaultKeychain) cert->copyTo(defaultKeychain); // try the default (if it's not the same) } catch (...) { // unable to add the certificate secdebug("trusteval", "failed to add certificate %p to keychain \"%s\"", cert, defaultKeychain->name()); } } } } } CssmDataContainer data; item->getData(data); if (data.length() != sizeof(TrustData)) MacOSError::throwMe(errSecInvalidTrustSetting); TrustData &trust = *data.interpretedAs<TrustData>(); if (trust.version != UserTrustItem::currentVersion) MacOSError::throwMe(errSecInvalidTrustSetting); return trust.trust; } else { return kSecTrustResultUnspecified; } }