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