blob: 7e40b9ba8f80e76bb84c3bff55c93f797b36a8f2 [file] [log] [blame]
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2017-2020, Regents of the University of California.
4 *
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
tylerliu8704d032020-06-23 10:18:15 -070021#ifndef NDNCERT_REQUESTER_HPP
22#define NDNCERT_REQUESTER_HPP
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070023
24#include "configuration.hpp"
tylerliu8704d032020-06-23 10:18:15 -070025#include "ca-state.hpp"
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070026#include "crypto-support/crypto-helper.hpp"
27
28namespace ndn {
29namespace ndncert {
30
31// TODO
32// For each RequesterState, create a validator instance and initialize it with CA's cert
33// The validator instance should be in CaProfile
34
35struct RequesterState {
36 explicit
37 RequesterState(security::v2::KeyChain& keyChain, const CaProfile& caItem, RequestType requestType);
38
tylerliudf6e5cc2020-10-05 18:52:13 -070039 /**
40 * The CA profile for this request.
41 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070042 CaProfile m_caItem;
tylerliudf6e5cc2020-10-05 18:52:13 -070043 /**
44 * The local keychain to generate and install identities, keys and certificates
45 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070046 security::v2::KeyChain& m_keyChain;
tylerliudf6e5cc2020-10-05 18:52:13 -070047 /**
48 * The type of request. Either NEW, RENEW, or REVOKE.
49 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070050 RequestType m_type;
51
tylerliudf6e5cc2020-10-05 18:52:13 -070052 /**
53 * The identity name for the requesting certificate.
54 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070055 Name m_identityName;
tylerliudf6e5cc2020-10-05 18:52:13 -070056 /**
57 * The keypair for the request.
58 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070059 security::Key m_keyPair;
tylerliudf6e5cc2020-10-05 18:52:13 -070060 /**
61 * The CA-generated request ID for the request.
62 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070063 std::string m_requestId;
tylerliudf6e5cc2020-10-05 18:52:13 -070064 /**
65 * The current status of the request.
66 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070067 Status m_status = Status::NOT_STARTED;
tylerliudf6e5cc2020-10-05 18:52:13 -070068
69 /**
70 * The type of challenge chosen.
71 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070072 std::string m_challengeType;
tylerliudf6e5cc2020-10-05 18:52:13 -070073 /**
74 * The status of the current challenge.
75 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070076 std::string m_challengeStatus;
tylerliudf6e5cc2020-10-05 18:52:13 -070077 /**
78 * The remaining number of tries left for the challenge
79 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070080 int m_remainingTries = 0;
tylerliudf6e5cc2020-10-05 18:52:13 -070081 /**
82 * The time this challenge will remain fresh
83 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070084 time::system_clock::TimePoint m_freshBefore;
tylerliudf6e5cc2020-10-05 18:52:13 -070085 /**
86 * the name of the certificate being issued.
87 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -070088 Name m_issuedCertName;
89
90 ECDHState m_ecdh;
91 uint8_t m_aesKey[16] = {0};
92
93 bool m_isCertInstalled = false;
94 bool m_isNewlyCreatedIdentity = false;
95 bool m_isNewlyCreatedKey = false;
96};
97
98class Requester : noncopyable
99{
100public:
tylerliudf6e5cc2020-10-05 18:52:13 -0700101 /**
102 * Generates a INFO interest corresponds to the CA for given prefix.
103 * @param caName the name prefix of the CA.
104 * @return A shared pointer to an interest ready to be sent.
105 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700106 static shared_ptr<Interest>
107 genCaProfileInterest(const Name& caName);
108
109 /**
tylerliudf6e5cc2020-10-05 18:52:13 -0700110 * Decodes the replied data for the configuration of the CA.
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700111 * Will first verify the signature of the packet using the key provided inside the profile.
112 * The application should be cautious whether to add CaProfile into the RequesterCaCache.
tylerliudf6e5cc2020-10-05 18:52:13 -0700113 * @param reply
114 * @return the CaProfile if decoding is successful
115 * @throw std::runtime_error if the decoding fails or receiving an error packet.
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700116 */
117 static boost::optional<CaProfile>
118 onCaProfileResponse(const Data& reply);
119
tylerliudf6e5cc2020-10-05 18:52:13 -0700120 /**
121 * Generates a PROBE interest to the CA (for suggested name assignments).
122 * @param ca the CA that interest is send to
123 * @param probeInfo the requester information to carry to the CA
124 * @return A shared pointer of to the encoded interest, ready to be sent.
125 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700126 static shared_ptr<Interest>
127 genProbeInterest(const CaProfile& ca, std::vector<std::tuple<std::string, std::string>>&& probeInfo);
128
tylerliudf6e5cc2020-10-05 18:52:13 -0700129 /**
130 * Decodes the replied data for PROBE process from the CA.
131 * Will first verify the signature of the packet using the key provided inside the profile.
132 * @param reply The replied data packet
133 * @param ca the profile of the CA that replies the packet
134 * @param identityNames The vector to load the decoded identity names from the data.
135 * @param otherCas The vector to load the decoded redirection CA prefixes from the data.
136 * @throw std::runtime_error if the decoding fails or receiving an error packet.
137 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700138 static void
139 onProbeResponse(const Data& reply, const CaProfile& ca,
140 std::vector<Name>& identityNames, std::vector<Name>& otherCas);
141
142 // NEW/REVOKE/RENEW related helpers
tylerliudf6e5cc2020-10-05 18:52:13 -0700143 /**
144 * Generates a NEW interest to the CA.
145 * @param state The current requester state for this request. Will be modified in the function.
146 * @param identityName The identity name to be requested.
147 * @param notBefore The expected notBefore field for the certificate (starting time)
148 * @param notAfter The expected notAfter field for the certificate (expiration time)
149 * @return The shared pointer to the encoded interest.
150 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700151 static shared_ptr<Interest>
152 genNewInterest(RequesterState& state, const Name& identityName,
153 const time::system_clock::TimePoint& notBefore,
154 const time::system_clock::TimePoint& notAfter);
155
tylerliudf6e5cc2020-10-05 18:52:13 -0700156 /**
157 * Generates a REVOKE interest to the CA.
158 * @param state The current requester state for this request. Will be modified in the function.
159 * @param certificate the certificate to the revoked.
160 * @return The shared pointer to the encoded interest.
161 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700162 static shared_ptr<Interest>
163 genRevokeInterest(RequesterState& state, const security::v2::Certificate& certificate);
164
tylerliudf6e5cc2020-10-05 18:52:13 -0700165 /**
166 * Decodes the replied data of NEW, RENEW, or REVOKE interest from the CA.
167 * @param state the current requester state for the request. Will be updated in the function.
168 * @param reply the replied data from the network
169 * @return the list of challenge accepted by the CA, for CHALLENGE step.
170 * @throw std::runtime_error if the decoding fails or receiving an error packet.
171 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700172 static std::list<std::string>
173 onNewRenewRevokeResponse(RequesterState& state, const Data& reply);
174
175 // CHALLENGE helpers
tylerliudf6e5cc2020-10-05 18:52:13 -0700176 /**
177 * Generates the required parameter for the selected challenge for the request
178 * @param state The requester state of the request.Will be updated in the function.
179 * @param challengeSelected The selected challenge for the request.
180 * Can use state.m_challengeType to continue.
181 * @return The requirement list for the current stage of the challenge, in name, prompt mapping.
182 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700183 static std::vector<std::tuple<std::string, std::string>>
184 selectOrContinueChallenge(RequesterState& state, const std::string& challengeSelected);
185
tylerliudf6e5cc2020-10-05 18:52:13 -0700186 /**
187 * Generates the CHALLENGE interest for the request.
188 * @param state The requester state of the request.
189 * @param parameters The requirement list, in name, value mapping.
190 * @return The shared pointer to the encoded interest
191 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700192 static shared_ptr<Interest>
193 genChallengeInterest(const RequesterState& state,
194 std::vector<std::tuple<std::string, std::string>>&& parameters);
195
tylerliudf6e5cc2020-10-05 18:52:13 -0700196 /**
197 * Decodes the responsed data from the CHALLENGE interest.
198 * @param state the corresponding requester state of the request. Will be modified.
199 * @param reply the response data.
200 * @throw std::runtime_error if the decoding fails or receiving an error packet.
201 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700202 static void
203 onChallengeResponse(RequesterState& state, const Data& reply);
204
tylerliudf6e5cc2020-10-05 18:52:13 -0700205 /**
206 * Generate the interest to fetch the issued certificate
207 * @param state the state of the request.
208 * @return The shared pointer to the encoded interest
209 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700210 static shared_ptr<Interest>
211 genCertFetchInterest(const RequesterState& state);
212
tylerliudf6e5cc2020-10-05 18:52:13 -0700213 /**
214 * Decoded and installs the response certificate from the certificate fetch.
215 * @param reply the data replied from the certificate fetch interest.
216 * @return The shared pointer to the certificate being fetched.
217 */
tylerliufeabfdc2020-10-03 15:09:58 -0700218 static shared_ptr<security::v2::Certificate>
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700219 onCertFetchResponse(const Data& reply);
220
tylerliudf6e5cc2020-10-05 18:52:13 -0700221 /**
222 * End the current request session and performs cleanup if necessary.
223 * @param state the requester state for the request.
224 */
tylerliufeabfdc2020-10-03 15:09:58 -0700225 static void
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700226 endSession(RequesterState& state);
227
228private:
229 static void
230 processIfError(const Data& data);
231};
232
233} // namespace ndncert
234} // namespace ndn
235
tylerliu8704d032020-06-23 10:18:15 -0700236#endif // NDNCERT_REQUESTER_HPP