blob: beea45d5e89c920279ff0530da14f2452ca24d85 [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
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -08009#include "asn_ext.hpp"
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080010#include "../../util/time.hpp"
11
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080012#include <boost/format.hpp>
13#include <boost/lexical_cast.hpp>
14
15using namespace CryptoPP;
16
17namespace ndn {
18
19size_t
20DEREncodeGeneralTime(CryptoPP::BufferedTransformation &bt, MillisecondsSince1970 time)
21{
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080022 if (time < 0)
23 throw Asn::Error("Calendar time value out of range");
24 else if (time > 2e14)
25 // 2e14 is about the year 8300. We don't want to go over a 4-digit year.
26 throw Asn::Error("Calendar time value out of range");
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080027
Alexander Afanasyev1e0a0772014-01-28 20:07:07 -080028
29 boost::posix_time::ptime boostTime =
30 UNIX_EPOCH_TIME + boost::posix_time::milliseconds(time);
31
32 const boost::format f = boost::format("%04d%02d%02d%02d%02d%02dZ")
33 % boostTime.date().year_month_day().year
34 % boostTime.date().year_month_day().month.as_number()
35 % boostTime.date().year_month_day().day.as_number()
36 % boostTime.time_of_day().hours()
37 % boostTime.time_of_day().minutes()
38 % boostTime.time_of_day().seconds()
39 ;
40
41 std::string asn1time = f.str();
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080042
43 bt.Put(GENERALIZED_TIME);
44 size_t lengthBytes = DERLengthEncode(bt, asn1time.size());
45 bt.Put(reinterpret_cast<const uint8_t*>(asn1time.c_str()), asn1time.size());
46 return 1+lengthBytes+asn1time.size();
47}
48
49void
50BERDecodeTime(CryptoPP::BufferedTransformation &bt, MillisecondsSince1970 &time)
51{
52 byte b;
53 if (!bt.Get(b) || (b != GENERALIZED_TIME && b != UTC_TIME))
54 BERDecodeError();
55
56 size_t bc;
57 if (!BERLengthDecode(bt, bc))
58 BERDecodeError();
59
60 SecByteBlock time_str(bc);
61 if (bc != bt.Get(time_str, bc))
62 BERDecodeError();
63
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080064 std::string str;
65 str.assign (time_str.begin(), time_str.end());
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080066
Alexander Afanasyev049f8f72013-12-26 19:07:15 -080067 if (b == UTC_TIME) {
68 if (boost::lexical_cast<int>(str.substr(0,2)) < 50)
69 str = "20" + str;
70 else
71 str = "19" + str;
72 }
73
74 time = fromIsoString(str.substr(0, 8) + "T" + str.substr(8, 6));
Alexander Afanasyev0ea6e082013-12-26 15:16:37 -080075}
76
77} // namespace ndn