blob: 511ff6ce5a4cbab90d93ea7dd1688878fbe32553 [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 -070031using namespace std;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080032using namespace CryptoPP;
Jeff Thompsonc0573432013-09-19 17:41:36 -070033
34namespace ndn {
35
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070036OID::OID(const char* oid)
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080037{
38 construct(oid);
39}
40
Jeff Thompsonc0573432013-09-19 17:41:36 -070041OID::OID(const string& oid)
42{
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080043 construct(oid);
44}
45
46void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070047OID::construct(const std::string& oid)
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080048{
Jeff Thompsonc0573432013-09-19 17:41:36 -070049 string str = oid + ".";
50
51 size_t pos = 0;
52 size_t ppos = 0;
53
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070054 while (string::npos != pos) {
Jeff Thompsonc0573432013-09-19 17:41:36 -070055 ppos = pos;
56
57 pos = str.find_first_of('.', pos);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070058 if (pos == string::npos)
Jeff Thompsone589c3f2013-10-12 17:30:50 -070059 break;
Jeff Thompsonc0573432013-09-19 17:41:36 -070060
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070061 m_oid.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
Jeff Thompsonc0573432013-09-19 17:41:36 -070062
63 pos++;
64 }
65}
66
Jeff Thompson6c729a22013-12-20 10:37:59 -080067string OID::toString() const
Jeff Thompsonc0573432013-09-19 17:41:36 -070068{
69 ostringstream convert;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070070
71 for (vector<int>::const_iterator it = m_oid.begin(); it != m_oid.end(); ++it) {
72 if (it != m_oid.begin())
Jeff Thompsonc0573432013-09-19 17:41:36 -070073 convert << ".";
74 convert << *it;
75 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070076
Jeff Thompsonc0573432013-09-19 17:41:36 -070077 return convert.str();
78}
79
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080080bool
81OID::equal(const OID& oid) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070082{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070083 vector<int>::const_iterator i = m_oid.begin();
84 vector<int>::const_iterator j = oid.m_oid.begin();
85
86 for (; i != m_oid.end () && j != oid.m_oid.end (); i++, j++) {
87 if (*i != *j)
Jeff Thompsonc0573432013-09-19 17:41:36 -070088 return false;
89 }
90
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070091 if (i == m_oid.end () && j == oid.m_oid.end ())
Jeff Thompsonc0573432013-09-19 17:41:36 -070092 return true;
93 else
94 return false;
95}
96
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080097inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070098EncodeValue(BufferedTransformation& bt, word32 v)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080099{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700100 for (unsigned int i = RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U) - 7; i != 0; i -= 7)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800101 bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
102 bt.Put((byte)(v & 0x7f));
103}
104
105inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700106DecodeValue(BufferedTransformation& bt, word32& v)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800107{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800108 v = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700109 size_t i = 0;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800110 while (true)
111 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700112 byte b;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800113 if (!bt.Get(b))
114 BERDecodeError();
115 i++;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700116 if (v >> (8*sizeof(v) - 7)) // v about to overflow
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800117 BERDecodeError();
118 v <<= 7;
119 v += b & 0x7f;
120 if (!(b & 0x80))
121 return i;
122 }
123}
124
125void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700126OID::encode(CryptoPP::BufferedTransformation& out) const
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800127{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700128 BOOST_ASSERT(m_oid.size() >= 2);
129
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800130 ByteQueue temp;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700131 temp.Put(byte(m_oid[0] * 40 + m_oid[1]));
132 for (size_t i = 2; i < m_oid.size(); i++)
133 EncodeValue(temp, m_oid[i]);
134
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800135 out.Put(OBJECT_IDENTIFIER);
136 DERLengthEncode(out, temp.CurrentSize());
137 temp.TransferTo(out);
138}
139
140void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700141OID::decode(CryptoPP::BufferedTransformation& in)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800142{
143 byte b;
144 if (!in.Get(b) || b != OBJECT_IDENTIFIER)
145 BERDecodeError();
146
147 size_t length;
148 if (!BERLengthDecode(in, length) || length < 1)
149 BERDecodeError();
150
151 if (!in.Get(b))
152 BERDecodeError();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700153
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800154 length--;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700155 m_oid.resize(2);
156 m_oid[0] = b / 40;
157 m_oid[1] = b % 40;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800158
159 while (length > 0)
160 {
161 word32 v;
162 size_t valueLen = DecodeValue(in, v);
163 if (valueLen > length)
164 BERDecodeError();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700165 m_oid.push_back(v);
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800166 length -= valueLen;
167 }
168}
169
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700170} // namespace ndn