blob: 0b77af9ef1e483dbc23a72c1e69242150b9e9238 [file] [log] [blame]
tylerliu729212e2020-09-26 14:31:25 -07001/*
2 * Copyright (c) 2017-2020, Regents of the University of California.
3 *
4 * This file is part of ndncert, a certificate management system based on NDN.
5 *
6 * ndncert is free software: you can redistribute it and/or modify it under the terms
7 * of the GNU General Public License as published by the Free Software Foundation, either
8 * version 3 of the License, or (at your option) any later version.
9 *
10 * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
11 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
12 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 *
14 * You should have received copies of the GNU General Public License along with
15 * ndncert, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * See AUTHORS.md for complete list of ndncert authors and contributors.
18 */
19
20#include "challenge-private-key.hpp"
21
22#include <iostream>
23#include <ndn-cxx/security/verification-helpers.hpp>
24#include <ndn-cxx/util/io.hpp>
25
26#include "../logging.hpp"
27
28namespace ndn {
29namespace ndncert {
30
31_LOG_INIT(ndncert.ChallengePrivateKey);
32
33NDNCERT_REGISTER_CHALLENGE(ChallengePrivateKey, "Private");
34
35const std::string ChallengePrivateKey::FAILURE_INVALID_REQUEST_TYPE = "failure-invalid-request-type";
36const std::string ChallengePrivateKey::FAILURE_INVALID_FORMAT_SELF_SIGNED = "failure-cannot-parse-self-signed";
37const std::string ChallengePrivateKey::FAILURE_INVALID_CREDENTIAL = "failure-invalid-credential";
38const std::string ChallengePrivateKey::JSON_PROOF_OF_PRIVATE_KEY = "proof-of-private-key";
39
40ChallengePrivateKey::ChallengePrivateKey()
41 : ChallengeModule("PrivateKey")
42{
43}
44
45// For CA
46void
47ChallengePrivateKey::handleChallengeRequest(const Block& params, CertificateRequest& request)
48{
49 if (request.m_requestType == REQUEST_TYPE_NEW) {
50 _LOG_TRACE("Cannot use this private key challenge for new certificate request");
51 request.m_status = STATUS_FAILURE;
52 request.m_challengeStatus = FAILURE_INVALID_REQUEST_TYPE;
53 updateRequestOnChallengeEnd(request);
54 }
55 params.parse();
56 shared_ptr<security::v2::Certificate> selfSigned;
57 auto& elements = params.elements();
58 for (size_t i = 0; i < elements.size(); i++) {
59 if (elements[i].type() == tlv_parameter_key) {
60 if (readString(elements[i]) == JSON_PROOF_OF_PRIVATE_KEY) {
61 std::istringstream ss(readString(params.elements()[i + 1]));
62 selfSigned = io::load<security::v2::Certificate>(ss);
63 if (selfSigned == nullptr) {
64 _LOG_ERROR("Cannot load credential parameter: cert");
65 request.m_status = STATUS_FAILURE;
66 request.m_challengeStatus = FAILURE_INVALID_FORMAT_SELF_SIGNED;
67 updateRequestOnChallengeEnd(request);
68 return;
69 }
70 }
71 else {
72 continue;
73 }
74 }
75 }
76
77 // verify the credential and the self-signed cert
78 if (security::verifySignature(*selfSigned, request.m_cert) &&
79 readString(selfSigned->getContent()) == request.m_requestId) {
80 request.m_status = STATUS_PENDING;
81 request.m_challengeStatus = CHALLENGE_STATUS_SUCCESS;
82 updateRequestOnChallengeEnd(request);
83 return;
84 }
85
86 _LOG_TRACE("Cannot verify the credential + self-signed Data + data content");
87 request.m_status = STATUS_FAILURE;
88 request.m_challengeStatus = FAILURE_INVALID_CREDENTIAL;
89 updateRequestOnChallengeEnd(request);
90}
91
92// For Client
93JsonSection
94ChallengePrivateKey::getRequirementForChallenge(int status, const std::string& challengeStatus)
95{
96 JsonSection result;
97 if (status == STATUS_BEFORE_CHALLENGE && challengeStatus == "") {
98 result.put(JSON_PROOF_OF_PRIVATE_KEY, "Please_copy_key_signed_request_id_data_here");
99 }
100 else {
101 _LOG_ERROR("Client's status and challenge status are wrong");
102 }
103 return result;
104}
105
106JsonSection
107ChallengePrivateKey::genChallengeRequestJson(int status, const std::string& challengeStatus, const JsonSection& params)
108{
109 JsonSection result;
110 if (status == STATUS_BEFORE_CHALLENGE && challengeStatus == "") {
111 result.put(JSON_PROOF_OF_PRIVATE_KEY, params.get(JSON_PROOF_OF_PRIVATE_KEY, ""));
112 }
113 else {
114 _LOG_ERROR("Client's status and challenge status are wrong");
115 }
116 return result;
117}
118
119Block
120ChallengePrivateKey::genChallengeRequestTLV(int status, const std::string& challengeStatus, const JsonSection& params)
121{
122 Block request = makeEmptyBlock(tlv_encrypted_payload);
123 if (status == STATUS_BEFORE_CHALLENGE && challengeStatus == "") {
124 request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
125 request.push_back(makeStringBlock(tlv_parameter_key, JSON_PROOF_OF_PRIVATE_KEY));
126 request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_PROOF_OF_PRIVATE_KEY, "")));
127 }
128 else {
129 _LOG_ERROR("Client's status and challenge status are wrong");
130 }
131 request.encode();
132 return request;
133}
134} // namespace ndncert
135} // namespace ndn