Commit
Author: Dirkjan Ochtman [dirkjan@ochtman.nl]
Hash: 89224dbd9e8b96226d953f4515921d7d972b06dd
Timestamp: Fri, 14 Apr 2023 09:34:54 +0000 (1 year ago)

+22 -20 +/-1 browse
Avoid panicking on invalid RSA key input
1diff --git a/src/common/crypto/ring_impls.rs b/src/common/crypto/ring_impls.rs
2index 284bf1c..dd93c41 100644
3--- a/src/common/crypto/ring_impls.rs
4+++ b/src/common/crypto/ring_impls.rs
5 @@ -139,7 +139,7 @@ impl RsaPublicKey {
6 pub(crate) fn verifying_key_from_bytes(
7 bytes: &[u8],
8 ) -> Result<Box<dyn VerifyingKey + Send + Sync>> {
9- let key = try_strip_rsa_prefix(bytes);
10+ let key = try_strip_rsa_prefix(bytes).unwrap_or(bytes);
11 Ok(Box::new(Self {
12 sha1: UnparsedPublicKey::new(
13 &RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY,
14 @@ -156,43 +156,45 @@ impl RsaPublicKey {
15 /// Try to strip an ASN.1 DER-encoded RSA public key prefix
16 ///
17 /// Returns the original slice if the prefix is not found.
18- fn try_strip_rsa_prefix(bytes: &[u8]) -> &[u8] {
19- let orig = bytes;
20- if bytes[0] != DER_SEQUENCE_TAG {
21- return orig;
22+ fn try_strip_rsa_prefix(bytes: &[u8]) -> Option<&[u8]> {
23+ if *bytes.first()? != DER_SEQUENCE_TAG {
24+ return None;
25 }
26
27- let (_, bytes) = decode_multi_byte_len(&bytes[1..]);
28- if bytes[0] != DER_SEQUENCE_TAG {
29- return orig;
30+ let (_, bytes) = decode_multi_byte_len(&bytes[1..])?;
31+ if *bytes.first()? != DER_SEQUENCE_TAG {
32+ return None;
33 }
34
35- let (byte_len, bytes) = decode_multi_byte_len(&bytes[1..]);
36- if bytes[0] != DER_OBJECT_ID_TAG || byte_len != 13 {
37- return orig;
38+ let (byte_len, bytes) = decode_multi_byte_len(&bytes[1..])?;
39+ if *bytes.first()? != DER_OBJECT_ID_TAG || byte_len != 13 {
40+ return None;
41 }
42
43- let bytes = &bytes[13..]; // skip the RSA encryption OID
44- if bytes[0] != DER_BIT_STRING_TAG {
45- return orig;
46+ let bytes = bytes.get(13..)?; // skip the RSA encryption OID
47+ if *bytes.first()? != DER_BIT_STRING_TAG {
48+ return None;
49 }
50
51- let (_, bytes) = decode_multi_byte_len(&bytes[1..]);
52- &bytes[1..] // skip the unused bits byte
53+ decode_multi_byte_len(&bytes[1..]).and_then(|(_, bytes)| bytes.get(1..)) // skip the unused bits byte
54 }
55
56- fn decode_multi_byte_len(bytes: &[u8]) -> (usize, &[u8]) {
57- if bytes[0] & 0x80 == 0 {
58- return (bytes[0] as usize, &bytes[1..]);
59+ fn decode_multi_byte_len(bytes: &[u8]) -> Option<(usize, &[u8])> {
60+ if bytes.first()? & 0x80 == 0 {
61+ return Some((bytes[0] as usize, &bytes[1..]));
62 }
63
64 let len_len = (bytes[0] & 0x7f) as usize;
65+ if bytes.len() < len_len + 1 {
66+ return None;
67+ }
68+
69 let mut len = 0;
70 for i in 0..len_len {
71 len = (len << 8) | bytes[1 + i] as usize;
72 }
73
74- (len, &bytes[len_len + 1..])
75+ Some((len, &bytes[len_len + 1..]))
76 }
77
78 const DER_OBJECT_ID_TAG: u8 = 0x06;