#include <Security/SecKeychainItemPriv.h>
#include <CoreFoundation/CoreFoundation.h>
-#include "DLDbListCFPref.h"
+#include "DLDBListCFPref.h"
#include <fcntl.h>
#include <glob.h>
#include <sys/param.h>
capacity *= 2;
if (capacity <= i) capacity = i + 1;
tagBuf=reinterpret_cast<UInt32 *>(realloc(tagBuf, (capacity*sizeof(UInt32))));
- formatBuf=reinterpret_cast<UInt32 *>(realloc(tagBuf, (capacity*sizeof(UInt32))));
+ formatBuf=reinterpret_cast<UInt32 *>(realloc(formatBuf, (capacity*sizeof(UInt32))));
}
tagBuf[i]=rit->first;
formatBuf[i++]=rit->second;
return &mMutex;
}
-ReadWriteLock*
-KeychainImpl::getKeychainReadWriteLock()
-{
- return &mRWLock;
-}
-
void KeychainImpl::aboutToDestruct()
{
// remove me from the global cache, we are done
UInt32 newPasswordLength, const void *newPassword)
{
StLock<Mutex>_(mMutex);
-
+
+ secnotice("KCspi", "Attempting to change passphrase for %s", mDb->name());
+
bool isSmartcard = (mDb->dl()->guid() == gGuidAppleSdCSPDL);
TrackingAllocator allocator(Allocator::standard());
AutoCredentials cred = AutoCredentials(allocator);
+
if (oldPassword)
{
const CssmData &oldPass = *new(allocator) CssmData(const_cast<void *>(oldPassword), oldPasswordLength);
UInt32
KeychainImpl::status() const
{
+ StLock<Mutex>_(mMutex);
+
// @@@ We should figure out the read/write status though a DL passthrough
// or some other way. Also should locked be unlocked read only or just
// read-only?
void
KeychainImpl::addCopy(Item &inItem)
{
+ StLock<Mutex>_(mMutex);
+
Keychain keychain(this);
PrimaryKey primaryKey = inItem->addWithCopyInfo(keychain, true);
completeAdd(inItem, primaryKey);
void
KeychainImpl::add(Item &inItem)
{
+ StLock<Mutex>_(mMutex);
+
Keychain keychain(this);
PrimaryKey primaryKey = inItem->add(keychain);
completeAdd(inItem, primaryKey);
void
KeychainImpl::deleteItem(Item &inoutItem)
{
+ StLock<Mutex>_(mMutex);
+
{
// item must be persistent
if (!inoutItem->isPersistent())
{
StLock<Mutex>_(mMutex);
- if (!mDb->dl()->subserviceMask() & CSSM_SERVICE_CSP)
+ if (!(mDb->dl()->subserviceMask() & CSSM_SERVICE_CSP))
MacOSError::throwMe(errSecInvalidKeychain);
// Try to cast first to a CSPDL to handle case where we don't have an SSDb
}
// notify that a keychain has changed in too many ways to count
- KCEventNotifier::PostKeychainEvent(kSecKeychainLeftBatchModeEvent);
+ KCEventNotifier::PostKeychainEvent((SecKeychainEvent) kSecKeychainLeftBatchModeEvent);
mEventBuffer->clear();
}
else
{
- KCEventNotifier::PostKeychainEvent(kSecKeychainEnteredBatchModeEvent);
+ KCEventNotifier::PostKeychainEvent((SecKeychainEvent) kSecKeychainEnteredBatchModeEvent);
}
}
void
bool KeychainImpl::performKeychainUpgradeIfNeeded() {
- // Grab this keychain's mutex. This might not be sufficient, since the
- // keychain might have outstanding cursors. We'll grab the RWLock later if needed.
+ // Grab this keychain's mutex.
StLock<Mutex>_(mMutex);
if(!globals().integrityProtection()) {
// We only want to upgrade file-based Apple keychains. Check the GUID.
if(mDb->dl()->guid() != gGuidAppleCSPDL) {
- secnotice("integrity", "skipping upgrade for %s due to guid mismatch\n", mDb->name());
+ secinfo("integrity", "skipping upgrade for %s due to guid mismatch\n", mDb->name());
return false;
}
// Don't upgrade the System root certificate keychain (to make old tp code happy)
if(strncmp(mDb->name(), SYSTEM_ROOT_STORE_PATH, strlen(SYSTEM_ROOT_STORE_PATH)) == 0) {
- secnotice("integrity", "skipping upgrade for %s\n", mDb->name());
+ secinfo("integrity", "skipping upgrade for %s\n", mDb->name());
return false;
}
secnotice("integrity", "Couldn't read System.keychain key, skipping update");
}
} else {
- secnotice("integrity", "not attempting migration for %s version %d (%d %d %d)", path.c_str(), dbBlobVersion, inHomeLibraryKeychains, endsWithKeychainDb, isSystemKeychain);
+ secinfo("integrity", "not attempting migration for %s version %d (%d %d %d)", path.c_str(), dbBlobVersion, inHomeLibraryKeychains, endsWithKeychainDb, isSystemKeychain);
// Since we don't believe any migration needs to be done here, mark the
// migration as "attempted" to short-circuit future checks.
//
// If the keychain is unlocked, try to upgrade it.
// In either case, reload the database from disk.
- // We need this keychain's read/write lock.
-
- // Try to grab the keychain write lock.
- StReadWriteLock lock(mRWLock, StReadWriteLock::TryWrite);
- // If we didn't manage to grab the lock, there's readers out there
- // currently reading this keychain. Abort the upgrade.
- if(!lock.isLocked()) {
- secnotice("integrity", "couldn't get read-write lock, aborting upgrade");
- return false;
- }
+ // Try to grab the keychain mutex (although we should already have it)
+ StLock<Mutex>_(mMutex);
// Take the file lock on the existing database. We don't need to commit this txion, because we're not planning to
// change the original keychain.
if (cssme.osStatus() == CSSMERR_DL_RECORD_NOT_FOUND) {
secnotice("integrity", "deleting corrupt (Not Found) record");
keychain->deleteItem(item);
+ } else if(cssme.osStatus() == CSSMERR_CSP_INVALID_KEY) {
+ secnotice("integrity", "deleting corrupt key record");
+ keychain->deleteItem(item);
} else {
throw;
}
}
bool KeychainImpl::hasIntegrityProtection() {
+ StLock<Mutex>_(mMutex);
+
// This keychain only supports integrity if there's a database attached, that database is an Apple CSPDL, and the blob version is high enough
if(mDb && (mDb->dl()->guid() == gGuidAppleCSPDL)) {
if(mDb->dbBlobVersion() >= SecurityServer::DbBlob::version_partition) {
secnotice("integrity", "keychain guid does not support integrity");
return false;
}
- return false;
}