///|
#borrow(output)
extern "C" fn pdf_secure_random_bytes_ffi(
output : FixedArray[Byte],
length : Int,
) -> Int = "pdflite_secure_random_bytes"
///|
fn pdf_secure_random_bytes_with_provider(
length : Int,
fill : (FixedArray[Byte], Int) -> Int,
) -> @core.PdfBytes raise @core.PdfError {
if length < 0 {
raise InvalidReadLength(length)
}
let output = FixedArray::make(length, b'\x00')
if fill(output, length) != 1 {
raise RandomBytesUnavailable
}
output.unsafe_reinterpret_as_bytes()
}
///|
/// Return cryptographically secure random bytes on the native target.
///
/// The native stub uses the platform RNG (`BCryptGenRandom` on Windows and
/// `/dev/urandom` on Unix-like systems). Negative lengths raise
/// `@core.PdfError::InvalidReadLength`; RNG failures raise `@core.PdfError::RandomBytesUnavailable`.
pub fn pdf_secure_random_bytes(
length : Int,
) -> @core.PdfBytes raise @core.PdfError {
pdf_secure_random_bytes_with_provider(length, pdf_secure_random_bytes_ffi)
}
///|
fn pdf_secure_aes_iv_provider(
_object_number : Int,
_generation : Int,
_index : Int,
) -> @core.PdfBytes raise @core.PdfError {
pdf_secure_random_bytes(16)
}
///|
fn pdf_secure_aesv3_random_provider(
_field : @crypt_core.PdfAesV3RandomField,
length : Int,
) -> @core.PdfBytes raise @core.PdfError {
pdf_secure_random_bytes(length)
}
///|
/// Encrypt a copy of the document with revision-4 AESV2 using native randomness.
///
/// Fresh random IVs are generated for encrypted strings and streams. When
/// `file_id` is empty, a random 16-byte first trailer ID is generated before
/// deriving the encryption key.
pub fn PdfDocument::encrypt_128bit_aesv2(
self : PdfDocument,
user_password : BytesView,
owner_password : BytesView,
denied_permissions : ArrayView[@crypt_core.PdfPermission],
encrypt_metadata? : Bool = true,
file_id? : BytesView = [],
) -> PdfDocument raise @core.PdfError {
let resolved_file_id = if file_id.length() > 0 {
file_id.to_owned()
} else {
pdf_secure_random_bytes(16)
}
self.encrypt_128bit_aesv2_with_iv_provider(
user_password,
owner_password,
denied_permissions,
pdf_secure_aes_iv_provider,
encrypt_metadata~,
file_id=resolved_file_id,
)
}
///|
/// Re-encrypt a decrypted AESV2 document using native random IVs.
///
/// The document must carry saved encryption state from a previous decrypt
/// operation; `password` is used to recover the file key for re-encryption.
pub fn PdfDocument::recrypt_with_password_aesv2(
self : PdfDocument,
password : BytesView,
) -> PdfDocument raise @core.PdfError {
self.recrypt_with_password_aesv2_with_iv_provider(
password, pdf_secure_aes_iv_provider,
)
}
///|
/// Encrypt a copy of the document with AESV3/AES-256 using native randomness.
///
/// Native random bytes supply the file key, salts, permissions padding, and
/// per-object IVs. Set `iso=true` for the ISO/PDF 2.0 AESV3 hash variant.
pub fn PdfDocument::encrypt_256bit_aesv3(
self : PdfDocument,
user_password : BytesView,
owner_password : BytesView,
denied_permissions : ArrayView[@crypt_core.PdfPermission],
iso? : Bool = false,
encrypt_metadata? : Bool = true,
file_id? : BytesView = [],
) -> PdfDocument raise @core.PdfError {
self.encrypt_256bit_aesv3_with_providers(
user_password,
owner_password,
denied_permissions,
pdf_secure_aesv3_random_provider,
pdf_secure_aes_iv_provider,
iso~,
encrypt_metadata~,
file_id~,
)
}
///|
/// Encrypt a copy of the document with the ISO AESV3/AES-256 variant.
///
/// This is the native-random convenience wrapper for
/// `encrypt_256bit_aesv3` with `iso=true`.
pub fn PdfDocument::encrypt_256bit_aesv3_iso(
self : PdfDocument,
user_password : BytesView,
owner_password : BytesView,
denied_permissions : ArrayView[@crypt_core.PdfPermission],
encrypt_metadata? : Bool = true,
file_id? : BytesView = [],
) -> PdfDocument raise @core.PdfError {
self.encrypt_256bit_aesv3(
user_password,
owner_password,
denied_permissions,
iso=true,
encrypt_metadata~,
file_id~,
)
}
///|
/// Re-encrypt a decrypted AESV3 document using native random IVs.
///
/// The document must carry saved encryption state from a previous decrypt
/// operation; `password` is used to recover the file key for re-encryption.
pub fn PdfDocument::recrypt_with_password_aesv3(
self : PdfDocument,
password : BytesView,
) -> PdfDocument raise @core.PdfError {
self.recrypt_with_password_aesv3_with_iv_provider(
password, pdf_secure_aes_iv_provider,
)
}
///|
/// Encrypt and serialize a document with AESV2 using native randomness.
///
/// The encrypted document is written with the requested write mode. Supplying a
/// `file_id` controls the trailer ID used for key derivation; IVs remain random.
pub fn pdf_write_encrypted_aesv2_document(
document : PdfDocument,
user_password : BytesView,
owner_password : BytesView,
denied_permissions : ArrayView[@crypt_core.PdfPermission],
encrypt_metadata? : Bool = true,
mode? : @writer.PdfWriteMode = PdfWriteClassic,
file_id? : BytesView = [],
) -> @core.PdfBytes raise @core.PdfError {
pdf_write_document_with_mode(
document.encrypt_128bit_aesv2(
user_password,
owner_password,
denied_permissions,
encrypt_metadata~,
file_id~,
),
mode,
)
}
///|
/// Encrypt and serialize a document with AESV3/AES-256 using native randomness.
///
/// Set `iso=true` for the ISO/PDF 2.0 hash variant. The requested write mode is
/// applied after encryption.
pub fn pdf_write_encrypted_aesv3_document(
document : PdfDocument,
user_password : BytesView,
owner_password : BytesView,
denied_permissions : ArrayView[@crypt_core.PdfPermission],
iso? : Bool = false,
encrypt_metadata? : Bool = true,
mode? : @writer.PdfWriteMode = PdfWriteClassic,
file_id? : BytesView = [],
) -> @core.PdfBytes raise @core.PdfError {
pdf_write_document_with_mode(
document.encrypt_256bit_aesv3(
user_password,
owner_password,
denied_permissions,
iso~,
encrypt_metadata~,
file_id~,
),
mode,
)
}
///|
/// Encrypt and serialize a document with the ISO AESV3/AES-256 variant.
pub fn pdf_write_encrypted_aesv3_iso_document(
document : PdfDocument,
user_password : BytesView,
owner_password : BytesView,
denied_permissions : ArrayView[@crypt_core.PdfPermission],
encrypt_metadata? : Bool = true,
mode? : @writer.PdfWriteMode = PdfWriteClassic,
file_id? : BytesView = [],
) -> @core.PdfBytes raise @core.PdfError {
pdf_write_encrypted_aesv3_document(
document,
user_password,
owner_password,
denied_permissions,
iso=true,
encrypt_metadata~,
mode~,
file_id~,
)
}