/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2023 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#include "ndn-cxx/security/transform/private-key.hpp"

#include "ndn-cxx/encoding/buffer-stream.hpp"
#include "ndn-cxx/security/key-params.hpp"
#include "ndn-cxx/security/transform/base64-decode.hpp"
#include "ndn-cxx/security/transform/bool-sink.hpp"
#include "ndn-cxx/security/transform/buffer-source.hpp"
#include "ndn-cxx/security/transform/public-key.hpp"
#include "ndn-cxx/security/transform/signer-filter.hpp"
#include "ndn-cxx/security/transform/stream-sink.hpp"
#include "ndn-cxx/security/transform/verifier-filter.hpp"
#include "ndn-cxx/util/string-helper.hpp"

#include "tests/boost-test.hpp"

#include <openssl/opensslv.h>
#include <boost/mpl/vector.hpp>
#include <sstream>

namespace ndn::tests {

using namespace ndn::security::transform;

BOOST_AUTO_TEST_SUITE(Security)
BOOST_AUTO_TEST_SUITE(Transform)
BOOST_AUTO_TEST_SUITE(TestPrivateKey)

BOOST_AUTO_TEST_CASE(Empty)
{
  // test invoking member functions on an empty (default-constructed) PrivateKey
  PrivateKey sKey;
  BOOST_CHECK_EQUAL(sKey.getKeyType(), KeyType::NONE);
  BOOST_CHECK_EQUAL(sKey.getKeySize(), 0);
  BOOST_CHECK_THROW(sKey.getKeyDigest(DigestAlgorithm::SHA256), PrivateKey::Error);
  BOOST_CHECK_THROW(sKey.derivePublicKey(), PrivateKey::Error);
  BOOST_CHECK_THROW(sKey.decrypt({}), PrivateKey::Error);
  std::ostringstream os;
  BOOST_CHECK_THROW(sKey.savePkcs1(os), PrivateKey::Error);
  std::string passwd("password");
  BOOST_CHECK_THROW(sKey.savePkcs8(os, passwd.data(), passwd.size()), PrivateKey::Error);
}

#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
BOOST_AUTO_TEST_CASE(KeyDigest)
{
  const Buffer buf(16);
  PrivateKey sKey;
  sKey.loadRaw(KeyType::HMAC, buf);
  auto digest = sKey.getKeyDigest(DigestAlgorithm::SHA256);

  const uint8_t expected[] = {
    0x37, 0x47, 0x08, 0xff, 0xf7, 0x71, 0x9d, 0xd5, 0x97, 0x9e, 0xc8, 0x75, 0xd5, 0x6c, 0xd2, 0x28,
    0x6f, 0x6d, 0x3c, 0xf7, 0xec, 0x31, 0x7a, 0x3b, 0x25, 0x63, 0x2a, 0xab, 0x28, 0xec, 0x37, 0xbb,
  };
  BOOST_CHECK_EQUAL_COLLECTIONS(digest->begin(), digest->end(),
                                expected, expected + sizeof(expected));
}
#endif

BOOST_AUTO_TEST_CASE(LoadRaw)
{
  const Buffer buf(32);
  PrivateKey sKey;
  sKey.loadRaw(KeyType::HMAC, buf);
#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
  BOOST_CHECK_EQUAL(sKey.getKeyType(), KeyType::HMAC);
  BOOST_CHECK_EQUAL(sKey.getKeySize(), 256);
#endif

  PrivateKey sKey2;
  BOOST_CHECK_THROW(sKey2.loadRaw(KeyType::NONE, buf), std::invalid_argument);
  BOOST_CHECK_THROW(sKey2.loadRaw(KeyType::RSA, buf), std::invalid_argument);
  BOOST_CHECK_THROW(sKey2.loadRaw(KeyType::EC, buf), std::invalid_argument);
  BOOST_CHECK_THROW(sKey2.loadRaw(KeyType::AES, buf), std::invalid_argument);
}

struct RsaKey_DesEncrypted
{
  const size_t keySize = 2048;
  const std::string privateKeyPkcs1 =
R"PEM(MIIEpAIBAAKCAQEAw0WM1/WhAxyLtEqsiAJgWDZWuzkYpeYVdeeZcqRZzzfRgBQT
sNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobws3iigohnM9yTK+KKiayPhIAm/+5H
GT6SgFJhYhqo1/upWdueojil6RP4/AgavHhopxlAVbk6G9VdVnlQcQ5Zv0OcGi73
c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9gZwIL5PuE9BiO6I39cL9z7EK1SfZh
OWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA9rH58ynaAix0tcR/nBMRLUX+e3rU
RHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0ywIDAQABAoIBADQkckOIl4IZMUTn
W8LFv6xOdkJwMKC8G6bsPRFbyY+HvC2TLt7epSvfS+f4AcYWaOPcDu2E49vt2sNr
cASly8hgwiRRAB3dHH9vcsboiTo8bi2RFvMqvjv9w3tK2yMxVDtmZamzrrnaV3YV
Q+5nyKo2F/PMDjQ4eUAKDOzjhBuKHsZBTFnA1MFNI+UKj5X4Yp64DFmKlxTX/U2b
wzVywo5hzx2Uhw51jmoLls4YUvMJXD0wW5ZtYRuPogXvXb/of9ef/20/wU11WFKg
Xb4gfR8zUXaXS1sXcnVm3+24vIs9dApUwykuoyjOqxWqcHRec2QT2FxVGkFEraze
CPa4rMECgYEA5Y8CywomIcTgerFGFCeMHJr8nQGqY2V/owFb3k9maczPnC9p4a9R
c5szLxA9FMYFxurQZMBWSEG2JS1HR2mnjigx8UKjYML/A+rvvjZOMe4M6Sy2ggh4
SkLZKpWTzjTe07ByM/j5v/SjNZhWAG7sw4/LmPGRQkwJv+KZhGojuOkCgYEA2cOF
T6cJRv6kvzTz9S0COZOVm+euJh/BXp7oAsAmbNfOpckPMzqHXy8/wpdKl6AAcB57
OuztlNfV1D7qvbz7JuRlYwQ0cEfBgbZPcz1p18HHDXhwn57ZPb8G33Yh9Omg0HNA
Imb4LsVuSqxA6NwSj7cpRekgTedrhLFPJ+Ydb5MCgYEAsM3Q7OjILcIg0t6uht9e
vrlwTsz1mtCV2co2I6crzdj9HeI2vqf1KAElDt6G7PUHhglcr/yjd8uEqmWRPKNX
ddnnfVZB10jYeP/93pac6z/Zmc3iU4yKeUe7U10ZFf0KkiiYDQd59CpLef/2XScS
HB0oRofnxRQjfjLc4muNT+ECgYEAlcDk06MOOTly+F8lCc1bA1dgAmgwFd2usDBd
Y07a3e0HGnGLN3Kfl7C5i0tZq64HvxLnMd2vgLVxQlXGPpdQrC1TH+XLXg+qnlZO
ivSH7i0/gx75bHvj75eH1XK65V8pDVDEoSPottllAIs21CxLw3N1ObOZWJm2EfmR
cuHICmsCgYAtFJ1idqMoHxES3mlRpf2JxyQudP3SCm2WpGmqVzhRYInqeatY5sUd
lPLHm/p77RT7EyxQHTlwn8FJPuM/4ZH1rQd/vB+Y8qAtYJCexDMsbvLW+Js+VOvk
jweEC0nrcL31j9mF0vz5E6tfRu4hhJ6L4yfWs0gSejskeVB/w8QY4g==
)PEM";
  const std::string privateKeyPkcs8 =
R"PEM(MIIFCzA9BgkqhkiG9w0BBQ0wMDAbBgkqhkiG9w0BBQwwDgQIOKYJXvB6p8kCAggA
MBEGBSsOAwIHBAiQgMK8kQXTyASCBMjeNiKYYw5/yHgs9BfSGrpqvV0LkkgMQNUW
R4ZY8fuNjZynd+PxDuw2pyrv1Yv3jc+tupwUehZEzYOnGd53wQAuLO+Z0TBgRFN7
Lhk+AxlT7hu0xaB3ZpJ/uvWpgEJHsq/aB/GYgyzXcQo2AiqzERVpMCWJVmE1L977
CHwJmLm5mxclVLYp1UK5lkIBFu/M4nPavmNmYNUU1LOrXRo56TlJ2kUp8gQyQI1P
VPxi4chmlsr/OnQ2d1eZN+euFm0CS+yP+LFgI9ZqdyH1w+J43SXdHDzauVcZp7oa
Kw24OrhHfolLAnQIECXEJYeT7tZmhC4O9V6B18PFVyxWnEU4eFNpFE8kYSmm8Um2
buvDKI71q43hm23moYT9uIM1f4M8UkoOliJGrlf4xgEcmDuokEX01PdOq1gc4nvG
0DCwDI9cOsyn8cxhk9UVtFgzuG/seuznxIv1F5H0hzYOyloStXxRisJES0kgByBt
FFTfyoFKRrmCjRIygwVKUSkSDR0DlQS5ZLvQyIswnSQFwxAHqfvoSL4dB9UAIAQ+
ALVF1maaHgptbL6Ifqf0GFCv0hdNCVNDNCdy8R+S6nEYE+YdYSIdT1L88KD5PjU3
YY/CMnxhTncMaT4acPO1UUYuSGRZ/JL6E0ihoqIU+bqUgLSHNzhPySPfN9uqN61Y
HFBtxeEPWKU0f/JPkRBMmZdMI1/OVmA3QHSRBydI+CQN8no2gZRFoVbHTkG8IMpE
1fiDJpwFkpzIv/JPiTSE7DeBH5NJk1bgu7TcuZfa4unyAqss0UuLnXzS06TppkUj
QGft0g8VPW56eli6B4xrSzzuvAdbrxsVfxdmtHPyYxLb3/UG1g4x/H/yULhx7x9P
iI6cw6JUE+8bwJV2ZIlHXXHO+wUp/gCFJ6MHo9wkR1QvnHP2ClJAzBm9OvYnUx2Y
SX0HxEowW8BkhxOF184LEmxeua0yyZUqCdrYmErp7x9EY/LhD1zBwH8OGRa0qzmR
VKxAPKihkb9OgxcUKbvKePx3k2cQ7fbCUspGPm4Kn1zwMgRAZ4fz/o8Lnwc8MSY3
lPWnmLTFu420SRH2g9N0o/r195hiZ5cc+KfF4pwZWKbEbKFk/UfXA9vmOi7BBtDJ
RWshOINhzMU6Ij3KuaEpHni1HoHjw0SQ97ow2x/aB8k2QC28tbsa49lD2KKJku6b
2Or89adwFKqMgS2IXfXMXs/iG5EFLYN6r8e40Dn5f1vJfRLJl03XByIfT2n92pw3
fP7muOIKLUsEKjOrmn94NwMlfeW13oQHEH2KjPOWFS/tyJHDdVU+of4COH5yg59a
TZqFkOTGeliE1O+6sfF9fRuVxFUF3D8Hpr0JIjdc6+3RgIlGsXc8BwiSjDSI2XW+
vo75/2zPU9t8OeXEIJk2CQGyqLwUJ6dyi/yDRrvZAgjrUvbpcxydnBAHrLbLUGXJ
aEHH2tjEtnTqVyTchr1yHoupcFOCkA0dAA66XqwcssQxJiMGrWTpCbgd9mrTXQaZ
U7afFN1jpO78tgBQUUpImXdHLLsqdN5tefqjileZGZ9x3/C6TNAfDwYJdsicNNn5
y+JVsbltfLWlJxb9teb3dtQiFlJ7ofprLJnJVqI/Js8lozY+KaxV2vtbZkcD4dM=
)PEM";
  const std::string publicKey =
