security: simplify PrivateKey implementation and improve error handling

Change-Id: I3270e4e9fe3dd942caab6bbe0b17db678b64648b
diff --git a/src/security/detail/openssl-helper.cpp b/src/security/detail/openssl-helper.cpp
index 8f8422a..12d1106 100644
--- a/src/security/detail/openssl-helper.cpp
+++ b/src/security/detail/openssl-helper.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -36,26 +36,18 @@
   }
 }
 
-EvpPkey::EvpPkey()
-  : m_key(nullptr)
-{
-}
-
-EvpPkey::~EvpPkey()
-{
-  EVP_PKEY_free(m_key);
-}
-
 EvpPkeyCtx::EvpPkeyCtx(EVP_PKEY* key)
   : m_ctx(EVP_PKEY_CTX_new(key, nullptr))
 {
-  BOOST_ASSERT(m_ctx != nullptr);
+  if (m_ctx == nullptr)
+    BOOST_THROW_EXCEPTION(std::runtime_error("EVP_PKEY_CTX creation failed"));
 }
 
 EvpPkeyCtx::EvpPkeyCtx(int id)
   : m_ctx(EVP_PKEY_CTX_new_id(id, nullptr))
 {
-  BOOST_ASSERT(m_ctx != nullptr);
+  if (m_ctx == nullptr)
+    BOOST_THROW_EXCEPTION(std::runtime_error("EVP_PKEY_CTX creation failed"));
 }
 
 EvpPkeyCtx::~EvpPkeyCtx()
@@ -63,14 +55,11 @@
   EVP_PKEY_CTX_free(m_ctx);
 }
 
-#if OPENSSL_VERSION_NUMBER < 0x1010000fL
-Bio::Bio(BIO_METHOD* method)
-#else
-Bio::Bio(const BIO_METHOD* method)
-#endif // OPENSSL_VERSION_NUMBER < 0x1010000fL
+Bio::Bio(Bio::MethodPtr method)
   : m_bio(BIO_new(method))
 {
-  BOOST_ASSERT(m_bio != nullptr);
+  if (m_bio == nullptr)
+    BOOST_THROW_EXCEPTION(std::runtime_error("BIO creation failed"));
 }
 
 Bio::~Bio()
@@ -78,6 +67,22 @@
   BIO_free_all(m_bio);
 }
 
+bool
+Bio::read(uint8_t* buf, size_t buflen) const noexcept
+{
+  BOOST_ASSERT(buflen <= std::numeric_limits<int>::max());
+  int n = BIO_read(m_bio, buf, static_cast<int>(buflen));
+  return n >= 0 && static_cast<size_t>(n) == buflen;
+}
+
+bool
+Bio::write(const uint8_t* buf, size_t buflen) noexcept
+{
+  BOOST_ASSERT(buflen <= std::numeric_limits<int>::max());
+  int n = BIO_write(m_bio, buf, static_cast<int>(buflen));
+  return n >= 0 && static_cast<size_t>(n) == buflen;
+}
+
 } // namespace detail
 } // namespace security
 } // namespace ndn
diff --git a/src/security/detail/openssl-helper.hpp b/src/security/detail/openssl-helper.hpp
index 50f21bc..ddd1ea6 100644
--- a/src/security/detail/openssl-helper.hpp
+++ b/src/security/detail/openssl-helper.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -22,8 +22,8 @@
 #ifndef NDN_CXX_SECURITY_DETAIL_OPENSSL_HELPER_HPP
 #define NDN_CXX_SECURITY_DETAIL_OPENSSL_HELPER_HPP
 
-#include "../security-common.hpp"
 #include "openssl.hpp"
+#include "../security-common.hpp"
 
 namespace ndn {
 namespace security {
@@ -32,30 +32,7 @@
 const EVP_MD*
 toDigestEvpMd(DigestAlgorithm algo);
 
-class EvpPkey
-{
-public:
-  EvpPkey();
-
-  ~EvpPkey();
-
-  EVP_PKEY*
-  get() const
-  {
-    return m_key;
-  }
-
-  EVP_PKEY**
-  operator&()
-  {
-    return &m_key;
-  }
-
-private:
-  EVP_PKEY* m_key;
-};
-
-class EvpPkeyCtx
+class EvpPkeyCtx : noncopyable
 {
 public:
   explicit
@@ -66,8 +43,7 @@
 
   ~EvpPkeyCtx();
 
-  EVP_PKEY_CTX*
-  get() const
+  operator EVP_PKEY_CTX*() const
   {
     return m_ctx;
   }
@@ -76,24 +52,31 @@
   EVP_PKEY_CTX* m_ctx;
 };
 
-class Bio
+class Bio : noncopyable
 {
 public:
-  explicit
 #if OPENSSL_VERSION_NUMBER < 0x1010000fL
-  Bio(BIO_METHOD* method);
+  using MethodPtr = BIO_METHOD*;
 #else
-  Bio(const BIO_METHOD* method);
+  using MethodPtr = const BIO_METHOD*;
 #endif // OPENSSL_VERSION_NUMBER < 0x1010000fL
 
+  explicit
+  Bio(MethodPtr method);
+
   ~Bio();
 
-  BIO*
-  get() const
+  operator BIO*() const
   {
     return m_bio;
   }
 
+  bool
+  read(uint8_t* buf, size_t buflen) const noexcept;
+
+  bool
+  write(const uint8_t* buf, size_t buflen) noexcept;
+
 private:
   BIO* m_bio;
 };