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