blob: da5ee5c6078a11636ea1626b4424ef4300c46a80 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompsonc0573432013-09-19 17:41:36 -07002/**
Alexander Afanasyev2fa59392016-07-29 17:24:23 -07003 * Copyright (c) 2013-2016 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * 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.
Jeff Thompsonc0573432013-09-19 17:41:36 -070020 */
21
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080022#include "oid.hpp"
23
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070024#include "../security/v1/cryptopp.hpp"
Jeff Thompsonc0573432013-09-19 17:41:36 -070025
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070026#include <sstream>
27
Jeff Thompsonc0573432013-09-19 17:41:36 -070028namespace ndn {
29
Yingdi Yu9d9d5992014-06-25 12:25:16 -070030static const int OID_MAGIC_NUMBER = 40;
31
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070032Oid::Oid(const char* oid)
33 : Oid(std::string(oid))
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080034{
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080035}
36
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070037Oid::Oid(const std::string& oid)
Jeff Thompsonc0573432013-09-19 17:41:36 -070038{
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070039 std::string str = oid + ".";
Jeff Thompsonc0573432013-09-19 17:41:36 -070040
41 size_t pos = 0;
42 size_t ppos = 0;
43
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070044 while (std::string::npos != pos) {
Jeff Thompsonc0573432013-09-19 17:41:36 -070045 ppos = pos;
46
47 pos = str.find_first_of('.', pos);
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070048 if (pos == std::string::npos)
Jeff Thompsone589c3f2013-10-12 17:30:50 -070049 break;
Jeff Thompsonc0573432013-09-19 17:41:36 -070050
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070051 m_oid.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
Jeff Thompsonc0573432013-09-19 17:41:36 -070052
53 pos++;
54 }
55}
56
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070057std::string
58Oid::toString() const
Jeff Thompsonc0573432013-09-19 17:41:36 -070059{
Yingdi Yu9d9d5992014-06-25 12:25:16 -070060 std::ostringstream convert;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070061
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070062 for (std::vector<int>::const_iterator it = m_oid.begin(); it != m_oid.end(); ++it) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070063 if (it != m_oid.begin())
Jeff Thompsonc0573432013-09-19 17:41:36 -070064 convert << ".";
65 convert << *it;
66 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070067
Jeff Thompsonc0573432013-09-19 17:41:36 -070068 return convert.str();
69}
70
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080071bool
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070072Oid::equal(const Oid& oid) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070073{
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070074 std::vector<int>::const_iterator i = m_oid.begin();
75 std::vector<int>::const_iterator j = oid.m_oid.begin();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070076
Yingdi Yu9d9d5992014-06-25 12:25:16 -070077 for (; i != m_oid.end() && j != oid.m_oid.end(); i++, j++) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070078 if (*i != *j)
Jeff Thompsonc0573432013-09-19 17:41:36 -070079 return false;
80 }
81
Yingdi Yu9d9d5992014-06-25 12:25:16 -070082 return (i == m_oid.end() && j == oid.m_oid.end()); // keep parenthesis for readability.
Jeff Thompsonc0573432013-09-19 17:41:36 -070083}
84
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080085inline void
Yingdi Yu9d9d5992014-06-25 12:25:16 -070086encodeValue(CryptoPP::BufferedTransformation& bt, CryptoPP::word32 v)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080087{
Yingdi Yu9d9d5992014-06-25 12:25:16 -070088 using namespace CryptoPP;
89
90 for (unsigned int i = RoundUpToMultipleOf(STDMAX(7U, BitPrecision(v)), 7U) - 7; i != 0; i -= 7)
91 bt.Put(static_cast<byte>(0x80 | ((v >> i) & 0x7f)));
92 bt.Put(static_cast<byte>(v & 0x7f));
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080093}
94
95inline size_t
Yingdi Yu9d9d5992014-06-25 12:25:16 -070096decodeValue(CryptoPP::BufferedTransformation& bt, CryptoPP::word32& v)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080097{
Yingdi Yu9d9d5992014-06-25 12:25:16 -070098 using namespace CryptoPP;
99
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800100 v = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700101 size_t i = 0;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800102 while (true)
103 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700104 byte b;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800105 if (!bt.Get(b))
106 BERDecodeError();
107 i++;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700108 if (v >> (8 * sizeof(v) - 7)) // v about to overflow
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800109 BERDecodeError();
110 v <<= 7;
111 v += b & 0x7f;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700112 if ((b & 0x80) == 0)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800113 return i;
114 }
115}
116
117void
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700118Oid::encode(CryptoPP::BufferedTransformation& out) const
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800119{
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700120 using namespace CryptoPP;
121
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700122 BOOST_ASSERT(m_oid.size() >= 2);
123
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800124 ByteQueue temp;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700125 temp.Put(byte(m_oid[0] * OID_MAGIC_NUMBER + m_oid[1]));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700126 for (size_t i = 2; i < m_oid.size(); i++)
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700127 encodeValue(temp, m_oid[i]);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700128
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800129 out.Put(OBJECT_IDENTIFIER);
130 DERLengthEncode(out, temp.CurrentSize());
131 temp.TransferTo(out);
132}
133
134void
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700135Oid::decode(CryptoPP::BufferedTransformation& in)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800136{
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700137 using namespace CryptoPP;
138
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800139 byte b;
140 if (!in.Get(b) || b != OBJECT_IDENTIFIER)
141 BERDecodeError();
142
143 size_t length;
144 if (!BERLengthDecode(in, length) || length < 1)
145 BERDecodeError();
146
147 if (!in.Get(b))
148 BERDecodeError();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700149
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800150 length--;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700151 m_oid.resize(2);
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700152 m_oid[0] = b / OID_MAGIC_NUMBER;
153 m_oid[1] = b % OID_MAGIC_NUMBER;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800154
155 while (length > 0)
156 {
157 word32 v;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700158 size_t valueLen = decodeValue(in, v);
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800159 if (valueLen > length)
160 BERDecodeError();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700161 m_oid.push_back(v);
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800162 length -= valueLen;
163 }
164}
165
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700166namespace oid {
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700167const Oid RSA("1.2.840.113549.1.1.1");
168const Oid ECDSA("1.2.840.10045.2.1");
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700169
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700170const Oid ATTRIBUTE_NAME("2.5.4.41");
171} // namespace oid
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700172
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700173} // namespace ndn