security: insert OpenSSL initialization call in PrivateKey::loadPkcs8
Change-Id: I71dc0c3ac71fa5db4f3be8ce51aea06e4cf7c088
Refs: #4204
diff --git a/src/security/transform/private-key.cpp b/src/security/transform/private-key.cpp
index 9cad918..c67d3d9 100644
--- a/src/security/transform/private-key.cpp
+++ b/src/security/transform/private-key.cpp
@@ -1,5 +1,5 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
* Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -41,6 +41,18 @@
namespace security {
namespace transform {
+static void
+opensslInitAlgorithms()
+{
+#if OPENSSL_VERSION_NUMBER < 0x1010000fL
+ static bool isInitialized = false;
+ if (!isInitialized) {
+ OpenSSL_add_all_algorithms();
+ isInitialized = true;
+ }
+#endif // OPENSSL_VERSION_NUMBER < 0x1010000fL
+}
+
class PrivateKey::Impl
{
public:
@@ -104,6 +116,7 @@
PrivateKey::loadPkcs8(const uint8_t* buf, size_t size, const char* pw, size_t pwLen)
{
BOOST_ASSERT(std::strlen(pw) == pwLen);
+ opensslInitAlgorithms();
detail::Bio mem(BIO_s_mem());
BIO_write(mem.get(), buf, size);
@@ -116,14 +129,16 @@
static inline int
passwordCallback(char* buf, int size, int rwflag, void* u)
{
+ BOOST_ASSERT(size >= 0);
auto cb = reinterpret_cast<PrivateKey::PasswordCallback*>(u);
- return (*cb)(buf, size, rwflag);
+ return (*cb)(buf, static_cast<size_t>(size), rwflag);
}
void
PrivateKey::loadPkcs8(const uint8_t* buf, size_t size, PasswordCallback pwCallback)
{
- OpenSSL_add_all_algorithms();
+ opensslInitAlgorithms();
+
detail::Bio mem(BIO_s_mem());
BIO_write(mem.get(), buf, size);
@@ -246,10 +261,10 @@
#else
switch (EVP_PKEY_base_id(m_impl->key)) {
#endif // OPENSSL_VERSION_NUMBER < 0x1010000fL
- case EVP_PKEY_RSA:
- return rsaDecrypt(cipherText, cipherLen);
- default:
- BOOST_THROW_EXCEPTION(Error("Decryption is not supported for this key type"));
+ case EVP_PKEY_RSA:
+ return rsaDecrypt(cipherText, cipherLen);
+ default:
+ BOOST_THROW_EXCEPTION(Error("Decryption is not supported for this key type"));
}
}
@@ -263,8 +278,8 @@
PrivateKey::toPkcs1() const
{
ENSURE_PRIVATE_KEY_LOADED(m_impl->key);
+ opensslInitAlgorithms();
- OpenSSL_add_all_algorithms();
detail::Bio mem(BIO_s_mem());
int ret = i2d_PrivateKey_bio(mem.get(), m_impl->key);
if (ret != 1)
@@ -280,11 +295,10 @@
ConstBufferPtr
PrivateKey::toPkcs8(const char* pw, size_t pwLen) const
{
- ENSURE_PRIVATE_KEY_LOADED(m_impl->key);
-
BOOST_ASSERT(std::strlen(pw) == pwLen);
+ ENSURE_PRIVATE_KEY_LOADED(m_impl->key);
+ opensslInitAlgorithms();
- OpenSSL_add_all_algorithms();
detail::Bio mem(BIO_s_mem());
int ret = i2d_PKCS8PrivateKey_bio(mem.get(), m_impl->key, EVP_des_cbc(),
const_cast<char*>(pw), pwLen, nullptr, nullptr);
@@ -302,8 +316,8 @@
PrivateKey::toPkcs8(PasswordCallback pwCallback) const
{
ENSURE_PRIVATE_KEY_LOADED(m_impl->key);
+ opensslInitAlgorithms();
- OpenSSL_add_all_algorithms();
detail::Bio mem(BIO_s_mem());
int ret = i2d_PKCS8PrivateKey_bio(mem.get(), m_impl->key, EVP_des_cbc(),
nullptr, 0,