R"PEM(MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw0WM1/WhAxyLtEqsiAJg
WDZWuzkYpeYVdeeZcqRZzzfRgBQTsNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobw
s3iigohnM9yTK+KKiayPhIAm/+5HGT6SgFJhYhqo1/upWdueojil6RP4/AgavHho
pxlAVbk6G9VdVnlQcQ5Zv0OcGi73c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9g
ZwIL5PuE9BiO6I39cL9z7EK1SfZhOWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA
9rH58ynaAix0tcR/nBMRLUX+e3rURHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0
ywIDAQAB
)PEM";
};

struct RsaKey_Aes256Encrypted
{
  // Generated with OpenSSL 3.0.0
  // openssl genpkey -quiet -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -outform PEM -out key.pem
  // openssl pkcs8 -in key.pem -nocrypt -traditional -outform PEM -out pvt1.pem
  // openssl pkcs8 -in key.pem -topk8 -v2 aes256 -passout pass:password -outform PEM -out pvt8.pem
  // openssl pkey -in key.pem -pubout -outform PEM -out pub.pem

  const size_t keySize = 2048;
  const std::string privateKeyPkcs1 =
R"PEM(MIIEowIBAAKCAQEAzEKtiRrzvhwGDMpsUlKMd7Veo9+lvLpttdX/ETo2exU36HqV
6zSM7LnpfqId7zug+l+VGwPd+oJOzROSCAoUcP3C3m9CkfqT97H9g2zdfwXqJnMQ
tnpAGngXOTF6RSBDVqo+jfeRw3c+MCXDZ0cHd49uv+CnWks6Sj+gowppdsQfvQRr
2incnwqht3JuaiTytxNrk6DjpoNTHyZJ53SY6DibGSk6aDFWMJcfvTZ6EuUbcepP
7HRwABn4Ctj1FTx3hDPe4sIrBFrbfP7yDQ9NxYh1baxXcCjWfCS43qUjrtcQFVkK
vE3uucmw1rf0C0Wy7dDvF2n1v+WLAEPSgJnumwIDAQABAoIBAEdNgWGKkIqNIsmF
QhHssg85t2tSL3t1wsWGic8cOJd3vTgAzuO3yPf8IBeuBPAVqyirhBPVokAIC/UH
v2LiDeexlbxrL1xhEhUVw48Eyj9Es8uvQCbK/ySeRlEXRfzqecc/j62kPfRzZDiP
fipHv8ILRlhh1lmtSBBSLMOtZ0pnJUmrNIOaFlJa56t0G3a+4C1u2swOtoCOWtyR
o7NAHiCcZNbnFQQSLyfDj3Sqnsaxke41A+gtrSeeUHkqnP0rxdmqChdyU36Yszi2
nB+yUXJT7Iw5GD+/vVUoby1/FVCRbh8zNfXvozC3llUSmsn3CBzVLoI+uwD5/zSz
+zMZ1x0CgYEA1o/cuEnALy+FXYbyrdV2R+ecy6t2/3WFDmK7+7klFFHcPBbmh/nL
OIjFPHVYUcyv2qW6JnCYqCutPOJ97JGvyScriNdg047UPGHaFaPZY/4rTXLm6tzN
I6E5eTRLkaFDVb96zYevxLjf88Lceocp2g8vR88kHqKe//0K8sBw+n0CgYEA87WA
CJOzmBdeWN7GbfA9rqxQq8qsFMaG+mJ5sE1MQHW5j/Hzsj6xi5qS9Uy8D9qlQiSV
nA/frqNBjaXiagVIqvfKvkkOFqRFIkVfGIJcYJk3tzi3tgdcHJ0B0LNCg/xHtjuZ
9KiuBNlDfkhsV6d7g/YQ0Sf/ghWmSGyOtVEtQPcCgYEAs5wYK1jpfVZtcN5/lc8k
RYr4MXJmmfB5opI6RL028eyYzOBquJb9bGTpnvOoLEmJSCIFUxpcYCK30UjUGs3V
9jBI/DM3hcGBns5W7liLqW3iN+IgtaiCPPpAj1qci9sP797rYNPd6nLMXlTXleZB
vZ2KebVHyjFdonLj0FQR/00CgYBSbXLuc7ZsnIrGmCKZEIZsS8/FKvlk1XjVuvTZ
kmtV6ftnGjiIcvft9cv6t4dr/VGju2f2rs/C62jClfasUTkwyjqCfYcMVWcknj35
ti20Zl4X1FEeegLHkrsIcXjv1yYSFrqNq3egIDPZxHkQdI8sJM+vTk33G4dwO3dR
EDG0JQKBgBeZhFw4R4MgCYUjNecw+k6AcU5J1JZ+KCJpSBv6J9ilQhkM0PeGLEab
TsurvpoIdAlqojgMnNf98gBahz+zjyLJEB+SPU6AGsahkQZ8wRY1a7ua/SjHPbCk
I3CkY6wqJK8vcjQkUQhE+5y1ZBIhQpH22eHyM4WMLaTFsL9yMvzY
)PEM";
  const std::string privateKeyPkcs8 =
