blob: 1e623a5058db78c977e9c3ada375fa17c33bdd63 [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 Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 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.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
Jeff Thompsonc0573432013-09-19 17:41:36 -070021 */
22
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080023#include "common.hpp"
Jeff Thompsonc0573432013-09-19 17:41:36 -070024
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080025#include "oid.hpp"
26
Junxiao Shi482ccc52014-03-31 13:05:24 -070027#include "../security/cryptopp.hpp"
Jeff Thompsonc0573432013-09-19 17:41:36 -070028
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070029#include <sstream>
30
Jeff Thompsonc0573432013-09-19 17:41:36 -070031namespace ndn {
32
Yingdi Yu9d9d5992014-06-25 12:25:16 -070033using std::string;
34using std::vector;
35
36static const int OID_MAGIC_NUMBER = 40;
37
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070038OID::OID(const char* oid)
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080039{
40 construct(oid);
41}
42
Jeff Thompsonc0573432013-09-19 17:41:36 -070043OID::OID(const string& oid)
44{
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080045 construct(oid);
46}
47
48void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070049OID::construct(const std::string& oid)
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080050{
Jeff Thompsonc0573432013-09-19 17:41:36 -070051 string str = oid + ".";
52
53 size_t pos = 0;
54 size_t ppos = 0;
55
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070056 while (string::npos != pos) {
Jeff Thompsonc0573432013-09-19 17:41:36 -070057 ppos = pos;
58
59 pos = str.find_first_of('.', pos);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070060 if (pos == string::npos)
Jeff Thompsone589c3f2013-10-12 17:30:50 -070061 break;
Jeff Thompsonc0573432013-09-19 17:41:36 -070062
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070063 m_oid.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
Jeff Thompsonc0573432013-09-19 17:41:36 -070064
65 pos++;
66 }
67}
68
Yingdi Yu9d9d5992014-06-25 12:25:16 -070069string
70OID::toString() const
Jeff Thompsonc0573432013-09-19 17:41:36 -070071{
Yingdi Yu9d9d5992014-06-25 12:25:16 -070072 std::ostringstream convert;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070073
74 for (vector<int>::const_iterator it = m_oid.begin(); it != m_oid.end(); ++it) {
75 if (it != m_oid.begin())
Jeff Thompsonc0573432013-09-19 17:41:36 -070076 convert << ".";
77 convert << *it;
78 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070079
Jeff Thompsonc0573432013-09-19 17:41:36 -070080 return convert.str();
81}
82
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080083bool
84OID::equal(const OID& oid) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070085{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070086 vector<int>::const_iterator i = m_oid.begin();
87 vector<int>::const_iterator j = oid.m_oid.begin();
88
Yingdi Yu9d9d5992014-06-25 12:25:16 -070089 for (; i != m_oid.end() && j != oid.m_oid.end(); i++, j++) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070090 if (*i != *j)
Jeff Thompsonc0573432013-09-19 17:41:36 -070091 return false;
92 }
93
Yingdi Yu9d9d5992014-06-25 12:25:16 -070094 return (i == m_oid.end() && j == oid.m_oid.end()); // keep parenthesis for readability.
Jeff Thompsonc0573432013-09-19 17:41:36 -070095}
96
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080097inline void
Yingdi Yu9d9d5992014-06-25 12:25:16 -070098encodeValue(CryptoPP::BufferedTransformation& bt, CryptoPP::word32 v)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080099{
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700100 using namespace CryptoPP;
101
102 for (unsigned int i = RoundUpToMultipleOf(STDMAX(7U, BitPrecision(v)), 7U) - 7; i != 0; i -= 7)
103 bt.Put(static_cast<byte>(0x80 | ((v >> i) & 0x7f)));
104 bt.Put(static_cast<byte>(v & 0x7f));
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800105}
106
107inline size_t
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700108decodeValue(CryptoPP::BufferedTransformation& bt, CryptoPP::word32& v)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800109{
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700110 using namespace CryptoPP;
111
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800112 v = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700113 size_t i = 0;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800114 while (true)
115 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700116 byte b;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800117 if (!bt.Get(b))
118 BERDecodeError();
119 i++;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700120 if (v >> (8 * sizeof(v) - 7)) // v about to overflow
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800121 BERDecodeError();
122 v <<= 7;
123 v += b & 0x7f;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700124 if ((b & 0x80) == 0)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800125 return i;
126 }
127}
128
129void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700130OID::encode(CryptoPP::BufferedTransformation& out) const
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800131{
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700132 using namespace CryptoPP;
133
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700134 BOOST_ASSERT(m_oid.size() >= 2);
135
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800136 ByteQueue temp;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700137 temp.Put(byte(m_oid[0] * OID_MAGIC_NUMBER + m_oid[1]));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700138 for (size_t i = 2; i < m_oid.size(); i++)
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700139 encodeValue(temp, m_oid[i]);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700140
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800141 out.Put(OBJECT_IDENTIFIER);
142 DERLengthEncode(out, temp.CurrentSize());
143 temp.TransferTo(out);
144}
145
146void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700147OID::decode(CryptoPP::BufferedTransformation& in)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800148{
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700149 using namespace CryptoPP;
150
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800151 byte b;
152 if (!in.Get(b) || b != OBJECT_IDENTIFIER)
153 BERDecodeError();
154
155 size_t length;
156 if (!BERLengthDecode(in, length) || length < 1)
157 BERDecodeError();
158
159 if (!in.Get(b))
160 BERDecodeError();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700161
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800162 length--;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700163 m_oid.resize(2);
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700164 m_oid[0] = b / OID_MAGIC_NUMBER;
165 m_oid[1] = b % OID_MAGIC_NUMBER;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800166
167 while (length > 0)
168 {
169 word32 v;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700170 size_t valueLen = decodeValue(in, v);
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800171 if (valueLen > length)
172 BERDecodeError();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700173 m_oid.push_back(v);
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800174 length -= valueLen;
175 }
176}
177
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700178namespace oid {
179const OID RSA("1.2.840.113549.1.1.1");
180const OID ECDSA("1.2.840.10045.2.1");
181
182const OID ATTRIBUTE_NAME("2.5.4.41");
183}
184
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700185} // namespace ndn