/* -*- 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/mp11/list.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);
}

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));
}

BOOST_AUTO_TEST_CASE(LoadRaw)
{
  const Buffer buf(32);
  PrivateKey sKey;
  sKey.loadRaw(KeyType::HMAC, buf);
  BOOST_CHECK_EQUAL(sKey.getKeyType(), KeyType::HMAC);
  BOOST_CHECK_EQUAL(sKey.getKeySize(), 256);

  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::mp11::mp_list<
#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::mp11::mp_list<
  HmacKeyGenParams,
  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
