@@ -479,6 +479,8 @@ compute_O_value(std::string const& user_password,
479479
480480 char upass[key_bytes];
481481 pad_or_truncate_password_V4 (user_password, upass);
482+ std::string k1 (reinterpret_cast <char *>(O_key), OU_key_bytes_V4);
483+ pad_short_parameter (k1, data.getLengthBytes ());
482484 iterate_rc4 (QUtil::unsigned_char_pointer (upass), key_bytes,
483485 O_key, data.getLengthBytes (),
484486 (data.getR () >= 3 ) ? 20 : 1 , false );
@@ -495,6 +497,7 @@ compute_U_value_R2(std::string const& user_password,
495497 std::string k1 = QPDF::compute_encryption_key (user_password, data);
496498 char udata[key_bytes];
497499 pad_or_truncate_password_V4 (" " , udata);
500+ pad_short_parameter (k1, data.getLengthBytes ());
498501 iterate_rc4 (QUtil::unsigned_char_pointer (udata), key_bytes,
499502 QUtil::unsigned_char_pointer (k1),
500503 data.getLengthBytes (), 1 , false );
@@ -516,6 +519,7 @@ compute_U_value_R3(std::string const& user_password,
516519 data.getId1 ().length ());
517520 MD5::Digest digest;
518521 md5.digest (digest);
522+ pad_short_parameter (k1, data.getLengthBytes ());
519523 iterate_rc4 (digest, sizeof (MD5::Digest),
520524 QUtil::unsigned_char_pointer (k1),
521525 data.getLengthBytes (), 20 , false );
@@ -591,7 +595,10 @@ check_owner_password_V4(std::string& user_password,
591595 compute_O_rc4_key (user_password, owner_password, data, key);
592596 unsigned char O_data[key_bytes];
593597 memcpy (O_data, QUtil::unsigned_char_pointer (data.getO ()), key_bytes);
594- iterate_rc4 (O_data, key_bytes, key, data.getLengthBytes (),
598+ std::string k1 (reinterpret_cast <char *>(key), OU_key_bytes_V4);
599+ pad_short_parameter (k1, data.getLengthBytes ());
600+ iterate_rc4 (O_data, key_bytes, QUtil::unsigned_char_pointer (k1),
601+ data.getLengthBytes (),
595602 (data.getR () >= 3 ) ? 20 : 1 , true );
596603 std::string new_user_password =
597604 std::string (reinterpret_cast <char *>(O_data), key_bytes);
@@ -886,6 +893,7 @@ QPDF::initializeEncryption()
886893
887894 if (V < 5 )
888895 {
896+ // These must be exactly the right number of bytes.
889897 pad_short_parameter (O, key_bytes);
890898 pad_short_parameter (U, key_bytes);
891899 if (! ((O.length () == key_bytes) && (U.length () == key_bytes)))
@@ -913,24 +921,12 @@ QPDF::initializeEncryption()
913921 UE = encryption_dict.getKey (" /UE" ).getStringValue ();
914922 Perms = encryption_dict.getKey (" /Perms" ).getStringValue ();
915923
924+ // These may be longer than the minimum number of bytes.
916925 pad_short_parameter (O, OU_key_bytes_V5);
917926 pad_short_parameter (U, OU_key_bytes_V5);
918927 pad_short_parameter (OE, OUE_key_bytes_V5);
919928 pad_short_parameter (UE, OUE_key_bytes_V5);
920929 pad_short_parameter (Perms, Perms_key_bytes_V5);
921- if ((O.length () < OU_key_bytes_V5) ||
922- (U.length () < OU_key_bytes_V5) ||
923- (OE.length () < OUE_key_bytes_V5) ||
924- (UE.length () < OUE_key_bytes_V5) ||
925- (Perms.length () < Perms_key_bytes_V5))
926- {
927- throw QPDFExc (qpdf_e_damaged_pdf, this ->m ->file ->getName (),
928- " encryption dictionary" ,
929- this ->m ->file ->getLastOffset (),
930- " incorrect length for some of"
931- " /O, /U, /OE, /UE, or /Perms in"
932- " encryption dictionary" );
933- }
934930 }
935931
936932 int Length = 40 ;
0 commit comments