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-2020 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 
30 
31 namespace ndn {
32 namespace security {
33 inline namespace v2 {
34 
35 BOOST_CONCEPT_ASSERT((WireEncodable<Certificate>));
36 BOOST_CONCEPT_ASSERT((WireDecodable<Certificate>));
37 
38 // /<NameSpace>/KEY/[KeyId]/[IssuerId]/[Version]
39 
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 
49 {
51 }
52 
54  : Data(std::move(data))
55 {
56  if (!isValidName(getName())) {
57  NDN_THROW(Data::Error("Name does not follow the naming convention for certificate"));
58  }
60  NDN_THROW(Data::Error("Expecting ContentType Key, got " + to_string(getContentType())));
61  }
62  if (getFreshnessPeriod() < time::seconds::zero()) {
63  NDN_THROW(Data::Error("FreshnessPeriod is not set"));
64  }
65  if (getContent().value_size() == 0) {
66  NDN_THROW(Data::Error("Content is empty"));
67  }
68 }
69 
71  : Certificate(Data(data))
72 {
73 }
74 
76  : Certificate(Data(block))
77 {
78 }
79 
80 Name
82 {
83  return getName().getPrefix(KEY_ID_OFFSET + 1);
84 }
85 
86 Name
88 {
90 }
91 
94 {
95  return getName().at(KEY_ID_OFFSET);
96 }
97 
100 {
101  return getName().at(ISSUER_ID_OFFSET);
102 }
103 
104 Buffer
106 {
107  if (getContent().value_size() == 0)
108  NDN_THROW(Data::Error("Content is empty"));
109  return Buffer(getContent().value(), getContent().value_size());
110 }
111 
114 {
116 }
117 
118 bool
120 {
122 }
123 
124 Block
125 Certificate::getExtension(uint32_t type) const
126 {
127  auto block = getSignatureInfo().getCustomTlv(type);
128  if (!block) {
129  NDN_THROW(Error("TLV-TYPE " + to_string(type) + " sub-element does not exist in SignatureInfo"));
130  }
131  return *block;
132 }
133 
134 bool
136 {
137  // /<NameSpace>/KEY/[KeyId]/[IssuerId]/[Version]
138  return (certName.size() >= Certificate::MIN_CERT_NAME_LENGTH &&
139  certName.get(Certificate::KEY_COMPONENT_OFFSET) == Certificate::KEY_COMPONENT);
140 }
141 
142 std::ostream&
143 operator<<(std::ostream& os, const Certificate& cert)
144 {
145  os << "Certificate name:\n";
146  os << " " << cert.getName() << "\n";
147  os << "Validity:\n";
148  {
149  os << " NotBefore: " << time::toIsoString(cert.getValidityPeriod().getPeriod().first) << "\n";
150  os << " NotAfter: " << time::toIsoString(cert.getValidityPeriod().getPeriod().second) << "\n";
151  }
152 
153  auto additionalDescription = cert.getSignatureInfo().getCustomTlv(tlv::AdditionalDescription);
154  if (additionalDescription) {
155  os << "Additional Description:\n";
156  for (const auto& item : v2::AdditionalDescription(*additionalDescription)) {
157  os << " " << item.first << ": " << item.second << "\n";
158  }
159  }
160 
161  os << "Public key bits:\n";
162  {
163  using namespace transform;
164  util::IndentedStream os2(os, " ");
165  bufferSource(cert.getPublicKey().data(), cert.getPublicKey().size()) >> base64Encode() >> streamSink(os2);
166  }
167 
168  os << "Signature Information:\n";
169  {
170  os << " Signature Type: " << static_cast<tlv::SignatureTypeValue>(cert.getSignatureType()) << "\n";
171 
172  auto keyLoc = cert.getKeyLocator();
173  if (keyLoc) {
174  os << " Key Locator: ";
175  if (keyLoc->getType() == tlv::Name && keyLoc->getName() == cert.getKeyName()) {
176  os << "Self-Signed ";
177  }
178  os << *keyLoc << "\n";
179  }
180  }
181 
182  return os;
183 }
184 
185 Name
187 {
188  if (!Certificate::isValidName(certName)) {
189  NDN_THROW(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
190  "does not respect the naming conventions"));
191  }
192 
193  return certName.getPrefix(Certificate::KEY_COMPONENT_OFFSET); // trim everything after and including "KEY"
194 }
195 
196 Name
198 {
199  if (!Certificate::isValidName(certName)) {
200  NDN_THROW(std::invalid_argument("Certificate name `" + certName.toUri() + "` "
201  "does not respect the naming conventions"));
202  }
203 
204  return certName.getPrefix(Certificate::KEY_ID_OFFSET + 1); // trim everything after key id
205 }
206 
207 } // inline namespace v2
208 } // namespace security
209 } // namespace ndn
PartialName getPrefix(ssize_t nComponents) const
Returns a prefix of the name.
Definition: name.hpp:212
Data & setContentType(uint32_t type)
Definition: data.cpp:343
Definition: data.cpp:26
static const ssize_t KEY_ID_OFFSET
The certificate following the certificate format naming convention.
Definition: certificate.hpp:81
Buffer getPublicKey() const
Get public key bits (in PKCS#8 format)
name::Component getIssuerId() const
Get issuer ID.
Definition: certificate.cpp:99
static const size_t MIN_KEY_NAME_LENGTH
std::string to_string(const T &val)
Definition: backports.hpp:101
Name getIdentity() const
Get identity name.
Definition: certificate.cpp:87
const Component & get(ssize_t i) const
Returns an immutable reference to the component at the specified index.
Definition: name.hpp:165
Abstraction of AdditionalDescription.
public key, certificate
Definition: tlv.hpp:162
Name extractKeyNameFromCertName(const Name &certName)
Extract key name from the certificate name certName.
STL namespace.
Represents a TLV element of the NDN packet format.
Definition: block.hpp:42
optional< KeyLocator > getKeyLocator() const noexcept
Get KeyLocator.
Definition: data.hpp:316
bool isValid(const time::system_clock::TimePoint &now=time::system_clock::now()) const
Check if now falls within the validity period.
static const size_t MIN_CERT_NAME_LENGTH
optional< Block > getCustomTlv(uint32_t type) const
Get first custom TLV element with the specified TLV-TYPE.
#define NDN_THROW(e)
Definition: exception.hpp:61
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
std::ostream & operator<<(std::ostream &os, const AdditionalDescription &desc)
int32_t getSignatureType() const noexcept
Get SignatureType.
Definition: data.hpp:308
Abstraction of validity period.
static const ssize_t KEY_COMPONENT_OFFSET
std::pair< time::system_clock::TimePoint, time::system_clock::TimePoint > getPeriod() const
Get the stored validity period.
static const ssize_t VERSION_OFFSET
unique_ptr< Sink > streamSink(std::ostream &os)
Definition: stream-sink.cpp:53
Name getKeyName() const
Get key name.
Definition: certificate.cpp:81
const Name & getName() const noexcept
Get name.
Definition: data.hpp:126
Represents an absolute name.
Definition: name.hpp:44
std::string toIsoString(const system_clock::TimePoint &timePoint)
Convert to the ISO string representation of the time (YYYYMMDDTHHMMSS,fffffffff)
Definition: time.cpp:143
SignatureTypeValue
SignatureType values.
Definition: tlv.hpp:131
size_t size() const
Returns the number of components.
Definition: name.hpp:154
time_point TimePoint
Definition: time.hpp:195
Represents a name component.
name::Component getKeyId() const
Get key ID.
Definition: certificate.cpp:93
static bool isValidName(const Name &certName)
Check if the specified name follows the naming convention for the certificate.
const Block & getContent() const noexcept
Get the Content element.
Definition: data.hpp:172
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:348
static const name::Component KEY_COMPONENT
static const ssize_t ISSUER_ID_OFFSET
Block getExtension(uint32_t type) const
Get extension with TLV type.
ValidityPeriod getValidityPeriod() const
Get validity period of the certificate.
time::milliseconds getFreshnessPeriod() const
Definition: data.hpp:286
Represents a Data packet.
Definition: data.hpp:39
General-purpose automatically managed/resized buffer.
Definition: buffer.hpp:40
Output to stream with specified indent or prefix.
uint32_t getContentType() const
Definition: data.hpp:277
bool isValid(const time::system_clock::TimePoint &ts=time::system_clock::now()) const
Check if the certificate is valid at ts.
const SignatureInfo & getSignatureInfo() const noexcept
Get SignatureInfo.
Definition: data.hpp:231
security::ValidityPeriod getValidityPeriod() const
Get ValidityPeriod.
unique_ptr< Transform > base64Encode(bool needBreak)
Name extractIdentityFromCertName(const Name &certName)
Extract identity namespace from the certificate name certName.