update request id generation

Change-Id: I72d864385093a5f1d849d6e9cfe4e6d5ee2882ac
diff --git a/src/ca-module.cpp b/src/ca-module.cpp
index 322bbb5..fed30aa 100644
--- a/src/ca-module.cpp
+++ b/src/ca-module.cpp
@@ -48,8 +48,7 @@
   // load the config and create storage
   m_config.load(configPath);
   m_storage = CaStorage::createCaStorage(storageType, m_config.m_caItem.m_caPrefix, "");
-  random::generateSecureBytes(m_requestIdGenKey, 16);
-
+  random::generateSecureBytes(m_requestIdGenKey, 32);
   registerPrefix();
 }
 
@@ -326,23 +325,20 @@
   }
 
   // create new request instance
-  uint64_t requestIdData[2];
-  size_t idDataLen = 16;
-  Block certNameData = clientCert->getName().wireEncode();
-  hmac_sha_256(m_requestIdGenKey, 16, certNameData.value(), certNameData.value_size(), reinterpret_cast<uint8_t *>(requestIdData), &idDataLen);
-  std::stringstream ss;
-  ss << std::hex << std::noshowbase<< requestIdData[0] << requestIdData[1];
-
-  std::string requestId = ss.str();
-
-  CaState requestState(m_config.m_caItem.m_caPrefix, requestId, requestType, Status::BEFORE_CHALLENGE, *clientCert,
-                       makeBinaryBlock(tlv::ContentType_Key, aesKey, sizeof(aesKey)));
+  uint8_t requestIdData[32];
+  Block certNameTlv = clientCert->getName().wireEncode();
+  ndn_compute_hmac_sha256(certNameTlv.wire(), certNameTlv.size(), m_requestIdGenKey, 32, requestIdData);
+  CaState requestState(m_config.m_caItem.m_caPrefix, hexlify(requestIdData, 32),
+                      requestType, Status::BEFORE_CHALLENGE, *clientCert,
+                      makeBinaryBlock(tlv::ContentType_Key, aesKey, sizeof(aesKey)));
   try {
     m_storage->addRequest(requestState);
   }
   catch (const std::runtime_error& e) {
-    requestId = std::to_string(random::generateWord64());
-    m_storage->addRequest(requestState);
+    _LOG_ERROR("Duplicate Request ID: The same request has been seen before.");
+    m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::INVALID_PARAMETER,
+                                       "Duplicate Request ID: The same request has been seen before.."));
+    return;
   }
   Data result;
   result.setName(request.getName());
diff --git a/src/ca-module.hpp b/src/ca-module.hpp
index 8172688..ac2a741 100644
--- a/src/ca-module.hpp
+++ b/src/ca-module.hpp
@@ -109,7 +109,7 @@
   CaConfig m_config;
   unique_ptr<CaStorage> m_storage;
   security::v2::KeyChain& m_keyChain;
-  uint8_t m_requestIdGenKey[16];
+  uint8_t m_requestIdGenKey[32];
 
   std::list<RegisteredPrefixHandle> m_registeredPrefixHandles;
   std::list<InterestFilterHandle> m_interestFilterHandles;
diff --git a/src/crypto-support/crypto-helper.cpp b/src/crypto-support/crypto-helper.cpp
index 915dce2..76ae679 100644
--- a/src/crypto-support/crypto-helper.cpp
+++ b/src/crypto-support/crypto-helper.cpp
@@ -193,11 +193,11 @@
 int
 ndn_compute_hmac_sha256(const uint8_t* data, const unsigned data_length,
                         const uint8_t* key, const unsigned key_length,
-                        uint8_t* prk)
+                        uint8_t* result)
 {
   HMAC(EVP_sha256(), key, key_length,
        (unsigned char*)data, data_length,
-       (unsigned char*)prk, nullptr);
+       (unsigned char*)result, nullptr);
   return 0;
 }
 
@@ -374,48 +374,6 @@
   }
 }
 
