///|
fn PdfDocument::finish_decrypted_copy(
self : PdfDocument,
values : @crypt_core.PdfEncryptionValues,
) -> Unit raise @core.PdfError {
self.set_trailer_dict(
self.trailer_dict().remove_dict_entry(pdf_crypt_encrypt_name),
)
self.set_saved_encryption(Some({ values, }))
}
///|
fn PdfDocument::decrypt_with_file_key(
self : PdfDocument,
values : @crypt_core.PdfEncryptionValues,
file_key : @core.PdfBytes,
no_encrypt_metadata : Bool,
) -> PdfDecryptionResult raise @core.PdfError {
let no_encrypt_metadata = values.effective_no_encrypt_metadata(
no_encrypt_metadata,
)
match values.crypt_type {
PdfCryptARC4(key_length_bits, _) => {
let output = self.arc4_crypt_parsed_objects(
file_key,
key_length_bits,
no_encrypt_metadata,
self.encryption_object_number(),
)
output.finish_decrypted_copy(values)
{
document: output,
denied_permissions: @crypt_core.pdf_permissions_of_p(values.permissions),
}
}
PdfCryptAESV2 => {
let output = self.aesv2_decrypt_parsed_objects(
file_key,
128,
no_encrypt_metadata,
self.encryption_object_number(),
)
output.finish_decrypted_copy(values)
{
document: output,
denied_permissions: @crypt_core.pdf_permissions_of_p(values.permissions),
}
}
PdfCryptAESV3(_) => {
let output = self.aesv3_decrypt_parsed_objects(
file_key,
no_encrypt_metadata,
self.encryption_object_number(),
)
output.finish_decrypted_copy(values)
{
document: output,
denied_permissions: @crypt_core.pdf_permissions_of_p(values.permissions),
}
}
}
}
///|
fn @crypt_core.PdfEncryptionValues::file_key_for_available_password(
self : @crypt_core.PdfEncryptionValues,
user_password : BytesView?,
owner_password : BytesView?,
no_encrypt_metadata : Bool,
) -> @core.PdfBytes? raise @core.PdfError {
match user_password {
Some(password) =>
match self.file_key_for_user_password(password, no_encrypt_metadata~) {
Some(key) => return Some(key)
None =>
match owner_password {
Some(password) =>
self.file_key_for_owner_password(password, no_encrypt_metadata~)
None => None
}
}
None =>
match owner_password {
Some(password) =>
self.file_key_for_owner_password(password, no_encrypt_metadata~)
None => self.file_key_for_user_password([], no_encrypt_metadata~)
}
}
}
///|
fn @crypt_core.PdfEncryptionValues::decrypt_single_stream_with_file_key(
self : @crypt_core.PdfEncryptionValues,
object_number : Int,
generation : Int,
stream : @syntax.PdfObject,
file_key : BytesView,
no_encrypt_metadata : Bool,
) -> @syntax.PdfObject raise @core.PdfError {
let no_encrypt_metadata = self.effective_no_encrypt_metadata(
no_encrypt_metadata,
)
match self.crypt_type {
PdfCryptARC4(key_length_bits, _) =>
pdf_arc4_crypt_pdf_object(
object_number, generation, file_key, key_length_bits, stream, no_encrypt_metadata,
)
PdfCryptAESV2 =>
pdf_aesv2_decrypt_pdf_object(
object_number, generation, file_key, 128, stream, no_encrypt_metadata,
)
PdfCryptAESV3(_) =>
pdf_aesv3_decrypt_pdf_object(file_key, stream, no_encrypt_metadata)
}
}
///|
/// Decrypt one encrypted stream object with available passwords.
///
/// Unencrypted documents return `stream` unchanged. Encrypted documents return
/// `None` when no supplied password authenticates. The caller supplies the
/// stream object's number and generation because object keys depend on them.
pub fn PdfDocument::decrypt_single_stream(
self : PdfDocument,
object_number : Int,
generation : Int,
stream : @syntax.PdfObject,
user_password? : BytesView? = None,
owner_password? : BytesView? = None,
no_encrypt_metadata? : Bool = false,
) -> @syntax.PdfObject? raise @core.PdfError {
if !self.is_encrypted() {
Some(stream)
} else {
let values = self.encryption_values()
match
values.file_key_for_available_password(
user_password, owner_password, no_encrypt_metadata,
) {
Some(file_key) =>
Some(
values.decrypt_single_stream_with_file_key(
object_number, generation, stream, file_key, no_encrypt_metadata,
),
)
None => None
}
}
}
///|
/// Decrypt this document using optional user and owner passwords.
///
/// If the document is not encrypted, a copied document and empty permissions
/// list are returned. If it is encrypted and no password works, the result is
/// `None`; malformed encryption data still raises `@core.PdfError`.
pub fn PdfDocument::decrypt_with_passwords(
self : PdfDocument,
user_password? : BytesView? = None,
owner_password? : BytesView? = None,
no_encrypt_metadata? : Bool = false,
) -> PdfDecryptionResult? raise @core.PdfError {
if !self.is_encrypted() {
Some({ document: self.copy(), denied_permissions: [], })
} else {
let values = self.encryption_values()
match
values.file_key_for_available_password(
user_password, owner_password, no_encrypt_metadata,
) {
Some(file_key) =>
Some(self.decrypt_with_file_key(values, file_key, no_encrypt_metadata))
None => None
}
}
}