Skip to content

Commit

Permalink
MAINT: Add R parameter to generate_values (#1820)
Browse files Browse the repository at this point in the history
Pass it through to compute_U_value / compute_O_value

Also fix a bug I (Martin) just introduced in
compute_O_value by setting the token_bytes=4 and not 16.

All credit for refactoring goes to exiledkingcc

Co-authored-by: exiledkingcc <exiledkingcc@gmail.com>
  • Loading branch information
MartinThoma and exiledkingcc authored Apr 30, 2023
1 parent 3de03b7 commit a2d1e5a
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 9 deletions.
17 changes: 8 additions & 9 deletions pypdf/_encryption.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,14 +730,15 @@ def verify_perms(

@staticmethod
def generate_values(
R: int,
user_password: bytes,
owner_password: bytes,
key: bytes,
p: int,
metadata_encrypted: bool,
) -> Dict[Any, Any]:
u_value, ue_value = AlgV5.compute_U_value(user_password, key)
o_value, oe_value = AlgV5.compute_O_value(owner_password, key, u_value)
u_value, ue_value = AlgV5.compute_U_value(R, user_password, key)
o_value, oe_value = AlgV5.compute_O_value(R, owner_password, key, u_value)
perms = AlgV5.compute_Perms_value(key, p, metadata_encrypted)
return {
"/U": u_value,
Expand All @@ -748,7 +749,7 @@ def generate_values(
}

@staticmethod
def compute_U_value(password: bytes, key: bytes) -> Tuple[bytes, bytes]:
def compute_U_value(R: int, password: bytes, key: bytes) -> Tuple[bytes, bytes]:
"""
Algorithm 3.8 Computing the encryption dictionary’s U (user password)
and UE (user encryption key) values.
Expand All @@ -766,6 +767,7 @@ def compute_U_value(password: bytes, key: bytes) -> Tuple[bytes, bytes]:
as the UE key.
Args:
R:
password:
key:
Expand All @@ -775,7 +777,6 @@ def compute_U_value(password: bytes, key: bytes) -> Tuple[bytes, bytes]:
random_bytes = secrets.token_bytes(16)
val_salt = random_bytes[:8]
key_salt = random_bytes[8:]
R = 4 # only one supported so far
u_value = AlgV5.calculate_hash(R, password, val_salt, b"") + val_salt + key_salt

tmp_key = AlgV5.calculate_hash(R, password, key_salt, b"")
Expand All @@ -785,7 +786,7 @@ def compute_U_value(password: bytes, key: bytes) -> Tuple[bytes, bytes]:

@staticmethod
def compute_O_value(
password: bytes, key: bytes, u_value: bytes
R: int, password: bytes, key: bytes, u_value: bytes
) -> Tuple[bytes, bytes]:
"""
Algorithm 3.9 Computing the encryption dictionary’s O (owner password)
Expand All @@ -807,6 +808,7 @@ def compute_O_value(
The resulting 32-byte string is stored as the OE key.
Args:
R:
password:
key:
u_value: A 32-byte string, based on the user password, that shall be
Expand All @@ -816,10 +818,9 @@ def compute_O_value(
Returns:
A tuple (O value, OE value)
"""
random_bytes = secrets.token_bytes(4)
random_bytes = secrets.token_bytes(16)
val_salt = random_bytes[:8]
key_salt = random_bytes[8:]
R = 4 # only one supported so far
o_value = (
AlgV5.calculate_hash(R, password, val_salt, u_value) + val_salt + key_salt
)
Expand Down Expand Up @@ -894,8 +895,6 @@ def __init__(
self.StrF = StrF
self.EFF = EFF

# 1 => owner password
# 2 => user password
self._password_type = PasswordType.NOT_DECRYPTED
self._key: Optional[bytes] = None

Expand Down
1 change: 1 addition & 0 deletions tests/test_encryption.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ def test_alg_v5_generate_values():
return
key = b"0123456789123451"
values = AlgV5.generate_values(
R=4,
user_password=b"foo",
owner_password=b"bar",
key=key,
Expand Down

0 comments on commit a2d1e5a

Please sign in to comment.