blob: 125b9a42679313de688831554081575675a1076f [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
9#if 1 // TODO: Remove this when we don't throw "not implemented".
10#include <stdexcept>
11#endif
12#include "der-exception.hpp"
13#include "../../util/logging.hpp"
Jeff Thompson5a6ce832013-10-18 11:54:35 -070014#include "../../c/util/time.h"
Jeff Thompsona92861a2013-10-16 14:06:23 -070015#include "der.hpp"
16
17INIT_LOGGER("ndn.der.DER");
18
19using namespace std;
20using namespace ndn::ptr_lib;
21
22namespace ndn {
23
24namespace der {
25
26/*
27 * DerNode
28 */
29DerNode::DerNode()
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070030 :parent_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -070031{}
32
33DerNode::DerNode(DerType type)
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070034 :type_(type),
35 parent_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -070036{}
37
Jeff Thompson2d47db72013-10-17 15:19:52 -070038DerNode::DerNode(InputIterator& start)
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070039 :parent_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -070040{
41 decode(start);
42}
43
44DerNode::~DerNode()
45{}
46
47void
48DerNode::encodeHeader(int size)
49{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070050 header_.push_back((char)type_);
Jeff Thompsona92861a2013-10-16 14:06:23 -070051
Jeff Thompson161a2e02013-10-16 16:04:08 -070052 if (size >= 127) {
53 int val = size;
54 char buf[sizeof(val) + 1];
55 char *p = &(buf[sizeof(buf)-1]);
56 int n = 0;
57 int mask = (1 << 8) - 1;
Jeff Thompsona92861a2013-10-16 14:06:23 -070058
Jeff Thompson161a2e02013-10-16 16:04:08 -070059 while (val != 0) {
60 p[0] = (char)(val & mask);
61 p--;
Jeff Thompsona92861a2013-10-16 14:06:23 -070062 n++;
Jeff Thompson161a2e02013-10-16 16:04:08 -070063 val >>= 8;
64 }
Jeff Thompsona92861a2013-10-16 14:06:23 -070065
Jeff Thompson161a2e02013-10-16 16:04:08 -070066 p[0] = (char)((1<<7) | n);
67 n++;
68
69 header_.insert(header_.end(), p, p+n);
70 }
71 else if (size >= 0)
72 header_.push_back((char)size);
Jeff Thompsona92861a2013-10-16 14:06:23 -070073 else
74 throw NegativeLengthException("Negative length");
75}
76
77int
Jeff Thompson2d47db72013-10-17 15:19:52 -070078DerNode::decodeHeader(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -070079{
Jeff Thompson2d47db72013-10-17 15:19:52 -070080 uint8_t type = start.ReadU8();
Jeff Thompsona92861a2013-10-16 14:06:23 -070081 // char type = start.get();
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070082 header_.push_back(type);
83 type_ = static_cast<DerType>((int)type);
Jeff Thompsona92861a2013-10-16 14:06:23 -070084
Jeff Thompson2d47db72013-10-17 15:19:52 -070085 uint8_t sizeLen = start.ReadU8();
Jeff Thompsona92861a2013-10-16 14:06:23 -070086 // char sizeLen = start.get();
Jeff Thompson7ff36fe2013-10-16 15:30:13 -070087 header_.push_back(sizeLen);
Jeff Thompsona92861a2013-10-16 14:06:23 -070088
89 bool longFormat = sizeLen & (1 << 7);
90
Jeff Thompson161a2e02013-10-16 16:04:08 -070091 if (!longFormat) {
92 // _LOG_DEBUG("Short Format");
93 // _LOG_DEBUG("sizeLen: " << (int)sizeLen);
94 return (int)sizeLen;
95 }
96 else {
97 // _LOG_DEBUG("Long Format");
98 uint8_t byte;
99 // char byte;
100 int lenCount = sizeLen & ((1<<7) - 1);
101 // _LOG_DEBUG("sizeLen: " << (int)sizeLen);
102 // _LOG_DEBUG("mask: " << (int)((1<<7) - 1));
103 // _LOG_DEBUG("lenCount: " << (int)lenCount);
104 int size = 0;
105 do {
Jeff Thompson2d47db72013-10-17 15:19:52 -0700106 byte = start.ReadU8();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700107 header_.push_back(byte);
108 size = size * 256 + (int)byte;
109 // _LOG_DEBUG("byte: " << (int)byte);
110 // _LOG_DEBUG("size: " << size);
111 lenCount--;
112 } while (lenCount > 0);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700113
Jeff Thompson161a2e02013-10-16 16:04:08 -0700114 return size;
115 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700116}
117
118void
Jeff Thompson2d47db72013-10-17 15:19:52 -0700119DerNode::encode(OutputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700120{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700121 start.write((const char*)&header_[0], header_.size());
122 start.write((const char*)&payload_[0], payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700123}
124
125void
Jeff Thompson2d47db72013-10-17 15:19:52 -0700126DerNode::decode(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700127{
128 int payloadSize = decodeHeader(start);
129 // _LOG_DEBUG("payloadSize: " << payloadSize);
Jeff Thompson161a2e02013-10-16 16:04:08 -0700130 if (payloadSize > 0 ) {
131 char buf[payloadSize];
132 start.read(buf, payloadSize);
133 payload_.insert(payload_.end(), buf, buf + payloadSize);
134 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700135}
136
137shared_ptr<DerNode>
Jeff Thompson2d47db72013-10-17 15:19:52 -0700138DerNode::parse(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700139{
Jeff Thompson2d47db72013-10-17 15:19:52 -0700140 int type = ((uint8_t)start.PeekU8());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700141
142 // _LOG_DEBUG("Type: " << hex << setw(2) << setfill('0') << type);
143 switch(type) {
144 case DER_BOOLEAN:
145 return shared_ptr<DerBool>(new DerBool(start));
146 case DER_INTEGER:
147 return shared_ptr<DerInteger>(new DerInteger(start));
148 case DER_BIT_STRING:
149 return shared_ptr<DerBitString>(new DerBitString(start));
150 case DER_OCTET_STRING:
151 return shared_ptr<DerOctetString>(new DerOctetString(start));
152 case DER_NULL:
153 return shared_ptr<DerNull>(new DerNull(start));
154 case DER_OBJECT_IDENTIFIER:
155 return shared_ptr<DerOid>(new DerOid(start));
156 case DER_SEQUENCE:
157 return shared_ptr<DerSequence>(new DerSequence(start));
158 case DER_PRINTABLE_STRING:
159 return shared_ptr<DerPrintableString>(new DerPrintableString(start));
160 case DER_GENERALIZED_TIME:
161 return shared_ptr<DerGtime>(new DerGtime(start));
162 default:
Jeff Thompson5a6ce832013-10-18 11:54:35 -0700163 throw DerDecodingException("Unimplemented DER type");
Jeff Thompson161a2e02013-10-16 16:04:08 -0700164 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700165}
166
167
168/*
169 * DerComplex
170 */
171DerComplex::DerComplex()
172 :DerNode(),
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700173 childChanged_(false),
174 size_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700175{}
176
177DerComplex::DerComplex(DerType type)
178 :DerNode(type),
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700179 childChanged_(false),
180 size_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700181{}
182
Jeff Thompson2d47db72013-10-17 15:19:52 -0700183DerComplex::DerComplex(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700184 :DerNode(),
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700185 childChanged_(false),
186 size_(0)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700187{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700188 size_ = DerNode::decodeHeader(start);
189 // _LOG_DEBUG("Size: " << size_);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700190
191 int accSize = 0;
192
Jeff Thompson161a2e02013-10-16 16:04:08 -0700193 while (accSize < size_) {
194 // _LOG_DEBUG("accSize: " << accSize);
195 shared_ptr<DerNode> nodePtr = DerNode::parse(start);
196 accSize += nodePtr->getSize();
197 addChild(nodePtr, false);
198 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700199}
200
201DerComplex::~DerComplex()
202{}
203
204int
205DerComplex::getSize()
206{
Jeff Thompson161a2e02013-10-16 16:04:08 -0700207 if (childChanged_) {
208 updateSize();
209 childChanged_ = false;
210 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700211
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700212 header_.clear();
213 DerNode::encodeHeader(size_);
214 return size_ + header_.size();
Jeff Thompsona92861a2013-10-16 14:06:23 -0700215}
216
Jeff Thompson415da1e2013-10-17 16:52:59 -0700217Blob
Jeff Thompsona92861a2013-10-16 14:06:23 -0700218DerComplex::getRaw()
219{
220 shared_ptr<vector<uint8_t> > blob(new vector<uint8_t>());
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700221 blob->insert(blob->end(), header_.begin(), header_.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700222
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700223 DerNodePtrList::iterator it = nodeList_.begin();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700224 for (; it != nodeList_.end(); it++) {
Jeff Thompson415da1e2013-10-17 16:52:59 -0700225 Blob childBlob = (*it)->getRaw();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700226 blob->insert(blob->end(), childBlob->begin(), childBlob->end());
227 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700228 return blob;
229}
230
231void
232DerComplex::updateSize()
233{
234 int newSize = 0;
235
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700236 DerNodePtrList::iterator it = nodeList_.begin();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700237 for (; it != nodeList_.end(); it++) {
238 newSize += (*it)->getSize();
239 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700240
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700241 size_ = newSize;
242 childChanged_ = false;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700243}
244
245void
246DerComplex::addChild(shared_ptr<DerNode> nodePtr, bool notifyParent)
247{
248 nodePtr->setParent(this);
249
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700250 nodeList_.push_back(nodePtr);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700251
Jeff Thompson161a2e02013-10-16 16:04:08 -0700252 if (!notifyParent)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700253 return;
254
Jeff Thompson161a2e02013-10-16 16:04:08 -0700255 if (childChanged_)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700256 return;
257 else
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700258 childChanged_ = true;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700259
Jeff Thompson161a2e02013-10-16 16:04:08 -0700260 if (0 != parent_)
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700261 parent_->setChildChanged();
Jeff Thompsona92861a2013-10-16 14:06:23 -0700262}
263
264void
265DerComplex::setChildChanged()
266{
Jeff Thompson161a2e02013-10-16 16:04:08 -0700267 if (0 != parent_ && !childChanged_) {
268 parent_->setChildChanged();
269 childChanged_ = true;
270 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700271 else
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700272 childChanged_ = true;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700273}
274
275void
Jeff Thompson2d47db72013-10-17 15:19:52 -0700276DerComplex::encode(OutputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700277{
278 updateSize();
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700279 header_.clear();
Jeff Thompsona92861a2013-10-16 14:06:23 -0700280
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700281 DerNode::encodeHeader(size_);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700282
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700283 start.write((const char*)&header_[0], header_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700284
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700285 DerNodePtrList::iterator it = nodeList_.begin();
Jeff Thompson161a2e02013-10-16 16:04:08 -0700286 for (; it != nodeList_.end(); it++)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700287 (*it)->encode(start);
288}
289
290
291/*
292 * DerByteString
293 */
294DerByteString::DerByteString(const string& str, DerType type)
295 :DerNode(type)
296{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700297 payload_.insert(payload_.end(), str.begin(), str.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700298
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700299 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700300}
301
302DerByteString::DerByteString(const std::vector<uint8_t>& blob, DerType type)
303 :DerNode(type)
304{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700305 payload_.insert(payload_.end(), blob.begin(), blob.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700306
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700307 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700308}
309
Jeff Thompson2d47db72013-10-17 15:19:52 -0700310DerByteString::DerByteString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700311 :DerNode(start)
312{}
313
314DerByteString::~DerByteString()
315{}
316
317
318/*
319 * DerBool
320 */
321DerBool::DerBool(bool value)
322 :DerNode(DER_BOOLEAN)
323
324{
325 char payload = (value ? 0xFF : 0x00);
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700326 payload_.push_back(payload);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700327
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700328 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700329}
330
Jeff Thompson2d47db72013-10-17 15:19:52 -0700331DerBool::DerBool(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700332 :DerNode(start)
333{}
334
335DerBool::~DerBool()
336{}
337
338
339/*
340 * DerInteger
341 */
342DerInteger::DerInteger(const vector<uint8_t>& blob)
343 :DerNode(DER_INTEGER)
344{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700345 payload_.insert(payload_.end(), blob.begin(), blob.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700346
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700347 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700348}
349
Jeff Thompson2d47db72013-10-17 15:19:52 -0700350DerInteger::DerInteger(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700351 :DerNode(start)
352{}
353
354DerInteger::~DerInteger()
355{}
356
357
358/*
359 * DerBitString
360 */
361DerBitString::DerBitString(const vector<uint8_t>& blob, uint8_t paddingLen)
362 :DerNode(DER_BIT_STRING)
363{
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700364 payload_.push_back((char)paddingLen);
365 payload_.insert(payload_.end(), blob.begin(), blob.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700366
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700367 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700368}
369
Jeff Thompson2d47db72013-10-17 15:19:52 -0700370DerBitString::DerBitString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700371 :DerNode(start)
372{}
373
374DerBitString::~DerBitString()
375{}
376
377
378/*
379 * DerOctetString
380 */
381DerOctetString::DerOctetString(const string& str)
382 :DerByteString(str, DER_OCTET_STRING)
383{}
384
385DerOctetString::DerOctetString(const vector<uint8_t>& blob)
386 :DerByteString(blob, DER_OCTET_STRING)
387{}
388
Jeff Thompson2d47db72013-10-17 15:19:52 -0700389DerOctetString::DerOctetString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700390 :DerByteString(start)
391{}
392
393DerOctetString::~DerOctetString()
394{}
395
396
397/*
398 * DerNull
399 */
400DerNull::DerNull()
401 :DerNode(DER_NULL)
402{
403 DerNode::encodeHeader(0);
404}
405
Jeff Thompson2d47db72013-10-17 15:19:52 -0700406DerNull::DerNull(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700407 :DerNode(start)
408{}
409
410DerNull::~DerNull()
411{}
412
413
414/*
415 * DerOid
416 */
417DerOid::DerOid(const OID& oid)
418 :DerNode(DER_OBJECT_IDENTIFIER)
419{
420 prepareEncoding(oid.getIntegerList());
421}
422
423
424DerOid::DerOid(const string& oidStr)
425 :DerNode(DER_OBJECT_IDENTIFIER)
426{
427 vector<int> value;
428
429 string str = oidStr + ".";
430
431 size_t pos = 0;
432 size_t ppos = 0;
433
Jeff Thompson161a2e02013-10-16 16:04:08 -0700434 while (string::npos != pos) {
Jeff Thompsona92861a2013-10-16 14:06:23 -0700435 ppos = pos;
436
437 pos = str.find_first_of('.', pos);
Jeff Thompson161a2e02013-10-16 16:04:08 -0700438 if (string::npos == pos)
439 break;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700440
441 value.push_back(atoi(str.substr(ppos, pos - ppos).c_str()));
442
443 pos++;
444 }
445
446 prepareEncoding(value);
447}
448
449DerOid::DerOid(const vector<int>& value)
450 :DerNode(DER_OBJECT_IDENTIFIER)
451{
452 prepareEncoding(value);
453}
454
Jeff Thompson2d47db72013-10-17 15:19:52 -0700455DerOid::DerOid(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700456 :DerNode(start)
457{}
458
459DerOid::~DerOid()
460{}
461
462void
463DerOid::prepareEncoding(const vector<int>& value)
464{
465 ostringstream os;
466
467 int firstNumber = 0;
468
Jeff Thompson161a2e02013-10-16 16:04:08 -0700469 if (value.size() >= 1) {
470 if (0 <= value[0] && 2 >= value[0])
471 firstNumber = value[0] * 40;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700472 else
Jeff Thompson161a2e02013-10-16 16:04:08 -0700473 throw DerEncodingException("first integer of oid is out of range");
Jeff Thompsona92861a2013-10-16 14:06:23 -0700474 }
475 else
476 throw DerEncodingException("no integer in oid");
477
Jeff Thompson161a2e02013-10-16 16:04:08 -0700478 if (value.size() >= 2) {
479 if (0 <= value[1] && 39 >= value[1])
480 firstNumber += value[1];
Jeff Thompsona92861a2013-10-16 14:06:23 -0700481 else
Jeff Thompson161a2e02013-10-16 16:04:08 -0700482 throw DerEncodingException("second integer of oid is out of range");
Jeff Thompsona92861a2013-10-16 14:06:23 -0700483 }
484
485 encode128(firstNumber, os);
486
Jeff Thompson161a2e02013-10-16 16:04:08 -0700487 if (value.size() > 2) {
Jeff Thompsona92861a2013-10-16 14:06:23 -0700488 int i = 2;
Jeff Thompson161a2e02013-10-16 16:04:08 -0700489 for (; i < value.size(); i++)
490 encode128(value[i], os);
Jeff Thompsona92861a2013-10-16 14:06:23 -0700491 }
492
493 string output = os.str();
494 DerNode::encodeHeader(output.size());
495
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700496 payload_.insert(payload_.end(), output.begin(), output.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700497}
498
499void
500DerOid::encode128(int value, ostringstream& os)
501{
502 int mask = (1 << 7) - 1;
503
Jeff Thompson161a2e02013-10-16 16:04:08 -0700504 if (128 > value) {
505 uint8_t singleByte = (uint8_t) mask & value;
506 os.write((char *)&singleByte, 1);
507 }
508 else {
Jeff Thompsona92861a2013-10-16 14:06:23 -0700509 uint8_t buf[(sizeof(value)*8 + 6)/7 + 1];
510 uint8_t *p = &(buf[sizeof(buf)-1]);
511 int n = 1;
512
513 p[0] = (uint8_t)(value & mask);
514 value >>= 7;
515
Jeff Thompson161a2e02013-10-16 16:04:08 -0700516 while (value != 0) {
517 (--p)[0] = (uint8_t)((value & mask) | (1 << 7));
518 n++;
519 value >>= 7;
520 }
Jeff Thompsona92861a2013-10-16 14:06:23 -0700521
522 os.write((char *)p, n);
523 }
524}
525
526int
527DerOid::decode128(int & offset)
528{
529 uint8_t flagMask = 0x80;
530 int result = 0;
Jeff Thompson161a2e02013-10-16 16:04:08 -0700531 while (payload_[offset] & flagMask) {
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700532 result = 128 * result + (uint8_t) payload_[offset] - 128;
Jeff Thompsona92861a2013-10-16 14:06:23 -0700533 offset++;
534 }
535
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700536 result = result * 128 + payload_[offset];
Jeff Thompsona92861a2013-10-16 14:06:23 -0700537 offset++;
538
539 return result;
540}
541
542
543/*
544 * DerSequence
545 */
546DerSequence::DerSequence()
547 :DerComplex(DER_SEQUENCE)
548{}
549
Jeff Thompson2d47db72013-10-17 15:19:52 -0700550DerSequence::DerSequence(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700551 :DerComplex(start)
552{}
553
554DerSequence::~DerSequence()
555{}
556
557
558/*
559 * DerPrintableString
560 */
561DerPrintableString::DerPrintableString(const string& str)
562 :DerByteString(str, DER_PRINTABLE_STRING)
563{}
564
565DerPrintableString::DerPrintableString(const vector<uint8_t>& blob)
566 :DerByteString(blob, DER_PRINTABLE_STRING)
567{}
568
Jeff Thompson2d47db72013-10-17 15:19:52 -0700569DerPrintableString::DerPrintableString(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700570 :DerByteString(start)
571{}
572
573DerPrintableString::~DerPrintableString()
574{}
575
576
577/*
578 * DerGtime
579 */
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700580DerGtime::DerGtime(const MillisecondsSince1970& time)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700581 :DerNode(DER_GENERALIZED_TIME)
582{
583 string pTimeStr = toIsoString(time);
584 int index = pTimeStr.find_first_of('T');
585 string derTime = pTimeStr.substr(0, index) + pTimeStr.substr(index+1, pTimeStr.size() - index -1) + "Z";
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700586 payload_.insert(payload_.end(), derTime.begin(), derTime.end());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700587
Jeff Thompson7ff36fe2013-10-16 15:30:13 -0700588 DerNode::encodeHeader(payload_.size());
Jeff Thompsona92861a2013-10-16 14:06:23 -0700589}
590
Jeff Thompson2d47db72013-10-17 15:19:52 -0700591DerGtime::DerGtime(InputIterator& start)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700592 :DerNode(start)
593{}
594
595DerGtime::~DerGtime()
596{}
597
Jeff Thompson9a8e82f2013-10-17 14:13:43 -0700598string DerGtime::toIsoString(const MillisecondsSince1970& time)
Jeff Thompsona92861a2013-10-16 14:06:23 -0700599{
Jeff Thompson5a6ce832013-10-18 11:54:35 -0700600 char isoString[25];
601 ndn_toIsoString(time, isoString);
602 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{
607#if 1
608 throw std::runtime_error("not implemented");
609#endif
610}
611
612} // der
613
614}