29 #include "ndn-cxx/security/impl/openssl-helper.hpp"    34 #include <boost/lexical_cast.hpp>    37 #define ENSURE_PRIVATE_KEY_LOADED(key) \    39     if ((key) == nullptr) \    40       NDN_THROW(Error("Private key has not been loaded yet")); \    43 #define ENSURE_PRIVATE_KEY_NOT_LOADED(key) \    45     if ((key) != nullptr) \    46       NDN_THROW(Error("Private key has already been loaded")); \    56 #if OPENSSL_VERSION_NUMBER < 0x1010000fL    57   static bool isInitialized = 
false;
    59     OpenSSL_add_all_algorithms();
    62 #endif // OPENSSL_VERSION_NUMBER < 0x1010000fL    65 class PrivateKey::Impl : noncopyable
    74   EVP_PKEY* key = 
nullptr;
    76 #if OPENSSL_VERSION_NUMBER < 0x1010100fL    82   : m_impl(make_unique<Impl>())
    94   switch (detail::getEvpPkeyType(m_impl->key)) {
   112       return static_cast<size_t>(EVP_PKEY_bits(m_impl->key));
   114 #if OPENSSL_VERSION_NUMBER >= 0x1010100fL   116       EVP_PKEY_get_raw_private_key(m_impl->key, 
nullptr, &nBytes);
   119       return m_impl->keySize;
   132                     boost::lexical_cast<std::string>(
getKeyType())));
   134   const uint8_t* 
buf = 
nullptr;
   136 #if OPENSSL_VERSION_NUMBER >= 0x1010000fL   137   buf = EVP_PKEY_get0_hmac(m_impl->key, &len);
   139   const auto* octstr = 
reinterpret_cast<ASN1_OCTET_STRING*
>(EVP_PKEY_get0(m_impl->key));
   141   len = octstr->length;
   161     pkeyType = EVP_PKEY_HMAC;
   164     NDN_THROW(std::invalid_argument(
"Unsupported key type " + boost::lexical_cast<std::string>(type)));
   168 #if OPENSSL_VERSION_NUMBER >= 0x1010100fL   169       EVP_PKEY_new_raw_private_key(pkeyType, 
nullptr, buf, size);
   171       EVP_PKEY_new_mac_key(pkeyType, 
nullptr, buf, static_cast<int>(size));
   173   if (m_impl->key == 
nullptr)
   176 #if OPENSSL_VERSION_NUMBER < 0x1010100fL   177   m_impl->keySize = size * 8;
   187   if (d2i_AutoPrivateKey(&m_impl->key, &buf, static_cast<long>(size)) == 
nullptr)
   218   BOOST_ASSERT(std::strlen(pw) == pwLen);
   222   detail::Bio membio(BIO_s_mem());
   223   if (!membio.write(buf, size))
   226   if (d2i_PKCS8PrivateKey_bio(membio, &m_impl->key, 
nullptr, const_cast<char*>(pw)) == 
nullptr)
   233   BOOST_ASSERT(size >= 0);
   235   return (*cb)(
buf, 
static_cast<size_t>(size), rwflag);
   244   detail::Bio membio(BIO_s_mem());
   245   if (!membio.write(buf, size))
   251     m_impl->key = d2i_PKCS8PrivateKey_bio(membio, 
nullptr, 
nullptr, 
nullptr);
   253   if (m_impl->key == 
nullptr)
   346   uint8_t* pkcs8 = 
