28 #include "ndn-cxx/security/impl/openssl-helper.hpp" 32 #include <boost/lexical_cast.hpp> 35 #define ENSURE_PRIVATE_KEY_LOADED(key) \ 37 if ((key) == nullptr) \ 38 NDN_THROW(Error("Private key has not been loaded yet")); \ 41 #define ENSURE_PRIVATE_KEY_NOT_LOADED(key) \ 43 if ((key) != nullptr) \ 44 NDN_THROW(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 63 class PrivateKey::Impl
81 : m_impl(make_unique<Impl>())
93 switch (detail::getEvpPkeyType(m_impl->key)) {
109 if (d2i_AutoPrivateKey(&m_impl->key, &buf, static_cast<long>(size)) ==
nullptr)
140 BOOST_ASSERT(std::strlen(pw) == pwLen);
144 detail::Bio membio(BIO_s_mem());
145 if (!membio.write(buf, size))
148 if (d2i_PKCS8PrivateKey_bio(membio, &m_impl->key,
nullptr, const_cast<char*>(pw)) ==
nullptr)
155 BOOST_ASSERT(size >= 0);
157 return (*cb)(buf,
static_cast<size_t>(size), rwflag);
166 detail::Bio membio(BIO_s_mem());
167 if (!membio.write(buf, size))
173 m_impl->key = d2i_PKCS8PrivateKey_bio(membio,
nullptr,
nullptr,
nullptr);
175 if (m_impl->key ==
nullptr)
268 uint8_t* pkcs8 =
nullptr;
269 int len = i2d_PUBKEY(m_impl->key, &pkcs8);
273 auto result = make_shared<Buffer>(pkcs8, len);
284 int keyType = detail::getEvpPkeyType(m_impl->key);
289 return rsaDecrypt(cipherText, cipherLen);
296 PrivateKey::getEvpPkey()
const 302 PrivateKey::toPkcs1()
const 307 detail::Bio membio(BIO_s_mem());
308 if (!i2d_PrivateKey_bio(membio, m_impl->key))
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);
324 detail::Bio membio(BIO_s_mem());
325 if (!i2d_PKCS8PrivateKey_bio(membio, m_impl->key, EVP_aes_256_cbc(),
nullptr, 0,
326 nullptr, const_cast<char*>(pw)))
329 auto buffer = make_shared<Buffer>(BIO_pending(membio));
330 membio.read(buffer->data(), buffer->size());
341 detail::Bio membio(BIO_s_mem());
342 if (!i2d_PKCS8PrivateKey_bio(membio, m_impl->key, EVP_aes_256_cbc(),
nullptr, 0,
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 355 detail::EvpPkeyCtx ctx(m_impl->key);
357 if (EVP_PKEY_decrypt_init(ctx) <= 0)
360 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
365 if (EVP_PKEY_decrypt(ctx,
nullptr, &outlen, cipherText, cipherLen) <= 0)
368 auto out = make_shared<Buffer>(outlen);
369 if (EVP_PKEY_decrypt(ctx, out->data(), &outlen, cipherText, cipherLen) <= 0)
376 unique_ptr<PrivateKey>
377 PrivateKey::generateRsaKey(uint32_t keySize)
379 detail::EvpPkeyCtx kctx(EVP_PKEY_RSA);
381 if (EVP_PKEY_keygen_init(kctx) <= 0)
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)
397 detail::EvpPkeyCtx pctx(EVP_PKEY_EC);
399 if (EVP_PKEY_paramgen_init(pctx) <= 0)
405 ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp224r1);
408 ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1);
411 ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp384r1);
414 ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_secp521r1);
423 if (EVP_PKEY_paramgen(pctx, ¶ms.key) <= 0)
426 detail::EvpPkeyCtx kctx(params.key);
427 if (EVP_PKEY_keygen_init(kctx) <= 0)
430 auto privateKey = make_unique<PrivateKey>();
431 if (EVP_PKEY_keygen(kctx, &privateKey->m_impl->key) <= 0)
437 unique_ptr<PrivateKey>
443 return PrivateKey::generateRsaKey(rsaParams.
getKeySize());
447 return PrivateKey::generateEcKey(ecParams.
getKeySize());
450 NDN_THROW(std::invalid_argument(
"Unsupported asymmetric key type " +
451 boost::lexical_cast<std::string>(keyParams.
getKeyType())));
#define ENSURE_PRIVATE_KEY_NOT_LOADED(key)
KeyType getKeyType() const
uint32_t getKeySize() const
RSA key, supports sign/verify and encrypt/decrypt operations.
#define ENSURE_PRIVATE_KEY_LOADED(key)
KeyType
The type of a cryptographic key.
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