28 #include "../detail/openssl-helper.hpp"    29 #include "../key-params.hpp"    30 #include "../../encoding/buffer-stream.hpp"    32 #include <boost/lexical_cast.hpp>    35 #define ENSURE_PRIVATE_KEY_LOADED(key) \    37     if ((key) == nullptr) \    38       BOOST_THROW_EXCEPTION(Error("Private key has not been loaded yet")); \    41 #define ENSURE_PRIVATE_KEY_NOT_LOADED(key) \    43     if ((key) != nullptr) \    44       BOOST_THROW_EXCEPTION(Error("Private key has already been loaded")); \    54 #if OPENSSL_VERSION_NUMBER < 0x1010000fL    55   static bool isInitialized = 
false;
    57     OpenSSL_add_all_algorithms();
    60 #endif // OPENSSL_VERSION_NUMBER < 0x1010000fL   109   if (d2i_AutoPrivateKey(&m_impl->key, &buf, static_cast<long>(size)) == 
nullptr)
   110     BOOST_THROW_EXCEPTION(
Error(
"Failed to load private key"));
   140   BOOST_ASSERT(std::strlen(pw) == pwLen);
   145   if (!membio.
write(buf, size))
   146     BOOST_THROW_EXCEPTION(
Error(
"Failed to copy buffer"));
   148   if (d2i_PKCS8PrivateKey_bio(membio, &m_impl->key, 
nullptr, const_cast<char*>(pw)) == 
nullptr)
   149     BOOST_THROW_EXCEPTION(
Error(
"Failed to load private key"));
   155   BOOST_ASSERT(size >= 0);
   157   return (*cb)(buf, 
static_cast<size_t>(size), rwflag);
   167   if (!membio.
write(buf, size))
   168     BOOST_THROW_EXCEPTION(
Error(
"Failed to copy buffer"));
   173     m_impl->key = d2i_PKCS8PrivateKey_bio(membio, 
nullptr, 
nullptr, 
nullptr);
   175   if (m_impl->key == 
nullptr)
   176     BOOST_THROW_EXCEPTION(
Error(
"Failed to load private key"));
   268   uint8_t* pkcs8 = 
nullptr;
   269   int len = i2d_PUBKEY(m_impl->key, &pkcs8);
   271     BOOST_THROW_EXCEPTION(
Error(
"Failed to derive public key"));
   273   auto result = make_shared<Buffer>(pkcs8, len);
   287       BOOST_THROW_EXCEPTION(
Error(
"Failed to determine key type"));
   289       return rsaDecrypt(cipherText, cipherLen);
   291       BOOST_THROW_EXCEPTION(
Error(
"Decryption is not supported for key type " + 
to_string(keyType)));
   296 PrivateKey::getEvpPkey()
 const   302 PrivateKey::toPkcs1()
 const   308   if (!i2d_PrivateKey_bio(membio, m_impl->key))
   309     BOOST_THROW_EXCEPTION(
Error(
"Cannot convert key to PKCS #1 format"));
   311   auto buffer = make_shared<Buffer>(BIO_pending(membio));
   312   membio.
read(buffer->data(), buffer->size());
   318 PrivateKey::toPkcs8(
const char* pw, 
size_t pwLen)
 const   320   BOOST_ASSERT(std::strlen(pw) == pwLen);
   325   if (!i2d_PKCS8PrivateKey_bio(membio, m_impl->key, EVP_des_ede3_cbc(), 
nullptr, 0,
   326                                nullptr, const_cast<char*>(pw)))
   327     BOOST_THROW_EXCEPTION(
Error(
"Cannot convert key to PKCS #8 format"));
   329   auto buffer = make_shared<Buffer>(BIO_pending(membio));
   330   membio.
