blob: 94578b4da71dd64500ec2d9b7c23fab82f8a265f [file] [log] [blame]
Jeff Thompsona92861a2013-10-16 14:06:23 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
6 * See COPYING for copyright and distribution information.
7 */
8
Jeff Thompsonea946202013-10-18 14:35:32 -07009#include <stdexcept>
Jeff Thompsona92861a2013-10-16 14:06:23 -070010#include "der-exception.hpp"
11#include "../../util/logging.hpp"
Jeff Thompson5a6ce832013-10-18 11:54:35 -070012#include "../../c/util/time.h"
Jeff Thompsona92861a2013-10-16 14:06:23 -070013#include "der.hpp"
14
15INIT_LOGGER("ndn.der.DER");
16
17using namespace std;
Jeff Thompsona92861a2013-10-16 14:06:23 -070018
19namespace ndn {
20
21namespace der {
22
23/*
24 * DerNode
25 */
26DerNode::DerNode()
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070027 :parent_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -070028{}
29
30DerNode::DerNode(DerType type)
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070031 :type_(type),
32 parent_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -070033{}
34
Jeff Thompson2d47db72013-10-17 15:19:52 -070035DerNode::DerNode(InputIterator& start)
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070036 :parent_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -070037{
38 decode(start);
39}
40
41DerNode::~DerNode()
42{}
43
44void
45DerNode::encodeHeader(int size)
46{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070047 header_.push_back((char)type_);
Jeff Thompsona92861a2013-10-16 14:06:23 -070048
Jeff Thompson161a2e02013-10-16 16:04:08 -070049 if (size >= 127) {
50 int val = size;
51 char buf[sizeof(val) + 1];
52 char *p = &(buf[sizeof(buf)-1]);
53 int n = 0;
54 int mask = (1 << 8) - 1;
Jeff Thompsona92861a2013-10-16 14:06:23 -070055
Jeff Thompson161a2e02013-10-16 16:04:08 -070056 while (val != 0) {
57 p[0] = (char)(val & mask);
58 p--;
Jeff Thompsona92861a2013-10-16 14:06:23 -070059 n++;
Jeff Thompson161a2e02013-10-16 16:04:08 -070060 val >>= 8;
61 }
Jeff Thompsona92861a2013-10-16 14:06:23 -070062
Jeff Thompson161a2e02013-10-16 16:04:08 -070063 p[0] = (char)((1<<7) | n);
64 n++;
65
66 header_.insert(header_.end(), p, p+n);
67 }
68 else if (size >= 0)
69 header_.push_back((char)size);
Jeff Thompsona92861a2013-10-16 14:06:23 -070070 else
71 throw NegativeLengthException("Negative length");
72}
73
74int
Jeff Thompson2d47db72013-10-17 15:19:52 -070075DerNode::decodeHeader(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -070076{
Jeff Thompson2d47db72013-10-17 15:19:52 -070077 uint8_t type = start.ReadU8();
Jeff Thompsona92861a2013-10-16 14:06:23 -070078 // char type = start.get();
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070079 header_.push_back(type);
80 type_ = static_cast<DerType>((int)type);
Jeff Thompsona92861a2013-10-16 14:06:23 -070081
Jeff Thompson2d47db72013-10-17 15:19:52 -070082 uint8_t sizeLen = start.ReadU8();
Jeff Thompsona92861a2013-10-16 14:06:23 -070083 // char sizeLen = start.get();
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070084 header_.push_back(sizeLen);
Jeff Thompsona92861a2013-10-16 14:06:23 -070085
86 bool longFormat = sizeLen & (1 << 7);
87
Jeff Thompson161a2e02013-10-16 16:04:08 -070088 if (!longFormat) {
89 // _LOG_DEBUG("Short Format");
90 // _LOG_DEBUG("sizeLen: " << (int)sizeLen);
91 return (int)sizeLen;
92 }
93 else {
94 // _LOG_DEBUG("Long Format");
95 uint8_t byte;
96 // char byte;
97 int lenCount = sizeLen & ((1<<7) - 1);
98 // _LOG_DEBUG("sizeLen: " << (int)sizeLen);
99 // _LOG_DEBUG("mask: " << (int)((1<<7) - 1));
100 // _LOG_DEBUG("lenCount: " << (int)lenCount);
101 int size = 0;
102 do {
Jeff Thompson2d47db72013-10-17 15:19:52 -0700103 byte = start.ReadU8();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700104 header_.push_back(byte);
105 size = size * 256 + (int)byte;
106 // _LOG_DEBUG("byte: " << (int)byte);
107 // _LOG_DEBUG("size: " << size);
108 lenCount--;
109 } while (lenCount > 0);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700110
Jeff Thompson161a2e02013-10-16 16:04:08 -0700111 return size;
112 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700113}
114
115void
Jeff Thompson2d47db72013-10-17 15:19:52 -0700116DerNode::encode(OutputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700117{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700118 start.write((const char*)&header_[0], header_.size());
119 start.write((const char*)&payload_[0], payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700120}
121
122void
Jeff Thompson2d47db72013-10-17 15:19:52 -0700123DerNode::decode(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700124{
125 int payloadSize = decodeHeader(start);
126 // _LOG_DEBUG("payloadSize: " << payloadSize);
Jeff Thompson161a2e02013-10-16 16:04:08 -0700127 if (payloadSize > 0 ) {
128 char buf[payloadSize];
129 start.read(buf, payloadSize);
130 payload_.insert(payload_.end(), buf, buf + payloadSize);
131 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700132}
133
Jeff Thompsonce115762013-12-18 14:59:56 -0800134ptr_lib::shared_ptr<DerNode>
Jeff Thompson2d47db72013-10-17 15:19:52 -0700135DerNode::parse(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700136{
Jeff Thompson2d47db72013-10-17 15:19:52 -0700137 int type = ((uint8_t)start.PeekU8());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700138
139 // _LOG_DEBUG("Type: " << hex << setw(2) << setfill('0') << type);
140 switch(type) {
141 case DER_BOOLEAN:
Jeff Thompsonce115762013-12-18 14:59:56 -0800142 return ptr_lib::shared_ptr<DerBool>(new DerBool(start));
Jeff Thompsona92861a2013-10-16 14:06:23 -0700143 case DER_INTEGER:
Jeff Thompsonce115762013-12-18 14:59:56 -0800144 return ptr_lib::shared_ptr<DerInteger>(new DerInteger(start));
Jeff Thompsona92861a2013-10-16 14:06:23 -0700145 case DER_BIT_STRING:
Jeff Thompsonce115762013-12-18 14:59:56 -0800146 return ptr_lib::shared_ptr<DerBitString>(new DerBitString(start));
Jeff Thompsona92861a2013-10-16 14:06:23 -0700147 case DER_OCTET_STRING:
Jeff Thompsonce115762013-12-18 14:59:56 -0800148 return ptr_lib::shared_ptr<DerOctetString>(new DerOctetString(start));
Jeff Thompsona92861a2013-10-16 14:06:23 -0700149 case DER_NULL:
Jeff Thompsonce115762013-12-18 14:59:56 -0800150 return ptr_lib::shared_ptr<DerNull>(new DerNull(start));
Jeff Thompsona92861a2013-10-16 14:06:23 -0700151 case DER_OBJECT_IDENTIFIER:
Jeff Thompsonce115762013-12-18 14:59:56 -0800152 return ptr_lib::shared_ptr<DerOid>(new DerOid(start));
Jeff Thompsona92861a2013-10-16 14:06:23 -0700153 case DER_SEQUENCE:
Jeff Thompsonce115762013-12-18 14:59:56 -0800154 return ptr_lib::shared_ptr<DerSequence>(new DerSequence(start));
Jeff Thompsona92861a2013-10-16 14:06:23 -0700155 case DER_PRINTABLE_STRING:
Jeff Thompsonce115762013-12-18 14:59:56 -0800156 return ptr_lib::shared_ptr<DerPrintableString>(new DerPrintableString(start));
Jeff Thompsona92861a2013-10-16 14:06:23 -0700157 case DER_GENERALIZED_TIME:
Jeff Thompsonce115762013-12-18 14:59:56 -0800158 return ptr_lib::shared_ptr<DerGtime>(new DerGtime(start));
Jeff Thompsona92861a2013-10-16 14:06:23 -0700159 default:
Jeff Thompson5a6ce832013-10-18 11:54:35 -0700160 throw DerDecodingException("Unimplemented DER type");
Jeff Thompson161a2e02013-10-16 16:04:08 -0700161 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700162}
163
164
165/*
166 * DerComplex
167 */
168DerComplex::DerComplex()
169 :DerNode(),
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700170 childChanged_(false),
171 size_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700172{}
173
174DerComplex::DerComplex(DerType type)
175 :DerNode(type),
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700176 childChanged_(false),
177 size_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700178{}
179
Jeff Thompson2d47db72013-10-17 15:19:52 -0700180DerComplex::DerComplex(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700181 :DerNode(),
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700182 childChanged_(false),
183 size_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700184{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700185 size_ = DerNode::decodeHeader(start);
186 // _LOG_DEBUG("Size: " << size_);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700187
188 int accSize = 0;
189
Jeff Thompson161a2e02013-10-16 16:04:08 -0700190 while (accSize < size_) {
191 // _LOG_DEBUG("accSize: " << accSize);
Jeff Thompsonce115762013-12-18 14:59:56 -0800192 ptr_lib::shared_ptr<DerNode> nodePtr = DerNode::parse(start);
Jeff Thompson161a2e02013-10-16 16:04:08 -0700193 accSize += nodePtr->getSize();
194 addChild(nodePtr, false);
195 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700196}
197
198DerComplex::~DerComplex()
199{}
200
201int
202DerComplex::getSize()
203{
Jeff Thompson161a2e02013-10-16 16:04:08 -0700204 if (childChanged_) {
205 updateSize();
206 childChanged_ = false;
207 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700208
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700209 header_.clear();
210 DerNode::encodeHeader(size_);
211 return size_ + header_.size();
Jeff Thompsona92861a2013-10-16 14:06:23 -0700212}
213
Jeff Thompson415da1e2013-10-17 16:52:59 -0700214Blob
Jeff Thompsona92861a2013-10-16 14:06:23 -0700215DerComplex::getRaw()
216{
Jeff Thompsonce115762013-12-18 14:59:56 -0800217 ptr_lib::shared_ptr<vector<uint8_t> > blob(new vector<uint8_t>());
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700218 blob->insert(blob->end(), header_.begin(), header_.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700219
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700220 DerNodePtrList::iterator it = nodeList_.begin();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700221 for (; it != nodeList_.end(); it++) {
Jeff Thompson415da1e2013-10-17 16:52:59 -0700222 Blob childBlob = (*it)->getRaw();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700223 blob->insert(blob->end(), childBlob->begin(), childBlob->end());
224 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700225 return blob;
226}
227
228void
229DerComplex::updateSize()
230{
231 int newSize = 0;
232
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700233 DerNodePtrList::iterator it = nodeList_.begin();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700234 for (; it != nodeList_.end(); it++) {
235 newSize += (*it)->getSize();
236 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700237
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700238 size_ = newSize;
239 childChanged_ = false;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700240}
241
242void
Jeff Thompsonce115762013-12-18 14:59:56 -0800243DerComplex::addChild(ptr_lib::shared_ptr<DerNode> nodePtr, bool notifyParent)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700244{
245 nodePtr->setParent(this);
246
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700247 nodeList_.push_back(nodePtr);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700248
Jeff Thompson161a2e02013-10-16 16:04:08 -0700249 if (!notifyParent)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700250 return;
251
Jeff Thompson161a2e02013-10-16 16:04:08 -0700252 if (childChanged_)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700253 return;
254 else
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700255 childChanged_ = true;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700256
Jeff Thompson161a2e02013-10-16 16:04:08 -0700257 if (0 != parent_)
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700258 parent_->setChildChanged();
Jeff Thompsona92861a2013-10-16 14:06:23 -0700259}
260
261void
262DerComplex::setChildChanged()
263{
Jeff Thompson161a2e02013-10-16 16:04:08 -0700264 if (0 != parent_ && !childChanged_) {
265 parent_->setChildChanged();
266 childChanged_ = true;
267 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700268 else
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700269 childChanged_ = true;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700270}
271
272void
Jeff Thompson2d47db72013-10-17 15:19:52 -0700273DerComplex::encode(OutputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700274{
275 updateSize();
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700276 header_.clear();
Jeff Thompsona92861a2013-10-16 14:06:23 -0700277
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700278 DerNode::encodeHeader(size_);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700279
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700280 start.write((const char*)&header_[0], header_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700281
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700282 DerNodePtrList::iterator it = nodeList_.begin();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700283 for (; it != nodeList_.end(); it++)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700284 (*it)->encode(start);
285}
286
287
288/*
289 * DerByteString
290 */
291DerByteString::DerByteString(const string& str, DerType type)
292 :DerNode(type)
293{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700294 payload_.insert(payload_.end(), str.begin(), str.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700295
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700296 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700297}
298
Jeff Thompson4affbf52013-10-18 14:36:46 -0700299DerByteString::DerByteString(const vector<uint8_t>& blob, DerType type)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700300 :DerNode(type)
301{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700302 payload_.insert(payload_.end(), blob.begin(), blob.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700303
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700304 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700305}
306
Jeff Thompson2d47db72013-10-17 15:19:52 -0700307DerByteString::DerByteString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700308 :DerNode(start)
309{}
310
311DerByteString::~DerByteString()
312{}
313
314
315/*
316 * DerBool
317 */
318DerBool::DerBool(bool value)
319 :DerNode(DER_BOOLEAN)
320
321{
322 char payload = (value ? 0xFF : 0x00);
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700323 payload_.push_back(payload);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700324
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700325 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700326}
327
Jeff Thompson2d47db72013-10-17 15:19:52 -0700328DerBool::DerBool(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700329 :DerNode(start)
330{}
331
332DerBool::~DerBool()
333{}
334
335
336/*
337 * DerInteger
338 */
339DerInteger::DerInteger(const vector<uint8_t>& blob)
340 :DerNode(DER_INTEGER)
341{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700342 payload_.insert(payload_.end(), blob.begin(), blob.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700343
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700344 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700345}
346
Jeff Thompson2d47db72013-10-17 15:19:52 -0700347DerInteger::DerInteger(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700348 :DerNode(start)
349{}
350
351DerInteger::~DerInteger()
352{}
353
354
355/*
356 * DerBitString
357 */
358DerBitString::DerBitString(const vector<uint8_t>& blob, uint8_t paddingLen)
359 :DerNode(DER_BIT_STRING)
360{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700361 payload_.push_back((char)paddingLen);
362 payload_.insert(payload_.end(), blob.begin(), blob.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700363
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700364 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700365}
366
Jeff Thompson2d47db72013-10-17 15:19:52 -0700367DerBitString::DerBitString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700368 :DerNode(start)
369{}
370
371DerBitString::~DerBitString()
372{}
373
374
375/*
376 * DerOctetString
377 */
378DerOctetString::DerOctetString(const string& str)
379 :DerByteString(str, DER_OCTET_STRING)
380{}
381
382DerOctetString::DerOctetString(const vector<uint8_t>& blob)
383 :DerByteString(blob, DER_OCTET_STRING)
384{}
385
Jeff Thompson2d47db72013-10-17 15:19:52 -0700386DerOctetString::DerOctetString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700387 :DerByteString(start)
388{}
389
390DerOctetString::~DerOctetString()
391{}
392
393
394/*
395 * DerNull
396 */
397DerNull::DerNull()
398 :DerNode(DER_NULL)
399{
400 DerNode::encodeHeader(0);
401}
402
Jeff Thompson2d47db72013-10-17 15:19:52 -0700403DerNull::DerNull(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700404 :DerNode(start)
405{}
406
407DerNull::~DerNull()
408{}
409
410
411/*
412 * DerOid
413 */
414DerOid::DerOid(const OID& oid)
415 :DerNode(DER_OBJECT_IDENTIFIER)
416{
417 prepareEncoding(oid.getIntegerList());
418}
419
420
421DerOid::DerOid(const string& oidStr)
422 :DerNode(DER_OBJECT_IDENTIFIER)
423{
424 vector<int> value;
425
426 string str = oidStr + ".";
427
428 size_t pos = 0;
429 size_t ppos = 0;
430
Jeff Thompson161a2e02013-10-16 16:04:08 -0700431 while (string::npos != pos) {
Jeff Thompsona92861a2013-10-16 14:06:23 -0700432 ppos = pos;
433
434 pos = str.find_first_of('.', pos);
Jeff Thompson161a2e02013-10-16 16:04:08 -0700435 if (string::npos == pos)
436 break;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700437
438 value.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
439
440 pos++;
441 }
442
443 prepareEncoding(value);
444}
445
446DerOid::DerOid(const vector<int>& value)
447 :DerNode(DER_OBJECT_IDENTIFIER)
448{
449 prepareEncoding(value);
450}
451
Jeff Thompson2d47db72013-10-17 15:19:52 -0700452DerOid::DerOid(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700453 :DerNode(start)
454{}
455
456DerOid::~DerOid()
457{}
458
459void
460DerOid::prepareEncoding(const vector<int>& value)
461{
462 ostringstream os;
463
464 int firstNumber = 0;
465
Jeff Thompson161a2e02013-10-16 16:04:08 -0700466 if (value.size() >= 1) {
467 if (0 <= value[0] && 2 >= value[0])
468 firstNumber = value[0] * 40;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700469 else
Jeff Thompson161a2e02013-10-16 16:04:08 -0700470 throw DerEncodingException("first integer of oid is out of range");
Jeff Thompsona92861a2013-10-16 14:06:23 -0700471 }
472 else
473 throw DerEncodingException("no integer in oid");
474
Jeff Thompson161a2e02013-10-16 16:04:08 -0700475 if (value.size() >= 2) {
476 if (0 <= value[1] && 39 >= value[1])
477 firstNumber += value[1];
Jeff Thompsona92861a2013-10-16 14:06:23 -0700478 else
Jeff Thompson161a2e02013-10-16 16:04:08 -0700479 throw DerEncodingException("second integer of oid is out of range");
Jeff Thompsona92861a2013-10-16 14:06:23 -0700480 }
481
482 encode128(firstNumber, os);
483
Jeff Thompson161a2e02013-10-16 16:04:08 -0700484 if (value.size() > 2) {
Jeff Thompsona92861a2013-10-16 14:06:23 -0700485 int i = 2;
Jeff Thompson161a2e02013-10-16 16:04:08 -0700486 for (; i < value.size(); i++)
487 encode128(value[i], os);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700488 }
489
490 string output = os.str();
491 DerNode::encodeHeader(output.size());
492
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700493 payload_.insert(payload_.end(), output.begin(), output.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700494}
495
496void
497DerOid::encode128(int value, ostringstream& os)
498{
499 int mask = (1 << 7) - 1;
500
Jeff Thompson161a2e02013-10-16 16:04:08 -0700501 if (128 > value) {
502 uint8_t singleByte = (uint8_t) mask & value;
503 os.write((char *)&singleByte, 1);
504 }
505 else {
Jeff Thompsona92861a2013-10-16 14:06:23 -0700506 uint8_t buf[(sizeof(value)*8 + 6)/7 + 1];
507 uint8_t *p = &(buf[sizeof(buf)-1]);
508 int n = 1;
509
510 p[0] = (uint8_t)(value & mask);
511 value >>= 7;
512
Jeff Thompson161a2e02013-10-16 16:04:08 -0700513 while (value != 0) {
514 (--p)[0] = (uint8_t)((value & mask) | (1 << 7));
515 n++;
516 value >>= 7;
517 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700518
519 os.write((char *)p, n);
520 }
521}
522
523int
524DerOid::decode128(int & offset)
525{
526 uint8_t flagMask = 0x80;
527 int result = 0;
Jeff Thompson161a2e02013-10-16 16:04:08 -0700528 while (payload_[offset] & flagMask) {
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700529 result = 128 * result + (uint8_t) payload_[offset] - 128;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700530 offset++;
531 }
532
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700533 result = result * 128 + payload_[offset];
Jeff Thompsona92861a2013-10-16 14:06:23 -0700534 offset++;
535
536 return result;
537}
538
539
540/*
541 * DerSequence
542 */
543DerSequence::DerSequence()
544 :DerComplex(DER_SEQUENCE)
545{}
546
Jeff Thompson2d47db72013-10-17 15:19:52 -0700547DerSequence::DerSequence(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700548 :DerComplex(start)
549{}
550
551DerSequence::~DerSequence()
552{}
553
554
555/*
556 * DerPrintableString
557 */
558DerPrintableString::DerPrintableString(const string& str)
559 :DerByteString(str, DER_PRINTABLE_STRING)
560{}
561
562DerPrintableString::DerPrintableString(const vector<uint8_t>& blob)
563 :DerByteString(blob, DER_PRINTABLE_STRING)
564{}
565
Jeff Thompson2d47db72013-10-17 15:19:52 -0700566DerPrintableString::DerPrintableString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700567 :DerByteString(start)
568{}
569
570DerPrintableString::~DerPrintableString()
571{}
572
573
574/*
575 * DerGtime
576 */
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700577DerGtime::DerGtime(const MillisecondsSince1970& time)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700578 :DerNode(DER_GENERALIZED_TIME)
579{
580 string pTimeStr = toIsoString(time);
581 int index = pTimeStr.find_first_of('T');
582 string derTime = pTimeStr.substr(0, index) + pTimeStr.substr(index+1, pTimeStr.size() - index -1) + "Z";
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700583 payload_.insert(payload_.end(), derTime.begin(), derTime.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700584
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700585 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700586}
587
Jeff Thompson2d47db72013-10-17 15:19:52 -0700588DerGtime::DerGtime(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700589 :DerNode(start)
590{}
591
592DerGtime::~DerGtime()
593{}
594
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700595string DerGtime::toIsoString(const MillisecondsSince1970& time)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700596{
Jeff Thompson5a6ce832013-10-18 11:54:35 -0700597 char isoString[25];
Jeff Thompsonea946202013-10-18 14:35:32 -0700598 ndn_Error error;
599 if ((error = ndn_toIsoString(time, isoString)))
600 throw runtime_error(ndn_getErrorString(error));
601
Jeff Thompson5a6ce832013-10-18 11:54:35 -0700602 return isoString;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700603}
604
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700605MillisecondsSince1970 DerGtime::fromIsoString(const string& isoString)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700606{
Jeff Thompsonea946202013-10-18 14:35:32 -0700607 MillisecondsSince1970 milliseconds;
608 ndn_Error error;
609 if ((error = ndn_fromIsoString(isoString.c_str(), &milliseconds)))
610 throw runtime_error(ndn_getErrorString(error));
611
612 return milliseconds;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700613}
614
615} // der
616
617}