mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-13 22:12:12 +00:00
hayro-syntax: refuse a legacy encryption key length above 128 bits instead of panicking (#817)
Port of pdfcraft #1882 (344ba9f8). Revisions 2-4 take the file key from a 16-byte MD5 hash; /V 2 /R 3 /Length 256 sliced past it and panicked on open.
This commit is contained in:
1 parent
cc6106c56a
commit
9eee29b69d
3 files changed
+23
-2
No files matched your search
Vendored
+7
@@ -377,3 +377,10 @@ comments label them `Craft patch (flatten)`.
|
||||
| hayro-interpret `color.rs` | `color::InkSpace`, `ColorSpace::ink_space` and `ColorSpace::ink_values`: how a space's colors are kept as inks (gray, CMYK, its colorants, `All`, `None`) and colors converted in batches, process color as `Color::ink_paint` converts it. `ColorSpace::components`; `ColorSpace::is_device_cmyk` and `ColorSpace::spot_alternate` public |
|
||||
| hayro-interpret `types.rs`, `x_object.rs` | `RasterImage::with_inks`: an image's samples in its own space's inks (`InkImage`), `/Decode` and `/Matte` applied, transfer functions left out, with its alpha at the alpha's own size |
|
||||
| hayro-interpret `interpret/mod.rs` | The `sh` operator drops the shading's `/Background`, which only a shading pattern paints (ISO 32000-2 §8.7.4.5.1) |
|
||||
|
||||
Legacy encryption key length, ported from [PdfCraft #1882](https://github.com/storytold/pdfcraft/pull/1882)
|
||||
(commit 344ba9f8, marked `PdfCraft patch` in `hayro-syntax/src/crypto/mod.rs`): an encryption
|
||||
dictionary of revision 2–4 whose `/Length` is above 128 bits is refused with `InvalidEncryption`.
|
||||
Those revisions take the file key from a 16-byte MD5 hash, so `/V 2 /R 3 /Length 256` sliced past
|
||||
the hash and panicked on open. Test:
|
||||
`crypto::pdfcraft_password_tests::legacy_key_length_above_128_bits_is_refused_not_a_panic`.
|
||||
Vendored
+1
-1
@@ -98,7 +98,7 @@
|
||||
"path": "src/crypto/mod.rs",
|
||||
"source_sha256": "6fca01cee7e67f3aaf435101b7ea98fa4fe23f807eadeaec63ee1c2ece759189",
|
||||
"source_git_blob": "15371514c10dc993b335edfec19a3f989b497954",
|
||||
"sha256": "6fca01cee7e67f3aaf435101b7ea98fa4fe23f807eadeaec63ee1c2ece759189"
|
||||
"sha256": "9e0fc0edf48217b01acfcf7bcd3ebe0673f225f0c3857bf887efd0b0f31a74b2"
|
||||
},
|
||||
{
|
||||
"path": "src/crypto/rc4.rs",
|
||||
|
||||
+15
-1
@@ -145,7 +145,9 @@ pub(crate) fn get(
|
||||
};
|
||||
|
||||
let byte_length = length / 8;
|
||||
if byte_length == 0 {
|
||||
// PdfCraft patch: revisions 2-4 derive an RC4 or AES-128 key from a 16-byte MD5 hash, so
|
||||
// a longer /Length is malformed (and would slice past the end of the hash).
|
||||
if byte_length == 0 || (revision <= 4 && byte_length > 16) {
|
||||
return Err(InvalidEncryption);
|
||||
}
|
||||
|
||||
@@ -902,4 +904,16 @@ mod pdfcraft_password_tests {
|
||||
assert_eq!(unlock(&user, "cafe\u{301}"), ok, "R6");
|
||||
assert_eq!(unlock(&user, "cafe"), wrong, "R6");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "std")]
|
||||
fn legacy_key_length_above_128_bits_is_refused_not_a_panic() {
|
||||
use crate::reader::{Reader, ReaderContext, ReaderExt};
|
||||
let hex32 = "00".repeat(32);
|
||||
for (length, expected) in [(128, DecryptionError::PasswordProtected), (256, InvalidEncryption)] {
|
||||
let dict = format!("<< /Filter /Standard /V 2 /R 3 /Length {length} /P -4 /O <{hex32}> /U <{hex32}> >>");
|
||||
let dict = Reader::new(dict.as_bytes()).read_with_context::<Dict<'_>>(&ReaderContext::dummy());
|
||||
assert_eq!(get(&dict.unwrap(), b"", b"").err(), Some(expected), "/Length {length}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user