R"PEM(MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIc3ZMcKTZDhcCAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBA1/62RtDr/mX2ZuI3Nq9tTBIIE
0ITRsiXopz4ox+k3ltt64vwQDLrKhm3uoz9lb885mD/wDkRU+02a3Kq+LjhExawM
Po8VVIbMjyXa3c2eYlmPOUXuXyMz8zi1NyDD1ypZTcVQxIT1ZZK+qsTlIy9Q2MIt
PU/Xg/nPCCJn7FBjkjqpGa942SVnvAbBLk342y8XozHmdbKYDVvNRjkYd6zUpR/n
5EG1AHBHNFySbtJSg5/6HU5sX6pM7LNAiTT3i0r8LcCWijHofhmUbCfrg+DdgW5+
ttmsTo/HZCjSSsHtd6xqxdOJyfvFIV1BvVKFP5X6OK8cnHtk/0SuNt2OROjvbOtU
JqSGkzV6MukagrMVtTu9BuXGNz8ee1zVglArEwHw13MihI9a/lGD/AujwjU9CdOd
jH6l2Ibp1MrSn52injoY9i6VmFSTktOrTrIzkGVevHcHkyZBqN3mwQRL3M16t0Bp
RJl01z5b7UYoSDO/w4BOtf6NK/zWix1+GHDnz9fplsaebiDF3YFOq6+p+1/14zPg
cfMkqgco6AGijPimhCQhMVnuWoBKcwIHCs6+sp02lI5HsVl3Lke4586w3qqOU9QY
L8iJFlLax/Sm9MVM/usWUaolXY6BElqkqhd3Z7KJoCazWos2oxVHkutKArNYf9XI
DV309jwBSnBDzmgDpXk7VZWFswxJIc8I1z5759wh370NJ06HeGCLvgBuLp6Dkq2c
hNqR32HWN7wjVqX2hB7X7RPjwX4a/z2oih/fQFc5WuIHfKWTviWcVq8jhIxocLqz
dSGWVvj6j0LoDh7s26iCXe6hb5N5khWHI6Dh7ZFC27aSejljyNqB+KEblIHvTPjS
WgGF14QTwDL6L4tpwtxoPG+QFnoHhM2ORkvwFkmQRmfSKeBfTapiRDLPQvlfIzTI
6Ie3l9gA4H14HqffawdwfP1fS/lOlLFH7SyO59tSjtVC3ErLMhHD+1R+Q3X1w/lF
jUZ2vwvE+86ikhxZvQCVOiCGXqry9qZfm67cuXD/tolAv5pV2qFDxHAEe5QqUYSv
bJTgo6zin1XByu3jlQPblcEeJ33iRcQDqh96GgMnJstsGuUjBREVjbNZ30YZYeVg
+L/h9otyO92Nq0knADHeixy9JZ2ATRMoTAT4XydSN9lHOh+K5pC3kf9pke2NCJyr
r/w9VQnQiIkxZ+THFshHHJxZZLlLwYWWr894rKftyZB+nDidNZfXr6K8VWoCAwh4
XwV6109KeHx86Kim9KQPn5RYVFdoxt2dO5O9vcXWtcNciIEi4MPyUM+oHwWrKTLX
EQsVu5gaz8vFt3lg0+Ctf8vAIA1/FxXEZ/BTAiV96lvRcUbXU2AdL+rNU2rtpqxH
h9L3r6IEN9WVIkNH5Q4CqSS9z+BxIPj76dA1MXK1nb8OJ9Y+BMPhktMz9M+KcVpD
1rXebv+/9Tw0lKLcNL50AglJOP+IRL0hHh62xtXs+FP5KocBs1kVAJORrS6wiy22
DGwcVmgTvWsPHzIf3IEa7DEjhClnU6alxKxCEmzPtm29upYXL9o3y7CMwidvCYpD
zFU2pIKA85YpjUYL25MiCyJPODc3VoW9l+rBqPu6bVWZXsfgsD4lcdFaJbPqcVby
PEe2dEUjhwpYgjbjOO7geMe+VeShipZJ63yFsNaPWzcz
)PEM";
  const std::string publicKey =
