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 2013-10-05 Jay Berkenbilt <ejb@ql.org> 9 2013-10-05 Jay Berkenbilt <ejb@ql.org>
2 10
3 * Replace operator[] in std::string and std::vector with "at" in 11 * Replace operator[] in std::string and std::vector with "at" in
libqpdf/QPDFWriter.cc
@@ -462,7 +462,9 @@ QPDFWriter::setEncryptionParameters( @@ -462,7 +462,9 @@ QPDFWriter::setEncryptionParameters(
462 462
463 if (R > 3) 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 bits_to_clear.erase(10); 468 bits_to_clear.erase(10);
467 } 469 }
468 470
qpdf/qpdf.cc
@@ -740,13 +740,13 @@ parse_encrypt_options( @@ -740,13 +740,13 @@ parse_encrypt_options(
740 { 740 {
741 usage("invalid -accessibility parameter"); 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 else 747 else
748 { 748 {
749 - usage("-accessibility invalid for 40-bit keys"); 749 + r3_accessibility = result;
750 } 750 }
751 } 751 }
752 else if (strcmp(arg, "cleartext-metadata") == 0) 752 else if (strcmp(arg, "cleartext-metadata") == 0)
@@ -1730,49 +1730,77 @@ int main(int argc, char* argv[]) @@ -1730,49 +1730,77 @@ int main(int argc, char* argv[])
1730 } 1730 }
1731 if (encrypt) 1731 if (encrypt)
1732 { 1732 {
  1733 + int R = 0;
1733 if (keylen == 40) 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 else if (keylen == 128) 1738 else if (keylen == 128)
1740 { 1739 {
1741 if (force_V4 || cleartext_metadata || use_aes) 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 else 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 else if (keylen == 256) 1749 else if (keylen == 256)
1756 { 1750 {
1757 if (force_R5) 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 else 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 else 1760 else
1773 { 1761 {
1774 throw std::logic_error("bad encryption keylen"); 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 if (linearize) 1805 if (linearize)
1778 { 1806 {
qpdf/qtest/qpdf.test
@@ -1399,6 +1399,9 @@ my @encrypted_files = @@ -1399,6 +1399,9 @@ my @encrypted_files =
1399 ['XI-R6,V5,U=view,O=master', 'master', 1399 ['XI-R6,V5,U=view,O=master', 'master',
1400 '-print=low', -2052, 1400 '-print=low', -2052,
1401 1, 1, 1, 0, 1, 1, 1, 1, 1], 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 ['XI-long-password', 'qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm'], 1405 ['XI-long-password', 'qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm'],
1403 ['XI-long-password', 'qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcv'], 1406 ['XI-long-password', 'qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcv'],
1404 ); 1407 );
@@ -1501,12 +1504,20 @@ foreach my $d (@encrypted_files) @@ -1501,12 +1504,20 @@ foreach my $d (@encrypted_files)
1501 # password. 1504 # password.
1502 $upass = ""; 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 $td->runtest("encrypt $file", 1514 $td->runtest("encrypt $file",
1505 {$td->COMMAND => 1515 {$td->COMMAND =>
1506 "qpdf --static-id --no-original-object-ids -qdf" . 1516 "qpdf --static-id --no-original-object-ids -qdf" .
1507 " $eflags $file.enc $file.enc2"}, 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 $td->runtest("check /P", 1521 $td->runtest("check /P",
1511 {$td->COMMAND => 1522 {$td->COMMAND =>
1512 "qpdf --show-encryption --password=\"$pass\"" . 1523 "qpdf --show-encryption --password=\"$pass\"" .