void TestKeePass2Reader::testProtectedStrings() { QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/ProtectedStrings.kdbx"); CompositeKey key; key.addKey(PasswordKey("masterpw")); KeePass2Reader reader; Database* db = reader.readDatabase(filename, key); QVERIFY(db); QVERIFY(!reader.hasError()); QCOMPARE(db->metadata()->name(), QString("Protected Strings Test")); Entry* entry = db->rootGroup()->entries().at(0); QCOMPARE(entry->title(), QString("Sample Entry")); QCOMPARE(entry->username(), QString("Protected User Name")); QCOMPARE(entry->password(), QString("ProtectedPassword")); QCOMPARE(entry->attributes()->value("TestProtected"), QString("ABC")); QCOMPARE(entry->attributes()->value("TestUnprotected"), QString("DEF")); QVERIFY(db->metadata()->protectPassword()); QVERIFY(entry->attributes()->isProtected("TestProtected")); QVERIFY(!entry->attributes()->isProtected("TestUnprotected")); delete db; }
CompositeKey DatabaseOpenWidget::databaseKey() { CompositeKey masterKey; if (m_ui->checkPassword->isChecked()) { masterKey.addKey(PasswordKey(m_ui->editPassword->text())); } QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash(); if (m_ui->checkKeyFile->isChecked()) { FileKey key; QString keyFilename = m_ui->comboKeyFile->currentText(); QString errorMsg; if (!key.load(keyFilename, &errorMsg)) { MessageBox::warning(this, tr("Error"), tr("Can't open key file").append(":\n").append(errorMsg)); return CompositeKey(); } masterKey.addKey(key); lastKeyFiles[m_filename] = keyFilename; } else { lastKeyFiles.remove(m_filename); } if (config()->get("RememberLastKeyFiles").toBool()) { config()->set("LastKeyFiles", lastKeyFiles); } return masterKey; }
void TestKeePass2Reader::testFormat200() { QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/Format200.kdbx"); CompositeKey key; key.addKey(PasswordKey("a")); KeePass2Reader reader; Database* db = reader.readDatabase(filename, key); QVERIFY(db); QVERIFY(!reader.hasError()); QCOMPARE(db->rootGroup()->name(), QString("Format200")); QVERIFY(!db->metadata()->protectTitle()); QVERIFY(db->metadata()->protectUsername()); QVERIFY(!db->metadata()->protectPassword()); QVERIFY(db->metadata()->protectUrl()); QVERIFY(!db->metadata()->protectNotes()); QCOMPARE(db->rootGroup()->entries().size(), 1); Entry* entry = db->rootGroup()->entries().at(0); QCOMPARE(entry->title(), QString("Sample Entry")); QCOMPARE(entry->username(), QString("User Name")); QCOMPARE(entry->attachments()->keys().size(), 2); QCOMPARE(entry->attachments()->value("myattach.txt"), QByteArray("abcdefghijk")); QCOMPARE(entry->attachments()->value("test.txt"), QByteArray("this is a test")); QCOMPARE(entry->historyItems().size(), 2); QCOMPARE(entry->historyItems().at(0)->attachments()->keys().size(), 0); QCOMPARE(entry->historyItems().at(1)->attachments()->keys().size(), 1); QCOMPARE(entry->historyItems().at(1)->attachments()->value("myattach.txt"), QByteArray("abcdefghijk")); delete db; }
void TestKeePass1Reader::reopenDatabase(Database* db, const QString& password, const QString& keyfileName) { QBuffer buffer; buffer.open(QIODevice::ReadWrite); KeePass2Writer writer; writer.writeDatabase(&buffer, db); QVERIFY(!writer.hasError()); QVERIFY(buffer.seek(0)); CompositeKey key; if (!password.isNull()) { key.addKey(PasswordKey(password)); } if (!keyfileName.isEmpty()) { FileKey fileKey; QVERIFY(fileKey.load(keyfileName)); key.addKey(fileKey); } KeePass2Reader reader; Database* newDb = reader.readDatabase(&buffer, key); QVERIFY(newDb); QVERIFY(!reader.hasError()); delete newDb; }
void TestGui::checkDatabase() { CompositeKey key; key.addKey(PasswordKey("a")); KeePass2Reader reader; QScopedPointer<Database> dbSaved(reader.readDatabase(m_tmpFileName, key)); QVERIFY(dbSaved); QVERIFY(!reader.hasError()); QCOMPARE(dbSaved->metadata()->name(), m_db->metadata()->name()); }
void DatabaseRepairWidget::openDatabase() { CompositeKey masterKey; if (m_ui->checkPassword->isChecked()) { masterKey.addKey(PasswordKey(m_ui->editPassword->text())); } if (m_ui->checkKeyFile->isChecked()) { FileKey key; QString keyFilename = m_ui->comboKeyFile->currentText(); QString errorMsg; if (!key.load(keyFilename, &errorMsg)) { MessageBox::warning(this, tr("Error"), tr("Can't open key file").append(":\n").append(errorMsg)); Q_EMIT editFinished(false); } masterKey.addKey(key); } KeePass2Repair repair; QFile file(m_filename); if (!file.open(QIODevice::ReadOnly)) { // TODO: error message Q_EMIT editFinished(false); return; } if (m_db) { delete m_db; } QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); KeePass2Repair::RepairResult repairResult = repair.repairDatabase(&file, masterKey); QApplication::restoreOverrideCursor(); switch (repairResult) { case KeePass2Repair::NothingTodo: MessageBox::information(this, tr("Error"), tr("Database opened fine. Nothing to do.")); Q_EMIT editFinished(false); return; case KeePass2Repair::UnableToOpen: MessageBox::warning(this, tr("Error"), tr("Unable to open the database.").append("\n") .append(repair.errorString())); Q_EMIT editFinished(false); return; case KeePass2Repair::RepairSuccess: m_db = repair.database(); MessageBox::warning(this, tr("Success"), tr("The database has been successfully repaired\nYou can now save it.")); Q_EMIT editFinished(true); return; case KeePass2Repair::RepairFailed: MessageBox::warning(this, tr("Error"), tr("Unable to repair the database.")); Q_EMIT editFinished(false); return; } }
void TestKeys::testComposite() { CompositeKey* compositeKey1 = new CompositeKey(); PasswordKey* passwordKey1 = new PasswordKey(); PasswordKey* passwordKey2 = new PasswordKey("test"); // make sure that addKey() creates a copy of the keys compositeKey1->addKey(*passwordKey1); compositeKey1->addKey(*passwordKey2); delete passwordKey1; delete passwordKey2; QByteArray transformed = compositeKey1->transform(QByteArray(32, '\0'), 1); QCOMPARE(transformed.size(), 32); // make sure the subkeys are copied CompositeKey* compositeKey2 = compositeKey1->clone(); delete compositeKey1; QCOMPARE(compositeKey2->transform(QByteArray(32, '\0'), 1), transformed); delete compositeKey2; CompositeKey* compositeKey3 = new CompositeKey(); CompositeKey* compositeKey4 = new CompositeKey(); // test clear() compositeKey3->addKey(PasswordKey("test")); compositeKey3->clear(); QCOMPARE(compositeKey3->rawKey(), compositeKey4->rawKey()); // test assignment operator compositeKey3->addKey(PasswordKey("123")); *compositeKey4 = *compositeKey3; QCOMPARE(compositeKey3->rawKey(), compositeKey4->rawKey()); // test self-assignment *compositeKey3 = *compositeKey3; QCOMPARE(compositeKey3->rawKey(), compositeKey4->rawKey()); delete compositeKey3; delete compositeKey4; }
void DatabaseOpenWidget::openDatabase() { QSharedPointer<CompositeKey> masterKey = databaseKey(); if (!masterKey) { return; } m_ui->editPassword->setShowPassword(false); QCoreApplication::processEvents(); m_db.reset(new Database()); QString error; QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); bool ok = m_db->open(m_filename, masterKey, &error, false); QApplication::restoreOverrideCursor(); if (!ok) { m_ui->messageWidget->showMessage(error, MessageWidget::MessageType::Error); return; } if (m_db) { #ifdef WITH_XC_TOUCHID QHash<QString, QVariant> useTouchID = config()->get("UseTouchID").toHash(); // check if TouchID can & should be used to unlock the database next time if (m_ui->checkTouchID->isChecked() && TouchID::getInstance().isAvailable()) { // encrypt and store key blob if (TouchID::getInstance().storeKey(m_filename, PasswordKey(m_ui->editPassword->text()).rawKey())) { useTouchID.insert(m_filename, true); } } else { // when TouchID not available or unchecked, reset for the current database TouchID::getInstance().reset(m_filename); useTouchID.insert(m_filename, false); } config()->set("UseTouchID", useTouchID); #endif if (m_ui->messageWidget->isVisible()) { m_ui->messageWidget->animatedHide(); } emit dialogFinished(true); } else { m_ui->messageWidget->showMessage(error, MessageWidget::Error); m_ui->editPassword->setText(""); #ifdef WITH_XC_TOUCHID // unable to unlock database, reset TouchID for the current database TouchID::getInstance().reset(m_filename); #endif } }
void TestKeePass2Reader::testCompressed() { QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/Compressed.kdbx"); CompositeKey key; key.addKey(PasswordKey("")); KeePass2Reader reader; Database* db = reader.readDatabase(filename, key); QVERIFY(db); QVERIFY(!reader.hasError()); QCOMPARE(db->metadata()->name(), QString("Compressed")); QCOMPARE(db->compressionAlgo(), Database::CompressionGZip); delete db; }
void TestKeePass2Reader::testNonAscii() { QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/NonAscii.kdbx"); CompositeKey key; key.addKey(PasswordKey(QString::fromUtf8("\xce\x94\xc3\xb6\xd8\xb6"))); KeePass2Reader reader; Database* db = reader.readDatabase(filename, key); QVERIFY(db); QVERIFY(!reader.hasError()); QCOMPARE(db->metadata()->name(), QString("NonAsciiTest")); QCOMPARE(db->compressionAlgo(), Database::CompressionNone); delete db; }
void TestKeePass2Reader::testBrokenHeaderHash() { // The protected stream key has been modified in the header. // Make sure the database won't open. QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/BrokenHeaderHash.kdbx"); CompositeKey key; key.addKey(PasswordKey("")); KeePass2Reader reader; Database* db = reader.readDatabase(filename, key); QVERIFY(!db); QVERIFY(reader.hasError()); delete db; }
void TestKeePass2Reader::testFormat300() { QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/Format300.kdbx"); CompositeKey key; key.addKey(PasswordKey("a")); KeePass2Reader reader; Database* db = reader.readDatabase(filename, key); QVERIFY(db); QVERIFY(!reader.hasError()); QCOMPARE(db->rootGroup()->name(), QString("Format300")); QCOMPARE(db->metadata()->name(), QString("Test Database Format 0x00030000")); delete db; }
void ChangeMasterKeyWidget::generateKey() { m_key.clear(); if (m_ui->passwordGroup->isChecked()) { if (m_ui->enterPasswordEdit->text() == m_ui->repeatPasswordEdit->text()) { if (m_ui->enterPasswordEdit->text().isEmpty()) { if (MessageBox::question(this, tr("Question"), tr("Do you really want to use an empty string as password?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) { return; } } m_key.addKey(PasswordKey(m_ui->enterPasswordEdit->text())); } else { MessageBox::warning(this, tr("Error"), tr("Different passwords supplied.")); m_ui->enterPasswordEdit->setText(""); m_ui->repeatPasswordEdit->setText(""); return; } } if (m_ui->keyFileGroup->isChecked()) { FileKey fileKey; QString errorMsg; if (!fileKey.load(m_ui->keyFileCombo->currentText(), &errorMsg)) { MessageBox::critical(this, tr("Failed to set key file"), tr("Failed to set %1 as the Key file:\n%2") .arg(m_ui->keyFileCombo->currentText(), errorMsg)); return; } m_key.addKey(fileKey); } if (m_ui->challengeResponseGroup->isChecked()) { int i = m_ui->challengeResponseCombo->currentIndex(); i = m_ui->challengeResponseCombo->itemData(i).toInt(); YkChallengeResponseKey key(i); m_key.addChallengeResponseKey(key); } Q_EMIT editFinished(true); }
void TestKeePass2Writer::initTestCase() { Crypto::init(); CompositeKey key; key.addKey(PasswordKey("test")); m_dbOrg = new Database(); m_dbOrg->setKey(key); m_dbOrg->metadata()->setName("TESTDB"); Group* group = m_dbOrg->rootGroup(); group->setUuid(Uuid::random()); group->setNotes("I'm a note!"); Entry* entry = new Entry(); entry->setPassword(QString::fromUtf8("\xc3\xa4\xa3\xb6\xc3\xbc\xe9\x9b\xbb\xe7\xb4\x85")); entry->setUuid(Uuid::random()); entry->attributes()->set("test", "protectedTest", true); QVERIFY(entry->attributes()->isProtected("test")); entry->attachments()->set("myattach.txt", QByteArray("this is an attachment")); entry->attachments()->set("aaa.txt", QByteArray("also an attachment")); entry->setGroup(group); Group* groupNew = new Group(); groupNew->setUuid(Uuid::random()); groupNew->setName("TESTGROUP"); groupNew->setNotes("I'm a sub group note!"); groupNew->setParent(group); QBuffer buffer; buffer.open(QBuffer::ReadWrite); KeePass2Writer writer; writer.writeDatabase(&buffer, m_dbOrg); QVERIFY(!writer.error()); buffer.seek(0); KeePass2Reader reader; m_dbTest = reader.readDatabase(&buffer, key); QVERIFY(!reader.hasError()); QVERIFY(m_dbTest); }