1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "parse_values.h"
6
7 #include <stdlib.h>
8
9 #include <tuple>
10
11 #include <openssl/base.h>
12 #include <openssl/bytestring.h>
13 #include <openssl/mem.h>
14
15 namespace bssl::der {
16
17 namespace {
18
ParseBoolInternal(Input in,bool * out,bool relaxed)19 bool ParseBoolInternal(Input in, bool *out, bool relaxed) {
20 // According to ITU-T X.690 section 8.2, a bool is encoded as a single octet
21 // where the octet of all zeroes is FALSE and a non-zero value for the octet
22 // is TRUE.
23 if (in.size() != 1) {
24 return false;
25 }
26 ByteReader data(in);
27 uint8_t byte;
28 if (!data.ReadByte(&byte)) {
29 return false;
30 }
31 if (byte == 0) {
32 *out = false;
33 return true;
34 }
35 // ITU-T X.690 section 11.1 specifies that for DER, the TRUE value must be
36 // encoded as an octet of all ones.
37 if (byte == 0xff || relaxed) {
38 *out = true;
39 return true;
40 }
41 return false;
42 }
43
44 // Reads a positive decimal number with |digits| digits and stores it in
45 // |*out|. This function does not check that the type of |*out| is large
46 // enough to hold 10^digits - 1; the caller must choose an appropriate type
47 // based on the number of digits they wish to parse.
48 template <typename UINT>
DecimalStringToUint(ByteReader & in,size_t digits,UINT * out)49 bool DecimalStringToUint(ByteReader &in, size_t digits, UINT *out) {
50 UINT value = 0;
51 for (size_t i = 0; i < digits; ++i) {
52 uint8_t digit;
53 if (!in.ReadByte(&digit)) {
54 return false;
55 }
56 if (digit < '0' || digit > '9') {
57 return false;
58 }
59 value = (value * 10) + (digit - '0');
60 }
61 *out = value;
62 return true;
63 }
64
65 // Checks that the values in a GeneralizedTime struct are valid. This involves
66 // checking that the year is 4 digits, the month is between 1 and 12, the day
67 // is a day that exists in that month (following current leap year rules),
68 // hours are between 0 and 23, minutes between 0 and 59, and seconds between
69 // 0 and 60 (to allow for leap seconds; no validation is done that a leap
70 // second is on a day that could be a leap second).
ValidateGeneralizedTime(const GeneralizedTime & time)71 bool ValidateGeneralizedTime(const GeneralizedTime &time) {
72 if (time.month < 1 || time.month > 12) {
73 return false;
74 }
75 if (time.day < 1) {
76 return false;
77 }
78 if (time.hours > 23) {
79 return false;
80 }
81 if (time.minutes > 59) {
82 return false;
83 }
84 // Leap seconds are allowed.
85 if (time.seconds > 60) {
86 return false;
87 }
88
89 // validate upper bound for day of month
90 switch (time.month) {
91 case 4:
92 case 6:
93 case 9:
94 case 11:
95 if (time.day > 30) {
96 return false;
97 }
98 break;
99 case 1:
100 case 3:
101 case 5:
102 case 7:
103 case 8:
104 case 10:
105 case 12:
106 if (time.day > 31) {
107 return false;
108 }
109 break;
110 case 2:
111 if (time.year % 4 == 0 &&
112 (time.year % 100 != 0 || time.year % 400 == 0)) {
113 if (time.day > 29) {
114 return false;
115 }
116 } else {
117 if (time.day > 28) {
118 return false;
119 }
120 }
121 break;
122 default:
123 abort();
124 }
125 return true;
126 }
127
128 // Returns the number of bytes of numeric precision in a DER encoded INTEGER
129 // value. |in| must be a valid DER encoding of an INTEGER for this to work.
130 //
131 // Normally the precision of the number is exactly in.size(). However when
132 // encoding positive numbers using DER it is possible to have a leading zero
133 // (to prevent number from being interpreted as negative).
134 //
135 // For instance a 160-bit positive number might take 21 bytes to encode. This
136 // function will return 20 in such a case.
GetUnsignedIntegerLength(Input in)137 size_t GetUnsignedIntegerLength(Input in) {
138 der::ByteReader reader(in);
139 uint8_t first_byte;
140 if (!reader.ReadByte(&first_byte)) {
141 return 0; // Not valid DER as |in| was empty.
142 }
143
144 if (first_byte == 0 && in.size() > 1) {
145 return in.size() - 1;
146 }
147 return in.size();
148 }
149
150 } // namespace
151
ParseBool(Input in,bool * out)152 bool ParseBool(Input in, bool *out) {
153 return ParseBoolInternal(in, out, false /* relaxed */);
154 }
155
156 // BER interprets any non-zero value as true, while DER requires a bool to
157 // have either all bits zero (false) or all bits one (true). To support
158 // malformed certs, we recognized the BER encoding instead of failing to
159 // parse.
ParseBoolRelaxed(Input in,bool * out)160 bool ParseBoolRelaxed(Input in, bool *out) {
161 return ParseBoolInternal(in, out, true /* relaxed */);
162 }
163
164 // ITU-T X.690 section 8.3.2 specifies that an integer value must be encoded
165 // in the smallest number of octets. If the encoding consists of more than
166 // one octet, then the bits of the first octet and the most significant bit
167 // of the second octet must not be all zeroes or all ones.
IsValidInteger(Input in,bool * negative)168 bool IsValidInteger(Input in, bool *negative) {
169 CBS cbs;
170 CBS_init(&cbs, in.data(), in.size());
171 int negative_int;
172 if (!CBS_is_valid_asn1_integer(&cbs, &negative_int)) {
173 return false;
174 }
175
176 *negative = !!negative_int;
177 return true;
178 }
179
ParseUint64(Input in,uint64_t * out)180 bool ParseUint64(Input in, uint64_t *out) {
181 // Reject non-minimally encoded numbers and negative numbers.
182 bool negative;
183 if (!IsValidInteger(in, &negative) || negative) {
184 return false;
185 }
186
187 // Reject (non-negative) integers whose value would overflow the output type.
188 if (GetUnsignedIntegerLength(in) > sizeof(*out)) {
189 return false;
190 }
191
192 ByteReader reader(in);
193 uint8_t data;
194 uint64_t value = 0;
195
196 while (reader.ReadByte(&data)) {
197 value <<= 8;
198 value |= data;
199 }
200 *out = value;
201 return true;
202 }
203
ParseUint8(Input in,uint8_t * out)204 bool ParseUint8(Input in, uint8_t *out) {
205 // TODO(eroman): Implement this more directly.
206 uint64_t value;
207 if (!ParseUint64(in, &value)) {
208 return false;
209 }
210
211 if (value > 0xFF) {
212 return false;
213 }
214
215 *out = static_cast<uint8_t>(value);
216 return true;
217 }
218
BitString(Input bytes,uint8_t unused_bits)219 BitString::BitString(Input bytes, uint8_t unused_bits)
220 : bytes_(bytes), unused_bits_(unused_bits) {
221 BSSL_CHECK(unused_bits < 8);
222 BSSL_CHECK(unused_bits == 0 || !bytes.empty());
223 // The unused bits must be zero.
224 BSSL_CHECK(bytes.empty() || (bytes.back() & ((1u << unused_bits) - 1)) == 0);
225 }
226
AssertsBit(size_t bit_index) const227 bool BitString::AssertsBit(size_t bit_index) const {
228 // Index of the byte that contains the bit.
229 size_t byte_index = bit_index / 8;
230
231 // If the bit is outside of the bitstring, by definition it is not
232 // asserted.
233 if (byte_index >= bytes_.size()) {
234 return false;
235 }
236
237 // Within a byte, bits are ordered from most significant to least significant.
238 // Convert |bit_index| to an index within the |byte_index| byte, measured from
239 // its least significant bit.
240 uint8_t bit_index_in_byte = 7 - (bit_index - byte_index * 8);
241
242 // BIT STRING parsing already guarantees that unused bits in a byte are zero
243 // (otherwise it wouldn't be valid DER). Therefore it isn't necessary to check
244 // |unused_bits_|
245 uint8_t byte = bytes_[byte_index];
246 return 0 != (byte & (1 << bit_index_in_byte));
247 }
248
ParseBitString(Input in)249 std::optional<BitString> ParseBitString(Input in) {
250 ByteReader reader(in);
251
252 // From ITU-T X.690, section 8.6.2.2 (applies to BER, CER, DER):
253 //
254 // The initial octet shall encode, as an unsigned binary integer with
255 // bit 1 as the least significant bit, the number of unused bits in the final
256 // subsequent octet. The number shall be in the range zero to seven.
257 uint8_t unused_bits;
258 if (!reader.ReadByte(&unused_bits)) {
259 return std::nullopt;
260 }
261 if (unused_bits > 7) {
262 return std::nullopt;
263 }
264
265 Input bytes;
266 if (!reader.ReadBytes(reader.BytesLeft(), &bytes)) {
267 return std::nullopt; // Not reachable.
268 }
269
270 // Ensure that unused bits in the last byte are set to 0.
271 if (unused_bits > 0) {
272 // From ITU-T X.690, section 8.6.2.3 (applies to BER, CER, DER):
273 //
274 // If the bitstring is empty, there shall be no subsequent octets,
275 // and the initial octet shall be zero.
276 if (bytes.empty()) {
277 return std::nullopt;
278 }
279 uint8_t last_byte = bytes.back();
280
281 // From ITU-T X.690, section 11.2.1 (applies to CER and DER, but not BER):
282 //
283 // Each unused bit in the final octet of the encoding of a bit string value
284 // shall be set to zero.
285 uint8_t mask = 0xFF >> (8 - unused_bits);
286 if ((mask & last_byte) != 0) {
287 return std::nullopt;
288 }
289 }
290
291 return BitString(bytes, unused_bits);
292 }
293
InUTCTimeRange() const294 bool GeneralizedTime::InUTCTimeRange() const {
295 return 1950 <= year && year < 2050;
296 }
297
operator <(const GeneralizedTime & lhs,const GeneralizedTime & rhs)298 bool operator<(const GeneralizedTime &lhs, const GeneralizedTime &rhs) {
299 return std::tie(lhs.year, lhs.month, lhs.day, lhs.hours, lhs.minutes,
300 lhs.seconds) < std::tie(rhs.year, rhs.month, rhs.day,
301 rhs.hours, rhs.minutes, rhs.seconds);
302 }
303
operator >(const GeneralizedTime & lhs,const GeneralizedTime & rhs)304 bool operator>(const GeneralizedTime &lhs, const GeneralizedTime &rhs) {
305 return rhs < lhs;
306 }
307
operator <=(const GeneralizedTime & lhs,const GeneralizedTime & rhs)308 bool operator<=(const GeneralizedTime &lhs, const GeneralizedTime &rhs) {
309 return !(lhs > rhs);
310 }
311
operator >=(const GeneralizedTime & lhs,const GeneralizedTime & rhs)312 bool operator>=(const GeneralizedTime &lhs, const GeneralizedTime &rhs) {
313 return !(lhs < rhs);
314 }
315
ParseUTCTime(Input in,GeneralizedTime * value)316 bool ParseUTCTime(Input in, GeneralizedTime *value) {
317 ByteReader reader(in);
318 GeneralizedTime time;
319 if (!DecimalStringToUint(reader, 2, &time.year) ||
320 !DecimalStringToUint(reader, 2, &time.month) ||
321 !DecimalStringToUint(reader, 2, &time.day) ||
322 !DecimalStringToUint(reader, 2, &time.hours) ||
323 !DecimalStringToUint(reader, 2, &time.minutes) ||
324 !DecimalStringToUint(reader, 2, &time.seconds)) {
325 return false;
326 }
327 uint8_t zulu;
328 if (!reader.ReadByte(&zulu) || zulu != 'Z' || reader.HasMore()) {
329 return false;
330 }
331 if (time.year < 50) {
332 time.year += 2000;
333 } else {
334 time.year += 1900;
335 }
336 if (!ValidateGeneralizedTime(time)) {
337 return false;
338 }
339 *value = time;
340 return true;
341 }
342
ParseGeneralizedTime(Input in,GeneralizedTime * value)343 bool ParseGeneralizedTime(Input in, GeneralizedTime *value) {
344 ByteReader reader(in);
345 GeneralizedTime time;
346 if (!DecimalStringToUint(reader, 4, &time.year) ||
347 !DecimalStringToUint(reader, 2, &time.month) ||
348 !DecimalStringToUint(reader, 2, &time.day) ||
349 !DecimalStringToUint(reader, 2, &time.hours) ||
350 !DecimalStringToUint(reader, 2, &time.minutes) ||
351 !DecimalStringToUint(reader, 2, &time.seconds)) {
352 return false;
353 }
354 uint8_t zulu;
355 if (!reader.ReadByte(&zulu) || zulu != 'Z' || reader.HasMore()) {
356 return false;
357 }
358 if (!ValidateGeneralizedTime(time)) {
359 return false;
360 }
361 *value = time;
362 return true;
363 }
364
ParseIA5String(Input in,std::string * out)365 bool ParseIA5String(Input in, std::string *out) {
366 for (uint8_t c : in) {
367 if (c > 127) {
368 return false;
369 }
370 }
371 *out = BytesAsStringView(in);
372 return true;
373 }
374
ParseVisibleString(Input in,std::string * out)375 bool ParseVisibleString(Input in, std::string *out) {
376 // ITU-T X.680:
377 // VisibleString : "Defining registration number 6" + SPACE
378 // 6 includes all the characters from '!' .. '~' (33 .. 126), space is 32.
379 // Also ITU-T X.691 says it much more clearly:
380 // "for VisibleString [the range] is 32 to 126 ... For VisibleString .. all
381 // the values in the range are present."
382 for (uint8_t c : in) {
383 if (c < 32 || c > 126) {
384 return false;
385 }
386 }
387 *out = BytesAsStringView(in);
388 return true;
389 }
390
ParsePrintableString(Input in,std::string * out)391 bool ParsePrintableString(Input in, std::string *out) {
392 for (uint8_t c : in) {
393 if (!(OPENSSL_isalpha(c) || c == ' ' || (c >= '\'' && c <= ':') ||
394 c == '=' || c == '?')) {
395 return false;
396 }
397 }
398 *out = BytesAsStringView(in);
399 return true;
400 }
401
ParseTeletexStringAsLatin1(Input in,std::string * out)402 bool ParseTeletexStringAsLatin1(Input in, std::string *out) {
403 out->clear();
404 // Convert from Latin-1 to UTF-8.
405 size_t utf8_length = in.size();
406 for (size_t i = 0; i < in.size(); i++) {
407 if (in[i] > 0x7f) {
408 utf8_length++;
409 }
410 }
411 out->reserve(utf8_length);
412 for (size_t i = 0; i < in.size(); i++) {
413 uint8_t u = in[i];
414 if (u <= 0x7f) {
415 out->push_back(u);
416 } else {
417 out->push_back(0xc0 | (u >> 6));
418 out->push_back(0x80 | (u & 0x3f));
419 }
420 }
421 BSSL_CHECK(utf8_length == out->size());
422 return true;
423 }
424
ParseUniversalString(Input in,std::string * out)425 bool ParseUniversalString(Input in, std::string *out) {
426 if (in.size() % 4 != 0) {
427 return false;
428 }
429
430 CBS cbs;
431 CBS_init(&cbs, in.data(), in.size());
432 bssl::ScopedCBB cbb;
433 if (!CBB_init(cbb.get(), in.size())) {
434 return false;
435 }
436
437 while (CBS_len(&cbs) != 0) {
438 uint32_t c;
439 if (!CBS_get_utf32_be(&cbs, &c) || //
440 !CBB_add_utf8(cbb.get(), c)) {
441 return false;
442 }
443 }
444
445 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
446 return true;
447 }
448
ParseBmpString(Input in,std::string * out)449 bool ParseBmpString(Input in, std::string *out) {
450 if (in.size() % 2 != 0) {
451 return false;
452 }
453
454 CBS cbs;
455 CBS_init(&cbs, in.data(), in.size());
456 bssl::ScopedCBB cbb;
457 if (!CBB_init(cbb.get(), in.size())) {
458 return false;
459 }
460
461 while (CBS_len(&cbs) != 0) {
462 uint32_t c;
463 if (!CBS_get_ucs2_be(&cbs, &c) || //
464 !CBB_add_utf8(cbb.get(), c)) {
465 return false;
466 }
467 }
468
469 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
470 return true;
471 }
472
473 } // namespace bssl::der
474