Exemple #1
0
/**
 * 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);
    }

}
Exemple #2
0
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;
}
Exemple #3
0
//
// 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");
}