R"PEM(MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzEKtiRrzvhwGDMpsUlKM
d7Veo9+lvLpttdX/ETo2exU36HqV6zSM7LnpfqId7zug+l+VGwPd+oJOzROSCAoU
cP3C3m9CkfqT97H9g2zdfwXqJnMQtnpAGngXOTF6RSBDVqo+jfeRw3c+MCXDZ0cH
d49uv+CnWks6Sj+gowppdsQfvQRr2incnwqht3JuaiTytxNrk6DjpoNTHyZJ53SY
6DibGSk6aDFWMJcfvTZ6EuUbcepP7HRwABn4Ctj1FTx3hDPe4sIrBFrbfP7yDQ9N
xYh1baxXcCjWfCS43qUjrtcQFVkKvE3uucmw1rf0C0Wy7dDvF2n1v+WLAEPSgJnu
mwIDAQAB
)PEM";
};

struct EcKeySpecifiedCurve_DesEncrypted
{
  // EC keys are generated in "namedCurve" format only. However, old keys in "specifiedCurve"
  // format are still accepted. See https://redmine.named-data.net/issues/5037

  const size_t keySize = 256;
  const std::string privateKeyPkcs1 =
R"PEM(MIIBaAIBAQQgRxwcbzK9RV6AHYFsDcykI86o3M/a1KlJn0z8PcLMBZOggfowgfcC
AQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA////////////////
MFsEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57Pr
vVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEE
axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54W
K84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8
YyVRAgEBoUQDQgAEaG4WJuDAt0QkEM4t29KDUdzkQlMPGrqWzkWhgt9OGnwc6O7A
ZLPSrDyhwyrKS7XLRXml5DisQ93RvByll32y8A==
)PEM";
  const std::string privateKeyPkcs8 =
R"PEM(MIIBwzA9BgkqhkiG9w0BBQ0wMDAbBgkqhkiG9w0BBQwwDgQIVHkBzLGtDvICAggA
MBEGBSsOAwIHBAhk6g9eI3toNwSCAYDd+LWPDBTrKV7vUyxTvDbpUd0eXfh73DKA
MHkdHuVmhpmpBbsF9XvaFuL8J/1xi1Yl2XGw8j3WyrprD2YEhl/+zKjNbdTDJmNO
SlomuwWb5AVCJ9reT94zIXKCnexUcyBFS7ep+P4dwuef0VjzprjfmnAZHrP+u594
ELHpKwi0ZpQLtcJjjud13bn43vbXb+aU7jmPV5lU2XP8TxaQJiYIibNEh1Y3TZGr
akJormYvhaYbiZkKLHQ9AvQMEjhoIW5WCB3q+tKZUKTzcQpjNnf9FOTeKN3jk3Kd
2OmibPZcbMJdgCD/nRVn1cBo7Hjn3IMjgtszQHtEUphOQiAkOJUnKmy9MTYqtcNN
6cuFItbu4QvbVwailgdUjOYwIJCmIxExlPV0ohS24pFGsO03Yn7W8rBB9VWENYmG
HkZIbGsHv7O9Wy7fv+FJgZkjeti0807IsNXSJl8LUK0ZIhAR7OU8uONWMsbHdQnk
q1HB1ZKa52ugACl7g/DF9b7CoSAjFeE=
)PEM";
  const std::string publicKey =
