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