Skip to content

adm_pdf_provenance_api

Says where a PDF comes from, and keeps the answer with the version: the column adm_document_versions.pdf_provenance.

A signature of a signing key of ADM is the mark of a file that ADM made and that nobody has changed since. This package reads the signatures of a PDF (see adm_pdf_signature_api) and sets the status:

Status Meaning
NOT_SIGNED The PDF has no signature.
ADM_SIGNED Every signature is a signature of a signing key of ADM. Every digest and every signature is valid, and the last signature covers the whole file.
MODIFIED A signature of a signing key of ADM is in the file, and a check fails. A byte of the signed range changed, or the file has more bytes behind the last signature.
FOREIGN_SIGNED The PDF has a signature of a certificate that is not a signing key of ADM, and no check of an ADM signature fails.
UNKNOWN ADM cannot say. The PDF needs a password, or cannot be read, or a signature of an ADM key cannot be checked, or the version was not examined yet (a version from before the column).

A folder with the signing mode OFF is not examined, see adm_signing_policy_api.

A certificate is a signing key of ADM when a row of adm_signing_keys has its fingerprint. The status of the key does not matter: a key that an administrator disabled stays a key of ADM, because its signatures stay what they were. The match is the one that adm_pdf_api.verify_signatures makes (signing_key_id).

When a file has several signatures, the earlier ones must be valid, and only the last one must cover the whole file. This is how a second signature is added (an incremental update).

What the status does not say. ADM does not check that a certificate is trusted, that it was not revoked, or when the signature was made, see adm_pdf_api.verify_signatures. A signature dictionary that a rewrite of the file left behind without a valid signature is not seen: it is in a compressed part of the file. It does not change the status.

ADM classifies a PDF when it stores a new version (adm_document_api.create_document, adm_document_api.add_document_version, and with them every PDF operation, the editor, the upload and the restore of an old version). A failure of the classification never makes the upload fail: the status is UNKNOWN, and the error is in the debug log. A file that is not a PDF is not examined and has no status. Versions that were stored before the column existed have no status until backfill ran.

True when the bytes are a PDF: the text %PDF- is in the first 1024 bytes. A cheap test that reads only the start of the file.

Signature:

function is_pdf (
p_content in blob
) return boolean;

Parameters:

Name Direction Type Description
p_content in blob The file

Returns: boolean - True for a PDF. False for a null BLOB, an empty file and any other file.


The status of a PDF, see the description of the package. The order is cheap first: a file that needs a password is UNKNOWN, a file without a signature is NOT_SIGNED, and only a file with a signature is verified (digest, signature, whole file). It does not read the file again and it does not change anything.

The call never raises an error. A failure gives UNKNOWN and a message in the debug log.

Signature:

function classify (
p_pdf in blob
) return varchar2;

Parameters:

Name Direction Type Description
p_pdf in blob The PDF

Returns: varchar2 - The status, never null


Classifies the versions that have no status yet, for the PDF documents that are not in the trash. The default is the latest version of every such document. It reads every file through adm_storage_api.get_file_content, so files in object storage are downloaded: use p_max_versions to work in batches, and call it until it returns 0.

Only an administrator or the system user can call it (adm_error.e_admin_required). Call it after adm_context_api.system_login: the reads of the system user are not written to the audit trail. The caller controls the transaction: the procedure does not commit. A version that cannot be read is skipped, and a message is in the debug log. It is found again by the next call.

Signature:

function backfill (
p_max_versions in number default null,
p_all_versions in boolean default false,
p_document_id in adm_documents.document_id%type default null
) return number;

Parameters:

Name Direction Type Description
p_max_versions in number default null Maximum number of versions to classify in this call. Null: all.
p_all_versions in boolean default false False (default): only the latest version of each document. True: also the older versions.
p_document_id in adm_documents.document_id%type default null Only this document. Null: every PDF document.

Returns: number - The number of versions that were classified