blob: dc1d8b5457d61281f7cc1ff4a7788396fd9199b0 [file] [log] [blame]
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento0f830802018-01-16 23:58:58 -05002/*
Eric Newberrya3c8bd12020-05-15 17:27:07 -07003 * Copyright (c) 2013-2020 Regents of the University of California.
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -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 * @author Zhiyi Zhang <dreamerbarrychang@gmail.com>
22 */
23
Davide Pesavento7e780642018-11-24 15:51:34 -050024#include "ndn-cxx/security/v2/certificate.hpp"
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -070025
Davide Pesavento7e780642018-11-24 15:51:34 -050026#include "tests/boost-test.hpp"
27#include "tests/unit/unit-test-time-fixture.hpp"
Davide Pesavento74daf742018-11-23 18:14:13 -050028
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -070029#include <boost/lexical_cast.hpp>
30
31namespace ndn {
32namespace security {
33namespace v2 {
34namespace tests {
35
36using namespace ndn::tests;
37
38BOOST_AUTO_TEST_SUITE(Security)
39BOOST_AUTO_TEST_SUITE(V2)
40BOOST_FIXTURE_TEST_SUITE(TestCertificate, UnitTestTimeFixture)
41
42const uint8_t PUBLIC_KEY[] = {
43 0x30, 0x81, 0x9d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
44 0x01, 0x05, 0x00, 0x03, 0x81, 0x8b, 0x00, 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e,
45 0x06, 0x3e, 0x47, 0x85, 0xb2, 0x34, 0x37, 0xaa, 0x85, 0x47, 0xac, 0x03, 0x24, 0x83, 0xb5,
46 0x9c, 0xa8, 0x05, 0x3a, 0x24, 0x1e, 0xeb, 0x89, 0x01, 0xbb, 0xe9, 0x9b, 0xb2, 0xc3, 0x22,
47 0xac, 0x68, 0xe3, 0xf0, 0x6c, 0x02, 0xce, 0x68, 0xa6, 0xc4, 0xd0, 0xa7, 0x06, 0x90, 0x9c,
48 0xaa, 0x1b, 0x08, 0x1d, 0x8b, 0x43, 0x9a, 0x33, 0x67, 0x44, 0x6d, 0x21, 0xa3, 0x1b, 0x88,
49 0x9a, 0x97, 0x5e, 0x59, 0xc4, 0x15, 0x0b, 0xd9, 0x2c, 0xbd, 0x51, 0x07, 0x61, 0x82, 0xad,
50 0xc1, 0xb8, 0xd7, 0xbf, 0x9b, 0xcf, 0x7d, 0x24, 0xc2, 0x63, 0xf3, 0x97, 0x17, 0xeb, 0xfe,
51 0x62, 0x25, 0xba, 0x5b, 0x4d, 0x8a, 0xc2, 0x7a, 0xbd, 0x43, 0x8a, 0x8f, 0xb8, 0xf2, 0xf1,
52 0xc5, 0x6a, 0x30, 0xd3, 0x50, 0x8c, 0xc8, 0x9a, 0xdf, 0xef, 0xed, 0x35, 0xe7, 0x7a, 0x62,
53 0xea, 0x76, 0x7c, 0xbb, 0x08, 0x26, 0xc7, 0x02, 0x01, 0x11
54};
55
56const uint8_t SIG_INFO[] = {
57 0x16, 0x55, 0x1B, 0x01, 0x01, 0x1C, 0x26, 0x07, 0x24, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x05,
58 0x73, 0x69, 0x74, 0x65, 0x31, 0x08, 0x11, 0x6B, 0x73, 0x6B, 0x2D, 0x32, 0x35, 0x31, 0x36, 0x34,
59 0x32, 0x35, 0x33, 0x37, 0x37, 0x30, 0x39, 0x34, 0x08, 0x03, 0x4B, 0x45, 0x59, 0xFD, 0x00, 0xFD,
60 0x26, 0xFD, 0x00, 0xFE, 0x0F, 0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x31, 0x34, 0x54, 0x32, 0x32,
61 0x33, 0x37, 0x33, 0x39, 0xFD, 0x00, 0xFF, 0x0F, 0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x31, 0x38,
62 0x54, 0x32, 0x32, 0x33, 0x37, 0x33, 0x38
63};
64
65const uint8_t SIG_VALUE[] = {
66 0x17, 0x80, // SignatureValue
67 0x2f, 0xd6, 0xf1, 0x6e, 0x80, 0x6f, 0x10, 0xbe, 0xb1, 0x6f, 0x3e, 0x31, 0xec,
68 0xe3, 0xb9, 0xea, 0x83, 0x30, 0x40, 0x03, 0xfc, 0xa0, 0x13, 0xd9, 0xb3, 0xc6,
69 0x25, 0x16, 0x2d, 0xa6, 0x58, 0x41, 0x69, 0x62, 0x56, 0xd8, 0xb3, 0x6a, 0x38,
70 0x76, 0x56, 0xea, 0x61, 0xb2, 0x32, 0x70, 0x1c, 0xb6, 0x4d, 0x10, 0x1d, 0xdc,
71 0x92, 0x8e, 0x52, 0xa5, 0x8a, 0x1d, 0xd9, 0x96, 0x5e, 0xc0, 0x62, 0x0b, 0xcf,
72 0x3a, 0x9d, 0x7f, 0xca, 0xbe, 0xa1, 0x41, 0x71, 0x85, 0x7a, 0x8b, 0x5d, 0xa9,
73 0x64, 0xd6, 0x66, 0xb4, 0xe9, 0x8d, 0x0c, 0x28, 0x43, 0xee, 0xa6, 0x64, 0xe8,
74 0x55, 0xf6, 0x1c, 0x19, 0x0b, 0xef, 0x99, 0x25, 0x1e, 0xdc, 0x78, 0xb3, 0xa7,
75 0xaa, 0x0d, 0x14, 0x58, 0x30, 0xe5, 0x37, 0x6a, 0x6d, 0xdb, 0x56, 0xac, 0xa3,
76 0xfc, 0x90, 0x7a, 0xb8, 0x66, 0x9c, 0x0e, 0xf6, 0xb7, 0x64, 0xd1
77};
78
79const uint8_t CERT[] = {
80 0x06, 0xFD, 0x01, 0xBB, // Data
81 0x07, 0x33, // Name /ndn/site1/KEY/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B
82 0x08, 0x03, 0x6E, 0x64, 0x6E,
83 0x08, 0x05, 0x73, 0x69, 0x74, 0x65, 0x31,
84 0x08, 0x03, 0x4B, 0x45, 0x59,
85 0x08, 0x11,
86 0x6B, 0x73, 0x6B, 0x2D, 0x31, 0x34, 0x31, 0x36, 0x34, 0x32, 0x35, 0x33, 0x37, 0x37, 0x30, 0x39,
87 0x34,
88 0x08, 0x04, 0x30, 0x31, 0x32, 0x33,
89 0x08, 0x07, 0xFD, 0x00, 0x00, 0x01, 0x49, 0xC9, 0x8B,
90 0x14, 0x09, // MetaInfo
91 0x18, 0x01, 0x02, // ContentType = Key
92 0x19, 0x04, 0x00, 0x36, 0xEE, 0x80, // FreshnessPeriod = 3600000 ms
93 0x15, 0xA0, // Content
94 0x30, 0x81, 0x9D, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
95 0x05, 0x00, 0x03, 0x81, 0x8B, 0x00, 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9E, 0x06, 0x3E,
96 0x47, 0x85, 0xB2, 0x34, 0x37, 0xAA, 0x85, 0x47, 0xAC, 0x03, 0x24, 0x83, 0xB5, 0x9C, 0xA8, 0x05,
97 0x3A, 0x24, 0x1E, 0xEB, 0x89, 0x01, 0xBB, 0xE9, 0x9B, 0xB2, 0xC3, 0x22, 0xAC, 0x68, 0xE3, 0xF0,
98 0x6C, 0x02, 0xCE, 0x68, 0xA6, 0xC4, 0xD0, 0xA7, 0x06, 0x90, 0x9C, 0xAA, 0x1B, 0x08, 0x1D, 0x8B,
99 0x43, 0x9A, 0x33, 0x67, 0x44, 0x6D, 0x21, 0xA3, 0x1B, 0x88, 0x9A, 0x97, 0x5E, 0x59, 0xC4, 0x15,
100 0x0B, 0xD9, 0x2C, 0xBD, 0x51, 0x07, 0x61, 0x82, 0xAD, 0xC1, 0xB8, 0xD7, 0xBF, 0x9B, 0xCF, 0x7D,
101 0x24, 0xC2, 0x63, 0xF3, 0x97, 0x17, 0xEB, 0xFE, 0x62, 0x25, 0xBA, 0x5B, 0x4D, 0x8A, 0xC2, 0x7A,
102 0xBD, 0x43, 0x8A, 0x8F, 0xB8, 0xF2, 0xF1, 0xC5, 0x6A, 0x30, 0xD3, 0x50, 0x8C, 0xC8, 0x9A, 0xDF,
103 0xEF, 0xED, 0x35, 0xE7, 0x7A, 0x62, 0xEA, 0x76, 0x7C, 0xBB, 0x08, 0x26, 0xC7, 0x02, 0x01, 0x11,
104 0x16, 0x55, // SignatureInfo
105 0x1B, 0x01, 0x01, // SignatureType
106 0x1C, 0x26, // KeyLocator: /ndn/site1/KEY/ksk-2516425377094
107 0x07, 0x24,
108 0x08, 0x03, 0x6E, 0x64, 0x6E,
109 0x08, 0x05, 0x73, 0x69, 0x74, 0x65, 0x31,
110 0x08, 0x03, 0x4B, 0x45, 0x59,
111 0x08, 0x11,
112 0x6B, 0x73, 0x6B, 0x2D, 0x32, 0x35, 0x31, 0x36, 0x34, 0x32, 0x35, 0x33, 0x37, 0x37, 0x30, 0x39,
113 0x34,
114 0xFD, 0x00, 0xFD, 0x26, // ValidityPeriod: (20150814T223739, 20150818T223738)
115 0xFD, 0x00, 0xFE, 0x0F,
116 0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x31, 0x34, 0x54, 0x32, 0x32, 0x33, 0x37, 0x33, 0x39,
117 0xFD, 0x00, 0xFF, 0x0F,
118 0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x31, 0x38, 0x54, 0x32, 0x32, 0x33, 0x37, 0x33, 0x38,
119 0x17, 0x80, // SignatureValue
120 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
121 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
122 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
123 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
124 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
125 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
126 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
127 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
128};
129
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700130static void
131generateFakeSignature(Data& data)
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700132{
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700133 SignatureInfo signatureInfo(Block(SIG_INFO, sizeof(SIG_INFO)));
134 signatureInfo.setKeyLocator(KeyLocator(Name("/ndn/site1/KEY/ksk-2516425377094")));
135 signatureInfo.setValidityPeriod(ValidityPeriod(time::fromIsoString("20141111T050000"),
136 time::fromIsoString("20141111T060000")));
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700137
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700138 data.setSignatureInfo(signatureInfo);
139 data.setSignatureValue(Block(SIG_VALUE, sizeof(SIG_VALUE)));
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700140}
141
142BOOST_AUTO_TEST_CASE(Construction)
143{
144 Block block(CERT, sizeof(CERT));
145 Certificate certificate(block);
146
147 BOOST_CHECK_EQUAL(certificate.getName(), "/ndn/site1/KEY/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B");
148 BOOST_CHECK_EQUAL(certificate.getKeyName(), "/ndn/site1/KEY/ksk-1416425377094");
149 BOOST_CHECK_EQUAL(certificate.getIdentity(), "/ndn/site1");
150 BOOST_CHECK_EQUAL(certificate.getIssuerId(), name::Component("0123"));
151 BOOST_CHECK_EQUAL(certificate.getKeyId(), name::Component("ksk-1416425377094"));
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700152 BOOST_CHECK_EQUAL(certificate.getSignatureInfo().getKeyLocator().getName(), "/ndn/site1/KEY/ksk-2516425377094");
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700153 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(certificate.getValidityPeriod()), "(20150814T223739, 20150818T223738)");
154
155 BOOST_CHECK_THROW(certificate.getExtension(12345), ndn::SignatureInfo::Error);
156 BOOST_CHECK_NO_THROW(certificate.getPublicKey());
157
158 Data data(block);
159 Certificate certificate2(std::move(data));
160 BOOST_CHECK_EQUAL(certificate, certificate2);
161}
162
163BOOST_AUTO_TEST_CASE(Setters)
164{
165 Certificate certificate;
166 certificate.setName("/ndn/site1/KEY/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B");
Davide Pesavento0f830802018-01-16 23:58:58 -0500167 certificate.setFreshnessPeriod(1_h);
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700168 certificate.setContent(PUBLIC_KEY, sizeof(PUBLIC_KEY));
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700169 generateFakeSignature(certificate);
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700170
171 BOOST_CHECK_EQUAL(certificate.getName(), "/ndn/site1/KEY/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B");
172 BOOST_CHECK_EQUAL(certificate.getKeyName(), "/ndn/site1/KEY/ksk-1416425377094");
173 BOOST_CHECK_EQUAL(certificate.getIdentity(), "/ndn/site1");
174 BOOST_CHECK_EQUAL(certificate.getIssuerId(), name::Component("0123"));
175 BOOST_CHECK_EQUAL(certificate.getKeyId(), name::Component("ksk-1416425377094"));
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700176 BOOST_CHECK_EQUAL(certificate.getSignatureInfo().getKeyLocator().getName(), "/ndn/site1/KEY/ksk-2516425377094");
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700177 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(certificate.getValidityPeriod()), "(20141111T050000, 20141111T060000)");
178
179 BOOST_CHECK_THROW(certificate.getExtension(12345), ndn::SignatureInfo::Error);
180 BOOST_CHECK_NO_THROW(certificate.getPublicKey());
181}
182
183BOOST_AUTO_TEST_CASE(ValidityPeriodChecking)
184{
185 Certificate certificate;
186 certificate.setName("/ndn/site1/KEY/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B");
Davide Pesavento0f830802018-01-16 23:58:58 -0500187 certificate.setFreshnessPeriod(1_h);
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700188 certificate.setContent(PUBLIC_KEY, sizeof(PUBLIC_KEY));
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700189 generateFakeSignature(certificate);
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700190
191 BOOST_CHECK_EQUAL(certificate.isValid(), true);
192 BOOST_CHECK_EQUAL(certificate.isValid(time::fromIsoString("20141111T045959")), false);
193 BOOST_CHECK_EQUAL(certificate.isValid(time::fromIsoString("20141111T060001")), false);
194}
195
196// This fixture prepares a well-formed certificate. A test case then modifies one of the
197// fields, and verifies the Certificate class correctly identifies the certificate as
198// malformed.
199class InvalidCertFixture
200{
201public:
202 InvalidCertFixture()
203 {
204 Certificate certBase(Block(CERT, sizeof(CERT)));
205 BOOST_CHECK_NO_THROW((Certificate(certBase)));
206
207 m_certBase = Data(certBase);
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700208 generateFakeSignature(m_certBase);
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700209
210 BOOST_CHECK_NO_THROW((Certificate(m_certBase)));
211 }
212
213public:
214 Data m_certBase;
215};
216
217BOOST_FIXTURE_TEST_CASE(InvalidName, InvalidCertFixture)
218{
219 Data data(m_certBase);
220 data.setName("/ndn/site1/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B");
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700221 generateFakeSignature(data);
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700222
223 BOOST_CHECK_THROW((Certificate(data)), Certificate::Error);
224 BOOST_CHECK_THROW((Certificate(std::move(data))), Certificate::Error);
225}
226
227BOOST_FIXTURE_TEST_CASE(InvalidType, InvalidCertFixture)
228{
229 Data data(m_certBase);
230 data.setContentType(tlv::ContentType_Blob);
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700231 generateFakeSignature(data);
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700232
233 BOOST_CHECK_THROW((Certificate(data)), Certificate::Error);
234 BOOST_CHECK_THROW((Certificate(std::move(data))), Certificate::Error);
235}
236
237BOOST_FIXTURE_TEST_CASE(EmptyContent, InvalidCertFixture)
238{
239 Data data(m_certBase);
240 data.setContent(nullptr, 0);
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700241 generateFakeSignature(data);
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700242
243 BOOST_CHECK_THROW((Certificate(data)), Certificate::Error);
244 BOOST_CHECK_THROW((Certificate(std::move(data))), Certificate::Error);
245
246 Certificate cert(m_certBase);
247 cert.setContent(nullptr, 0);
Eric Newberrya3c8bd12020-05-15 17:27:07 -0700248 generateFakeSignature(cert);
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700249 BOOST_CHECK_THROW(cert.getPublicKey(), Certificate::Error);
250}
251
Alexander Afanasyev5f1820e2017-01-04 18:12:42 -0800252BOOST_AUTO_TEST_CASE(PrintCertificateInfo)
253{
254 const std::string expectedCertificateInfo = std::string(R"INFO(
255Certificate name:
256 /ndn/site1/KEY/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B
257Validity:
258 NotBefore: 20150814T223739
259 NotAfter: 20150818T223738
260Public key bits:
261 MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCeBj5HhbI0N6qFR6wDJIO1nKgF
262 OiQe64kBu+mbssMirGjj8GwCzmimxNCnBpCcqhsIHYtDmjNnRG0hoxuImpdeWcQV
263 C9ksvVEHYYKtwbjXv5vPfSTCY/OXF+v+YiW6W02Kwnq9Q4qPuPLxxWow01CMyJrf
264 7+0153pi6nZ8uwgmxwIBEQ==
265Signature Information:
266 Signature Type: SignatureSha256WithRsa
267 Key Locator: Name=/ndn/site1/KEY/ksk-2516425377094
268)INFO").substr(1);
269
270 Certificate certificate(Block(CERT, sizeof(CERT)));
271 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(certificate), expectedCertificateInfo);
272
273 // @todo Check output formats of other certificates
274}
275
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700276BOOST_AUTO_TEST_SUITE_END() // TestCertificate
277BOOST_AUTO_TEST_SUITE_END() // V2
278BOOST_AUTO_TEST_SUITE_END() // Security
279
280} // namespace tests
281} // namespace v2
282} // namespace security
283} // namespace ndn