blob: edbfa1ae207a9b0f17b84e323403aaa38edc0547 [file] [log] [blame]
Jeff Thompsonc0573432013-09-19 17:41:36 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
Jeff Thompsonc0573432013-09-19 17:41:36 -070012 */
13
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080014#include "common.hpp"
Jeff Thompsonc0573432013-09-19 17:41:36 -070015
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080016#include "oid.hpp"
17
Junxiao Shi482ccc52014-03-31 13:05:24 -070018#include "../security/cryptopp.hpp"
Jeff Thompsonc0573432013-09-19 17:41:36 -070019
20using namespace std;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080021using namespace CryptoPP;
Jeff Thompsonc0573432013-09-19 17:41:36 -070022
23namespace ndn {
24
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070025OID::OID(const char* oid)
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080026{
27 construct(oid);
28}
29
Jeff Thompsonc0573432013-09-19 17:41:36 -070030OID::OID(const string& oid)
31{
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080032 construct(oid);
33}
34
35void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070036OID::construct(const std::string& oid)
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080037{
Jeff Thompsonc0573432013-09-19 17:41:36 -070038 string str = oid + ".";
39
40 size_t pos = 0;
41 size_t ppos = 0;
42
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070043 while (string::npos != pos) {
Jeff Thompsonc0573432013-09-19 17:41:36 -070044 ppos = pos;
45
46 pos = str.find_first_of('.', pos);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070047 if (pos == string::npos)
Jeff Thompsone589c3f2013-10-12 17:30:50 -070048 break;
Jeff Thompsonc0573432013-09-19 17:41:36 -070049
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070050 m_oid.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
Jeff Thompsonc0573432013-09-19 17:41:36 -070051
52 pos++;
53 }
54}
55
Jeff Thompson6c729a22013-12-20 10:37:59 -080056string OID::toString() const
Jeff Thompsonc0573432013-09-19 17:41:36 -070057{
58 ostringstream convert;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070059
60 for (vector<int>::const_iterator it = m_oid.begin(); it != m_oid.end(); ++it) {
61 if (it != m_oid.begin())
Jeff Thompsonc0573432013-09-19 17:41:36 -070062 convert << ".";
63 convert << *it;
64 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070065
Jeff Thompsonc0573432013-09-19 17:41:36 -070066 return convert.str();
67}
68
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080069bool
70OID::equal(const OID& oid) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070071{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070072 vector<int>::const_iterator i = m_oid.begin();
73 vector<int>::const_iterator j = oid.m_oid.begin();
74
75 for (; i != m_oid.end () && j != oid.m_oid.end (); i++, j++) {
76 if (*i != *j)
Jeff Thompsonc0573432013-09-19 17:41:36 -070077 return false;
78 }
79
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070080 if (i == m_oid.end () && j == oid.m_oid.end ())
Jeff Thompsonc0573432013-09-19 17:41:36 -070081 return true;
82 else
83 return false;
84}
85
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080086inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070087EncodeValue(BufferedTransformation& bt, word32 v)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080088{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070089 for (unsigned int i = RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U) - 7; i != 0; i -= 7)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080090 bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
91 bt.Put((byte)(v & 0x7f));
92}
93
94inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070095DecodeValue(BufferedTransformation& bt, word32& v)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080096{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080097 v = 0;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070098 size_t i = 0;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080099 while (true)
100 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700101 byte b;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800102 if (!bt.Get(b))
103 BERDecodeError();
104 i++;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700105 if (v >> (8*sizeof(v) - 7)) // v about to overflow
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800106 BERDecodeError();
107 v <<= 7;
108 v += b & 0x7f;
109 if (!(b & 0x80))
110 return i;
111 }
112}
113
114void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700115OID::encode(CryptoPP::BufferedTransformation& out) const
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800116{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700117 BOOST_ASSERT(m_oid.size() >= 2);
118
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800119 ByteQueue temp;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700120 temp.Put(byte(m_oid[0] * 40 + m_oid[1]));
121 for (size_t i = 2; i < m_oid.size(); i++)
122 EncodeValue(temp, m_oid[i]);
123
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800124 out.Put(OBJECT_IDENTIFIER);
125 DERLengthEncode(out, temp.CurrentSize());
126 temp.TransferTo(out);
127}
128
129void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700130OID::decode(CryptoPP::BufferedTransformation& in)
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800131{
132 byte b;
133 if (!in.Get(b) || b != OBJECT_IDENTIFIER)
134 BERDecodeError();
135
136 size_t length;
137 if (!BERLengthDecode(in, length) || length < 1)
138 BERDecodeError();
139
140 if (!in.Get(b))
141 BERDecodeError();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700142
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800143 length--;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700144 m_oid.resize(2);
145 m_oid[0] = b / 40;
146 m_oid[1] = b % 40;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800147
148 while (length > 0)
149 {
150 word32 v;
151 size_t valueLen = DecodeValue(in, v);
152 if (valueLen > length)
153 BERDecodeError();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700154 m_oid.push_back(v);
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -0800155 length -= valueLen;
156 }
157}
158
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700159} // namespace ndn