nullptr;
   347   int len = i2d_PUBKEY(m_impl->key, &pkcs8);
   351   auto result = make_shared<Buffer>(pkcs8, len);
   362   int keyType = detail::getEvpPkeyType(m_impl->key);
   367       return rsaDecrypt(cipherText, cipherLen);
   374 PrivateKey::getEvpPkey()
 const   380 PrivateKey::toPkcs1()
 const   385   detail::Bio membio(BIO_s_mem());
   386   if (!i2d_PrivateKey_bio(membio, m_impl->key))
   389   auto buffer = make_shared<Buffer>(BIO_pending(membio));
   390   if (!membio.read(buffer->data(), buffer->size()))
   397 PrivateKey::toPkcs8(
const char* pw, 
size_t pwLen)
 const   399   BOOST_ASSERT(std::strlen(pw) == pwLen);
   403   detail::Bio membio(BIO_s_mem());
   404   if (!i2d_PKCS8PrivateKey_bio(membio, m_impl->key, EVP_aes_256_cbc(), 
nullptr, 0,
   405                                nullptr, const_cast<char*>(pw)))
   408   auto buffer = make_shared<Buffer>(BIO_pending(membio));
   409   if (!membio.read(buffer->data(), buffer->size()))
   421   detail::Bio membio(BIO_s_mem());
   422   if (!i2d_PKCS8PrivateKey_bio(membio, m_impl->key, EVP_aes_256_cbc(), 
nullptr, 0,
   426   auto buffer = make_shared<Buffer>(BIO_pending(membio));
   427   if (!membio.read(buffer->data(), buffer->size()))
   434 PrivateKey::rsaDecrypt(
const uint8_t* cipherText, 
size_t cipherLen)
 const   436   detail::EvpPkeyCtx ctx(m_impl->key);
   438   if (EVP_PKEY_decrypt_init(ctx) <= 0)
   441   if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
   446   if (EVP_PKEY_decrypt(ctx, 
nullptr, &outlen, cipherText, cipherLen) <= 0)
   449   auto out = make_shared<Buffer>(outlen);
   450   if (EVP_PKEY_decrypt(ctx, out->data(), &outlen, cipherText, cipherLen) <= 0)
   457 unique_ptr<PrivateKey>
   458 PrivateKey::generateRsaKey(uint32_t keySize)
   460   detail::EvpPkeyCtx kctx(EVP_PKEY_RSA);
   462   if (EVP_PKEY_keygen_init(kctx) <= 0)
   465   if (EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, static_cast<int>(keySize)) <= 0)
   468   auto privateKey = make_unique<PrivateKey>();
   469   if (EVP_PKEY_keygen(kctx, &privateKey->m_impl->key) <= 0)
   475 unique_ptr<PrivateKey>
   476 PrivateKey::generateEcKey(uint32_t keySize)
   478   detail::EvpPkeyCtx pctx(EVP_PKEY_EC);
   480   if (EVP_PKEY_paramgen_init(pctx) <= 0)
   486     ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp224r1);
   489     ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1); 
   492     ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp384r1);
   495     ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp521r1);
   504   if (EVP_PKEY_paramgen(pctx, ¶ms.key) <= 0)
   507   detail::EvpPkeyCtx kctx(params.key);
   508   if (EVP_PKEY_keygen_init(kctx) <= 0)
   511   auto privateKey = make_unique<PrivateKey>();
   512   if (EVP_PKEY_keygen(kctx, &privateKey->m_impl->key) <= 0)
   518 unique_ptr<PrivateKey>
   519 PrivateKey::generateHmacKey(uint32_t keySize)
   521   std::vector<uint8_t> rawKey(keySize / 8);
   524   auto privateKey = make_unique<PrivateKey>();
   526     privateKey->loadRaw(
KeyType::HMAC, rawKey.data(), rawKey.size());
   535 unique_ptr<PrivateKey>
   541       return PrivateKey::generateRsaKey(rsaParams.
getKeySize());
   545       return PrivateKey::generateEcKey(ecParams.
getKeySize());
   549       return PrivateKey::generateHmacKey(hmacParams.
getKeySize());
   552       NDN_THROW(std::invalid_argument(
"Unsupported key type " +
   553                                       boost::lexical_cast<std::string>(keyParams.
getKeyType())));
 
Unknown or unsupported key type. 
SimpleSymmetricKeyParams is a template for symmetric keys with only one parameter: size...
#define ENSURE_PRIVATE_KEY_NOT_LOADED(key)
std::string to_string(const T &val)
RSA key, supports sign/verify and encrypt/decrypt operations. 
#define ENSURE_PRIVATE_KEY_LOADED(key)
HMAC key, supports sign/verify operations. 
KeyType
The type of a cryptographic key. 
Elliptic Curve key (e.g. for ECDSA), supports sign/verify operations. 
uint32_t getKeySize() const
KeyType getKeyType() const
shared_ptr< Buffer > buf()
Flush written data to the stream and return shared pointer to the underlying buffer. 
void generateSecureBytes(uint8_t *bytes, size_t size)
Fill bytes of size with cryptographically secure random bytes. 
Base class for key parameters. 
uint32_t getKeySize() const
implements an output stream that constructs ndn::Buffer 
SimplePublicKeyParams is a template for public keys with only one parameter: size. 
shared_ptr< const Buffer > ConstBufferPtr