read(buffer->data(), buffer->size());
   342   if (!i2d_PKCS8PrivateKey_bio(membio, m_impl->key, EVP_des_ede3_cbc(), 
nullptr, 0,
   344     BOOST_THROW_EXCEPTION(
Error(
"Cannot convert key to PKCS #8 format"));
   346   auto buffer = make_shared<Buffer>(BIO_pending(membio));
   347   membio.
read(buffer->data(), buffer->size());
   353 PrivateKey::rsaDecrypt(
const uint8_t* cipherText, 
size_t cipherLen)
 const   357   if (EVP_PKEY_decrypt_init(ctx) <= 0)
   358     BOOST_THROW_EXCEPTION(
Error(
"Failed to initialize decryption context"));
   360   if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
   361     BOOST_THROW_EXCEPTION(
Error(
"Failed to set padding"));
   365   if (EVP_PKEY_decrypt(ctx, 
nullptr, &outlen, cipherText, cipherLen) <= 0)
   366     BOOST_THROW_EXCEPTION(
Error(
"Failed to estimate output length"));
   368   auto out = make_shared<Buffer>(outlen);
   369   if (EVP_PKEY_decrypt(ctx, out->data(), &outlen, cipherText, cipherLen) <= 0)
   370     BOOST_THROW_EXCEPTION(
Error(
"Failed to decrypt ciphertext"));
   376 unique_ptr<PrivateKey>
   377 PrivateKey::generateRsaKey(uint32_t keySize)
   381   if (EVP_PKEY_keygen_init(kctx) <= 0)
   382     BOOST_THROW_EXCEPTION(
PrivateKey::Error(
"Failed to initialize RSA keygen context"));
   384   if (EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, static_cast<int>(keySize)) <= 0)
   387   auto privateKey = make_unique<PrivateKey>();
   388   if (EVP_PKEY_keygen(kctx, &privateKey->m_impl->key) <= 0)
   394 unique_ptr<PrivateKey>
   395 PrivateKey::generateEcKey(uint32_t keySize)
   399   if (EVP_PKEY_paramgen_init(pctx) <= 0)
   400     BOOST_THROW_EXCEPTION(
PrivateKey::Error(
"Failed to initialize EC paramgen context"));
   405       ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1); 
   408       ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp384r1);
   417   if (EVP_PKEY_paramgen(pctx, ¶ms.key) <= 0)
   421   if (EVP_PKEY_keygen_init(kctx) <= 0)
   422     BOOST_THROW_EXCEPTION(
PrivateKey::Error(
"Failed to initialize EC keygen context"));
   424   auto privateKey = make_unique<PrivateKey>();
   425   if (EVP_PKEY_keygen(kctx, &privateKey->m_impl->key) <= 0)
   431 unique_ptr<PrivateKey>
   437       return PrivateKey::generateRsaKey(rsaParams.
getKeySize());
   441       return PrivateKey::generateEcKey(ecParams.
getKeySize());
   444       BOOST_THROW_EXCEPTION(std::invalid_argument(
"Unsupported asymmetric key type " +
   445                                                   boost::lexical_cast<std::string>(keyParams.
getKeyType())));
 Copyright (c) 2011-2015 Regents of the University of California. 
 
int getEvpPkeyType(EVP_PKEY *key)
 
#define ENSURE_PRIVATE_KEY_NOT_LOADED(key)
 
KeyType getKeyType() const 
 
uint32_t getKeySize() const 
 
RSA key, supports sign/verify and encrypt/decrypt operations. 
 
unique_ptr< T > make_unique(Args &&...args)
 
#define ENSURE_PRIVATE_KEY_LOADED(key)
 
Catch-all error for security policy errors that don't fit in other categories. 
 
KeyType
The type of a cryptographic key. 
 
bool read(uint8_t *buf, size_t buflen) const noexcept
 
Elliptic Curve key (e.g. for ECDSA), supports sign/verify operations. 
 
shared_ptr< Buffer > buf()
Flush written data to the stream and return shared pointer to the underlying buffer. 
 
Base class of key parameters. 
 
implements an output stream that constructs ndn::Buffer 
 
std::string to_string(const V &v)
 
SimplePublicKeyParams is a template for public keys with only one parameter: size. 
 
shared_ptr< const Buffer > ConstBufferPtr
 
bool write(const uint8_t *buf, size_t buflen) noexcept