blob: b2145e681d39eb5ba7fd7b9d5436510ec11791ed [file] [log] [blame]
Yingdi Yub263f152015-07-12 16:50:13 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento6158f472017-08-11 18:55:09 -04002/*
Davide Pesavento809f7542021-03-24 18:53:05 -04003 * Copyright (c) 2013-2021 Regents of the University of California.
Yingdi Yub263f152015-07-12 16:50:13 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
Davide Pesavento7e780642018-11-24 15:51:34 -050022#include "ndn-cxx/security/transform/signer-filter.hpp"
Yingdi Yub263f152015-07-12 16:50:13 -070023
Davide Pesavento7e780642018-11-24 15:51:34 -050024#include "ndn-cxx/encoding/buffer-stream.hpp"
Laqin Fan0fe72ea2019-05-22 16:42:59 -050025#include "ndn-cxx/security/key-params.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050026#include "ndn-cxx/security/transform/base64-decode.hpp"
27#include "ndn-cxx/security/transform/buffer-source.hpp"
28#include "ndn-cxx/security/transform/private-key.hpp"
29#include "ndn-cxx/security/transform/stream-sink.hpp"
30#include "ndn-cxx/security/verification-helpers.hpp"
Yingdi Yub263f152015-07-12 16:50:13 -070031
Davide Pesavento7e780642018-11-24 15:51:34 -050032#include "tests/boost-test.hpp"
Yingdi Yub263f152015-07-12 16:50:13 -070033
34namespace ndn {
35namespace security {
36namespace transform {
37namespace tests {
38
39BOOST_AUTO_TEST_SUITE(Security)
40BOOST_AUTO_TEST_SUITE(Transform)
41BOOST_AUTO_TEST_SUITE(TestSignerFilter)
42
Laqin Fan0fe72ea2019-05-22 16:42:59 -050043const uint8_t DATA[] = {0x01, 0x02, 0x03, 0x04};
44
Yingdi Yub263f152015-07-12 16:50:13 -070045BOOST_AUTO_TEST_CASE(Rsa)
46{
Davide Pesavento6158f472017-08-11 18:55:09 -040047 const std::string publicKeyPkcs8 =
Yingdi Yub263f152015-07-12 16:50:13 -070048 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw0WM1/WhAxyLtEqsiAJg\n"
49 "WDZWuzkYpeYVdeeZcqRZzzfRgBQTsNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobw\n"
50 "s3iigohnM9yTK+KKiayPhIAm/+5HGT6SgFJhYhqo1/upWdueojil6RP4/AgavHho\n"
51 "pxlAVbk6G9VdVnlQcQ5Zv0OcGi73c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9g\n"
52 "ZwIL5PuE9BiO6I39cL9z7EK1SfZhOWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA\n"
53 "9rH58ynaAix0tcR/nBMRLUX+e3rURHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0\n"
54 "ywIDAQAB\n";
Davide Pesavento6158f472017-08-11 18:55:09 -040055 const std::string privateKeyPkcs1 =
Yingdi Yub263f152015-07-12 16:50:13 -070056 "MIIEpAIBAAKCAQEAw0WM1/WhAxyLtEqsiAJgWDZWuzkYpeYVdeeZcqRZzzfRgBQT\n"
57 "sNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobws3iigohnM9yTK+KKiayPhIAm/+5H\n"
58 "GT6SgFJhYhqo1/upWdueojil6RP4/AgavHhopxlAVbk6G9VdVnlQcQ5Zv0OcGi73\n"
59 "c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9gZwIL5PuE9BiO6I39cL9z7EK1SfZh\n"
60 "OWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA9rH58ynaAix0tcR/nBMRLUX+e3rU\n"
61 "RHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0ywIDAQABAoIBADQkckOIl4IZMUTn\n"
62 "W8LFv6xOdkJwMKC8G6bsPRFbyY+HvC2TLt7epSvfS+f4AcYWaOPcDu2E49vt2sNr\n"
63 "cASly8hgwiRRAB3dHH9vcsboiTo8bi2RFvMqvjv9w3tK2yMxVDtmZamzrrnaV3YV\n"
64 "Q+5nyKo2F/PMDjQ4eUAKDOzjhBuKHsZBTFnA1MFNI+UKj5X4Yp64DFmKlxTX/U2b\n"
65 "wzVywo5hzx2Uhw51jmoLls4YUvMJXD0wW5ZtYRuPogXvXb/of9ef/20/wU11WFKg\n"
66 "Xb4gfR8zUXaXS1sXcnVm3+24vIs9dApUwykuoyjOqxWqcHRec2QT2FxVGkFEraze\n"
67 "CPa4rMECgYEA5Y8CywomIcTgerFGFCeMHJr8nQGqY2V/owFb3k9maczPnC9p4a9R\n"
68 "c5szLxA9FMYFxurQZMBWSEG2JS1HR2mnjigx8UKjYML/A+rvvjZOMe4M6Sy2ggh4\n"
69 "SkLZKpWTzjTe07ByM/j5v/SjNZhWAG7sw4/LmPGRQkwJv+KZhGojuOkCgYEA2cOF\n"
70 "T6cJRv6kvzTz9S0COZOVm+euJh/BXp7oAsAmbNfOpckPMzqHXy8/wpdKl6AAcB57\n"
71 "OuztlNfV1D7qvbz7JuRlYwQ0cEfBgbZPcz1p18HHDXhwn57ZPb8G33Yh9Omg0HNA\n"
72 "Imb4LsVuSqxA6NwSj7cpRekgTedrhLFPJ+Ydb5MCgYEAsM3Q7OjILcIg0t6uht9e\n"
73 "vrlwTsz1mtCV2co2I6crzdj9HeI2vqf1KAElDt6G7PUHhglcr/yjd8uEqmWRPKNX\n"
74 "ddnnfVZB10jYeP/93pac6z/Zmc3iU4yKeUe7U10ZFf0KkiiYDQd59CpLef/2XScS\n"
75 "HB0oRofnxRQjfjLc4muNT+ECgYEAlcDk06MOOTly+F8lCc1bA1dgAmgwFd2usDBd\n"
76 "Y07a3e0HGnGLN3Kfl7C5i0tZq64HvxLnMd2vgLVxQlXGPpdQrC1TH+XLXg+qnlZO\n"
77 "ivSH7i0/gx75bHvj75eH1XK65V8pDVDEoSPottllAIs21CxLw3N1ObOZWJm2EfmR\n"
78 "cuHICmsCgYAtFJ1idqMoHxES3mlRpf2JxyQudP3SCm2WpGmqVzhRYInqeatY5sUd\n"
79 "lPLHm/p77RT7EyxQHTlwn8FJPuM/4ZH1rQd/vB+Y8qAtYJCexDMsbvLW+Js+VOvk\n"
80 "jweEC0nrcL31j9mF0vz5E6tfRu4hhJ6L4yfWs0gSejskeVB/w8QY4g==\n";
Yingdi Yub263f152015-07-12 16:50:13 -070081
82 OBufferStream os1;
83 bufferSource(publicKeyPkcs8) >> base64Decode() >> streamSink(os1);
Davide Pesavento6158f472017-08-11 18:55:09 -040084 auto pubKey = os1.buf();
Yingdi Yub263f152015-07-12 16:50:13 -070085
86 PrivateKey sKey;
Davide Pesavento6158f472017-08-11 18:55:09 -040087 sKey.loadPkcs1Base64(reinterpret_cast<const uint8_t*>(privateKeyPkcs1.data()), privateKeyPkcs1.size());
Yingdi Yub263f152015-07-12 16:50:13 -070088
Davide Pesavento06f1bdf2017-09-16 18:59:15 -040089 BOOST_CHECK_THROW(SignerFilter(DigestAlgorithm::NONE, sKey), Error);
90
Davide Pesavento6158f472017-08-11 18:55:09 -040091 OBufferStream os2;
Laqin Fan0fe72ea2019-05-22 16:42:59 -050092 bufferSource(DATA, sizeof(DATA)) >> signerFilter(DigestAlgorithm::SHA256, sKey) >> streamSink(os2);
Davide Pesavento6158f472017-08-11 18:55:09 -040093 auto sig = os2.buf();
Yingdi Yub263f152015-07-12 16:50:13 -070094
Davide Pesavento809f7542021-03-24 18:53:05 -040095 BOOST_TEST(verifySignature({{DATA, sizeof(DATA)}}, sig->data(), sig->size(), pubKey->data(), pubKey->size()));
Yingdi Yub263f152015-07-12 16:50:13 -070096}
97
98BOOST_AUTO_TEST_CASE(Ecdsa)
99{
Davide Pesavento6158f472017-08-11 18:55:09 -0400100 const std::string privateKeyPkcs1 =
Yingdi Yub263f152015-07-12 16:50:13 -0700101 "MIIBaAIBAQQgRxwcbzK9RV6AHYFsDcykI86o3M/a1KlJn0z8PcLMBZOggfowgfcC\n"
102 "AQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAAAAAAAAAAAAAA////////////////\n"
103 "MFsEIP////8AAAABAAAAAAAAAAAAAAAA///////////////8BCBaxjXYqjqT57Pr\n"
104 "vVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEE\n"
105 "axfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54W\n"
106 "K84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8\n"
107 "YyVRAgEBoUQDQgAEaG4WJuDAt0QkEM4t29KDUdzkQlMPGrqWzkWhgt9OGnwc6O7A\n"
108 "ZLPSrDyhwyrKS7XLRXml5DisQ93RvByll32y8A==\n";
Davide Pesavento6158f472017-08-11 18:55:09 -0400109 const std::string publicKeyPkcs8 =
Yingdi Yub263f152015-07-12 16:50:13 -0700110 "MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAA\n"
111 "AAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA////\n"
112 "///////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSd\n"
113 "NgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5\n"
114 "RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA\n"
115 "//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABGhuFibgwLdEJBDOLdvSg1Hc\n"
116 "5EJTDxq6ls5FoYLfThp8HOjuwGSz0qw8ocMqyku1y0V5peQ4rEPd0bwcpZd9svA=\n";
Yingdi Yub263f152015-07-12 16:50:13 -0700117
118 OBufferStream os1;
119 bufferSource(publicKeyPkcs8) >> base64Decode() >> streamSink(os1);
Davide Pesavento6158f472017-08-11 18:55:09 -0400120 auto pubKey = os1.buf();
Yingdi Yub263f152015-07-12 16:50:13 -0700121
122 PrivateKey sKey;
Davide Pesavento6158f472017-08-11 18:55:09 -0400123 sKey.loadPkcs1Base64(reinterpret_cast<const uint8_t*>(privateKeyPkcs1.data()), privateKeyPkcs1.size());
Yingdi Yub263f152015-07-12 16:50:13 -0700124
Davide Pesavento06f1bdf2017-09-16 18:59:15 -0400125 BOOST_CHECK_THROW(SignerFilter(DigestAlgorithm::NONE, sKey), Error);
126
Davide Pesavento6158f472017-08-11 18:55:09 -0400127 OBufferStream os2;
Laqin Fan0fe72ea2019-05-22 16:42:59 -0500128 bufferSource(DATA, sizeof(DATA)) >> signerFilter(DigestAlgorithm::SHA256, sKey) >> streamSink(os2);
Davide Pesavento6158f472017-08-11 18:55:09 -0400129 auto sig = os2.buf();
Yingdi Yub263f152015-07-12 16:50:13 -0700130
Davide Pesavento809f7542021-03-24 18:53:05 -0400131 BOOST_TEST(verifySignature({{DATA, sizeof(DATA)}}, sig->data(), sig->size(), pubKey->data(), pubKey->size()));
Laqin Fan0fe72ea2019-05-22 16:42:59 -0500132}
133
Davide Pesavento5e494c02019-09-29 16:30:19 -0400134BOOST_AUTO_TEST_SUITE(Hmac)
135
136// Test vectors from RFC 4231
Davide Pesavento93101df2021-06-15 18:33:09 -0400137// https://datatracker.ietf.org/doc/html/rfc4231#section-4
Davide Pesavento5e494c02019-09-29 16:30:19 -0400138BOOST_AUTO_TEST_CASE(Rfc4231Test1)
Laqin Fan0fe72ea2019-05-22 16:42:59 -0500139{
Davide Pesavento5e494c02019-09-29 16:30:19 -0400140 // Test case 1
141 const uint8_t rawKey[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
142 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
143 const std::string data("Hi There");
144 const uint8_t hmacSha224[] = {0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19, 0x68, 0x32,
145 0x10, 0x7c, 0xd4, 0x9d, 0xf3, 0x3f, 0x47, 0xb4, 0xb1, 0x16,
146 0x99, 0x12, 0xba, 0x4f, 0x53, 0x68, 0x4b, 0x22};
147 const uint8_t hmacSha256[] = {0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8,
148 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00,
149 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32,
150 0xcf, 0xf7};
151 const uint8_t hmacSha384[] = {0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62, 0x6b, 0x08,
152 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f, 0x15, 0xf9, 0xda, 0xdb,
153 0xe4, 0x10, 0x1e, 0xc6, 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb,
154 0xc5, 0x9c, 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
155 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6};
156 const uint8_t hmacSha512[] = {0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d, 0x4f, 0xf0,
157 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0, 0x23, 0x79, 0xf4, 0xe2,
158 0xce, 0x4e, 0xc2, 0x78, 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1,
159 0x7c, 0xde, 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
160 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4, 0xbe, 0x9d,
161 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70, 0x2e, 0x69, 0x6c, 0x20,
162 0x3a, 0x12, 0x68, 0x54};
Laqin Fan0fe72ea2019-05-22 16:42:59 -0500163
Davide Pesavento5e494c02019-09-29 16:30:19 -0400164 PrivateKey key;
165 key.loadRaw(KeyType::HMAC, rawKey, sizeof(rawKey));
Laqin Fan0fe72ea2019-05-22 16:42:59 -0500166
Davide Pesavento5e494c02019-09-29 16:30:19 -0400167 BOOST_CHECK_THROW(SignerFilter(DigestAlgorithm::NONE, key), Error);
Laqin Fan0fe72ea2019-05-22 16:42:59 -0500168
Davide Pesavento5e494c02019-09-29 16:30:19 -0400169 OBufferStream os224;
170 bufferSource(data) >> signerFilter(DigestAlgorithm::SHA224, key) >> streamSink(os224);
171 auto sig = os224.buf();
172 BOOST_CHECK_EQUAL_COLLECTIONS(sig->begin(), sig->end(), hmacSha224, hmacSha224 + sizeof(hmacSha224));
173
174 OBufferStream os256;
175 bufferSource(data) >> signerFilter(DigestAlgorithm::SHA256, key) >> streamSink(os256);
176 sig = os256.buf();
177 BOOST_CHECK_EQUAL_COLLECTIONS(sig->begin(), sig->end(), hmacSha256, hmacSha256 + sizeof(hmacSha256));
178
179 OBufferStream os384;
180 bufferSource(data) >> signerFilter(DigestAlgorithm::SHA384, key) >> streamSink(os384);
181 sig = os384.buf();
182 BOOST_CHECK_EQUAL_COLLECTIONS(sig->begin(), sig->end(), hmacSha384, hmacSha384 + sizeof(hmacSha384));
183
184 OBufferStream os512;
185 bufferSource(data) >> signerFilter(DigestAlgorithm::SHA512, key) >> streamSink(os512);
186 sig = os512.buf();
187 BOOST_CHECK_EQUAL_COLLECTIONS(sig->begin(), sig->end(), hmacSha512, hmacSha512 + sizeof(hmacSha512));
Laqin Fan0fe72ea2019-05-22 16:42:59 -0500188}
189
Davide Pesavento5e494c02019-09-29 16:30:19 -0400190BOOST_AUTO_TEST_CASE(Rfc4231Test2)
Laqin Fan0fe72ea2019-05-22 16:42:59 -0500191{
Davide Pesavento5e494c02019-09-29 16:30:19 -0400192 // Test case 2 (HMAC-SHA-256 only)
193 const char rawKey[] = "Jefe";
194 const std::string data("what do ya want for nothing?");
195 const uint8_t hmacSha256[] = {0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, 0x6a, 0x04,
196 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00, 0x3f, 0x08,
197 0x9d, 0x27, 0x39, 0x83, 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec,
198 0x38, 0x43};
Laqin Fan0fe72ea2019-05-22 16:42:59 -0500199
Davide Pesavento5e494c02019-09-29 16:30:19 -0400200 PrivateKey key;
201 key.loadRaw(KeyType::HMAC, reinterpret_cast<const uint8_t*>(rawKey), std::strlen(rawKey));
202
203 OBufferStream os256;
204 bufferSource(data) >> signerFilter(DigestAlgorithm::SHA256, key) >> streamSink(os256);
205 auto sig = os256.buf();
206 BOOST_CHECK_EQUAL_COLLECTIONS(sig->begin(), sig->end(), hmacSha256, hmacSha256 + sizeof(hmacSha256));
Yingdi Yub263f152015-07-12 16:50:13 -0700207}
208
Davide Pesavento5e494c02019-09-29 16:30:19 -0400209BOOST_AUTO_TEST_CASE(Rfc4231Test3)
210{
211 // Test case 3 (HMAC-SHA-256 only)
212 const uint8_t rawKey[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
213 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
214 const uint8_t data[] = {0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
215 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
216 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
217 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
218 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd};
219 const uint8_t hmacSha256[] = {0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, 0x85, 0x4d,
220 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59, 0x09, 0x8b,
221 0x3e, 0xf8, 0xc1, 0x22, 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5,
222 0x65, 0xfe};
223
224 PrivateKey key;
225 key.loadRaw(KeyType::HMAC, rawKey, sizeof(rawKey));
226
227 OBufferStream os256;
228 bufferSource(data, sizeof(data)) >> signerFilter(DigestAlgorithm::SHA256, key) >> streamSink(os256);
229 auto sig = os256.buf();
230 BOOST_CHECK_EQUAL_COLLECTIONS(sig->begin(), sig->end(), hmacSha256, hmacSha256 + sizeof(hmacSha256));
231}
232
233BOOST_AUTO_TEST_SUITE_END() // Hmac
234
Davide Pesavento06f1bdf2017-09-16 18:59:15 -0400235BOOST_AUTO_TEST_CASE(InvalidKey)
236{
Davide Pesavento5e494c02019-09-29 16:30:19 -0400237 PrivateKey key;
238 BOOST_CHECK_THROW(SignerFilter(DigestAlgorithm::SHA256, key), Error);
Davide Pesavento06f1bdf2017-09-16 18:59:15 -0400239}
240
Yingdi Yub263f152015-07-12 16:50:13 -0700241BOOST_AUTO_TEST_SUITE_END() // TestSignerFilter
242BOOST_AUTO_TEST_SUITE_END() // Transform
243BOOST_AUTO_TEST_SUITE_END() // Security
244
245} // namespace tests
246} // namespace transform
247} // namespace security
248} // namespace ndn