ca+tools: configurable ca forwarding hint and ca-server interface improvement

Change-Id: I95cc6b2fb195f7c3625f14a4f8856abcf65022d9
diff --git a/src/detail/ca-profile.cpp b/src/detail/ca-profile.cpp
index 86d5be4..06dec71 100644
--- a/src/detail/ca-profile.cpp
+++ b/src/detail/ca-profile.cpp
@@ -35,6 +35,11 @@
   if (profile.caPrefix.empty()) {
     NDN_THROW(std::runtime_error("Cannot parse ca-prefix from the config file"));
   }
+  // Forwarding hint
+  profile.forwardingHint = Name(json.get(CONFIG_FORWARDING_HINT, ""));
+  if (profile.forwardingHint.empty()) {
+    profile.forwardingHint = Name(profile.caPrefix).append("CA");
+  }
   // CA info
   profile.caInfo = json.get(CONFIG_CA_INFO, "");
   // CA max validity period
diff --git a/src/detail/ca-profile.hpp b/src/detail/ca-profile.hpp
index 6ca9b19..09e1303 100644
--- a/src/detail/ca-profile.hpp
+++ b/src/detail/ca-profile.hpp
@@ -37,6 +37,7 @@
 const std::string CONFIG_SUPPORTED_CHALLENGES = "supported-challenges";
 const std::string CONFIG_CHALLENGE = "challenge";
 const std::string CONFIG_CERTIFICATE = "certificate";
+const std::string CONFIG_FORWARDING_HINT = "forwarding-hint";
 const std::string CONFIG_REDIRECTION = "redirect-to";
 const std::string CONFIG_NAME_ASSIGNMENT = "name-assignment";
 const std::string CONFIG_REDIRECTION_POLICY_TYPE = "policy-type";
@@ -65,6 +66,10 @@
    */
   Name caPrefix;
   /**
+   * @brief Forwarding hint for requesters to retrieve issued certificates.
+   */
+  Name forwardingHint;
+  /**
    * @brief CA Information.
    */
   std::string caInfo;
diff --git a/src/detail/challenge-encoder.cpp b/src/detail/challenge-encoder.cpp
index 9f36042..f42460c 100644
--- a/src/detail/challenge-encoder.cpp
+++ b/src/detail/challenge-encoder.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2017-2022, Regents of the University of California.
+ * Copyright (c) 2017-2024, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -23,7 +23,7 @@
 namespace ndncert::challengetlv {
 
 Block
-encodeDataContent(ca::RequestState& request, const Name& issuedCertName)
+encodeDataContent(ca::RequestState& request, const Name& issuedCertName, const Name& forwardingHint)
 {
   Block response(tlv::EncryptedPayload);
   response.push_back(ndn::makeNonNegativeIntegerBlock(tlv::Status, static_cast<uint64_t>(request.status)));
@@ -41,7 +41,7 @@
   }
   if (!issuedCertName.empty()) {
     response.push_back(makeNestedBlock(tlv::IssuedCertName, issuedCertName));
-    response.push_back(makeNestedBlock(ndn::tlv::ForwardingHint, Name(request.caPrefix).append("CA")));
+    response.push_back(makeNestedBlock(ndn::tlv::ForwardingHint, forwardingHint));
   }
   response.encode();
 
diff --git a/src/detail/challenge-encoder.hpp b/src/detail/challenge-encoder.hpp
index 5c502d2..2329928 100644
--- a/src/detail/challenge-encoder.hpp
+++ b/src/detail/challenge-encoder.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2017-2022, Regents of the University of California.
+ * Copyright (c) 2017-2024, Regents of the University of California.
  *
  * This file is part of ndncert, a certificate management system based on NDN.
  *
@@ -27,7 +27,8 @@
 namespace ndncert::challengetlv {
 
 Block
-encodeDataContent(ca::RequestState& request, const Name& issuedCertName = Name());
+encodeDataContent(ca::RequestState& request, const Name& issuedCertName = Name(),
+                  const Name& forwardingHint = Name());
 
 void
 decodeDataContent(const Block& contentBlock, requester::Request& state);