mirror of
https://github.com/typst/typst
synced 2025-05-22 04:55:29 +08:00
WIP: digital signatures
This commit is contained in:
parent
c4dd6fa062
commit
28905fedc1
369
Cargo.lock
generated
369
Cargo.lock
generated
@ -8,6 +8,17 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cipher",
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
@ -141,6 +152,12 @@ version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "biblatex"
|
||||
version = "0.9.3"
|
||||
@ -205,6 +222,24 @@ dependencies = [
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
@ -229,6 +264,15 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cbc"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
|
||||
dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.106"
|
||||
@ -303,6 +347,16 @@ dependencies = [
|
||||
"half",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"inout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "citationberg"
|
||||
version = "0.3.1"
|
||||
@ -372,6 +426,18 @@ dependencies = [
|
||||
"roff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cms"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b77c319abfd5219629c45c34c89ba945ed3c5e49fcde9d16b6c3885f118a730"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"der",
|
||||
"spki",
|
||||
"x509-cert",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cobs"
|
||||
version = "0.2.3"
|
||||
@ -423,6 +489,12 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
@ -448,6 +520,15 @@ dependencies = [
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
@ -497,6 +578,16 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.3.0"
|
||||
@ -524,6 +615,30 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.7.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"der_derive",
|
||||
"flagset",
|
||||
"pem-rfc7468",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "der_derive"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
@ -544,6 +659,18 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"const-oid",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
@ -701,6 +828,12 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flagset"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3ea1ec5f8307826a5b71094dd91fc04d4ae75d5709b20ad351c7fb4815c86ec"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.30"
|
||||
@ -791,6 +924,16 @@ version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
@ -873,6 +1016,15 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hypher"
|
||||
version = "0.1.5"
|
||||
@ -1136,6 +1288,16 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inout"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.13"
|
||||
@ -1239,6 +1401,15 @@ dependencies = [
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
dependencies = [
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
@ -1449,6 +1620,23 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint-dig"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"lazy_static",
|
||||
"libm",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-traits",
|
||||
"rand",
|
||||
"smallvec",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
@ -1475,6 +1663,17 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
@ -1482,6 +1681,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1647,11 +1847,19 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||
|
||||
[[package]]
|
||||
name = "pbkdf2"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"hmac",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pdf-writer"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af6a7882fda7808481d43c51cadfc3ec934c6af72612a1fe6985ce329a2f0469"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"itoa",
|
||||
@ -1659,6 +1867,15 @@ dependencies = [
|
||||
"ryu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
@ -1722,6 +1939,44 @@ dependencies = [
|
||||
"ttf-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs1"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
|
||||
dependencies = [
|
||||
"der",
|
||||
"pkcs8",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs5"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"cbc",
|
||||
"der",
|
||||
"pbkdf2",
|
||||
"scrypt",
|
||||
"sha2",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs8"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
|
||||
dependencies = [
|
||||
"der",
|
||||
"pkcs5",
|
||||
"rand_core",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.30"
|
||||
@ -1859,6 +2114,8 @@ version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
@ -1877,6 +2134,9 @@ name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
@ -1999,6 +2259,26 @@ version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"digest",
|
||||
"num-bigint-dig",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"pkcs1",
|
||||
"pkcs8",
|
||||
"rand_core",
|
||||
"signature",
|
||||
"spki",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
@ -2055,6 +2335,15 @@ version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "salsa20"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213"
|
||||
dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
@ -2079,6 +2368,17 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "scrypt"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f"
|
||||
dependencies = [
|
||||
"pbkdf2",
|
||||
"salsa20",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.11.0"
|
||||
@ -2184,12 +2484,33 @@ dependencies = [
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shell-escape"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
@ -2238,6 +2559,16 @@ version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"der",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
@ -2310,6 +2641,12 @@ name = "subsetter"
|
||||
version = "0.11.0"
|
||||
source = "git+https://github.com/typst/subsetter?rev=4e0058b#4e0058b4b9a0948a5f79894111948d95e59ba350"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "svg2pdf"
|
||||
version = "0.11.0"
|
||||
@ -2588,6 +2925,12 @@ version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "typst"
|
||||
version = "0.11.0"
|
||||
@ -2777,6 +3120,7 @@ dependencies = [
|
||||
"arrayvec",
|
||||
"base64",
|
||||
"bytemuck",
|
||||
"cms",
|
||||
"comemo",
|
||||
"ecow",
|
||||
"image",
|
||||
@ -2784,6 +3128,10 @@ dependencies = [
|
||||
"miniz_oxide",
|
||||
"once_cell",
|
||||
"pdf-writer",
|
||||
"pkcs8",
|
||||
"rand",
|
||||
"rsa",
|
||||
"sha2",
|
||||
"subsetter",
|
||||
"svg2pdf",
|
||||
"ttf-parser",
|
||||
@ -3406,6 +3754,17 @@ dependencies = [
|
||||
"tap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x509-cert"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"der",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.3.1"
|
||||
@ -3528,6 +3887,12 @@ dependencies = [
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
||||
|
||||
[[package]]
|
||||
name = "zerotrie"
|
||||
version = "0.1.3"
|
||||
|
@ -39,6 +39,7 @@ ciborium = "0.2.1"
|
||||
clap = { version = "4.4", features = ["derive", "env"] }
|
||||
clap_complete = "4.2.1"
|
||||
clap_mangen = "0.2.10"
|
||||
cms = "0.2.3"
|
||||
ctrlc = "3.4.1"
|
||||
codespan-reporting = "0.11"
|
||||
comemo = "0.4"
|
||||
@ -78,16 +79,19 @@ pathdiff = "0.2"
|
||||
pdf-writer = "0.10.0"
|
||||
phf = { version = "0.11", features = ["macros"] }
|
||||
pixglyph = "0.4"
|
||||
pkcs8 = { version = "0.10.2", features = ["pkcs5", "encryption"] }
|
||||
png = "0.17"
|
||||
portable-atomic = "1.6"
|
||||
proc-macro2 = "1"
|
||||
pulldown-cmark = "0.9"
|
||||
quote = "1"
|
||||
qcms = "0.3.0"
|
||||
rand = "0.8.5"
|
||||
rayon = "1.7.0"
|
||||
regex = "1"
|
||||
resvg = { version = "0.42", default-features = false, features = ["raster-images"] }
|
||||
roxmltree = "0.20"
|
||||
rsa = "0.9.6"
|
||||
rustybuzz = "0.14"
|
||||
same-file = "1"
|
||||
self-replace = "1.3.7"
|
||||
@ -95,6 +99,7 @@ semver = "1"
|
||||
serde = { version = "1.0.184", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
serde_yaml = "0.9"
|
||||
sha2 = { version = "0.10.8", featurs = ["oid"] }
|
||||
shell-escape = "0.1.5"
|
||||
siphasher = "1"
|
||||
smallvec = { version = "1.11.1", features = ["union", "const_generics", "const_new"] }
|
||||
@ -126,6 +131,7 @@ xmlparser = "0.13.5"
|
||||
xmlwriter = "0.1.0"
|
||||
xmp-writer = "0.2"
|
||||
xz2 = { version = "0.1", features = ["static"] }
|
||||
x509-cert = "0.2.5"
|
||||
yaml-front-matter = "0.1"
|
||||
zip = { version = "2", default-features = false, features = ["deflate"] }
|
||||
|
||||
@ -142,3 +148,6 @@ strip = true
|
||||
[workspace.lints.clippy]
|
||||
uninlined_format_args = "warn"
|
||||
blocks_in_conditions = "allow"
|
||||
|
||||
[patch.crates-io]
|
||||
pdf-writer = { path = "../pdf-writer" }
|
||||
|
@ -17,8 +17,10 @@ typst = { workspace = true }
|
||||
typst-assets = { workspace = true }
|
||||
typst-macros = { workspace = true }
|
||||
typst-timing = { workspace = true }
|
||||
arrayvec = { workspace = true }
|
||||
base64 = { workspace = true }
|
||||
bytemuck = { workspace = true }
|
||||
cms = { workspace = true }
|
||||
comemo = { workspace = true }
|
||||
ecow = { workspace = true }
|
||||
image = { workspace = true }
|
||||
@ -26,7 +28,10 @@ indexmap = { workspace = true }
|
||||
miniz_oxide = { workspace = true }
|
||||
once_cell = { workspace = true }
|
||||
pdf-writer = { workspace = true }
|
||||
arrayvec = { workspace = true }
|
||||
pkcs8 = { workspace = true, features = ["pkcs5", "encryption"] }
|
||||
rand = { workspace = true }
|
||||
rsa = { workspace = true }
|
||||
sha2 = { workspace = true, features = ["oid"] }
|
||||
subsetter = { workspace = true }
|
||||
svg2pdf = { workspace = true }
|
||||
ttf-parser = { workspace = true }
|
||||
|
@ -10,17 +10,17 @@ use typst::foundations::{Datetime, Smart};
|
||||
use typst::layout::Dir;
|
||||
use typst::text::Lang;
|
||||
|
||||
use crate::WithEverything;
|
||||
use crate::{hash_base64, outline, page::PdfPageLabel};
|
||||
use crate::{signature, WithEverything};
|
||||
|
||||
/// Write the document catalog.
|
||||
pub fn write_catalog(
|
||||
ctx: WithEverything,
|
||||
ident: Smart<&str>,
|
||||
timestamp: Option<Datetime>,
|
||||
pdf: &mut Pdf,
|
||||
mut pdf: Pdf,
|
||||
alloc: &mut Ref,
|
||||
) {
|
||||
) -> Vec<u8> {
|
||||
let lang = ctx
|
||||
.resources
|
||||
.languages
|
||||
@ -35,10 +35,10 @@ pub fn write_catalog(
|
||||
};
|
||||
|
||||
// Write the outline tree.
|
||||
let outline_root_id = outline::write_outline(pdf, alloc, &ctx);
|
||||
let outline_root_id = outline::write_outline(&mut pdf, alloc, &ctx);
|
||||
|
||||
// Write the page labels.
|
||||
let page_labels = write_page_labels(pdf, alloc, &ctx);
|
||||
let page_labels = write_page_labels(&mut pdf, alloc, &ctx);
|
||||
|
||||
// Write the document information.
|
||||
let info_ref = alloc.bump();
|
||||
@ -132,6 +132,9 @@ pub fn write_catalog(
|
||||
.pair(Name(b"Type"), Name(b"Metadata"))
|
||||
.pair(Name(b"Subtype"), Name(b"XML"));
|
||||
|
||||
// Prepare digital signatures
|
||||
let (signature_range, signature_form_ref) = signature::prepare(alloc, &mut pdf);
|
||||
|
||||
// Write the document catalog.
|
||||
let catalog_ref = alloc.bump();
|
||||
let mut catalog = pdf.catalog(catalog_ref);
|
||||
@ -167,7 +170,11 @@ pub fn write_catalog(
|
||||
catalog.lang(TextStr(lang.as_str()));
|
||||
}
|
||||
|
||||
catalog.insert(Name(b"AcroForm")).primitive(signature_form_ref);
|
||||
|
||||
catalog.finish();
|
||||
|
||||
signature::write(signature_range, pdf.finish())
|
||||
}
|
||||
|
||||
/// Write the page labels.
|
||||
|
@ -13,6 +13,7 @@ mod outline;
|
||||
mod page;
|
||||
mod pattern;
|
||||
mod resources;
|
||||
mod signature;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::hash::Hash;
|
||||
@ -348,10 +349,9 @@ impl<S> PdfBuilder<S> {
|
||||
process: P,
|
||||
) -> Vec<u8>
|
||||
where
|
||||
P: Fn(S, Smart<&str>, Option<Datetime>, &mut Pdf, &mut Ref),
|
||||
P: Fn(S, Smart<&str>, Option<Datetime>, Pdf, &mut Ref) -> Vec<u8>,
|
||||
{
|
||||
process(self.state, ident, timestamp, &mut self.pdf, &mut self.alloc);
|
||||
self.pdf.finish()
|
||||
process(self.state, ident, timestamp, self.pdf, &mut self.alloc)
|
||||
}
|
||||
}
|
||||
|
||||
|
168
crates/typst-pdf/src/signature.rs
Normal file
168
crates/typst-pdf/src/signature.rs
Normal file
@ -0,0 +1,168 @@
|
||||
use pkcs8::DecodePrivateKey;
|
||||
use sha2::{
|
||||
digest::const_oid::db::rfc5912::{ID_SHA_512, SHA_512_WITH_RSA_ENCRYPTION},
|
||||
Digest,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
use cms::{
|
||||
cert::{
|
||||
x509::{
|
||||
der::{
|
||||
asn1::{OctetString, SetOfVec},
|
||||
oid::db::rfc5911::{ID_DATA, ID_SIGNED_DATA},
|
||||
Any, AnyRef, Encode,
|
||||
},
|
||||
spki::AlgorithmIdentifier,
|
||||
Certificate,
|
||||
},
|
||||
CertificateChoices, IssuerAndSerialNumber,
|
||||
},
|
||||
content_info::{CmsVersion, ContentInfo},
|
||||
signed_data::{
|
||||
CertificateSet, EncapsulatedContentInfo, SignedData, SignerIdentifier,
|
||||
SignerInfo, SignerInfos,
|
||||
},
|
||||
};
|
||||
use pdf_writer::{
|
||||
types::{FieldType, SigFlags},
|
||||
writers::{Field, Form},
|
||||
Finish, Name, Pdf, Primitive, Ref, Str,
|
||||
};
|
||||
use rsa::{traits::SignatureScheme, Pkcs1v15Sign, RsaPrivateKey};
|
||||
use sha2::Sha512;
|
||||
|
||||
const SIG_SIZE: usize = 1024 * 4;
|
||||
|
||||
pub fn prepare(alloc: &mut Ref, pdf: &mut Pdf) -> (Range<usize>, Ref) {
|
||||
let form_ref = alloc.bump();
|
||||
let signature_field_ref = alloc.bump();
|
||||
|
||||
let mut signature_field: Field = pdf.indirect(signature_field_ref).start();
|
||||
signature_field.field_type(FieldType::Signature);
|
||||
let mut signature_dict = signature_field.insert(Name(b"V")).dict();
|
||||
signature_dict.pair(Name(b"Type"), Name(b"Sig"));
|
||||
signature_dict.pair(Name(b"Filter"), Name(b"Adobe.PPKLite"));
|
||||
signature_dict.pair(Name(b"SubFilter"), Name(b"adbe.pkcs7.detached"));
|
||||
let mut placeholder = [0; SIG_SIZE];
|
||||
placeholder[0] = 255; // Make sure pdf-writer writes this array as binary
|
||||
let sig_end = signature_dict
|
||||
.pair(Name(b"Contents"), Str(&placeholder))
|
||||
.current_len();
|
||||
let sig_start = sig_end
|
||||
- SIG_SIZE * 2 // 2 chars to write each byte
|
||||
- 2; // take < and > into account;
|
||||
signature_dict
|
||||
.insert(Name(b"ByteRange"))
|
||||
.array()
|
||||
.items([0, sig_start as i32, sig_end as i32])
|
||||
.item(Str(b"typst-document-size"));
|
||||
signature_dict.finish();
|
||||
signature_field.finish();
|
||||
|
||||
let mut form: Form = pdf.indirect(form_ref).start();
|
||||
form.fields([signature_field_ref]);
|
||||
form.sig_flags(SigFlags::SIGNATURES_EXIST);
|
||||
|
||||
(sig_start..sig_end, form_ref)
|
||||
}
|
||||
|
||||
pub fn write(range: Range<usize>, mut bytes: Vec<u8>) -> Vec<u8> {
|
||||
let needle = b"(typst-document-size)";
|
||||
let doc_size_start = bytes[range.end..]
|
||||
.windows(needle.len())
|
||||
.position(|x| x == needle)
|
||||
.unwrap();
|
||||
let doc_size_range = doc_size_start..(doc_size_start + needle.len());
|
||||
dbg!(&range, &doc_size_range);
|
||||
let mut actual_size = Vec::new();
|
||||
<i32 as pdf_writer::Primitive>::write(bytes.len() as i32, &mut actual_size);
|
||||
actual_size.extend(std::iter::repeat(b' ').take(needle.len() - actual_size.len()));
|
||||
bytes.splice(
|
||||
doc_size_range.start + range.end..doc_size_range.end + range.end,
|
||||
actual_size,
|
||||
);
|
||||
|
||||
let mut hasher = Sha512::new();
|
||||
hasher.update(&bytes[0..range.start]);
|
||||
hasher.update(&bytes[range.end..]);
|
||||
let hashed = hasher.finalize();
|
||||
|
||||
let priv_key =
|
||||
RsaPrivateKey::from_pkcs8_encrypted_pem(include_str!("../../../key.pem"), "abcd")
|
||||
.unwrap();
|
||||
let signer = Pkcs1v15Sign::new::<Sha512>();
|
||||
let signature =
|
||||
signer.sign(Some(&mut rand::rngs::OsRng), &priv_key, &hashed).unwrap();
|
||||
|
||||
let pem_chain =
|
||||
Certificate::load_pem_chain(include_bytes!("../../../cert.pem")).unwrap();
|
||||
let sig_data = ContentInfo {
|
||||
content_type: ID_SIGNED_DATA,
|
||||
content: Any::from(
|
||||
AnyRef::try_from(
|
||||
SignedData {
|
||||
version: CmsVersion::V0,
|
||||
digest_algorithms: SetOfVec::try_from(vec![AlgorithmIdentifier {
|
||||
oid: SHA_512_WITH_RSA_ENCRYPTION,
|
||||
parameters: None,
|
||||
}])
|
||||
.unwrap(),
|
||||
encap_content_info: EncapsulatedContentInfo {
|
||||
econtent_type: ID_DATA,
|
||||
econtent: None,
|
||||
},
|
||||
certificates: Some(CertificateSet(
|
||||
SetOfVec::from_iter(
|
||||
pem_chain
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(CertificateChoices::Certificate),
|
||||
)
|
||||
.unwrap(),
|
||||
)),
|
||||
crls: None,
|
||||
signer_infos: SignerInfos(
|
||||
SetOfVec::from_iter(pem_chain.into_iter().map(|cert| {
|
||||
SignerInfo {
|
||||
version: CmsVersion::V1,
|
||||
sid: SignerIdentifier::IssuerAndSerialNumber(
|
||||
IssuerAndSerialNumber {
|
||||
issuer: cert.tbs_certificate.issuer,
|
||||
serial_number: cert.tbs_certificate.serial_number,
|
||||
},
|
||||
),
|
||||
digest_alg: AlgorithmIdentifier {
|
||||
oid: ID_SHA_512,
|
||||
parameters: None,
|
||||
},
|
||||
signed_attrs: None, // TODO: should contain revocation information (see section 12.8.3.3.2)
|
||||
signature_algorithm: AlgorithmIdentifier {
|
||||
oid: SHA_512_WITH_RSA_ENCRYPTION,
|
||||
parameters: None,
|
||||
},
|
||||
signature: OctetString::new(&signature[..]).unwrap(),
|
||||
unsigned_attrs: None, // TODO: should contain timestamp
|
||||
}
|
||||
}))
|
||||
.unwrap(),
|
||||
),
|
||||
}
|
||||
.to_der()
|
||||
.unwrap()
|
||||
.as_slice(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
};
|
||||
let mut sig = sig_data.to_der().unwrap();
|
||||
// pad with 0 to keep the ranges correct
|
||||
sig.extend(std::iter::repeat(0).take(SIG_SIZE - sig.len()));
|
||||
let mut encoded_sig = Vec::with_capacity(sig.len() * 2);
|
||||
Str(&sig).write(&mut encoded_sig);
|
||||
|
||||
dbg!(range.len(), encoded_sig.len());
|
||||
bytes.splice(range, encoded_sig);
|
||||
|
||||
bytes
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user