@ -99,11 +99,11 @@ sub pdf_compute_encryption_key_owner
my $ o_key ;
if ( $ R == 2 )
{
$ o_key = substr ( $ o_digest , 0 , 8 ) ; # rc4 key is always 5 for revision 2, but for 3 or greather is dependent on the value of the encryption dictionaries length entry
$ o_key = substr ( $ o_digest , 0 , 8 ) ; # rc4 key is always 5 for revision 2, but for 3 or greather is dependent on the value of the encryption dictionaries length entry
}
else
{
$ o_key = substr ( $ o_digest , 0 , 16 ) ; # length is always 128 bits or 16 bytes
$ o_key = substr ( $ o_digest , 0 , 16 ) ; # length is always 128 bits or 16 bytes
}
return $ o_key ;
@ -175,15 +175,15 @@ sub module_generate_hash
if ( $ u eq "0000000000000000000000000000000000000000000000000000000000000000" )
{
my $ res ;
if ( $ u_pass eq "" )
if ( $ u_pass eq "" )
{
# we don't know the user-password so calculate $u based on the owner-password
$ res = pdf_compute_encryption_key_user ( $ word , $ padding , $ id , $ u , $ o , $ P , $ V , $ R , $ enc ) ;
$ res = pdf_compute_encryption_key_user ( $ word , $ padding , $ id , $ u , $ o , $ P , $ V , $ R , $ enc ) ;
}
else
{
# we do know the user-password, so we can generate $u
$ res = pdf_compute_encryption_key_user ( $ u_pass , $ padding , $ id , $ u , $ o , $ P , $ V , $ R , $ enc ) ;
# we do know the user-password, so we can generate $u
$ res = pdf_compute_encryption_key_user ( $ u_pass , $ padding , $ id , $ u , $ o , $ P , $ V , $ R , $ enc ) ;
}
my $ digest = md5 ( $ padding . pack ( "H*" , $ id ) ) ;
@ -193,7 +193,7 @@ sub module_generate_hash
my @ ress = split "" , $ res ;
# do xor of rc4 19 times
# do xor of rc4 19 times
for ( my $ x = 1 ; $ x <= 19 ; $ x + + )
{
my @ xor ;
@ -213,28 +213,28 @@ sub module_generate_hash
}
else
{
$ u = pack ( "H*" , $ u )
$ u = pack ( "H*" , $ u )
}
################ OWNER PASSWORD #################
my $ o_key = pdf_compute_encryption_key_owner ( $ word , $ padding , $ id , $ u , $ o , $ P , $ V , $ R , $ enc ) ;
my $ o_key = pdf_compute_encryption_key_owner ( $ word , $ padding , $ id , $ u , $ o , $ P , $ V , $ R , $ enc ) ;
my $ n = Crypt::RC4 - > new ( $ o_key ) ;
if ( $ u_pass eq "" )
if ( $ u_pass eq "" )
{
$ o = $ n - > RC4 ( substr ( $ padding , 0 , 32 - length "" ) ) ;
$ o = $ n - > RC4 ( substr ( $ padding , 0 , 32 - length "" ) ) ;
}
else
{
# dynamically add user password including padding to the RC4 input for the computation of the pdf o-value
$ o = $ n - > RC4 ( $ u_pass . substr ( $ padding , 0 , 32 - length $ u_pass ) ) ;
# dynamically add user password including padding to the RC4 input for the computation of the pdf o-value
$ o = $ n - > RC4 ( $ u_pass . substr ( $ padding , 0 , 32 - length $ u_pass ) ) ;
}
my @ ress2 = split "" , $ o_key ;
if ( $ R >= 3 )
{
# do xor of rc4 19 times
# do xor of rc4 19 times
for ( my $ x = 1 ; $ x <= 19 ; $ x + + )
{
my @ xor ;
@ -245,14 +245,14 @@ sub module_generate_hash
}
my $ s = join ( "" , @ xor ) ;
my $ n2 = Crypt::RC4 - > new ( $ s ) ;
my $ n2 = Crypt::RC4 - > new ( $ s ) ;
$ o = $ n2 - > RC4 ( $ o ) ;
}
}
my $ hash ;
if ( $ u_pass eq "" )
if ( $ u_pass eq "" )
{
$ hash = sprintf ( '$pdf$%d*%d*128*%d*%d*16*%s*32*%s*32*%s' , $ V , $ R , $ P , $ enc , $ id , unpack ( "H*" , $ u ) , unpack ( "H*" , $ o ) ) ;
}
@ -275,7 +275,7 @@ sub module_verify_hash
my @ data = split /\*/ , $ hash_in ;
my $ i_data = scalar @ data ;
return unless ( $ i_data == 11 ) || ( $ i_data == 12 ) ; # or 12 if user-password is included
return unless ( $ i_data == 11 ) || ( $ i_data == 12 ) ; # or 12 if user-password is included
my $ V = shift @ data ; $ V = substr ( $ V , 5 , 1 ) ;
my $ R = shift @ data ;
@ -290,7 +290,8 @@ sub module_verify_hash
my $ o = shift @ data ;
my $ u_pass = "" ;
if ( $ i_data == 12 ) {
if ( $ i_data == 12 )
{
$ u_pass = shift @ data ;
}