blob: 06dec71d9c633a2290f54b6c6a0e1c5269e7a9f8 [file] [log] [blame]
Zhiyi Zhang3f20f952020-11-19 19:26:43 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento0dc02012021-11-23 22:55:03 -05002/*
Davide Pesavento842f1f72024-02-21 21:27:25 -05003 * Copyright (c) 2017-2024, Regents of the University of California.
Zhiyi Zhang3f20f952020-11-19 19:26:43 -08004 *
5 * This file is part of ndncert, a certificate management system based on NDN.
6 *
7 * ndncert is free software: you can redistribute it and/or modify it under the terms
8 * of the GNU General Public License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
10 *
11 * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License along with
16 * ndncert, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * See AUTHORS.md for complete list of ndncert authors and contributors.
19 */
20
21#include "detail/ca-profile.hpp"
Zhiyi Zhang84e11842020-11-19 20:03:23 -080022#include "challenge/challenge-module.hpp"
Davide Pesavento0dc02012021-11-23 22:55:03 -050023
Davide Pesavento9510c912024-02-25 17:50:05 -050024#include <boost/algorithm/string/case_conv.hpp>
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080025#include <ndn-cxx/util/io.hpp>
Davide Pesavento0dc02012021-11-23 22:55:03 -050026
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080027namespace ndncert {
28
Zhiyi Zhang1e418f22020-11-19 19:49:32 -080029CaProfile
30CaProfile::fromJson(const JsonSection& json)
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080031{
Zhiyi Zhang1e418f22020-11-19 19:49:32 -080032 CaProfile profile;
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080033 // CA prefix
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080034 profile.caPrefix = Name(json.get(CONFIG_CA_PREFIX, ""));
35 if (profile.caPrefix.empty()) {
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080036 NDN_THROW(std::runtime_error("Cannot parse ca-prefix from the config file"));
37 }
Tianyuan Yu42bc63e2024-10-18 10:18:38 -070038 // Forwarding hint
39 profile.forwardingHint = Name(json.get(CONFIG_FORWARDING_HINT, ""));
40 if (profile.forwardingHint.empty()) {
41 profile.forwardingHint = Name(profile.caPrefix).append("CA");
42 }
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080043 // CA info
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080044 profile.caInfo = json.get(CONFIG_CA_INFO, "");
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080045 // CA max validity period
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080046 profile.maxValidityPeriod = time::seconds(json.get(CONFIG_MAX_VALIDITY_PERIOD, 86400));
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080047 // CA max suffix length
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040048 profile.maxSuffixLength = std::nullopt;
Zhiyi Zhang1e418f22020-11-19 19:49:32 -080049 auto maxSuffixLength = json.get_optional<size_t>(CONFIG_MAX_SUFFIX_LENGTH);
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080050 if (maxSuffixLength) {
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080051 profile.maxSuffixLength = *maxSuffixLength;
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080052 }
53 // probe parameter keys
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080054 profile.probeParameterKeys.clear();
Zhiyi Zhang1e418f22020-11-19 19:49:32 -080055 auto probeParametersJson = json.get_child_optional(CONFIG_PROBE_PARAMETERS);
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080056 if (probeParametersJson) {
57 for (const auto& item : *probeParametersJson) {
58 auto probeParameter = item.second.get(CONFIG_PROBE_PARAMETER, "");
59 probeParameter = boost::algorithm::to_lower_copy(probeParameter);
60 if (probeParameter == "") {
61 NDN_THROW(std::runtime_error("Probe parameter key cannot be empty."));
62 }
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080063 profile.probeParameterKeys.push_back(probeParameter);
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080064 }
65 }
66 // supported challenges
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080067 profile.supportedChallenges.clear();
Zhiyi Zhang1e418f22020-11-19 19:49:32 -080068 auto challengeListJson = json.get_child_optional(CONFIG_SUPPORTED_CHALLENGES);
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080069 if (challengeListJson) {
70 for (const auto& item : *challengeListJson) {
71 auto challengeType = item.second.get(CONFIG_CHALLENGE, "");
72 challengeType = boost::algorithm::to_lower_copy(challengeType);
73 if (challengeType == "") {
tylerliuf26d41b2021-10-12 16:50:16 -070074 NDN_THROW(std::runtime_error("Challenge type cannot be empty."));
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080075 }
76 if (!ChallengeModule::isChallengeSupported(challengeType)) {
77 NDN_THROW(std::runtime_error("Challenge " + challengeType + " is not supported."));
78 }
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080079 profile.supportedChallenges.push_back(challengeType);
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080080 }
81 }
82 // anchor certificate
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080083 profile.cert = nullptr;
Zhiyi Zhang1e418f22020-11-19 19:49:32 -080084 auto certificateStr = json.get(CONFIG_CERTIFICATE, "");
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040085 if (!certificateStr.empty()) {
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080086 std::istringstream ss(certificateStr);
Davide Pesavento0dc02012021-11-23 22:55:03 -050087 profile.cert = ndn::io::load<Certificate>(ss);
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080088 }
Zhiyi Zhang1e418f22020-11-19 19:49:32 -080089 return profile;
Zhiyi Zhang3f20f952020-11-19 19:26:43 -080090}
91
92JsonSection
93CaProfile::toJson() const
94{
95 JsonSection caItem;
Zhiyi Zhang44c6a352020-12-14 10:57:17 -080096 caItem.put(CONFIG_CA_PREFIX, caPrefix.toUri());
97 caItem.put(CONFIG_CA_INFO, caInfo);
98 caItem.put(CONFIG_MAX_VALIDITY_PERIOD, maxValidityPeriod.count());
99 if (maxSuffixLength) {
100 caItem.put(CONFIG_MAX_SUFFIX_LENGTH, *maxSuffixLength);
Zhiyi Zhang3f20f952020-11-19 19:26:43 -0800101 }
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800102 if (!probeParameterKeys.empty()) {
Zhiyi Zhang3f20f952020-11-19 19:26:43 -0800103 JsonSection probeParametersJson;
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800104 for (const auto& key : probeParameterKeys) {
Zhiyi Zhang3f20f952020-11-19 19:26:43 -0800105 JsonSection keyJson;
106 keyJson.put(CONFIG_PROBE_PARAMETER, key);
Davide Pesavento0d1d11c2022-04-11 22:11:34 -0400107 probeParametersJson.push_back({"", keyJson});
Zhiyi Zhang3f20f952020-11-19 19:26:43 -0800108 }
109 caItem.add_child("", probeParametersJson);
110 }
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800111 if (!supportedChallenges.empty()) {
Zhiyi Zhang3f20f952020-11-19 19:26:43 -0800112 JsonSection challengeListJson;
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800113 for (const auto& challenge : supportedChallenges) {
Zhiyi Zhang3f20f952020-11-19 19:26:43 -0800114 JsonSection challengeJson;
115 challengeJson.put(CONFIG_CHALLENGE, challenge);
Davide Pesavento0d1d11c2022-04-11 22:11:34 -0400116 challengeListJson.push_back({"", challengeJson});
Zhiyi Zhang3f20f952020-11-19 19:26:43 -0800117 }
118 caItem.add_child("", challengeListJson);
119 }
Zhiyi Zhang44c6a352020-12-14 10:57:17 -0800120 if (cert != nullptr) {
Zhiyi Zhang3f20f952020-11-19 19:26:43 -0800121 std::stringstream ss;
Davide Pesavento0dc02012021-11-23 22:55:03 -0500122 ndn::io::save(*cert, ss);
Zhiyi Zhang3f20f952020-11-19 19:26:43 -0800123 caItem.put("certificate", ss.str());
124 }
125 return caItem;
126}
127
128} // namespace ndncert