// Open key4.db and check encoded PBE algorithm and iteration count. // Compare bytes against the expected values to avoid ASN.1 here.
std::string key_db = mNSSDBDir.GetPath() + "/key4.db";
// Provide buffers of sufficient size, so that token // will write the data. This is annoying, but PK11_GetAttributes // won't allocate in the cases below when a single attribute // is missing. So, just put them all on the stack. unsignedchar buf1[100]; unsignedchar buf2[100];
CK_ATTRIBUTE template_attrs[] = {{0xffffffffUL, buf1, sizeof(buf1)},
{0xfffffffeUL, buf2, sizeof(buf2)}};
SECStatus rv =
PK11_ReadRawAttributes(nullptr, PK11_TypeGeneric, obj.get(),
template_attrs, PR_ARRAY_SIZE(template_attrs));
EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(SEC_ERROR_BAD_DATA, PORT_GetError());
// MSVC rewards -1UL with a C4146 warning...
ASSERT_EQ(0UL, template_attrs[0].ulValueLen + 1);
ASSERT_EQ(0UL, template_attrs[1].ulValueLen + 1);
}
// The size limit for a password is 500 characters as defined in pkcs11i.h
TEST_F(SoftokenTest, CreateObjectChangeToBigPassword) {
ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
ASSERT_TRUE(slot);
EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, nullptr));
EXPECT_EQ(
SECSuccess,
PK11_ChangePW(slot.get(), "", "rUIFIFr2bxKnbJbitsfkyqttpk6vCJzlYMNxcxXcaN37gSZKbLk763X7iR" "yeVNWZHQ02lSF69HYjzTyPW3318ZD0DBFMMbALZ8ZPZP73CIo5uIQlaowV" "IbP8eOhRYtGUqoLGlcIFNEYogV8Q3GN58VeBMs0KxrIOvPQ9s8SnYYkqvt" "zzgntmAvCgvk64x6eQf0okHwegd5wi6m0WVJytEepWXkP9J629FSa5kNT8" "FvL3jvslkiImzTNuTvl32fQDXXMSc8vVk5Q3mH7trMZM0VDdwHWYERjHbz" "kGxFgp0VhediHx7p9kkz6H6ac4et9sW4UkTnN7xhYc1Zr17wRSk2heQtcX" "oZJGwuzhiKm8A8wkuVxms6zO56P4JORIk8oaUW6lyNTLo2kWWnTA"));
EXPECT_EQ(SECSuccess, PK11_Logout(slot.get()));
ScopedPK11GenericObject obj(PK11_CreateGenericObject(
slot.get(), attributes, PR_ARRAY_SIZE(attributes), true));
EXPECT_EQ(nullptr, obj);
}
TEST_F(SoftokenTest, CreateObjectChangeToEmptyPassword) {
ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
ASSERT_TRUE(slot);
EXPECT_EQ(SECSuccess, PK11_InitPin(slot.get(), nullptr, "password"));
EXPECT_EQ(SECSuccess, PK11_ChangePW(slot.get(), "password", "")); // PK11_Logout returnes an error and SEC_ERROR_TOKEN_NOT_LOGGED_IN if the user // is not "logged in".
EXPECT_EQ(SECFailure, PK11_Logout(slot.get()));
EXPECT_EQ(SEC_ERROR_TOKEN_NOT_LOGGED_IN, PORT_GetError());
ScopedPK11GenericObject obj(PK11_CreateGenericObject(
slot.get(), attributes, PR_ARRAY_SIZE(attributes), true)); // Because there's no password we can't logout and the operation should have // succeeded.
EXPECT_NE(nullptr, obj);
}
// We should be able to read CRLF, LF and CR. // During the Initialization of the NSS Database, is called a function to load // PKCS11 modules defined in pkcs11.txt. This file is read to get the // specifications, parse them and load the modules. Here we are ensuring that // the parsing will work correctly, independent of the breaking line format of // pkcs11.txt file, which could vary depending where it was created. // If the parsing is not well interpreted, the database cannot initialize.
TEST_F(SoftokenTest, CreateObjectReadBreakLine) { const std::string path = mNSSDBDir.GetPath(); const std::string dbname_in = path + "/pkcs11.txt"; const std::string dbname_out_cr = path + "/pkcs11_cr.txt"; const std::string dbname_out_crlf = path + "/pkcs11_crlf.txt"; const std::string dbname_out_lf = path + "/pkcs11_lf.txt";
class SoftokenPasswordChangeTest
: public SoftokenTest, public ::testing::WithParamInterface<PasswordPair> {};
TEST_P(SoftokenPasswordChangeTest, KeepTrustAfterPasswordChange) { const PasswordPair &passwords = GetParam();
ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
ASSERT_TRUE(slot); // Set a password.
EXPECT_EQ(SECSuccess,
PK11_InitPin(slot.get(), nullptr, passwords.mInitialPassword));
SECItem certDERItem = {siBuffer, certDER, sizeof(certDER)}; // Import a certificate.
ScopedCERTCertificate cert(CERT_NewTempCertificate(
CERT_GetDefaultCertDB(), &certDERItem, nullptr, true, true));
EXPECT_TRUE(cert);
SECStatus result =
PK11_ImportCert(slot.get(), cert.get(), CK_INVALID_HANDLE, "test", false);
EXPECT_EQ(SECSuccess, result); // Set a trust value.
CERTCertTrust trust = {CERTDB_TRUSTED_CLIENT_CA | CERTDB_NS_TRUSTED_CA |
CERTDB_TRUSTED_CA | CERTDB_VALID_CA,
0, 0};
result = CERT_ChangeCertTrust(nullptr, cert.get(), &trust);
EXPECT_EQ(SECSuccess, result); // Release the certificate to ensure we get it from the DB rather than an // in-memory cache, below.
cert = nullptr; // Change the password.
result = PK11_ChangePW(slot.get(), passwords.mInitialPassword,
passwords.mSecondPassword);
EXPECT_EQ(SECSuccess, result); // Look up the certificate again.
ScopedCERTCertificate newCert(
PK11_FindCertFromDERCertItem(slot.get(), &certDERItem, nullptr));
EXPECT_TRUE(newCert.get()); // The trust should be the same as before.
CERTCertTrust newTrust = {0, 0, 0};
result = CERT_GetCertTrust(newCert.get(), &newTrust);
EXPECT_EQ(SECSuccess, result);
EXPECT_EQ(trust.sslFlags, newTrust.sslFlags);
EXPECT_EQ(trust.emailFlags, newTrust.emailFlags);
EXPECT_EQ(trust.objectSigningFlags, newTrust.objectSigningFlags);
}
staticconst PasswordPair PASSWORD_CHANGE_TESTS[] = {
{"password", ""}, // non-empty to empty password
{"", "password"}, // empty to non-empty password
{"password", "password2"}, // non-empty to non-empty password
};
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
EXPECT_TRUE(slot); if (!slot) return SECFailure;
/* create a private/public key pair in with the given params */
SECKEYPublicKey *pub_tmp = nullptr;
ScopedSECKEYPrivateKey priv_key(
PK11_GenerateKeyPair(slot.get(), CKM_DH_PKCS_KEY_PAIR_GEN, &dh_params,
&pub_tmp, PR_FALSE, PR_TRUE, nullptr)); if ((genFailOK) && ((priv_key.get() == nullptr) || (pub_tmp == nullptr))) { return SECFailure;
}
EXPECT_NE(nullptr, priv_key.get())
<< "PK11_GenerateKeyPair failed: " << PORT_ErrorToName(PORT_GetError());
EXPECT_NE(nullptr, pub_tmp); if ((priv_key.get() == nullptr) || (pub_tmp == nullptr)) return SECFailure;
ScopedSECKEYPublicKey pub_key(pub_tmp);
ScopedSECKEYPublicKey peer_pub_key_manager(nullptr);
SECKEYPublicKey *peer_pub_key = pub_key.get();
/* if a subprime has been given set it on the PKCS #11 key */ if (params->subPrime.data != nullptr) {
SECStatus rv;
EXPECT_EQ(SECSuccess, rv = PK11_WriteRawAttribute(
PK11_TypePrivKey, priv_key.get(), CKA_SUBPRIME,
(SECItem *)¶ms->subPrime))
<< "PK11_WriteRawAttribute failed: "
<< PORT_ErrorToString(PORT_GetError()); if (rv != SECSuccess) { return rv;
}
}
/* find if we weren't passed a public value in, use the
* one we just generated */ if (pub_key_value && pub_key_value->data) {
peer_pub_key = SECKEY_CopyPublicKey(pub_key.get());
EXPECT_NE(nullptr, peer_pub_key); if (peer_pub_key == nullptr) { return SECFailure;
}
peer_pub_key->u.dh.publicValue = *pub_key_value;
peer_pub_key_manager.reset(peer_pub_key);
}
/* now do the derive. time it and return the time if
* the caller requested it. */ auto start = high_resolution_clock::now();
ScopedPK11SymKey derivedKey(PK11_PubDerive(
priv_key.get(), peer_pub_key, PR_FALSE, nullptr, nullptr,
CKM_DH_PKCS_DERIVE, CKM_HKDF_DERIVE, CKA_DERIVE, 32, nullptr)); auto stop = high_resolution_clock::now(); if (!derivedKey) {
std::cerr << "PK11_PubDerive failed: "
<< PORT_ErrorToString(PORT_GetError()) << std::endl;
}
if (time) { auto duration = duration_cast<microseconds>(stop - start);
*time = duration.count();
} return derivedKey ? SECSuccess : SECFailure;
}
class SoftokenDhTest : public SoftokenTest { protected:
SoftokenDhTest() : SoftokenTest("SoftokenDhTest.d-") {} #ifdef NSS_USE_TIMING_CODE
time_t reference_time[CLASS_LAST] = {0}; #endif
constchar *param_value(DhParamType param_type) { switch (param_type) { case TLS_APPROVED: return"TLS_APPROVED"; case IKE_APPROVED: return"IKE_APPROVED"; case SAFE_PRIME: return"SAFE_PRIME"; case SAFE_PRIME_WITH_SUBPRIME: return"SAFE_PRIME_WITH_SUBPRIME"; case KNOWN_SUBPRIME: return"KNOWN_SUBPRIME"; case UNKNOWN_SUBPRIME: return"UNKNOWN_SUBPRIME"; case WRONG_SUBPRIME: return"WRONG_SUBPRIME"; case BAD_PUB_KEY: return"BAD_PUB_KEY";
} return"**Invalid**";
}
constchar *key_value(DhKeyClass key_class) { switch (key_class) { case CLASS_1536: return"CLASS_1536"; case CLASS_2048: return"CLASS_2048"; case CLASS_3072: return"CLASS_3072"; case CLASS_4096: return"CLASS_4096"; case CLASS_6144: return"CLASS_6144"; case CLASS_8192: return"CLASS_8192"; case CLASS_LAST: break;
} return"**Invalid**";
}
class SoftokenDhValidate : public SoftokenDhTest, public ::testing::WithParamInterface<DhTestVector> {
};
/* test the DH validation process. In non-fips mode, only BAD_PUB_KEY tests
* should fail */
TEST_P(SoftokenDhValidate, DhVectors) { const DhTestVector dhTestValues = GetParam();
std::string testId = (char *)(dhTestValues.id);
std::string err = "Test(" + testId + ") failed";
SECStatus rv;
time_t time;
auto it = passwords.begin(); auto prev_it = it;
SECStatus rv = PK11_InitPin(slot.get(), nullptr, (*it).c_str()); if (it + 1 == passwords.end())
EXPECT_EQ(SECFailure, rv); else
EXPECT_EQ(SECSuccess, rv); for (it++; it != passwords.end(); it++, prev_it++) {
rv = PK11_ChangePW(slot.get(), (*prev_it).c_str(), (*it).c_str()); if (it + 1 == passwords.end())
EXPECT_EQ(SECFailure, rv); else
EXPECT_EQ(SECSuccess, rv);
}
}
class SoftokenFipsDhValidate
: public SoftokenFipsDhTest, public ::testing::WithParamInterface<DhTestVector> {};
/* test the DH validation process. In fips mode, primes with unknown
* subprimes, and all sorts of bad public keys should fail */
TEST_P(SoftokenFipsDhValidate, DhVectors) { const DhTestVector dhTestValues = GetParam();
std::string testId = (char *)(dhTestValues.id);
std::string err = "Test(" + testId + ") failed";
time_t time;
PRBool genFailOK = PR_FALSE;
SECStatus rv;
switch (dhTestValues.param_type) { case TLS_APPROVED: case IKE_APPROVED:
EXPECT_EQ(SECSuccess, rv) << err; #ifdef NSS_USE_TIMING_CODE
EXPECT_LE(time, reference_time[dhTestValues.key_class]) << err; #endif break; case SAFE_PRIME: case SAFE_PRIME_WITH_SUBPRIME: case KNOWN_SUBPRIME: case UNKNOWN_SUBPRIME: case WRONG_SUBPRIME: case BAD_PUB_KEY:
EXPECT_EQ(SECFailure, rv) << err; break;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.