blob: d1504e156ce6f0f0b9014de1494f546ce16cfd5a [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
Alexander Afanasyev736708b2014-01-06 14:45:34 -08008#if __clang__
9#pragma clang diagnostic push
10#pragma clang diagnostic ignored "-Wreorder"
11#pragma clang diagnostic ignored "-Wtautological-compare"
12#pragma clang diagnostic ignored "-Wunused-variable"
13#pragma clang diagnostic ignored "-Wunused-function"
14#elif __GNUC__
15#pragma GCC diagnostic ignored "-Wreorder"
16#pragma GCC diagnostic ignored "-Wtautological-compare"
17#pragma GCC diagnostic ignored "-Wunused-variable"
18#pragma GCC diagnostic ignored "-Wunused-function"
19#endif
20
Jeff Thompsonc0573432013-09-19 17:41:36 -070021#include <stdlib.h>
22#include <sstream>
23
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080024#include "encoding/oid.hpp"
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080025#include <cryptopp/asn.h>
Jeff Thompsonc0573432013-09-19 17:41:36 -070026
27using namespace std;
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080028using namespace CryptoPP;
Jeff Thompsonc0573432013-09-19 17:41:36 -070029
30namespace ndn {
31
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080032OID::OID(const char *oid)
33{
34 construct(oid);
35}
36
Jeff Thompsonc0573432013-09-19 17:41:36 -070037OID::OID(const string& oid)
38{
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080039 construct(oid);
40}
41
42void
43OID::construct(const std::string &oid)
44{
Jeff Thompsonc0573432013-09-19 17:41:36 -070045 string str = oid + ".";
46
47 size_t pos = 0;
48 size_t ppos = 0;
49
50 while(string::npos != pos){
51 ppos = pos;
52
53 pos = str.find_first_of('.', pos);
54 if(pos == string::npos)
Jeff Thompsone589c3f2013-10-12 17:30:50 -070055 break;
Jeff Thompsonc0573432013-09-19 17:41:36 -070056
57 oid_.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
58
59 pos++;
60 }
61}
62
Jeff Thompson6c729a22013-12-20 10:37:59 -080063string OID::toString() const
Jeff Thompsonc0573432013-09-19 17:41:36 -070064{
65 ostringstream convert;
66
Jeff Thompson6c729a22013-12-20 10:37:59 -080067 vector<int>::const_iterator it = oid_.begin();
Jeff Thompsonc0573432013-09-19 17:41:36 -070068 for(; it < oid_.end(); it++){
69 if(it != oid_.begin())
70 convert << ".";
71 convert << *it;
72 }
73
74 return convert.str();
75}
76
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080077bool
78OID::equal(const OID& oid) const
Jeff Thompsonc0573432013-09-19 17:41:36 -070079{
80 vector<int>::const_iterator i = oid_.begin();
81 vector<int>::const_iterator j = oid.oid_.begin();
82
83 for (; i != oid_.end () && j != oid.oid_.end (); i++, j++) {
84 if(*i != *j)
85 return false;
86 }
87
88 if (i == oid_.end () && j == oid.oid_.end ())
89 return true;
90 else
91 return false;
92}
93
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080094inline void
95EncodeValue(BufferedTransformation &bt, word32 v)
96{
97 for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7)
98 bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
99 bt.Put((byte)(v & 0x7f));
100}
101
102inline size_t
103DecodeValue(BufferedTransformation &bt, word32 &v)
104{
105 byte b;
106 size_t i=0;
107 v = 0;
108 while (true)
109 {
110 if (!bt.Get(b))
111 BERDecodeError();
112 i++;
113 if (v >> (8*sizeof(v)-7)) // v about to overflow
114 BERDecodeError();
115 v <<= 7;
116 v += b & 0x7f;
117 if (!(b & 0x80))
118 return i;
119 }
120}
121
122void
123OID::encode(CryptoPP::BufferedTransformation &out) const
124{
125 assert(oid_.size() >= 2);
126 ByteQueue temp;
127 temp.Put(byte(oid_[0] * 40 + oid_[1]));
128 for (size_t i=2; i<oid_.size(); i++)
129 EncodeValue(temp, oid_[i]);
130 out.Put(OBJECT_IDENTIFIER);
131 DERLengthEncode(out, temp.CurrentSize());
132 temp.TransferTo(out);
133}
134
135void
136OID::decode(CryptoPP::BufferedTransformation &in)
137{
138 byte b;
139 if (!in.Get(b) || b != OBJECT_IDENTIFIER)
140 BERDecodeError();
141
142 size_t length;
143 if (!BERLengthDecode(in, length) || length < 1)
144 BERDecodeError();
145
146 if (!in.Get(b))
147 BERDecodeError();
148
149 length--;
150 oid_.resize(2);
151 oid_[0] = b / 40;
152 oid_[1] = b % 40;
153
154 while (length > 0)
155 {
156 word32 v;
157 size_t valueLen = DecodeValue(in, v);
158 if (valueLen > length)
159 BERDecodeError();
160 oid_.push_back(v);
161 length -= valueLen;
162 }
163}
164
Jeff Thompsonc0573432013-09-19 17:41:36 -0700165}