35 #include <boost/lexical_cast.hpp> 38 #define ENSURE_PRIVATE_KEY_LOADED(key) \ 40 if ((key) == nullptr) \ 41 NDN_THROW(Error("Private key has not been loaded yet")); \ 44 #define ENSURE_PRIVATE_KEY_NOT_LOADED(key) \ 46 if ((key) != nullptr) \ 47 NDN_THROW(Error("Private key has already been loaded")); \ 63 EVP_PKEY*
key =
nullptr;
67 : m_impl(make_unique<Impl>())
97 return static_cast<size_t>(EVP_PKEY_bits(m_impl->key));
100 EVP_PKEY_get_raw_private_key(m_impl->key,
nullptr, &nBytes);
113 boost::lexical_cast<std::string>(
getKeyType())));
116 const uint8_t* buf = EVP_PKEY_get0_hmac(m_impl->key, &len);
135 pkeyType = EVP_PKEY_HMAC;
138 NDN_THROW(std::invalid_argument(
"Unsupported key type " + boost::lexical_cast<std::string>(type)));
141 m_impl->key = EVP_PKEY_new_raw_private_key(pkeyType,
nullptr, buf.data(), buf.size());
142 if (m_impl->key ==
nullptr)
151 auto ptr = buf.data();
152 if (d2i_AutoPrivateKey(&m_impl->key, &ptr, static_cast<long>(buf.size())) ==
nullptr)
183 BOOST_ASSERT(std::strlen(pw) == pwLen);
187 if (!membio.
write(buf))
190 if (d2i_PKCS8PrivateKey_bio(membio, &m_impl->key,
nullptr, const_cast<char*>(pw)) ==
nullptr)
197 BOOST_ASSERT(size >= 0);
199 return (*cb)(buf,
static_cast<size_t>(
size), rwflag);
208 if (!membio.
write(buf))
214 m_impl->key = d2i_PKCS8PrivateKey_bio(membio,
nullptr,
nullptr,
nullptr);
216 if (m_impl->key ==
nullptr)
309 uint8_t* pkcs8 =
nullptr;
310 int len = i2d_PUBKEY(m_impl->key, &pkcs8);
314 auto result = make_shared<Buffer>(pkcs8, len);
330 return rsaDecrypt(cipherText);
337 PrivateKey::getEvpPkey()
const 343 PrivateKey::toPkcs1()
const 348 if (!i2d_PrivateKey_bio(membio, m_impl->key))
351 auto buffer = make_shared<Buffer>(BIO_pending(membio));
352 if (!membio.
read(*buffer))
359 PrivateKey::toPkcs8(
const char* pw,
size_t pwLen)
const 361 BOOST_ASSERT(std::strlen(pw) == pwLen);
365 if (!i2d_PKCS8PrivateKey_bio(membio, m_impl->key, EVP_aes_256_cbc(),
nullptr, 0,
366 nullptr, const_cast<char*>(pw)))
369 auto buffer = make_shared<Buffer>(BIO_pending(membio));
370 if (!membio.
read(*buffer))
382 if (!i2d_PKCS8PrivateKey_bio(membio, m_impl->key, EVP_aes_256_cbc(),
nullptr, 0,
386 auto buffer = make_shared<Buffer>(BIO_pending(membio));
387 if (!membio.
read(*buffer))
394 PrivateKey::rsaDecrypt(span<const uint8_t> cipherText)
const 398 if (EVP_PKEY_decrypt_init(ctx) <= 0)
401 if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
406 if (EVP_PKEY_decrypt(ctx,
nullptr, &outlen, cipherText.data(), cipherText.size()) <= 0)
409 auto out = make_shared<Buffer>(outlen);
410 if (EVP_PKEY_decrypt(ctx, out->data(), &outlen, cipherText.data(), cipherText.size()) <= 0)
417 unique_ptr<PrivateKey>
418 PrivateKey::generateRsaKey(uint32_t keySize)
422 if (EVP_PKEY_keygen_init(kctx) <= 0)
425 if (EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, static_cast<int>(keySize)) <= 0)
428 auto privateKey = make_unique<PrivateKey>();
429 if (EVP_PKEY_keygen(kctx, &privateKey->m_impl->key) <= 0)
435 unique_ptr<PrivateKey>
436 PrivateKey::generateEcKey(uint32_t keySize)
438 EC_KEY* eckey =
nullptr;
441 eckey = EC_KEY_new_by_curve_name(NID_secp224r1);
444 eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
447 eckey = EC_KEY_new_by_curve_name(NID_secp384r1);
450 eckey = EC_KEY_new_by_curve_name(NID_secp521r1);
455 if (eckey ==
nullptr) {
460 if (EC_KEY_generate_key(eckey) != 1) {
464 auto privateKey = make_unique<PrivateKey>();
465 privateKey->m_impl->key = EVP_PKEY_new();
466 if (privateKey->m_impl->key ==
nullptr)
468 if (EVP_PKEY_set1_EC_KEY(privateKey->m_impl->key, eckey) != 1)
474 unique_ptr<PrivateKey>
475 PrivateKey::generateHmacKey(uint32_t keySize)
477 std::vector<uint8_t> rawKey(keySize / 8);
480 auto privateKey = make_unique<PrivateKey>();
491 unique_ptr<PrivateKey>
496 const auto& rsaParams =
static_cast<const RsaKeyParams&
>(keyParams);
497 return PrivateKey::generateRsaKey(rsaParams.getKeySize());
500 const auto& ecParams =
static_cast<const EcKeyParams&
>(keyParams);
501 return PrivateKey::generateEcKey(ecParams.getKeySize());
504 const auto& hmacParams =
static_cast<const HmacKeyParams&
>(keyParams);
505 return PrivateKey::generateHmacKey(hmacParams.getKeySize());
508 NDN_THROW(std::invalid_argument(
"Unsupported key type " +
509 boost::lexical_cast<std::string>(keyParams.
getKeyType())));
NDN_CXX_NODISCARD bool read(span< uint8_t > buf) const noexcept
Copyright (c) 2011-2015 Regents of the University of California.
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.
int getEvpPkeyType(const EVP_PKEY *key)
#define ENSURE_PRIVATE_KEY_LOADED(key)
void generateSecureBytes(span< uint8_t > buf)
Fill buffer with cryptographically secure random bytes.
HMAC key, supports sign/verify operations.
KeyType
The type of a cryptographic key.
NDN_CXX_NODISCARD bool write(span< const uint8_t > buf) noexcept
scope_exit< EF > make_scope_exit(EF action)
Elliptic Curve key (e.g. for ECDSA), supports sign/verify operations.
KeyType getKeyType() const
shared_ptr< Buffer > buf()
Flush written data to the stream and return shared pointer to the underlying buffer.
Base class for key parameters.
implements an output stream that constructs ndn::Buffer
span_constexpr std::size_t size(span< T, Extent > const &spn)
SimplePublicKeyParams is a template for public keys with only one parameter: size.
shared_ptr< const Buffer > ConstBufferPtr