blob: 5890a9c3905438e3cb93d6038d876eda4bd3ce36 [file] [log] [blame]
Yingdi Yub8f8b342015-04-27 11:06:42 -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.
Yingdi Yub8f8b342015-04-27 11:06:42 -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
22#include "key.hpp"
23#include "pib-impl.hpp"
24#include "pib.hpp"
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070025#include "../v2/certificate.hpp"
Yingdi Yu6ee2d362015-07-16 21:48:05 -070026#include "../transform/public-key.hpp"
Yingdi Yub8f8b342015-04-27 11:06:42 -070027
28namespace ndn {
29namespace security {
Yingdi Yu6ee2d362015-07-16 21:48:05 -070030namespace pib {
Yingdi Yub8f8b342015-04-27 11:06:42 -070031
32Key::Key()
Yingdi Yu6ee2d362015-07-16 21:48:05 -070033 : m_keyType(KeyType::NONE)
34 , m_hasDefaultCertificate(false)
Yingdi Yub8f8b342015-04-27 11:06:42 -070035 , m_needRefreshCerts(false)
36 , m_impl(nullptr)
37{
38}
39
Yingdi Yu6ee2d362015-07-16 21:48:05 -070040Key::Key(const Name& keyName, const uint8_t* key, size_t keyLen, shared_ptr<PibImpl> impl)
41 : m_keyName(keyName)
42 , m_key(key, keyLen)
Yingdi Yub8f8b342015-04-27 11:06:42 -070043 , m_hasDefaultCertificate(false)
44 , m_needRefreshCerts(true)
45 , m_impl(impl)
46{
47 validityCheck();
48
Yingdi Yu6ee2d362015-07-16 21:48:05 -070049 m_identity = v2::extractIdentityFromKeyName(keyName);
50 m_impl->addIdentity(m_identity);
51 m_impl->addKey(m_identity, m_keyName, key, keyLen);
Yingdi Yub8f8b342015-04-27 11:06:42 -070052
Yingdi Yu6ee2d362015-07-16 21:48:05 -070053 transform::PublicKey publicKey;
54 publicKey.loadPkcs8(key, keyLen);
55 m_keyType = publicKey.getKeyType();
Yingdi Yub8f8b342015-04-27 11:06:42 -070056}
57
Yingdi Yu6ee2d362015-07-16 21:48:05 -070058Key::Key(const Name& keyName, shared_ptr<PibImpl> impl)
59 : m_keyName(keyName)
Yingdi Yub8f8b342015-04-27 11:06:42 -070060 , m_hasDefaultCertificate(false)
61 , m_needRefreshCerts(true)
62 , m_impl(impl)
63{
64 validityCheck();
65
Yingdi Yu6ee2d362015-07-16 21:48:05 -070066 m_identity = v2::extractIdentityFromKeyName(keyName);
67 m_key = m_impl->getKeyBits(m_keyName);
Yingdi Yub8f8b342015-04-27 11:06:42 -070068
Yingdi Yu6ee2d362015-07-16 21:48:05 -070069 transform::PublicKey key;
70 key.loadPkcs8(m_key.buf(), m_key.size());
71 m_keyType = key.getKeyType();
Yingdi Yub8f8b342015-04-27 11:06:42 -070072}
73
74const Name&
75Key::getName() const
76{
77 validityCheck();
78
79 return m_keyName;
80}
81
82const Name&
83Key::getIdentity() const
84{
85 validityCheck();
86
Yingdi Yu6ee2d362015-07-16 21:48:05 -070087 return m_identity;
Yingdi Yub8f8b342015-04-27 11:06:42 -070088}
89
Yingdi Yu6ee2d362015-07-16 21:48:05 -070090const Buffer&
Yingdi Yub8f8b342015-04-27 11:06:42 -070091Key::getPublicKey() const
92{
93 validityCheck();
94
95 return m_key;
96}
97
98void
Yingdi Yu6ee2d362015-07-16 21:48:05 -070099Key::addCertificate(const v2::Certificate& certificate)
Yingdi Yub8f8b342015-04-27 11:06:42 -0700100{
101 validityCheck();
102
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700103 if (certificate.getKeyName() != m_keyName)
104 BOOST_THROW_EXCEPTION(Pib::Error("Certificate name does not match key name"));
105
Yingdi Yub8f8b342015-04-27 11:06:42 -0700106 if (!m_needRefreshCerts &&
107 m_certificates.find(certificate.getName()) == m_certificates.end()) {
108 // if we have already loaded all the certificate, but the new certificate is not one of them
109 // the CertificateContainer should be refreshed
110 m_needRefreshCerts = true;
111 }
112
113 m_impl->addCertificate(certificate);
114}
115
116void
117Key::removeCertificate(const Name& certName)
118{
119 validityCheck();
120
121 if (m_hasDefaultCertificate && m_defaultCertificate.getName() == certName)
122 m_hasDefaultCertificate = false;
123
124 m_impl->removeCertificate(certName);
125 m_needRefreshCerts = true;
126}
127
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700128v2::Certificate
Yingdi Yuc8209892015-06-19 17:47:56 -0700129Key::getCertificate(const Name& certName) const
Yingdi Yub8f8b342015-04-27 11:06:42 -0700130{
131 validityCheck();
132
133 return m_impl->getCertificate(certName);
134}
135
Yingdi Yuc8209892015-06-19 17:47:56 -0700136const CertificateContainer&
137Key::getCertificates() const
Yingdi Yub8f8b342015-04-27 11:06:42 -0700138{
139 validityCheck();
140
141 if (m_needRefreshCerts) {
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700142 m_certificates = CertificateContainer(m_impl->getCertificatesOfKey(m_keyName), m_impl);
Yingdi Yub8f8b342015-04-27 11:06:42 -0700143 m_needRefreshCerts = false;
144 }
145
146 return m_certificates;
147}
148
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700149const v2::Certificate&
Yingdi Yub8f8b342015-04-27 11:06:42 -0700150Key::setDefaultCertificate(const Name& certName)
151{
152 validityCheck();
153
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700154 m_impl->setDefaultCertificateOfKey(m_keyName, certName);
Yingdi Yub8f8b342015-04-27 11:06:42 -0700155 m_defaultCertificate = m_impl->getCertificate(certName);
Yingdi Yub8f8b342015-04-27 11:06:42 -0700156 m_hasDefaultCertificate = true;
157 return m_defaultCertificate;
158}
159
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700160const v2::Certificate&
161Key::setDefaultCertificate(const v2::Certificate& certificate)
Yingdi Yub8f8b342015-04-27 11:06:42 -0700162{
163 addCertificate(certificate);
164 return setDefaultCertificate(certificate.getName());
165}
166
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700167const v2::Certificate&
Yingdi Yuc8209892015-06-19 17:47:56 -0700168Key::getDefaultCertificate() const
Yingdi Yub8f8b342015-04-27 11:06:42 -0700169{
170 validityCheck();
171
172 if (!m_hasDefaultCertificate) {
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700173 m_defaultCertificate = m_impl->getDefaultCertificateOfKey(m_keyName);
Yingdi Yub8f8b342015-04-27 11:06:42 -0700174 m_hasDefaultCertificate = true;
175 }
176
177 return m_defaultCertificate;
178}
179
180Key::operator bool() const
181{
182 return !(this->operator!());
183}
184
185bool
186Key::operator!() const
187{
188 return (m_impl == nullptr);
189}
190
191void
192Key::validityCheck() const
193{
194 if (m_impl == nullptr)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700195 BOOST_THROW_EXCEPTION(std::domain_error("Invalid Key instance"));
Yingdi Yub8f8b342015-04-27 11:06:42 -0700196}
197
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700198} // namespace pib
199
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700200namespace v2 {
201
202Name
203constructKeyName(const Name& identity, const name::Component& keyId)
204{
205 Name keyName = identity;
206 keyName
207 .append(Certificate::KEY_COMPONENT)
208 .append(keyId);
209 return keyName;
210}
211
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700212bool
213isValidKeyName(const Name& keyName)
214{
215 return (keyName.size() > Certificate::MIN_KEY_NAME_LENGTH &&
216 keyName.get(-Certificate::MIN_KEY_NAME_LENGTH) == Certificate::KEY_COMPONENT);
217}
218
219Name
220extractIdentityFromKeyName(const Name& keyName)
221{
222 if (!isValidKeyName(keyName)) {
223 BOOST_THROW_EXCEPTION(std::invalid_argument("Key name `" + keyName.toUri() + "` "
224 "does not follow the naming conventions"));
225 }
226
227 return keyName.getPrefix(-Certificate::MIN_KEY_NAME_LENGTH); // trim everything after and including "KEY"
228}
229
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700230} // namespace v2
231
Yingdi Yub8f8b342015-04-27 11:06:42 -0700232} // namespace security
233} // namespace ndn