R"PEM(MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAA
AAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA////
///////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSd
NgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5
RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA
//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABGhuFibgwLdEJBDOLdvSg1Hc
5EJTDxq6ls5FoYLfThp8HOjuwGSz0qw8ocMqyku1y0V5peQ4rEPd0bwcpZd9svA=
)PEM";
};

struct EcKeyNamedCurve_DesEncrypted
{
  // Generated with older (1.0.x?) OpenSSL
  // openssl ecparam -name secp384r1 -genkey -out pvt1.pem
  // openssl pkcs8 -in pvt1.pem -topk8 -passout pass:password -outform PEM -out pvt8.pem
  // openssl ec -in pvt1.pem -pubout -outform PEM -out pub.pem

  const size_t keySize = 384;
  const std::string privateKeyPkcs1 =
R"PEM(MIGkAgEBBDCUsb7NymksCkQAjdLMjUilWhOEyeYmGi79sX1RbsmfnoF/8SesKBhO
or+TZ8g8/8igBwYFK4EEACKhZANiAARWGplLOGdQiXRFQcd0VLPeTt0zXEj5zvSv
aHx9MrzBy57wgz10wTAiR561wuLtFAYxmqL9Ikrzx/BaEg0+v2zQ05NCzMNN8v2c
7/FzOhD7fmZrlJsT6Q2aHGExW0Rj3GE=
)PEM";
  const std::string privateKeyPkcs8 =
R"PEM(MIHgMBsGCSqGSIb3DQEFAzAOBAjniUjwJfWsMQICCAAEgcCakGTKa49csaPpmtzi
5sTJw+AH8ajUqcDbtp2pJP/Ni6M1p9fai9hOKPElf9uJuYh/S80FAU6WQmZBAxL4
bF598ncLPogpGvz21wLuSc1xnbD829zAsMmh0XZvMZpBWX2g0NnZJx7GOraskTSh
7qGu70B+uKzw+JxIzgBEeMcoBUg8mTEht5zghfLGYkQp6BpTPdpU64udpPAKzFNs
5X+BzBnT5Yy49/Lp4uYIji8qwJFF3VqTn8RFKunFYDDejRU=
)PEM";
  const std::string publicKey =
R"PEM(MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEVhqZSzhnUIl0RUHHdFSz3k7dM1xI+c70
r2h8fTK8wcue8IM9dMEwIkeetcLi7RQGMZqi/SJK88fwWhINPr9s0NOTQszDTfL9
nO/xczoQ+35ma5SbE+kNmhxhMVtEY9xh
)PEM";
};

struct EcKeyNamedCurve_Aes256Encrypted
{
  // Generated with OpenSSL 3.0.0
  // openssl genpkey -quiet -algorithm EC -pkeyopt ec_paramgen_curve:P-384
  //                 -pkeyopt ec_param_enc:named_curve -outform PEM -out key.pem
  // openssl pkcs8 -in key.pem -nocrypt -traditional -outform PEM -out pvt1.pem
  // openssl pkcs8 -in key.pem -topk8 -v2 aes256 -passout pass:password -outform PEM -out pvt8.pem
  // openssl pkey -in key.pem -pubout -outform PEM -out pub.pem

  const size_t keySize = 384;
  const std::string privateKeyPkcs1 =
R"PEM(MIGkAgEBBDAa5I6hfwcDZ8Hzn6/ZU3jV/Fp6jZP+tgUHSdMcfRS3iLOY296KdcXd
xISVHU3g+XygBwYFK4EEACKhZANiAAQh3xGTxgMFXwoRNBCrnzawZnoQUojZ1Qe5
3VrR+9ECawVf2sPklX+Lw1pE1TG5q+YepM8imRclRbXLBSGPF6f+qJCiFWR71XS2
CX2kW/AZOGluxYrVMe22ns5TY2o50G8=
)PEM";
  const std::string privateKeyPkcs8 =
R"PEM(MIIBHDBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIy4A7Il3JRNQCAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBPYOn/2qSDBlKhZ6+ckre8BIHA
jXwlDh+OX+1VayCWohXUooxZPfgKmIVkxhNrQzn0DV/FW9WbiXC72vss75/o5O2H
o4EuIOxnbxIM5HhsrdDY5g8Abkk5gKYt+eVJQn1EPAR+PU9T8OUKyQr9rO0Pvsu8
9h5V9+WFHNnNBTN3pqIV5cU25oVX7tqeZKs+5I4QIaq4hzPj+k15dLFaaq5XejZH
KjMKNdKbfz4TEs7u1W9YyrD3Z8/RgzLwVRjJqqOKeoJF4b1lOqOd5rWb4Oa06alr
)PEM";
  const std::string publicKey =
R"PEM(MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEId8Rk8YDBV8KETQQq582sGZ6EFKI2dUH
ud1a0fvRAmsFX9rD5JV/i8NaRNUxuavmHqTPIpkXJUW1ywUhjxen/qiQohVke9V0
tgl9pFvwGThpbsWK1THttp7OU2NqOdBv
)PEM";
};

