blob: a1ee39d8df6543d16b298745a20eb9defbac388f [file] [log] [blame]
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -08001/**
2 * Copyright (C) 2013 Regents of the University of California.
3 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
6 * See COPYING for copyright and distribution information.
7 */
8
9#include <ndn-cpp/ndn-cpp-config.h>
10#include "asn_ext.hpp"
11
12#if NDN_CPP_HAVE_TIME_H
13#include <time.h>
14#endif
15#if NDN_CPP_HAVE_SYS_TIME_H
16#include <sys/time.h>
17#endif
18
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080019#include "../../util/time.hpp"
20
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080021#include <boost/format.hpp>
22#include <boost/lexical_cast.hpp>
23
24using namespace CryptoPP;
25
26namespace ndn {
27
28size_t
29DEREncodeGeneralTime(CryptoPP::BufferedTransformation &bt, MillisecondsSince1970 time)
30{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080031 if (time < 0)
32 throw Asn::Error("Calendar time value out of range");
33 else if (time > 2e14)
34 // 2e14 is about the year 8300. We don't want to go over a 4-digit year.
35 throw Asn::Error("Calendar time value out of range");
36
37 time_t secondsSince1970 = time / 1000;
38 struct tm* gmt = gmtime(&secondsSince1970);
39
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080040 std::string asn1time ((boost::format("%04d%02d%02d%02d%02d%02dZ")
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080041 % (1900 + gmt->tm_year)
42 % (gmt->tm_mon + 1)
43 % gmt->tm_mday
44 % gmt->tm_hour
45 % gmt->tm_min
46 % gmt->tm_sec).str());
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080047
48 bt.Put(GENERALIZED_TIME);
49 size_t lengthBytes = DERLengthEncode(bt, asn1time.size());
50 bt.Put(reinterpret_cast<const uint8_t*>(asn1time.c_str()), asn1time.size());
51 return 1+lengthBytes+asn1time.size();
52}
53
54void
55BERDecodeTime(CryptoPP::BufferedTransformation &bt, MillisecondsSince1970 &time)
56{
57 byte b;
58 if (!bt.Get(b) || (b != GENERALIZED_TIME && b != UTC_TIME))
59 BERDecodeError();
60
61 size_t bc;
62 if (!BERLengthDecode(bt, bc))
63 BERDecodeError();
64
65 SecByteBlock time_str(bc);
66 if (bc != bt.Get(time_str, bc))
67 BERDecodeError();
68
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080069 std::string str;
70 str.assign (time_str.begin(), time_str.end());
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080071
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080072 if (b == UTC_TIME) {
73 if (boost::lexical_cast<int>(str.substr(0,2)) < 50)
74 str = "20" + str;
75 else
76 str = "19" + str;
77 }
78
79 time = fromIsoString(str.substr(0, 8) + "T" + str.substr(8, 6));
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080080}
81
82} // namespace ndn