mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 12:38:12 +00:00
LibPDF: Implement 7.6.4.4.11 Algorithm 12: Authenticating owner password
...for handlers of revision 6. Since this adds U to the hash input, also trim the size of U and O to 48 bytes. The spec requires them to be 48 bytes, but all the newer PDFs on https://cipa.jp/e/std/std-sec.html have 127 bytes -- 48 real bytes and 79 nul padding bytes. These files were created by: Creator: Word 用 Acrobat PDFMaker 17 Producer: Adobe PDF Library 15.0 and Creator: Word 用 Acrobat PDFMaker 17 Producer: Adobe PDF Library 17.11.238
This commit is contained in:
parent
8f6c67a71c
commit
57768325cc
2 changed files with 32 additions and 0 deletions
|
@ -166,6 +166,19 @@ PDFErrorOr<NonnullRefPtr<StandardSecurityHandler>> StandardSecurityHandler::crea
|
|||
if (encryption_dict->contains(CommonNames::EncryptMetadata))
|
||||
encryption_dict->get_value(CommonNames::EncryptMetadata).get<bool>();
|
||||
|
||||
if (v >= 5) {
|
||||
// O and U are 48 bytes for V == 5, but some files pad them with nul bytes to 127 bytes. So trim them, if necessary.
|
||||
if (o.length() > 48)
|
||||
o = o.substring(0, 48);
|
||||
if (u.length() > 48)
|
||||
u = u.substring(0, 48);
|
||||
|
||||
if (o.length() != 48)
|
||||
return Error(Error::Type::Parse, "Invalid O size");
|
||||
if (u.length() != 48)
|
||||
return Error(Error::Type::Parse, "Invalid U size");
|
||||
}
|
||||
|
||||
return adopt_ref(*new StandardSecurityHandler(document, revision, o, u, p, encrypt_metadata, length, method));
|
||||
}
|
||||
|
||||
|
@ -294,6 +307,24 @@ bool StandardSecurityHandler::authenticate_user_password_r6_and_later(StringView
|
|||
return hash == m_u_entry.bytes().trim(32);
|
||||
}
|
||||
|
||||
bool StandardSecurityHandler::authenticate_owner_password_r6_and_later(StringView password)
|
||||
{
|
||||
// ISO 32000 (PDF 2.0), 7.6.4.4.11 Algorithm 12: Authenticating the owner password (Security handlers of
|
||||
// revision 6)
|
||||
|
||||
// a) Test the password against the owner key by computing the 32-byte hash using algorithm 2.B with an
|
||||
// input string consisting of the UTF-8 password concatenated with the 8 bytes of Owner Validation Salt
|
||||
// and the 48 byte U string. If the 32- byte result matches the first 32 bytes of the O string, this is the owner
|
||||
// password.
|
||||
ByteBuffer input;
|
||||
input.append(password.bytes());
|
||||
input.append(m_o_entry.bytes().slice(32, 8)); // See comment in compute_encryption_key_r6_and_later() re "Validation Salt".
|
||||
input.append(m_u_entry.bytes());
|
||||
auto hash = computing_a_hash_r6_and_later(input, password, HashKind::Owner);
|
||||
|
||||
return hash == m_o_entry.bytes().trim(32);
|
||||
}
|
||||
|
||||
bool StandardSecurityHandler::try_provide_user_password(StringView password_string)
|
||||
{
|
||||
bool has_user_password;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue