security: encode EC public key with named curve
refs #5037
Change-Id: I5d77782e347579fe6dffb188a92178f592bcd492
diff --git a/tests/unit/security/transform/private-key.t.cpp b/tests/unit/security/transform/private-key.t.cpp
index 2317479..738067a 100644
--- a/tests/unit/security/transform/private-key.t.cpp
+++ b/tests/unit/security/transform/private-key.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -31,6 +31,7 @@
#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"
@@ -160,8 +161,11 @@
"ywIDAQAB\n";
};
-struct EcKeyTestData
+struct EcKeySpecificCurveTestData
{
+ // EC keys are generated in named curve format only. However, old keys in specific curve format
+ // are still accepted. See https://redmine.named-data.net/issues/5037
+
const size_t keySize = 256;
const std::string privateKeyPkcs1 =
"MIIBaAIBAQQgRxwcbzK9RV6AHYFsDcykI86o3M/a1KlJn0z8PcLMBZOggfowgfcC\n"
@@ -193,7 +197,31 @@
"5EJTDxq6ls5FoYLfThp8HOjuwGSz0qw8ocMqyku1y0V5peQ4rEPd0bwcpZd9svA=\n";
};
-using KeyTestDataSets = boost::mpl::vector<RsaKeyTestData, EcKeyTestData>;
+struct EcKeyNamedCurveTestData
+{
+ // openssl ecparam -name secp384r1 -genkey -out pvt1.pem
+ // openssl pkcs8 -topk8 -passout pass:password -in pvt1.pem -out pvt8.pem
+ // openssl ec -in pvt1.pem -pubout -out pub8.pem
+
+ const size_t keySize = 384;
+ const std::string privateKeyPkcs1 =
+ "MIGkAgEBBDCUsb7NymksCkQAjdLMjUilWhOEyeYmGi79sX1RbsmfnoF/8SesKBhO\n"
+ "or+TZ8g8/8igBwYFK4EEACKhZANiAARWGplLOGdQiXRFQcd0VLPeTt0zXEj5zvSv\n"
+ "aHx9MrzBy57wgz10wTAiR561wuLtFAYxmqL9Ikrzx/BaEg0+v2zQ05NCzMNN8v2c\n"
+ "7/FzOhD7fmZrlJsT6Q2aHGExW0Rj3GE=\n";
+ const std::string privateKeyPkcs8 =
+ "MIHgMBsGCSqGSIb3DQEFAzAOBAjniUjwJfWsMQICCAAEgcCakGTKa49csaPpmtzi\n"
+ "5sTJw+AH8ajUqcDbtp2pJP/Ni6M1p9fai9hOKPElf9uJuYh/S80FAU6WQmZBAxL4\n"
+ "bF598ncLPogpGvz21wLuSc1xnbD829zAsMmh0XZvMZpBWX2g0NnZJx7GOraskTSh\n"
+ "7qGu70B+uKzw+JxIzgBEeMcoBUg8mTEht5zghfLGYkQp6BpTPdpU64udpPAKzFNs\n"
+ "5X+BzBnT5Yy49/Lp4uYIji8qwJFF3VqTn8RFKunFYDDejRU=\n";
+ const std::string publicKeyPkcs8 =
+ "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEVhqZSzhnUIl0RUHHdFSz3k7dM1xI+c70\n"
+ "r2h8fTK8wcue8IM9dMEwIkeetcLi7RQGMZqi/SJK88fwWhINPr9s0NOTQszDTfL9\n"
+ "nO/xczoQ+35ma5SbE+kNmhxhMVtEY9xh\n";
+};
+
+using KeyTestDataSets = boost::mpl::vector<RsaKeyTestData, EcKeySpecificCurveTestData, EcKeyNamedCurveTestData>;
static void
checkPkcs8Encoding(ConstBufferPtr encoding, const std::string& password, ConstBufferPtr pkcs1)
@@ -410,25 +438,48 @@
BOOST_CHECK_THROW(hmacKey->decrypt(os.buf()->data(), os.buf()->size()), PrivateKey::Error);
}
-struct RsaKeyGenParams
+class RsaKeyGenParams
{
+public:
using Params = RsaKeyParams;
using hasPublicKey = std::true_type;
using canSavePkcs1 = std::true_type;
+
+ static void
+ checkPublicKey(const Buffer& bits)
+ {
+ }
};
-struct EcKeyGenParams
+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));
+ }
};
-struct HmacKeyGenParams
+class HmacKeyGenParams
{
+public:
using Params = HmacKeyParams;
using hasPublicKey = std::false_type;
using canSavePkcs1 = std::false_type;
+
+ static void
+ checkPublicKey(const Buffer& bits)
+ {
+ }
};
using KeyGenParams = boost::mpl::vector<RsaKeyGenParams,
@@ -452,6 +503,8 @@
bool result = false;
if (typename T::hasPublicKey()) {
auto pKeyBits = sKey->derivePublicKey();
+ BOOST_REQUIRE(pKeyBits != nullptr);
+ T::checkPublicKey(*pKeyBits);
PublicKey pKey;
pKey.loadPkcs8(pKeyBits->data(), pKeyBits->size());
BOOST_CHECK_NO_THROW(bufferSource(data, sizeof(data)) >>