Skip to content

Commit 26ff0b8

Browse files
authored
base64ct: Don't fail with InvalidLength when reading nothing at end of data (#1716)
* der: pem reader rejects zero lengths reads [tests] Since base64ct 1.7.0 ([#1387]), it now rejects zero lengths reads. This happens to trigger with an sha256WithRSAEncryption AlgorithmIdentifier where the parameters are null. * base64ct: Don't fail with `InvalidLength` when reading nothing at end of data
1 parent 0ebdd64 commit 26ff0b8

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

Diff for: base64ct/src/decoder.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl<'i, E: Encoding> Decoder<'i, E> {
104104
/// - `Ok(bytes)` if the expected amount of data was read
105105
/// - `Err(Error::InvalidLength)` if the exact amount of data couldn't be read
106106
pub fn decode<'o>(&mut self, out: &'o mut [u8]) -> Result<&'o [u8], Error> {
107-
if self.is_finished() {
107+
if self.is_finished() && !out.is_empty() {
108108
return Err(InvalidLength);
109109
}
110110

@@ -591,6 +591,21 @@ mod tests {
591591
assert_eq!(buf.as_slice(), MULTILINE_PADDED_BIN);
592592
}
593593

594+
#[cfg(feature = "std")]
595+
#[test]
596+
fn decode_empty_at_end() {
597+
let mut decoder = Decoder::<Base64>::new(b"AAAA").unwrap();
598+
599+
// Strip initial bytes
600+
let mut buf = vec![0u8; 3];
601+
assert_eq!(decoder.decode(&mut buf), Ok(&vec![0u8; 3][..]));
602+
603+
// Now try to read nothing from the end
604+
let mut buf: Vec<u8> = vec![];
605+
606+
assert_eq!(decoder.decode(&mut buf), Ok(&[][..]));
607+
}
608+
594609
/// Core functionality of a decoding test
595610
#[allow(clippy::arithmetic_side_effects)]
596611
fn decode_test<'a, F, V>(expected: &[u8], f: F)

Diff for: der/tests/pem.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#![cfg(all(feature = "derive", feature = "oid", feature = "pem"))]
44

55
use der::{
6-
Decode, DecodePem, EncodePem, Sequence,
6+
Any, Decode, DecodePem, EncodePem, Sequence,
77
asn1::{BitString, ObjectIdentifier},
88
pem::{LineEnding, PemLabel},
99
};
@@ -15,14 +15,14 @@ const SPKI_DER: &[u8] = include_bytes!("examples/spki.der");
1515
const SPKI_PEM: &str = include_str!("examples/spki.pem");
1616

1717
/// X.509 `AlgorithmIdentifier`
18-
#[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence)]
18+
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
1919
pub struct AlgorithmIdentifier {
2020
pub algorithm: ObjectIdentifier,
21-
// pub parameters: ... (not used in spki.pem)
21+
pub parameters: Option<Any>,
2222
}
2323

2424
/// X.509 `SubjectPublicKeyInfo` (SPKI) in borrowed form
25-
#[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence)]
25+
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
2626
pub struct SpkiBorrowed<'a> {
2727
pub algorithm: AlgorithmIdentifier,
2828
#[asn1(type = "BIT STRING")]
@@ -65,3 +65,17 @@ fn to_pem() {
6565
let pem = spki.to_pem(LineEnding::LF).unwrap();
6666
assert_eq!(&pem, SPKI_PEM);
6767
}
68+
69+
#[test]
70+
fn read_zero_slices_from_pem() {
71+
let spki = SpkiOwned {
72+
algorithm: AlgorithmIdentifier {
73+
algorithm: ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.11"),
74+
parameters: Some(Any::null()),
75+
},
76+
subject_public_key: BitString::new(0, []).unwrap(),
77+
};
78+
79+
let pem = spki.to_pem(LineEnding::LF).unwrap();
80+
SpkiOwned::from_pem(pem).unwrap();
81+
}

0 commit comments

Comments
 (0)