blob: b5188e99f1441db94409eeab1360eb4caf0fc2e0 [file] [log] [blame]
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Yingdi Yu6ee2d362015-07-16 21:48:05 -07003 * 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 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
23 */
24
25#include "certificate.hpp"
26#include "../../encoding/block-helpers.hpp"
27
28namespace ndn {
29namespace security {
30namespace v2 {
31
32BOOST_CONCEPT_ASSERT((WireEncodable<Certificate>));
33BOOST_CONCEPT_ASSERT((WireDecodable<Certificate>));
34
35// /<NameSpace>/KEY/[KeyId]/[IssuerId]/[Version]
36
37const ssize_t Certificate::VERSION_OFFSET = -1;
38const ssize_t Certificate::ISSUER_ID_OFFSET = -2;
39const ssize_t Certificate::KEY_ID_OFFSET = -3;
40const ssize_t Certificate::KEY_COMPONENT_OFFSET = -4;
41const size_t Certificate::MIN_CERT_NAME_LENGTH = 4;
42const size_t Certificate::MIN_KEY_NAME_LENGTH = 2;
43const name::Component Certificate::KEY_COMPONENT("KEY");
44
45Certificate::Certificate()
46{
47 setContentType(tlv::ContentTypeValue::ContentType_Key);
48}
49
50Certificate::Certificate(Data&& data)
51 : Data(data)
52{
53 if (!isValidName(getName())) {
54 BOOST_THROW_EXCEPTION(Data::Error("Name does not follow the naming convention for certificate"));
55 }
56 if (getContentType() != tlv::ContentTypeValue::ContentType_Key) {
57 BOOST_THROW_EXCEPTION(Data::Error("ContentType is not KEY"));
58 }
59 if (getFreshnessPeriod() < time::seconds::zero()) {
60 BOOST_THROW_EXCEPTION(Data::Error("FreshnessPeriod is not set"));
61 }
62 if (getContent().value_size() == 0) {
63 BOOST_THROW_EXCEPTION(Data::Error("Content is empty"));
64 }
65}
66
67Certificate::Certificate(const Data& data)
68 : Certificate(Data(data))
69{
70}
71
72Certificate::Certificate(const Block& block)
73 : Certificate(Data(block))
74{
75}
76
77Name
78Certificate::getKeyName() const
79{
80 return getName().getPrefix(KEY_ID_OFFSET + 1);
81}
82
83Name
84Certificate::getIdentity() const
85{
86 return getName().getPrefix(KEY_COMPONENT_OFFSET);
87}
88
89name::Component
90Certificate::getKeyId() const
91{
92 return getName().at(KEY_ID_OFFSET);
93}
94
95name::Component
96Certificate::getIssuerId() const
97{
98 return getName().at(ISSUER_ID_OFFSET);
99}
100
101const Buffer
102Certificate::getPublicKey() const
103{
104 if (getContent().value_size() == 0)
105 BOOST_THROW_EXCEPTION(Data::Error("Content is empty"));
106 return Buffer(getContent().value(), getContent().value_size());
107}
108
109ValidityPeriod
110Certificate::getValidityPeriod() const
111{
112 return getSignature().getSignatureInfo().getValidityPeriod();
113}
114
115bool
116Certificate::isValid(const time::system_clock::TimePoint& ts) const
117{
118 return getSignature().getSignatureInfo().getValidityPeriod().isValid(ts);
119}
120
121const Block&
122Certificate::getExtension(uint32_t type) const
123{
124 return getSignature().getSignatureInfo().getTypeSpecificTlv(type);
125}
126
127bool
128Certificate::isValidName(const Name& certName)
129{
130 // /<NameSpace>/KEY/[KeyId]/[IssuerId]/[Version]
131 return (certName.size() >= Certificate::MIN_CERT_NAME_LENGTH &&
132 certName.get(Certificate::KEY_COMPONENT_OFFSET) == Certificate::KEY_COMPONENT);
133}
134
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700135Name
136extractIdentityFromCertName(const Name& certName)
137{
138 if (!Certificate::isValidName(certName)) {
139 BOOST_THROW_EXCEPTION(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
140 "does not follow the naming conventions"));
141 }
142
143 return certName.getPrefix(Certificate::KEY_COMPONENT_OFFSET); // trim everything after and including "KEY"
144}
145
146Name
147extractKeyNameFromCertName(const Name& certName)
148{
149 if (!Certificate::isValidName(certName)) {
150 BOOST_THROW_EXCEPTION(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
151 "does not follow the naming conventions"));
152 }
153
154 return certName.getPrefix(Certificate::KEY_ID_OFFSET + 1); // trim everything after key id
155}
156
Zhiyi Zhangf4bb5c72015-08-19 19:02:51 -0700157} // namespace v2
158} // namespace security
159} // namespace ndn