blob: fc311610b8383e2325b39946729cfef8af4a9ce0 [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;
18using namespace ndn::ptr_lib;
19
20namespace ndn {
21
22namespace der {
23
24/*
25 * DerNode
26 */
27DerNode::DerNode()
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070028 :parent_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -070029{}
30
31DerNode::DerNode(DerType type)
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070032 :type_(type),
33 parent_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -070034{}
35
Jeff Thompson2d47db72013-10-17 15:19:52 -070036DerNode::DerNode(InputIterator& start)
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070037 :parent_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -070038{
39 decode(start);
40}
41
42DerNode::~DerNode()
43{}
44
45void
46DerNode::encodeHeader(int size)
47{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070048 header_.push_back((char)type_);
Jeff Thompsona92861a2013-10-16 14:06:23 -070049
Jeff Thompson161a2e02013-10-16 16:04:08 -070050 if (size >= 127) {
51 int val = size;
52 char buf[sizeof(val) + 1];
53 char *p = &(buf[sizeof(buf)-1]);
54 int n = 0;
55 int mask = (1 << 8) - 1;
Jeff Thompsona92861a2013-10-16 14:06:23 -070056
Jeff Thompson161a2e02013-10-16 16:04:08 -070057 while (val != 0) {
58 p[0] = (char)(val & mask);
59 p--;
Jeff Thompsona92861a2013-10-16 14:06:23 -070060 n++;
Jeff Thompson161a2e02013-10-16 16:04:08 -070061 val >>= 8;
62 }
Jeff Thompsona92861a2013-10-16 14:06:23 -070063
Jeff Thompson161a2e02013-10-16 16:04:08 -070064 p[0] = (char)((1<<7) | n);
65 n++;
66
67 header_.insert(header_.end(), p, p+n);
68 }
69 else if (size >= 0)
70 header_.push_back((char)size);
Jeff Thompsona92861a2013-10-16 14:06:23 -070071 else
72 throw NegativeLengthException("Negative length");
73}
74
75int
Jeff Thompson2d47db72013-10-17 15:19:52 -070076DerNode::decodeHeader(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -070077{
Jeff Thompson2d47db72013-10-17 15:19:52 -070078 uint8_t type = start.ReadU8();
Jeff Thompsona92861a2013-10-16 14:06:23 -070079 // char type = start.get();
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070080 header_.push_back(type);
81 type_ = static_cast<DerType>((int)type);
Jeff Thompsona92861a2013-10-16 14:06:23 -070082
Jeff Thompson2d47db72013-10-17 15:19:52 -070083 uint8_t sizeLen = start.ReadU8();
Jeff Thompsona92861a2013-10-16 14:06:23 -070084 // char sizeLen = start.get();
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070085 header_.push_back(sizeLen);
Jeff Thompsona92861a2013-10-16 14:06:23 -070086
87 bool longFormat = sizeLen & (1 << 7);
88
Jeff Thompson161a2e02013-10-16 16:04:08 -070089 if (!longFormat) {
90 // _LOG_DEBUG("Short Format");
91 // _LOG_DEBUG("sizeLen: " << (int)sizeLen);
92 return (int)sizeLen;
93 }
94 else {
95 // _LOG_DEBUG("Long Format");
96 uint8_t byte;
97 // char byte;
98 int lenCount = sizeLen & ((1<<7) - 1);
99 // _LOG_DEBUG("sizeLen: " << (int)sizeLen);
100 // _LOG_DEBUG("mask: " << (int)((1<<7) - 1));
101 // _LOG_DEBUG("lenCount: " << (int)lenCount);
102 int size = 0;
103 do {
Jeff Thompson2d47db72013-10-17 15:19:52 -0700104 byte = start.ReadU8();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700105 header_.push_back(byte);
106 size = size * 256 + (int)byte;
107 // _LOG_DEBUG("byte: " << (int)byte);
108 // _LOG_DEBUG("size: " << size);
109 lenCount--;
110 } while (lenCount > 0);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700111
Jeff Thompson161a2e02013-10-16 16:04:08 -0700112 return size;
113 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700114}
115
116void
Jeff Thompson2d47db72013-10-17 15:19:52 -0700117DerNode::encode(OutputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700118{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700119 start.write((const char*)&header_[0], header_.size());
120 start.write((const char*)&payload_[0], payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700121}
122
123void
Jeff Thompson2d47db72013-10-17 15:19:52 -0700124DerNode::decode(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700125{
126 int payloadSize = decodeHeader(start);
127 // _LOG_DEBUG("payloadSize: " << payloadSize);
Jeff Thompson161a2e02013-10-16 16:04:08 -0700128 if (payloadSize > 0 ) {
129 char buf[payloadSize];
130 start.read(buf, payloadSize);
131 payload_.insert(payload_.end(), buf, buf + payloadSize);
132 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700133}
134
135shared_ptr<DerNode>
Jeff Thompson2d47db72013-10-17 15:19:52 -0700136DerNode::parse(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700137{
Jeff Thompson2d47db72013-10-17 15:19:52 -0700138 int type = ((uint8_t)start.PeekU8());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700139
140 // _LOG_DEBUG("Type: " << hex << setw(2) << setfill('0') << type);
141 switch(type) {
142 case DER_BOOLEAN:
143 return shared_ptr<DerBool>(new DerBool(start));
144 case DER_INTEGER:
145 return shared_ptr<DerInteger>(new DerInteger(start));
146 case DER_BIT_STRING:
147 return shared_ptr<DerBitString>(new DerBitString(start));
148 case DER_OCTET_STRING:
149 return shared_ptr<DerOctetString>(new DerOctetString(start));
150 case DER_NULL:
151 return shared_ptr<DerNull>(new DerNull(start));
152 case DER_OBJECT_IDENTIFIER:
153 return shared_ptr<DerOid>(new DerOid(start));
154 case DER_SEQUENCE:
155 return shared_ptr<DerSequence>(new DerSequence(start));
156 case DER_PRINTABLE_STRING:
157 return shared_ptr<DerPrintableString>(new DerPrintableString(start));
158 case DER_GENERALIZED_TIME:
159 return shared_ptr<DerGtime>(new DerGtime(start));
160 default:
Jeff Thompson5a6ce832013-10-18 11:54:35 -0700161 throw DerDecodingException("Unimplemented DER type");
Jeff Thompson161a2e02013-10-16 16:04:08 -0700162 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700163}
164
165
166/*
167 * DerComplex
168 */
169DerComplex::DerComplex()
170 :DerNode(),
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700171 childChanged_(false),
172 size_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700173{}
174
175DerComplex::DerComplex(DerType type)
176 :DerNode(type),
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700177 childChanged_(false),
178 size_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700179{}
180
Jeff Thompson2d47db72013-10-17 15:19:52 -0700181DerComplex::DerComplex(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700182 :DerNode(),
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700183 childChanged_(false),
184 size_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700185{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700186 size_ = DerNode::decodeHeader(start);
187 // _LOG_DEBUG("Size: " << size_);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700188
189 int accSize = 0;
190
Jeff Thompson161a2e02013-10-16 16:04:08 -0700191 while (accSize < size_) {
192 // _LOG_DEBUG("accSize: " << accSize);
193 shared_ptr<DerNode> nodePtr = DerNode::parse(start);
194 accSize += nodePtr->getSize();
195 addChild(nodePtr, false);
196 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700197}
198
199DerComplex::~DerComplex()
200{}
201
202int
203DerComplex::getSize()
204{
Jeff Thompson161a2e02013-10-16 16:04:08 -0700205 if (childChanged_) {
206 updateSize();
207 childChanged_ = false;
208 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700209
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700210 header_.clear();
211 DerNode::encodeHeader(size_);
212 return size_ + header_.size();
Jeff Thompsona92861a2013-10-16 14:06:23 -0700213}
214
Jeff Thompson415da1e2013-10-17 16:52:59 -0700215Blob
Jeff Thompsona92861a2013-10-16 14:06:23 -0700216DerComplex::getRaw()
217{
218 shared_ptr<vector<uint8_t> > blob(new vector<uint8_t>());
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700219 blob->insert(blob->end(), header_.begin(), header_.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700220
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700221 DerNodePtrList::iterator it = nodeList_.begin();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700222 for (; it != nodeList_.end(); it++) {
Jeff Thompson415da1e2013-10-17 16:52:59 -0700223 Blob childBlob = (*it)->getRaw();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700224 blob->insert(blob->end(), childBlob->begin(), childBlob->end());
225 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700226 return blob;
227}
228
229void
230DerComplex::updateSize()
231{
232 int newSize = 0;
233
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700234 DerNodePtrList::iterator it = nodeList_.begin();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700235 for (; it != nodeList_.end(); it++) {
236 newSize += (*it)->getSize();
237 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700238
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700239 size_ = newSize;
240 childChanged_ = false;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700241}
242
243void
244DerComplex::addChild(shared_ptr<DerNode> nodePtr, bool notifyParent)
245{
246 nodePtr->setParent(this);
247
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700248 nodeList_.push_back(nodePtr);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700249
Jeff Thompson161a2e02013-10-16 16:04:08 -0700250 if (!notifyParent)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700251 return;
252
Jeff Thompson161a2e02013-10-16 16:04:08 -0700253 if (childChanged_)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700254 return;
255 else
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700256 childChanged_ = true;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700257
Jeff Thompson161a2e02013-10-16 16:04:08 -0700258 if (0 != parent_)
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700259 parent_->setChildChanged();
Jeff Thompsona92861a2013-10-16 14:06:23 -0700260}
261
262void
263DerComplex::setChildChanged()
264{
Jeff Thompson161a2e02013-10-16 16:04:08 -0700265 if (0 != parent_ && !childChanged_) {
266 parent_->setChildChanged();
267 childChanged_ = true;
268 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700269 else
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700270 childChanged_ = true;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700271}
272
273void
Jeff Thompson2d47db72013-10-17 15:19:52 -0700274DerComplex::encode(OutputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700275{
276 updateSize();
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700277 header_.clear();
Jeff Thompsona92861a2013-10-16 14:06:23 -0700278
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700279 DerNode::encodeHeader(size_);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700280
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700281 start.write((const char*)&header_[0], header_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700282
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700283 DerNodePtrList::iterator it = nodeList_.begin();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700284 for (; it != nodeList_.end(); it++)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700285 (*it)->encode(start);
286}
287
288
289/*
290 * DerByteString
291 */
292DerByteString::DerByteString(const string& str, DerType type)
293 :DerNode(type)
294{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700295 payload_.insert(payload_.end(), str.begin(), str.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700296
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700297 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700298}
299
Jeff Thompson4affbf52013-10-18 14:36:46 -0700300DerByteString::DerByteString(const vector<uint8_t>& blob, DerType type)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700301 :DerNode(type)
302{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700303 payload_.insert(payload_.end(), blob.begin(), blob.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700304
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700305 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700306}
307
Jeff Thompson2d47db72013-10-17 15:19:52 -0700308DerByteString::DerByteString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700309 :DerNode(start)
310{}
311
312DerByteString::~DerByteString()
313{}
314
315
316/*
317 * DerBool
318 */
319DerBool::DerBool(bool value)
320 :DerNode(DER_BOOLEAN)
321
322{
323 char payload = (value ? 0xFF : 0x00);
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700324 payload_.push_back(payload);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700325
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700326 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700327}
328
Jeff Thompson2d47db72013-10-17 15:19:52 -0700329DerBool::DerBool(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700330 :DerNode(start)
331{}
332
333DerBool::~DerBool()
334{}
335
336
337/*
338 * DerInteger
339 */
340DerInteger::DerInteger(const vector<uint8_t>& blob)
341 :DerNode(DER_INTEGER)
342{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700343 payload_.insert(payload_.end(), blob.begin(), blob.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700344
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700345 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700346}
347
Jeff Thompson2d47db72013-10-17 15:19:52 -0700348DerInteger::DerInteger(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700349 :DerNode(start)
350{}
351
352DerInteger::~DerInteger()
353{}
354
355
356/*
357 * DerBitString
358 */
359DerBitString::DerBitString(const vector<uint8_t>& blob, uint8_t paddingLen)
360 :DerNode(DER_BIT_STRING)
361{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700362 payload_.push_back((char)paddingLen);
363 payload_.insert(payload_.end(), blob.begin(), blob.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700364
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700365 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700366}
367
Jeff Thompson2d47db72013-10-17 15:19:52 -0700368DerBitString::DerBitString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700369 :DerNode(start)
370{}
371
372DerBitString::~DerBitString()
373{}
374
375
376/*
377 * DerOctetString
378 */
379DerOctetString::DerOctetString(const string& str)
380 :DerByteString(str, DER_OCTET_STRING)
381{}
382
383DerOctetString::DerOctetString(const vector<uint8_t>& blob)
384 :DerByteString(blob, DER_OCTET_STRING)
385{}
386
Jeff Thompson2d47db72013-10-17 15:19:52 -0700387DerOctetString::DerOctetString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700388 :DerByteString(start)
389{}
390
391DerOctetString::~DerOctetString()
392{}
393
394
395/*
396 * DerNull
397 */
398DerNull::DerNull()
399 :DerNode(DER_NULL)
400{
401 DerNode::encodeHeader(0);
402}
403
Jeff Thompson2d47db72013-10-17 15:19:52 -0700404DerNull::DerNull(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700405 :DerNode(start)
406{}
407
408DerNull::~DerNull()
409{}
410
411
412/*
413 * DerOid
414 */
415DerOid::DerOid(const OID& oid)
416 :DerNode(DER_OBJECT_IDENTIFIER)
417{
418 prepareEncoding(oid.getIntegerList());
419}
420
421
422DerOid::DerOid(const string& oidStr)
423 :DerNode(DER_OBJECT_IDENTIFIER)
424{
425 vector<int> value;
426
427 string str = oidStr + ".";
428
429 size_t pos = 0;
430 size_t ppos = 0;
431
Jeff Thompson161a2e02013-10-16 16:04:08 -0700432 while (string::npos != pos) {
Jeff Thompsona92861a2013-10-16 14:06:23 -0700433 ppos = pos;
434
435 pos = str.find_first_of('.', pos);
Jeff Thompson161a2e02013-10-16 16:04:08 -0700436 if (string::npos == pos)
437 break;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700438
439 value.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
440
441 pos++;
442 }
443
444 prepareEncoding(value);
445}
446
447DerOid::DerOid(const vector<int>& value)
448 :DerNode(DER_OBJECT_IDENTIFIER)
449{
450 prepareEncoding(value);
451}
452
Jeff Thompson2d47db72013-10-17 15:19:52 -0700453DerOid::DerOid(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700454 :DerNode(start)
455{}
456
457DerOid::~DerOid()
458{}
459
460void
461DerOid::prepareEncoding(const vector<int>& value)
462{
463 ostringstream os;
464
465 int firstNumber = 0;
466
Jeff Thompson161a2e02013-10-16 16:04:08 -0700467 if (value.size() >= 1) {
468 if (0 <= value[0] && 2 >= value[0])
469 firstNumber = value[0] * 40;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700470 else
Jeff Thompson161a2e02013-10-16 16:04:08 -0700471 throw DerEncodingException("first integer of oid is out of range");
Jeff Thompsona92861a2013-10-16 14:06:23 -0700472 }
473 else
474 throw DerEncodingException("no integer in oid");
475
Jeff Thompson161a2e02013-10-16 16:04:08 -0700476 if (value.size() >= 2) {
477 if (0 <= value[1] && 39 >= value[1])
478 firstNumber += value[1];
Jeff Thompsona92861a2013-10-16 14:06:23 -0700479 else
Jeff Thompson161a2e02013-10-16 16:04:08 -0700480 throw DerEncodingException("second integer of oid is out of range");
Jeff Thompsona92861a2013-10-16 14:06:23 -0700481 }
482
483 encode128(firstNumber, os);
484
Jeff Thompson161a2e02013-10-16 16:04:08 -0700485 if (value.size() > 2) {
Jeff Thompsona92861a2013-10-16 14:06:23 -0700486 int i = 2;
Jeff Thompson161a2e02013-10-16 16:04:08 -0700487 for (; i < value.size(); i++)
488 encode128(value[i], os);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700489 }
490
491 string output = os.str();
492 DerNode::encodeHeader(output.size());
493
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700494 payload_.insert(payload_.end(), output.begin(), output.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700495}
496
497void
498DerOid::encode128(int value, ostringstream& os)
499{
500 int mask = (1 << 7) - 1;
501
Jeff Thompson161a2e02013-10-16 16:04:08 -0700502 if (128 > value) {
503 uint8_t singleByte = (uint8_t) mask & value;
504 os.write((char *)&singleByte, 1);
505 }
506 else {
Jeff Thompsona92861a2013-10-16 14:06:23 -0700507 uint8_t buf[(sizeof(value)*8 + 6)/7 + 1];
508 uint8_t *p = &(buf[sizeof(buf)-1]);
509 int n = 1;
510
511 p[0] = (uint8_t)(value & mask);
512 value >>= 7;
513
Jeff Thompson161a2e02013-10-16 16:04:08 -0700514 while (value != 0) {
515 (--p)[0] = (uint8_t)((value & mask) | (1 << 7));
516 n++;
517 value >>= 7;
518 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700519
520 os.write((char *)p, n);
521 }
522}
523
524int
525DerOid::decode128(int & offset)
526{
527 uint8_t flagMask = 0x80;
528 int result = 0;
Jeff Thompson161a2e02013-10-16 16:04:08 -0700529 while (payload_[offset] & flagMask) {
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700530 result = 128 * result + (uint8_t) payload_[offset] - 128;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700531 offset++;
532 }
533
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700534 result = result * 128 + payload_[offset];
Jeff Thompsona92861a2013-10-16 14:06:23 -0700535 offset++;
536
537 return result;
538}
539
540
541/*
542 * DerSequence
543 */
544DerSequence::DerSequence()
545 :DerComplex(DER_SEQUENCE)
546{}
547
Jeff Thompson2d47db72013-10-17 15:19:52 -0700548DerSequence::DerSequence(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700549 :DerComplex(start)
550{}
551
552DerSequence::~DerSequence()
553{}
554
555
556/*
557 * DerPrintableString
558 */
559DerPrintableString::DerPrintableString(const string& str)
560 :DerByteString(str, DER_PRINTABLE_STRING)
561{}
562
563DerPrintableString::DerPrintableString(const vector<uint8_t>& blob)
564 :DerByteString(blob, DER_PRINTABLE_STRING)
565{}
566
Jeff Thompson2d47db72013-10-17 15:19:52 -0700567DerPrintableString::DerPrintableString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700568 :DerByteString(start)
569{}
570
571DerPrintableString::~DerPrintableString()
572{}
573
574
575/*
576 * DerGtime
577 */
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700578DerGtime::DerGtime(const MillisecondsSince1970& time)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700579 :DerNode(DER_GENERALIZED_TIME)
580{
581 string pTimeStr = toIsoString(time);
582 int index = pTimeStr.find_first_of('T');
583 string derTime = pTimeStr.substr(0, index) + pTimeStr.substr(index+1, pTimeStr.size() - index -1) + "Z";
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700584 payload_.insert(payload_.end(), derTime.begin(), derTime.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700585
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700586 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700587}
588
Jeff Thompson2d47db72013-10-17 15:19:52 -0700589DerGtime::DerGtime(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700590 :DerNode(start)
591{}
592
593DerGtime::~DerGtime()
594{}
595
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700596string DerGtime::toIsoString(const MillisecondsSince1970& time)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700597{
Jeff Thompson5a6ce832013-10-18 11:54:35 -0700598 char isoString[25];
Jeff Thompsonea946202013-10-18 14:35:32 -0700599 ndn_Error error;
600 if ((error = ndn_toIsoString(time, isoString)))
601 throw runtime_error(ndn_getErrorString(error));
602
Jeff Thompson5a6ce832013-10-18 11:54:35 -0700603 return isoString;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700604}
605
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700606MillisecondsSince1970 DerGtime::fromIsoString(const string& isoString)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700607{
Jeff Thompsonea946202013-10-18 14:35:32 -0700608 MillisecondsSince1970 milliseconds;
609 ndn_Error error;
610 if ((error = ndn_fromIsoString(isoString.c_str(), &milliseconds)))
611 throw runtime_error(ndn_getErrorString(error));
612
613 return milliseconds;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700614}
615
616} // der
617
618}