mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-02 22:50:20 +00:00
Add encrypt key to json
This commit is contained in:
parent
656d7bc006
commit
12777a04ca
@ -1,5 +1,9 @@
|
||||
2020-01-26 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Add "encrypt" key to the json output. This contains largely the
|
||||
same information as given by --show-encryption but in a
|
||||
consistent, parseable format.
|
||||
|
||||
* Add options --is-encrypted and --requires-password. These can be
|
||||
used with files, including encrypted files with unknown passwords,
|
||||
to determine whether or not a file is encrypted and whether a
|
||||
|
@ -4725,6 +4725,18 @@ print "\n";
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Added <literal>encrypt</literal> key to JSON options. With
|
||||
the exception of the reconstructed user password for older
|
||||
encryption formats, this provides the same information as
|
||||
<option>--show-encryption</option> but in a consistent,
|
||||
parseable format. See output of <command>qpdf
|
||||
--json-help</command> for details.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
|
189
qpdf/qpdf.cc
189
qpdf/qpdf.cc
@ -564,6 +564,83 @@ static JSON json_schema(std::set<std::string>* keys = 0)
|
||||
"annotation flags from /F --"
|
||||
" see pdf_annotation_flag_e in qpdf/Constants.h"));
|
||||
}
|
||||
if (all_keys || keys->count("encrypt"))
|
||||
{
|
||||
JSON encrypt = schema.addDictionaryMember(
|
||||
"encrypt", JSON::makeDictionary());
|
||||
encrypt.addDictionaryMember(
|
||||
"encrypted",
|
||||
JSON::makeString("whether the document is encrypted"));
|
||||
encrypt.addDictionaryMember(
|
||||
"userpasswordmatched",
|
||||
JSON::makeString("whether supplied password matched user password;"
|
||||
" always false for non-encrypted files"));
|
||||
encrypt.addDictionaryMember(
|
||||
"ownerpasswordmatched",
|
||||
JSON::makeString("whether supplied password matched owner password;"
|
||||
" always false for non-encrypted files"));
|
||||
JSON capabilities = encrypt.addDictionaryMember(
|
||||
"capabilities", JSON::makeDictionary());
|
||||
capabilities.addDictionaryMember(
|
||||
"accessibility",
|
||||
JSON::makeString("allow extraction for accessibility?"));
|
||||
capabilities.addDictionaryMember(
|
||||
"extract",
|
||||
JSON::makeString("allow extraction?"));
|
||||
capabilities.addDictionaryMember(
|
||||
"printlow",
|
||||
JSON::makeString("allow low resolution printing?"));
|
||||
capabilities.addDictionaryMember(
|
||||
"printhigh",
|
||||
JSON::makeString("allow high resolution printing?"));
|
||||
capabilities.addDictionaryMember(
|
||||
"modifyassembly",
|
||||
JSON::makeString("allow modifying document assembly?"));
|
||||
capabilities.addDictionaryMember(
|
||||
"modifyforms",
|
||||
JSON::makeString("allow modifying forms?"));
|
||||
capabilities.addDictionaryMember(
|
||||
"moddifyannotations",
|
||||
JSON::makeString("allow modifying annotations?"));
|
||||
capabilities.addDictionaryMember(
|
||||
"modifyother",
|
||||
JSON::makeString("allow other modifications?"));
|
||||
capabilities.addDictionaryMember(
|
||||
"modify",
|
||||
JSON::makeString("allow all modifications?"));
|
||||
|
||||
JSON parameters = encrypt.addDictionaryMember(
|
||||
"parameters", JSON::makeDictionary());
|
||||
parameters.addDictionaryMember(
|
||||
"R",
|
||||
JSON::makeString("R value from Encrypt dictionary"));
|
||||
parameters.addDictionaryMember(
|
||||
"V",
|
||||
JSON::makeString("V value from Encrypt dictionary"));
|
||||
parameters.addDictionaryMember(
|
||||
"P",
|
||||
JSON::makeString("P value from Encrypt dictionary"));
|
||||
parameters.addDictionaryMember(
|
||||
"bits",
|
||||
JSON::makeString("encryption key bit length"));
|
||||
parameters.addDictionaryMember(
|
||||
"key",
|
||||
JSON::makeString("encryption key; will be null"
|
||||
" unless --show-encryption-key was specified"));
|
||||
parameters.addDictionaryMember(
|
||||
"method",
|
||||
JSON::makeString("overall encryption method:"
|
||||
" none, mixed, RC4, AESv2, AESv3"));
|
||||
parameters.addDictionaryMember(
|
||||
"streammethod",
|
||||
JSON::makeString("encryption method for streams"));
|
||||
parameters.addDictionaryMember(
|
||||
"stringmethod",
|
||||
JSON::makeString("encryption method for string"));
|
||||
parameters.addDictionaryMember(
|
||||
"filemethod",
|
||||
JSON::makeString("encryption method for attachments"));
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
|
||||
@ -936,7 +1013,8 @@ ArgParser::initOptionTable()
|
||||
// The list of selectable top-level keys id duplicated in three
|
||||
// places: json_schema, do_json, and initOptionTable.
|
||||
char const* json_key_choices[] = {
|
||||
"objects", "pages", "pagelabels", "outlines", "acroform", 0};
|
||||
"objects", "pages", "pagelabels", "outlines", "acroform",
|
||||
"encrypt", 0};
|
||||
(*t)["json-key"] = oe_requiredChoices(
|
||||
&ArgParser::argJsonKey, json_key_choices);
|
||||
(*t)["json-object"] = oe_requiredParameter(
|
||||
@ -1568,8 +1646,11 @@ ArgParser::argJsonHelp()
|
||||
<< std::endl
|
||||
<< "specify a subset of top-level keys when you invoke qpdf, but the \"version\""
|
||||
<< std::endl
|
||||
<< "and \"parameters\" keys will always be present."
|
||||
<< "and \"parameters\" keys will always be present. Note that the \"encrypt\""
|
||||
<< std::endl
|
||||
<< "key's values will be populated for non-encrypted files. Some values will"
|
||||
<< std::endl
|
||||
<< "be null, and others will have values that apply to unencrypted files."
|
||||
<< std::endl
|
||||
<< json_schema().unparse()
|
||||
<< std::endl;
|
||||
@ -3817,6 +3898,106 @@ static void do_json_acroform(QPDF& pdf, Options& o, JSON& j)
|
||||
}
|
||||
}
|
||||
|
||||
static void do_json_encrypt(QPDF& pdf, Options& o, JSON& j)
|
||||
{
|
||||
int R = 0;
|
||||
int P = 0;
|
||||
int V = 0;
|
||||
QPDF::encryption_method_e stream_method = QPDF::e_none;
|
||||
QPDF::encryption_method_e string_method = QPDF::e_none;
|
||||
QPDF::encryption_method_e file_method = QPDF::e_none;
|
||||
bool is_encrypted = pdf.isEncrypted(
|
||||
R, P, V, stream_method, string_method, file_method);
|
||||
JSON j_encrypt = j.addDictionaryMember(
|
||||
"encrypt", JSON::makeDictionary());
|
||||
j_encrypt.addDictionaryMember(
|
||||
"encrypted",
|
||||
JSON::makeBool(is_encrypted));
|
||||
j_encrypt.addDictionaryMember(
|
||||
"userpasswordmatched",
|
||||
JSON::makeBool(is_encrypted && pdf.userPasswordMatched()));
|
||||
j_encrypt.addDictionaryMember(
|
||||
"ownerpasswordmatched",
|
||||
JSON::makeBool(is_encrypted && pdf.ownerPasswordMatched()));
|
||||
JSON j_capabilities = j_encrypt.addDictionaryMember(
|
||||
"capabilities", JSON::makeDictionary());
|
||||
j_capabilities.addDictionaryMember(
|
||||
"accessibility",
|
||||
JSON::makeBool(pdf.allowAccessibility()));
|
||||
j_capabilities.addDictionaryMember(
|
||||
"extract",
|
||||
JSON::makeBool(pdf.allowExtractAll()));
|
||||
j_capabilities.addDictionaryMember(
|
||||
"printlow",
|
||||
JSON::makeBool(pdf.allowPrintLowRes()));
|
||||
j_capabilities.addDictionaryMember(
|
||||
"printhigh",
|
||||
JSON::makeBool(pdf.allowPrintHighRes()));
|
||||
j_capabilities.addDictionaryMember(
|
||||
"modifyassembly",
|
||||
JSON::makeBool(pdf.allowModifyAssembly()));
|
||||
j_capabilities.addDictionaryMember(
|
||||
"modifyforms",
|
||||
JSON::makeBool(pdf.allowModifyForm()));
|
||||
j_capabilities.addDictionaryMember(
|
||||
"moddifyannotations",
|
||||
JSON::makeBool(pdf.allowModifyAnnotation()));
|
||||
j_capabilities.addDictionaryMember(
|
||||
"modifyother",
|
||||
JSON::makeBool(pdf.allowModifyOther()));
|
||||
j_capabilities.addDictionaryMember(
|
||||
"modify",
|
||||
JSON::makeBool(pdf.allowModifyAll()));
|
||||
JSON j_parameters = j_encrypt.addDictionaryMember(
|
||||
"parameters", JSON::makeDictionary());
|
||||
j_parameters.addDictionaryMember("R", JSON::makeInt(R));
|
||||
j_parameters.addDictionaryMember("V", JSON::makeInt(V));
|
||||
j_parameters.addDictionaryMember("P", JSON::makeInt(P));
|
||||
int bits = 0;
|
||||
JSON key = JSON::makeNull();
|
||||
if (is_encrypted)
|
||||
{
|
||||
std::string encryption_key = pdf.getEncryptionKey();
|
||||
bits = QIntC::to_int(encryption_key.length() * 8);
|
||||
if (o.show_encryption_key)
|
||||
{
|
||||
key = JSON::makeString(QUtil::hex_encode(encryption_key));
|
||||
}
|
||||
}
|
||||
j_parameters.addDictionaryMember("bits", JSON::makeInt(bits));
|
||||
j_parameters.addDictionaryMember("key", key);
|
||||
auto fix_method = [is_encrypted](QPDF::encryption_method_e& m) {
|
||||
if (is_encrypted && m == QPDF::e_none)
|
||||
{
|
||||
m = QPDF::e_rc4;
|
||||
}
|
||||
};
|
||||
fix_method(stream_method);
|
||||
fix_method(string_method);
|
||||
fix_method(file_method);
|
||||
std::string s_stream_method = show_encryption_method(stream_method);
|
||||
std::string s_string_method = show_encryption_method(string_method);
|
||||
std::string s_file_method = show_encryption_method(file_method);
|
||||
std::string s_overall_method;
|
||||
if ((stream_method == string_method) &&
|
||||
(stream_method == file_method))
|
||||
{
|
||||
s_overall_method = s_stream_method;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_overall_method = "mixed";
|
||||
}
|
||||
j_parameters.addDictionaryMember(
|
||||
"method", JSON::makeString(s_overall_method));
|
||||
j_parameters.addDictionaryMember(
|
||||
"streammethod", JSON::makeString(s_stream_method));
|
||||
j_parameters.addDictionaryMember(
|
||||
"stringmethod", JSON::makeString(s_string_method));
|
||||
j_parameters.addDictionaryMember(
|
||||
"filemethod", JSON::makeString(s_file_method));
|
||||
}
|
||||
|
||||
static void do_json(QPDF& pdf, Options& o)
|
||||
{
|
||||
JSON j = JSON::makeDictionary();
|
||||
@ -3869,6 +4050,10 @@ static void do_json(QPDF& pdf, Options& o)
|
||||
{
|
||||
do_json_acroform(pdf, o, j);
|
||||
}
|
||||
if (all_keys || o.json_keys.count("encrypt"))
|
||||
{
|
||||
do_json_encrypt(pdf, o, j);
|
||||
}
|
||||
|
||||
// Check against schema
|
||||
|
||||
|
@ -607,6 +607,7 @@ my @json_files = (
|
||||
['image-streams', []],
|
||||
['image-streams-small', []],
|
||||
['field-types', []],
|
||||
['field-types', ['--show-encryption-key']],
|
||||
['image-streams', ['--decode-level=all']],
|
||||
['image-streams', ['--decode-level=specialized']],
|
||||
['page-labels-and-outlines', ['--json-key=objects']],
|
||||
@ -621,6 +622,8 @@ my @json_files = (
|
||||
['--json-key=objects', '--json-object=trailer', '--json-object=2 0 R']],
|
||||
['field-types', ['--json-key=acroform']],
|
||||
['need-appearances', ['--json-key=acroform']],
|
||||
['V4-aes', ['--json-key=encrypt']],
|
||||
['V4-aes', ['--json-key=encrypt', '--show-encryption-key']],
|
||||
);
|
||||
$n_tests += scalar(@json_files);
|
||||
foreach my $d (@json_files)
|
||||
@ -3176,7 +3179,7 @@ my @encrypted_files =
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
);
|
||||
|
||||
$n_tests += 5 + (2 * (@encrypted_files)) + (6 * (@encrypted_files - 6)) + 9;
|
||||
$n_tests += 5 + (2 * (@encrypted_files)) + (7 * (@encrypted_files - 6)) + 9;
|
||||
|
||||
$td->runtest("encrypted file",
|
||||
{$td->COMMAND => "test_driver 2 encrypted-with-images.pdf"},
|
||||
@ -3216,7 +3219,9 @@ foreach my $d (@encrypted_files)
|
||||
$modifyother, $modifyall) = @$d;
|
||||
|
||||
my $f = sub { $_[0] ? "allowed" : "not allowed" };
|
||||
my $jf = sub { $_[0] ? "true" : "false" };
|
||||
my $enc_details = "";
|
||||
my $enc_json = "{\n \"encrypt\": {\n \"capabilities\": {\n";
|
||||
if ($match_owner)
|
||||
{
|
||||
$enc_details .= "Supplied password is owner password\n";
|
||||
@ -3235,6 +3240,37 @@ foreach my $d (@encrypted_files)
|
||||
"modify annotations: " . &$f($modifyannot) . "\n" .
|
||||
"modify other: " . &$f($modifyother) . "\n" .
|
||||
"modify anything: " . &$f($modifyall) . "\n";
|
||||
$enc_json .=
|
||||
" \"accessibility\": " . &$jf($accessible) . ",\n" .
|
||||
" \"extract\": " . &$jf($extract) . ",\n" .
|
||||
" \"moddifyannotations\": " . &$jf($modifyannot) . ",\n" .
|
||||
" \"modify\": " . &$jf($modifyall) . ",\n" .
|
||||
" \"modifyassembly\": " . &$jf($modifyassembly) . ",\n" .
|
||||
" \"modifyforms\": " . &$jf($modifyform) . ",\n" .
|
||||
" \"modifyother\": " . &$jf($modifyother) . ",\n" .
|
||||
" \"printhigh\": " . &$jf($printhigh) . ",\n" .
|
||||
" \"printlow\": " . &$jf($printlow) . "\n" .
|
||||
" },\n" .
|
||||
" \"encrypted\": true,\n" .
|
||||
" \"ownerpasswordmatched\": ---opm---,\n" .
|
||||
" \"parameters\": {\n" .
|
||||
" \"P\": ---P---,\n" .
|
||||
" \"R\": ---R---,\n" .
|
||||
" \"V\": ---V---,\n" .
|
||||
" \"bits\": ---bits---,\n" .
|
||||
" \"filemethod\": \"---method---\",\n" .
|
||||
" \"key\": null,\n" .
|
||||
" \"method\": \"---method---\",\n" .
|
||||
" \"streammethod\": \"---method---\",\n" .
|
||||
" \"stringmethod\": \"---method---\"\n" .
|
||||
" },\n" .
|
||||
" \"userpasswordmatched\": ---upm---\n" .
|
||||
" },\n" .
|
||||
" \"parameters\": {\n" .
|
||||
" \"decodelevel\": \"generalized\"\n" .
|
||||
" },\n" .
|
||||
" \"version\": 1\n" .
|
||||
"}\n";
|
||||
if ($file =~ m/XI-/)
|
||||
{
|
||||
$enc_details .=
|
||||
@ -3277,6 +3313,16 @@ foreach my $d (@encrypted_files)
|
||||
my $upass = $3 || "";
|
||||
my $opass = $4 || "";
|
||||
my $bits = (($V == 5) ? 256 : ($V == 2) ? 128 : 40);
|
||||
my $method = $bits == 256 ? "AESv3" : "RC4";
|
||||
my $opm = ($pass eq $opass ? "true" : "false");
|
||||
my $upm = ($pass eq $upass ? "true" : "false");
|
||||
$enc_json =~ s/---R---/$R/;
|
||||
$enc_json =~ s/---P---/$P/;
|
||||
$enc_json =~ s/---V---/$V/;
|
||||
$enc_json =~ s/---bits---/$bits/;
|
||||
$enc_json =~ s/---method---/$method/g;
|
||||
$enc_json =~ s/---opm---/$opm/;
|
||||
$enc_json =~ s/---upm---/$upm/;
|
||||
|
||||
my $eflags = "-encrypt \"$upass\" \"$opass\" $bits $xeflags --";
|
||||
if (($pass ne $upass) && ($V >= 5))
|
||||
@ -3307,6 +3353,13 @@ foreach my $d (@encrypted_files)
|
||||
"User password = $upass\n$enc_details",
|
||||
$td->EXIT_STATUS => 0},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
$td->runtest("json encrypt key ($enc_n)",
|
||||
{$td->COMMAND =>
|
||||
"qpdf --json --json-key=encrypt" .
|
||||
" --password=\"$pass\"" .
|
||||
" $file.enc2"},
|
||||
{$td->STRING => $enc_json, $td->EXIT_STATUS => 0},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
$td->runtest("decrypt again",
|
||||
{$td->COMMAND =>
|
||||
"qpdf --static-id --no-original-object-ids -qdf" .
|
||||
|
@ -4,6 +4,33 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/Pages": "2 0 R",
|
||||
|
@ -0,0 +1,33 @@
|
||||
{
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": true,
|
||||
"ownerpasswordmatched": true,
|
||||
"parameters": {
|
||||
"P": -4,
|
||||
"R": 4,
|
||||
"V": 4,
|
||||
"bits": 128,
|
||||
"filemethod": "AESv2",
|
||||
"key": "474258b004f2ce0017adeb6e79574357",
|
||||
"method": "AESv2",
|
||||
"streammethod": "AESv2",
|
||||
"stringmethod": "AESv2"
|
||||
},
|
||||
"userpasswordmatched": true
|
||||
},
|
||||
"parameters": {
|
||||
"decodelevel": "generalized"
|
||||
},
|
||||
"version": 1
|
||||
}
|
33
qpdf/qtest/qpdf/json-V4-aes-encrypt.out
Normal file
33
qpdf/qtest/qpdf/json-V4-aes-encrypt.out
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": true,
|
||||
"ownerpasswordmatched": true,
|
||||
"parameters": {
|
||||
"P": -4,
|
||||
"R": 4,
|
||||
"V": 4,
|
||||
"bits": 128,
|
||||
"filemethod": "AESv2",
|
||||
"key": null,
|
||||
"method": "AESv2",
|
||||
"streammethod": "AESv2",
|
||||
"stringmethod": "AESv2"
|
||||
},
|
||||
"userpasswordmatched": true
|
||||
},
|
||||
"parameters": {
|
||||
"decodelevel": "generalized"
|
||||
},
|
||||
"version": 1
|
||||
}
|
2721
qpdf/qtest/qpdf/json-field-types---show-encryption-key.out
Normal file
2721
qpdf/qtest/qpdf/json-field-types---show-encryption-key.out
Normal file
File diff suppressed because it is too large
Load Diff
@ -385,6 +385,33 @@
|
||||
"hasacroform": true,
|
||||
"needappearances": true
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/AcroForm": {
|
||||
|
@ -4,6 +4,33 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/Pages": "2 0 R",
|
||||
|
@ -4,6 +4,33 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/Pages": "2 0 R",
|
||||
|
@ -4,6 +4,33 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/Pages": "2 0 R",
|
||||
|
@ -4,6 +4,33 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/Pages": "2 0 R",
|
||||
|
@ -4,6 +4,33 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/Names": {
|
||||
|
@ -4,6 +4,33 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/Dests": "107 0 R",
|
||||
|
@ -4,6 +4,33 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/Outlines": "95 0 R",
|
||||
|
@ -4,6 +4,33 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/PageLabels": "2 0 R",
|
||||
|
@ -4,6 +4,33 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/Pages": "3 0 R",
|
||||
|
Loading…
Reference in New Issue
Block a user