| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */ |
| /** |
| * Copyright (C) 2013 Regents of the University of California. |
| * @author: Jeff Thompson <jefft0@remap.ucla.edu> |
| * See COPYING for copyright and distribution information. |
| */ |
| |
| #include <stdlib.h> |
| #include <sstream> |
| |
| #include <ndn-cpp/encoding/oid.hpp> |
| #include <cryptopp/asn.h> |
| |
| using namespace std; |
| using namespace CryptoPP; |
| |
| namespace ndn { |
| |
| OID::OID(const char *oid) |
| { |
| construct(oid); |
| } |
| |
| OID::OID(const string& oid) |
| { |
| construct(oid); |
| } |
| |
| void |
| OID::construct(const std::string &oid) |
| { |
| string str = oid + "."; |
| |
| size_t pos = 0; |
| size_t ppos = 0; |
| |
| while(string::npos != pos){ |
| ppos = pos; |
| |
| pos = str.find_first_of('.', pos); |
| if(pos == string::npos) |
| break; |
| |
| oid_.push_back(atoi(str.substr(ppos, pos - ppos).c_str())); |
| |
| pos++; |
| } |
| } |
| |
| string OID::toString() const |
| { |
| ostringstream convert; |
| |
| vector<int>::const_iterator it = oid_.begin(); |
| for(; it < oid_.end(); it++){ |
| if(it != oid_.begin()) |
| convert << "."; |
| convert << *it; |
| } |
| |
| return convert.str(); |
| } |
| |
| bool |
| OID::equal(const OID& oid) const |
| { |
| vector<int>::const_iterator i = oid_.begin(); |
| vector<int>::const_iterator j = oid.oid_.begin(); |
| |
| for (; i != oid_.end () && j != oid.oid_.end (); i++, j++) { |
| if(*i != *j) |
| return false; |
| } |
| |
| if (i == oid_.end () && j == oid.oid_.end ()) |
| return true; |
| else |
| return false; |
| } |
| |
| inline void |
| EncodeValue(BufferedTransformation &bt, word32 v) |
| { |
| for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7) |
| bt.Put((byte)(0x80 | ((v >> i) & 0x7f))); |
| bt.Put((byte)(v & 0x7f)); |
| } |
| |
| inline size_t |
| DecodeValue(BufferedTransformation &bt, word32 &v) |
| { |
| byte b; |
| size_t i=0; |
| v = 0; |
| while (true) |
| { |
| if (!bt.Get(b)) |
| BERDecodeError(); |
| i++; |
| if (v >> (8*sizeof(v)-7)) // v about to overflow |
| BERDecodeError(); |
| v <<= 7; |
| v += b & 0x7f; |
| if (!(b & 0x80)) |
| return i; |
| } |
| } |
| |
| void |
| OID::encode(CryptoPP::BufferedTransformation &out) const |
| { |
| assert(oid_.size() >= 2); |
| ByteQueue temp; |
| temp.Put(byte(oid_[0] * 40 + oid_[1])); |
| for (size_t i=2; i<oid_.size(); i++) |
| EncodeValue(temp, oid_[i]); |
| out.Put(OBJECT_IDENTIFIER); |
| DERLengthEncode(out, temp.CurrentSize()); |
| temp.TransferTo(out); |
| } |
| |
| void |
| OID::decode(CryptoPP::BufferedTransformation &in) |
| { |
| byte b; |
| if (!in.Get(b) || b != OBJECT_IDENTIFIER) |
| BERDecodeError(); |
| |
| size_t length; |
| if (!BERLengthDecode(in, length) || length < 1) |
| BERDecodeError(); |
| |
| if (!in.Get(b)) |
| BERDecodeError(); |
| |
| length--; |
| oid_.resize(2); |
| oid_[0] = b / 40; |
| oid_[1] = b % 40; |
| |
| while (length > 0) |
| { |
| word32 v; |
| size_t valueLen = DecodeValue(in, v); |
| if (valueLen > length) |
| BERDecodeError(); |
| oid_.push_back(v); |
| length -= valueLen; |
| } |
| } |
| |
| } |