Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

openssl_rsa.cpp
Go to the documentation of this file.
1 /*
2 * RSA operations provided by OpenSSL
3 * (C) 2015 Jack Lloyd
4 * (C) 2017 Alexander Bluhm
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9 #include <botan/internal/openssl.h>
10
11 #if defined(BOTAN_HAS_RSA)
12
13 #include <botan/rsa.h>
14 #include <botan/rng.h>
15 #include <botan/internal/pk_ops_impl.h>
16 #include <botan/internal/ct_utils.h>
17
18 #include <functional>
19 #include <memory>
20 #include <cstdlib>
21
22 #include <openssl/rsa.h>
23 #include <openssl/x509.h>
24 #include <openssl/err.h>
25 #include <openssl/rand.h>
26 #include <limits.h>
27
28 namespace Botan {
29
30 namespace {
31
32 std::pair<int, size_t> get_openssl_enc_pad(const std::string& eme)
33 {
34 if(eme == "Raw")
35 return std::make_pair(RSA_NO_PADDING, 0);
36 else if(eme == "EME-PKCS1-v1_5")
37 return std::make_pair(RSA_PKCS1_PADDING, 11);
38 else if(eme == "OAEP(SHA-1)" || eme == "EME1(SHA-1)")
39 return std::make_pair(RSA_PKCS1_OAEP_PADDING, 41);
40 else
41 throw Lookup_Error("OpenSSL RSA does not support EME " + eme);
42 }
43
44 class OpenSSL_RSA_Encryption_Operation final : public PK_Ops::Encryption
45 {
46 public:
47
48 OpenSSL_RSA_Encryption_Operation(const RSA_PublicKey& rsa, int pad, size_t pad_overhead) :
49 m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad)
50 {
51 const std::vector<uint8_t> der = rsa.public_key_bits();
52 const uint8_t* der_ptr = der.data();
53 m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size()));
54 if(!m_openssl_rsa)
55 throw OpenSSL_Error("d2i_RSAPublicKey", ERR_get_error());
56
57 m_bits = 8 * (n_size() - pad_overhead) - 1;
58 }
59
60 size_t ciphertext_length(size_t) const override { return ::RSA_size(m_openssl_rsa.get()); }
61
62 size_t max_input_bits() const override { return m_bits; };
63
64 secure_vector<uint8_t> encrypt(const uint8_t msg[], size_t msg_len,
65 RandomNumberGenerator&) override
66 {
67 const size_t mod_sz = n_size();
68
69 if(msg_len > mod_sz)
70 throw Invalid_Argument("Input too large for RSA key");
71
72 secure_vector<uint8_t> outbuf(mod_sz);
73
74 secure_vector<uint8_t> inbuf;
75
76 if(m_padding == RSA_NO_PADDING)
77 {
78 inbuf.resize(mod_sz);
79 copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
80 }
81 else
82 {
83 inbuf.assign(msg, msg + msg_len);
84 }
85
86 int rc = ::RSA_public_encrypt(inbuf.size(), inbuf.data(), outbuf.data(),
87 m_openssl_rsa.get(), m_padding);
88 if(rc < 0)
89 throw OpenSSL_Error("RSA_public_encrypt", ERR_get_error());
90
91 return outbuf;
92 }
93
94 private:
95 size_t n_size() const { return ::RSA_size(m_openssl_rsa.get()); }
96 std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
97 size_t m_bits = 0;
98 int m_padding = 0;
99 };
100
101 class OpenSSL_RSA_Decryption_Operation final : public PK_Ops::Decryption
102 {
103 public:
104
105 OpenSSL_RSA_Decryption_Operation(const RSA_PrivateKey& rsa, int pad) :
106 m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad)
107 {
108 const secure_vector<uint8_t> der = rsa.private_key_bits();
109 const uint8_t* der_ptr = der.data();
110 m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
111 if(!m_openssl_rsa)
112 throw OpenSSL_Error("d2i_RSAPrivateKey", ERR_get_error());
113 }
114
115 size_t plaintext_length(size_t) const override { return ::RSA_size(m_openssl_rsa.get()); }
116
117 secure_vector<uint8_t> decrypt(uint8_t& valid_mask,
118 const uint8_t msg[], size_t msg_len) override
119 {
120 secure_vector<uint8_t> buf(::RSA_size(m_openssl_rsa.get()));
121 int rc = ::RSA_private_decrypt(msg_len, msg, buf.data(), m_openssl_rsa.get(), m_padding);
122 if(rc < 0 || static_cast<size_t>(rc) > buf.size())
123 {
124 valid_mask = 0;
125 buf.resize(0);
126 }
127 else
128 {
129 valid_mask = 0xFF;
130 buf.resize(rc);
131 }
132
133 if(m_padding == RSA_NO_PADDING)
134 {
135 return CT::strip_leading_zeros(buf);
136 }
137
138 return buf;
139 }
140
141 private:
142 std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
143 int m_padding = 0;
144 };
145
146 class OpenSSL_RSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA
147 {
148 public:
149
150 OpenSSL_RSA_Verification_Operation(const RSA_PublicKey& rsa, const std::string& emsa) :
151 PK_Ops::Verification_with_EMSA(emsa),
152 m_openssl_rsa(nullptr, ::RSA_free)
153 {
154 const std::vector<uint8_t> der = rsa.public_key_bits();
155 const uint8_t* der_ptr = der.data();
156 m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size()));
157 if(!m_openssl_rsa)
158 throw OpenSSL_Error("d2i_RSAPublicKey", ERR_get_error());
159 }
160
161 size_t max_input_bits() const override
162 {
163 #if OPENSSL_VERSION_NUMBER < 0x10100000L
164 return ::BN_num_bits(m_openssl_rsa->n) - 1;
165 #else
166 return ::RSA_bits(m_openssl_rsa.get()) - 1;
167 #endif
168 }
169
170 bool with_recovery() const override { return true; }
171
172 secure_vector<uint8_t> verify_mr(const uint8_t msg[], size_t msg_len) override
173 {
174 const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
175
176 if(msg_len > mod_sz)
177 throw Invalid_Argument("OpenSSL RSA verify input too large");
178
179 secure_vector<uint8_t> inbuf(mod_sz);
180
181 if(msg_len > 0)
182 copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
183
184 secure_vector<uint8_t> outbuf(mod_sz);
185
186 int rc = ::RSA_public_decrypt(inbuf.size(), inbuf.data(), outbuf.data(),
187 m_openssl_rsa.get(), RSA_NO_PADDING);
188 if(rc < 0)
189 throw Invalid_Argument("RSA_public_decrypt");
190
191 return CT::strip_leading_zeros(outbuf);
192 }
193 private:
194 std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
195 };
196
197 class OpenSSL_RSA_Signing_Operation final : public PK_Ops::Signature_with_EMSA
198 {
199 public:
200
201 OpenSSL_RSA_Signing_Operation(const RSA_PrivateKey& rsa, const std::string& emsa) :
202 PK_Ops::Signature_with_EMSA(emsa),
203 m_openssl_rsa(nullptr, ::RSA_free)
204 {
205 const secure_vector<uint8_t> der = rsa.private_key_bits();
206 const uint8_t* der_ptr = der.data();
207 m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
208 if(!m_openssl_rsa)
209 throw OpenSSL_Error("d2i_RSAPrivateKey", ERR_get_error());
210 }
211
212 size_t signature_length() const override { return ::RSA_size(m_openssl_rsa.get()); }
213
214 secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len,
215 RandomNumberGenerator&) override
216 {
217 const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
218
219 if(msg_len > mod_sz)
220 throw Invalid_Argument("OpenSSL RSA sign input too large");
221
222 secure_vector<uint8_t> inbuf(mod_sz);
223 copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
224
225 secure_vector<uint8_t> outbuf(mod_sz);
226
227 int rc = ::RSA_private_encrypt(inbuf.size(), inbuf.data(), outbuf.data(),
228 m_openssl_rsa.get(), RSA_NO_PADDING);
229 if(rc < 0)
230 throw OpenSSL_Error("RSA_private_encrypt", ERR_get_error());
231
232 return outbuf;
233 }
234
235 size_t max_input_bits() const override
236 {
237 #if OPENSSL_VERSION_NUMBER < 0x10100000L
238 return ::BN_num_bits(m_openssl_rsa->n) - 1;
239 #else
240 return ::RSA_bits(m_openssl_rsa.get()) - 1;
241 #endif
242 }
243
244 private:
245 std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
246 };
247
248 }
249
250 std::unique_ptr<PK_Ops::Encryption>
251 make_openssl_rsa_enc_op(const RSA_PublicKey& key, const std::string& params)
252 {
253 auto pad_info = get_openssl_enc_pad(params);
254 return std::unique_ptr<PK_Ops::Encryption>(
255 new OpenSSL_RSA_Encryption_Operation(key, pad_info.first, pad_info.second));
256 }
257
258 std::unique_ptr<PK_Ops::Decryption>
259 make_openssl_rsa_dec_op(const RSA_PrivateKey& key, const std::string& params)
260 {
261 auto pad_info = get_openssl_enc_pad(params);
262 return std::unique_ptr<PK_Ops::Decryption>(new OpenSSL_RSA_Decryption_Operation(key, pad_info.first));
263 }
264
265 std::unique_ptr<PK_Ops::Verification>
266 make_openssl_rsa_ver_op(const RSA_PublicKey& key, const std::string& params)
267 {
268 return std::unique_ptr<PK_Ops::Verification>(new OpenSSL_RSA_Verification_Operation(key, params));
269 }
270
271 std::unique_ptr<PK_Ops::Signature>
272 make_openssl_rsa_sig_op(const RSA_PrivateKey& key, const std::string& params)
273 {
274 return std::unique_ptr<PK_Ops::Signature>(new OpenSSL_RSA_Signing_Operation(key, params));
275 }
276
277 std::unique_ptr<RSA_PrivateKey>
278 make_openssl_rsa_private_key(RandomNumberGenerator& rng, size_t rsa_bits)
279 {
280 if (rsa_bits > INT_MAX)
281 throw Internal_Error("rsa_bits overflow");
282
283 secure_vector<uint8_t> seed(BOTAN_SYSTEM_RNG_POLL_REQUEST);
284 rng.randomize(seed.data(), seed.size());
285 RAND_seed(seed.data(), seed.size());
286
287 std::unique_ptr<BIGNUM, std::function<void (BIGNUM*)>> bn(BN_new(), BN_free);
288 if(!bn)
289 throw OpenSSL_Error("BN_new", ERR_get_error());
290 if(!BN_set_word(bn.get(), RSA_F4))
291 throw OpenSSL_Error("BN_set_word", ERR_get_error());
292
293 std::unique_ptr<RSA, std::function<void (RSA*)>> rsa(RSA_new(), RSA_free);
294 if(!rsa)
295 throw OpenSSL_Error("RSA_new", ERR_get_error());
296 if(!RSA_generate_key_ex(rsa.get(), rsa_bits, bn.get(), nullptr))
297 throw OpenSSL_Error("RSA_generate_key_ex", ERR_get_error());
298
299 uint8_t* der = nullptr;
300 int bytes = i2d_RSAPrivateKey(rsa.get(), &der);
301 if(bytes < 0)
302 throw OpenSSL_Error("i2d_RSAPrivateKey", ERR_get_error());
303
304 const secure_vector<uint8_t> keydata(der, der + bytes);
305 secure_scrub_memory(der, bytes);
306 std::free(der);
307 return std::unique_ptr<Botan::RSA_PrivateKey>
308 (new RSA_PrivateKey(AlgorithmIdentifier(), keydata));
309 }
310 }
311
312 #endif // BOTAN_HAS_RSA
m_bits
std::vector< bitmask_type > m_bits
Definition: mem_pool.cpp:195
final
int(* final)(unsigned char *, CTX *)
Definition: commoncrypto_hash.cpp:28
Botan::CT::strip_leading_zeros
secure_vector< uint8_t > strip_leading_zeros(const uint8_t in[], size_t length)
Definition: ct_utils.cpp:65
Botan::CryptoBox::decrypt
std::string decrypt(const uint8_t input[], size_t input_len, const std::string &passphrase)
Definition: cryptobox.cpp:162
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:132
Botan
Definition: alg_id.cpp:13
Botan::secure_scrub_memory
void secure_scrub_memory(void *ptr, size_t n)
Definition: os_utils.cpp:66
Botan::OCSP::Response_Status_Code::Internal_Error
Botan::CryptoBox::encrypt
std::string encrypt(const uint8_t input[], size_t input_len, const std::string &passphrase, RandomNumberGenerator &rng)
Definition: cryptobox.cpp:43