Botan  2.1.0
Crypto and TLS for C++11
openssl_rsa.cpp
Go to the documentation of this file.
1 /*
2 * RSA operations provided by OpenSSL
3 * (C) 2015 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/internal/openssl.h>
9 
10 #if defined(BOTAN_HAS_RSA)
11 
12 #include <botan/rsa.h>
13 #include <botan/internal/pk_ops_impl.h>
14 #include <botan/internal/ct_utils.h>
15 
16 #include <functional>
17 #include <memory>
18 
19 #include <openssl/rsa.h>
20 #include <openssl/x509.h>
21 #include <openssl/err.h>
22 
23 namespace Botan {
24 
25 namespace {
26 
27 std::pair<int, size_t> get_openssl_enc_pad(const std::string& eme)
28  {
29  ERR_load_crypto_strings();
30  if(eme == "Raw")
31  return std::make_pair(RSA_NO_PADDING, 0);
32  else if(eme == "EME-PKCS1-v1_5")
33  return std::make_pair(RSA_PKCS1_PADDING, 11);
34  else if(eme == "OAEP(SHA-1)" || eme == "EME1(SHA-1)")
35  return std::make_pair(RSA_PKCS1_OAEP_PADDING, 41);
36  else
37  throw Lookup_Error("OpenSSL RSA does not support EME " + eme);
38  }
39 
40 class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption
41  {
42  public:
43 
44  OpenSSL_RSA_Encryption_Operation(const RSA_PublicKey& rsa, int pad, size_t pad_overhead) :
45  m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad)
46  {
47  const std::vector<uint8_t> der = rsa.public_key_bits();
48  const uint8_t* der_ptr = der.data();
49  m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size()));
50  if(!m_openssl_rsa)
51  throw OpenSSL_Error("d2i_RSAPublicKey");
52 
53  m_bits = 8 * (n_size() - pad_overhead) - 1;
54  }
55 
56  size_t max_input_bits() const override { return m_bits; };
57 
58  secure_vector<uint8_t> encrypt(const uint8_t msg[], size_t msg_len,
59  RandomNumberGenerator&) override
60  {
61  const size_t mod_sz = n_size();
62 
63  if(msg_len > mod_sz)
64  throw Invalid_Argument("Input too large for RSA key");
65 
66  secure_vector<uint8_t> outbuf(mod_sz);
67 
68  secure_vector<uint8_t> inbuf;
69 
70  if(m_padding == RSA_NO_PADDING)
71  {
72  inbuf.resize(mod_sz);
73  copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
74  }
75  else
76  {
77  inbuf.assign(msg, msg + msg_len);
78  }
79 
80  int rc = ::RSA_public_encrypt(inbuf.size(), inbuf.data(), outbuf.data(),
81  m_openssl_rsa.get(), m_padding);
82  if(rc < 0)
83  throw OpenSSL_Error("RSA_public_encrypt");
84 
85  return outbuf;
86  }
87 
88  private:
89  size_t n_size() const { return ::RSA_size(m_openssl_rsa.get()); }
90  std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
91  size_t m_bits = 0;
92  int m_padding = 0;
93  };
94 
95 class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption
96  {
97  public:
98 
99  OpenSSL_RSA_Decryption_Operation(const RSA_PrivateKey& rsa, int pad) :
100  m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad)
101  {
102  const secure_vector<uint8_t> der = rsa.private_key_bits();
103  const uint8_t* der_ptr = der.data();
104  m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
105  if(!m_openssl_rsa)
106  throw OpenSSL_Error("d2i_RSAPrivateKey");
107  }
108 
109  secure_vector<uint8_t> decrypt(uint8_t& valid_mask,
110  const uint8_t msg[], size_t msg_len) override
111  {
112  secure_vector<uint8_t> buf(::RSA_size(m_openssl_rsa.get()));
113  int rc = ::RSA_private_decrypt(msg_len, msg, buf.data(), m_openssl_rsa.get(), m_padding);
114  if(rc < 0 || static_cast<size_t>(rc) > buf.size())
115  {
116  valid_mask = 0;
117  buf.resize(0);
118  }
119  else
120  {
121  valid_mask = 0xFF;
122  buf.resize(rc);
123  }
124 
125  if(m_padding == RSA_NO_PADDING)
126  {
127  return CT::strip_leading_zeros(buf);
128  }
129 
130  return buf;
131  }
132 
133  private:
134  std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
135  int m_padding = 0;
136  };
137 
138 class OpenSSL_RSA_Verification_Operation : public PK_Ops::Verification_with_EMSA
139  {
140  public:
141 
142  OpenSSL_RSA_Verification_Operation(const RSA_PublicKey& rsa, const std::string& emsa) :
143  PK_Ops::Verification_with_EMSA(emsa),
144  m_openssl_rsa(nullptr, ::RSA_free)
145  {
146  const std::vector<uint8_t> der = rsa.public_key_bits();
147  const uint8_t* der_ptr = der.data();
148  m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size()));
149  }
150 
151  size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; }
152 
153  bool with_recovery() const override { return true; }
154 
155  secure_vector<uint8_t> verify_mr(const uint8_t msg[], size_t msg_len) override
156  {
157  const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
158 
159  if(msg_len > mod_sz)
160  throw Invalid_Argument("OpenSSL RSA verify input too large");
161 
162  secure_vector<uint8_t> inbuf(mod_sz);
163  copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
164 
165  secure_vector<uint8_t> outbuf(mod_sz);
166 
167  int rc = ::RSA_public_decrypt(inbuf.size(), inbuf.data(), outbuf.data(),
168  m_openssl_rsa.get(), RSA_NO_PADDING);
169  if(rc < 0)
170  throw Invalid_Argument("RSA_public_decrypt");
171 
172  return CT::strip_leading_zeros(outbuf);
173  }
174  private:
175  std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
176  };
177 
178 class OpenSSL_RSA_Signing_Operation : public PK_Ops::Signature_with_EMSA
179  {
180  public:
181 
182  OpenSSL_RSA_Signing_Operation(const RSA_PrivateKey& rsa, const std::string& emsa) :
183  PK_Ops::Signature_with_EMSA(emsa),
184  m_openssl_rsa(nullptr, ::RSA_free)
185  {
186  const secure_vector<uint8_t> der = rsa.private_key_bits();
187  const uint8_t* der_ptr = der.data();
188  m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
189  if(!m_openssl_rsa)
190  throw OpenSSL_Error("d2i_RSAPrivateKey");
191  }
192 
193  secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len,
194  RandomNumberGenerator&) override
195  {
196  const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
197 
198  if(msg_len > mod_sz)
199  throw Invalid_Argument("OpenSSL RSA sign input too large");
200 
201  secure_vector<uint8_t> inbuf(mod_sz);
202  copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
203 
204  secure_vector<uint8_t> outbuf(mod_sz);
205 
206  int rc = ::RSA_private_encrypt(inbuf.size(), inbuf.data(), outbuf.data(),
207  m_openssl_rsa.get(), RSA_NO_PADDING);
208  if(rc < 0)
209  throw OpenSSL_Error("RSA_private_encrypt");
210 
211  return outbuf;
212  }
213 
214  size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; }
215 
216  private:
217  std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
218  };
219 
220 }
221 
222 std::unique_ptr<PK_Ops::Encryption>
223 make_openssl_rsa_enc_op(const RSA_PublicKey& key, const std::string& params)
224  {
225  auto pad_info = get_openssl_enc_pad(params);
226  return std::unique_ptr<PK_Ops::Encryption>(
227  new OpenSSL_RSA_Encryption_Operation(key, pad_info.first, pad_info.second));
228  }
229 
230 std::unique_ptr<PK_Ops::Decryption>
231 make_openssl_rsa_dec_op(const RSA_PrivateKey& key, const std::string& params)
232  {
233  auto pad_info = get_openssl_enc_pad(params);
234  return std::unique_ptr<PK_Ops::Decryption>(new OpenSSL_RSA_Decryption_Operation(key, pad_info.first));
235  }
236 
237 std::unique_ptr<PK_Ops::Verification>
238 make_openssl_rsa_ver_op(const RSA_PublicKey& key, const std::string& params)
239  {
240  return std::unique_ptr<PK_Ops::Verification>(new OpenSSL_RSA_Verification_Operation(key, params));
241  }
242 
243 std::unique_ptr<PK_Ops::Signature>
244 make_openssl_rsa_sig_op(const RSA_PrivateKey& key, const std::string& params)
245  {
246  return std::unique_ptr<PK_Ops::Signature>(new OpenSSL_RSA_Signing_Operation(key, params));
247  }
248 
249 }
250 
251 #endif // BOTAN_HAS_RSA
std::string encrypt(const uint8_t input[], size_t input_len, const std::string &passphrase, RandomNumberGenerator &rng)
Definition: cryptobox.cpp:42
std::string decrypt(const uint8_t input[], size_t input_len, const std::string &passphrase)
Definition: cryptobox.cpp:102
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:68
Definition: alg_id.cpp:13
secure_vector< uint8_t > strip_leading_zeros(const uint8_t in[], size_t length)
Definition: ct_utils.h:186