summarylogtreecommitdiffstats
path: root/rnp-botan-3.13-rsa-padding.patch
blob: 64b77290e5243e598f3faafaf850c8e12594cd62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
From 822838886c6005d5bd1ac8be9ec5679cfa3e5cd0 Mon Sep 17 00:00:00 2001
From: Ronald Tse <ronald.tse@ribose.com>
Date: Mon, 20 Jul 2026 18:04:20 +0800
Subject: [PATCH] Pad short RSA signature/ciphertext to the modulus length.

Botan 3.13 rejects RSA signatures and ciphertexts which are not
exactly the length of the modulus (GH #5592 #5630 #5675), while
OpenPGP MPIs have leading zero bytes stripped, so about 1/256 of
RSA values is encoded one byte shorter.

Left-pad those with zeroes during verification and decryption, the
same way the OpenSSL backend already does for signatures. Also fix
the leading-zero skip in decryption to compare against the modulus
size instead of the exponent size.

Backported from upstream rnp commit 822838886c6005d5bd1ac8be9ec5679cfa3e5cd0
to Thunderbird's vendored copy of rnp.
See https://bugzilla.mozilla.org/show_bug.cgi?id=2068089
---
 comm/third_party/rnp/src/lib/crypto/rsa.cpp | 32 ++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/comm/third_party/rnp/src/lib/crypto/rsa.cpp b/comm/third_party/rnp/src/lib/crypto/rsa.cpp
index 20746df30..bc2ee2dce 100644
--- a/comm/third_party/rnp/src/lib/crypto/rsa.cpp
+++ b/comm/third_party/rnp/src/lib/crypto/rsa.cpp
@@ -125,8 +125,20 @@ Key::verify_pkcs1(const Signature &        sig,

     rnp::botan::op::Verify verify_op;
     if (botan_pk_op_verify_create(&verify_op.get(), rsa_key.get(), pad, 0) ||
-        botan_pk_op_verify_update(verify_op.get(), hash.data(), hash.size()) ||
-        botan_pk_op_verify_finish(verify_op.get(), sig.s.data(), sig.s.size())) {
+        botan_pk_op_verify_update(verify_op.get(), hash.data(), hash.size())) {
+        return RNP_ERROR_SIGNATURE_INVALID;
+    }
+    if (sig.s.size() < n.size()) {
+        /* Botan 3.13+ requires signature to be exactly the length of the modulus, while
+         * OpenPGP MPIs have leading zero bytes stripped. */
+        rnp::secure_bytes padded(n.size() - sig.s.size(), 0);
+        padded.insert(padded.end(), sig.s.data(), sig.s.data() + sig.s.size());
+        if (botan_pk_op_verify_finish(verify_op.get(), padded.data(), padded.size())) {
+            return RNP_ERROR_SIGNATURE_INVALID;
+        }
+        return RNP_SUCCESS;
+    }
+    if (botan_pk_op_verify_finish(verify_op.get(), sig.s.data(), sig.s.size())) {
         return RNP_ERROR_SIGNATURE_INVALID;
     }
     return RNP_SUCCESS;
@@ -184,15 +196,23 @@ Key::decrypt_pkcs1(rnp::RNG &rng, rnp::secure_bytes &out, const Encrypted &in) c
     if (botan_pk_op_decrypt_create(&decrypt_op.get(), rsa_key.get(), "PKCS1v15", 0)) {
         return RNP_ERROR_GENERIC;
     }
-    /* Skip trailing zeroes if any as Botan3 doesn't like m.len > n.len */
+    /* Skip leading zeroes if any as Botan3 doesn't like m.len > n.len */
     size_t skip = 0;
-    while ((in.m.size() - skip > e.size()) && !in.m[skip]) {
+    while ((in.m.size() - skip > n.size()) && !in.m[skip]) {
         skip++;
     }
+    rnp::secure_bytes enc;
+    if (in.m.size() - skip < n.size()) {
+        /* Botan 3.13+ requires ciphertext to be exactly the length of the modulus, while
+         * OpenPGP MPIs have leading zero bytes stripped. */
+        enc.assign(n.size() - (in.m.size() - skip), 0);
+        enc.insert(enc.end(), in.m.data() + skip, in.m.data() + in.m.size());
+    } else {
+        enc.assign(in.m.data() + skip, in.m.data() + in.m.size());
+    }
     out.resize(n.size());
     size_t out_len = out.size();
-    if (botan_pk_op_decrypt(
-          decrypt_op.get(), out.data(), &out_len, in.m.data() + skip, in.m.size() - skip)) {
+    if (botan_pk_op_decrypt(decrypt_op.get(), out.data(), &out_len, enc.data(), enc.size())) {
         out.resize(0);
         return RNP_ERROR_GENERIC;
     }
--
2.51.0