diff --git a/ca.conf.sample b/ca.conf.sample index 003da8e..393cd4a 100644 --- a/ca.conf.sample +++ b/ca.conf.sample @@ -19,7 +19,9 @@ "redirect-to": [ { "ca-prefix": "/ndn/edu/ucla", - "certificate": "Bv0BNQcwCANuZG4IA2VkdQgEdWNsYQgDS0VZCAgAdGt6D7S2VAgEc2VsZggJ/QAAAX5lZMOiFAkYAQIZBAA27oAVWzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOKmvwHmK5t+MhMPgft4qmKC7YF9I6UM/o7GFa4BjZQknsqLvxdW2zIAF+iPPHJV0eVAijX6bYrQobuomiWZAY0WUBsBAxwhBx8IA25kbggDZWR1CAR1Y2xhCANLRVkICAB0a3oPtLZU/QD9Jv0A/g8xOTcwMDEwMVQwMDAwMDD9AP8PMjA0MjAxMTJUMDAxNjQ5F0cwRQIgBF/HS0j1DMo/dIILv/6IMUmMAhVtS3m97YgS8tsBhC0CIQCgEm0e6KoBCyV6PiueN9YW9zSSkdg8MLCxsyduP8tRsQ==" + "certificate": "Bv0BNQcwCANuZG4IA2VkdQgEdWNsYQgDS0VZCAgAdGt6D7S2VAgEc2VsZggJ/QAAAX5lZMOiFAkYAQIZBAA27oAVWzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOKmvwHmK5t+MhMPgft4qmKC7YF9I6UM/o7GFa4BjZQknsqLvxdW2zIAF+iPPHJV0eVAijX6bYrQobuomiWZAY0WUBsBAxwhBx8IA25kbggDZWR1CAR1Y2xhCANLRVkICAB0a3oPtLZU/QD9Jv0A/g8xOTcwMDEwMVQwMDAwMDD9AP8PMjA0MjAxMTJUMDAxNjQ5F0cwRQIgBF/HS0j1DMo/dIILv/6IMUmMAhVtS3m97YgS8tsBhC0CIQCgEm0e6KoBCyV6PiueN9YW9zSSkdg8MLCxsyduP8tRsQ==", + "policy-type": "email", + "policy-param": "g.ucla.edu" }, { "ca-prefix": "/ndn/edu/ucla/cs", diff --git a/src/ca-module.cpp b/src/ca-module.cpp index 7f51eba..09c0b9c 100644 --- a/src/ca-module.cpp +++ b/src/ca-module.cpp @@ -441,7 +441,8 @@ CaModule::onChallenge(const Interest& request) requestState->status = Status::SUCCESS; m_storage->deleteRequest(requestState->requestId); - payload = challengetlv::encodeDataContent(*requestState, issuedCert.getName()); + payload = challengetlv::encodeDataContent(*requestState, issuedCert.getName(), + m_config.caProfile.forwardingHint); NDN_LOG_TRACE("Challenge succeeded. Certificate has been issued: " << issuedCert.getName()); } else if (requestState->requestType == RequestType::REVOKE) { 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 @@ CaProfile::fromJson(const JsonSection& json) 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_PROBE_PARAMETER = "probe-parameter-key"; 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"; @@ -64,6 +65,10 @@ class CaProfile * @brief CA Name prefix (without /CA suffix). */ Name caPrefix; + /** + * @brief Forwarding hint for requesters to retrieve issued certificates. + */ + Name forwardingHint; /** * @brief CA Information. */ 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(request.status))); @@ -41,7 +41,7 @@ encodeDataContent(ca::RequestState& request, const Name& issuedCertName) } 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); diff --git a/tests/unit-tests/config-files/config-ca-1 b/tests/unit-tests/config-files/config-ca-1 index 8ea5d38..044260b 100644 --- a/tests/unit-tests/config-files/config-ca-1 +++ b/tests/unit-tests/config-files/config-ca-1 @@ -1,5 +1,6 @@ { "ca-prefix": "/ndn", + "forwarding-hint": "/repo", "ca-info": "ndn testbed ca", "max-validity-period": "864000", "max-suffix-length": 3, diff --git a/tests/unit-tests/configuration.t.cpp b/tests/unit-tests/configuration.t.cpp index ec43b17..00f8ba5 100644 --- a/tests/unit-tests/configuration.t.cpp +++ b/tests/unit-tests/configuration.t.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. * @@ -33,6 +33,7 @@ BOOST_AUTO_TEST_CASE(CaConfigFile) ca::CaConfig config; config.load("tests/unit-tests/config-files/config-ca-1"); BOOST_CHECK_EQUAL(config.caProfile.caPrefix, "/ndn"); + BOOST_CHECK_EQUAL(config.caProfile.forwardingHint, "/repo"); BOOST_CHECK_EQUAL(config.caProfile.caInfo, "ndn testbed ca"); BOOST_CHECK_EQUAL(config.caProfile.maxValidityPeriod, time::seconds(864000)); BOOST_CHECK_EQUAL(*config.caProfile.maxSuffixLength, 3); @@ -43,6 +44,7 @@ BOOST_AUTO_TEST_CASE(CaConfigFile) config.load("tests/unit-tests/config-files/config-ca-2"); BOOST_CHECK_EQUAL(config.caProfile.caPrefix, "/ndn"); + BOOST_CHECK_EQUAL(config.caProfile.forwardingHint, "/ndn/CA"); BOOST_CHECK_EQUAL(config.caProfile.caInfo, "missing max validity period, max suffix length, and probe"); BOOST_CHECK_EQUAL(config.caProfile.maxValidityPeriod, time::seconds(86400)); BOOST_CHECK(!config.caProfile.maxSuffixLength.has_value()); diff --git a/tools/ndncert-ca-server.cpp b/tools/ndncert-ca-server.cpp index a683a9f..1bdb269 100644 --- a/tools/ndncert-ca-server.cpp +++ b/tools/ndncert-ca-server.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2023, 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. * @@ -37,7 +37,7 @@ namespace ndncert::ca { static ndn::Face face; static ndn::KeyChain keyChain; -static std::string repoHost = "localhost"; +static std::string repoHost; static std::string repoPort = "7376"; constexpr size_t MAX_CACHED_CERT_NUM = 100; @@ -48,7 +48,7 @@ writeDataToRepo(const Data& data) requestStream.expires_after(std::chrono::seconds(5)); requestStream.connect(repoHost, repoPort); if (!requestStream) { - std::cerr << "ERROR: Cannot publish the certificate to repo-ng" + std::cerr << "ERROR: Cannot publish the certificate to repo" << " (" << requestStream.error().message() << ")" << std::endl; return false; } @@ -92,9 +92,9 @@ main(int argc, char* argv[]) optsDesc.add_options() ("help,h", "print this help message and exit") ("config-file,c", po::value(&configFilePath)->default_value(configFilePath), "path to configuration file") - ("repo-output,r", po::bool_switch(&wantRepoOut), "when enabled, all issued certificates will be published to repo-ng") - ("repo-host,H", po::value(&repoHost)->default_value(repoHost), "repo-ng host") - ("repo-port,P", po::value(&repoPort)->default_value(repoPort), "repo-ng port"); + ("repo-host,H", po::value(&repoHost)->default_value(repoHost), + "repo host (if empty or unspecified, issued certificates will not be published to a repo)") + ("repo-port,P", po::value(&repoPort)->default_value(repoPort), "repo port"); po::variables_map vm; try { @@ -117,6 +117,10 @@ main(int argc, char* argv[]) return 0; } + if (!repoHost.empty()) { + wantRepoOut = true; + } + CaModule ca(face, keyChain, configFilePath); std::deque cachedCertificates; auto profileData = ca.getCaProfileData();