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.
Functions and Procedures
Section titled “Functions and Procedures”is_pdf
Section titled “is_pdf”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.
classify
Section titled “classify”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
backfill
Section titled “backfill”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