security: add HMAC support to SignerFilter and VerifierFilter
Introduce HmacKeyParams
Add HMAC support to transform::PrivateKey
Deprecate HmacFilter
Refs: #3075
Change-Id: I16e24c1c4f278b08c7f51c91e9317b7820943536
diff --git a/tests/unit/security/key-params.t.cpp b/tests/unit/security/key-params.t.cpp
index 0fc6cd5..336520d 100644
--- a/tests/unit/security/key-params.t.cpp
+++ b/tests/unit/security/key-params.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -36,20 +36,20 @@
RsaKeyParams params;
BOOST_CHECK_EQUAL(params.getKeyType(), KeyType::RSA);
BOOST_CHECK_EQUAL(params.getKeySize(), 2048);
- BOOST_CHECK(params.getKeyIdType() == KeyIdType::RANDOM);
+ BOOST_CHECK_EQUAL(params.getKeyIdType(), KeyIdType::RANDOM);
RsaKeyParams params2(4096, KeyIdType::SHA256);
BOOST_CHECK_EQUAL(params2.getKeyType(), KeyType::RSA);
BOOST_CHECK_EQUAL(params2.getKeySize(), 4096);
- BOOST_CHECK(params2.getKeyIdType() == KeyIdType::SHA256);
+ BOOST_CHECK_EQUAL(params2.getKeyIdType(), KeyIdType::SHA256);
BOOST_CHECK_THROW(RsaKeyParams(1024), KeyParams::Error);
name::Component keyId("keyId");
RsaKeyParams params4(keyId);
- BOOST_CHECK(params4.getKeyType() == KeyType::RSA);
+ BOOST_CHECK_EQUAL(params4.getKeyType(), KeyType::RSA);
BOOST_CHECK_EQUAL(params4.getKeySize(), 2048);
- BOOST_CHECK(params4.getKeyIdType() == KeyIdType::USER_SPECIFIED);
+ BOOST_CHECK_EQUAL(params4.getKeyIdType(), KeyIdType::USER_SPECIFIED);
BOOST_CHECK_EQUAL(params4.getKeyId(), keyId);
}
@@ -58,20 +58,20 @@
EcKeyParams params;
BOOST_CHECK_EQUAL(params.getKeyType(), KeyType::EC);
BOOST_CHECK_EQUAL(params.getKeySize(), 256);
- BOOST_CHECK(params.getKeyIdType() == KeyIdType::RANDOM);
+ BOOST_CHECK_EQUAL(params.getKeyIdType(), KeyIdType::RANDOM);
EcKeyParams params2(384, KeyIdType::SHA256);
BOOST_CHECK_EQUAL(params2.getKeyType(), KeyType::EC);
BOOST_CHECK_EQUAL(params2.getKeySize(), 384);
- BOOST_CHECK(params2.getKeyIdType() == KeyIdType::SHA256);
+ BOOST_CHECK_EQUAL(params2.getKeyIdType(), KeyIdType::SHA256);
- BOOST_CHECK_THROW(EcKeyParams(3), KeyParams::Error);
+ BOOST_CHECK_THROW(EcKeyParams(64), KeyParams::Error);
name::Component keyId("keyId");
EcKeyParams params4(keyId);
- BOOST_CHECK(params4.getKeyType() == KeyType::EC);
+ BOOST_CHECK_EQUAL(params4.getKeyType(), KeyType::EC);
BOOST_CHECK_EQUAL(params4.getKeySize(), 256);
- BOOST_CHECK(params4.getKeyIdType() == KeyIdType::USER_SPECIFIED);
+ BOOST_CHECK_EQUAL(params4.getKeyIdType(), KeyIdType::USER_SPECIFIED);
BOOST_CHECK_EQUAL(params4.getKeyId(), keyId);
}
@@ -82,32 +82,73 @@
BOOST_CHECK_EQUAL(params.getKeyType(), KeyType::AES);
BOOST_CHECK_EQUAL(params.getKeySize(), 128);
BOOST_CHECK_EQUAL(params.getKeyIdType(), KeyIdType::USER_SPECIFIED);
+ BOOST_CHECK_EQUAL(params.getKeyId(), keyId);
AesKeyParams params2(keyId, 192);
- BOOST_CHECK(params2.getKeyType() == KeyType::AES);
+ BOOST_CHECK_EQUAL(params2.getKeyType(), KeyType::AES);
BOOST_CHECK_EQUAL(params2.getKeySize(), 192);
- BOOST_CHECK(params.getKeyIdType() == KeyIdType::USER_SPECIFIED);
+ BOOST_CHECK_EQUAL(params2.getKeyIdType(), KeyIdType::USER_SPECIFIED);
+ BOOST_CHECK_EQUAL(params2.getKeyId(), keyId);
AesKeyParams params3(keyId, 256);
BOOST_CHECK_EQUAL(params3.getKeyType(), KeyType::AES);
BOOST_CHECK_EQUAL(params3.getKeySize(), 256);
- BOOST_CHECK(params.getKeyIdType() == KeyIdType::USER_SPECIFIED);
+ BOOST_CHECK_EQUAL(params3.getKeyIdType(), KeyIdType::USER_SPECIFIED);
+ BOOST_CHECK_EQUAL(params3.getKeyId(), keyId);
- BOOST_CHECK_THROW(AesKeyParams(keyId, 4), KeyParams::Error);
+ BOOST_CHECK_THROW(AesKeyParams(keyId, 64), KeyParams::Error);
- AesKeyParams params5(keyId);
+ AesKeyParams params4;
+ BOOST_CHECK_EQUAL(params4.getKeyType(), KeyType::AES);
+ BOOST_CHECK_EQUAL(params4.getKeySize(), 128);
+ BOOST_CHECK_EQUAL(params4.getKeyIdType(), KeyIdType::RANDOM);
+
+ AesKeyParams params5(192);
BOOST_CHECK_EQUAL(params5.getKeyType(), KeyType::AES);
- BOOST_CHECK_EQUAL(params5.getKeySize(), 128);
- BOOST_CHECK_EQUAL(params5.getKeyIdType(), KeyIdType::USER_SPECIFIED);
- BOOST_CHECK_EQUAL(params5.getKeyId(), keyId);
-
- AesKeyParams params6(192);
- BOOST_CHECK(params6.getKeyType() == KeyType::AES);
- BOOST_CHECK_EQUAL(params6.getKeySize(), 192);
- BOOST_CHECK(params6.getKeyIdType() == KeyIdType::RANDOM);
+ BOOST_CHECK_EQUAL(params5.getKeySize(), 192);
+ BOOST_CHECK_EQUAL(params5.getKeyIdType(), KeyIdType::RANDOM);
}
-BOOST_AUTO_TEST_CASE(KeyIdTypeInfo)
+BOOST_AUTO_TEST_CASE(Hmac)
+{
+ name::Component keyId("keyId");
+ HmacKeyParams params(keyId);
+ BOOST_CHECK_EQUAL(params.getKeyType(), KeyType::HMAC);
+ BOOST_CHECK_EQUAL(params.getKeySize(), 256);
+ BOOST_CHECK_EQUAL(params.getKeyIdType(), KeyIdType::USER_SPECIFIED);
+ BOOST_CHECK_EQUAL(params.getKeyId(), keyId);
+
+ HmacKeyParams params2(keyId, 384);
+ BOOST_CHECK_EQUAL(params2.getKeyType(), KeyType::HMAC);
+ BOOST_CHECK_EQUAL(params2.getKeySize(), 384);
+ BOOST_CHECK_EQUAL(params2.getKeyIdType(), KeyIdType::USER_SPECIFIED);
+ BOOST_CHECK_EQUAL(params2.getKeyId(), keyId);
+
+ BOOST_CHECK_THROW(HmacKeyParams(keyId, 192), KeyParams::Error); // too short
+ BOOST_CHECK_THROW(HmacKeyParams(keyId, 300), KeyParams::Error); // not a multiple of 8
+
+ HmacKeyParams params3;
+ BOOST_CHECK_EQUAL(params3.getKeyType(), KeyType::HMAC);
+ BOOST_CHECK_EQUAL(params3.getKeySize(), 256);
+ BOOST_CHECK_EQUAL(params3.getKeyIdType(), KeyIdType::RANDOM);
+
+ HmacKeyParams params4(1024);
+ BOOST_CHECK_EQUAL(params4.getKeyType(), KeyType::HMAC);
+ BOOST_CHECK_EQUAL(params4.getKeySize(), 1024);
+ BOOST_CHECK_EQUAL(params4.getKeyIdType(), KeyIdType::RANDOM);
+}
+
+BOOST_AUTO_TEST_CASE(KeyTypeToString)
+{
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(KeyType::NONE), "NONE");
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(KeyType::RSA), "RSA");
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(KeyType::EC), "EC");
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(KeyType::AES), "AES");
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(KeyType::HMAC), "HMAC");
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(static_cast<KeyType>(12345)), "12345");
+}
+
+BOOST_AUTO_TEST_CASE(KeyIdTypeToString)
{
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(KeyIdType::USER_SPECIFIED), "USER_SPECIFIED");
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(KeyIdType::SHA256), "SHA256");
diff --git a/tests/unit/security/transform/private-key.t.cpp b/tests/unit/security/transform/private-key.t.cpp
index 0cef079..de1d9b2 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-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -22,8 +22,15 @@
#include "ndn-cxx/security/transform/private-key.hpp"
#include "ndn-cxx/encoding/buffer-stream.hpp"
+#include "ndn-cxx/security/impl/openssl.hpp"
#include "ndn-cxx/security/key-params.hpp"
-#include "ndn-cxx/security/transform.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 "tests/boost-test.hpp"
@@ -144,7 +151,7 @@
checkPkcs8Encoding(ConstBufferPtr encoding, const std::string& password, ConstBufferPtr pkcs1)
{
PrivateKey sKey;
- sKey.loadPkcs8(encoding->data(), encoding->size(), password.c_str(), password.size());
+ sKey.loadPkcs8(encoding->data(), encoding->size(), password.data(), password.size());
OBufferStream os;
sKey.savePkcs1(os);
BOOST_CHECK_EQUAL_COLLECTIONS(pkcs1->begin(), pkcs1->end(),
@@ -163,7 +170,7 @@
{
T dataSet;
- const uint8_t* sKeyPkcs1Base64 = reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.c_str());
+ const uint8_t* sKeyPkcs1Base64 = reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.data());
size_t sKeyPkcs1Base64Len = dataSet.privateKeyPkcs1.size();
OBufferStream os;
bufferSource(sKeyPkcs1Base64, sKeyPkcs1Base64Len) >> base64Decode() >> streamSink(os);
@@ -200,7 +207,7 @@
BOOST_CHECK_EQUAL_COLLECTIONS(sKeyPkcs1, sKeyPkcs1 + sKeyPkcs1Len,
os3.buf()->begin(), os3.buf()->end());
- const uint8_t* sKeyPkcs8Base64 = reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs8.c_str());
+ const uint8_t* sKeyPkcs8Base64 = reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs8.data());
size_t sKeyPkcs8Base64Len = dataSet.privateKeyPkcs8.size();
OBufferStream os4;
bufferSource(sKeyPkcs8Base64, sKeyPkcs8Base64Len) >> base64Decode() >> streamSink(os4);
@@ -218,14 +225,14 @@
// load key in base64-encoded pkcs8 format
PrivateKey sKey5;
BOOST_CHECK_NO_THROW(sKey5.loadPkcs8Base64(sKeyPkcs8Base64, sKeyPkcs8Base64Len,
- password.c_str(), password.size()));
+ password.data(), password.size()));
PrivateKey sKey6;
BOOST_CHECK_NO_THROW(sKey6.loadPkcs8Base64(sKeyPkcs8Base64, sKeyPkcs8Base64Len, pwCallback));
std::stringstream ss7(dataSet.privateKeyPkcs8);
PrivateKey sKey7;
- BOOST_CHECK_NO_THROW(sKey7.loadPkcs8Base64(ss7, password.c_str(), password.size()));
+ BOOST_CHECK_NO_THROW(sKey7.loadPkcs8Base64(ss7, password.data(), password.size()));
std::stringstream ss8(dataSet.privateKeyPkcs8);
PrivateKey sKey8;
@@ -233,7 +240,7 @@
// load key in pkcs8 format
PrivateKey sKey9;
- BOOST_CHECK_NO_THROW(sKey9.loadPkcs8(sKeyPkcs8, sKeyPkcs8Len, password.c_str(), password.size()));
+ BOOST_CHECK_NO_THROW(sKey9.loadPkcs8(sKeyPkcs8, sKeyPkcs8Len, password.data(), password.size()));
PrivateKey sKey10;
BOOST_CHECK_NO_THROW(sKey10.loadPkcs8(sKeyPkcs8, sKeyPkcs8Len, pwCallback));
@@ -241,7 +248,7 @@
std::stringstream ss11;
ss11.write(reinterpret_cast<const char*>(sKeyPkcs8), sKeyPkcs8Len);
PrivateKey sKey11;
- BOOST_CHECK_NO_THROW(sKey11.loadPkcs8(ss11, password.c_str(), password.size()));
+ BOOST_CHECK_NO_THROW(sKey11.loadPkcs8(ss11, password.data(), password.size()));
std::stringstream ss12;
ss12.write(reinterpret_cast<const char*>(sKeyPkcs8), sKeyPkcs8Len);
@@ -250,12 +257,12 @@
// load key using wrong password, Error is expected
PrivateKey sKey13;
- BOOST_CHECK_THROW(sKey13.loadPkcs8Base64(sKeyPkcs8Base64, sKeyPkcs8Base64Len, wrongpw.c_str(), wrongpw.size()),
+ BOOST_CHECK_THROW(sKey13.loadPkcs8Base64(sKeyPkcs8Base64, sKeyPkcs8Base64Len, wrongpw.data(), wrongpw.size()),
PrivateKey::Error);
// save key in base64-encoded pkcs8 format
OBufferStream os14;
- BOOST_REQUIRE_NO_THROW(sKey.savePkcs8Base64(os14, password.c_str(), password.size()));
+ BOOST_REQUIRE_NO_THROW(sKey.savePkcs8Base64(os14, password.data(), password.size()));
checkPkcs8Base64Encoding(os14.buf(), password, sKeyPkcs1Buf);
OBufferStream os15;
@@ -264,7 +271,7 @@
// save key in pkcs8 format
OBufferStream os16;
- BOOST_REQUIRE_NO_THROW(sKey.savePkcs8(os16, password.c_str(), password.size()));
+ BOOST_REQUIRE_NO_THROW(sKey.savePkcs8(os16, password.data(), password.size()));
checkPkcs8Encoding(os16.buf(), password, sKeyPkcs1Buf);
OBufferStream os17;
@@ -276,7 +283,7 @@
{
T dataSet;
- const uint8_t* sKeyPkcs1Base64 = reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.c_str());
+ const uint8_t* sKeyPkcs1Base64 = reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.data());
size_t sKeyPkcs1Base64Len = dataSet.privateKeyPkcs1.size();
PrivateKey sKey;
sKey.loadPkcs1Base64(sKeyPkcs1Base64, sKeyPkcs1Base64Len);
@@ -294,7 +301,7 @@
RsaKeyTestData dataSet;
PrivateKey sKey;
- sKey.loadPkcs1Base64(reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.c_str()),
+ sKey.loadPkcs1Base64(reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.data()),
dataSet.privateKeyPkcs1.size());
BOOST_CHECK_EQUAL(sKey.getKeyType(), KeyType::RSA);
@@ -320,12 +327,12 @@
RsaKeyTestData dataSet;
PublicKey pKey;
- pKey.loadPkcs8Base64(reinterpret_cast<const uint8_t*>(dataSet.publicKeyPkcs8.c_str()),
+ pKey.loadPkcs8Base64(reinterpret_cast<const uint8_t*>(dataSet.publicKeyPkcs8.data()),
dataSet.publicKeyPkcs8.size());
BOOST_CHECK_EQUAL(pKey.getKeyType(), KeyType::RSA);
PrivateKey sKey;
- sKey.loadPkcs1Base64(reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.c_str()),
+ sKey.loadPkcs1Base64(reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.data()),
dataSet.privateKeyPkcs1.size());
BOOST_CHECK_EQUAL(sKey.getKeyType(), KeyType::RSA);
@@ -337,57 +344,94 @@
decrypted->begin(), decrypted->end());
}
-BOOST_AUTO_TEST_CASE(UnsupportedEcDecryption)
+BOOST_AUTO_TEST_CASE(UnsupportedDecryption)
{
- EcKeyTestData dataSet;
-
- PrivateKey sKey;
- sKey.loadPkcs1Base64(reinterpret_cast<const uint8_t*>(dataSet.privateKeyPkcs1.c_str()),
- dataSet.privateKeyPkcs1.size());
- BOOST_CHECK_EQUAL(sKey.getKeyType(), KeyType::EC);
-
OBufferStream os;
bufferSource("Y2lhbyFob2xhIWhlbGxvIQ==") >> base64Decode() >> streamSink(os);
- BOOST_CHECK_THROW(sKey.decrypt(os.buf()->data(), os.buf()->size()), PrivateKey::Error);
+ auto ecKey = generatePrivateKey(EcKeyParams());
+ BOOST_CHECK_THROW(ecKey->decrypt(os.buf()->data(), os.buf()->size()), PrivateKey::Error);
+
+ auto hmacKey = generatePrivateKey(HmacKeyParams());
+ BOOST_CHECK_THROW(hmacKey->decrypt(os.buf()->data(), os.buf()->size()), PrivateKey::Error);
}
-using KeyParams = boost::mpl::vector<RsaKeyParams, EcKeyParams>;
-
-BOOST_AUTO_TEST_CASE_TEMPLATE(GenerateKey, T, KeyParams)
+struct RsaKeyGenParams
{
- unique_ptr<PrivateKey> sKey = generatePrivateKey(T());
- PublicKey pKey;
- ConstBufferPtr pKeyBits = sKey->derivePublicKey();
- pKey.loadPkcs8(pKeyBits->data(), pKeyBits->size());
+ using Params = RsaKeyParams;
+ using hasPublicKey = std::true_type;
+ using canSavePkcs1 = std::true_type;
+};
+
+struct EcKeyGenParams
+{
+ using Params = EcKeyParams;
+ using hasPublicKey = std::true_type;
+ using canSavePkcs1 = std::true_type;
+};
+
+struct HmacKeyGenParams
+{
+ using Params = HmacKeyParams;
+ using hasPublicKey = std::false_type;
+ using canSavePkcs1 = std::false_type;
+};
+
+using KeyGenParams = boost::mpl::vector<RsaKeyGenParams,
+ EcKeyGenParams,
+ HmacKeyGenParams>;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(GenerateKey, T, KeyGenParams)
+{
+ unique_ptr<PrivateKey> sKey = generatePrivateKey(typename T::Params());
+ BOOST_CHECK_NE(sKey->getKeyType(), KeyType::NONE);
+ BOOST_CHECK_GT(sKey->getKeySize(), 0);
const uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
OBufferStream os;
BOOST_REQUIRE_NO_THROW(bufferSource(data, sizeof(data)) >>
signerFilter(DigestAlgorithm::SHA256, *sKey) >>
streamSink(os));
+ auto sig = os.buf();
- ConstBufferPtr sig = os.buf();
bool result = false;
- BOOST_REQUIRE_NO_THROW(bufferSource(data, sizeof(data)) >>
+ if (typename T::hasPublicKey()) {
+ auto pKeyBits = sKey->derivePublicKey();
+ PublicKey pKey;
+ pKey.loadPkcs8(pKeyBits->data(), pKeyBits->size());
+ BOOST_CHECK_NO_THROW(bufferSource(data, sizeof(data)) >>
verifierFilter(DigestAlgorithm::SHA256, pKey, sig->data(), sig->size()) >>
boolSink(result));
+ }
+ else {
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL
+ BOOST_CHECK_THROW(sKey->derivePublicKey(), PrivateKey::Error);
+#endif
+ BOOST_CHECK_NO_THROW(bufferSource(data, sizeof(data)) >>
+ verifierFilter(DigestAlgorithm::SHA256, *sKey, sig->data(), sig->size()) >>
+ boolSink(result));
+ }
BOOST_CHECK(result);
- unique_ptr<PrivateKey> sKey2 = generatePrivateKey(T());
+ if (typename T::canSavePkcs1()) {
+ unique_ptr<PrivateKey> sKey2 = generatePrivateKey(typename T::Params());
- OBufferStream os1;
- sKey->savePkcs1(os1);
- ConstBufferPtr key1Pkcs1 = os1.buf();
+ OBufferStream os1;
+ sKey->savePkcs1(os1);
+ OBufferStream os2;
+ sKey2->savePkcs1(os2);
- OBufferStream os2;
- sKey2->savePkcs1(os2);
- ConstBufferPtr key2Pkcs1 = os2.buf();
-
- BOOST_CHECK(*key1Pkcs1 != *key2Pkcs1);
+ BOOST_CHECK(*os1.buf() != *os2.buf());
+ }
+ else {
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL
+ OBufferStream os1;
+ BOOST_CHECK_THROW(sKey->savePkcs1(os1), PrivateKey::Error);
+#endif
+ }
}
-BOOST_AUTO_TEST_CASE(UnsupportedKeyType)
+BOOST_AUTO_TEST_CASE(GenerateKeyUnsupportedType)
{
BOOST_CHECK_THROW(generatePrivateKey(AesKeyParams()), std::invalid_argument);
}
diff --git a/tests/unit/security/transform/signer-filter.t.cpp b/tests/unit/security/transform/signer-filter.t.cpp
index aa6f6e3..4c75204 100644
--- a/tests/unit/security/transform/signer-filter.t.cpp
+++ b/tests/unit/security/transform/signer-filter.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -22,6 +22,7 @@
#include "ndn-cxx/security/transform/signer-filter.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/buffer-source.hpp"
#include "ndn-cxx/security/transform/private-key.hpp"
@@ -39,6 +40,8 @@
BOOST_AUTO_TEST_SUITE(Transform)
BOOST_AUTO_TEST_SUITE(TestSignerFilter)
+const uint8_t DATA[] = {0x01, 0x02, 0x03, 0x04};
+
BOOST_AUTO_TEST_CASE(Rsa)
{
const std::string publicKeyPkcs8 =
@@ -75,7 +78,6 @@
"cuHICmsCgYAtFJ1idqMoHxES3mlRpf2JxyQudP3SCm2WpGmqVzhRYInqeatY5sUd\n"
"lPLHm/p77RT7EyxQHTlwn8FJPuM/4ZH1rQd/vB+Y8qAtYJCexDMsbvLW+Js+VOvk\n"
"jweEC0nrcL31j9mF0vz5E6tfRu4hhJ6L4yfWs0gSejskeVB/w8QY4g==\n";
- const uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
OBufferStream os1;
bufferSource(publicKeyPkcs8) >> base64Decode() >> streamSink(os1);
@@ -87,10 +89,10 @@
BOOST_CHECK_THROW(SignerFilter(DigestAlgorithm::NONE, sKey), Error);
OBufferStream os2;
- bufferSource(data, sizeof(data)) >> signerFilter(DigestAlgorithm::SHA256, sKey) >> streamSink(os2);
+ bufferSource(DATA, sizeof(DATA)) >> signerFilter(DigestAlgorithm::SHA256, sKey) >> streamSink(os2);
auto sig = os2.buf();
- BOOST_CHECK(verifySignature(data, sizeof(data), sig->data(), sig->size(), pubKey->data(), pubKey->size()));
+ BOOST_CHECK(verifySignature(DATA, sizeof(DATA), sig->data(), sig->size(), pubKey->data(), pubKey->size()));
}
BOOST_AUTO_TEST_CASE(Ecdsa)
@@ -112,7 +114,6 @@
"RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA\n"
"//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABGhuFibgwLdEJBDOLdvSg1Hc\n"
"5EJTDxq6ls5FoYLfThp8HOjuwGSz0qw8ocMqyku1y0V5peQ4rEPd0bwcpZd9svA=\n";
- const uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
OBufferStream os1;
bufferSource(publicKeyPkcs8) >> base64Decode() >> streamSink(os1);
@@ -124,10 +125,34 @@
BOOST_CHECK_THROW(SignerFilter(DigestAlgorithm::NONE, sKey), Error);
OBufferStream os2;
- bufferSource(data, sizeof(data)) >> signerFilter(DigestAlgorithm::SHA256, sKey) >> streamSink(os2);
+ bufferSource(DATA, sizeof(DATA)) >> signerFilter(DigestAlgorithm::SHA256, sKey) >> streamSink(os2);
auto sig = os2.buf();
- BOOST_CHECK(verifySignature(data, sizeof(data), sig->data(), sig->size(), pubKey->data(), pubKey->size()));
+ BOOST_CHECK(verifySignature(DATA, sizeof(DATA), sig->data(), sig->size(), pubKey->data(), pubKey->size()));
+}
+
+BOOST_AUTO_TEST_CASE(Hmac)
+{
+ auto sKey = generatePrivateKey(HmacKeyParams());
+
+ BOOST_CHECK_THROW(SignerFilter(DigestAlgorithm::NONE, *sKey), Error);
+
+ OBufferStream os;
+ bufferSource(DATA, sizeof(DATA)) >> signerFilter(DigestAlgorithm::SHA256, *sKey) >> streamSink(os);
+ auto sig = os.buf();
+
+ BOOST_CHECK_EQUAL(sig->size(), 32);
+}
+
+BOOST_AUTO_TEST_CASE(HmacKeyTooShort)
+{
+ auto sKey = generatePrivateKey(HmacKeyParams(256));
+
+ OBufferStream os;
+ BOOST_CHECK_THROW(bufferSource(DATA, sizeof(DATA)) >>
+ signerFilter(DigestAlgorithm::SHA512, *sKey) >>
+ streamSink(os),
+ Error);
}
BOOST_AUTO_TEST_CASE(InvalidKey)
diff --git a/tests/unit/security/transform/verifier-filter.t.cpp b/tests/unit/security/transform/verifier-filter.t.cpp
index ef38276..8d733d3 100644
--- a/tests/unit/security/transform/verifier-filter.t.cpp
+++ b/tests/unit/security/transform/verifier-filter.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -22,6 +22,7 @@
#include "ndn-cxx/security/transform/verifier-filter.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"
@@ -41,6 +42,8 @@
BOOST_AUTO_TEST_SUITE(Transform)
BOOST_AUTO_TEST_SUITE(TestVerifierFilter)
+const uint8_t DATA[] = {0x01, 0x02, 0x03, 0x04};
+
BOOST_AUTO_TEST_CASE(Rsa)
{
const std::string publicKeyPkcs8 =
@@ -78,7 +81,6 @@
"/YnHJC50/dIKbZakaapXOFFgiep5q1jmxR2U8seb+nvtFPsTLFAdOXCfwUk+4z/h\n"
"kfWtB3+8H5jyoC1gkJ7EMyxu8tb4mz5U6+SPB4QLSetwvfWP2YXS/PkTq19G7iGE\n"
"novjJ9azSBJ6OyR5UH/DxBji\n";
- const uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
OBufferStream os1;
bufferSource(publicKeyPkcs8) >> base64Decode() >> streamSink(os1);
@@ -91,13 +93,14 @@
sKey.loadPkcs1Base64(reinterpret_cast<const uint8_t*>(privateKeyPkcs1.data()), privateKeyPkcs1.size());
OBufferStream os2;
- bufferSource(data, sizeof(data)) >> signerFilter(DigestAlgorithm::SHA256, sKey) >> streamSink(os2);
+ bufferSource(DATA, sizeof(DATA)) >> signerFilter(DigestAlgorithm::SHA256, sKey) >> streamSink(os2);
auto sig = os2.buf();
BOOST_CHECK_THROW(VerifierFilter(DigestAlgorithm::NONE, pKey, sig->data(), sig->size()), Error);
+ BOOST_CHECK_THROW(VerifierFilter(DigestAlgorithm::SHA256, sKey, sig->data(), sig->size()), Error);
bool result = false;
- bufferSource(data, sizeof(data)) >>
+ bufferSource(DATA, sizeof(DATA)) >>
verifierFilter(DigestAlgorithm::SHA256, pKey, sig->data(), sig->size()) >>
boolSink(result);
@@ -123,7 +126,6 @@
"RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA\n"
"//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABGhuFibgwLdEJBDOLdvSg1Hc\n"
"5EJTDxq6ls5FoYLfThp8HOjuwGSz0qw8ocMqyku1y0V5peQ4rEPd0bwcpZd9svA=\n";
- const uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
OBufferStream os1;
bufferSource(publicKeyPkcs8) >> base64Decode() >> streamSink(os1);
@@ -136,23 +138,44 @@
sKey.loadPkcs1Base64(reinterpret_cast<const uint8_t*>(privateKeyPkcs1.data()), privateKeyPkcs1.size());
OBufferStream os2;
- bufferSource(data, sizeof(data)) >> signerFilter(DigestAlgorithm::SHA256, sKey) >> streamSink(os2);
+ bufferSource(DATA, sizeof(DATA)) >> signerFilter(DigestAlgorithm::SHA256, sKey) >> streamSink(os2);
auto sig = os2.buf();
BOOST_CHECK_THROW(VerifierFilter(DigestAlgorithm::NONE, pKey, sig->data(), sig->size()), Error);
+ BOOST_CHECK_THROW(VerifierFilter(DigestAlgorithm::SHA256, sKey, sig->data(), sig->size()), Error);
bool result = false;
- bufferSource(data, sizeof(data)) >>
+ bufferSource(DATA, sizeof(DATA)) >>
verifierFilter(DigestAlgorithm::SHA256, pKey, sig->data(), sig->size()) >>
boolSink(result);
BOOST_CHECK_EQUAL(result, true);
}
+BOOST_AUTO_TEST_CASE(Hmac)
+{
+ auto sKey = generatePrivateKey(HmacKeyParams());
+
+ OBufferStream os;
+ bufferSource(DATA, sizeof(DATA)) >> signerFilter(DigestAlgorithm::SHA256, *sKey) >> streamSink(os);
+ auto sig = os.buf();
+
+ BOOST_CHECK_THROW(VerifierFilter(DigestAlgorithm::NONE, *sKey, sig->data(), sig->size()), Error);
+
+ bool result = false;
+ bufferSource(DATA, sizeof(DATA)) >>
+ verifierFilter(DigestAlgorithm::SHA256, *sKey, sig->data(), sig->size()) >>
+ boolSink(result);
+
+ BOOST_CHECK_EQUAL(result, true);
+}
+
BOOST_AUTO_TEST_CASE(InvalidKey)
{
- PublicKey pKey;
- BOOST_CHECK_THROW(VerifierFilter(DigestAlgorithm::SHA256, pKey, nullptr, 0), Error);
+ PublicKey pubKey;
+ BOOST_CHECK_THROW(VerifierFilter(DigestAlgorithm::SHA256, pubKey, nullptr, 0), Error);
+ PrivateKey privKey;
+ BOOST_CHECK_THROW(VerifierFilter(DigestAlgorithm::SHA256, privKey, nullptr, 0), Error);
}
BOOST_AUTO_TEST_SUITE_END() // TestVerifierFilter