Commit a237e9244512951e47cca0251aed00d8094de469

Authored by Jay Berkenbilt
1 parent ac9c1f0d

Warn when -accessibility=n will be ignored

Also accept -accessibility=n with 256 bit keys even though it will be
ignored.
ChangeLog
  1 +2013-10-18 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Warn when -accessibility=n is specified with a modern encryption
  4 + format (R > 3). Also, accept this flag (and ignore with warning)
  5 + with 256-bit encryption. qpdf has always ignored the
  6 + accessibility setting with R > 3, but it previously did so
  7 + silently.
  8 +
1 9 2013-10-05 Jay Berkenbilt <ejb@ql.org>
2 10  
3 11 * Replace operator[] in std::string and std::vector with "at" in
... ...
libqpdf/QPDFWriter.cc
... ... @@ -462,7 +462,9 @@ QPDFWriter::setEncryptionParameters(
462 462  
463 463 if (R > 3)
464 464 {
465   - // Bit 10 is deprecated and should always be set.
  465 + // Bit 10 is deprecated and should always be set. This used
  466 + // to mean accessibility. There is no way to disable
  467 + // accessibility with R > 3.
466 468 bits_to_clear.erase(10);
467 469 }
468 470  
... ...
qpdf/qpdf.cc
... ... @@ -740,13 +740,13 @@ parse_encrypt_options(
740 740 {
741 741 usage("invalid -accessibility parameter");
742 742 }
743   - if (keylen == 128)
  743 + if (keylen == 40)
744 744 {
745   - r3_accessibility = result;
  745 + usage("-accessibility invalid for 40-bit keys");
746 746 }
747 747 else
748 748 {
749   - usage("-accessibility invalid for 40-bit keys");
  749 + r3_accessibility = result;
750 750 }
751 751 }
752 752 else if (strcmp(arg, "cleartext-metadata") == 0)
... ... @@ -1730,49 +1730,77 @@ int main(int argc, char* argv[])
1730 1730 }
1731 1731 if (encrypt)
1732 1732 {
  1733 + int R = 0;
1733 1734 if (keylen == 40)
1734 1735 {
1735   - w.setR2EncryptionParameters(
1736   - user_password.c_str(), owner_password.c_str(),
1737   - r2_print, r2_modify, r2_extract, r2_annotate);
  1736 + R = 2;
1738 1737 }
1739 1738 else if (keylen == 128)
1740 1739 {
1741 1740 if (force_V4 || cleartext_metadata || use_aes)
1742 1741 {
1743   - w.setR4EncryptionParameters(
1744   - user_password.c_str(), owner_password.c_str(),
1745   - r3_accessibility, r3_extract, r3_print, r3_modify,
1746   - !cleartext_metadata, use_aes);
  1742 + R = 4;
1747 1743 }
1748 1744 else
1749 1745 {
1750   - w.setR3EncryptionParameters(
1751   - user_password.c_str(), owner_password.c_str(),
1752   - r3_accessibility, r3_extract, r3_print, r3_modify);
  1746 + R = 3;
1753 1747 }
1754 1748 }
1755 1749 else if (keylen == 256)
1756 1750 {
1757 1751 if (force_R5)
1758 1752 {
1759   - w.setR5EncryptionParameters(
1760   - user_password.c_str(), owner_password.c_str(),
1761   - r3_accessibility, r3_extract, r3_print, r3_modify,
1762   - !cleartext_metadata);
  1753 + R = 5;
1763 1754 }
1764 1755 else
1765 1756 {
1766   - w.setR6EncryptionParameters(
1767   - user_password.c_str(), owner_password.c_str(),
1768   - r3_accessibility, r3_extract, r3_print, r3_modify,
1769   - !cleartext_metadata);
  1757 + R = 6;
1770 1758 }
1771 1759 }
1772 1760 else
1773 1761 {
1774 1762 throw std::logic_error("bad encryption keylen");
1775 1763 }
  1764 + if ((R > 3) && (r3_accessibility == false))
  1765 + {
  1766 + std::cerr << whoami
  1767 + << ": -accessibility=n is ignored for modern"
  1768 + << " encryption formats" << std::endl;
  1769 + }
  1770 + switch (R)
  1771 + {
  1772 + case 2:
  1773 + w.setR2EncryptionParameters(
  1774 + user_password.c_str(), owner_password.c_str(),
  1775 + r2_print, r2_modify, r2_extract, r2_annotate);
  1776 + break;
  1777 + case 3:
  1778 + w.setR3EncryptionParameters(
  1779 + user_password.c_str(), owner_password.c_str(),
  1780 + r3_accessibility, r3_extract, r3_print, r3_modify);
  1781 + break;
  1782 + case 4:
  1783 + w.setR4EncryptionParameters(
  1784 + user_password.c_str(), owner_password.c_str(),
  1785 + r3_accessibility, r3_extract, r3_print, r3_modify,
  1786 + !cleartext_metadata, use_aes);
  1787 + break;
  1788 + case 5:
  1789 + w.setR5EncryptionParameters(
  1790 + user_password.c_str(), owner_password.c_str(),
  1791 + r3_accessibility, r3_extract, r3_print, r3_modify,
  1792 + !cleartext_metadata);
  1793 + break;
  1794 + case 6:
  1795 + w.setR6EncryptionParameters(
  1796 + user_password.c_str(), owner_password.c_str(),
  1797 + r3_accessibility, r3_extract, r3_print, r3_modify,
  1798 + !cleartext_metadata);
  1799 + break;
  1800 + default:
  1801 + throw std::logic_error("bad encryption R value");
  1802 + break;
  1803 + }
1776 1804 }
1777 1805 if (linearize)
1778 1806 {
... ...
qpdf/qtest/qpdf.test
... ... @@ -1399,6 +1399,9 @@ my @encrypted_files =
1399 1399 ['XI-R6,V5,U=view,O=master', 'master',
1400 1400 '-print=low', -2052,
1401 1401 1, 1, 1, 0, 1, 1, 1, 1, 1],
  1402 + ['XI-R6,V5,U=view,O=master', 'master',
  1403 + '-accessibility=n', -4, # -accessibility=n has no effect
  1404 + 1, 1, 1, 1, 1, 1, 1, 1, 1],
1402 1405 ['XI-long-password', 'qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm'],
1403 1406 ['XI-long-password', 'qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcv'],
1404 1407 );
... ... @@ -1501,12 +1504,20 @@ foreach my $d (@encrypted_files)
1501 1504 # password.
1502 1505 $upass = "";
1503 1506 }
  1507 + my $accessibility_warning = "";
  1508 + if (($R > 3) && ($eflags =~ /accessibility=n/))
  1509 + {
  1510 + $accessibility_warning =
  1511 + "qpdf: -accessibility=n is ignored" .
  1512 + " for modern encryption formats\n";
  1513 + }
1504 1514 $td->runtest("encrypt $file",
1505 1515 {$td->COMMAND =>
1506 1516 "qpdf --static-id --no-original-object-ids -qdf" .
1507 1517 " $eflags $file.enc $file.enc2"},
1508   - {$td->STRING => "",
1509   - $td->EXIT_STATUS => 0});
  1518 + {$td->STRING => $accessibility_warning,
  1519 + $td->EXIT_STATUS => 0},
  1520 + $td->NORMALIZE_NEWLINES);
1510 1521 $td->runtest("check /P",
1511 1522 {$td->COMMAND =>
1512 1523 "qpdf --show-encryption --password=\"$pass\"" .
... ...