Botan 1.10.17

asn1_eac_tm.cpp
Go to the documentation of this file.
1 /*
2 * EAC Time Types
3 * (C) 2007 FlexSecure GmbH
4 * 2008 Jack Lloyd
5 *
6 * Distributed under the terms of the Botan license
7 */
8
9 #include <botan/eac_asn_obj.h>
10 #include <botan/der_enc.h>
11 #include <botan/ber_dec.h>
12 #include <botan/charset.h>
13 #include <botan/parsing.h>
14 #include <botan/internal/rounding.h>
15 #include <botan/time.h>
16
17 namespace Botan {
18
19 namespace {
20
21 SecureVector<byte> enc_two_digit(u32bit in)
22 {
23 SecureVector<byte> result;
24 in %= 100;
25 if (in < 10)
26 result.push_back(0x00);
27 else
28 {
29 u32bit y_first_pos = round_down<u32bit>(in, 10) / 10;
30 result.push_back(static_cast<byte>(y_first_pos));
31 }
32
33 u32bit y_sec_pos = in % 10;
34 result.push_back(static_cast<byte>(y_sec_pos));
35 return result;
36 }
37
38 u32bit dec_two_digit(byte b1, byte b2)
39 {
40 u32bit upper = b1;
41 u32bit lower = b2;
42
43 if(upper > 9 || lower > 9)
44 throw Invalid_Argument("CVC dec_two_digit value too large");
45
46 return upper*10 + lower;
47 }
48
49 }
50
51 /*
52 * Create an EAC_Time
53 */
54 EAC_Time::EAC_Time(u64bit timer, ASN1_Tag t) : tag(t)
55 {
56 calendar_point cal = calendar_value(timer);
57
58 year = cal.year;
59 month = cal.month;
60 day = cal.day;
61 }
62
63 /*
64 * Create an EAC_Time
65 */
66 EAC_Time::EAC_Time(const std::string& t_spec, ASN1_Tag t) : tag(t)
67 {
68 set_to(t_spec);
69 }
70 /*
71 * Create an EAC_Time
72 */
73 EAC_Time::EAC_Time(u32bit y, u32bit m, u32bit d, ASN1_Tag t) :
74 year(y), month(m), day(d), tag(t)
75 {
76 }
77
78 /*
79 * Set the time with a human readable string
80 */
81 void EAC_Time::set_to(const std::string& time_str)
82 {
83 if (time_str == "")
84 {
85 year = month = day = 0;
86 return;
87 }
88
89 std::vector<std::string> params;
90 std::string current;
91
92 for (u32bit j = 0; j != time_str.size(); ++j)
93 {
94 if (Charset::is_digit(time_str[j]))
95 current += time_str[j];
96 else
97 {
98 if (current != "")
99 params.push_back(current);
100 current.clear();
101 }
102 }
103 if (current != "")
104 params.push_back(current);
105
106 if (params.size() != 3)
107 throw Invalid_Argument("Invalid time specification " + time_str);
108
109 year = to_u32bit(params[0]);
110 month = to_u32bit(params[1]);
111 day = to_u32bit(params[2]);
112
113 if (!passes_sanity_check())
114 throw Invalid_Argument("Invalid time specification " + time_str);
115 }
116
117
118 /*
119 * DER encode a EAC_Time
120 */
121 void EAC_Time::encode_into(DER_Encoder& der) const
122 {
123 der.add_object(tag, APPLICATION,
124 encoded_eac_time());
125 }
126
127 /*
128 * Return a string representation of the time
129 */
130 std::string EAC_Time::as_string() const
131 {
132 if (time_is_set() == false)
133 throw Invalid_State("EAC_Time::as_string: No time set");
134
135 std::string asn1rep;
136 asn1rep = to_string(year, 2);
137
138 asn1rep += to_string(month, 2) + to_string(day, 2);
139
140 return asn1rep;
141 }
142
143 /*
144 * Return if the time has been set somehow
145 */
146 bool EAC_Time::time_is_set() const
147 {
148 return (year != 0);
149 }
150
151 /*
152 * Return a human readable string representation
153 */
154 std::string EAC_Time::readable_string() const
155 {
156 if (time_is_set() == false)
157 throw Invalid_State("EAC_Time::readable_string: No time set");
158
159 std::string readable;
160 readable += to_string(year, 2) + "/";
161 readable += to_string(month, 2) + "/";
162 readable += to_string(day, 2) + " ";
163
164 return readable;
165 }
166
167 /*
168 * Do a general sanity check on the time
169 */
170 bool EAC_Time::passes_sanity_check() const
171 {
172 if (year < 2000 || year > 2099)
173 return false;
174 if (month == 0 || month > 12)
175 return false;
176 if (day == 0 || day > 31)
177 return false;
178
179 return true;
180 }
181
182 /*
183 * modification functions
184 */
185
186 void EAC_Time::add_years(u32bit years)
187 {
188 year += years;
189 }
190 void EAC_Time::add_months(u32bit months)
191 {
192 year += months/12;
193 month += months % 12;
194 if(month > 12)
195 {
196 year += 1;
197 month -= 12;
198 }
199 }
200
201
202 /*
203 * Compare this time against another
204 */
205 s32bit EAC_Time::cmp(const EAC_Time& other) const
206 {
207 if (time_is_set() == false)
208 throw Invalid_State("EAC_Time::cmp: No time set");
209
210 const s32bit EARLIER = -1, LATER = 1, SAME_TIME = 0;
211
212 if (year < other.year) return EARLIER;
213 if (year > other.year) return LATER;
214 if (month < other.month) return EARLIER;
215 if (month > other.month) return LATER;
216 if (day < other.day) return EARLIER;
217 if (day > other.day) return LATER;
218
219 return SAME_TIME;
220 }
221
222 /*
223 * Compare two EAC_Times for in various ways
224 */
225 bool operator==(const EAC_Time& t1, const EAC_Time& t2)
226 {
227 return (t1.cmp(t2) == 0);
228 }
229
230 bool operator!=(const EAC_Time& t1, const EAC_Time& t2)
231 {
232 return (t1.cmp(t2) != 0);
233 }
234
235 bool operator<=(const EAC_Time& t1, const EAC_Time& t2)
236 {
237 return (t1.cmp(t2) <= 0);
238 }
239
240 bool operator>=(const EAC_Time& t1, const EAC_Time& t2)
241 {
242 return (t1.cmp(t2) >= 0);
243 }
244
245 bool operator>(const EAC_Time& t1, const EAC_Time& t2)
246 {
247 return (t1.cmp(t2) > 0);
248 }
249
250 bool operator<(const EAC_Time& t1, const EAC_Time& t2)
251 {
252 return (t1.cmp(t2) < 0);
253 }
254
255 /*
256 * Decode a BER encoded EAC_Time
257 */
258 void EAC_Time::decode_from(BER_Decoder& source)
259 {
260 BER_Object obj = source.get_next_object();
261
262 if(obj.type_tag != this->tag)
263 throw BER_Decoding_Error("Tag mismatch when decoding");
264
265 if(obj.value.size() != 6)
266 {
267 throw Decoding_Error("EAC_Time decoding failed");
268 }
269
270 try
271 {
272 u32bit tmp_year = dec_two_digit(obj.value[0], obj.value[1]);
273 u32bit tmp_mon = dec_two_digit(obj.value[2], obj.value[3]);
274 u32bit tmp_day = dec_two_digit(obj.value[4], obj.value[5]);
275 year = tmp_year + 2000;
276 month = tmp_mon;
277 day = tmp_day;
278 }
279 catch (Invalid_Argument)
280 {
281 throw Decoding_Error("EAC_Time decoding failed");
282 }
283
284 }
285
286 u32bit EAC_Time::get_year() const
287 {
288 return year;
289 }
290
291 u32bit EAC_Time::get_month() const
292 {
293 return month;
294 }
295
296 u32bit EAC_Time::get_day() const
297 {
298 return day;
299 }
300
301 /*
302 * make the value an octet string for encoding
303 */
304 SecureVector<byte> EAC_Time::encoded_eac_time() const
305 {
306 SecureVector<byte> result;
307 result += enc_two_digit(year);
308 result += enc_two_digit(month);
309 result += enc_two_digit(day);
310 return result;
311 }
312
313 ASN1_Ced::ASN1_Ced(std::string const& str) :
314 EAC_Time(str, ASN1_Tag(37))
315 {}
316
317 ASN1_Ced::ASN1_Ced(u64bit val) :
318 EAC_Time(val, ASN1_Tag(37))
319 {}
320
321 ASN1_Ced::ASN1_Ced(EAC_Time const& other) :
322 EAC_Time(other.get_year(),
323 other.get_month(),
324 other.get_day(),
325 ASN1_Tag(37))
326 {}
327
328 ASN1_Cex::ASN1_Cex(std::string const& str) :
329 EAC_Time(str, ASN1_Tag(36))
330 {}
331
332 ASN1_Cex::ASN1_Cex(u64bit val) :
333 EAC_Time(val, ASN1_Tag(36))
334 {}
335
336 ASN1_Cex::ASN1_Cex(EAC_Time const& other) :
337 EAC_Time(other.get_year(),
338 other.get_month(),
339 other.get_day(),
340 ASN1_Tag(36))
341 {}
342
343 }
Botan::EAC_Time::readable_string
std::string readable_string() const
Definition: asn1_eac_tm.cpp:154
Botan::EAC_Time::get_day
u32bit get_day() const
Definition: asn1_eac_tm.cpp:296
Botan::operator!=
bool operator!=(const OctetString &s1, const OctetString &s2)
Definition: symkey.cpp:106
Botan::operator>=
bool BOTAN_DLL operator>=(const X509_Time &, const X509_Time &)
Definition: asn1_tm.cpp:283
Botan::EAC_Time::cmp
s32bit cmp(const EAC_Time &other) const
Definition: asn1_eac_tm.cpp:205
Botan::EAC_Time::get_month
u32bit get_month() const
Definition: asn1_eac_tm.cpp:291
Botan::operator==
bool operator==(const OctetString &s1, const OctetString &s2)
Definition: symkey.cpp:98
Botan::ASN1_Cex::ASN1_Cex
ASN1_Cex(std::string const &str="")
Definition: asn1_eac_tm.cpp:328
Botan::EAC_Time::EAC_Time
EAC_Time(u64bit, ASN1_Tag t=ASN1_Tag(0))
Definition: asn1_eac_tm.cpp:54
Botan::Invalid_State
Definition: exceptn.h:25
Botan::Invalid_Argument
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
Botan::EAC_Time::decode_from
void decode_from(class BER_Decoder &)
Definition: asn1_eac_tm.cpp:258
Botan::calendar_value
calendar_point calendar_value(u64bit a_time_t)
Definition: time.cpp:81
Botan::calendar_point::month
byte month
Definition: time.h:24
Botan::EAC_Time::add_years
void add_years(u32bit years)
Definition: asn1_eac_tm.cpp:186
Botan::s32bit
signed int s32bit
Definition: types.h:37
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::EAC_Time
Definition: eac_asn_obj.h:21
Botan::u64bit
unsigned long long u64bit
Definition: types.h:49
Botan::calendar_point::year
u32bit year
Definition: time.h:21
Botan::DER_Encoder
Definition: der_enc.h:22
Botan::EAC_Time::add_months
void add_months(u32bit months)
Definition: asn1_eac_tm.cpp:190
Botan::operator>
bool BOTAN_DLL operator>(const X509_Time &, const X509_Time &)
Definition: asn1_tm.cpp:288
Botan::ASN1_Tag
ASN1_Tag
Definition: asn1_int.h:19
Botan::EAC_Time::get_year
u32bit get_year() const
Definition: asn1_eac_tm.cpp:286
Botan::ASN1_Ced::ASN1_Ced
ASN1_Ced(std::string const &str="")
Definition: asn1_eac_tm.cpp:313
Botan::calendar_point
Definition: time.h:18
Botan::Decoding_Error
Definition: exceptn.h:138
Botan
Definition: algo_base.h:14
Botan::BER_Object::value
SecureVector< byte > value
Definition: asn1_int.h:83
Botan::EAC_Time::encode_into
void encode_into(class DER_Encoder &) const
Definition: asn1_eac_tm.cpp:121
Botan::calendar_point::day
byte day
Definition: time.h:27
Botan::Charset::is_digit
bool is_digit(char c)
Definition: charset.cpp:128
Botan::BER_Decoder::get_next_object
BER_Object get_next_object()
Definition: ber_dec.cpp:196
Botan::MemoryRegion::size
size_t size() const
Definition: secmem.h:29
Botan::APPLICATION
Definition: asn1_int.h:21
Botan::EAC_Time::time_is_set
bool time_is_set() const
Definition: asn1_eac_tm.cpp:146
Botan::BER_Object::type_tag
ASN1_Tag type_tag
Definition: asn1_int.h:82
Botan::operator<
bool BOTAN_DLL operator<(const X509_Time &, const X509_Time &)
Definition: asn1_tm.cpp:286
Botan::BER_Decoding_Error
Definition: asn1_int.h:107
Botan::to_string
std::string to_string(u64bit n, size_t min_len)
Definition: parsing.cpp:42
Botan::SecureVector< byte >
Botan::BER_Decoder
Definition: ber_dec.h:19
Botan::operator<=
bool BOTAN_DLL operator<=(const X509_Time &, const X509_Time &)
Definition: asn1_tm.cpp:281
Botan::BER_Object
Definition: asn1_int.h:77
Botan::to_u32bit
u32bit to_u32bit(const std::string &number)
Definition: parsing.cpp:18
Botan::EAC_Time::as_string
std::string as_string() const
Definition: asn1_eac_tm.cpp:130
Botan::DER_Encoder::add_object
DER_Encoder & add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const byte rep[], size_t length)
Definition: der_enc.cpp:346
Botan::u32bit
unsigned int u32bit
Definition: types.h:32
Botan::EAC_Time::set_to
void set_to(const std::string &str)
Definition: asn1_eac_tm.cpp:81