aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/rsa
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2015-12-19 16:34:42 -0500
committerJack Lloyd <[email protected]>2015-12-19 16:34:42 -0500
commita8b20fc90c6f2dc1df9f8533964c72cf29c947e0 (patch)
treefefe3754796f238bac73d1ce27cbb5056bfe455e /src/lib/pubkey/rsa
parent0fae1884079518e4f6d1c049cc7f341cd96c8a65 (diff)
Merge the openssl code together.
Having the code diffused all over the place was ugly and would not scale well to multiple alternative providers. GH #368
Diffstat (limited to 'src/lib/pubkey/rsa')
-rw-r--r--src/lib/pubkey/rsa/openssl_rsa.cpp283
1 files changed, 0 insertions, 283 deletions
diff --git a/src/lib/pubkey/rsa/openssl_rsa.cpp b/src/lib/pubkey/rsa/openssl_rsa.cpp
deleted file mode 100644
index a25c8552e..000000000
--- a/src/lib/pubkey/rsa/openssl_rsa.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
-* RSA operations provided by OpenSSL
-* (C) 2015 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/rsa.h>
-
-#if defined(BOTAN_HAS_OPENSSL)
-
-#include <botan/internal/openssl.h>
-#include <botan/internal/pk_utils.h>
-#include <botan/internal/ct_utils.h>
-#include <functional>
-#include <memory>
-
-#include <openssl/rsa.h>
-#include <openssl/x509.h>
-#include <openssl/err.h>
-
-namespace Botan {
-
-namespace {
-
-std::pair<int, size_t> get_openssl_enc_pad(const std::string& eme)
- {
- ERR_load_crypto_strings();
- if(eme == "Raw")
- return std::make_pair(RSA_NO_PADDING, 0);
- else if(eme == "EME-PKCS1-v1_5")
- return std::make_pair(RSA_PKCS1_PADDING, 11);
- else if(eme == "OAEP(SHA-1)")
- return std::make_pair(RSA_PKCS1_OAEP_PADDING, 41);
- else
- throw Lookup_Error("OpenSSL RSA does not support EME " + eme);
- }
-
-class OpenSSL_RSA_Encryption_Operation : public PK_Ops::Encryption
- {
- public:
- typedef RSA_PublicKey Key_Type;
-
- static OpenSSL_RSA_Encryption_Operation* make(const Spec& spec)
- {
- try
- {
- if(auto* key = dynamic_cast<const RSA_PublicKey*>(&spec.key()))
- {
- auto pad_info = get_openssl_enc_pad(spec.padding());
- return new OpenSSL_RSA_Encryption_Operation(*key, pad_info.first, pad_info.second);
- }
- }
- catch(...) {}
-
- return nullptr;
- }
-
- OpenSSL_RSA_Encryption_Operation(const RSA_PublicKey& rsa, int pad, size_t pad_overhead) :
- m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad)
- {
- const std::vector<byte> der = rsa.x509_subject_public_key();
- const byte* der_ptr = der.data();
- m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size()));
- if(!m_openssl_rsa)
- throw OpenSSL_Error("d2i_RSAPublicKey");
-
- m_bits = 8 * (n_size() - pad_overhead) - 1;
- }
-
- size_t max_input_bits() const override { return m_bits; };
-
- secure_vector<byte> encrypt(const byte msg[], size_t msg_len,
- RandomNumberGenerator&) override
- {
- const size_t mod_sz = n_size();
-
- if(msg_len > mod_sz)
- throw Invalid_Argument("Input too large for RSA key");
-
- secure_vector<byte> outbuf(mod_sz);
-
- secure_vector<byte> inbuf;
-
- if(m_padding == RSA_NO_PADDING)
- {
- inbuf.resize(mod_sz);
- copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
- }
- else
- {
- inbuf.assign(msg, msg + msg_len);
- }
-
- int rc = ::RSA_public_encrypt(inbuf.size(), inbuf.data(), outbuf.data(),
- m_openssl_rsa.get(), m_padding);
- if(rc < 0)
- throw OpenSSL_Error("RSA_public_encrypt");
-
- return outbuf;
- }
-
- private:
- size_t n_size() const { return ::RSA_size(m_openssl_rsa.get()); }
- std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
- size_t m_bits = 0;
- int m_padding = 0;
- };
-
-class OpenSSL_RSA_Decryption_Operation : public PK_Ops::Decryption
- {
- public:
- typedef RSA_PrivateKey Key_Type;
-
- static OpenSSL_RSA_Decryption_Operation* make(const Spec& spec)
- {
- try
- {
- if(auto* key = dynamic_cast<const RSA_PrivateKey*>(&spec.key()))
- {
- auto pad_info = get_openssl_enc_pad(spec.padding());
- return new OpenSSL_RSA_Decryption_Operation(*key, pad_info.first);
- }
- }
- catch(...) {}
-
- return nullptr;
- }
-
- OpenSSL_RSA_Decryption_Operation(const RSA_PrivateKey& rsa, int pad) :
- m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad)
- {
- const secure_vector<byte> der = rsa.pkcs8_private_key();
- const byte* der_ptr = der.data();
- m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
- if(!m_openssl_rsa)
- throw OpenSSL_Error("d2i_RSAPrivateKey");
- }
-
- size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; }
-
- secure_vector<byte> decrypt(const byte msg[], size_t msg_len) override
- {
- secure_vector<byte> buf(::RSA_size(m_openssl_rsa.get()));
- int rc = ::RSA_private_decrypt(msg_len, msg, buf.data(), m_openssl_rsa.get(), m_padding);
- if(rc < 0 || static_cast<size_t>(rc) > buf.size())
- throw OpenSSL_Error("RSA_private_decrypt");
- buf.resize(rc);
-
- if(m_padding == RSA_NO_PADDING)
- {
- return CT::strip_leading_zeros(buf);
- }
-
- return buf;
- }
-
- private:
- std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
- int m_padding = 0;
- };
-
-class OpenSSL_RSA_Verification_Operation : public PK_Ops::Verification_with_EMSA
- {
- public:
- typedef RSA_PublicKey Key_Type;
-
- static OpenSSL_RSA_Verification_Operation* make(const Spec& spec)
- {
- if(const RSA_PublicKey* rsa = dynamic_cast<const RSA_PublicKey*>(&spec.key()))
- {
- return new OpenSSL_RSA_Verification_Operation(*rsa, spec.padding());
- }
-
- return nullptr;
- }
-
- OpenSSL_RSA_Verification_Operation(const RSA_PublicKey& rsa, const std::string& emsa) :
- PK_Ops::Verification_with_EMSA(emsa),
- m_openssl_rsa(nullptr, ::RSA_free)
- {
- const std::vector<byte> der = rsa.x509_subject_public_key();
- const byte* der_ptr = der.data();
- m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size()));
- }
-
- size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; }
-
- bool with_recovery() const override { return true; }
-
- secure_vector<byte> verify_mr(const byte msg[], size_t msg_len) override
- {
- const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
-
- if(msg_len > mod_sz)
- throw Invalid_Argument("OpenSSL RSA verify input too large");
-
- secure_vector<byte> inbuf(mod_sz);
- copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
-
- secure_vector<byte> outbuf(mod_sz);
-
- int rc = ::RSA_public_decrypt(inbuf.size(), inbuf.data(), outbuf.data(),
- m_openssl_rsa.get(), RSA_NO_PADDING);
- if(rc < 0)
- throw Invalid_Argument("RSA_public_decrypt");
-
- return CT::strip_leading_zeros(outbuf);
- }
- private:
- std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
- };
-
-class OpenSSL_RSA_Signing_Operation : public PK_Ops::Signature_with_EMSA
- {
- public:
- typedef RSA_PrivateKey Key_Type;
-
- static OpenSSL_RSA_Signing_Operation* make(const Spec& spec)
- {
- if(const RSA_PrivateKey* rsa = dynamic_cast<const RSA_PrivateKey*>(&spec.key()))
- {
- return new OpenSSL_RSA_Signing_Operation(*rsa, spec.padding());
- }
-
- return nullptr;
- }
-
- OpenSSL_RSA_Signing_Operation(const RSA_PrivateKey& rsa, const std::string& emsa) :
- PK_Ops::Signature_with_EMSA(emsa),
- m_openssl_rsa(nullptr, ::RSA_free)
- {
- const secure_vector<byte> der = rsa.pkcs8_private_key();
- const byte* der_ptr = der.data();
- m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
- if(!m_openssl_rsa)
- throw OpenSSL_Error("d2i_RSAPrivateKey");
- }
-
- secure_vector<byte> raw_sign(const byte msg[], size_t msg_len,
- RandomNumberGenerator&) override
- {
- const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
-
- if(msg_len > mod_sz)
- throw Invalid_Argument("OpenSSL RSA sign input too large");
-
- secure_vector<byte> inbuf(mod_sz);
- copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
-
- secure_vector<byte> outbuf(mod_sz);
-
- int rc = ::RSA_private_encrypt(inbuf.size(), inbuf.data(), outbuf.data(),
- m_openssl_rsa.get(), RSA_NO_PADDING);
- if(rc < 0)
- throw OpenSSL_Error("RSA_private_encrypt");
-
- return outbuf;
- }
-
- size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; }
-
- private:
- std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
- };
-
-BOTAN_REGISTER_TYPE(PK_Ops::Verification, OpenSSL_RSA_Verification_Operation, "RSA",
- OpenSSL_RSA_Verification_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO);
-
-BOTAN_REGISTER_TYPE(PK_Ops::Signature, OpenSSL_RSA_Signing_Operation, "RSA",
- OpenSSL_RSA_Signing_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO);
-
-BOTAN_REGISTER_TYPE(PK_Ops::Encryption, OpenSSL_RSA_Encryption_Operation, "RSA",
- OpenSSL_RSA_Encryption_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO);
-
-BOTAN_REGISTER_TYPE(PK_Ops::Decryption, OpenSSL_RSA_Decryption_Operation, "RSA",
- OpenSSL_RSA_Decryption_Operation::make, "openssl", BOTAN_OPENSSL_RSA_PRIO);
-
-}
-
-}
-
-#endif // BOTAN_HAS_OPENSSL