Coverage Report

Created: 2022-05-20 06:13

/src/serenity/Userland/Libraries/LibCrypto/PK/RSA.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#include <AK/Debug.h>
8
#include <AK/Random.h>
9
#include <AK/ScopeGuard.h>
10
#include <LibCrypto/ASN1/ASN1.h>
11
#include <LibCrypto/ASN1/DER.h>
12
#include <LibCrypto/ASN1/PEM.h>
13
#include <LibCrypto/PK/RSA.h>
14
15
namespace Crypto {
16
namespace PK {
17
18
static constexpr Array<int, 7> pkcs8_rsa_key_oid { 1, 2, 840, 113549, 1, 1, 1 };
19
20
RSA::KeyPairType RSA::parse_rsa_key(ReadonlyBytes der)
21
28
{
22
    // we are going to assign to at least one of these
23
28
    KeyPairType keypair;
24
25
28
    ASN1::Decoder decoder(der);
26
    // There are four possible (supported) formats:
27
    // PKCS#1 private key
28
    // PKCS#1 public key
29
    // PKCS#8 private key
30
    // PKCS#8 public key
31
32
    // They're all a single sequence, so let's check that first
33
28
    {
34
28
        auto result = decoder.peek();
35
28
        if (result.is_error()) {
36
            // Bad data.
37
2
            dbgln_if(RSA_PARSE_DEBUG, "RSA key parse failed: {}", result.error());
38
2
            return keypair;
39
2
        }
40
26
        auto tag = result.value();
41
26
        if (tag.kind != ASN1::Kind::Sequence) {
42
6
            dbgln_if(RSA_PARSE_DEBUG, "RSA key parse failed: Expected a Sequence but got {}", ASN1::kind_name(tag.kind));
43
6
            return keypair;
44
6
        }
45
26
    }
46
47
    // Then enter the sequence
48
20
    {
49
20
        auto error = decoder.enter();
50
20
        if (error.has_value()) {
51
            // Something was weird with the input.
52
1
            dbgln_if(RSA_PARSE_DEBUG, "RSA key parse failed: {}", error.value());
53
1
            return keypair;
54
1
        }
55
20
    }
56
57
19
    bool has_read_error = false;
58
59
19
    auto const check_if_pkcs8_rsa_key = [&] {
60
        // see if it's a sequence:
61
19
        auto tag_result = decoder.peek();
62
19
        if (tag_result.is_error()) {
63
            // Decode error :shrug:
64
1
            dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#8 public key parse failed: {}", tag_result.error());
65
1
            return false;
66
1
        }
67
68
18
        auto tag = tag_result.value();
69
18
        if (tag.kind != ASN1::Kind::Sequence) {
70
            // We don't know what this is, but it sure isn't a PKCS#8 key.
71
9
            dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#8 public key parse failed: Expected a Sequence but got {}", ASN1::kind_name(tag.kind));
72
9
            return false;
73
9
        }
74
75
        // It's a sequence, now let's see if it's actually an RSA key.
76
9
        auto error = decoder.enter();
77
9
        if (error.has_value()) {
78
            // Shenanigans!
79
1
            dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#8 public key parse failed: {}", error.value());
80
1
            return false;
81
1
        }
82
83
8
        ScopeGuard leave { [&] {
84
8
            auto error = decoder.leave();
85
8
            if (error.has_value()) {
86
0
                dbgln_if(RSA_PARSE_DEBUG, "RSA key parse failed: {}", error.value());
87
0
                has_read_error = true;
88
0
            }
89
8
        } };
90
91
        // Now let's read the OID.
92
8
        auto oid_result = decoder.read<Vector<int>>();
93
8
        if (oid_result.is_error()) {
94
8
            dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#8 public key parse failed: {}", oid_result.error());
95
8
            return false;
96
8
        }
97
98
0
        auto oid = oid_result.release_value();
99
        // Now let's check that the OID matches "RSA key"
100
0
        if (oid != pkcs8_rsa_key_oid) {
101
            // Oh well. not an RSA key at all.
102
0
            dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#8 public key parse failed: Not an RSA key");
103
0
            return false;
104
0
        }
105
106
0
        return true;
107
0
    };
108
109
19
    auto integer_result = decoder.read<UnsignedBigInteger>();
110
111
19
    if (!integer_result.is_error()) {
112
0
        auto first_integer = integer_result.release_value();
113
114
        // It's either a PKCS#1 key, or a PKCS#8 private key.
115
        // Check for the PKCS#8 private key right away.
116
0
        if (check_if_pkcs8_rsa_key()) {
117
0
            if (has_read_error)
118
0
                return keypair;
119
            // Now read the private key, which is actually an octet string containing the PKCS#1 encoded private key.
120
0
            auto data_result = decoder.read<StringView>();
121
0
            if (data_result.is_error()) {
122
0
                dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#8 private key parse failed: {}", data_result.error());
123
0
                return keypair;
124
0
            }
125
0
            return parse_rsa_key(data_result.value().bytes());
126
0
        }
127
128
0
        if (has_read_error)
129
0
            return keypair;
130
131
        // It's not a PKCS#8 key, so it's a PKCS#1 key (or something we don't support)
132
        // if the first integer is zero or one, it's a private key.
133
0
        if (first_integer == 0) {
134
            // This is a private key, parse the rest.
135
0
            auto modulus_result = decoder.read<UnsignedBigInteger>();
136
0
            if (modulus_result.is_error()) {
137
0
                dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#1 private key parse failed: {}", modulus_result.error());
138
0
                return keypair;
139
0
            }
140
0
            auto modulus = modulus_result.release_value();
141
142
0
            auto public_exponent_result = decoder.read<UnsignedBigInteger>();
143
0
            if (public_exponent_result.is_error()) {
144
0
                dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#1 private key parse failed: {}", public_exponent_result.error());
145
0
                return keypair;
146
0
            }
147
0
            auto public_exponent = public_exponent_result.release_value();
148
149
0
            auto private_exponent_result = decoder.read<UnsignedBigInteger>();
150
0
            if (private_exponent_result.is_error()) {
151
0
                dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#1 private key parse failed: {}", private_exponent_result.error());
152
0
                return keypair;
153
0
            }
154
0
            auto private_exponent = private_exponent_result.release_value();
155
156
            // Drop the rest of the fields on the floor, we don't use them.
157
            // FIXME: Actually use them...
158
0
            keypair.private_key = { modulus, move(private_exponent), public_exponent };
159
0
            keypair.public_key = { move(modulus), move(public_exponent) };
160
161
0
            return keypair;
162
0
        } else if (first_integer == 1) {
163
            // This is a multi-prime key, we don't support that.
164
0
            dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#1 private key parse failed: Multi-prime key not supported");
165
0
            return keypair;
166
0
        } else {
167
0
            auto&& modulus = move(first_integer);
168
169
            // Try reading a public key, `first_integer` is the modulus.
170
0
            auto public_exponent_result = decoder.read<UnsignedBigInteger>();
171
0
            if (public_exponent_result.is_error()) {
172
                // Bad public key.
173
0
                dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#1 public key parse failed: {}", public_exponent_result.error());
174
0
                return keypair;
175
0
            }
176
177
0
            auto public_exponent = public_exponent_result.release_value();
178
0
            keypair.public_key.set(move(modulus), move(public_exponent));
179
180
0
            return keypair;
181
0
        }
182
183
19
    } else {
184
        // It wasn't a PKCS#1 key, let's try our luck with PKCS#8.
185
19
        if (!check_if_pkcs8_rsa_key())
186
19
            return keypair;
187
188
0
        if (has_read_error)
189
0
            return keypair;
190
191
        // Now we have a bit string, which contains the PKCS#1 encoded public key.
192
0
        auto data_result = decoder.read<BitmapView>();
193
0
        if (data_result.is_error()) {
194
0
            dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#8 public key parse failed: {}", data_result.error());
195
0
            return keypair;
196
0
        }
197
198
        // Now just read it as a PKCS#1 DER.
199
0
        auto data = data_result.release_value();
200
        // FIXME: This is pretty awkward, maybe just generate a zero'd out ByteBuffer from the parser instead?
201
0
        auto padded_data_result = ByteBuffer::create_zeroed(data.size_in_bytes());
202
0
        if (padded_data_result.is_error()) {
203
0
            dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#1 key parse failed: Not enough memory");
204
0
            return keypair;
205
0
        }
206
0
        auto padded_data = padded_data_result.release_value();
207
0
        padded_data.overwrite(0, data.data(), data.size_in_bytes());
208
209
0
        return parse_rsa_key(padded_data.bytes());
210
0
    }
211
19
}
212
213
void RSA::encrypt(ReadonlyBytes in, Bytes& out)
214
0
{
215
0
    dbgln_if(CRYPTO_DEBUG, "in size: {}", in.size());
216
0
    auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
217
0
    if (!(in_integer < m_public_key.modulus())) {
218
0
        dbgln("value too large for key");
219
0
        out = {};
220
0
        return;
221
0
    }
222
0
    auto exp = NumberTheory::ModularPower(in_integer, m_public_key.public_exponent(), m_public_key.modulus());
223
0
    auto size = exp.export_data(out);
224
0
    auto outsize = out.size();
225
0
    if (size != outsize) {
226
0
        dbgln("POSSIBLE RSA BUG!!! Size mismatch: {} requested but {} bytes generated", outsize, size);
227
0
        out = out.slice(outsize - size, size);
228
0
    }
229
0
}
230
231
void RSA::decrypt(ReadonlyBytes in, Bytes& out)
232
0
{
233
    // FIXME: Actually use the private key properly
234
235
0
    auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
236
0
    auto exp = NumberTheory::ModularPower(in_integer, m_private_key.private_exponent(), m_private_key.modulus());
237
0
    auto size = exp.export_data(out);
238
239
0
    auto align = m_private_key.length();
240
0
    auto aligned_size = (size + align - 1) / align * align;
241
242
0
    for (auto i = size; i < aligned_size; ++i)
243
0
        out[out.size() - i - 1] = 0; // zero the non-aligned values
244
0
    out = out.slice(out.size() - aligned_size, aligned_size);
245
0
}
246
247
void RSA::sign(ReadonlyBytes in, Bytes& out)
248
0
{
249
0
    auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
250
0
    auto exp = NumberTheory::ModularPower(in_integer, m_private_key.private_exponent(), m_private_key.modulus());
251
0
    auto size = exp.export_data(out);
252
0
    out = out.slice(out.size() - size, size);
253
0
}
254
255
void RSA::verify(ReadonlyBytes in, Bytes& out)
256
0
{
257
0
    auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size());
258
0
    auto exp = NumberTheory::ModularPower(in_integer, m_public_key.public_exponent(), m_public_key.modulus());
259
0
    auto size = exp.export_data(out);
260
0
    out = out.slice(out.size() - size, size);
261
0
}
262
263
void RSA::import_private_key(ReadonlyBytes bytes, bool pem)
264
0
{
265
0
    ByteBuffer buffer;
266
0
    if (pem) {
267
0
        buffer = decode_pem(bytes);
268
0
        bytes = buffer;
269
0
    }
270
271
0
    auto key = parse_rsa_key(bytes);
272
0
    if (!key.private_key.length()) {
273
0
        dbgln("We expected to see a private key, but we found none");
274
0
        VERIFY_NOT_REACHED();
275
0
    }
276
0
    m_private_key = key.private_key;
277
0
}
278
279
void RSA::import_public_key(ReadonlyBytes bytes, bool pem)
280
0
{
281
0
    ByteBuffer buffer;
282
0
    if (pem) {
283
0
        buffer = decode_pem(bytes);
284
0
        bytes = buffer;
285
0
    }
286
287
0
    auto key = parse_rsa_key(bytes);
288
0
    if (!key.public_key.length()) {
289
0
        dbgln("We expected to see a public key, but we found none");
290
0
        VERIFY_NOT_REACHED();
291
0
    }
292
0
    m_public_key = key.public_key;
293
0
}
294
295
template<typename HashFunction>
296
void RSA_EMSA_PSS<HashFunction>::sign(ReadonlyBytes in, Bytes& out)
297
{
298
    // -- encode via EMSA_PSS
299
    auto mod_bits = m_rsa.private_key().modulus().trimmed_length() * sizeof(u32) * 8;
300
301
    Vector<u8, 2048> EM;
302
    EM.resize(mod_bits);
303
    auto EM_buf = Bytes { EM };
304
    m_emsa_pss.encode(in, EM_buf, mod_bits - 1);
305
306
    // -- sign via RSA
307
    m_rsa.sign(EM_buf, out);
308
}
309
310
template<typename HashFunction>
311
VerificationConsistency RSA_EMSA_PSS<HashFunction>::verify(ReadonlyBytes in)
312
{
313
    auto mod_bytes = m_rsa.public_key().modulus().trimmed_length() * sizeof(u32);
314
    if (in.size() != mod_bytes)
315
        return VerificationConsistency::Inconsistent;
316
317
    Vector<u8, 256> EM;
318
    EM.resize(mod_bytes);
319
    auto EM_buf = Bytes { EM };
320
321
    // -- verify via RSA
322
    m_rsa.verify(in, EM_buf);
323
324
    // -- verify via EMSA_PSS
325
    return m_emsa_pss.verify(in, EM, mod_bytes * 8 - 1);
326
}
327
328
void RSA_PKCS1_EME::encrypt(ReadonlyBytes in, Bytes& out)
329
0
{
330
0
    auto mod_len = (m_public_key.modulus().trimmed_length() * sizeof(u32) * 8 + 7) / 8;
331
0
    dbgln_if(CRYPTO_DEBUG, "key size: {}", mod_len);
332
0
    if (in.size() > mod_len - 11) {
333
0
        dbgln("message too long :(");
334
0
        out = out.trim(0);
335
0
        return;
336
0
    }
337
0
    if (out.size() < mod_len) {
338
0
        dbgln("output buffer too small");
339
0
        return;
340
0
    }
341
342
0
    auto ps_length = mod_len - in.size() - 3;
343
0
    Vector<u8, 8096> ps;
344
0
    ps.resize(ps_length);
345
346
0
    fill_with_random(ps.data(), ps_length);
347
    // since fill_with_random can create zeros (shocking!)
348
    // we have to go through and un-zero the zeros
349
0
    for (size_t i = 0; i < ps_length; ++i)
350
0
        while (!ps[i])
351
0
            fill_with_random(ps.span().offset(i), 1);
352
353
0
    u8 paddings[] { 0x00, 0x02 };
354
355
0
    out.overwrite(0, paddings, 2);
356
0
    out.overwrite(2, ps.data(), ps_length);
357
0
    out.overwrite(2 + ps_length, paddings, 1);
358
0
    out.overwrite(3 + ps_length, in.data(), in.size());
359
0
    out = out.trim(3 + ps_length + in.size()); // should be a single block
360
361
0
    dbgln_if(CRYPTO_DEBUG, "padded output size: {} buffer size: {}", 3 + ps_length + in.size(), out.size());
362
363
0
    RSA::encrypt(out, out);
364
0
}
365
void RSA_PKCS1_EME::decrypt(ReadonlyBytes in, Bytes& out)
366
0
{
367
0
    auto mod_len = (m_public_key.modulus().trimmed_length() * sizeof(u32) * 8 + 7) / 8;
368
0
    if (in.size() != mod_len) {
369
0
        dbgln("decryption error: wrong amount of data: {}", in.size());
370
0
        out = out.trim(0);
371
0
        return;
372
0
    }
373
374
0
    RSA::decrypt(in, out);
375
376
0
    if (out.size() < RSA::output_size()) {
377
0
        dbgln("decryption error: not enough data after decryption: {}", out.size());
378
0
        out = out.trim(0);
379
0
        return;
380
0
    }
381
382
0
    if (out[0] != 0x00) {
383
0
        dbgln("invalid padding byte 0 : {}", out[0]);
384
0
        return;
385
0
    }
386
387
0
    if (out[1] != 0x02) {
388
0
        dbgln("invalid padding byte 1 : {}", out[1]);
389
0
        return;
390
0
    }
391
392
0
    size_t offset = 2;
393
0
    while (offset < out.size() && out[offset])
394
0
        ++offset;
395
396
0
    if (offset == out.size()) {
397
0
        dbgln("garbage data, no zero to split padding");
398
0
        return;
399
0
    }
400
401
0
    ++offset;
402
403
0
    if (offset - 3 < 8) {
404
0
        dbgln("PS too small");
405
0
        return;
406
0
    }
407
408
0
    out = out.slice(offset, out.size() - offset);
409
0
}
410
411
void RSA_PKCS1_EME::sign(ReadonlyBytes, Bytes&)
412
0
{
413
0
    dbgln("FIXME: RSA_PKCS_EME::sign");
414
0
}
415
void RSA_PKCS1_EME::verify(ReadonlyBytes, Bytes&)
416
0
{
417
0
    dbgln("FIXME: RSA_PKCS_EME::verify");
418
0
}
419
}
420
}