/** * Interoperability test. * * data must point at an array of two driver structures. Data will be encrypted * with the first driver, and decrypted with the second. * * If the two drivers interoperate, the test passes. */ static void crypto_block_cross(abts_case *tc, apr_pool_t *pool, const apr_crypto_driver_t **drivers, const apr_crypto_block_key_type_e type, const apr_crypto_block_key_mode_e mode, int doPad, const unsigned char *in, apr_size_t inlen, const char *description) { const apr_crypto_driver_t *driver1 = drivers[0]; const apr_crypto_driver_t *driver2 = drivers[1]; apr_crypto_t *f1 = NULL; apr_crypto_t *f2 = NULL; const apr_crypto_key_t *key1 = NULL; const apr_crypto_key_t *key2 = NULL; unsigned char *cipherText = NULL; apr_size_t cipherTextLen = 0; unsigned char *plainText = NULL; apr_size_t plainTextLen = 0; const unsigned char *iv = NULL; apr_size_t blockSize = 0; f1 = make(tc, pool, driver1); f2 = make(tc, pool, driver2); key1 = passphrase(tc, pool, driver1, f1, type, mode, doPad, description); key2 = passphrase(tc, pool, driver2, f2, type, mode, doPad, description); cipherText = encrypt_block(tc, pool, driver1, f1, key1, in, inlen, &cipherText, &cipherTextLen, &iv, &blockSize, description); plainText = decrypt_block(tc, pool, driver2, f2, key2, cipherText, cipherTextLen, &plainText, &plainTextLen, iv, &blockSize, description); if (cipherText && plainText) { if (memcmp(in, plainText, inlen)) { fprintf(stderr, "cross mismatch: %s %s/%s\n", description, apr_crypto_driver_name(driver1), apr_crypto_driver_name( driver2)); } ABTS_STR_EQUAL(tc, (char *)in, (char *)plainText); } }
bool CPosixConnection::Connect(IPassphraseStorage *storage, const CIPConfig &ipconfig) { if (!m_managed) return true; std::string passphrase(""); if (storage && m_type == NETWORK_CONNECTION_TYPE_WIFI) { if (m_encryption != NETWORK_CONNECTION_ENCRYPTION_NONE) { if (!storage->GetPassphrase(m_essid, passphrase)) return false; if (passphrase.size() <= 0) return false; } } else { passphrase = g_guiSettings.GetString("network.passphrase"); /* CVariant secret; if (m_keyringManager->FindSecret("network", m_essid, secret) && secret.isString()) { passphrase = secret.asString(); return true; } */ } if (DoConnection(ipconfig, passphrase) && GetState() == NETWORK_CONNECTION_STATE_CONNECTED) { // if we connect, save out the essid g_guiSettings.SetString("network.essid", m_essid.c_str()); // quick update of some internal vars m_method = ipconfig.m_method; m_address = ipconfig.m_address; m_netmask = ipconfig.m_netmask; m_gateway = ipconfig.m_gateway; return true; } else { if (storage) storage->InvalidatePassphrase(m_essid); } return false; }
// // Same thing, but obtain a new secret somehow and set it into the common. // void KeychainDatabase::establishNewSecrets(const AccessCredentials *creds, SecurityAgent::Reason reason) { list<CssmSample> samples; if (creds && creds->samples().collect(CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK, samples)) { for (list<CssmSample>::iterator it = samples.begin(); it != samples.end(); it++) { TypedList &sample = *it; sample.checkProper(); switch (sample.type()) { // interactively prompt the user case CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT: { secdebug("KCdb", "%p specified interactive passphrase", this); QueryNewPassphrase query(*this, reason); StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common()); query.inferHints(Server::process()); CssmAutoData passphrase(Allocator::standard(Allocator::sensitive)); CssmAutoData oldPassphrase(Allocator::standard(Allocator::sensitive)); if (query(oldPassphrase, passphrase) == SecurityAgent::noReason) { common().setup(NULL, passphrase); change_secret_on_keybag(common(), oldPassphrase.data(), (int)oldPassphrase.length(), passphrase.data(), (int)passphrase.length()); return; } } break; // try to use an explicitly given passphrase case CSSM_SAMPLE_TYPE_PASSWORD: { secdebug("KCdb", "%p specified explicit passphrase", this); if (sample.length() != 2) CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE); common().setup(NULL, sample[1]); if (common().isLoginKeychain()) { CssmAutoData oldPassphrase(Allocator::standard(Allocator::sensitive)); list<CssmSample> oldSamples; creds->samples().collect(CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK, oldSamples); for (list<CssmSample>::iterator oit = oldSamples.begin(); oit != oldSamples.end(); oit++) { TypedList &tmpList = *oit; tmpList.checkProper(); if (tmpList.type() == CSSM_SAMPLE_TYPE_PASSWORD) { if (tmpList.length() == 2) { oldPassphrase = tmpList[1].data(); } } } if (!oldPassphrase.length() && mSecret && mSecret.length()) { oldPassphrase = mSecret; } change_secret_on_keybag(common(), oldPassphrase.data(), (int)oldPassphrase.length(), sample[1].data().data(), (int)sample[1].data().length()); } return; } // try to open with a given master key case CSSM_WORDID_SYMMETRIC_KEY: case CSSM_SAMPLE_TYPE_ASYMMETRIC_KEY: secdebug("KCdb", "%p specified explicit master key", this); common().setup(NULL, keyFromCreds(sample, 3)); return; // explicitly defeat the default action but don't try anything in particular case CSSM_WORDID_CANCELED: secdebug("KCdb", "%p defeat default action", this); break; default: // Unknown sub-sample for acquiring new secret. // If we wanted to be fascist, we could now do // CssmError::throwMe(CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED); // But instead we try to be tolerant and continue on. // This DOES however count as an explicit attempt at specifying unlock, // so we will no longer try the default case below... secdebug("KCdb", "%p unknown sub-sample acquisition (%d) ignored", this, sample.type()); break; } } } else { // default action -- interactive (only) QueryNewPassphrase query(*this, reason); StSyncLock<Mutex, Mutex> uisync(common().uiLock(), common()); query.inferHints(Server::process()); CssmAutoData passphrase(Allocator::standard(Allocator::sensitive)); CssmAutoData oldPassphrase(Allocator::standard(Allocator::sensitive)); if (query(oldPassphrase, passphrase) == SecurityAgent::noReason) { common().setup(NULL, passphrase); change_secret_on_keybag(common(), oldPassphrase.data(), (int)oldPassphrase.length(), passphrase.data(), (int)passphrase.length()); return; } } // out of options - no secret obtained CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED); }
// // Database tests. // Database locks/unlocks etc. // void databases() { printf("* Database manipulation test\n"); CssmAllocator &alloc = CssmAllocator::standard(); ClientSession ss(alloc, alloc); AutoCredentials pwCred(alloc); StringData passphrase("two"); StringData badPassphrase("three"); pwCred += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK, new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD), new(alloc) ListElement(passphrase)); pwCred += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK, new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD), new(alloc) ListElement(badPassphrase)); // pwCred = (NEW: two, OLD: three) DbTester db1(ss, "/tmp/one", NULL, 30, true); DbTester db2(ss, "/tmp/two", &pwCred, 60, false); // db2.passphrase = two // encode db1 and re-open it CssmData dbBlob; ss.encodeDb(db1, dbBlob); DbHandle db1b = ss.decodeDb(db1.dbId, &nullCred, dbBlob); if (db1b == db1.dbRef) detail("REUSED DB HANDLE ON DECODEDB (probably wrong)"); // open db1 a third time (so now there's three db handles for db1) DbHandle db1c = ss.decodeDb(db1.dbId, &nullCred, dbBlob); // lock them to get started ss.lock(db1); ss.lock(db2); // unlock it through user prompt("unlock"); ss.unlock(db1); prompt(); ss.unlock(db1b); // 2nd unlock should not prompt ss.lock(db1c); // lock it again prompt("unlock"); ss.unlock(db1); // and that should prompt again prompt(); // db2 has a passphrase lock credentials - it'll work without U/I db2.unlock("wrong passphrase"); // pw=two, cred=three AutoCredentials pwCred2(alloc); pwCred2 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK, new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD), new(alloc) ListElement(passphrase)); // pwCred2 = (OLD: two) ss.authenticateDb(db2, CSSM_DB_ACCESS_WRITE, &pwCred2); // set it db2.unlock(); ss.lock(db2); // now change db2's passphrase ss.lock(db2); pwCred2 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK, new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD), new(alloc) ListElement(badPassphrase)); // pwCred2 = (OLD: two, NEW: three) db2.changePassphrase(&pwCred2); // passphrase = three, cred = (OLD: two) // encode and re-decode to make sure new data is there CssmData blob2; ss.encodeDb(db2, blob2); DbHandle db2a = ss.decodeDb(db2.dbId, &pwCred, blob2); // db2a cred = (OLD: two, NEW: three) // now, the *old* cred won't work anymore db2.unlock("old passphrase accepted"); // back to the old credentials, which *do* have the (old bad, now good) passphrase ss.lock(db2a); ss.unlock(db2a); detail("New passphrase accepted"); // clear the credentials (this will prompt; cancel it) ss.authenticateDb(db2, CSSM_DB_ACCESS_WRITE, NULL); prompt("cancel"); db2.unlock("null credential accepted"); prompt(); // fell-swoop from-to change password operation StringData newPassphrase("hollerith"); AutoCredentials pwCred3(alloc); pwCred3 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK, new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD), new(alloc) ListElement(newPassphrase)); pwCred3 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK, new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD), new(alloc) ListElement(passphrase)); db2.changePassphrase(&pwCred3, "accepting original (unchanged) passphrase"); AutoCredentials pwCred4(alloc); pwCred4 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK, new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD), new(alloc) ListElement(newPassphrase)); pwCred4 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK, new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD), new(alloc) ListElement(badPassphrase)); db2.changePassphrase(&pwCred4); // final status check AutoCredentials pwCred5(alloc); pwCred5 += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK, new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD), new(alloc) ListElement(newPassphrase)); ss.authenticateDb(db2, CSSM_DB_ACCESS_WRITE, &pwCred5); db2.unlock(); detail("Final passphrase change verified"); }