blob: ab987ddbaef81af938a1c5a05ac4894e61492e2c [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
Zhiyi Zhang837406d2020-10-05 22:01:31 -0700120 static boost::optional<CaProfile>
121 onCaProfileResponseAfterRedirection(const Data& reply, const Name& caCertFullName);
122
tylerliudf6e5cc2020-10-05 18:52:13 -0700123 /**
124 * Generates a PROBE interest to the CA (for suggested name assignments).
125 * @param ca the CA that interest is send to
126 * @param probeInfo the requester information to carry to the CA
127 * @return A shared pointer of to the encoded interest, ready to be sent.
128 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700129 static shared_ptr<Interest>
130 genProbeInterest(const CaProfile& ca, std::vector<std::tuple<std::string, std::string>>&& probeInfo);
131
tylerliudf6e5cc2020-10-05 18:52:13 -0700132 /**
133 * Decodes the replied data for PROBE process from the CA.
134 * Will first verify the signature of the packet using the key provided inside the profile.
135 * @param reply The replied data packet
136 * @param ca the profile of the CA that replies the packet
137 * @param identityNames The vector to load the decoded identity names from the data.
138 * @param otherCas The vector to load the decoded redirection CA prefixes from the data.
139 * @throw std::runtime_error if the decoding fails or receiving an error packet.
140 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700141 static void
142 onProbeResponse(const Data& reply, const CaProfile& ca,
143 std::vector<Name>& identityNames, std::vector<Name>& otherCas);
144
145 // NEW/REVOKE/RENEW related helpers
tylerliudf6e5cc2020-10-05 18:52:13 -0700146 /**
147 * Generates a NEW interest to the CA.
148 * @param state The current requester state for this request. Will be modified in the function.
149 * @param identityName The identity name to be requested.
150 * @param notBefore The expected notBefore field for the certificate (starting time)
151 * @param notAfter The expected notAfter field for the certificate (expiration time)
152 * @return The shared pointer to the encoded interest.
153 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700154 static shared_ptr<Interest>
155 genNewInterest(RequesterState& state, const Name& identityName,
156 const time::system_clock::TimePoint& notBefore,
157 const time::system_clock::TimePoint& notAfter);
158
tylerliudf6e5cc2020-10-05 18:52:13 -0700159 /**
160 * Generates a REVOKE interest to the CA.
161 * @param state The current requester state for this request. Will be modified in the function.
162 * @param certificate the certificate to the revoked.
163 * @return The shared pointer to the encoded interest.
164 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700165 static shared_ptr<Interest>
166 genRevokeInterest(RequesterState& state, const security::v2::Certificate& certificate);
167
tylerliudf6e5cc2020-10-05 18:52:13 -0700168 /**
169 * Decodes the replied data of NEW, RENEW, or REVOKE interest from the CA.
170 * @param state the current requester state for the request. Will be updated in the function.
171 * @param reply the replied data from the network
172 * @return the list of challenge accepted by the CA, for CHALLENGE step.
173 * @throw std::runtime_error if the decoding fails or receiving an error packet.
174 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700175 static std::list<std::string>
176 onNewRenewRevokeResponse(RequesterState& state, const Data& reply);
177
178 // CHALLENGE helpers
tylerliudf6e5cc2020-10-05 18:52:13 -0700179 /**
180 * Generates the required parameter for the selected challenge for the request
181 * @param state The requester state of the request.Will be updated in the function.
182 * @param challengeSelected The selected challenge for the request.
183 * Can use state.m_challengeType to continue.
184 * @return The requirement list for the current stage of the challenge, in name, prompt mapping.
185 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700186 static std::vector<std::tuple<std::string, std::string>>
187 selectOrContinueChallenge(RequesterState& state, const std::string& challengeSelected);
188
tylerliudf6e5cc2020-10-05 18:52:13 -0700189 /**
190 * Generates the CHALLENGE interest for the request.
191 * @param state The requester state of the request.
192 * @param parameters The requirement list, in name, value mapping.
193 * @return The shared pointer to the encoded interest
194 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700195 static shared_ptr<Interest>
196 genChallengeInterest(const RequesterState& state,
197 std::vector<std::tuple<std::string, std::string>>&& parameters);
198
tylerliudf6e5cc2020-10-05 18:52:13 -0700199 /**
200 * Decodes the responsed data from the CHALLENGE interest.
201 * @param state the corresponding requester state of the request. Will be modified.
202 * @param reply the response data.
203 * @throw std::runtime_error if the decoding fails or receiving an error packet.
204 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700205 static void
206 onChallengeResponse(RequesterState& state, const Data& reply);
207
tylerliudf6e5cc2020-10-05 18:52:13 -0700208 /**
209 * Generate the interest to fetch the issued certificate
210 * @param state the state of the request.
211 * @return The shared pointer to the encoded interest
212 */
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700213 static shared_ptr<Interest>
214 genCertFetchInterest(const RequesterState& state);
215
tylerliudf6e5cc2020-10-05 18:52:13 -0700216 /**
217 * Decoded and installs the response certificate from the certificate fetch.
218 * @param reply the data replied from the certificate fetch interest.
219 * @return The shared pointer to the certificate being fetched.
220 */
tylerliufeabfdc2020-10-03 15:09:58 -0700221 static shared_ptr<security::v2::Certificate>
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700222 onCertFetchResponse(const Data& reply);
223
tylerliudf6e5cc2020-10-05 18:52:13 -0700224 /**
225 * End the current request session and performs cleanup if necessary.
226 * @param state the requester state for the request.
227 */
tylerliufeabfdc2020-10-03 15:09:58 -0700228 static void
Zhiyi Zhang1d3dcd22020-10-01 22:25:43 -0700229 endSession(RequesterState& state);
230
231private:
232 static void
233 processIfError(const Data& data);
234};
235
236} // namespace ndncert
237} // namespace ndn
238
tylerliu8704d032020-06-23 10:18:15 -0700239#endif // NDNCERT_REQUESTER_HPP