-int
-hmac_sha_256(const uint8_t* key, size_t key_len,
-             const uint8_t* cleartext, size_t cleartext_len,
-             uint8_t* output, size_t* output_len)
-{
-    if (!key || !cleartext || !output) {
-        return -1;
-    }
-
-    auto private_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, key, key_len);
-    auto hmac_context = EVP_MD_CTX_new();
-    if (!private_key || !hmac_context) {
-        handleErrors("Cannot create and initialise the context when calling HMAC_CTX_new()");
-        return -1;
-    }
-
-    if (EVP_DigestSignInit(hmac_context, nullptr, EVP_sha256(), nullptr, private_key) != 1) {
-        handleErrors("Cannot initialize DigestSign when calling EVP_DigestSignInit()");
-        EVP_MD_CTX_free(hmac_context);
-        EVP_PKEY_free(private_key);
-        return -1;
-    }
-
-    if (EVP_DigestSignUpdate(hmac_context, cleartext, cleartext_len) != 1) {
-        handleErrors("Cannot update DigestSign when calling EVP_DigestSignUpdate()");
-        EVP_MD_CTX_free(hmac_context);
-        EVP_PKEY_free(private_key);
-        return -1;
-    }
-
-    if (EVP_DigestSignFinal(hmac_context, output, output_len) != 1) {
-        handleErrors("Cannot finish DigestSign when calling EVP_DigestSignFinal()");
-        EVP_MD_CTX_free(hmac_context);
-        EVP_PKEY_free(private_key);
-        return -1;
-    }
-
-    EVP_MD_CTX_free(hmac_context);
-    EVP_PKEY_free(private_key);
-    return 0;
-}
-
 void
 handleErrors(const std::string& errorInfo)
 {
diff --git a/src/crypto-support/crypto-helper.hpp b/src/crypto-support/crypto-helper.hpp
index 88f1519..95879b3 100644
--- a/src/crypto-support/crypto-helper.hpp
+++ b/src/crypto-support/crypto-helper.hpp
@@ -69,10 +69,19 @@
      int saltLen, uint8_t* okm, int okm_len,
      const uint8_t* info = INFO, int info_len = INFO_LEN);
 
+/**
+ * HMAC SHA 256 keyed hash function
+ * @param key the key for the function
+ * @param key_len the length of the key
+ * @param data the array to hmac
+ * @param data_length the length of the array
+ * @param result result. Enough memory (32 Bytes) must be allocated beforehand
+ * @return 0 if successful, -1 if failed
+ */
 int
 ndn_compute_hmac_sha256(const uint8_t* data, const unsigned data_length,
                         const uint8_t* key, const unsigned key_length,
-                        uint8_t* prk);
+                        uint8_t* result);
 
 /**
  * Authentication GCM 128 Encryption
diff --git a/src/ndncert-common.cpp b/src/ndncert-common.cpp
index 3e31596..439b5f5 100644
--- a/src/ndncert-common.cpp
+++ b/src/ndncert-common.cpp
@@ -97,5 +97,16 @@
   return json;
 }
 
+std::string
+hexlify(const uint8_t* bytes, size_t byteLen)
+{
+  std::stringstream ss;
+  ss << std::hex;
+  for (size_t i = 0; i < byteLen; i++) {
+    ss << std::setw(2) << std::setfill('0') << (int)bytes[i];
+  }
+  return ss.str();
+}
+
 }  // namespace ndncert
 }  // namespace ndn
diff --git a/src/ndncert-common.hpp b/src/ndncert-common.hpp
index c680923..4da43c9 100644
--- a/src/ndncert-common.hpp
+++ b/src/ndncert-common.hpp
@@ -170,6 +170,9 @@
 JsonSection
 convertString2Json(const std::string& jsonContent);
 
+std::string
+hexlify(const uint8_t* bytes, size_t byteLen);
+
 }  // namespace ndncert
 }  // namespace ndn
 
diff --git a/tests/unit-tests/ndncert-common.t.cpp b/tests/unit-tests/ndncert-common.t.cpp
new file mode 100644
index 0000000..40f1bb9
--- /dev/null
+++ b/tests/unit-tests/ndncert-common.t.cpp
@@ -0,0 +1,40 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2017-2020, Regents of the University of California.
+ *
+ * This file is part of ndncert, a certificate management system based on NDN.
+ *
+ * ndncert is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License along with
+ * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndncert authors and contributors.
+ */
+
+#include "ndncert-common.hpp"
+#include "test-common.hpp"
+
+namespace ndn {
+namespace ndncert {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(TestCommon)
+
+BOOST_AUTO_TEST_CASE(EncodingDecoding) {
+  const uint8_t str[] = {0xbc, 0x22, 0xf3, 0xf0, 0x5c, 0xc4, 0x0d, 0xb9,
+                         0x31, 0x1e, 0x41, 0x92, 0x96, 0x6f, 0xee, 0x92};
+  BOOST_CHECK_EQUAL(hexlify(str, sizeof(str)), "bc22f3f05cc40db9311e4192966fee92");
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestCommon
+
+} // namespace tests
+} // namespace ndncert
+} // namespace ndn