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-2023 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 
32 
33 namespace ndn::security {
34 
36 {
38  setFreshnessPeriod(1_h);
39 }
40 
42  : Data(std::move(data))
43 {
44  if (!isValidName(getName())) {
45  NDN_THROW(Error("Certificate name does not follow the naming conventions"));
46  }
48  NDN_THROW(Error("Expecting ContentType=Key, got " + to_string(getContentType())));
49  }
50  if (getFreshnessPeriod() <= 0_ms) {
51  NDN_THROW(Error("Certificate FreshnessPeriod cannot be zero"));
52  }
53 }
54 
56  : Certificate(Data(data))
57 {
58 }
59 
61  : Certificate(Data(block))
62 {
63 }
64 
65 Name
67 {
69 }
70 
71 Name
73 {
74  return getName().getPrefix(KEY_ID_OFFSET + 1);
75 }
76 
79 {
80  return getName().at(KEY_ID_OFFSET);
81 }
82 
85 {
86  return getName().at(ISSUER_ID_OFFSET);
87 }
88 
91 {
93 }
94 
95 bool
97 {
99 }
100 
101 Block
102 Certificate::getExtension(uint32_t type) const
103 {
104  auto block = getSignatureInfo().getCustomTlv(type);
105  if (!block) {
106  NDN_THROW(Error("TLV-TYPE " + to_string(type) + " sub-element does not exist in SignatureInfo"));
107  }
108  return *block;
109 }
110 
111 bool
113 {
114  // /<IdentityName>/KEY/<KeyId>/<IssuerId>/<Version>
115  return certName.size() >= Certificate::MIN_CERT_NAME_LENGTH &&
117 }
118 
119 std::ostream&
120 operator<<(std::ostream& os, const Certificate& cert)
121 {
122  os << "Certificate Name:\n"
123  << " " << cert.getName() << "\n";
124 
125  auto optAddlDesc = cert.getSignatureInfo().getCustomTlv(tlv::AdditionalDescription);
126  if (optAddlDesc) {
127  os << "Additional Description:\n";
128  try {
129  AdditionalDescription additionalDesc(*optAddlDesc);
130  for (const auto& item : additionalDesc) {
131  os << " " << item.first << ": " << item.second << "\n";
132  }
133  }
134  catch (const tlv::Error&) {
135  using namespace transform;
136  util::IndentedStream os2(os, " ");
137  bufferSource(optAddlDesc->value_bytes()) >> base64Encode() >> streamSink(os2);
138  }
139  }
140 
141  os << "Public Key:\n";
142  {
143  using namespace transform;
144 
145  os << " Key Type: ";
146  try {
147  PublicKey key;
148  key.loadPkcs8(cert.getPublicKey());
149  os << key.getKeySize() << "-bit " << key.getKeyType();
150  }
151  catch (const std::runtime_error&) {
152  os << "Unknown (" << cert.getPublicKey().size() << " bytes)";
153  }
154  os << "\n";
155 
156  if (!cert.getPublicKey().empty()) {
157  util::IndentedStream os2(os, " ");
158  bufferSource(cert.getPublicKey()) >> base64Encode() >> streamSink(os2);
159  }
160  }
161 
162  try {
163  const auto& validityPeriod = cert.getValidityPeriod().getPeriod();
164  os << "Validity:\n"
165  << " Not Before: " << time::toIsoExtendedString(validityPeriod.first) << "\n"
166  << " Not After: " << time::toIsoExtendedString(validityPeriod.second) << "\n";
167  }
168  catch (const tlv::Error&) {
169  // ignore
170  }
171 
172  os << "Signature Information:\n"
173  << " Signature Type: " << static_cast<tlv::SignatureTypeValue>(cert.getSignatureType()) << "\n";
174 
175  auto keyLoc = cert.getKeyLocator();
176  if (keyLoc) {
177  os << " Key Locator: " << *keyLoc << "\n";
178  if (keyLoc->getType() == tlv::Name && keyLoc->getName() == cert.getKeyName()) {
179  os << " Self-Signed: yes\n";
180  }
181  }
182 
183  return os;
184 }
185 
186 Name
188 {
189  if (!Certificate::isValidName(certName)) {
190  NDN_THROW(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
191  "does not respect the naming conventions"));
192  }
193 
194  return certName.getPrefix(Certificate::KEY_COMPONENT_OFFSET); // trim everything after and including "KEY"
195 }
196 
197 Name
199 {
200  if (!Certificate::isValidName(certName)) {
201  NDN_THROW(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
202  "does not respect the naming conventions"));
203  }
204 
205  return certName.getPrefix(Certificate::KEY_ID_OFFSET + 1); // trim everything after key id
206 }
207 
208 } // namespace ndn::security
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:358
time::milliseconds getFreshnessPeriod() const noexcept
Return the value of FreshnessPeriod.
Definition: data.hpp:327
Data & setFreshnessPeriod(time::milliseconds freshnessPeriod)
Set the FreshnessPeriod.
Definition: data.cpp:347
uint32_t getContentType() const noexcept
Return the value of ContentType.
Definition: data.hpp:312
const SignatureInfo & getSignatureInfo() const noexcept
Get the SignatureInfo element.
Definition: data.hpp:243
const Name & getName() const noexcept
Get the Data name.
Definition: data.hpp:137
std::optional< KeyLocator > getKeyLocator() const noexcept
Get the KeyLocator element.
Definition: data.hpp:367
Data & setContentType(uint32_t type)
Set the ContentType.
Definition: data.cpp:337
Represents an absolute name.
Definition: name.hpp:45
PartialName getPrefix(ssize_t nComponents) const
Returns a prefix of the name.
Definition: name.hpp:241
size_t size() const noexcept
Returns the number of components.
Definition: name.hpp:180
const Component & at(ssize_t i) const
Returns an immutable reference to the component at the specified index, with bounds checking.
Definition: name.cpp:146
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:324
security::ValidityPeriod getValidityPeriod() const
Get the ValidityPeriod element.
std::optional< Block > getCustomTlv(uint32_t type) const
Get first custom TLV element with the specified TLV-TYPE.
Represents a name component.
Represents an AdditionalDescription TLV element.
Represents an NDN certificate.
Definition: certificate.hpp:58
name::Component getIssuerId() const
Get issuer ID.
Definition: certificate.cpp:84
span< const uint8_t > getPublicKey() const noexcept
Return the public key as a DER-encoded SubjectPublicKeyInfo structure, i.e., exactly as it appears in...
Name getKeyName() const
Get key name.
Definition: certificate.cpp:72
Name getIdentity() const
Get identity name.
Definition: certificate.cpp:66
static constexpr ssize_t KEY_COMPONENT_OFFSET
name::Component getKeyId() const
Get key ID.
Definition: certificate.cpp:78
bool isValid(const time::system_clock::time_point &ts=time::system_clock::now()) const
Check if the certificate is valid at ts.
Definition: certificate.cpp:96
ValidityPeriod getValidityPeriod() const
Get validity period of the certificate.
Definition: certificate.cpp:90
static constexpr ssize_t ISSUER_ID_OFFSET
static constexpr ssize_t KEY_ID_OFFSET
static const name::Component KEY_COMPONENT
static bool isValidName(const Name &certName)
Check if the specified name respects the naming conventions for certificates.
static constexpr size_t MIN_CERT_NAME_LENGTH
Block getExtension(uint32_t type) const
Get extension with TLV type.
Represents a ValidityPeriod TLV element.
std::pair< time::system_clock::time_point, time::system_clock::time_point > getPeriod() const
Get the stored validity period.
bool isValid(const time::system_clock::time_point &now=time::system_clock::now()) const
Check if now falls within the validity period.
::boost::chrono::time_point< system_clock > time_point
Definition: time.hpp:205
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:56
std::string to_string(const errinfo_stacktrace &x)
Definition: exception.cpp:30
unique_ptr< Sink > streamSink(std::ostream &os)
Definition: stream-sink.cpp:51
unique_ptr< Transform > base64Encode(bool needBreak)
Contains the ndn-cxx security framework.
std::ostream & operator<<(std::ostream &os, const AdditionalDescription &desc)
Name extractIdentityFromCertName(const Name &certName)
Extract identity namespace from the certificate name certName.
Name extractKeyNameFromCertName(const Name &certName)
Extract key name 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:136
@ 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