blob: 9f360426faa3d0aa6e9b59d841f3a1d26fadc15f [file] [log] [blame]
Suyong Won19fba4d2020-05-09 13:39:46 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento0dc02012021-11-23 22:55:03 -05002/*
Tianyuan Yu13aac732022-03-03 20:59:54 -08003 * Copyright (c) 2017-2022, Regents of the University of California.
Suyong Won19fba4d2020-05-09 13:39:46 -07004 *
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
Zhiyi Zhangb041d442020-10-22 21:57:11 -070021#include "detail/challenge-encoder.hpp"
Suyong Won19fba4d2020-05-09 13:39:46 -070022
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040023namespace ndncert::challengetlv {
Suyong Won19fba4d2020-05-09 13:39:46 -070024
25Block
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040026encodeDataContent(ca::RequestState& request, const Name& issuedCertName)
Suyong Won19fba4d2020-05-09 13:39:46 -070027{
tylerliu1f480be2020-11-10 13:02:53 -080028 Block response(tlv::EncryptedPayload);
Davide Pesavento0dc02012021-11-23 22:55:03 -050029 response.push_back(ndn::makeNonNegativeIntegerBlock(tlv::Status, static_cast<uint64_t>(request.status)));
tylerliu7b9185c2020-11-24 12:15:18 -080030 if (request.challengeState) {
Davide Pesavento0dc02012021-11-23 22:55:03 -050031 response.push_back(ndn::makeStringBlock(tlv::ChallengeStatus, request.challengeState->challengeStatus));
32 response.push_back(ndn::makeNonNegativeIntegerBlock(tlv::RemainingTries,
33 request.challengeState->remainingTries));
34 response.push_back(ndn::makeNonNegativeIntegerBlock(tlv::RemainingTime,
35 request.challengeState->remainingTime.count()));
tylerliuf51e3162020-12-20 19:22:59 -080036 if (request.challengeState->challengeStatus == "need-proof") {
Davide Pesavento0dc02012021-11-23 22:55:03 -050037 response.push_back(ndn::makeStringBlock(tlv::ParameterKey, "nonce"));
38 auto nonce = ndn::fromHex(request.challengeState->secrets.get("nonce", ""));
Davide Pesavento6f1a2ab2022-03-17 03:57:21 -040039 response.push_back(ndn::makeBinaryBlock(tlv::ParameterValue, *nonce));
tylerliuf51e3162020-12-20 19:22:59 -080040 }
tylerliuab9cba22020-10-09 00:13:46 -070041 }
tylerliubb630362020-11-10 11:31:35 -080042 if (!issuedCertName.empty()) {
43 response.push_back(makeNestedBlock(tlv::IssuedCertName, issuedCertName));
Tianyuan Yu60775552022-03-07 17:10:10 -080044 response.push_back(makeNestedBlock(ndn::tlv::ForwardingHint, Name(request.caPrefix).append("CA")));
Zhiyi Zhanga2db7192020-10-30 09:08:19 -070045 }
Suyong Won44d0cce2020-05-10 04:07:43 -070046 response.encode();
Davide Pesavento0dc02012021-11-23 22:55:03 -050047
tylerliu7b9185c2020-11-24 12:15:18 -080048 return encodeBlockWithAesGcm128(ndn::tlv::Content, request.encryptionKey.data(),
Zhiyi Zhang4c259db2020-10-30 09:36:01 -070049 response.value(), response.value_size(),
Zhiyi Zhang4f1c0102020-12-21 15:08:09 -080050 request.requestId.data(), request.requestId.size(),
51 request.encryptionIv);
Suyong Won19fba4d2020-05-09 13:39:46 -070052}
53
Zhiyi Zhangf2306f72020-10-09 11:26:05 -070054void
Davide Pesavento0d1d11c2022-04-11 22:11:34 -040055decodeDataContent(const Block& contentBlock, requester::Request& state)
Zhiyi Zhangf2306f72020-10-09 11:26:05 -070056{
Zhiyi Zhang6499edd2021-02-17 22:37:21 -080057 auto result = decodeBlockWithAesGcm128(contentBlock, state.m_aesKey.data(),
58 state.m_requestId.data(), state.m_requestId.size(),
Zhiyi Zhang3b9a5032021-02-18 11:15:09 -080059 state.m_decryptionIv, state.m_encryptionIv);
Davide Pesavento6f1a2ab2022-03-17 03:57:21 -040060 auto data = ndn::makeBinaryBlock(tlv::EncryptedPayload, result);
Zhiyi Zhangf2306f72020-10-09 11:26:05 -070061 data.parse();
Davide Pesavento0dc02012021-11-23 22:55:03 -050062
Tianyuan Yu13aac732022-03-03 20:59:54 -080063 int numStatus = 0;
64 bool lookingForNonce = false;
65 for (const auto &item : data.elements()) {
66 if (!lookingForNonce) {
67 switch (item.type()) {
68 case tlv::Status:
69 state.m_status = statusFromBlock(data.get(tlv::Status));
70 numStatus++;
71 break;
72 case tlv::ChallengeStatus:
73 state.m_challengeStatus = readString(item);
74 break;
75 case tlv::RemainingTries:
76 state.m_remainingTries = readNonNegativeInteger(item);
77 break;
78 case tlv::RemainingTime:
79 state.m_freshBefore = time::system_clock::now() +
80 time::seconds(readNonNegativeInteger(item));
81 break;
82 case tlv::IssuedCertName:
83 state.m_issuedCertName = Name(item.blockFromValue());
84 break;
Tianyuan Yu60775552022-03-07 17:10:10 -080085 case ndn::tlv::ForwardingHint:
86 state.m_forwardingHint = Name(item.blockFromValue());
87 break;
Tianyuan Yu13aac732022-03-03 20:59:54 -080088 case tlv::ParameterKey:
89 if (readString(item) == "nonce") {
90 lookingForNonce = true;
91 }
92 else {
93 NDN_THROW(std::runtime_error("Unknown Parameter: " + readString(item)));
94 }
95 break;
96 default:
97 if (ndn::tlv::isCriticalType(item.type())) {
98 NDN_THROW(std::runtime_error("Unrecognized TLV Type: " + std::to_string(item.type())));
99 }
100 else {
101 //ignore
102 }
103 break;
104 }
105 }
106 else {
107 if (item.type() == tlv::ParameterValue) {
108 lookingForNonce = false;
109 if (item.value_size() != 16) {
110 NDN_THROW(std::runtime_error("Wrong nonce length"));
111 }
112 memcpy(state.m_nonce.data(), item.value(), 16);
113 }
114 else {
tylerliuf51e3162020-12-20 19:22:59 -0800115 NDN_THROW(std::runtime_error("Parameter Key found, but no value found"));
Tianyuan Yu13aac732022-03-03 20:59:54 -0800116 }
tylerliuf51e3162020-12-20 19:22:59 -0800117 }
Tianyuan Yu13aac732022-03-03 20:59:54 -0800118 }
119 if (numStatus != 1) {
120 NDN_THROW(std::runtime_error("number of status block is not equal to 1; there are " +
121 std::to_string(numStatus) + " status blocks"));
tylerliuf51e3162020-12-20 19:22:59 -0800122 }
tylerliu0790bdb2020-10-02 00:50:51 -0700123}
124
Davide Pesavento0d1d11c2022-04-11 22:11:34 -0400125} // namespace ndncert::challengetlv