use unique ECDH state / Encryption key for request in CA
Change-Id: If9f5471664d2eec7562b963c40f404ecfa3e5269
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index 0c5373f..0cd35cc 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -247,9 +247,10 @@
}
// get server's ECDH pub key
- auto myEcdhPubKeyBase64 = m_ecdh.getBase64PubKey();
+ ECDHState ecdh;
+ auto myEcdhPubKeyBase64 = ecdh.getBase64PubKey();
try {
- m_ecdh.deriveSecret(peerKeyBase64);
+ ecdh.deriveSecret(peerKeyBase64);
}
catch (const std::exception& e) {
_LOG_ERROR("Cannot derive a shared secret using the provided ECDH key: " << e.what());
@@ -260,8 +261,9 @@
// generate salt for HKDF
auto saltInt = random::generateSecureWord64();
// hkdf
- hkdf(m_ecdh.context->sharedSecret, m_ecdh.context->sharedSecretLen,
- (uint8_t*)&saltInt, sizeof(saltInt), m_aesKey, sizeof(m_aesKey));
+ uint8_t aesKey[AES_128_KEY_LEN];
+ hkdf(ecdh.context->sharedSecret, ecdh.context->sharedSecretLen,
+ (uint8_t*)&saltInt, sizeof(saltInt), aesKey, sizeof(aesKey));
shared_ptr<security::v2::Certificate> clientCert = nullptr;
// parse certificate request
@@ -334,7 +336,8 @@
// create new request instance
std::string requestId = std::to_string(random::generateWord64());
- RequestState certRequest(m_config.m_caPrefix, requestId, requestType, Status::BEFORE_CHALLENGE, *clientCert);
+ RequestState certRequest(m_config.m_caPrefix, requestId, requestType, Status::BEFORE_CHALLENGE, *clientCert,
+ makeBinaryBlock(tlv::ContentType_Key, aesKey, sizeof(aesKey)));
m_storage->addRequest(certRequest);
Data result;
result.setName(request.getName());
@@ -379,7 +382,7 @@
// decrypt the parameters
Buffer paramTLVPayload;
try {
- paramTLVPayload = decodeBlockWithAesGcm128(request.getApplicationParameters(), m_aesKey,
+ paramTLVPayload = decodeBlockWithAesGcm128(request.getApplicationParameters(), certRequest.m_encryptionKey.value(),
(uint8_t*)"test", strlen("test"));
}
catch (const std::exception& e) {
@@ -450,7 +453,7 @@
Data result;
result.setName(request.getName());
result.setFreshnessPeriod(DEFAULT_DATA_FRESHNESS_PERIOD);
- auto contentBlock = encodeBlockWithAesGcm128(tlv::Content, m_aesKey, payload.value(),
+ auto contentBlock = encodeBlockWithAesGcm128(tlv::Content, certRequest.m_encryptionKey.value(), payload.value(),
payload.value_size(), (uint8_t*)"test", strlen("test"));
result.setContent(contentBlock);
m_keyChain.sign(result, signingByIdentity(m_config.m_caPrefix));
diff --git a/src/ca-module.hpp b/src/ca-module.hpp
index 3bb3a1e..c6b3e71 100644
--- a/src/ca-module.hpp
+++ b/src/ca-module.hpp
@@ -113,8 +113,6 @@
std::list<RegisteredPrefixHandle> m_registeredPrefixHandles;
std::list<InterestFilterHandle> m_interestFilterHandles;
- ECDHState m_ecdh;
- uint8_t m_aesKey[16] = {0};
};
} // namespace ndncert
diff --git a/src/ca-storage-detail/ca-sqlite.cpp b/src/ca-storage-detail/ca-sqlite.cpp
index 905bfa5..a0f24ec 100644
--- a/src/ca-storage-detail/ca-sqlite.cpp
+++ b/src/ca-storage-detail/ca-sqlite.cpp
@@ -50,7 +50,8 @@
challenge_tp TEXT,
remaining_tries INTEGER,
remaining_time INTEGER,
- challenge_secrets TEXT
+ challenge_secrets TEXT,
+ encryption_key BLOB NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS
CertRequestIdIndex ON CertRequests(request_id);
@@ -120,7 +121,7 @@
R"_SQLTEXT_(SELECT id, ca_name, status,
challenge_status, cert_request,
challenge_type, challenge_secrets,
- challenge_tp, remaining_tries, remaining_time, request_type
+ challenge_tp, remaining_tries, remaining_time, request_type, encryption_key
FROM CertRequests where request_id = ?)_SQLTEXT_");
statement.bind(1, requestId, SQLITE_TRANSIENT);
@@ -135,14 +136,15 @@
auto remainingTries = statement.getInt(8);
auto remainingTime = statement.getInt(9);
auto requestType = static_cast<RequestType>(statement.getInt(10));
+ auto encryptionKey = statement.getBlock(11);
if (challengeType != "") {
return RequestState(caName, requestId, requestType, status, cert,
challengeType, challengeStatus, time::fromIsoString(challengeTp),
remainingTries, time::seconds(remainingTime),
- convertString2Json(challengeSecrets));
+ convertString2Json(challengeSecrets), encryptionKey);
}
else {
- return RequestState(caName, requestId, requestType, status, cert);
+ return RequestState(caName, requestId, requestType, status, cert, encryptionKey);
}
}
else {
@@ -174,14 +176,15 @@
m_database,
R"_SQLTEXT_(INSERT INTO CertRequests (request_id, ca_name, status, request_type,
cert_key_name, cert_request, challenge_type, challenge_status, challenge_secrets,
- challenge_tp, remaining_tries, remaining_time)
- values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?))_SQLTEXT_");
+ challenge_tp, remaining_tries, remaining_time, encryption_key)
+ values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?))_SQLTEXT_");
statement.bind(1, request.m_requestId, SQLITE_TRANSIENT);
statement.bind(2, request.m_caPrefix.wireEncode(), SQLITE_TRANSIENT);
statement.bind(3, static_cast<int>(request.m_status));
statement.bind(4, static_cast<int>(request.m_requestType));
statement.bind(5, keyNameTlv, SQLITE_TRANSIENT);
statement.bind(6, request.m_cert.wireEncode(), SQLITE_TRANSIENT);
+ statement.bind(13, request.m_encryptionKey, SQLITE_TRANSIENT);
if (request.m_challengeState) {
statement.bind(7, request.m_challengeType, SQLITE_TRANSIENT);
statement.bind(8, request.m_challengeState->m_challengeStatus, SQLITE_TRANSIENT);
@@ -234,7 +237,7 @@
std::list<RequestState> result;
Sqlite3Statement statement(m_database, R"_SQLTEXT_(SELECT id, request_id, ca_name, status,
challenge_status, cert_key_name, cert_request, challenge_type, challenge_secrets,
- challenge_tp, remaining_tries, remaining_time, request_type
+ challenge_tp, remaining_tries, remaining_time, request_type, encryption_key
FROM CertRequests)_SQLTEXT_");
while (statement.step() == SQLITE_ROW) {
auto requestId = statement.getString(1);
@@ -248,14 +251,15 @@
auto remainingTries = statement.getInt(10);
auto remainingTime = statement.getInt(11);
auto requestType = static_cast<RequestType>(statement.getInt(12));
+ auto encryptionKey = statement.getBlock(13);
if (challengeType != "") {
result.push_back(RequestState(caName, requestId, requestType, status, cert,
challengeType, challengeStatus, time::fromIsoString(challengeTp),
remainingTries, time::seconds(remainingTime),
- convertString2Json(challengeSecrets)));
+ convertString2Json(challengeSecrets), encryptionKey));
}
else {
- result.push_back(RequestState(caName, requestId, requestType, status, cert));
+ result.push_back(RequestState(caName, requestId, requestType, status, cert, encryptionKey));
}
}
return result;
@@ -268,7 +272,7 @@
Sqlite3Statement statement(m_database,
R"_SQLTEXT_(SELECT id, request_id, ca_name, status,
challenge_status, cert_key_name, cert_request, challenge_type, challenge_secrets,
- challenge_tp, remaining_tries, remaining_time, request_type
+ challenge_tp, remaining_tries, remaining_time, request_type, encryption_key
FROM CertRequests WHERE ca_name = ?)_SQLTEXT_");
statement.bind(1, caName.wireEncode(), SQLITE_TRANSIENT);
@@ -284,14 +288,15 @@
auto remainingTries = statement.getInt(10);
auto remainingTime = statement.getInt(11);
auto requestType = static_cast<RequestType>(statement.getInt(12));
+ auto encryptionKey = statement.getBlock(13);
if (challengeType != "") {
result.push_back(RequestState(caName, requestId, requestType, status, cert,
challengeType, challengeStatus, time::fromIsoString(challengeTp),
remainingTries, time::seconds(remainingTime),
- convertString2Json(challengeSecrets)));
+ convertString2Json(challengeSecrets), encryptionKey));
}
else {
- result.push_back(RequestState(caName, requestId, requestType, status, cert));
+ result.push_back(RequestState(caName, requestId, requestType, status, cert, encryptionKey));
}
}
return result;
diff --git a/src/crypto-support/crypto-helper.hpp b/src/crypto-support/crypto-helper.hpp
index ad8aa22..1ff0149 100644
--- a/src/crypto-support/crypto-helper.hpp
+++ b/src/crypto-support/crypto-helper.hpp
@@ -30,6 +30,7 @@
static const int INFO_LEN = 10;
static const uint8_t INFO[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9};
+static const int AES_128_KEY_LEN = 16;
struct ECDH_CTX {
int EC_NID;
diff --git a/src/request-state.cpp b/src/request-state.cpp
index 1cc696c..7268d0e 100644
--- a/src/request-state.cpp
+++ b/src/request-state.cpp
@@ -43,19 +43,21 @@
}
RequestState::RequestState(const Name& caName, const std::string& requestId, RequestType requestType, Status status,
- const security::v2::Certificate& cert)
+ const security::v2::Certificate& cert, Block encryptionKey)
: m_caPrefix(caName)
, m_requestId(requestId)
, m_requestType(requestType)
, m_status(status)
, m_cert(cert)
+ , m_encryptionKey(std::move(encryptionKey))
{
}
RequestState::RequestState(const Name& caName, const std::string& requestId, RequestType requestType, Status status,
const security::v2::Certificate& cert, const std::string& challengeType,
const std::string& challengeStatus, const system_clock::TimePoint& challengeTp,
- size_t remainingTries, time::seconds remainingTime, JsonSection&& challengeSecrets)
+ size_t remainingTries, time::seconds remainingTime, JsonSection&& challengeSecrets,
+ Block encryptionKey)
: m_caPrefix(caName)
, m_requestId(requestId)
, m_requestType(requestType)
@@ -63,6 +65,7 @@
, m_cert(cert)
, m_challengeType(challengeType)
, m_challengeState(ChallengeState(challengeStatus, challengeTp, remainingTries, remainingTime, std::move(challengeSecrets)))
+ , m_encryptionKey(std::move(encryptionKey))
{
}
diff --git a/src/request-state.hpp b/src/request-state.hpp
index b5dc430..f8c0443 100644
--- a/src/request-state.hpp
+++ b/src/request-state.hpp
@@ -45,14 +45,16 @@
*
*/
class RequestState {
+
public:
RequestState();
RequestState(const Name& caName, const std::string& requestId, RequestType requestType, Status status,
- const security::v2::Certificate& cert);
+ const security::v2::Certificate& cert, Block m_encryptionKey);
RequestState(const Name& caName, const std::string& requestId, RequestType requestType, Status status,
const security::v2::Certificate& cert, const std::string& challengeType,
const std::string& challengeStatus, const system_clock::TimePoint& challengeTp,
- size_t remainingTries, time::seconds remainingTime, JsonSection&& challengeSecrets);
+ size_t remainingTries, time::seconds remainingTime, JsonSection&& challengeSecrets,
+ Block m_encryptionKey);
public:
Name m_caPrefix;
@@ -60,6 +62,7 @@
RequestType m_requestType;
Status m_status;
security::v2::Certificate m_cert;
+ Block m_encryptionKey;
std::string m_challengeType;
boost::optional<ChallengeState> m_challengeState;