Coverage Report

Created: 2026-09-26 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibCrypto/ASN1/DER.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2021, the SerenityOS developers.
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#include <AK/IntegralMath.h>
8
#include <AK/Math/Rounding.h>
9
#include <AK/Stream.h>
10
#include <AK/Try.h>
11
#include <AK/Utf8View.h>
12
#include <LibCrypto/ASN1/DER.h>
13
14
namespace Crypto::ASN1 {
15
16
ErrorOr<Tag> Decoder::read_tag()
17
118k
{
18
118k
    auto byte = TRY(read_byte());
19
118k
    u8 class_ = byte & 0xc0;
20
118k
    u8 type = byte & 0x20;
21
118k
    u8 kind = byte & 0x1f;
22
23
118k
    if (kind == 0x1f) {
24
2.53k
        kind = 0;
25
9.58k
        while (byte & 0x80) {
26
7.23k
            byte = TRY(read_byte());
27
7.05k
            kind = (kind << 7) | (byte & 0x7f);
28
7.05k
        }
29
2.53k
    }
30
31
118k
    return Tag { (Kind)kind, (Class)class_, (Type)type };
32
118k
}
33
34
ErrorOr<size_t> Decoder::read_length()
35
119k
{
36
119k
    auto byte = TRY(read_byte());
37
118k
    size_t length = byte;
38
39
118k
    if (byte & 0x80) {
40
9.47k
        auto count = byte & 0x7f;
41
9.47k
        if (count == 0x7f)
42
87
            return Error::from_string_literal("ASN1::Decoder: Length has an invalid count value");
43
44
9.38k
        auto data = TRY(read_bytes(count));
45
9.22k
        length = 0;
46
47
9.22k
        if (data.size() > sizeof(size_t))
48
91
            return Error::from_string_literal("ASN1::Decoder: Length is larger than the target type");
49
50
9.13k
        for (auto&& byte : data)
51
18.9k
            length = (length << 8) | (size_t)byte;
52
9.13k
    }
53
54
118k
    return length;
55
118k
}
56
57
ErrorOr<u8> Decoder::read_byte()
58
244k
{
59
244k
    if (m_stack.is_empty())
60
0
        return Error::from_string_literal("ASN1::Decoder: Reading byte from an empty stack");
61
62
244k
    auto& entry = m_stack.last();
63
244k
    if (entry.is_empty())
64
280
        return Error::from_string_literal("ASN1::Decoder: Reading byte from an empty entry");
65
66
244k
    auto byte = entry[0];
67
244k
    entry = entry.slice(1);
68
69
244k
    return byte;
70
244k
}
71
72
ErrorOr<ReadonlyBytes> Decoder::peek_entry_bytes()
73
5.18k
{
74
5.18k
    if (m_stack.is_empty())
75
0
        return Error::from_string_literal("ASN1::Decoder: Reading bytes from an empty stack");
76
77
5.18k
    auto entry = m_stack.last();
78
79
5.18k
    return entry;
80
5.18k
}
81
82
ErrorOr<ReadonlyBytes> Decoder::read_bytes(size_t length)
83
127k
{
84
127k
    if (m_stack.is_empty())
85
0
        return Error::from_string_literal("ASN1::Decoder: Reading bytes from an empty stack");
86
87
127k
    auto& entry = m_stack.last();
88
127k
    if (entry.size() < length)
89
1.45k
        return Error::from_string_literal("ASN1::Decoder: Reading bytes from an empty entry");
90
91
126k
    auto bytes = entry.slice(0, length);
92
126k
    entry = entry.slice(length);
93
94
126k
    return bytes;
95
127k
}
96
97
ErrorOr<bool> Decoder::decode_boolean(ReadonlyBytes data)
98
3.03k
{
99
3.03k
    if (data.size() != 1)
100
152
        return Error::from_string_literal("ASN1::Decoder: Decoding boolean from a non boolean-sized span");
101
102
2.88k
    return data[0] != 0;
103
3.03k
}
104
105
ErrorOr<UnsignedBigInteger> Decoder::decode_arbitrary_sized_integer(ReadonlyBytes data)
106
7.27k
{
107
7.27k
    if (data.size() < 1)
108
83
        return Error::from_string_literal("ASN1::Decoder: Decoding arbitrary sized integer from an empty span");
109
110
7.19k
    if (data.size() > 1
111
4.07k
        && ((data[0] == 0xff && data[1] & 0x80)
112
4.01k
            || (data[0] == 0x00 && !(data[1] & 0x80)))) {
113
107
        return Error::from_string_literal("ASN1::Decoder: Arbitrary sized integer has an invalid format");
114
107
    }
115
116
7.08k
    bool is_negative = data[0] & 0x80;
117
7.08k
    if (is_negative)
118
134
        return Error::from_string_literal("ASN1::Decoder: Decoding a negative unsigned arbitrary sized integer");
119
120
6.95k
    return UnsignedBigInteger::import_data(data.data(), data.size());
121
7.08k
}
122
123
ErrorOr<StringView> Decoder::decode_octet_string(ReadonlyBytes bytes)
124
5.45k
{
125
5.45k
    return StringView { bytes.data(), bytes.size() };
126
5.45k
}
127
128
ErrorOr<nullptr_t> Decoder::decode_null(ReadonlyBytes data)
129
2.30k
{
130
2.30k
    if (data.size() != 0)
131
68
        return Error::from_string_literal("ASN1::Decoder: Decoding null from a non-empty span");
132
133
2.23k
    return nullptr;
134
2.30k
}
135
136
ErrorOr<Vector<int>> Decoder::decode_object_identifier(ReadonlyBytes data)
137
15.8k
{
138
15.8k
    Vector<int> result;
139
15.8k
    result.append(0); // Reserved space.
140
141
15.8k
    u32 value = 0;
142
6.06M
    for (auto&& byte : data) {
143
6.06M
        if (value == 0 && byte == 0x80)
144
54
            return Error::from_string_literal("ASN1::Decoder: Invalid first byte in object identifier");
145
146
6.06M
        value = (value << 7) | (byte & 0x7f);
147
6.06M
        if (!(byte & 0x80)) {
148
5.64M
            result.append(value);
149
5.64M
            value = 0;
150
5.64M
        }
151
6.06M
    }
152
153
15.7k
    if (result.size() == 1 || result[1] >= 1600)
154
288
        return Error::from_string_literal("ASN1::Decoder: Invalid encoding in object identifier");
155
156
15.4k
    result[0] = result[1] / 40;
157
15.4k
    result[1] = result[1] % 40;
158
159
15.4k
    return result;
160
15.7k
}
161
162
ErrorOr<StringView> Decoder::decode_printable_string(ReadonlyBytes data)
163
38.9k
{
164
38.9k
    Utf8View view { data };
165
38.9k
    if (!view.validate())
166
469
        return Error::from_string_literal("ASN1::Decoder: Invalid UTF-8 in printable string");
167
168
38.5k
    return StringView { data };
169
38.9k
}
170
171
ErrorOr<BitStringView> Decoder::decode_bit_string(ReadonlyBytes data)
172
1.71k
{
173
1.71k
    if (data.size() < 1)
174
36
        return Error::from_string_literal("ASN1::Decoder: Decoding bit string from empty span");
175
176
1.67k
    auto unused_bits = data[0];
177
1.67k
    auto total_size_in_bits = (data.size() - 1) * 8;
178
179
1.67k
    if (unused_bits > total_size_in_bits)
180
68
        return Error::from_string_literal("ASN1::Decoder: Number of unused bits is larger than the total size");
181
182
1.61k
    return BitStringView { data.slice(1), unused_bits };
183
1.67k
}
184
185
ErrorOr<Tag> Decoder::peek()
186
205k
{
187
205k
    if (m_stack.is_empty())
188
0
        return Error::from_string_literal("ASN1::Decoder: Peeking using an empty stack");
189
190
205k
    if (eof())
191
515
        return Error::from_string_literal("ASN1::Decoder: Peeking using a decoder that is at EOF");
192
193
204k
    if (m_current_tag.has_value())
194
86.6k
        return m_current_tag.value();
195
196
118k
    m_current_tag = TRY(read_tag());
197
198
118k
    return m_current_tag.value();
199
118k
}
200
201
bool Decoder::eof() const
202
352k
{
203
352k
    return m_stack.is_empty() || m_stack.last().is_empty();
204
352k
}
205
206
ErrorOr<void> Decoder::enter()
207
42.2k
{
208
42.2k
    if (m_stack.is_empty())
209
0
        return Error::from_string_literal("ASN1::Decoder: Entering using an empty stack");
210
211
42.2k
    auto tag = TRY(peek());
212
42.2k
    if (tag.type != Type::Constructed)
213
17
        return Error::from_string_literal("ASN1::Decoder: Entering a non-constructed type");
214
215
42.2k
    auto length = TRY(read_length());
216
217
42.1k
    auto data = TRY(read_bytes(length));
218
219
41.8k
    m_current_tag.clear();
220
221
41.8k
    m_stack.append(data);
222
41.8k
    return {};
223
42.1k
}
224
225
ErrorOr<void> Decoder::leave()
226
31.8k
{
227
31.8k
    if (m_stack.is_empty())
228
0
        return Error::from_string_literal("ASN1::Decoder: Leaving using an empty stack");
229
230
31.8k
    if (m_stack.size() == 1)
231
0
        return Error::from_string_literal("ASN1::Decoder: Leaving the main context");
232
233
31.8k
    m_stack.take_last();
234
31.8k
    m_current_tag.clear();
235
236
31.8k
    return {};
237
31.8k
}
238
239
ErrorOr<void> Encoder::write_tag(Class class_, Type type, Kind kind)
240
0
{
241
0
    auto class_byte = to_underlying(class_);
242
0
    auto type_byte = to_underlying(type);
243
0
    auto kind_byte = to_underlying(kind);
244
245
0
    auto byte = class_byte | type_byte | kind_byte;
246
0
    if (kind_byte > 0x1f) {
247
0
        auto high = kind_byte >> 7;
248
0
        byte = class_byte | type_byte | 0x1f;
249
0
        TRY(write_byte(byte));
250
0
        byte = (kind_byte & 0x7f) | high;
251
0
    }
252
253
0
    return write_byte(byte);
254
0
}
255
256
ErrorOr<void> Encoder::write_byte(u8 byte)
257
0
{
258
0
    return write_bytes({ &byte, 1 });
259
0
}
260
261
ErrorOr<void> Encoder::write_length(size_t value)
262
0
{
263
0
    if (value < 0x80)
264
0
        return write_byte(value);
265
266
0
    double minimum_bits = AK::log2(value);
267
0
    size_t size_in_bits = AK::floor(minimum_bits) + 1;
268
0
    size_t size = ceil_div(size_in_bits, 8uz);
269
0
    TRY(write_byte(0x80 | size));
270
271
0
    for (size_t i = 0; i < size; i++) {
272
0
        auto shift = (size - i - 1) * 8;
273
0
        auto byte = (value >> shift) & 0xff;
274
0
        TRY(write_byte(byte));
275
0
    }
276
277
0
    return {};
278
0
}
279
280
ErrorOr<void> Encoder::write_bytes(ReadonlyBytes bytes)
281
0
{
282
0
    auto output = TRY(m_buffer_stack.last().get_bytes_for_writing(bytes.size()));
283
0
    bytes.copy_to(output);
284
0
    return {};
285
0
}
286
287
ErrorOr<void> Encoder::write_boolean(bool value, Optional<Class> class_override, Optional<Kind> kind_override)
288
0
{
289
0
    auto class_ = class_override.value_or(Class::Universal);
290
0
    auto type = Type::Primitive;
291
0
    auto kind = kind_override.value_or(Kind::Boolean);
292
293
0
    TRY(write_tag(class_, type, kind));
294
0
    TRY(write_length(1));
295
0
    return write_byte(value ? 0xff : 0x00);
296
0
}
297
298
ErrorOr<void> Encoder::write_arbitrary_sized_integer(UnsignedBigInteger const& value, Optional<Class> class_override, Optional<Kind> kind_override)
299
0
{
300
0
    auto class_ = class_override.value_or(Class::Universal);
301
0
    auto type = Type::Primitive;
302
0
    auto kind = kind_override.value_or(Kind::Integer);
303
0
    TRY(write_tag(class_, type, kind));
304
305
0
    auto max_byte_size = max(1ull, value.length() * UnsignedBigInteger::BITS_IN_WORD / 8); // At minimum, we need one byte to encode 0.
306
0
    ByteBuffer buffer;
307
0
    auto output = TRY(buffer.get_bytes_for_writing(max_byte_size));
308
0
    auto size = value.export_data(output);
309
    // DER does not allow empty integers, encode a zero if the exported size is zero.
310
0
    if (size == 0) {
311
0
        output[0] = 0;
312
0
        size = 1;
313
0
    }
314
315
    // Chop off the leading zeros
316
0
    if constexpr (AK::HostIsLittleEndian) {
317
0
        while (size > 1 && output[0] == 0) {
318
0
            size--;
319
0
            output = output.slice(1);
320
0
        }
321
    } else {
322
        while (size > 1 && output[size - 1] == 0)
323
            size--;
324
    }
325
326
    // If the MSB is set, we need to add a leading zero to indicate a positive number.
327
0
    if ((output[0] & 0x80) != 0) {
328
0
        TRY(write_length(size + 1));
329
0
        TRY(write_byte(0));
330
0
    } else {
331
0
        TRY(write_length(size));
332
0
    }
333
0
    return write_bytes(output.slice(0, size));
334
0
}
335
336
ErrorOr<void> Encoder::write_printable_string(StringView string, Optional<Class> class_override, Optional<Kind> kind_override)
337
0
{
338
0
    Utf8View view { string };
339
0
    if (!view.validate())
340
0
        return Error::from_string_literal("ASN1::Encoder: Invalid UTF-8 in printable string");
341
342
0
    auto class_ = class_override.value_or(Class::Universal);
343
0
    auto type = Type::Primitive;
344
0
    auto kind = kind_override.value_or(Kind::PrintableString);
345
346
0
    TRY(write_tag(class_, type, kind));
347
0
    TRY(write_length(string.length()));
348
0
    return write_bytes(string.bytes());
349
0
}
350
351
ErrorOr<void> Encoder::write_octet_string(ReadonlyBytes bytes, Optional<Class> class_override, Optional<Kind> kind_override)
352
0
{
353
0
    auto class_ = class_override.value_or(Class::Universal);
354
0
    auto type = Type::Primitive;
355
0
    auto kind = kind_override.value_or(Kind::OctetString);
356
357
0
    TRY(write_tag(class_, type, kind));
358
0
    TRY(write_length(bytes.size()));
359
0
    return write_bytes(bytes);
360
0
}
361
362
ErrorOr<void> Encoder::write_null(Optional<Class> class_override, Optional<Kind> kind_override)
363
0
{
364
0
    auto class_ = class_override.value_or(Class::Universal);
365
0
    auto type = Type::Primitive;
366
0
    auto kind = kind_override.value_or(Kind::Null);
367
368
0
    TRY(write_tag(class_, type, kind));
369
0
    TRY(write_length(0));
370
0
    return {};
371
0
}
372
373
ErrorOr<void> Encoder::write_object_identifier(Span<int const> segments, Optional<Class> class_override, Optional<Kind> kind_override)
374
0
{
375
0
    auto class_ = class_override.value_or(Class::Universal);
376
0
    auto type = Type::Primitive;
377
0
    auto kind = kind_override.value_or(Kind::ObjectIdentifier);
378
379
0
    if (segments.size() < 2)
380
0
        return Error::from_string_literal("ASN1::Encoder: Object identifier must have at least two segments");
381
382
0
    TRY(write_tag(class_, type, kind));
383
0
    size_t length = 1;
384
0
    for (size_t i = 2; i < segments.size(); i++) {
385
0
        auto segment = segments[i];
386
0
        if (segment < 0)
387
0
            return Error::from_string_literal("ASN1::Encoder: Object identifier segments must be non-negative");
388
389
0
        if (segment < 0x80)
390
0
            length += 1;
391
0
        else if (segment < 0x4000)
392
0
            length += 2;
393
0
        else if (segment < 0x200000)
394
0
            length += 3;
395
0
        else
396
0
            length += 4;
397
0
    }
398
399
0
    TRY(write_length(length));
400
401
0
    auto first_byte = (segments[0] * 40) + segments[1];
402
0
    TRY(write_byte(first_byte));
403
404
0
    for (size_t i = 2; i < segments.size(); i++) {
405
0
        auto segment = segments[i];
406
0
        if (segment < 0x80) {
407
0
            TRY(write_byte(segment));
408
0
        } else if (segment < 0x4000) {
409
0
            TRY(write_byte((segment >> 7) | 0x80));
410
0
            TRY(write_byte(segment & 0x7f));
411
0
        } else if (segment < 0x200000) {
412
0
            TRY(write_byte((segment >> 14) | 0x80));
413
0
            TRY(write_byte(((segment >> 7) & 0x7f) | 0x80));
414
0
            TRY(write_byte(segment & 0x7f));
415
0
        } else {
416
0
            TRY(write_byte((segment >> 21) | 0x80));
417
0
            TRY(write_byte(((segment >> 14) & 0x7f) | 0x80));
418
0
            TRY(write_byte(((segment >> 7) & 0x7f) | 0x80));
419
0
            TRY(write_byte(segment & 0x7f));
420
0
        }
421
0
    }
422
423
0
    return {};
424
0
}
425
426
ErrorOr<void> Encoder::write_bit_string(BitStringView view, Optional<Class> class_override, Optional<Kind> kind_override)
427
0
{
428
0
    auto class_ = class_override.value_or(Class::Universal);
429
0
    auto type = Type::Primitive;
430
0
    auto kind = kind_override.value_or(Kind::BitString);
431
432
0
    auto unused_bits = view.unused_bits();
433
0
    auto total_size_in_bits = view.byte_length() * 8 - unused_bits;
434
435
0
    TRY(write_tag(class_, type, kind));
436
0
    TRY(write_length(ceil_div(total_size_in_bits, 8uz) + 1));
437
0
    TRY(write_byte(unused_bits));
438
0
    return write_bytes(view.underlying_bytes());
439
0
}
440
441
ErrorOr<void> pretty_print(Decoder& decoder, Stream& stream, int indent)
442
0
{
443
0
    while (!decoder.eof()) {
444
0
        auto tag = TRY(decoder.peek());
445
446
0
        StringBuilder builder;
447
0
        for (int i = 0; i < indent; ++i)
448
0
            builder.append(' ');
449
0
        builder.appendff("<{}> ", class_name(tag.class_));
450
0
        if (tag.type == Type::Constructed) {
451
0
            builder.appendff("[{}] {} ({})", type_name(tag.type), to_underlying(tag.kind), kind_name(tag.kind));
452
0
            TRY(decoder.enter());
453
454
0
            builder.append('\n');
455
0
            TRY(stream.write_until_depleted(builder.string_view().bytes()));
456
457
0
            TRY(pretty_print(decoder, stream, indent + 2));
458
459
0
            TRY(decoder.leave());
460
461
0
            continue;
462
0
        } else {
463
0
            if (tag.class_ != Class::Universal)
464
0
                builder.appendff("[{}] {} {}", type_name(tag.type), to_underlying(tag.kind), kind_name(tag.kind));
465
0
            else
466
0
                builder.appendff("[{}] {}", type_name(tag.type), kind_name(tag.kind));
467
0
            switch (tag.kind) {
468
0
            case Kind::Eol: {
469
0
                TRY(decoder.read<ReadonlyBytes>());
470
0
                break;
471
0
            }
472
0
            case Kind::Boolean: {
473
0
                auto value = TRY(decoder.read<bool>());
474
0
                builder.appendff(" {}", value);
475
0
                break;
476
0
            }
477
0
            case Kind::Integer: {
478
0
                auto value = TRY(decoder.read<ReadonlyBytes>());
479
0
                builder.append(" 0x"sv);
480
0
                for (auto ch : value)
481
0
                    builder.appendff("{:0>2x}", ch);
482
0
                break;
483
0
            }
484
0
            case Kind::BitString: {
485
0
                auto value = TRY(decoder.read<BitmapView>());
486
0
                builder.append(" 0b"sv);
487
0
                for (size_t i = 0; i < value.size(); ++i)
488
0
                    builder.append(value.get(i) ? '1' : '0');
489
0
                break;
490
0
            }
491
0
            case Kind::OctetString: {
492
0
                auto value = TRY(decoder.read<StringView>());
493
0
                builder.append(" 0x"sv);
494
0
                for (auto ch : value)
495
0
                    builder.appendff("{:0>2x}", ch);
496
0
                break;
497
0
            }
498
0
            case Kind::Null: {
499
0
                TRY(decoder.read<decltype(nullptr)>());
500
0
                break;
501
0
            }
502
0
            case Kind::ObjectIdentifier: {
503
0
                auto value = TRY(decoder.read<Vector<int>>());
504
0
                for (auto& id : value)
505
0
                    builder.appendff(" {}", id);
506
0
                break;
507
0
            }
508
0
            case Kind::UTCTime:
509
0
            case Kind::GeneralizedTime:
510
0
            case Kind::IA5String:
511
0
            case Kind::VisibleString:
512
0
            case Kind::BMPString:
513
0
            case Kind::PrintableString: {
514
0
                auto value = TRY(decoder.read<StringView>());
515
0
                builder.append(' ');
516
0
                builder.append(value);
517
0
                break;
518
0
            }
519
0
            case Kind::Utf8String: {
520
0
                auto value = TRY(decoder.read<Utf8View>());
521
0
                builder.append(' ');
522
0
                for (auto cp : value)
523
0
                    builder.append_code_point(cp);
524
0
                break;
525
0
            }
526
0
            case Kind::Sequence:
527
0
            case Kind::Set:
528
0
                return Error::from_string_literal("ASN1::Decoder: Unexpected Primitive");
529
0
            default: {
530
0
                dbgln("PrettyPrint error: Unhandled kind {}", to_underlying(tag.kind));
531
0
            }
532
0
            }
533
0
        }
534
535
0
        builder.append('\n');
536
0
        TRY(stream.write_until_depleted(builder.string_view().bytes()));
537
0
    }
538
539
0
    return {};
540
0
}
541
542
}