struct EcKeyNamedCurve_Des3Encrypted
{
  // Generated with OpenSSL 3.0.0
  // openssl genpkey -quiet -algorithm EC -pkeyopt ec_paramgen_curve:P-256
  //                 -pkeyopt ec_param_enc:named_curve -outform PEM -out key.pem
  // openssl pkcs8 -in key.pem -nocrypt -traditional -outform PEM -out pvt1.pem
  // openssl pkcs8 -in key.pem -topk8 -v2 des3 -passout pass:password -outform PEM -out pvt8.pem
  // openssl pkey -in key.pem -pubout -outform PEM -out pub.pem

  const size_t keySize = 256;
  const std::string privateKeyPkcs1 =
R"PEM(MHcCAQEEIEbb/pnOVzkIZP4jrpZQCxl2OTJVQD7rHBJxxv8Aa215oAoGCCqGSM49
AwEHoUQDQgAEvSFhYwmFe17QAj0xhumERNJFf5MTkAegdE+db4ojchAbcDLRcnzY
+TUx5pTBqdBg+STMK7h36ZUn+KcMeizMRA==
)PEM";
  const std::string privateKeyPkcs8 =
R"PEM(MIHjME4GCSqGSIb3DQEFDTBBMCkGCSqGSIb3DQEFDDAcBAj2rY09BeCZGgICCAAw
DAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQI6CIHMAz7K7AEgZBzyr8QcH1OWEqc
ByPy4Vlze9D0izD7/NIxUeauHILqXMjU6Z057oYZ14Nm+DpbyJWu16gjZ2N+M2GH
4bH8gS6JUGhqtSbQ1Oo5lmjPXphefZp0tarv19Hp8S1VKmcVoj65kxfn5x0GKepg
fhXlMB2uQHvNoujU9PyeTZhwjAPQ6vHgFonbPPaL/f256NqMmnA=
)PEM";
  const std::string publicKey =
R"PEM(MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvSFhYwmFe17QAj0xhumERNJFf5MT
kAegdE+db4ojchAbcDLRcnzY+TUx5pTBqdBg+STMK7h36ZUn+KcMeizMRA==
)PEM";
};

using KeyTestDataSets = boost::mpl::vector<
#if OPENSSL_VERSION_NUMBER < 0x30000000L
  // DES-encrypted keys
  // .privateKeyPkcs8 uses either the PBES1 or PBES2 encryption scheme with DES-CBC-Pad (see RFC 8018)
  // This is no longer supported out-of-the-box by OpenSSL 3.0 and later
  RsaKey_DesEncrypted,
  EcKeySpecifiedCurve_DesEncrypted,
  EcKeyNamedCurve_DesEncrypted,
#endif
  // AES-encrypted keys
  // .privateKeyPkcs8 uses the PBES2 encryption scheme with AES-CBC-Pad (see RFC 8018)
  // This works with all supported versions of OpenSSL
  RsaKey_Aes256Encrypted,
  EcKeyNamedCurve_Aes256Encrypted,
  // 3DES-encrypted keys
  // .privateKeyPkcs8 uses the PBES2 encryption scheme with DES-EDE3-CBC-Pad (see RFC 8018)
  // This works with all supported versions of OpenSSL
  EcKeyNamedCurve_Des3Encrypted
>;

static void
checkPkcs8Encoding(const ConstBufferPtr& encoding,
                   const std::string& password,
                   const ConstBufferPtr& pkcs1)
{
  PrivateKey sKey;
  sKey.loadPkcs8(*encoding, password.data(), password.size());
  OBufferStream os;
  sKey.savePkcs1(os);
  BOOST_CHECK_EQUAL_COLLECTIONS(pkcs1->begin(), pkcs1->end(),
                                os.buf()->begin(), os.buf()->end());
}

static void
checkPkcs8Base64Encoding(const ConstBufferPtr& encoding,
                         const std::string& password,
                         const ConstBufferPtr& pkcs1)
{
  OBufferStream os;
  bufferSource(*encoding) >> base64Decode() >> streamSink(os);
  checkPkcs8Encoding(os.buf(), password, pkcs1);
}

