blob: 3eb1d7a179870b5cf1926edcfc540e9a2e41ffd9 [file] [log] [blame]
Yingdi Yu202a2e92015-07-12 16:49:25 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Davide Pesavento794f6872017-05-15 23:33:38 -04003 * Copyright (c) 2013-2017 Regents of the University of California.
Yingdi Yu202a2e92015-07-12 16:49:25 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library 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 Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#ifndef NDN_CXX_SECURITY_TRANSFORM_PRIVATE_KEY_HPP
23#define NDN_CXX_SECURITY_TRANSFORM_PRIVATE_KEY_HPP
24
25#include "public-key.hpp"
26#include "../../encoding/buffer.hpp"
27
28namespace ndn {
29
30class KeyParams;
31
32namespace security {
33namespace transform {
34
35/**
36 * @brief Abstraction of private key in crypto transformation
37 */
38class PrivateKey : noncopyable
39{
40public:
41 class Error : public std::runtime_error
42 {
43 public:
44 explicit
45 Error(const std::string& what)
46 : std::runtime_error(what)
47 {
48 }
49 };
50
51 friend class SignerFilter;
52
53 /**
54 * @brief Callback for application to handle password input
55 *
56 * Password should be stored in @p buf and should not be longer than @p size. It is
57 * recommended to ask the user to verify the passphrase if @p shouldConfirm is true, e.g., by
58 * prompting for the password twice.
59 */
60 typedef function<int(char* buf, size_t bufSize, bool shouldConfirm)> PasswordCallback;
61
62public:
63 /**
64 * @brief Create a private key instance
65 *
66 * One must call loadXXXX(...) to load private key.
67 */
68 PrivateKey();
69
70 ~PrivateKey();
71
72 /**
73 * @brief Load the private key in PKCS#1 format from a buffer @p buf
74 */
75 void
76 loadPkcs1(const uint8_t* buf, size_t size);
77
78 /**
79 * @brief Load the private key in PKCS#1 format from a stream @p is
80 */
81 void
82 loadPkcs1(std::istream& is);
83
84 /**
85 * @brief Load the private key in base64-encoded PKCS#1 format from a buffer @p buf
86 */
87 void
88 loadPkcs1Base64(const uint8_t* buf, size_t size);
89
90 /**
91 * @brief Load the private key in base64-encoded PKCS#1 format from a stream @p is
92 */
93 void
94 loadPkcs1Base64(std::istream& is);
95
96 /**
97 * @brief Load the private key in encrypted PKCS#8 format from a buffer @p buf with passphrase @p pw
98 *
99 * @pre strlen(pw) == pwLen
100 */
101 void
102 loadPkcs8(const uint8_t* buf, size_t size, const char* pw, size_t pwLen);
103
104 /**
105 * @brief Load the private key in encrypted PKCS#8 format from a buffer @p buf with
106 * passphrase obtained from @p pwCallback
107 *
108 * The default password callback is provided by OpenSSL
109 */
110 void
111 loadPkcs8(const uint8_t* buf, size_t size, PasswordCallback pwCallback = nullptr);
112
113 /**
114 * @brief Load the private key in encrypted PKCS#8 format from a stream @p is with passphrase @p pw
115 *
116 * @pre strlen(pw) == pwLen
117 */
118 void
119 loadPkcs8(std::istream& is, const char* pw, size_t pwLen);
120
121 /**
122 * @brief Load the private key in encrypted PKCS#8 format from a stream @p is with passphrase
123 * obtained from @p pwCallback
124 *
125 * The default password callback is provided by OpenSSL
126 */
127 void
128 loadPkcs8(std::istream& is, PasswordCallback pwCallback = nullptr);
129
130 /**
131 * @brief Load the private key in base64-encoded encrypted PKCS#8 format from a buffer @p buf
132 * with passphrase @p pw
133 *
134 * @pre strlen(pw) == pwLen
135 */
136 void
137 loadPkcs8Base64(const uint8_t* buf, size_t size, const char* pw, size_t pwLen);
138
139 /**
140 * @brief Load the private key in encrypted PKCS#8 format from a buffer @p buf with
141 * passphrase obtained from @p pwCallback
142 *
143 * The default password callback is provided by OpenSSL
144 */
145 void
146 loadPkcs8Base64(const uint8_t* buf, size_t size, PasswordCallback pwCallback = nullptr);
147
148 /**
149 * @brief Load the private key in base64-encoded encrypted PKCS#8 format from a stream @p is
150 * with passphrase @p pw
151 *
152 * @pre strlen(pw) == pwLen
153 */
154 void
155 loadPkcs8Base64(std::istream& is, const char* pw, size_t pwLen);
156
157 /**
158 * @brief Load the private key in base64-encoded encrypted PKCS#8 format from a stream @p is
159 * with passphrase obtained from @p pwCallback
160 *
161 * The default password callback is provided by OpenSSL
162 */
163 void
164 loadPkcs8Base64(std::istream& is, PasswordCallback pwCallback = nullptr);
165
166 /**
167 * @brief Save the private key in PKCS#1 format into a stream @p os
168 */
169 void
170 savePkcs1(std::ostream& os) const;
171
172 /**
173 * @brief Save the private key in base64-encoded PKCS#1 format into a stream @p os
174 */
175 void
176 savePkcs1Base64(std::ostream& os) const;
177
178 /**
179 * @brief Save the private key in encrypted PKCS#8 format into a stream @p os
180 */
181 void
182 savePkcs8(std::ostream& os, const char* pw, size_t pwLen) const;
183
184 /**
185 * @brief Save the private key in encrypted PKCS#8 format into a stream @p os with passphrase
186 * obtained from @p pwCallback
187 *
188 * The default password callback is provided by OpenSSL
189 */
190 void
191 savePkcs8(std::ostream& os, PasswordCallback pwCallback = nullptr) const;
192
193 /**
194 * @brief Save the private key in base64-encoded encrypted PKCS#8 format into a stream @p os
195 */
196 void
197 savePkcs8Base64(std::ostream& os, const char* pw, size_t pwLen) const;
198
199 /**
200 * @brief Save the private key in base64-encoded encrypted PKCS#8 format into a stream @p os
201 * with passphrase obtained from @p pwCallback
202 *
203 * The default password callback is provided by OpenSSL
204 */
205 void
206 savePkcs8Base64(std::ostream& os, PasswordCallback pwCallback = nullptr) const;
207
208 /**
209 * @return Public key bits in PKCS#8 format
210 */
211 ConstBufferPtr
212 derivePublicKey() const;
213
214 /**
215 * @return Plain text of @p cipherText decrypted using the private key.
216 *
217 * Only RSA encryption is supported for now.
218 */
219 ConstBufferPtr
220 decrypt(const uint8_t* cipherText, size_t cipherLen) const;
221
222private:
223 /**
224 * @return A pointer to an EVP_PKEY instance.
225 *
226 * One need to explicitly cast the return value to EVP_PKEY*.
227 */
228 void*
229 getEvpPkey() const;
230
231private:
232 ConstBufferPtr
233 toPkcs1() const;
234
235 ConstBufferPtr
236 toPkcs8(const char* pw, size_t pwLen) const;
237
238 ConstBufferPtr
239 toPkcs8(PasswordCallback pwCallback = nullptr) const;
240
241 ConstBufferPtr
242 rsaDecrypt(const uint8_t* cipherText, size_t cipherLen) const;
243
244private:
245 class Impl;
Davide Pesavento794f6872017-05-15 23:33:38 -0400246 const unique_ptr<Impl> m_impl;
Yingdi Yu202a2e92015-07-12 16:49:25 -0700247};
248
249/**
250 * @brief generate a private key according to @p keyParams.
251 *
252 * @note the public key can be derived from the private key
253 *
254 * @throw std::argument_error if the key type is not supported
255 * @throw std::runtime_error when failing to generate the key
256 */
257unique_ptr<PrivateKey>
258generatePrivateKey(const KeyParams& keyParams);
259
260} // namespace transform
261} // namespace security
262} // namespace ndn
263
264#endif // NDN_CXX_SECURITY_TRANSFORM_PRIVATE_KEY_HPP