certificate.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2022 Regents of the University of California.
4  *
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 
29 
30 namespace ndn {
31 namespace security {
32 inline namespace v2 {
33 
34 BOOST_CONCEPT_ASSERT((WireEncodable<Certificate>));
35 BOOST_CONCEPT_ASSERT((WireDecodable<Certificate>));
36 static_assert(std::is_base_of<Data::Error, Certificate::Error>::value,
37  "Certificate::Error must inherit from Data::Error");
38 
39 // /<IdentityName>/KEY/<KeyId>/<IssuerId>/<Version>
40 const ssize_t Certificate::VERSION_OFFSET = -1;
41 const ssize_t Certificate::ISSUER_ID_OFFSET = -2;
42 const ssize_t Certificate::KEY_ID_OFFSET = -3;
43 const ssize_t Certificate::KEY_COMPONENT_OFFSET = -4;
44 const size_t Certificate::MIN_CERT_NAME_LENGTH = 4;
45 const size_t Certificate::MIN_KEY_NAME_LENGTH = 2;
46 const name::Component Certificate::KEY_COMPONENT("KEY");
47 const name::Component Certificate::DEFAULT_ISSUER_ID("NA");
48 
50 {
52  setFreshnessPeriod(1_h);
53 }
54 
56  : Data(std::move(data))
57 {
58  if (!isValidName(getName())) {
59  NDN_THROW(Error("Certificate name does not follow the naming conventions"));
60  }
62  NDN_THROW(Error("Expecting ContentType=Key, got " + to_string(getContentType())));
63  }
64  if (getFreshnessPeriod() <= 0_ms) {
65  NDN_THROW(Error("Certificate FreshnessPeriod cannot be zero"));
66  }
67 }
68 
70  : Certificate(Data(data))
71 {
72 }
73 
75  : Certificate(Data(block))
76 {
77 }
78 
79 Name
81 {
83 }
84 
85 Name
87 {
88  return getName().getPrefix(KEY_ID_OFFSET + 1);
89 }
90 
93 {
94  return getName().at(KEY_ID_OFFSET);
95 }
96 
99 {
100  return getName().at(ISSUER_ID_OFFSET);
101 }
102 
105 {
107 }
108 
109 bool
111 {
113 }
114 
115 Block
116 Certificate::getExtension(uint32_t type) const
117 {
118  auto block = getSignatureInfo().getCustomTlv(type);
119  if (!block) {
120  NDN_THROW(Error("TLV-TYPE " + to_string(type) + " sub-element does not exist in SignatureInfo"));
121  }
122  return *block;
123 }
124 
125 bool
127 {
128  // /<IdentityName>/KEY/<KeyId>/<IssuerId>/<Version>
129  return certName.size() >= Certificate::MIN_CERT_NAME_LENGTH &&
131 }
132 
133 std::ostream&
134 operator<<(std::ostream& os, const Certificate& cert)
135 {
136  os << "Certificate Name:\n"
137  << " " << cert.getName() << "\n";
138 
139  auto optAddlDesc = cert.getSignatureInfo().getCustomTlv(tlv::AdditionalDescription);
140  if (optAddlDesc) {
141  os << "Additional Description:\n";
142  try {
143  AdditionalDescription additionalDesc(*optAddlDesc);
144  for (const auto& item : additionalDesc) {
145  os << " " << item.first << ": " << item.second << "\n";
146  }
147  }
148  catch (const tlv::Error&) {
149  using namespace transform;
150  util::IndentedStream os2(os, " ");
151  bufferSource(optAddlDesc->value_bytes()) >> base64Encode() >> streamSink(os2);
152  }
153  }
154 
155  os << "Public Key:\n";
156  {
157  using namespace transform;
158 
159  os << " Key Type: ";
160  try {
161  PublicKey key;
162  key.loadPkcs8(cert.getPublicKey());
163  os << key.getKeySize() << "-bit " << key.getKeyType();
164  }
165  catch (const std::runtime_error&) {
166  os << "Unknown (" << cert.getPublicKey().size() << " bytes)";
167  }
168  os << "\n";
169 
170  if (!cert.getPublicKey().empty()) {
171  util::IndentedStream os2(os, " ");
172  bufferSource(cert.getPublicKey()) >> base64Encode() >> streamSink(os2);
173  }
174  }
175 
176  try {
177  const auto& validityPeriod = cert.getValidityPeriod().getPeriod();
178  os << "Validity:\n"
179  << " Not Before: " << time::toIsoExtendedString(validityPeriod.first) << "\n"
180  << " Not After: " << time::toIsoExtendedString(validityPeriod.second) << "\n";
181  }
182  catch (const tlv::Error&) {
183  // ignore
184  }
185 
186  os << "Signature Information:\n"
187  << " Signature Type: " << static_cast<tlv::SignatureTypeValue>(cert.getSignatureType()) << "\n";
188 
189  auto keyLoc = cert.getKeyLocator();
190  if (keyLoc) {
191  os << " Key Locator: " << *keyLoc << "\n";
192  if (keyLoc->getType() == tlv::Name && keyLoc->getName() == cert.getKeyName()) {
193  os << " Self-Signed: yes\n";
194  }
195  }
196 
197  return os;
198 }
199 
200 Name
202 {
203  if (!Certificate::isValidName(certName)) {
204  NDN_THROW(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
205  "does not respect the naming conventions"));
206  }
207 
208  return certName.getPrefix(Certificate::KEY_COMPONENT_OFFSET); // trim everything after and including "KEY"
209 }
210 
211 Name
213 {
214  if (!Certificate::isValidName(certName)) {
215  NDN_THROW(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
216  "does not respect the naming conventions"));
217  }
218 
219  return certName.getPrefix(Certificate::KEY_ID_OFFSET + 1); // trim everything after key id
220 }
221 
222 } // inline namespace v2
223 } // namespace security
224 } // namespace ndn
Represents a TLV element of the NDN packet format.
Definition: block.hpp:45
Represents a Data packet.
Definition: data.hpp:39
int32_t getSignatureType() const noexcept
Get the SignatureType.
Definition: data.hpp:317
optional< KeyLocator > getKeyLocator() const noexcept
Get the KeyLocator element.
Definition: data.hpp:326
Data & setFreshnessPeriod(time::milliseconds freshnessPeriod)
Definition: data.cpp:344
const SignatureInfo & getSignatureInfo() const noexcept
Get the SignatureInfo element.
Definition: data.hpp:224
const Name & getName() const noexcept
Get the data name.
Definition: data.hpp:129
time::milliseconds getFreshnessPeriod() const
Definition: data.hpp:294
uint32_t getContentType() const
Definition: data.hpp:285
Data & setContentType(uint32_t type)
Definition: data.cpp:334
Represents an absolute name.
Definition: name.hpp:44
PartialName getPrefix(ssize_t nComponents) const
Returns a prefix of the name.
Definition: name.hpp:216
size_t size() const noexcept
Returns the number of components.
Definition: name.hpp:155
const Component & at(ssize_t i) const
Returns an immutable reference to the component at the specified index, with bounds checking.
Definition: name.cpp:171
void toUri(std::ostream &os, name::UriFormat format=name::UriFormat::DEFAULT) const
Write URI representation of the name to the output stream.
Definition: name.cpp:349
security::ValidityPeriod getValidityPeriod() const
Get the ValidityPeriod element.
optional< Block > getCustomTlv(uint32_t type) const
Get first custom TLV element with the specified TLV-TYPE.
Represents a name component.
Represents a ValidityPeriod TLV element.
bool isValid(const time::system_clock::TimePoint &now=time::system_clock::now()) const
Check if now falls within the validity period.
std::pair< time::system_clock::TimePoint, time::system_clock::TimePoint > getPeriod() const
Get the stored validity period.
Represents an AdditionalDescription TLV element.
Represents an NDN certificate.
Definition: certificate.hpp:60
bool isValid(const time::system_clock::TimePoint &ts=time::system_clock::now()) const
Check if the certificate is valid at ts.
name::Component getIssuerId() const
Get issuer ID.
Definition: certificate.cpp:98
static const name::Component KEY_COMPONENT
Name getKeyName() const
Get key name.
Definition: certificate.cpp:86
static const name::Component DEFAULT_ISSUER_ID
Name getIdentity() const
Get identity name.
Definition: certificate.cpp:80
ValidityPeriod getValidityPeriod() const
Get validity period of the certificate.
static const ssize_t KEY_COMPONENT_OFFSET
static const size_t MIN_KEY_NAME_LENGTH
static bool isValidName(const Name &certName)
Check if the specified name follows the naming convention for the certificate.
name::Component getKeyId() const
Get key ID.
Definition: certificate.cpp:92
static const size_t MIN_CERT_NAME_LENGTH
static const ssize_t ISSUER_ID_OFFSET
span< const uint8_t > getPublicKey() const noexcept
Return the public key as a DER-encoded SubjectPublicKeyInfo structure, i.e., exactly as it appears in...
static const ssize_t VERSION_OFFSET
static const ssize_t KEY_ID_OFFSET
Block getExtension(uint32_t type) const
Get extension with TLV type.
time_point TimePoint
Definition: time.hpp:203
Represents an error in TLV encoding or decoding.
Definition: tlv.hpp:54
Output to stream with specified indent or prefix.
#define NDN_THROW(e)
Definition: exception.hpp:61
std::string to_string(const errinfo_stacktrace &x)
Definition: exception.cpp:31
unique_ptr< Sink > streamSink(std::ostream &os)
Definition: stream-sink.cpp:53
unique_ptr< Transform > base64Encode(bool needBreak)
std::ostream & operator<<(std::ostream &os, const AdditionalDescription &desc)
Name extractKeyNameFromCertName(const Name &certName)
Extract key name from the certificate name certName.
Name extractIdentityFromCertName(const Name &certName)
Extract identity namespace from the certificate name certName.
std::string toIsoExtendedString(const system_clock::time_point &timePoint)
Convert to the ISO 8601 string representation, extended format (YYYY-MM-DDTHH:MM:SS,...
Definition: time.cpp:149
@ Name
Definition: tlv.hpp:71
@ AdditionalDescription
Definition: tlv.hpp:110
@ ContentType_Key
public key, certificate
Definition: tlv.hpp:147
SignatureTypeValue
SignatureType values.
Definition: tlv.hpp:127
Definition: data.cpp:25