BOOST_AUTO_TEST_CASE_TEMPLATE(SaveLoad, T, KeyTestDataSets)
{
  T dataSet;

  auto sKeyPkcs1Base64 = make_span(reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.data()),
                                   dataSet.privateKeyPkcs1.size());
  OBufferStream os;
  bufferSource(sKeyPkcs1Base64) >> base64Decode() >> streamSink(os);
  auto sKeyPkcs1 = os.buf();

  // load key in base64-encoded pkcs1 format
  PrivateKey sKey;
  BOOST_CHECK_NO_THROW(sKey.loadPkcs1Base64(sKeyPkcs1Base64));
  BOOST_CHECK_EQUAL(sKey.getKeySize(), dataSet.keySize);

  std::stringstream ss2(dataSet.privateKeyPkcs1);
  PrivateKey sKey2;
  BOOST_CHECK_NO_THROW(sKey2.loadPkcs1Base64(ss2));

  // load key in pkcs1 format
  PrivateKey sKey3;
  BOOST_CHECK_NO_THROW(sKey3.loadPkcs1(*sKeyPkcs1));
  BOOST_CHECK_EQUAL(sKey3.getKeySize(), dataSet.keySize);

  std::stringstream ss4;
  ss4.write(reinterpret_cast<const char*>(sKeyPkcs1->data()), sKeyPkcs1->size());
  PrivateKey sKey4;
  BOOST_CHECK_NO_THROW(sKey4.loadPkcs1(ss4));

  // save key in base64-encoded pkcs1 format
  OBufferStream os2;
  BOOST_REQUIRE_NO_THROW(sKey.savePkcs1Base64(os2));
  BOOST_CHECK_EQUAL_COLLECTIONS(sKeyPkcs1Base64.begin(), sKeyPkcs1Base64.end(),
                                os2.buf()->begin(), os2.buf()->end());

  // save key in pkcs1 format
  OBufferStream os3;
  BOOST_REQUIRE_NO_THROW(sKey.savePkcs1(os3));
  BOOST_CHECK_EQUAL_COLLECTIONS(sKeyPkcs1->begin(), sKeyPkcs1->end(),
                                os3.buf()->begin(), os3.buf()->end());

  auto sKeyPkcs8Base64 = make_span(reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs8.data()),
                                   dataSet.privateKeyPkcs8.size());
  OBufferStream os4;
  bufferSource(sKeyPkcs8Base64) >> base64Decode() >> streamSink(os4);
  auto sKeyPkcs8 = os4.buf();

  std::string password("password");
  std::string wrongpw("wrongpw");
  auto pwCallback = [&password] (char* buf, size_t size, int) -> int {
    BOOST_REQUIRE_LE(password.size(), size);
    std::copy(password.begin(), password.end(), buf);
    return static_cast<int>(password.size());
  };

  // load key in base64-encoded pkcs8 format
  PrivateKey sKey5;
  BOOST_CHECK_NO_THROW(sKey5.loadPkcs8Base64(sKeyPkcs8Base64, password.data(), password.size()));
  BOOST_CHECK_EQUAL(sKey5.getKeySize(), dataSet.keySize);

  PrivateKey sKey6;
  BOOST_CHECK_NO_THROW(sKey6.loadPkcs8Base64(sKeyPkcs8Base64, pwCallback));

  std::stringstream ss7(dataSet.privateKeyPkcs8);
  PrivateKey sKey7;
  BOOST_CHECK_NO_THROW(sKey7.loadPkcs8Base64(ss7, password.data(), password.size()));

  std::stringstream ss8(dataSet.privateKeyPkcs8);
  PrivateKey sKey8;
  BOOST_CHECK_NO_THROW(sKey8.loadPkcs8Base64(ss8, pwCallback));

  // load key in pkcs8 format
  PrivateKey sKey9;
  BOOST_CHECK_NO_THROW(sKey9.loadPkcs8(*sKeyPkcs8, password.data(), password.size()));
  BOOST_CHECK_EQUAL(sKey9.getKeySize(), dataSet.keySize);

  PrivateKey sKey10;
  BOOST_CHECK_NO_THROW(sKey10.loadPkcs8(*sKeyPkcs8, pwCallback));

  std::stringstream ss11;
  ss11.write(reinterpret_cast<const char*>(sKeyPkcs8->data()), sKeyPkcs8->size());
  PrivateKey sKey11;
  BOOST_CHECK_NO_THROW(sKey11.loadPkcs8(ss11, password.data(), password.size()));

  std::stringstream ss12;
  ss12.write(reinterpret_cast<const char*>(sKeyPkcs8->data()), sKeyPkcs8->size());
  PrivateKey sKey12;
  BOOST_CHECK_NO_THROW(sKey12.loadPkcs8(ss12, pwCallback));

  // load key using wrong password, Error is expected
  PrivateKey sKey13;
  BOOST_CHECK_THROW(sKey13.loadPkcs8Base64(sKeyPkcs8Base64, wrongpw.data(), wrongpw.size()),
                    PrivateKey::Error);
  BOOST_CHECK_EQUAL(sKey13.getKeyType(), KeyType::NONE);
  BOOST_CHECK_EQUAL(sKey13.getKeySize(), 0);

  // save key in base64-encoded pkcs8 format
  OBufferStream os14;
  BOOST_REQUIRE_NO_THROW(sKey.savePkcs8Base64(os14, password.data(), password.size()));
  checkPkcs8Base64Encoding(os14.buf(), password, sKeyPkcs1);

  OBufferStream os15;
  BOOST_REQUIRE_NO_THROW(sKey.savePkcs8Base64(os15, pwCallback));
  checkPkcs8Base64Encoding(os15.buf(), password, sKeyPkcs1);

  // save key in pkcs8 format
  OBufferStream os16;
  BOOST_REQUIRE_NO_THROW(sKey.savePkcs8(os16, password.data(), password.size()));
  checkPkcs8Encoding(os16.buf(), password, sKeyPkcs1);

  OBufferStream os17;
  BOOST_REQUIRE_NO_THROW(sKey.savePkcs8(os17, pwCallback));
  checkPkcs8Encoding(os17.buf(), password, sKeyPkcs1);
}

BOOST_AUTO_TEST_CASE_TEMPLATE(DerivePublicKey, T, KeyTestDataSets)
{
  T dataSet;

  auto sKeyPkcs1Base64 = make_span(reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.data()),
                                   dataSet.privateKeyPkcs1.size());
  PrivateKey sKey;
  sKey.loadPkcs1Base64(sKeyPkcs1Base64);

  // derive public key and compare
  ConstBufferPtr pKeyBits = sKey.derivePublicKey();
  OBufferStream os;
  bufferSource(dataSet.publicKey) >> base64Decode() >> streamSink(os);
  BOOST_CHECK_EQUAL_COLLECTIONS(pKeyBits->begin(), pKeyBits->end(),
                                os.buf()->begin(), os.buf()->end());
}

BOOST_AUTO_TEST_CASE(RsaDecryption)
{
  RsaKey_Aes256Encrypted dataSet;

  PrivateKey sKey;
  sKey.loadPkcs1Base64({reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.data()),
                        dataSet.privateKeyPkcs1.size()});
  BOOST_CHECK_EQUAL(sKey.getKeyType(), KeyType::RSA);

  const uint8_t plaintext[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};

  // Ciphertext generated with OpenSSL 3.0.0
  // printf ... | openssl pkeyutl -encrypt -inkey pub.pem -pubin -pkeyopt rsa_padding_mode:oaep | base64
  const std::string ciphertext =
