blob: 0fb66972718d962b14435fddd1bacfdc325a2de8 [file] [log] [blame]
Jeff Thompsonc0573432013-09-19 17:41:36 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
5 * See COPYING for copyright and distribution information.
6 */
7
8#include <stdlib.h>
9#include <sstream>
10
Jeff Thompson31b5c2f2013-10-12 15:13:16 -070011#include <ndn-cpp/encoding/oid.hpp>
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080012#include <cryptopp/asn.h>
Jeff Thompsonc0573432013-09-19 17:41:36 -070013
14using namespace std;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080015using namespace CryptoPP;
Jeff Thompsonc0573432013-09-19 17:41:36 -070016
17namespace ndn {
18
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080019OID::OID(const char *oid)
20{
21 construct(oid);
22}
23
Jeff Thompsonc0573432013-09-19 17:41:36 -070024OID::OID(const string& oid)
25{
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080026 construct(oid);
27}
28
29void
30OID::construct(const std::string &oid)
31{
Jeff Thompsonc0573432013-09-19 17:41:36 -070032 string str = oid + ".";
33
34 size_t pos = 0;
35 size_t ppos = 0;
36
37 while(string::npos != pos){
38 ppos = pos;
39
40 pos = str.find_first_of('.', pos);
41 if(pos == string::npos)
Jeff Thompsone589c3f2013-10-12 17:30:50 -070042 break;
Jeff Thompsonc0573432013-09-19 17:41:36 -070043
44 oid_.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
45
46 pos++;
47 }
48}
49
Jeff Thompson6c729a22013-12-20 10:37:59 -080050string OID::toString() const
Jeff Thompsonc0573432013-09-19 17:41:36 -070051{
52 ostringstream convert;
53
Jeff Thompson6c729a22013-12-20 10:37:59 -080054 vector<int>::const_iterator it = oid_.begin();
Jeff Thompsonc0573432013-09-19 17:41:36 -070055 for(; it < oid_.end(); it++){
56 if(it != oid_.begin())
57 convert << ".";
58 convert << *it;
59 }
60
61 return convert.str();
62}
63
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080064bool
65OID::equal(const OID& oid) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070066{
67 vector<int>::const_iterator i = oid_.begin();
68 vector<int>::const_iterator j = oid.oid_.begin();
69
70 for (; i != oid_.end () && j != oid.oid_.end (); i++, j++) {
71 if(*i != *j)
72 return false;
73 }
74
75 if (i == oid_.end () && j == oid.oid_.end ())
76 return true;
77 else
78 return false;
79}
80
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080081inline void
82EncodeValue(BufferedTransformation &bt, word32 v)
83{
84 for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7)
85 bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
86 bt.Put((byte)(v & 0x7f));
87}
88
89inline size_t
90DecodeValue(BufferedTransformation &bt, word32 &v)
91{
92 byte b;
93 size_t i=0;
94 v = 0;
95 while (true)
96 {
97 if (!bt.Get(b))
98 BERDecodeError();
99 i++;
100 if (v >> (8*sizeof(v)-7)) // v about to overflow
101 BERDecodeError();
102 v <<= 7;
103 v += b & 0x7f;
104 if (!(b & 0x80))
105 return i;
106 }
107}
108
109void
110OID::encode(CryptoPP::BufferedTransformation &out) const
111{
112 assert(oid_.size() >= 2);
113 ByteQueue temp;
114 temp.Put(byte(oid_[0] * 40 + oid_[1]));
115 for (size_t i=2; i<oid_.size(); i++)
116 EncodeValue(temp, oid_[i]);
117 out.Put(OBJECT_IDENTIFIER);
118 DERLengthEncode(out, temp.CurrentSize());
119 temp.TransferTo(out);
120}
121
122void
123OID::decode(CryptoPP::BufferedTransformation &in)
124{
125 byte b;
126 if (!in.Get(b) || b != OBJECT_IDENTIFIER)
127 BERDecodeError();
128
129 size_t length;
130 if (!BERLengthDecode(in, length) || length < 1)
131 BERDecodeError();
132
133 if (!in.Get(b))
134 BERDecodeError();
135
136 length--;
137 oid_.resize(2);
138 oid_[0] = b / 40;
139 oid_[1] = b % 40;
140
141 while (length > 0)
142 {
143 word32 v;
144 size_t valueLen = DecodeValue(in, v);
145 if (valueLen > length)
146 BERDecodeError();
147 oid_.push_back(v);
148 length -= valueLen;
149 }
150}
151
Jeff Thompsonc0573432013-09-19 17:41:36 -0700152}