Revocation: fixes and combine with New
Change-Id: I68bc117d1ae35d7dc4c754c76bf88003ebc637b5
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index 5201e31..9e9bf61 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -226,7 +226,20 @@
void
CaModule::onNew(const Interest& request)
{
- // NEW Naming Convention: /<CA-prefix>/CA/NEW/[SignedInterestParameters_Digest]
+ // NEW Naming Convention: /<CA-prefix>/CA/NEW/[SignedInterestParameters_Digest]
+ onRequestInit(request, REQUEST_TYPE_NEW);
+}
+
+void
+CaModule::onRevoke(const Interest& request)
+{
+ // REVOKE Naming Convention: /<CA-prefix>/CA/REVOKE/[SignedInterestParameters_Digest]
+ onRequestInit(request, REQUEST_TYPE_REVOKE);
+}
+
+void
+CaModule::onRequestInit(const Interest& request, int requestType)
+{
// get ECDH pub key and cert request
const auto& parameterTLV = request.getApplicationParameters();
parameterTLV.parse();
@@ -258,52 +271,80 @@
hkdf(m_ecdh.context->sharedSecret, m_ecdh.context->sharedSecretLen,
(uint8_t*)&saltInt, sizeof(saltInt), m_aesKey, sizeof(m_aesKey));
- // parse certificate request
- Block cert_req = parameterTLV.get(tlv_cert_request);
- cert_req.parse();
-
shared_ptr<security::v2::Certificate> clientCert = nullptr;
- try {
- security::v2::Certificate cert = security::v2::Certificate(cert_req.get(tlv::Data));
- clientCert = make_shared<security::v2::Certificate>(cert);
- }
- catch (const std::exception& e) {
- _LOG_ERROR("Unrecognized certificate request: " << e.what());
- return;
- }
- // check the validity period
- auto expectedPeriod = clientCert->getValidityPeriod().getPeriod();
- auto currentTime = time::system_clock::now();
- if (expectedPeriod.first < currentTime - REQUEST_VALIDITY_PERIOD_NOT_BEFORE_GRACE_PERIOD) {
- _LOG_ERROR("Client requests a too old notBefore timepoint.");
- return;
- }
- if (expectedPeriod.second > currentTime + m_config.m_maxValidityPeriod ||
- expectedPeriod.second <= expectedPeriod.first) {
- _LOG_ERROR("Client requests an invalid validity period or a notAfter timepoint beyond the allowed time period.");
- return;
- }
+ if (requestType == REQUEST_TYPE_NEW) {
+ // parse certificate request
+ Block cert_req = parameterTLV.get(tlv_cert_request);
+ cert_req.parse();
- // verify the self-signed certificate, the request, and the token
- if (!m_config.m_caPrefix.isPrefixOf(clientCert->getName()) // under ca prefix
- || !security::v2::Certificate::isValidName(clientCert->getName()) // is valid cert name
- || clientCert->getName().size() < m_config.m_caName.size() + IS_SUBNAME_MIN_OFFSET) {
- _LOG_ERROR("Invalid self-signed certificate name " << clientCert->getName());
- return;
- }
- if (!security::verifySignature(*clientCert, *clientCert)) {
- _LOG_ERROR("Cert request with bad signature.");
- return;
- }
- if (!security::verifySignature(request, *clientCert)) {
- _LOG_ERROR("Interest with bad signature.");
- return;
+ try {
+ security::v2::Certificate cert = security::v2::Certificate(cert_req.get(tlv::Data));
+ clientCert = make_shared<security::v2::Certificate>(cert);
+ }
+ catch (const std::exception &e) {
+ _LOG_ERROR("Unrecognized certificate request: " << e.what());
+ return;
+ }
+ // check the validity period
+ auto expectedPeriod = clientCert->getValidityPeriod().getPeriod();
+ auto currentTime = time::system_clock::now();
+ if (expectedPeriod.first < currentTime - REQUEST_VALIDITY_PERIOD_NOT_BEFORE_GRACE_PERIOD) {
+ _LOG_ERROR("Client requests a too old notBefore timepoint.");
+ return;
+ }
+ if (expectedPeriod.second > currentTime + m_config.m_maxValidityPeriod ||
+ expectedPeriod.second <= expectedPeriod.first) {
+ _LOG_ERROR("Client requests an invalid validity period or a notAfter timepoint beyond the allowed time period.");
+ return;
+ }
+
+ // verify the self-signed certificate, the request, and the token
+ if (!m_config.m_caPrefix.isPrefixOf(clientCert->getName()) // under ca prefix
+ || !security::v2::Certificate::isValidName(clientCert->getName()) // is valid cert name
+ || clientCert->getName().size() < m_config.m_caName.size() + IS_SUBNAME_MIN_OFFSET) {
+ _LOG_ERROR("Invalid self-signed certificate name " << clientCert->getName());
+ return;
+ }
+ if (!security::verifySignature(*clientCert, *clientCert)) {
+ _LOG_ERROR("Cert request with bad signature.");
+ return;
+ }
+ if (!security::verifySignature(request, *clientCert)) {
+ _LOG_ERROR("Interest with bad signature.");
+ return;
+ }
+ } else if (requestType == REQUEST_TYPE_REVOKE) {
+ // parse certificate request
+ Block cert_revoke = parameterTLV.get(tlv_cert_to_revoke);
+ cert_revoke.parse();
+
+ try {
+ security::v2::Certificate cert = security::v2::Certificate(cert_revoke.get(tlv::Data));
+ clientCert = make_shared<security::v2::Certificate>(cert);
+ }
+ catch (const std::exception &e) {
+ _LOG_ERROR("Unrecognized certificate: " << e.what());
+ return;
+ }
+
+ // verify the certificate
+ if (!m_config.m_caName.isPrefixOf(clientCert->getName()) // under ca prefix
+ || !security::v2::Certificate::isValidName(clientCert->getName()) // is valid cert name
+ || clientCert->getName().size() < m_config.m_caName.size() + IS_SUBNAME_MIN_OFFSET) {
+ _LOG_ERROR("Invalid certificate name " << clientCert->getName());
+ return;
+ }
+ const auto& cert = m_keyChain.getPib().getIdentity(m_config.m_caName).getDefaultKey().getDefaultCertificate();
+ if (!security::verifySignature(*clientCert, cert)) {
+ _LOG_ERROR("Cert request with bad signature.");
+ return;
+ }
}
// create new request instance
std::string requestId = std::to_string(random::generateWord64());
- CertificateRequest certRequest(m_config.m_caPrefix, requestId, REQUEST_TYPE_NEW, STATUS_BEFORE_CHALLENGE, *clientCert);
+ CertificateRequest certRequest(m_config.m_caPrefix, requestId, requestType, STATUS_BEFORE_CHALLENGE, *clientCert);
try {
m_storage->addRequest(certRequest);
@@ -316,10 +357,17 @@
Data result;
result.setName(request.getName());
result.setFreshnessPeriod(DEFAULT_DATA_FRESHNESS_PERIOD);
- result.setContent(NEW::encodeDataContent(myEcdhPubKeyBase64,
- std::to_string(saltInt),
- certRequest,
- m_config.m_supportedChallenges));
+ if (requestType == REQUEST_TYPE_NEW) {
+ result.setContent(NEW::encodeDataContent(myEcdhPubKeyBase64,
+ std::to_string(saltInt),
+ certRequest,
+ m_config.m_supportedChallenges));
+ } else if (requestType == REQUEST_TYPE_REVOKE) {
+ result.setContent(REVOKE::encodeDataContent(myEcdhPubKeyBase64,
+ std::to_string(saltInt),
+ certRequest,
+ m_config.m_supportedChallenges));
+ }
m_keyChain.sign(result, signingByIdentity(m_config.m_caPrefix));
m_face.put(result);
@@ -452,91 +500,6 @@
}
}
-void
-CaModule::onRevoke(const Interest& request)
-{
- // NEW Naming Convention: /<CA-prefix>/CA/REVOKE/[SignedInterestParameters_Digest]
- // get ECDH pub key and cert request
- const auto& parameterJson = jsonFromBlock(request.getApplicationParameters());
- if (parameterJson.empty()) {
- _LOG_ERROR("Empty JSON obtained from the Interest parameter.");
- return;
- }
- std::string peerKeyBase64 = parameterJson.get(JSON_CLIENT_ECDH, "");
- if (peerKeyBase64 == "") {
- _LOG_ERROR("Empty JSON_CLIENT_ECDH obtained from the Interest parameter.");
- return;
- }
-
- // get server's ECDH pub key
- auto myEcdhPubKeyBase64 = m_ecdh.getBase64PubKey();
- try {
- m_ecdh.deriveSecret(peerKeyBase64);
- }
- catch (const std::exception& e) {
- _LOG_ERROR("Cannot derive a shared secret using the provided ECDH key: " << e.what());
- return;
- }
-
- // parse certificate request
- std::string certRevokeStr = parameterJson.get(JSON_CLIENT_CERT_REVOKE, "");
- shared_ptr<security::v2::Certificate> clientCert = nullptr;
- try {
- std::stringstream ss(certRevokeStr);
- clientCert = io::load<security::v2::Certificate>(ss);
- }
- catch (const std::exception& e) {
- _LOG_ERROR("Unrecognized revocation request: " << e.what());
- return;
- }
-
- // verify the certificate
- if (!m_config.m_caName.isPrefixOf(clientCert->getName()) // under ca prefix
- || !security::v2::Certificate::isValidName(clientCert->getName()) // is valid cert name
- || clientCert->getName().size() != m_config.m_caName.size() + IS_SUBNAME_MIN_OFFSET) {
- _LOG_ERROR("Invalid certificate name " << clientCert->getName());
- return;
- }
- const auto& cert = m_keyChain.getPib().getIdentity(m_config.m_caName).getDefaultKey().getDefaultCertificate();
- if (!security::verifySignature(*clientCert, cert)) {
- _LOG_ERROR("Cert request with bad signature.");
- return;
- }
-
- // 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));
-
- // create new request instance
- std::string requestId = std::to_string(random::generateWord64());
- CertificateRequest certRequest(m_config.m_caName, requestId, REQUEST_TYPE_REVOKE, STATUS_BEFORE_CHALLENGE,
- *clientCert);
- try {
- m_storage->addRequest(certRequest);
- }
- catch (const std::exception& e) {
- _LOG_ERROR("Cannot add new request instance into the storage: " << e.what());
- return;
- }
-
- Data result;
- result.setName(request.getName());
- result.setFreshnessPeriod(DEFAULT_DATA_FRESHNESS_PERIOD);
- result.setContent(REVOKE::encodeDataContent(myEcdhPubKeyBase64,
- std::to_string(saltInt),
- certRequest,
- m_config.m_supportedChallenges));
- m_keyChain.sign(result, signingByIdentity(m_config.m_caPrefix));
- m_face.put(result);
-
- if (m_config.m_statusUpdateCallback) {
- m_config.m_statusUpdateCallback(certRequest);
- }
-}
-
-
security::v2::Certificate
CaModule::issueCertificate(const CertificateRequest& certRequest)
{