@mostajs/pdf-sign 0.4.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/README.md +18 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/pyhanko-signer.d.ts +7 -1
- package/dist/pyhanko-signer.d.ts.map +1 -1
- package/dist/pyhanko-signer.js +34 -0
- package/dist/pyhanko-signer.js.map +1 -1
- package/dist/sign.d.ts +13 -1
- package/dist/sign.d.ts.map +1 -1
- package/dist/sign.js +2 -2
- package/dist/sign.js.map +1 -1
- package/dist/timestamp.d.ts +3 -0
- package/dist/timestamp.d.ts.map +1 -0
- package/dist/timestamp.js +53 -0
- package/dist/timestamp.js.map +1 -0
- package/dist/types.d.ts +59 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/verify.js +1 -1
- package/dist/verify.js.map +1 -1
- package/llms.txt +9 -1
- package/package.json +1 -1
- package/python/sign_with_perms.py +180 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog — @mostajs/pdf-sign
|
|
2
2
|
|
|
3
|
+
## 0.6.0 — 11/10/2026
|
|
4
|
+
|
|
5
|
+
**`timestampPdf` : un horodatage de DOCUMENT ajouté à un PDF déjà signé, sans toucher à sa signature.**
|
|
6
|
+
|
|
7
|
+
### Ajouté
|
|
8
|
+
- `timestampPdf({ input, output?, timestampUrl, timestampHeaders?, timestampAuth?, timestampTimeout?, openPassword? })`
|
|
9
|
+
pose un jeton RFC 3161 (PAdES « DocTimeStamp ») par **mise à jour incrémentale** : les octets d'origine sont
|
|
10
|
+
gardés, les signatures déjà présentes restent intactes. Un document chiffré par des permissions (sans mot de passe
|
|
11
|
+
d'ouverture) s'horodate aussi. `verifyPdf` le lit comme `type: "horodatage-document"`.
|
|
12
|
+
- Mêmes garde-fous que `signPdf`, par les mêmes fonctions (désormais exportées de `sign.ts`) : les identifiants du
|
|
13
|
+
`.env` ne partent que vers `PDF_SIGN_TSA` ; jamais en clair hors de la boucle locale ; aucun repli — un horodateur
|
|
14
|
+
muet ou qui refuse la clé fait échouer, cause nommée (« identifiants refusés… (HTTP 401) »). Exige pyhanko.
|
|
15
|
+
- Types `TimestampOptions`, `HorodateurOptions`. Python : `sign_with_perms.py timestamp IN OUT CONFIG`.
|
|
16
|
+
- Raison : qatrax-cra (D4, doc 26) vend « une signature » = un horodatage **qualifié** posé sur le certificat déjà
|
|
17
|
+
scellé par le cachet de service ; le certificat reste un seul document, son sceau d'origine intact.
|
|
18
|
+
|
|
19
|
+
### Essais
|
|
20
|
+
T-DTS-1..6 (`test-scripts/test-horodatage-document.ts`). Sabotages relevés : réécriture non incrémentale (T-DTS-1,
|
|
21
|
+
2, 3), document chiffré non ouvert (T-DTS-3), repli silencieux sur l'original (T-DTS-4, 6).
|
|
22
|
+
|
|
23
|
+
## 0.5.0 — 07/10/2026
|
|
24
|
+
|
|
25
|
+
**`verifyPdf` dit QUAND et QUI, plus seulement « valide ».**
|
|
26
|
+
|
|
27
|
+
### Ajouté (additif : les champs existants ne changent pas)
|
|
28
|
+
- Par signature (moteur pyhanko) : `type` (signature ou horodatage de document), `level` (PAdES-B-B,
|
|
29
|
+
B-T, B-LT, horodatage de document), `claimedSigningTime` (la date DÉCLARÉE par le signataire),
|
|
30
|
+
`timestamp` (date ATTESTÉE `genTime`, politique `policy` (OID), numéro, autorité `tsa`, chaîne
|
|
31
|
+
embarquée, intact/valid/trusted du jeton), `signerCertificate` (titulaire, émetteur, numéro,
|
|
32
|
+
validité, `selfSigned`), `name` (nom affiché par les lecteurs), `reason`, `location`, `subFilter`,
|
|
33
|
+
`coverage`, `digestAlgorithm`. Au niveau du document : `dss`.
|
|
34
|
+
- Raison : la date déclarée (antidatable) et la date attestée par un horodateur étaient
|
|
35
|
+
indiscernables ; aucun écran de vérification ne pouvait les opposer.
|
|
36
|
+
|
|
37
|
+
### Corrigé
|
|
38
|
+
- Une signature que pyhanko REFUSE de valider (CMS abîmé, certificat de signature qui ne
|
|
39
|
+
correspond plus) est désormais rendue **invalide** (`intact: false, valid: false, error`) au lieu
|
|
40
|
+
de faire échouer toute la vérification. Jusqu'en 0.4.1, un document altéré de cette façon ne
|
|
41
|
+
rendait plus rien. T-DET-1..4.
|
|
42
|
+
|
|
3
43
|
## 0.4.1 — 29/09/2026
|
|
4
44
|
|
|
5
45
|
**pyhanko 0.37 taisait le diagnostic « identifiants refusés » — et rien ne fixait les versions.**
|
package/README.md
CHANGED
|
@@ -147,6 +147,24 @@ pyhanko, seul, l'aurait présenté comme une « réponse malformée ».
|
|
|
147
147
|
Les identifiants partent au moteur par le fichier de configuration temporaire (dossier en 0700,
|
|
148
148
|
effacé après usage), **jamais** par la ligne de commande — et le CLI ne les accepte qu'en `.env`.
|
|
149
149
|
|
|
150
|
+
## Horodatage d'un document déjà signé *(0.6.0)*
|
|
151
|
+
|
|
152
|
+
`timestampPdf` ajoute un jeton RFC 3161 (PAdES « DocTimeStamp ») à un PDF, **sans toucher** aux signatures qu'il
|
|
153
|
+
porte déjà : mise à jour incrémentale, octets d'origine gardés. Usage type : poser un horodatage **qualifié** sur un
|
|
154
|
+
document scellé par un cachet de service.
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { timestampPdf } from "@mostajs/pdf-sign";
|
|
158
|
+
const { bytes } = await timestampPdf({
|
|
159
|
+
input: pdfScelle, // octets ou chemin
|
|
160
|
+
timestampUrl: "https://api.evidency.io/v3/projects/<ID>/timestamp",
|
|
161
|
+
timestampHeaders: { "X-API-KEY": process.env.CLE },
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Mêmes garde-fous que la signature (tableau ci-dessus), aucun repli : si l'horodateur ne répond pas ou refuse la clé,
|
|
166
|
+
rien n'est rendu. Exige pyhanko. Essais : `test-scripts/test-horodatage-document.ts`.
|
|
167
|
+
|
|
150
168
|
## Configuration (`.env`)
|
|
151
169
|
|
|
152
170
|
| Clé | Rôle |
|
package/dist/index.d.ts
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
* @license AGPL-3.0-or-later
|
|
9
9
|
*/
|
|
10
10
|
export { signPdf } from "./sign.js";
|
|
11
|
+
export { timestampPdf } from "./timestamp.js";
|
|
11
12
|
export { verifyPdf } from "./verify.js";
|
|
12
13
|
export { detectEngines, resolvePython, pyhankoAvailable } from "./engines.js";
|
|
13
14
|
export { loadPdfSignConfig, type PdfSignConfig } from "./config.js";
|
|
14
|
-
export type { SignOptions, SignResult, SignMeta, SignField, SignPermissions, SignEngine, VerifyOptions, VerifyResult, SignatureInfo, EngineAvailability, } from "./types.js";
|
|
15
|
+
export type { SignOptions, SignResult, SignMeta, SignField, SignPermissions, SignEngine, VerifyOptions, VerifyResult, SignatureInfo, EngineAvailability, TimestampOptions, HorodateurOptions, } from "./types.js";
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACpE,YAAY,EACV,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EACzE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACpE,YAAY,EACV,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EACzE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,GACpG,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* @license AGPL-3.0-or-later
|
|
9
9
|
*/
|
|
10
10
|
export { signPdf } from "./sign.js";
|
|
11
|
+
export { timestampPdf } from "./timestamp.js";
|
|
11
12
|
export { verifyPdf } from "./verify.js";
|
|
12
13
|
export { detectEngines, resolvePython, pyhankoAvailable } from "./engines.js";
|
|
13
14
|
export { loadPdfSignConfig } from "./config.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAsB,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAsB,MAAM,aAAa,CAAC"}
|
package/dist/pyhanko-signer.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import type { SignOptions, SignResult } from "./types.js";
|
|
1
|
+
import type { SignOptions, SignResult, TimestampOptions } from "./types.js";
|
|
2
2
|
/** Signe via pyhanko (PAdES visible + éventuelles permissions restrictives). */
|
|
3
3
|
export declare function signPyhanko(opts: SignOptions, python: string): SignResult;
|
|
4
|
+
/**
|
|
5
|
+
* 0.6.0 — horodatage de DOCUMENT via pyhanko (`PdfTimeStamper`) : mise à jour incrémentale, les signatures déjà
|
|
6
|
+
* présentes restent intactes. Mêmes règles que la signature : identifiants par fichier, jamais par `argv` ; aucun
|
|
7
|
+
* repli — un horodateur qui ne répond pas fait échouer, et la cause est remontée.
|
|
8
|
+
*/
|
|
9
|
+
export declare function timestampPyhanko(opts: TimestampOptions, python: string): SignResult;
|
|
4
10
|
//# sourceMappingURL=pyhanko-signer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pyhanko-signer.d.ts","sourceRoot":"","sources":["../src/pyhanko-signer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAmB,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"pyhanko-signer.d.ts","sourceRoot":"","sources":["../src/pyhanko-signer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAmB,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAsD7F,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAuDzE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAwBnF"}
|
package/dist/pyhanko-signer.js
CHANGED
|
@@ -115,4 +115,38 @@ export function signPyhanko(opts, python) {
|
|
|
115
115
|
rmSync(dir, { recursive: true, force: true });
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* 0.6.0 — horodatage de DOCUMENT via pyhanko (`PdfTimeStamper`) : mise à jour incrémentale, les signatures déjà
|
|
120
|
+
* présentes restent intactes. Mêmes règles que la signature : identifiants par fichier, jamais par `argv` ; aucun
|
|
121
|
+
* repli — un horodateur qui ne répond pas fait échouer, et la cause est remontée.
|
|
122
|
+
*/
|
|
123
|
+
export function timestampPyhanko(opts, python) {
|
|
124
|
+
const dir = mkdtempSync(join(tmpdir(), "mosta-pdf-sign-"));
|
|
125
|
+
try {
|
|
126
|
+
const inPath = typeof opts.input === "string" ? opts.input : toFile(dir, "in.pdf", opts.input);
|
|
127
|
+
const outPath = opts.output ?? join(dir, "out.pdf");
|
|
128
|
+
const cfgPath = toFile(dir, "config.json", JSON.stringify({
|
|
129
|
+
open_password: opts.openPassword || undefined,
|
|
130
|
+
timestamp_url: opts.timestampUrl,
|
|
131
|
+
timestamp_headers: opts.timestampHeaders,
|
|
132
|
+
timestamp_auth: opts.timestampAuth,
|
|
133
|
+
timestamp_timeout: opts.timestampTimeout,
|
|
134
|
+
}));
|
|
135
|
+
try {
|
|
136
|
+
execFileSync(python, [SIGN_PY, "timestamp", inPath, outPath, cfgPath], { stdio: ["ignore", "inherit", "pipe"] });
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
const trace = String(e?.stderr ?? "");
|
|
140
|
+
if (trace)
|
|
141
|
+
process.stderr.write(trace);
|
|
142
|
+
throw new Error(diagnostiquer(trace) ?? "Horodatage du document impossible (voir le journal du serveur).");
|
|
143
|
+
}
|
|
144
|
+
if (opts.output)
|
|
145
|
+
return { output: outPath, engine: "pyhanko" };
|
|
146
|
+
return { bytes: readFileSync(outPath), engine: "pyhanko" };
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
rmSync(dir, { recursive: true, force: true });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
118
152
|
//# sourceMappingURL=pyhanko-signer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pyhanko-signer.js","sourceRoot":"","sources":["../src/pyhanko-signer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;GAKG;AACH,SAAS,aAAa,CAAC,KAAa;IAClC,gGAAgG;IAChG,kGAAkG;IAClG,sFAAsF;IACtF,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACtD,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3D,IAAI,6DAA6D,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9E,OAAO,qDAAqD,CAAC;IAC/D,CAAC;IACD,IAAI,6CAA6C,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9D,OAAO,qDAAqD,CAAC;IAC/D,CAAC;IACD,IAAI,uDAAuD,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO,qEAAqE,CAAC;IAC/E,CAAC;IACD,IAAI,gCAAgC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACpF,OAAO,0FAA0F,CAAC;IACpG,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,MAAM,CAAC,GAAW,EAAE,IAAY,EAAE,IAAyB;IAClE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1B,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACvB,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,cAAc,CAAC,CAAkB;IACxC,OAAO;QACL,aAAa,EAAE,CAAC,CAAC,aAAa,IAAI,IAAI;QACtC,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK;QAC3B,iBAAiB,EAAE,CAAC,CAAC,gBAAgB,IAAI,KAAK;QAC9C,eAAe,EAAE,CAAC,CAAC,cAAc,IAAI,KAAK;QAC1C,oFAAoF;QACpF,6FAA6F;QAC7F,yFAAyF;QACzF,+EAA+E;QAC/E,6FAA6F;QAC7F,WAAW,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;QACjC,YAAY,EAAE,CAAC,CAAC,WAAW,IAAI,KAAK;QACpC,YAAY,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;QACnC,aAAa,EAAE,CAAC,CAAC,YAAY,IAAI,IAAI;KACtC,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW,CAAC,IAAiB,EAAE,MAAc;IAC3D,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/F,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAEpD,IAAI,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC;QACnC,IAAI,CAAC,QAAQ;YAAE,QAAQ,GAAG,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QAEtE,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzE,MAAM,GAAG,GAAG;YACV,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;YACrB,KAAK,EAAE;gBACL,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI;gBACtB,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC;gBAC3B,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC;gBAC3C,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU;aACpC;YACD,WAAW,EAAE,KAAK;YAClB,2FAA2F;YAC3F,gFAAgF;YAChF,aAAa,EAAE,IAAI,CAAC,YAAY,IAAI,SAAS;YAC7C,2FAA2F;YAC3F,wCAAwC;YACxC,aAAa,EAAE,IAAI,CAAC,YAAY,IAAI,SAAS;YAC7C,uFAAuF;YACvF,8EAA8E;YAC9E,iBAAiB,EAAE,IAAI,CAAC,gBAAgB;YACxC,cAAc,EAAE,IAAI,CAAC,aAAa;YAClC,iBAAiB,EAAE,IAAI,CAAC,gBAAgB;SACzC,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QAEhE,oFAAoF;QACpF,EAAE;QACF,8FAA8F;QAC9F,yFAAyF;QACzF,yFAAyF;QACzF,0FAA0F;QAC1F,gGAAgG;QAChG,IAAI,CAAC;YACH,YAAY,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,EACjF,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;YACtC,IAAI,KAAK;gBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAO,oCAAoC;YAClF,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC/D,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC7D,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"pyhanko-signer.js","sourceRoot":"","sources":["../src/pyhanko-signer.ts"],"names":[],"mappings":"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"}
|
package/dist/sign.d.ts
CHANGED
|
@@ -8,6 +8,18 @@
|
|
|
8
8
|
* @author Dr Hamid MADANI <drmdh@msn.com>
|
|
9
9
|
* @license AGPL-3.0-or-later
|
|
10
10
|
*/
|
|
11
|
-
import type { SignOptions, SignResult } from "./types.js";
|
|
11
|
+
import type { HorodateurOptions, SignOptions, SignResult } from "./types.js";
|
|
12
|
+
import type { PdfSignConfig } from "./config.js";
|
|
12
13
|
export declare function signPdf(opts: SignOptions): Promise<SignResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Les identifiants d'un horodateur VOYAGENT AVEC SON ADRESSE — même règle que le certificat et sa
|
|
16
|
+
* phrase, plus haut.
|
|
17
|
+
*
|
|
18
|
+
* Ceux du `.env` ne partent que vers l'horodateur du `.env` (`PDF_SIGN_TSA`). Un appelant qui
|
|
19
|
+
* vise une autre adresse fournit les siens, ou n'en envoie aucun : joindre notre clé d'API à une
|
|
20
|
+
* requête vers un tiers, c'est la lui donner.
|
|
21
|
+
*/
|
|
22
|
+
export declare function identifiantsHorodateur(opts: HorodateurOptions, cfg: PdfSignConfig): HorodateurOptions;
|
|
23
|
+
/** Refuse, AVANT toute requête, un horodatage dont la demande est incohérente ou dangereuse. */
|
|
24
|
+
export declare function controlerHorodatage(o: HorodateurOptions): void;
|
|
13
25
|
//# sourceMappingURL=sign.d.ts.map
|
package/dist/sign.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../src/sign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../src/sign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAqDpE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,EAAE,aAAa,GAAG,iBAAiB,CAUrG;AAID,gGAAgG;AAChG,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAqB9D"}
|
package/dist/sign.js
CHANGED
|
@@ -60,7 +60,7 @@ export async function signPdf(opts) {
|
|
|
60
60
|
* vise une autre adresse fournit les siens, ou n'en envoie aucun : joindre notre clé d'API à une
|
|
61
61
|
* requête vers un tiers, c'est la lui donner.
|
|
62
62
|
*/
|
|
63
|
-
function identifiantsHorodateur(opts, cfg) {
|
|
63
|
+
export function identifiantsHorodateur(opts, cfg) {
|
|
64
64
|
const t = cfg.tsa;
|
|
65
65
|
const memeHorodateur = !!opts.timestampUrl && opts.timestampUrl === t.url;
|
|
66
66
|
return {
|
|
@@ -73,7 +73,7 @@ function identifiantsHorodateur(opts, cfg) {
|
|
|
73
73
|
}
|
|
74
74
|
const LOCALES = new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
|
|
75
75
|
/** Refuse, AVANT toute requête, un horodatage dont la demande est incohérente ou dangereuse. */
|
|
76
|
-
function controlerHorodatage(o) {
|
|
76
|
+
export function controlerHorodatage(o) {
|
|
77
77
|
const identifie = !!o.timestampAuth || Object.keys(o.timestampHeaders ?? {}).length > 0;
|
|
78
78
|
if (!o.timestampUrl) {
|
|
79
79
|
if (identifie) {
|
package/dist/sign.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sign.js","sourceRoot":"","sources":["../src/sign.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"sign.js","sourceRoot":"","sources":["../src/sign.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timestamp.d.ts","sourceRoot":"","sources":["../src/timestamp.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAiB/D,wBAAsB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAW9E"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mostajs/pdf-sign — HORODATAGE DE DOCUMENT (0.6.0).
|
|
3
|
+
*
|
|
4
|
+
* Ajoute un jeton RFC 3161 (PAdES « DocTimeStamp ») à un PDF, signé ou non, par mise à jour incrémentale : les
|
|
5
|
+
* signatures déjà présentes restent intactes. Premier usage : qatrax-cra (D4, doc 26, 11/10/2026) — l'horodatage
|
|
6
|
+
* QUALIFIÉ posé sur un certificat déjà scellé par le cachet de service.
|
|
7
|
+
*
|
|
8
|
+
* Mêmes règles que `signPdf` : les identifiants du `.env` ne partent que vers l'horodateur du `.env` ; pas
|
|
9
|
+
* d'identifiants en clair hors de la boucle locale ; aucun repli. Le cœur Node ne sait pas horodater : pyhanko est
|
|
10
|
+
* exigé.
|
|
11
|
+
*
|
|
12
|
+
* @author Dr Hamid MADANI <drmdh@msn.com>
|
|
13
|
+
* @license AGPL-3.0-or-later
|
|
14
|
+
*/
|
|
15
|
+
import { openSync, readSync, closeSync } from "node:fs";
|
|
16
|
+
import { detectEngines } from "./engines.js";
|
|
17
|
+
import { loadPdfSignConfig } from "./config.js";
|
|
18
|
+
import { controlerHorodatage, identifiantsHorodateur } from "./sign.js";
|
|
19
|
+
import { timestampPyhanko } from "./pyhanko-signer.js";
|
|
20
|
+
const ENTETE_PDF = Buffer.from("%PDF-");
|
|
21
|
+
function estPdf(input) {
|
|
22
|
+
if (typeof input !== "string")
|
|
23
|
+
return Buffer.from(input.subarray(0, 5)).equals(ENTETE_PDF);
|
|
24
|
+
const tampon = Buffer.alloc(5);
|
|
25
|
+
let fd = null;
|
|
26
|
+
try {
|
|
27
|
+
fd = openSync(input, "r");
|
|
28
|
+
readSync(fd, tampon, 0, 5, 0);
|
|
29
|
+
return tampon.equals(ENTETE_PDF);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
if (fd !== null)
|
|
36
|
+
closeSync(fd);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export async function timestampPdf(opts) {
|
|
40
|
+
if (!String(opts.timestampUrl ?? "").trim()) {
|
|
41
|
+
throw new Error("Horodatage de document : l'adresse de l'horodateur (`timestampUrl`) est requise.");
|
|
42
|
+
}
|
|
43
|
+
if (!estPdf(opts.input))
|
|
44
|
+
throw new Error("Horodatage de document : l'entrée n'est pas un PDF.");
|
|
45
|
+
const cfg = loadPdfSignConfig();
|
|
46
|
+
const o = { ...opts, ...identifiantsHorodateur(opts, cfg) };
|
|
47
|
+
controlerHorodatage(o);
|
|
48
|
+
const avail = detectEngines(cfg.python);
|
|
49
|
+
if (!avail.pyhanko)
|
|
50
|
+
throw new Error("Horodatage de document : moteur pyhanko indisponible — lancer python/setup-venv.sh (ou PDF_SIGN_PYTHON).");
|
|
51
|
+
return timestampPyhanko(o, avail.python);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=timestamp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timestamp.js","sourceRoot":"","sources":["../src/timestamp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAExC,SAAS,MAAM,CAAC,KAA0B;IACxC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3F,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,EAAE,GAAkB,IAAI,CAAC;IAC7B,IAAI,CAAC;QAAC,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAAC,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAAC,CAAC;IACnG,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;YACf,CAAC;QAAC,IAAI,EAAE,KAAK,IAAI;YAAE,SAAS,CAAC,EAAE,CAAC,CAAC;IAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAsB;IACvD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,kFAAkF,CAAC,CAAC;IACtG,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IAChG,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAChC,MAAM,CAAC,GAAqB,EAAE,GAAG,IAAI,EAAE,GAAG,sBAAsB,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;IAC9E,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,0GAA0G,CAAC,CAAC;IAChJ,OAAO,gBAAgB,CAAC,CAAC,EAAE,KAAK,CAAC,MAAgB,CAAC,CAAC;AACrD,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -94,6 +94,22 @@ export interface SignOptions {
|
|
|
94
94
|
/** `auto` (défaut) = pyhanko si dispo sinon Node ; `node` = PKCS#7 ; `pyhanko` = PAdES. */
|
|
95
95
|
engine?: SignEngine;
|
|
96
96
|
}
|
|
97
|
+
/** Ce qui désigne un horodateur RFC 3161 et ses identifiants — commun à la signature et à l'horodatage de document. */
|
|
98
|
+
export type HorodateurOptions = Pick<SignOptions, "timestampUrl" | "timestampHeaders" | "timestampAuth" | "timestampTimeout">;
|
|
99
|
+
/**
|
|
100
|
+
* 0.6.0 — horodatage de DOCUMENT (PAdES « DocTimeStamp ») : un jeton RFC 3161 ajouté, par mise à jour incrémentale, à
|
|
101
|
+
* un PDF qui peut déjà porter des signatures. Elles restent intactes : les octets d'origine ne sont pas réécrits.
|
|
102
|
+
*/
|
|
103
|
+
export interface TimestampOptions extends HorodateurOptions {
|
|
104
|
+
/** PDF source : chemin ou octets. */
|
|
105
|
+
input: string | Uint8Array;
|
|
106
|
+
/** Chemin de sortie ; si absent, les octets horodatés sont renvoyés. */
|
|
107
|
+
output?: string;
|
|
108
|
+
/** L'horodateur (obligatoire : un horodatage de document sans horodateur n'a pas de sens). */
|
|
109
|
+
timestampUrl: string;
|
|
110
|
+
/** Mot de passe d'ouverture, si le document en porte un. */
|
|
111
|
+
openPassword?: string;
|
|
112
|
+
}
|
|
97
113
|
export interface SignResult {
|
|
98
114
|
output?: string;
|
|
99
115
|
bytes?: Uint8Array;
|
|
@@ -107,17 +123,60 @@ export interface VerifyOptions {
|
|
|
107
123
|
trustPem?: string;
|
|
108
124
|
engine?: SignEngine;
|
|
109
125
|
}
|
|
126
|
+
/** Ce qu'un vérificateur doit voir d'un certificat (0.5.0) — jamais sa clé. */
|
|
127
|
+
export interface CertificateInfo {
|
|
128
|
+
subject: string;
|
|
129
|
+
issuer?: string;
|
|
130
|
+
serial?: string;
|
|
131
|
+
notBefore?: string | null;
|
|
132
|
+
notAfter?: string | null;
|
|
133
|
+
/** Émetteur = titulaire : personne d'autre ne s'en porte garant. */
|
|
134
|
+
selfSigned?: boolean;
|
|
135
|
+
}
|
|
136
|
+
/** Le jeton d'horodatage RFC 3161 attaché à une signature, ou l'horodatage de document (0.5.0). */
|
|
137
|
+
export interface TimestampInfo {
|
|
138
|
+
/** La date ATTESTÉE par l'horodateur (ISO 8601) — à opposer à `claimedSigningTime`. */
|
|
139
|
+
genTime: string | null;
|
|
140
|
+
/** Politique d'horodatage (OID), celle que publie le prestataire. */
|
|
141
|
+
policy: string;
|
|
142
|
+
serial?: string;
|
|
143
|
+
hashAlgorithm?: string;
|
|
144
|
+
tsa: CertificateInfo | null;
|
|
145
|
+
/** Sujets des certificats embarqués dans le jeton. */
|
|
146
|
+
chain: string[];
|
|
147
|
+
intact: boolean | null;
|
|
148
|
+
valid: boolean | null;
|
|
149
|
+
trusted: boolean | null;
|
|
150
|
+
}
|
|
110
151
|
export interface SignatureInfo {
|
|
111
152
|
field?: string;
|
|
112
153
|
intact?: boolean;
|
|
113
154
|
valid?: boolean;
|
|
114
155
|
trusted?: boolean;
|
|
115
156
|
signer?: string;
|
|
157
|
+
type?: "signature" | "horodatage-document";
|
|
158
|
+
/** Nom AFFICHÉ par les lecteurs (« signé par … ») : déclaratif, à ne pas confondre avec le certificat. */
|
|
159
|
+
name?: string | null;
|
|
160
|
+
reason?: string | null;
|
|
161
|
+
location?: string | null;
|
|
162
|
+
subFilter?: string | null;
|
|
163
|
+
/** L'heure DÉCLARÉE par le signataire : sans horodatage, elle est antidatable. */
|
|
164
|
+
claimedSigningTime?: string | null;
|
|
165
|
+
coverage?: string | null;
|
|
166
|
+
digestAlgorithm?: string | null;
|
|
167
|
+
signerCertificate?: CertificateInfo | null;
|
|
168
|
+
timestamp?: TimestampInfo | null;
|
|
169
|
+
/** Cause, quand le moteur refuse de valider la signature (rendue invalide, jamais en panne). */
|
|
170
|
+
error?: string;
|
|
171
|
+
/** PAdES-B-B (aucune date attestée), B-T (jeton), B-LT (+ DSS), ou horodatage de document (B-LTA). */
|
|
172
|
+
level?: string;
|
|
116
173
|
}
|
|
117
174
|
export interface VerifyResult {
|
|
118
175
|
signed: boolean;
|
|
119
176
|
signatures: SignatureInfo[];
|
|
120
177
|
engine: "pyhanko" | "node";
|
|
178
|
+
/** Données de validation à long terme (DSS) présentes dans le document (0.5.0). */
|
|
179
|
+
dss?: boolean;
|
|
121
180
|
}
|
|
122
181
|
export interface EngineAvailability {
|
|
123
182
|
node: boolean;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,6DAA6D;AAC7D,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,yFAAyF;AACzF,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3B,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,qGAAqG;IACrG,WAAW,CAAC,EAAE,eAAe,GAAG,KAAK,CAAC;IAEtC;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,6GAA6G;IAC7G,aAAa,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACnD,0GAA0G;IAC1G,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,uGAAuG;IACvG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,6DAA6D;AAC7D,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,yFAAyF;AACzF,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3B,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,qGAAqG;IACrG,WAAW,CAAC,EAAE,eAAe,GAAG,KAAK,CAAC;IAEtC;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,6GAA6G;IAC7G,aAAa,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACnD,0GAA0G;IAC1G,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,uHAAuH;AACvH,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,GAAG,kBAAkB,GAAG,eAAe,GAAG,kBAAkB,CAAC,CAAC;AAE9H;;;GAGG;AACH,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD,qCAAqC;IACrC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3B,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8FAA8F;IAC9F,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,uGAAuG;IACvG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,mGAAmG;AACnG,MAAM,WAAW,aAAa;IAC5B,uFAAuF;IACvF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,EAAE,eAAe,GAAG,IAAI,CAAC;IAC5B,sDAAsD;IACtD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,IAAI,CAAC,EAAE,WAAW,GAAG,qBAAqB,CAAC;IAC3C,0GAA0G;IAC1G,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iBAAiB,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAC3C,SAAS,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACjC,gGAAgG;IAChG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sGAAsG;IACtG,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,MAAM,EAAE,SAAS,GAAG,MAAM,CAAC;IAC3B,mFAAmF;IACnF,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
package/dist/verify.js
CHANGED
|
@@ -39,7 +39,7 @@ export function verifyPdf(opts) {
|
|
|
39
39
|
}
|
|
40
40
|
const line = out.trim().split("\n").pop() ?? "{}";
|
|
41
41
|
const parsed = JSON.parse(line);
|
|
42
|
-
return { signed: !!parsed.signed, signatures: parsed.signatures ?? [], engine: "pyhanko" };
|
|
42
|
+
return { signed: !!parsed.signed, signatures: parsed.signatures ?? [], engine: "pyhanko", dss: !!parsed.dss };
|
|
43
43
|
}
|
|
44
44
|
// Détection Node basique : présence d'un /ByteRange + dictionnaire de signature.
|
|
45
45
|
const s = readFileSync(opts.input).toString("latin1");
|
package/dist/verify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,UAAU,SAAS,CAAC,IAAmB;IAC3C,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC;IAEvC,iGAAiG;IACjG,gGAAgG;IAChG,8FAA8F;IAC9F,8FAA8F;IAC9F,8FAA8F;IAC9F,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,6HAA6H,CAAC,CAAC;IACjJ,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,IAAI,CAAC,YAAY;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACpD,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,MAAgB,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC7G,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;YACtC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,uCAAuC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QACrI,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
|
package/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @mostajs/pdf-sign — fiche LLM
|
|
2
2
|
> Signature numérique de PDF, moteur HYBRIDE : cœur Node (PKCS#7 détaché via @signpdf, zéro Python) + bascule pyhanko (PAdES visible + permissions AES-256 + MOT DE PASSE d'ouverture) quand un venv est disponible. Config 100 % `.env`, CLI + API. Portage générique du pipeline pyhanko+pikepdf éprouvé. IMPLÉMENTÉ 0.1.0.
|
|
3
3
|
|
|
4
|
-
- Version: 0.
|
|
4
|
+
- Version: 0.5.0 · Licence: AGPL-3.0-or-later · Auteur: Dr Hamid MADANI <drmdh@msn.com>
|
|
5
5
|
- Chemin: mostajs/mosta-pdf-sign-stack/mosta-pdf-sign · UI: ../mosta-pdf-sign-ui
|
|
6
6
|
|
|
7
7
|
## RÔLE
|
|
@@ -32,7 +32,15 @@ La signature PAdES + permissions AES-256 garantit intégrité, authenticité et
|
|
|
32
32
|
· opts.timestampUrl : horodatage RFC 3161 → PAdES-T (0.3.0). Horodateur muet ⇒ la signature ÉCHOUE.
|
|
33
33
|
· opts.timestampHeaders / opts.timestampAuth / opts.timestampTimeout (0.4.0) : joindre un
|
|
34
34
|
horodateur QUALIFIÉ, qui authentifie (clé d'API en en-tête, ou HTTP Basic). Exige pyhanko.
|
|
35
|
+
- timestampPdf(opts): Promise<SignResult> (0.6.0) — horodatage de DOCUMENT (DocTimeStamp) ajouté par mise à jour
|
|
36
|
+
incrémentale à un PDF déjà signé : signatures existantes intactes. opts : input, output?, timestampUrl (requis),
|
|
37
|
+
timestampHeaders?/timestampAuth?/timestampTimeout?, openPassword?. Mêmes garde-fous que signPdf, aucun repli.
|
|
38
|
+
Exige pyhanko.
|
|
35
39
|
- verifyPdf(opts): VerifyResult — validation pyhanko complète si dispo, sinon détection Node (/ByteRange)
|
|
40
|
+
0.5.0 : + par signature type, level (PAdES-B-B/B-T/B-LT), claimedSigningTime (DÉCLARÉE), timestamp
|
|
41
|
+
{genTime (ATTESTÉE), policy OID, tsa, chain, intact/valid/trusted}, signerCertificate {subject, issuer,
|
|
42
|
+
notBefore, notAfter, selfSigned}, name/reason/location, coverage ; document : dss. Signature que
|
|
43
|
+
pyhanko refuse = invalide avec `error`, jamais une exception.
|
|
36
44
|
- detectEngines(python?): EngineAvailability — { node:true, pyhanko:bool, python }
|
|
37
45
|
- resolvePython / pyhankoAvailable
|
|
38
46
|
- loadPdfSignConfig(): PdfSignConfig — lecture `.env` via @mostajs/config
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mostajs/pdf-sign",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Signature numérique de PDF pour @mostajs — moteur HYBRIDE : cœur Node (PKCS#7 via @signpdf) + bascule pyhanko (PAdES + permissions AES-256) si disponible. Config .env, CLI, API. Réutilise le pipeline éprouvé pyhanko+pikepdf.",
|
|
5
5
|
"author": "Dr Hamid MADANI <drmdh@msn.com>",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|
|
@@ -9,6 +9,7 @@ ET la validité cryptographique de la signature.
|
|
|
9
9
|
Usage :
|
|
10
10
|
sign_with_perms.py sign INPUT.pdf OUTPUT.pdf CERT.p12 PASSFILE CONFIG.json
|
|
11
11
|
sign_with_perms.py verify PDF [CERT.pem] [MOT_DE_PASSE]
|
|
12
|
+
sign_with_perms.py timestamp INPUT.pdf OUTPUT.pdf CONFIG.json (0.6.0 : horodatage de document)
|
|
12
13
|
|
|
13
14
|
Le moteur Node (@mostajs/pdf-sign) écrit CONFIG.json puis appelle ce script.
|
|
14
15
|
|
|
@@ -212,6 +213,112 @@ def _cert_name(cert):
|
|
|
212
213
|
return str(cert) if cert else ""
|
|
213
214
|
|
|
214
215
|
|
|
216
|
+
def _iso(d):
|
|
217
|
+
try:
|
|
218
|
+
return d.isoformat() if d is not None else None
|
|
219
|
+
except Exception:
|
|
220
|
+
return None
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def _cert_info(c):
|
|
224
|
+
"""Ce qu'un vérificateur doit voir d'un certificat — jamais sa clé."""
|
|
225
|
+
if c is None:
|
|
226
|
+
return None
|
|
227
|
+
try:
|
|
228
|
+
v = c["tbs_certificate"]["validity"]
|
|
229
|
+
return {
|
|
230
|
+
"subject": c.subject.human_friendly,
|
|
231
|
+
"issuer": c.issuer.human_friendly,
|
|
232
|
+
"serial": format(c.serial_number, "x"),
|
|
233
|
+
"notBefore": _iso(v["not_before"].native),
|
|
234
|
+
"notAfter": _iso(v["not_after"].native),
|
|
235
|
+
"selfSigned": c.subject == c.issuer,
|
|
236
|
+
}
|
|
237
|
+
except Exception:
|
|
238
|
+
return {"subject": _cert_name(c)}
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _jeton(token):
|
|
242
|
+
"""Le jeton RFC 3161 : date, politique, autorité, chaîne embarquée."""
|
|
243
|
+
try:
|
|
244
|
+
sd = token["content"]
|
|
245
|
+
tst = sd["encap_content_info"]["content"].parsed
|
|
246
|
+
certs = [c.chosen for c in (sd["certificates"] or [])]
|
|
247
|
+
tsa = certs[0] if certs else None
|
|
248
|
+
sid = sd["signer_infos"][0]["sid"]
|
|
249
|
+
for c in certs: # le certificat qui a SIGNÉ le jeton, pas le premier venu
|
|
250
|
+
if sid.name == "issuer_and_serial_number" and c.serial_number == sid.chosen["serial_number"].native:
|
|
251
|
+
tsa = c
|
|
252
|
+
return {
|
|
253
|
+
"genTime": _iso(tst["gen_time"].native),
|
|
254
|
+
"policy": tst["policy"].dotted,
|
|
255
|
+
"serial": format(tst["serial_number"].native, "x"),
|
|
256
|
+
"hashAlgorithm": tst["message_imprint"]["hash_algorithm"]["algorithm"].native,
|
|
257
|
+
"tsa": _cert_info(tsa),
|
|
258
|
+
"chain": [c.subject.human_friendly for c in certs],
|
|
259
|
+
}
|
|
260
|
+
except Exception:
|
|
261
|
+
return None
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def _details(s, status, est_horodatage, dss):
|
|
265
|
+
d = {"type": "horodatage-document" if est_horodatage else "signature"}
|
|
266
|
+
so = s.sig_object
|
|
267
|
+
for cle, nom in (("/Name", "name"), ("/Reason", "reason"), ("/Location", "location"), ("/SubFilter", "subFilter")):
|
|
268
|
+
try:
|
|
269
|
+
v = so.get(cle)
|
|
270
|
+
d[nom] = str(v).lstrip("/") if v is not None else None
|
|
271
|
+
except Exception:
|
|
272
|
+
d[nom] = None
|
|
273
|
+
try:
|
|
274
|
+
d["claimedSigningTime"] = _iso(s.self_reported_timestamp) # DÉCLARÉE par le signataire
|
|
275
|
+
except Exception:
|
|
276
|
+
d["claimedSigningTime"] = None
|
|
277
|
+
try:
|
|
278
|
+
d["coverage"] = status.coverage.name
|
|
279
|
+
except Exception:
|
|
280
|
+
d["coverage"] = None
|
|
281
|
+
try:
|
|
282
|
+
d["digestAlgorithm"] = status.md_algorithm
|
|
283
|
+
except Exception:
|
|
284
|
+
d["digestAlgorithm"] = None
|
|
285
|
+
try:
|
|
286
|
+
cert = getattr(status, "signing_cert", None) if status is not None else s.signer_cert
|
|
287
|
+
except Exception:
|
|
288
|
+
cert = None
|
|
289
|
+
d["signerCertificate"] = _cert_info(cert)
|
|
290
|
+
jeton = None
|
|
291
|
+
if est_horodatage:
|
|
292
|
+
try:
|
|
293
|
+
jeton = _jeton(s.signed_data_obj if hasattr(s, "signed_data_obj") else None) or None
|
|
294
|
+
except Exception:
|
|
295
|
+
jeton = None
|
|
296
|
+
if jeton is None:
|
|
297
|
+
try:
|
|
298
|
+
from asn1crypto import cms
|
|
299
|
+
jeton = _jeton(cms.ContentInfo({"content_type": "signed_data", "content": s.signed_data}))
|
|
300
|
+
except Exception:
|
|
301
|
+
jeton = None
|
|
302
|
+
else:
|
|
303
|
+
try:
|
|
304
|
+
attrs = s.signer_info["unsigned_attrs"] or []
|
|
305
|
+
toks = [a["values"][0] for a in attrs if a["type"].native == "signature_time_stamp_token"]
|
|
306
|
+
jeton = _jeton(toks[0]) if toks else None
|
|
307
|
+
except Exception:
|
|
308
|
+
jeton = None
|
|
309
|
+
if jeton is not None:
|
|
310
|
+
tv = getattr(status, "timestamp_validity", None) if not est_horodatage else status
|
|
311
|
+
jeton["intact"] = bool(getattr(tv, "intact", False)) if tv is not None else None
|
|
312
|
+
jeton["valid"] = bool(getattr(tv, "valid", False)) if tv is not None else None
|
|
313
|
+
jeton["trusted"] = bool(getattr(tv, "trusted", False)) if tv is not None else None
|
|
314
|
+
d["timestamp"] = jeton
|
|
315
|
+
if est_horodatage:
|
|
316
|
+
d["level"] = "horodatage de document (PAdES-B-LTA)"
|
|
317
|
+
else:
|
|
318
|
+
d["level"] = "PAdES-B-LT" if (jeton and dss) else ("PAdES-B-T" if jeton else "PAdES-B-B")
|
|
319
|
+
return d
|
|
320
|
+
|
|
321
|
+
|
|
215
322
|
def do_verify(pdf_path, cert_pem, open_password=None):
|
|
216
323
|
import logging
|
|
217
324
|
# Silence les logs internes (tracebacks de chaîne de confiance) : on renvoie le verdict en JSON.
|
|
@@ -262,21 +369,85 @@ def do_verify(pdf_path, cert_pem, open_password=None):
|
|
|
262
369
|
print(json.dumps({"signed": False, "signatures": []}))
|
|
263
370
|
return
|
|
264
371
|
out = []
|
|
372
|
+
dss = "/DSS" in r.root
|
|
265
373
|
for s in sigs:
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
374
|
+
est_horodatage = str(s.sig_object.get("/Type", "")) == "/DocTimeStamp"
|
|
375
|
+
# 0.5.0 : une signature que pyhanko REFUSE de valider (structure CMS abîmée, certificat
|
|
376
|
+
# qui ne correspond plus…) est un verdict — invalide —, pas une panne de la vérification.
|
|
377
|
+
# Jusqu'en 0.4.1, l'exception remontait et l'appelant ne lisait plus RIEN du document.
|
|
378
|
+
try:
|
|
379
|
+
if est_horodatage:
|
|
380
|
+
from pyhanko.sign.validation import validate_pdf_timestamp
|
|
381
|
+
status = validate_pdf_timestamp(s, vc)
|
|
382
|
+
else:
|
|
383
|
+
status = validate_pdf_signature(s, vc)
|
|
384
|
+
base = {
|
|
385
|
+
"field": s.field_name,
|
|
386
|
+
"intact": bool(status.intact),
|
|
387
|
+
"valid": bool(status.valid),
|
|
388
|
+
"trusted": bool(getattr(status, "trusted", False)),
|
|
389
|
+
"signer": _cert_name(getattr(status, "signing_cert", None)),
|
|
390
|
+
}
|
|
391
|
+
except Exception as e:
|
|
392
|
+
status = None
|
|
393
|
+
try:
|
|
394
|
+
signataire = s.signer_cert
|
|
395
|
+
except Exception:
|
|
396
|
+
signataire = None
|
|
397
|
+
base = {"field": s.field_name, "intact": False, "valid": False, "trusted": False,
|
|
398
|
+
"signer": _cert_name(signataire), "error": str(e).split("\n")[0][:300]}
|
|
399
|
+
# 0.5.0 — le DÉTAIL, additif : chaque champ est lu à part, et un champ illisible vaut
|
|
400
|
+
# null plutôt que de faire échouer la vérification entière.
|
|
401
|
+
base.update(_details(s, status, est_horodatage, dss))
|
|
402
|
+
out.append(base)
|
|
403
|
+
print(json.dumps({"signed": True, "signatures": out, "dss": dss}, default=str))
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def do_timestamp(inp, outp, config_path):
|
|
407
|
+
"""0.6.0 -- HORODATAGE DE DOCUMENT (PAdES DocTimeStamp), par mise a jour incrementale.
|
|
408
|
+
|
|
409
|
+
Les signatures deja presentes restent intactes : les octets d'origine ne sont pas reecrits. Un document chiffre
|
|
410
|
+
par des permissions (sans mot de passe d'ouverture) s'ouvre avec la chaine vide -- les permissions posees a la
|
|
411
|
+
signature laissent toujours `modify_form`. Aucun repli : un horodateur qui ne repond pas fait echouer.
|
|
412
|
+
"""
|
|
413
|
+
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
|
|
414
|
+
from pyhanko.sign import signers, timestamps
|
|
415
|
+
|
|
416
|
+
with open(config_path, "r", encoding="utf-8") as f:
|
|
417
|
+
cfg = json.load(f)
|
|
418
|
+
tsa_url = cfg.get("timestamp_url")
|
|
419
|
+
if not tsa_url:
|
|
420
|
+
raise SystemExit("ERREUR -- horodatage impossible : aucune adresse d'horodateur.")
|
|
421
|
+
auth_cfg = cfg.get("timestamp_auth")
|
|
422
|
+
auth = (auth_cfg["user"], auth_cfg.get("password", "")) if auth_cfg else None
|
|
423
|
+
print(f"-- horodatage de document : {tsa_url}%s --" % (" (authentifie)" if auth or cfg.get("timestamp_headers") else ""),
|
|
424
|
+
flush=True)
|
|
425
|
+
timestamper = timestamps.HTTPTimeStamper(
|
|
426
|
+
url=tsa_url, headers=cfg.get("timestamp_headers") or None, auth=auth,
|
|
427
|
+
timeout=cfg.get("timestamp_timeout") or 10,
|
|
428
|
+
)
|
|
429
|
+
with open(inp, "rb") as src:
|
|
430
|
+
writer = IncrementalPdfFileWriter(src)
|
|
431
|
+
if getattr(writer.prev, "encrypted", False):
|
|
432
|
+
from pyhanko.pdf_utils.crypt import AuthStatus
|
|
433
|
+
if writer.encrypt(cfg.get("open_password") or "").status == AuthStatus.FAILED:
|
|
434
|
+
raise SystemExit("ERREUR -- document verrouillé : son mot de passe d'ouverture est requis pour l'horodater.")
|
|
435
|
+
with open(outp, "wb") as out_f:
|
|
436
|
+
try:
|
|
437
|
+
signers.PdfTimeStamper(timestamper).timestamp_pdf(writer, md_algorithm="sha256", output=out_f)
|
|
438
|
+
except Exception as e:
|
|
439
|
+
raise SystemExit(
|
|
440
|
+
f"ERREUR -- horodatage impossible ({tsa_url}) : {_cause_horodatage(e)}. "
|
|
441
|
+
"Le document n'a PAS été horodaté."
|
|
442
|
+
)
|
|
443
|
+
print(f"OK -- PDF horodaté : {outp}", flush=True)
|
|
275
444
|
|
|
276
445
|
|
|
277
446
|
if __name__ == "__main__":
|
|
278
447
|
if len(sys.argv) >= 2 and sys.argv[1] == "sign" and len(sys.argv) == 7:
|
|
279
448
|
do_sign(sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6])
|
|
449
|
+
elif len(sys.argv) == 5 and sys.argv[1] == "timestamp":
|
|
450
|
+
do_timestamp(sys.argv[2], sys.argv[3], sys.argv[4])
|
|
280
451
|
elif len(sys.argv) >= 2 and sys.argv[1] == "verify" and len(sys.argv) >= 3:
|
|
281
452
|
do_verify(sys.argv[2],
|
|
282
453
|
sys.argv[3] if len(sys.argv) > 3 and sys.argv[3] else None,
|