Mercurial > dropbear
comparison libtomcrypt/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c @ 1471:6dba84798cd5
Update to libtomcrypt 1.18.1, merged with Dropbear changes
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 09 Feb 2018 21:44:05 +0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1470:8bba51a55704 | 1471:6dba84798cd5 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 */ | |
9 #include "tomcrypt.h" | |
10 | |
11 /** | |
12 @file der_decode_generalizedtime.c | |
13 ASN.1 DER, decode a GeneralizedTime, Steffen Jaeckel | |
14 Based on der_decode_utctime.c | |
15 */ | |
16 | |
17 #ifdef LTC_DER | |
18 | |
19 static int _char_to_int(unsigned char x) | |
20 { | |
21 switch (x) { | |
22 case '0': return 0; | |
23 case '1': return 1; | |
24 case '2': return 2; | |
25 case '3': return 3; | |
26 case '4': return 4; | |
27 case '5': return 5; | |
28 case '6': return 6; | |
29 case '7': return 7; | |
30 case '8': return 8; | |
31 case '9': return 9; | |
32 default: return 100; | |
33 } | |
34 } | |
35 | |
36 #define DECODE_V(y, max) do {\ | |
37 y = _char_to_int(buf[x])*10 + _char_to_int(buf[x+1]); \ | |
38 if (y >= max) return CRYPT_INVALID_PACKET; \ | |
39 x += 2; \ | |
40 } while(0) | |
41 | |
42 #define DECODE_V4(y, max) do {\ | |
43 y = _char_to_int(buf[x])*1000 + _char_to_int(buf[x+1])*100 + _char_to_int(buf[x+2])*10 + _char_to_int(buf[x+3]); \ | |
44 if (y >= max) return CRYPT_INVALID_PACKET; \ | |
45 x += 4; \ | |
46 } while(0) | |
47 | |
48 /** | |
49 Decodes a Generalized time structure in DER format (reads all 6 valid encoding formats) | |
50 @param in Input buffer | |
51 @param inlen Length of input buffer in octets | |
52 @param out [out] Destination of Generalized time structure | |
53 @return CRYPT_OK if successful | |
54 */ | |
55 int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, | |
56 ltc_generalizedtime *out) | |
57 { | |
58 unsigned char buf[32]; | |
59 unsigned long x; | |
60 int y; | |
61 | |
62 LTC_ARGCHK(in != NULL); | |
63 LTC_ARGCHK(inlen != NULL); | |
64 LTC_ARGCHK(out != NULL); | |
65 | |
66 /* check header */ | |
67 if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) { | |
68 return CRYPT_INVALID_PACKET; | |
69 } | |
70 | |
71 /* decode the string */ | |
72 for (x = 0; x < in[1]; x++) { | |
73 y = der_ia5_value_decode(in[x+2]); | |
74 if (y == -1) { | |
75 return CRYPT_INVALID_PACKET; | |
76 } | |
77 if (!((y >= '0' && y <= '9') | |
78 || y == 'Z' || y == '.' | |
79 || y == '+' || y == '-')) { | |
80 return CRYPT_INVALID_PACKET; | |
81 } | |
82 buf[x] = y; | |
83 } | |
84 *inlen = 2 + x; | |
85 | |
86 if (x < 15) { | |
87 return CRYPT_INVALID_PACKET; | |
88 } | |
89 | |
90 /* possible encodings are | |
91 YYYYMMDDhhmmssZ | |
92 YYYYMMDDhhmmss+hh'mm' | |
93 YYYYMMDDhhmmss-hh'mm' | |
94 YYYYMMDDhhmmss.fsZ | |
95 YYYYMMDDhhmmss.fs+hh'mm' | |
96 YYYYMMDDhhmmss.fs-hh'mm' | |
97 | |
98 So let's do a trivial decode upto [including] ss | |
99 */ | |
100 | |
101 x = 0; | |
102 DECODE_V4(out->YYYY, 10000); | |
103 DECODE_V(out->MM, 13); | |
104 DECODE_V(out->DD, 32); | |
105 DECODE_V(out->hh, 24); | |
106 DECODE_V(out->mm, 60); | |
107 DECODE_V(out->ss, 60); | |
108 | |
109 /* clear fractional seconds info */ | |
110 out->fs = 0; | |
111 | |
112 /* now is it Z or . */ | |
113 if (buf[x] == 'Z') { | |
114 return CRYPT_OK; | |
115 } else if (buf[x] == '.') { | |
116 x++; | |
117 while (buf[x] >= '0' && buf[x] <= '9') { | |
118 unsigned fs = out->fs; | |
119 if (x >= sizeof(buf)) return CRYPT_INVALID_PACKET; | |
120 out->fs *= 10; | |
121 out->fs += _char_to_int(buf[x]); | |
122 if (fs > out->fs) return CRYPT_OVERFLOW; | |
123 x++; | |
124 } | |
125 } | |
126 | |
127 /* now is it Z, +, - */ | |
128 if (buf[x] == 'Z') { | |
129 return CRYPT_OK; | |
130 } else if (buf[x] == '+' || buf[x] == '-') { | |
131 out->off_dir = (buf[x++] == '+') ? 0 : 1; | |
132 DECODE_V(out->off_hh, 24); | |
133 DECODE_V(out->off_mm, 60); | |
134 return CRYPT_OK; | |
135 } else { | |
136 return CRYPT_INVALID_PACKET; | |
137 } | |
138 } | |
139 | |
140 #endif | |
141 | |
142 /* ref: $Format:%D$ */ | |
143 /* git commit: $Format:%H$ */ | |
144 /* commit time: $Format:%ai$ */ |