mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
In json mode, reveal recovered user password when otherwise unavailable
This commit is contained in:
parent
f049a77c59
commit
b7bbf12e85
@ -1,5 +1,10 @@
|
||||
2022-05-30 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* When showing encryption data in json output, when the user
|
||||
password was recovered with by the owner password and the
|
||||
specified password does not match the user password, reveal the
|
||||
user password. This is not possible with 256-bit keys.
|
||||
|
||||
* Include additional information in --list-attachments --verbose
|
||||
and in --json --json-key=attachments.
|
||||
|
||||
|
2
TODO
2
TODO
@ -70,8 +70,6 @@ Remaining work:
|
||||
|
||||
* --show-xref: add
|
||||
|
||||
* --encryption: show recovered user password when available
|
||||
|
||||
* Consider having --check, --show-encryption, etc., just select the
|
||||
right keys when in json mode. I don't think I want check on by
|
||||
default, so that might be different.
|
||||
|
@ -1382,6 +1382,15 @@ QPDFJob::doJSONEncrypt(Pipeline* p, bool& first, QPDF& pdf)
|
||||
j_encrypt.addDictionaryMember(
|
||||
"ownerpasswordmatched",
|
||||
JSON::makeBool(is_encrypted && pdf.ownerPasswordMatched()));
|
||||
if (is_encrypted && (V < 5) && pdf.ownerPasswordMatched() &&
|
||||
(!pdf.userPasswordMatched())) {
|
||||
std::string user_password = pdf.getTrimmedUserPassword();
|
||||
j_encrypt.addDictionaryMember(
|
||||
"recovereduserpassword", JSON::makeString(user_password));
|
||||
} else {
|
||||
j_encrypt.addDictionaryMember(
|
||||
"recovereduserpassword", JSON::makeNull());
|
||||
}
|
||||
JSON j_capabilities =
|
||||
j_encrypt.addDictionaryMember("capabilities", JSON::makeDictionary());
|
||||
j_capabilities.addDictionaryMember(
|
||||
@ -1669,6 +1678,7 @@ QPDFJob::json_schema(int json_version, std::set<std::string>* keys)
|
||||
},
|
||||
"encrypted": "whether the document is encrypted",
|
||||
"ownerpasswordmatched": "whether supplied password matched owner password; always false for non-encrypted files",
|
||||
"recovereduserpassword": "If the owner password was used to recover the user password, reveal user password; otherwise null",
|
||||
"parameters": {
|
||||
"P": "P value from Encrypt dictionary",
|
||||
"R": "R value from Encrypt dictionary",
|
||||
|
@ -103,6 +103,12 @@ For a detailed list of changes, please see the file
|
||||
attachments is also included in the ``attachments`` json key
|
||||
with ``--json``.
|
||||
|
||||
- For encrypted files, ``qpdf --json`` reveals the user password
|
||||
when the specified password did not match the user password and
|
||||
the owner password was used to recover the user password. The
|
||||
user password is not recoverable from the owner password when
|
||||
256-bit keys are in use.
|
||||
|
||||
- Library Enhancements
|
||||
|
||||
- New methods ``insertItemAndGet``, ``appendItemAndGet``,
|
||||
|
@ -219,6 +219,7 @@ foreach my $d (@encrypted_files)
|
||||
" \"streammethod\": \"---method---\",\n" .
|
||||
" \"stringmethod\": \"---method---\"\n" .
|
||||
" },\n" .
|
||||
" \"recovereduserpassword\": ---rup---,\n" .
|
||||
" \"userpasswordmatched\": ---upm---\n" .
|
||||
" }\n" .
|
||||
"}\n";
|
||||
@ -267,6 +268,8 @@ foreach my $d (@encrypted_files)
|
||||
my $method = $bits == 256 ? "AESv3" : "RC4";
|
||||
my $opm = ($pass eq $opass ? "true" : "false");
|
||||
my $upm = ($pass eq $upass ? "true" : "false");
|
||||
my $rup = (($pass eq $opass) && ($pass ne $upass) && ($V < 5))
|
||||
? "\"$upass\"" : "null";
|
||||
$enc_json =~ s/---R---/$R/;
|
||||
$enc_json =~ s/---P---/$P/;
|
||||
$enc_json =~ s/---V---/$V/;
|
||||
@ -274,6 +277,7 @@ foreach my $d (@encrypted_files)
|
||||
$enc_json =~ s/---method---/$method/g;
|
||||
$enc_json =~ s/---opm---/$opm/;
|
||||
$enc_json =~ s/---upm---/$upm/;
|
||||
$enc_json =~ s/---rup---/$rup/;
|
||||
|
||||
my $eflags = "--allow-weak-crypto" .
|
||||
" -encrypt \"$upass\" \"$opass\" $bits $xeflags --";
|
||||
|
@ -28,6 +28,7 @@
|
||||
"streammethod": "AESv2",
|
||||
"stringmethod": "AESv2"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": true
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
"streammethod": "AESv2",
|
||||
"stringmethod": "AESv2"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": true
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
"streammethod": "AESv2",
|
||||
"stringmethod": "AESv2"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": true
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
"streammethod": "AESv2",
|
||||
"stringmethod": "AESv2"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": true
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -96,6 +96,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -428,6 +428,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -428,6 +428,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -428,6 +428,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -428,6 +428,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -271,6 +271,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -271,6 +271,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -271,6 +271,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -271,6 +271,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -271,6 +271,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -271,6 +271,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -271,6 +271,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -271,6 +271,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -462,6 +462,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [
|
||||
|
@ -462,6 +462,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [
|
||||
|
@ -567,6 +567,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [
|
||||
|
@ -567,6 +567,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [
|
||||
|
@ -637,6 +637,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [
|
||||
|
@ -637,6 +637,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [
|
||||
|
@ -534,6 +534,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
@ -534,6 +534,7 @@
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"recovereduserpassword": null,
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
|
Loading…
Reference in New Issue
Block a user