blob: cc7a0724c65249ebda5832215bda12ef82ed197b [file] [log] [blame]
Bob Beckbc97b7a2023-04-18 08:35:15 -06001// 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
Bob Beck3aecf1d2023-09-08 11:56:02 -06007#include <stdlib.h>
8
Bob Beckbc97b7a2023-04-18 08:35:15 -06009#include <tuple>
Bob Beckbc97b7a2023-04-18 08:35:15 -060010
Bob Beck05007562023-08-17 20:22:17 +000011#include <openssl/base.h>
Bob Beckbc97b7a2023-04-18 08:35:15 -060012#include <openssl/bytestring.h>
Bob Beck3aecf1d2023-09-08 11:56:02 -060013#include <openssl/mem.h>
Bob Beckbc97b7a2023-04-18 08:35:15 -060014
15namespace bssl::der {
16
17namespace {
18
Bob Beck5c7a2a02023-11-20 17:28:21 -070019bool ParseBoolInternal(const Input &in, bool *out, bool relaxed) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060020 // 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.
Bob Beck6beabf32023-11-21 09:43:52 -070023 if (in.Length() != 1) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060024 return false;
Bob Beck6beabf32023-11-21 09:43:52 -070025 }
Bob Beckbc97b7a2023-04-18 08:35:15 -060026 ByteReader data(in);
27 uint8_t byte;
Bob Beck6beabf32023-11-21 09:43:52 -070028 if (!data.ReadByte(&byte)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060029 return false;
Bob Beck6beabf32023-11-21 09:43:52 -070030 }
Bob Beckbc97b7a2023-04-18 08:35:15 -060031 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.
48template <typename UINT>
Bob Beck5c7a2a02023-11-20 17:28:21 -070049bool DecimalStringToUint(ByteReader &in, size_t digits, UINT *out) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060050 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).
Bob Beck5c7a2a02023-11-20 17:28:21 -070071bool ValidateGeneralizedTime(const GeneralizedTime &time) {
Bob Beck6beabf32023-11-21 09:43:52 -070072 if (time.month < 1 || time.month > 12) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060073 return false;
Bob Beck6beabf32023-11-21 09:43:52 -070074 }
75 if (time.day < 1) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060076 return false;
Bob Beck6beabf32023-11-21 09:43:52 -070077 }
Bob Beckbc97b7a2023-04-18 08:35:15 -060078 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:
Bob Beck6beabf32023-11-21 09:43:52 -070095 if (time.day > 30) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060096 return false;
Bob Beck6beabf32023-11-21 09:43:52 -070097 }
Bob Beckbc97b7a2023-04-18 08:35:15 -060098 break;
99 case 1:
100 case 3:
101 case 5:
102 case 7:
103 case 8:
104 case 10:
105 case 12:
Bob Beck6beabf32023-11-21 09:43:52 -0700106 if (time.day > 31) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600107 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700108 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600109 break;
110 case 2:
111 if (time.year % 4 == 0 &&
112 (time.year % 100 != 0 || time.year % 400 == 0)) {
Bob Beck6beabf32023-11-21 09:43:52 -0700113 if (time.day > 29) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600114 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700115 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600116 } else {
Bob Beck6beabf32023-11-21 09:43:52 -0700117 if (time.day > 28) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600118 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700119 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600120 }
121 break;
122 default:
Bob Beck3aecf1d2023-09-08 11:56:02 -0600123 abort();
Bob Beckbc97b7a2023-04-18 08:35:15 -0600124 }
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.Length(). 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.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700137size_t GetUnsignedIntegerLength(const Input &in) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600138 der::ByteReader reader(in);
139 uint8_t first_byte;
Bob Beck6beabf32023-11-21 09:43:52 -0700140 if (!reader.ReadByte(&first_byte)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600141 return 0; // Not valid DER as |in| was empty.
Bob Beck6beabf32023-11-21 09:43:52 -0700142 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600143
Bob Beck6beabf32023-11-21 09:43:52 -0700144 if (first_byte == 0 && in.Length() > 1) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600145 return in.Length() - 1;
Bob Beck6beabf32023-11-21 09:43:52 -0700146 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600147 return in.Length();
148}
149
150} // namespace
151
Bob Beck5c7a2a02023-11-20 17:28:21 -0700152bool ParseBool(const Input &in, bool *out) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600153 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.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700160bool ParseBoolRelaxed(const Input &in, bool *out) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600161 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.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700168bool IsValidInteger(const Input &in, bool *negative) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600169 CBS cbs;
170 CBS_init(&cbs, in.UnsafeData(), in.Length());
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
Bob Beck5c7a2a02023-11-20 17:28:21 -0700180bool ParseUint64(const Input &in, uint64_t *out) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600181 // Reject non-minimally encoded numbers and negative numbers.
182 bool negative;
Bob Beck6beabf32023-11-21 09:43:52 -0700183 if (!IsValidInteger(in, &negative) || negative) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600184 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700185 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600186
187 // Reject (non-negative) integers whose value would overflow the output type.
Bob Beck6beabf32023-11-21 09:43:52 -0700188 if (GetUnsignedIntegerLength(in) > sizeof(*out)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600189 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700190 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600191
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
Bob Beck5c7a2a02023-11-20 17:28:21 -0700204bool ParseUint8(const Input &in, uint8_t *out) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600205 // TODO(eroman): Implement this more directly.
206 uint64_t value;
Bob Beck6beabf32023-11-21 09:43:52 -0700207 if (!ParseUint64(in, &value)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600208 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700209 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600210
Bob Beck6beabf32023-11-21 09:43:52 -0700211 if (value > 0xFF) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600212 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700213 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600214
215 *out = static_cast<uint8_t>(value);
216 return true;
217}
218
Bob Beck5c7a2a02023-11-20 17:28:21 -0700219BitString::BitString(const Input &bytes, uint8_t unused_bits)
Bob Beckbc97b7a2023-04-18 08:35:15 -0600220 : bytes_(bytes), unused_bits_(unused_bits) {
Bob Beck05007562023-08-17 20:22:17 +0000221 BSSL_CHECK(unused_bits < 8);
222 BSSL_CHECK(unused_bits == 0 || bytes.Length() != 0);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600223 // The unused bits must be zero.
Bob Beck05007562023-08-17 20:22:17 +0000224 BSSL_CHECK(bytes.Length() == 0 ||
225 (bytes[bytes.Length() - 1] & ((1u << unused_bits) - 1)) == 0);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600226}
227
228bool BitString::AssertsBit(size_t bit_index) const {
229 // Index of the byte that contains the bit.
230 size_t byte_index = bit_index / 8;
231
232 // If the bit is outside of the bitstring, by definition it is not
233 // asserted.
Bob Beck6beabf32023-11-21 09:43:52 -0700234 if (byte_index >= bytes_.Length()) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600235 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700236 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600237
238 // Within a byte, bits are ordered from most significant to least significant.
239 // Convert |bit_index| to an index within the |byte_index| byte, measured from
240 // its least significant bit.
241 uint8_t bit_index_in_byte = 7 - (bit_index - byte_index * 8);
242
243 // BIT STRING parsing already guarantees that unused bits in a byte are zero
244 // (otherwise it wouldn't be valid DER). Therefore it isn't necessary to check
245 // |unused_bits_|
Bob Beck05007562023-08-17 20:22:17 +0000246 uint8_t byte = bytes_[byte_index];
Bob Beckbc97b7a2023-04-18 08:35:15 -0600247 return 0 != (byte & (1 << bit_index_in_byte));
248}
249
Bob Beck5c7a2a02023-11-20 17:28:21 -0700250std::optional<BitString> ParseBitString(const Input &in) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600251 ByteReader reader(in);
252
253 // From ITU-T X.690, section 8.6.2.2 (applies to BER, CER, DER):
254 //
255 // The initial octet shall encode, as an unsigned binary integer with
256 // bit 1 as the least significant bit, the number of unused bits in the final
257 // subsequent octet. The number shall be in the range zero to seven.
258 uint8_t unused_bits;
Bob Beck6beabf32023-11-21 09:43:52 -0700259 if (!reader.ReadByte(&unused_bits)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600260 return std::nullopt;
Bob Beck6beabf32023-11-21 09:43:52 -0700261 }
262 if (unused_bits > 7) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600263 return std::nullopt;
Bob Beck6beabf32023-11-21 09:43:52 -0700264 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600265
266 Input bytes;
Bob Beck6beabf32023-11-21 09:43:52 -0700267 if (!reader.ReadBytes(reader.BytesLeft(), &bytes)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600268 return std::nullopt; // Not reachable.
Bob Beck6beabf32023-11-21 09:43:52 -0700269 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600270
271 // Ensure that unused bits in the last byte are set to 0.
272 if (unused_bits > 0) {
273 // From ITU-T X.690, section 8.6.2.3 (applies to BER, CER, DER):
274 //
275 // If the bitstring is empty, there shall be no subsequent octets,
276 // and the initial octet shall be zero.
Bob Beck6beabf32023-11-21 09:43:52 -0700277 if (bytes.Length() == 0) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600278 return std::nullopt;
Bob Beck6beabf32023-11-21 09:43:52 -0700279 }
Bob Beck05007562023-08-17 20:22:17 +0000280 uint8_t last_byte = bytes[bytes.Length() - 1];
Bob Beckbc97b7a2023-04-18 08:35:15 -0600281
282 // From ITU-T X.690, section 11.2.1 (applies to CER and DER, but not BER):
283 //
284 // Each unused bit in the final octet of the encoding of a bit string value
285 // shall be set to zero.
286 uint8_t mask = 0xFF >> (8 - unused_bits);
Bob Beck6beabf32023-11-21 09:43:52 -0700287 if ((mask & last_byte) != 0) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600288 return std::nullopt;
Bob Beck6beabf32023-11-21 09:43:52 -0700289 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600290 }
291
292 return BitString(bytes, unused_bits);
293}
294
295bool GeneralizedTime::InUTCTimeRange() const {
296 return 1950 <= year && year < 2050;
297}
298
Bob Beck5c7a2a02023-11-20 17:28:21 -0700299bool operator<(const GeneralizedTime &lhs, const GeneralizedTime &rhs) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600300 return std::tie(lhs.year, lhs.month, lhs.day, lhs.hours, lhs.minutes,
301 lhs.seconds) < std::tie(rhs.year, rhs.month, rhs.day,
302 rhs.hours, rhs.minutes, rhs.seconds);
303}
304
Bob Beck5c7a2a02023-11-20 17:28:21 -0700305bool operator>(const GeneralizedTime &lhs, const GeneralizedTime &rhs) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600306 return rhs < lhs;
307}
308
Bob Beck5c7a2a02023-11-20 17:28:21 -0700309bool operator<=(const GeneralizedTime &lhs, const GeneralizedTime &rhs) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600310 return !(lhs > rhs);
311}
312
Bob Beck5c7a2a02023-11-20 17:28:21 -0700313bool operator>=(const GeneralizedTime &lhs, const GeneralizedTime &rhs) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600314 return !(lhs < rhs);
315}
316
Bob Beck5c7a2a02023-11-20 17:28:21 -0700317bool ParseUTCTime(const Input &in, GeneralizedTime *value) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600318 ByteReader reader(in);
319 GeneralizedTime time;
320 if (!DecimalStringToUint(reader, 2, &time.year) ||
321 !DecimalStringToUint(reader, 2, &time.month) ||
322 !DecimalStringToUint(reader, 2, &time.day) ||
323 !DecimalStringToUint(reader, 2, &time.hours) ||
324 !DecimalStringToUint(reader, 2, &time.minutes) ||
325 !DecimalStringToUint(reader, 2, &time.seconds)) {
326 return false;
327 }
328 uint8_t zulu;
Bob Beck6beabf32023-11-21 09:43:52 -0700329 if (!reader.ReadByte(&zulu) || zulu != 'Z' || reader.HasMore()) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600330 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700331 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600332 if (time.year < 50) {
333 time.year += 2000;
334 } else {
335 time.year += 1900;
336 }
Bob Beck6beabf32023-11-21 09:43:52 -0700337 if (!ValidateGeneralizedTime(time)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600338 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700339 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600340 *value = time;
341 return true;
342}
343
Bob Beck5c7a2a02023-11-20 17:28:21 -0700344bool ParseGeneralizedTime(const Input &in, GeneralizedTime *value) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600345 ByteReader reader(in);
346 GeneralizedTime time;
347 if (!DecimalStringToUint(reader, 4, &time.year) ||
348 !DecimalStringToUint(reader, 2, &time.month) ||
349 !DecimalStringToUint(reader, 2, &time.day) ||
350 !DecimalStringToUint(reader, 2, &time.hours) ||
351 !DecimalStringToUint(reader, 2, &time.minutes) ||
352 !DecimalStringToUint(reader, 2, &time.seconds)) {
353 return false;
354 }
355 uint8_t zulu;
Bob Beck6beabf32023-11-21 09:43:52 -0700356 if (!reader.ReadByte(&zulu) || zulu != 'Z' || reader.HasMore()) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600357 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700358 }
359 if (!ValidateGeneralizedTime(time)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600360 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700361 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600362 *value = time;
363 return true;
364}
365
Bob Beck5c7a2a02023-11-20 17:28:21 -0700366bool ParseIA5String(Input in, std::string *out) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600367 for (char c : in.AsStringView()) {
Bob Beck6beabf32023-11-21 09:43:52 -0700368 if (static_cast<uint8_t>(c) > 127) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600369 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700370 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600371 }
372 *out = in.AsString();
373 return true;
374}
375
Bob Beck5c7a2a02023-11-20 17:28:21 -0700376bool ParseVisibleString(Input in, std::string *out) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600377 // ITU-T X.680:
378 // VisibleString : "Defining registration number 6" + SPACE
379 // 6 includes all the characters from '!' .. '~' (33 .. 126), space is 32.
380 // Also ITU-T X.691 says it much more clearly:
381 // "for VisibleString [the range] is 32 to 126 ... For VisibleString .. all
382 // the values in the range are present."
383 for (char c : in.AsStringView()) {
Bob Beck6beabf32023-11-21 09:43:52 -0700384 if (static_cast<uint8_t>(c) < 32 || static_cast<uint8_t>(c) > 126) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600385 return false;
Bob Beck6beabf32023-11-21 09:43:52 -0700386 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600387 }
388 *out = in.AsString();
389 return true;
390}
391
Bob Beck5c7a2a02023-11-20 17:28:21 -0700392bool ParsePrintableString(Input in, std::string *out) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600393 for (char c : in.AsStringView()) {
Bob Beck3aecf1d2023-09-08 11:56:02 -0600394 if (!(OPENSSL_isalpha(c) || c == ' ' || (c >= '\'' && c <= ':') ||
Bob Beckbc97b7a2023-04-18 08:35:15 -0600395 c == '=' || c == '?')) {
396 return false;
397 }
398 }
399 *out = in.AsString();
400 return true;
401}
402
Bob Beck5c7a2a02023-11-20 17:28:21 -0700403bool ParseTeletexStringAsLatin1(Input in, std::string *out) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600404 out->clear();
405 // Convert from Latin-1 to UTF-8.
406 size_t utf8_length = in.Length();
407 for (size_t i = 0; i < in.Length(); i++) {
Bob Beck05007562023-08-17 20:22:17 +0000408 if (in[i] > 0x7f) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600409 utf8_length++;
Bob Beck05007562023-08-17 20:22:17 +0000410 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600411 }
412 out->reserve(utf8_length);
413 for (size_t i = 0; i < in.Length(); i++) {
Bob Beck05007562023-08-17 20:22:17 +0000414 uint8_t u = in[i];
Bob Beckbc97b7a2023-04-18 08:35:15 -0600415 if (u <= 0x7f) {
416 out->push_back(u);
417 } else {
418 out->push_back(0xc0 | (u >> 6));
419 out->push_back(0x80 | (u & 0x3f));
420 }
421 }
Bob Beck05007562023-08-17 20:22:17 +0000422 BSSL_CHECK(utf8_length == out->size());
Bob Beckbc97b7a2023-04-18 08:35:15 -0600423 return true;
424}
425
Bob Beck5c7a2a02023-11-20 17:28:21 -0700426bool ParseUniversalString(Input in, std::string *out) {
Bob Beck3aecf1d2023-09-08 11:56:02 -0600427 if (in.Length() % 4 != 0) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600428 return false;
Bob Beckbc97b7a2023-04-18 08:35:15 -0600429 }
Bob Beck3aecf1d2023-09-08 11:56:02 -0600430
431 CBS cbs;
432 CBS_init(&cbs, in.UnsafeData(), in.Length());
433 bssl::ScopedCBB cbb;
434 if (!CBB_init(cbb.get(), in.Length())) {
435 return false;
436 }
437
438 while (CBS_len(&cbs) != 0) {
439 uint32_t c;
440 if (!CBS_get_utf32_be(&cbs, &c) || //
441 !CBB_add_utf8(cbb.get(), c)) {
442 return false;
443 }
444 }
445
446 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600447 return true;
448}
449
Bob Beck5c7a2a02023-11-20 17:28:21 -0700450bool ParseBmpString(Input in, std::string *out) {
Bob Beck3aecf1d2023-09-08 11:56:02 -0600451 if (in.Length() % 2 != 0) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600452 return false;
Bob Beckbc97b7a2023-04-18 08:35:15 -0600453 }
Bob Beck3aecf1d2023-09-08 11:56:02 -0600454
455 CBS cbs;
456 CBS_init(&cbs, in.UnsafeData(), in.Length());
457 bssl::ScopedCBB cbb;
458 if (!CBB_init(cbb.get(), in.Length())) {
459 return false;
460 }
461
462 while (CBS_len(&cbs) != 0) {
463 uint32_t c;
464 if (!CBS_get_ucs2_be(&cbs, &c) || //
465 !CBB_add_utf8(cbb.get(), c)) {
466 return false;
467 }
468 }
469
470 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
Bob Beckbc97b7a2023-04-18 08:35:15 -0600471 return true;
472}
473
474} // namespace bssl::der