R"BASE64(BgVqf6yKhMytCeL6+/oEoyx9rahh2+a1iU0D17RgfX6Q/3eNEcC2xY5QomjI7k/no8yiTZbXT9R4
REE6ic0DjFSbFwJjC/P0/oTSQyUNn4xNO+aK0MGnyeN34A8c3bZfLuo2DU496SQF0B9I5SS3gEA9
rqdIAdbWoOCKi1EX5SXtAOPTsj5PHHH+UM52bxOrUPvGSl9tRaz5S6hVf2haSoio4nnG3/bA6pdb
hHjyHHA/oi1PlFRIe0EO2/riAdqdIW3eOqZGP5t5QAMmiP178A9YQdbSavTgBSuE20T01U82Ln+L
pNk+PE/mmM20iNBo8C9cAJVUju6T4DCNZk7H5Q==
)BASE64";
  OBufferStream os;
  bufferSource(ciphertext) >> base64Decode() >> streamSink(os);

  auto decrypted = sKey.decrypt(*os.buf());
  BOOST_CHECK_EQUAL_COLLECTIONS(plaintext, plaintext + sizeof(plaintext),
                                decrypted->begin(), decrypted->end());
}

BOOST_AUTO_TEST_CASE(RsaEncryptDecrypt)
{
  RsaKey_Aes256Encrypted dataSet;

  PublicKey pKey;
  pKey.loadPkcs8Base64({reinterpret_cast<const uint8_t*>(dataSet.publicKey.data()),
                        dataSet.publicKey.size()});
  BOOST_CHECK_EQUAL(pKey.getKeyType(), KeyType::RSA);

  PrivateKey sKey;
  sKey.loadPkcs1Base64({reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.data()),
                        dataSet.privateKeyPkcs1.size()});
  BOOST_CHECK_EQUAL(sKey.getKeyType(), KeyType::RSA);

  const uint8_t plaintext[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};

  auto ciphertext = pKey.encrypt(plaintext);
  auto decrypted = sKey.decrypt(*ciphertext);
  BOOST_CHECK_EQUAL_COLLECTIONS(plaintext, plaintext + sizeof(plaintext),
                                decrypted->begin(), decrypted->end());
}

BOOST_AUTO_TEST_CASE(UnsupportedDecryption)
{
  OBufferStream os;
  bufferSource("Y2lhbyFob2xhIWhlbGxvIQ==") >> base64Decode() >> streamSink(os);

  auto ecKey = generatePrivateKey(EcKeyParams());
  BOOST_CHECK_THROW(ecKey->decrypt(*os.buf()), PrivateKey::Error);

  auto hmacKey = generatePrivateKey(HmacKeyParams());
  BOOST_CHECK_THROW(hmacKey->decrypt(*os.buf()), PrivateKey::Error);
}

class RsaKeyGenParams
{
public:
  using Params = RsaKeyParams;
  using hasPublicKey = std::true_type;
  using canSavePkcs1 = std::true_type;

  static void
  checkPublicKey(const Buffer&)
  {
  }
};

class EcKeyGenParams
{
public:
  using Params = EcKeyParams;
  using hasPublicKey = std::true_type;
  using canSavePkcs1 = std::true_type;

  static void
  checkPublicKey(const Buffer& bits)
  {
    // EC key generation should use named curve format. See https://redmine.named-data.net/issues/5037
    // OBJECT IDENTIFIER 1.2.840.10045.3.1.7 prime256v1 (ANSI X9.62 named elliptic curve)
    const uint8_t oid[] = {0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07};
    BOOST_CHECK_MESSAGE(std::search(bits.begin(), bits.end(), oid, oid + sizeof(oid)) != bits.end(),
                        "OID not found in " << toHex(bits));
  }
};

class HmacKeyGenParams
{
public:
  using Params = HmacKeyParams;
  using hasPublicKey = std::false_type;
  using canSavePkcs1 = std::false_type;

  static void
  checkPublicKey(const Buffer&)
  {
  }
};

using KeyGenParams = boost::mpl::vector<
#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
  HmacKeyGenParams,
#endif
  RsaKeyGenParams,
  EcKeyGenParams
>;

BOOST_AUTO_TEST_CASE_TEMPLATE(GenerateKey, T, KeyGenParams)
{
  typename T::Params params;
  auto sKey = generatePrivateKey(params);
  BOOST_CHECK_EQUAL(sKey->getKeyType(), params.getKeyType());
  BOOST_CHECK_EQUAL(sKey->getKeySize(), params.getKeySize());

  const uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
  OBufferStream os;
  BOOST_REQUIRE_NO_THROW(bufferSource(data) >>
                         signerFilter(DigestAlgorithm::SHA256, *sKey) >>
                         streamSink(os));
  auto sig = os.buf();

  bool result = false;
  if (typename T::hasPublicKey()) {
    auto pKeyBits = sKey->derivePublicKey();
    BOOST_REQUIRE(pKeyBits != nullptr);
    T::checkPublicKey(*pKeyBits);
    PublicKey pKey;
    pKey.loadPkcs8(*pKeyBits);
    BOOST_CHECK_NO_THROW(bufferSource(data) >>
                         verifierFilter(DigestAlgorithm::SHA256, pKey, *sig) >>
                         boolSink(result));
  }
  else {
    BOOST_CHECK_THROW(sKey->derivePublicKey(), PrivateKey::Error);
    BOOST_CHECK_NO_THROW(bufferSource(data) >>
                         verifierFilter(DigestAlgorithm::SHA256, *sKey, *sig) >>
                         boolSink(result));
  }
  BOOST_CHECK(result);

  if (typename T::canSavePkcs1()) {
    auto sKey2 = generatePrivateKey(params);

    OBufferStream os1;
    sKey->savePkcs1(os1);
    OBufferStream os2;
    sKey2->savePkcs1(os2);

    BOOST_CHECK(*os1.buf() != *os2.buf());
  }
  else {
    OBufferStream os1;
    BOOST_CHECK_THROW(sKey->savePkcs1(os1), PrivateKey::Error);
  }
}

BOOST_AUTO_TEST_CASE(GenerateKeyUnsupportedType)
{
  BOOST_CHECK_THROW(generatePrivateKey(AesKeyParams()), std::invalid_argument);
}

BOOST_AUTO_TEST_SUITE_END() // TestPrivateKey
BOOST_AUTO_TEST_SUITE_END() // Transform
BOOST_AUTO_TEST_SUITE_END() // Security

} // namespace ndn::tests
