blob: 2db72f7c14822ad773fa7f749a2758e092a5ca5a [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
19OID::OID(const string& oid)
20{
21 string str = oid + ".";
22
23 size_t pos = 0;
24 size_t ppos = 0;
25
26 while(string::npos != pos){
27 ppos = pos;
28
29 pos = str.find_first_of('.', pos);
30 if(pos == string::npos)
Jeff Thompsone589c3f2013-10-12 17:30:50 -070031 break;
Jeff Thompsonc0573432013-09-19 17:41:36 -070032
33 oid_.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
34
35 pos++;
36 }
37}
38
Jeff Thompson6c729a22013-12-20 10:37:59 -080039string OID::toString() const
Jeff Thompsonc0573432013-09-19 17:41:36 -070040{
41 ostringstream convert;
42
Jeff Thompson6c729a22013-12-20 10:37:59 -080043 vector<int>::const_iterator it = oid_.begin();
Jeff Thompsonc0573432013-09-19 17:41:36 -070044 for(; it < oid_.end(); it++){
45 if(it != oid_.begin())
46 convert << ".";
47 convert << *it;
48 }
49
50 return convert.str();
51}
52
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080053bool
54OID::equal(const OID& oid) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070055{
56 vector<int>::const_iterator i = oid_.begin();
57 vector<int>::const_iterator j = oid.oid_.begin();
58
59 for (; i != oid_.end () && j != oid.oid_.end (); i++, j++) {
60 if(*i != *j)
61 return false;
62 }
63
64 if (i == oid_.end () && j == oid.oid_.end ())
65 return true;
66 else
67 return false;
68}
69
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080070inline void
71EncodeValue(BufferedTransformation &bt, word32 v)
72{
73 for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7)
74 bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
75 bt.Put((byte)(v & 0x7f));
76}
77
78inline size_t
79DecodeValue(BufferedTransformation &bt, word32 &v)
80{
81 byte b;
82 size_t i=0;
83 v = 0;
84 while (true)
85 {
86 if (!bt.Get(b))
87 BERDecodeError();
88 i++;
89 if (v >> (8*sizeof(v)-7)) // v about to overflow
90 BERDecodeError();
91 v <<= 7;
92 v += b & 0x7f;
93 if (!(b & 0x80))
94 return i;
95 }
96}
97
98void
99OID::encode(CryptoPP::BufferedTransformation &out) const
100{
101 assert(oid_.size() >= 2);
102 ByteQueue temp;
103 temp.Put(byte(oid_[0] * 40 + oid_[1]));
104 for (size_t i=2; i<oid_.size(); i++)
105 EncodeValue(temp, oid_[i]);
106 out.Put(OBJECT_IDENTIFIER);
107 DERLengthEncode(out, temp.CurrentSize());
108 temp.TransferTo(out);
109}
110
111void
112OID::decode(CryptoPP::BufferedTransformation &in)
113{
114 byte b;
115 if (!in.Get(b) || b != OBJECT_IDENTIFIER)
116 BERDecodeError();
117
118 size_t length;
119 if (!BERLengthDecode(in, length) || length < 1)
120 BERDecodeError();
121
122 if (!in.Get(b))
123 BERDecodeError();
124
125 length--;
126 oid_.resize(2);
127 oid_[0] = b / 40;
128 oid_[1] = b % 40;
129
130 while (length > 0)
131 {
132 word32 v;
133 size_t valueLen = DecodeValue(in, v);
134 if (valueLen > length)
135 BERDecodeError();
136 oid_.push_back(v);
137 length -= valueLen;
138 }
139}
140
Jeff Thompsonc0573432013-09-19 17:41:36 -0700141}