mirror of
https://github.com/mtrojnar/osslsigncode.git
synced 2025-04-05 09:08:04 -05:00
Compare commits
434 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4568c890cc | ||
![]() |
4bd167a8be | ||
![]() |
e7405fa839 | ||
![]() |
776e2ec7b6 | ||
![]() |
838aaaee8d | ||
![]() |
e8f19a6efe | ||
![]() |
3a8e25e5bb | ||
![]() |
7d1b460dfe | ||
![]() |
bc3e9e2172 | ||
![]() |
21bce757ef | ||
![]() |
6a43f62835 | ||
![]() |
8780e6f8e4 | ||
![]() |
78a23caa54 | ||
![]() |
d92927aff4 | ||
![]() |
4f412b5989 | ||
![]() |
e6f3ff631d | ||
![]() |
09135aabb8 | ||
![]() |
de983e680f | ||
![]() |
dc827b94e5 | ||
![]() |
40ce811701 | ||
![]() |
db5b4c4dc0 | ||
![]() |
4ee429792d | ||
![]() |
27686c0b0c | ||
![]() |
21133f9c3b | ||
![]() |
64305d6415 | ||
![]() |
4dd836bab1 | ||
![]() |
f57c213207 | ||
![]() |
76ee550c9d | ||
![]() |
2b3228d549 | ||
![]() |
bad6e96e0f | ||
![]() |
3c8c74a8c3 | ||
![]() |
771014a41e | ||
![]() |
476168e09e | ||
![]() |
be4f010535 | ||
![]() |
2c27e2e37d | ||
![]() |
b829e7a802 | ||
![]() |
d0ae214cb4 | ||
![]() |
9b1a6c9fb8 | ||
![]() |
41b662a8fe | ||
![]() |
5232734071 | ||
![]() |
996cf20fa9 | ||
![]() |
825c9dad7c | ||
![]() |
6e5bef14e9 | ||
![]() |
a53bd2bdb3 | ||
![]() |
e4d471b885 | ||
![]() |
bcb9737dda | ||
![]() |
7a5389b719 | ||
![]() |
d9f0a8dade | ||
![]() |
aa8c8dd720 | ||
![]() |
16c5e5aa4a | ||
![]() |
ded1f7aa67 | ||
![]() |
6ad2679f17 | ||
![]() |
4776f43f04 | ||
![]() |
d9db038c65 | ||
![]() |
e8ef027776 | ||
![]() |
0a0761746f | ||
![]() |
f51e2a4869 | ||
![]() |
093ed12c66 | ||
![]() |
71a046a2d0 | ||
![]() |
c73f82b558 | ||
![]() |
b294f5d18f | ||
![]() |
e07bb7d6b2 | ||
![]() |
699bc85d0a | ||
![]() |
192e7a732b | ||
![]() |
656051676f | ||
![]() |
3998bcabb2 | ||
![]() |
fa40c57f80 | ||
![]() |
0b93a94ffa | ||
![]() |
105fd3af4a | ||
![]() |
86a594b087 | ||
![]() |
1dea73b038 | ||
![]() |
b661ed08ed | ||
![]() |
ead0584611 | ||
![]() |
bd7751147e | ||
![]() |
1bc7fc36b8 | ||
![]() |
42e9733916 | ||
![]() |
b2024cee9d | ||
![]() |
9d152b8477 | ||
![]() |
7a02d51a83 | ||
![]() |
dac68a3a4d | ||
![]() |
bd1ab77f44 | ||
![]() |
5ee859db2c | ||
![]() |
ee3c51f6d5 | ||
![]() |
cedb8b5798 | ||
![]() |
dcf58a00e7 | ||
![]() |
4576895718 | ||
![]() |
1bdcad619e | ||
![]() |
31b046cf98 | ||
![]() |
f3ac2c0c6f | ||
![]() |
f22c83514c | ||
![]() |
44ca1f38e6 | ||
![]() |
0985c47990 | ||
![]() |
aa158e40ec | ||
![]() |
5da62de5ef | ||
![]() |
4d08fbb2c1 | ||
![]() |
98b004edda | ||
![]() |
34bf3bc525 | ||
![]() |
64e1bba96b | ||
![]() |
46bcaa9d88 | ||
![]() |
867e0d446d | ||
![]() |
7285778cb0 | ||
![]() |
c909ba82d7 | ||
![]() |
7b60d6447d | ||
![]() |
588a1a0b5f | ||
![]() |
8a9b275494 | ||
![]() |
0db17be606 | ||
![]() |
f9ad19d4a2 | ||
![]() |
b9ca24d423 | ||
![]() |
8d2b562244 | ||
![]() |
6f4e9ab597 | ||
![]() |
6d6270094e | ||
![]() |
57563716d1 | ||
![]() |
8ab8a133f7 | ||
![]() |
ef5047038e | ||
![]() |
e290e03341 | ||
![]() |
900ffed596 | ||
![]() |
33253afb5e | ||
![]() |
3aba55e5e0 | ||
![]() |
898a53b2a7 | ||
![]() |
75ce1dadf5 | ||
![]() |
4166476030 | ||
![]() |
a5690f2d19 | ||
![]() |
cdb75578e9 | ||
![]() |
e2ab4a152d | ||
![]() |
b8e690f3bd | ||
![]() |
c89d6b43aa | ||
![]() |
9faed39931 | ||
![]() |
ecb17709fc | ||
![]() |
9ebd79ad18 | ||
![]() |
1700455533 | ||
![]() |
a6f767f5a3 | ||
![]() |
4c5b329bc4 | ||
![]() |
5626482e82 | ||
![]() |
2d21a2121c | ||
![]() |
5d2bf2c80f | ||
![]() |
5b8376ce32 | ||
![]() |
1fc2c937f2 | ||
![]() |
2ed54490a6 | ||
![]() |
a096aa8a33 | ||
![]() |
aa08566a63 | ||
![]() |
c04b229ce2 | ||
![]() |
adcfd9a33f | ||
![]() |
f2f3a8891c | ||
![]() |
29eedf9059 | ||
![]() |
d6f94d71f7 | ||
![]() |
a509a66c65 | ||
![]() |
7bf4c92d83 | ||
![]() |
0a0fdfe96a | ||
![]() |
199f2b4586 | ||
![]() |
a92c4a5522 | ||
![]() |
dc44ed5f5b | ||
![]() |
c6990878c2 | ||
![]() |
abbbfabdc7 | ||
![]() |
2a4b75842a | ||
![]() |
56e7a72e8a | ||
![]() |
b61bcaac2e | ||
![]() |
924af9e783 | ||
![]() |
cb80c7d188 | ||
![]() |
76bb06bf7e | ||
![]() |
4b6027a4f7 | ||
![]() |
de6a65cc67 | ||
![]() |
c90166ba8d | ||
![]() |
b00ceee310 | ||
![]() |
54e61cb76a | ||
![]() |
fb731f2b5e | ||
![]() |
eec5a0755d | ||
![]() |
41d98c3917 | ||
![]() |
7fa0b21ddd | ||
![]() |
e0eb331baf | ||
![]() |
7bb21c3539 | ||
![]() |
edcb18d63f | ||
![]() |
3d7b8d2a21 | ||
![]() |
7bfe3b5db9 | ||
![]() |
dd365d68c4 | ||
![]() |
09555e8c05 | ||
![]() |
e4aa06f0c0 | ||
![]() |
46e9ee447f | ||
![]() |
3e7247d9dc | ||
![]() |
d2f1b9c035 | ||
![]() |
4199310cdf | ||
![]() |
0204d04a25 | ||
![]() |
246f0abbfc | ||
![]() |
0f51a06b8f | ||
![]() |
44a6768089 | ||
![]() |
93f5f800d6 | ||
![]() |
4db6ed0cad | ||
![]() |
32b65659be | ||
![]() |
8e74a05b40 | ||
![]() |
83e47e0252 | ||
![]() |
41e6042c26 | ||
![]() |
33c1fdaa85 | ||
![]() |
11eb76d4f3 | ||
![]() |
b0391244a6 | ||
![]() |
83f6ceeaea | ||
![]() |
b96a7a2232 | ||
![]() |
ff8034af2e | ||
![]() |
bde67ec1e2 | ||
![]() |
c5ad70d31a | ||
![]() |
27a2a2bfa3 | ||
![]() |
827f167f8b | ||
![]() |
4098a5efc7 | ||
![]() |
e88bc1ca14 | ||
![]() |
dd2aaf0804 | ||
![]() |
08113a08cb | ||
![]() |
29843ccf40 | ||
![]() |
5fef4faf47 | ||
![]() |
5981c740c9 | ||
![]() |
f3af509973 | ||
![]() |
c29e14e697 | ||
![]() |
4da5526c05 | ||
![]() |
4ec23dbaa5 | ||
![]() |
d9979c4bc6 | ||
![]() |
695892b8bf | ||
![]() |
192ff59916 | ||
![]() |
506daf84ac | ||
![]() |
bb6322e378 | ||
![]() |
b0eaa96d45 | ||
![]() |
fade782e58 | ||
![]() |
199a852c12 | ||
![]() |
95a8a9d9c1 | ||
![]() |
c197d7727c | ||
![]() |
efbe570f27 | ||
![]() |
fef65536f6 | ||
![]() |
1155a9c338 | ||
![]() |
f67ca8aac5 | ||
![]() |
d59601f2b9 | ||
![]() |
7f87f930f7 | ||
![]() |
dadca2516d | ||
![]() |
a862378280 | ||
![]() |
c4ec6debe5 | ||
![]() |
08c205a02f | ||
![]() |
acfece2c26 | ||
![]() |
61cf89f26f | ||
![]() |
07a927f34a | ||
![]() |
257cb1fb08 | ||
![]() |
c48a6cdef0 | ||
![]() |
8bba4496c0 | ||
![]() |
dfc13c9bf8 | ||
![]() |
f57b469c29 | ||
![]() |
c718882ffb | ||
![]() |
3109bdf0ab | ||
![]() |
7aca21b481 | ||
![]() |
8c113b3a86 | ||
![]() |
f3a5ecce9c | ||
![]() |
1c678bf926 | ||
![]() |
454e15326d | ||
![]() |
db556d0a2d | ||
![]() |
8bdd22c183 | ||
![]() |
cc4e5a5076 | ||
![]() |
b8cb44fa47 | ||
![]() |
36cdea56de | ||
![]() |
77e63fa0cb | ||
![]() |
225ce9bbd6 | ||
![]() |
a5011a00c5 | ||
![]() |
f9006f099a | ||
![]() |
b9664394a5 | ||
![]() |
68c4163332 | ||
![]() |
c143eff68f | ||
![]() |
cbdbd9dbd0 | ||
![]() |
20bfc0ffeb | ||
![]() |
8e075d625d | ||
![]() |
4eeaee4c16 | ||
![]() |
6da29943ea | ||
![]() |
431d6ab1bd | ||
![]() |
5d51f0e2c7 | ||
![]() |
4d476213d4 | ||
![]() |
21c196342f | ||
![]() |
b8d83bb15e | ||
![]() |
abf5aa68f8 | ||
![]() |
762dd8a21b | ||
![]() |
86e4eb9252 | ||
![]() |
7510e3c553 | ||
![]() |
225a8f78fa | ||
![]() |
23288f5a00 | ||
![]() |
0e80573c58 | ||
![]() |
8f6d1617eb | ||
![]() |
15185acb0a | ||
![]() |
703ae70602 | ||
![]() |
c59f5dd02c | ||
![]() |
0a9dcbda6c | ||
![]() |
f87618326f | ||
![]() |
80de8e7738 | ||
![]() |
306d467a29 | ||
![]() |
d0a958919d | ||
![]() |
81b58f744d | ||
![]() |
8f30bf28e7 | ||
![]() |
a12b5c0951 | ||
![]() |
5bf24b34a2 | ||
![]() |
7871e28141 | ||
![]() |
d7daf98db8 | ||
![]() |
1d0918c84d | ||
![]() |
f42459ff09 | ||
![]() |
66a6a1ced5 | ||
![]() |
a44c8decbc | ||
![]() |
d556fb78dc | ||
![]() |
4c856f3a1e | ||
![]() |
1bf5f9a07b | ||
![]() |
c930d9aa7a | ||
![]() |
5df8d7c181 | ||
![]() |
cf20354b91 | ||
![]() |
665ecfb64c | ||
![]() |
6430bf0036 | ||
![]() |
92673b8f00 | ||
![]() |
3d0640a2cc | ||
![]() |
28c68aeebf | ||
![]() |
26b7d5f617 | ||
![]() |
88bf99dec8 | ||
![]() |
757d9c39a4 | ||
![]() |
ce2d586956 | ||
![]() |
396318dcd1 | ||
![]() |
24ed108099 | ||
![]() |
7b29b45348 | ||
![]() |
6b3450ada8 | ||
![]() |
ac3e8e5221 | ||
![]() |
99400d92d6 | ||
![]() |
b63b023c5c | ||
![]() |
6ffe7fa0de | ||
![]() |
b7d4c72756 | ||
![]() |
fb19651926 | ||
![]() |
213ea27f99 | ||
![]() |
a19d77a8a7 | ||
![]() |
6a873c3a49 | ||
![]() |
a892c50147 | ||
![]() |
95615faf1d | ||
![]() |
860e8d6f4e | ||
![]() |
60fe5d15fe | ||
![]() |
b96717506c | ||
![]() |
157bb78a6e | ||
![]() |
4396c451eb | ||
![]() |
40bd33ee01 | ||
![]() |
d7ae7c90f9 | ||
![]() |
247a82232c | ||
![]() |
3a84987107 | ||
![]() |
afda3cc810 | ||
![]() |
44eeeb1515 | ||
![]() |
1c523ed616 | ||
![]() |
8ba94fafd9 | ||
![]() |
82185eef18 | ||
![]() |
bec2ae2eed | ||
![]() |
c5c23cefac | ||
![]() |
4c1b972f9e | ||
![]() |
1bd9a87e2f | ||
![]() |
65d17836ab | ||
![]() |
6a1a884f3c | ||
![]() |
98308f2e0a | ||
![]() |
da4413d0c7 | ||
![]() |
c08b8cb3d5 | ||
![]() |
5af84745de | ||
![]() |
0459fb99ef | ||
![]() |
73d7cf011e | ||
![]() |
7affd85c46 | ||
![]() |
d8a182614c | ||
![]() |
ac672640be | ||
![]() |
5d68e8699a | ||
![]() |
b48458499b | ||
![]() |
4731667c35 | ||
![]() |
85594d9fb2 | ||
![]() |
5f60cc6563 | ||
![]() |
77b2b30d1f | ||
![]() |
e0d652b987 | ||
![]() |
b774a56aa9 | ||
![]() |
6eaf0d9368 | ||
![]() |
d471b51db5 | ||
![]() |
7b12abf21f | ||
![]() |
f248286d6f | ||
![]() |
5db237f242 | ||
![]() |
95c5a4451b | ||
![]() |
f0207411b9 | ||
![]() |
aef958f880 | ||
![]() |
a6d3be739e | ||
![]() |
4eeeec32b4 | ||
![]() |
ce196ce147 | ||
![]() |
289c345280 | ||
![]() |
bdea1d1c2a | ||
![]() |
45fedd9e50 | ||
![]() |
e177ded9a5 | ||
![]() |
5a2d0affc1 | ||
![]() |
5afafecc23 | ||
![]() |
07bf24911d | ||
![]() |
357747d2fc | ||
![]() |
28f6ffbc42 | ||
![]() |
fb75eee385 | ||
![]() |
6e2fb03b7b | ||
![]() |
46d43d70b3 | ||
![]() |
407579ca58 | ||
![]() |
96df1a709f | ||
![]() |
8c37b00d83 | ||
![]() |
f2559972f3 | ||
![]() |
057d38ee76 | ||
![]() |
ed8ee4194b | ||
![]() |
c64add388b | ||
![]() |
2912eb054c | ||
![]() |
de05123adc | ||
![]() |
180b352102 | ||
![]() |
72de045151 | ||
![]() |
95d77c9b98 | ||
![]() |
64e7e26eba | ||
![]() |
e26a50a618 | ||
![]() |
d2aa35a7f6 | ||
![]() |
1c175c4339 | ||
![]() |
3dad092be9 | ||
![]() |
de0bf341a5 | ||
![]() |
4d5052c3f4 | ||
![]() |
04823393f2 | ||
![]() |
cfb897a902 | ||
![]() |
8b064ca814 | ||
![]() |
1bdfcc8940 | ||
![]() |
bcdc5b7030 | ||
![]() |
3908e874a4 | ||
![]() |
a161efdb25 | ||
![]() |
b01a2f5cd7 | ||
![]() |
b6e6165782 | ||
![]() |
9b3697ad76 | ||
![]() |
758003156e | ||
![]() |
4f590989ce | ||
![]() |
6df4c12624 | ||
![]() |
315357f092 | ||
![]() |
c0d9569c4f | ||
![]() |
352ef49b3a | ||
![]() |
f004aa3f48 | ||
![]() |
6edd56bfac | ||
![]() |
67e4edfe45 | ||
![]() |
5ad5260351 | ||
![]() |
790abf66da | ||
![]() |
1dc209baa8 | ||
![]() |
2f011cfc31 | ||
![]() |
e8fe3e934d | ||
![]() |
f8849b8048 | ||
![]() |
86d593f264 | ||
![]() |
5e064233a3 | ||
![]() |
fb1bc06440 | ||
![]() |
80d5948eeb | ||
![]() |
0d6d0071d3 | ||
![]() |
250521e07f |
237
.github/workflows/ci.yml
vendored
Normal file
237
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: Release
|
||||
version: osslsigncode-2.10-dev
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- id: ubuntu-24.04
|
||||
triplet: x64-linux
|
||||
compiler: gcc
|
||||
os: ubuntu-24.04
|
||||
generator: Unix Makefiles
|
||||
vcpkg_root:
|
||||
- id: ubuntu-22.04
|
||||
triplet: x64-linux
|
||||
compiler: gcc
|
||||
os: ubuntu-22.04
|
||||
generator: Unix Makefiles
|
||||
vcpkg_root:
|
||||
- id: ubuntu-20.04
|
||||
triplet: x64-linux
|
||||
compiler: gcc
|
||||
os: ubuntu-20.04
|
||||
generator: Unix Makefiles
|
||||
vcpkg_root:
|
||||
- id: macOS
|
||||
triplet: arm64-osx
|
||||
compiler: clang
|
||||
os: macOS-latest
|
||||
generator: Unix Makefiles
|
||||
vcpkg_root: /usr/local/share/vcpkg
|
||||
cache: /Users/runner/.cache/vcpkg/archives
|
||||
- id: windows-x64-vs
|
||||
triplet: x64-windows
|
||||
compiler: vs
|
||||
arch: x64
|
||||
os: windows-latest
|
||||
generator: Ninja
|
||||
vcpkg_root: C:/vcpkg
|
||||
cache: C:/Users/runneradmin/AppData/Local/vcpkg/archives
|
||||
- id: windows-x86-vs
|
||||
triplet: x86-windows
|
||||
compiler: vs
|
||||
arch: x86
|
||||
os: windows-latest
|
||||
generator: Ninja
|
||||
vcpkg_root: C:/vcpkg
|
||||
cache: C:/Users/runneradmin/AppData/Local/vcpkg/archives
|
||||
- id: windows-x64-static-vs
|
||||
triplet: x64-windows-static
|
||||
compiler: vs
|
||||
arch: x64
|
||||
os: windows-latest
|
||||
generator: Ninja
|
||||
vcpkg_root: C:/vcpkg
|
||||
cache: C:/Users/runneradmin/AppData/Local/vcpkg/archives
|
||||
- id: windows-x64-mingw
|
||||
triplet: x64-windows
|
||||
compiler: mingw
|
||||
os: windows-latest
|
||||
generator: Ninja
|
||||
vcpkg_root: C:/vcpkg
|
||||
cache: C:/Users/runneradmin/AppData/Local/vcpkg/archives
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
env:
|
||||
VCPKG_ROOT: ${{matrix.vcpkg_root}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Cache the vcpkg archives
|
||||
if: matrix.cache != ''
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{matrix.cache}}
|
||||
key: ${{matrix.id}}-${{hashFiles('vcpkg.json')}}
|
||||
restore-keys: |
|
||||
${{matrix.id}}-${{hashFiles('vcpkg.json')}}
|
||||
${{matrix.id}}-
|
||||
|
||||
- name: Configure Visual Studio
|
||||
if: matrix.compiler == 'vs'
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: ${{matrix.arch}}
|
||||
|
||||
- name: Install MSYS2
|
||||
if: matrix.compiler == 'mingw'
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
update: true
|
||||
install: mingw-w64-x86_64-ninja
|
||||
|
||||
- name: Put MSYS2_MinGW64 on PATH
|
||||
if: matrix.compiler == 'mingw'
|
||||
run: echo "D:/a/_temp/msys64/mingw64/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
|
||||
- name: Set up Python (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.13'
|
||||
update-environment: false
|
||||
architecture: 'arm64'
|
||||
|
||||
- name: Set up Python virtual environment (Linux/macOS)
|
||||
if: runner.os != 'Windows'
|
||||
run: |
|
||||
python -m venv --system-site-packages --copies venv
|
||||
|
||||
- name: Set up Python virtual environment (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: |
|
||||
python.exe -m venv --system-site-packages --copies venv
|
||||
|
||||
- name: Install Xcode (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: latest-stable
|
||||
|
||||
- name: Setup the oldest supported version of cmake (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
uses: jwlawson/actions-setup-cmake@v2.0
|
||||
|
||||
- name: Install python3 cryptography module (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
source venv/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install --upgrade cryptography
|
||||
python -c "import sys; print(sys.executable)"
|
||||
python --version
|
||||
python -c "import cryptography; print(f'Python3 cryptography version {cryptography.__version__}')"
|
||||
|
||||
- name: Install python3 cryptography module (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
source venv/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
ARCHFLAGS="-arch arm64" python -m pip install --upgrade cryptography
|
||||
python -c "import sys; print(sys.executable)"
|
||||
python --version
|
||||
python -c "import cryptography; print(f'Python3 cryptography version {cryptography.__version__}')"
|
||||
|
||||
- name: Install python3 cryptography module (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: |
|
||||
.\venv\Scripts\Activate.ps1
|
||||
python.exe -m ensurepip
|
||||
python.exe -m pip install --upgrade pip
|
||||
python.exe -m pip install cryptography
|
||||
python.exe -c "import sys; print(sys.executable)"
|
||||
python.exe --version
|
||||
python.exe -c "import cryptography; print(f'Python3 cryptography version {cryptography.__version__}')"
|
||||
|
||||
- name: Configure CMake (Linux/macOS)
|
||||
if: runner.os != 'Windows'
|
||||
run: |
|
||||
source venv/bin/activate
|
||||
cmake \
|
||||
-G "${{matrix.generator}}" \
|
||||
-S "${{github.workspace}}" \
|
||||
-B "${{github.workspace}}/build" \
|
||||
-DCMAKE_OSX_ARCHITECTURES=arm64 \
|
||||
-DCMAKE_BUILD_TYPE="${{env.BUILD_TYPE}}" \
|
||||
-DCMAKE_INSTALL_PREFIX="${{github.workspace}}/dist"
|
||||
|
||||
- name: Configure CMake (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: |
|
||||
.\venv\Scripts\Activate.ps1
|
||||
cmake `
|
||||
-G "${{matrix.generator}}" `
|
||||
-S "${{github.workspace}}" `
|
||||
-B "${{github.workspace}}/build" `
|
||||
-DCMAKE_BUILD_TYPE="${{env.BUILD_TYPE}}" `
|
||||
-DCMAKE_INSTALL_PREFIX="${{github.workspace}}/dist"
|
||||
|
||||
- name: Build
|
||||
run: cmake
|
||||
--build ${{github.workspace}}/build
|
||||
--config ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: List files (Linux/macOS)
|
||||
if: runner.os != 'Windows'
|
||||
run: find .. -ls
|
||||
|
||||
- name: List files (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: Get-ChildItem -Recurse -Name ..
|
||||
|
||||
- name: Test (Linux/macOS)
|
||||
if: runner.os != 'Windows'
|
||||
working-directory: ${{github.workspace}}/build
|
||||
run: |
|
||||
source ../venv/bin/activate
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Test (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
working-directory: ${{github.workspace}}/build
|
||||
run: |
|
||||
..\venv\Scripts\Activate.ps1
|
||||
ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Upload the errors
|
||||
uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: errors-${{matrix.id}}
|
||||
path: |
|
||||
${{github.workspace}}/build/Testing/Temporary/LastTest.log
|
||||
${{github.workspace}}/build/Testing/conf/makecerts.log
|
||||
${{github.workspace}}/build/Testing/logs/server.log
|
||||
${{github.workspace}}/build/Testing/logs/port.log
|
||||
|
||||
- name: Install
|
||||
run: cmake --install ${{github.workspace}}/build
|
||||
|
||||
- name: Upload the executables
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{env.version}}-${{matrix.id}}
|
||||
path: ${{github.workspace}}/dist
|
59
.github/workflows/codeql-analysis.yml
vendored
Normal file
59
.github/workflows/codeql-analysis.yml
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: '45 1 * * 2'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
26
.github/workflows/coverity.yml
vendored
Normal file
26
.github/workflows/coverity.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
name: Coverity Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
coverity:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
token: ${{secrets.COVERITY_SCAN_TOKEN}}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
if: env.token
|
||||
- name: Get ready for scanning
|
||||
if: env.token
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libssl-dev libcurl4-openssl-dev
|
||||
cmake -S ${{github.workspace}} -B ${{github.workspace}}/build
|
||||
- uses: vapier/coverity-scan-action@v1
|
||||
if: env.token
|
||||
with:
|
||||
email: ${{secrets.COVERITY_SCAN_EMAIL}}
|
||||
token: ${{secrets.COVERITY_SCAN_TOKEN}}
|
||||
command: make -C ${{github.workspace}}/build
|
41
.gitignore
vendored
41
.gitignore
vendored
@ -1,20 +1,19 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
compile
|
||||
build/
|
||||
CMakeFiles/
|
||||
_CPack_Packages/
|
||||
Testing/
|
||||
.vs/
|
||||
|
||||
CMakeCache.txt
|
||||
cmake_install.cmake
|
||||
config.h
|
||||
config.h.in
|
||||
config.h.in~
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
missing
|
||||
CPackConfig.cmake
|
||||
CPackSourceConfig.cmake
|
||||
CTestTestfile.cmake
|
||||
install_manifest.txt
|
||||
Makefile
|
||||
osslsigncode
|
||||
osslsigncode.o
|
||||
osslsigncode.exe
|
||||
stamp-h1
|
||||
|
||||
.#*#
|
||||
@ -23,24 +22,20 @@ stamp-h1
|
||||
.*.rej
|
||||
.*~
|
||||
#*#
|
||||
*.asc
|
||||
*.bak
|
||||
*.bz2
|
||||
*.d
|
||||
*.def
|
||||
*.dll
|
||||
*.exe
|
||||
*.gz
|
||||
*.la
|
||||
*.lib
|
||||
*.lo
|
||||
*.orig
|
||||
*.pc
|
||||
*.pdb
|
||||
*.rej
|
||||
*.u
|
||||
*.rc
|
||||
*.pc
|
||||
*~
|
||||
*.gz
|
||||
*.bz2
|
||||
|
||||
**/*.log
|
||||
!myapp.exe
|
||||
*.pem
|
||||
|
111
CHANGELOG.md
111
CHANGELOG.md
@ -1,111 +0,0 @@
|
||||
### 2.1 (2020-10-11)
|
||||
|
||||
- certificate chain verification support
|
||||
- timestamp verification support
|
||||
- CRL verification support ("-CRLfile" option)
|
||||
- improved CAB signature support
|
||||
- nested signatures support
|
||||
- user-specified signing time ("-st" option) by vszakats
|
||||
- added more tests
|
||||
- fixed numerous bugs
|
||||
- dropped OpenSSL 1.1.0 support
|
||||
|
||||
### 2.0 (2018-12-04)
|
||||
|
||||
- orphaned project adopted by Michał Trojnara
|
||||
- ported to OpenSSL 1.1.x
|
||||
- ported to SoftHSM2
|
||||
- add support for pkcs11-based hardware tokens
|
||||
(Patch from Leif Johansson)
|
||||
- improved error reporting of timestamping errors
|
||||
(Patch from Carlo Teubner)
|
||||
|
||||
### 1.7.1 (2014-07-11)
|
||||
|
||||
- MSI: added -add-msi-dse option
|
||||
(Patch from Mikkel Krautz)
|
||||
- MSI: fix build when GSF_CAN_READ_MSI_METADATA defined
|
||||
(Patch from Mikkel Krautz)
|
||||
|
||||
### 1.7 (2014-07-10)
|
||||
|
||||
- add support for nested signatures
|
||||
(Patch from Mikkel Krautz)
|
||||
- fix compilation problem with OpenSSL < 1.0.0
|
||||
- added OpenSSL linkage exception to license
|
||||
|
||||
### 1.6 (2014-01-21)
|
||||
|
||||
- add support for reading password from file
|
||||
- add support for asking for password (on systems that
|
||||
provide support for it)
|
||||
- add support for compiling and running on Windows
|
||||
(Patch from Heiko Hund)
|
||||
- fix compilation without curl
|
||||
(Fix from Heiko Hund)
|
||||
- added support for giving multiple timestamp servers
|
||||
as arguments (first one that succeeds will be used)
|
||||
- signatures on hierarchical MSI files were broken
|
||||
(Fix from Mikkel Krautz)
|
||||
- MSI: Add support for MsiDigitalSignatureEx signature
|
||||
(Patch from Mikkel Krautz)
|
||||
- add support for adding additional/cross certificates
|
||||
through -ac option
|
||||
(Thanks to Lars Munch for idea + testing)
|
||||
- MSI: Add support for signature extract/remove/verify
|
||||
(Patches from Mikkel Krautz)
|
||||
- PE/MSI: Implement -require-leaf-hash for verify.
|
||||
(Patch from Mikkel Krautz)
|
||||
|
||||
### 1.5.2 (2013-03-13)
|
||||
|
||||
- added support for signing with SHA-384 and SHA-512
|
||||
- added support for page hashing (-ph option)
|
||||
|
||||
### 1.5.1 (2013-03-12)
|
||||
|
||||
- forgot to bump version number...
|
||||
|
||||
### 1.5 (2013-03-12)
|
||||
|
||||
- added support for signing MSI files (patch from Marc-André Lureau)
|
||||
- calculate correct PE checksum instead of setting it to 0
|
||||
(patch from Roland Schwingel)
|
||||
- added support for RFC3161 timestamping (-ts option)
|
||||
- added support for extracting/removing/verifying signature on PE files
|
||||
- fixed problem with not being able to decode timestamps with no newlines
|
||||
- added stricter checks for PE file validity
|
||||
- added support for reading keys from PVK files (requires OpenSSL 1.0.0 or later)
|
||||
- added support for reading certificates from PEM files
|
||||
- renamed program option: -spc to -certs (old option name still valid)
|
||||
|
||||
### 1.4 (2011-08-12)
|
||||
|
||||
- improved build system (patch from Alon Bar-Lev)
|
||||
- support reading cert+key from PKCS12 file (patch from Alon Bar-Lev)
|
||||
- support reading key from PEM file
|
||||
- added support for sha1/sha256 - default hash is now sha1
|
||||
- added flag for commercial signing (default is individual)
|
||||
|
||||
### 1.3.1 (2009-08-07)
|
||||
|
||||
- support signing of 64-bit executables (fix from Paul Kendall)
|
||||
|
||||
### 1.3 (2008-01-31)
|
||||
|
||||
- fixed padding problem (fix from Ryan Rubley)
|
||||
- allow signing of already signed files (fix from Ryan Rubley)
|
||||
- added Ryan Rubley's PVK-to-DER guide into the README
|
||||
|
||||
### 1.2 (2005-01-21)
|
||||
|
||||
- autoconf:ed (Thanks to Roy Keene)
|
||||
- added documentation
|
||||
- don't override PKCS7_get_signed_attribute, it wasn't
|
||||
actually needed, it was me being confused.
|
||||
- compiles without curl, which means no timestamping
|
||||
- version number output
|
||||
|
||||
### 1.1 (2005-01-19)
|
||||
|
||||
- Initial release
|
126
CMakeLists.txt
Normal file
126
CMakeLists.txt
Normal file
@ -0,0 +1,126 @@
|
||||
# required cmake version
|
||||
cmake_minimum_required(VERSION 3.17)
|
||||
|
||||
# autodetect vcpkg CMAKE_TOOLCHAIN_FILE if VCPKG_ROOT is defined
|
||||
# this needs to be configured before the project() directive
|
||||
if((CMAKE_GENERATOR MATCHES "Ninja") AND DEFINED ENV{VCPKG_ROOT} AND NOT $ENV{VCPKG_ROOT} STREQUAL "" AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
|
||||
endif((CMAKE_GENERATOR MATCHES "Ninja") AND DEFINED ENV{VCPKG_ROOT} AND NOT $ENV{VCPKG_ROOT} STREQUAL "" AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
set(BUILTIN_SOCKET ON CACHE BOOL "") # for static Python
|
||||
|
||||
# configure basic project information
|
||||
project(osslsigncode
|
||||
VERSION 2.10
|
||||
DESCRIPTION "OpenSSL based Authenticode signing for PE, CAB, CAT and MSI files"
|
||||
HOMEPAGE_URL "https://github.com/mtrojnar/osslsigncode"
|
||||
LANGUAGES C)
|
||||
|
||||
# force nonstandard version format for development packages
|
||||
set(DEV "-dev")
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}${DEV}")
|
||||
|
||||
# version and contact information
|
||||
set(PACKAGE_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
|
||||
set(PACKAGE_BUGREPORT "Michal.Trojnara@stunnel.org")
|
||||
|
||||
# specify the C standard
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DUSE_WIN32)
|
||||
endif()
|
||||
|
||||
# load CMake library modules
|
||||
include(FindOpenSSL)
|
||||
if(OPENSSL_VERSION VERSION_LESS "1.1.1")
|
||||
message(FATAL_ERROR "OpenSSL version must be at least 1.1.1")
|
||||
endif()
|
||||
if(OPENSSL_VERSION VERSION_LESS "3.0.0")
|
||||
include(FindCURL)
|
||||
endif(OPENSSL_VERSION VERSION_LESS "3.0.0")
|
||||
include(FindZLIB)
|
||||
|
||||
# load CMake project modules
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
|
||||
include(SetBashCompletion)
|
||||
include(FindHeaders)
|
||||
|
||||
# define the target
|
||||
add_executable(osslsigncode)
|
||||
|
||||
# add compiler/linker flags
|
||||
include(SetCompilerFlags)
|
||||
|
||||
# create and use config.h
|
||||
configure_file(Config.h.in config.h)
|
||||
target_compile_definitions(osslsigncode PRIVATE HAVE_CONFIG_H=1)
|
||||
|
||||
# set sources
|
||||
target_sources(osslsigncode PRIVATE osslsigncode.c helpers.c utf.c msi.c pe.c cab.c cat.c appx.c script.c)
|
||||
if(NOT UNIX)
|
||||
target_sources(osslsigncode PRIVATE applink.c)
|
||||
endif(NOT UNIX)
|
||||
|
||||
# set include directories
|
||||
target_include_directories(osslsigncode PRIVATE "${PROJECT_BINARY_DIR}")
|
||||
|
||||
# set OpenSSL includes/libraries
|
||||
if(NOT OPENSSL_FOUND)
|
||||
message(FATAL_ERROR "OpenSSL library not found")
|
||||
endif(NOT OPENSSL_FOUND)
|
||||
target_include_directories(osslsigncode PRIVATE ${OPENSSL_INCLUDE_DIR})
|
||||
target_link_libraries(osslsigncode PRIVATE ${OPENSSL_LIBRARIES})
|
||||
|
||||
# set cURL includes/libraries
|
||||
if(OPENSSL_VERSION VERSION_LESS "3.0.0")
|
||||
if(CURL_FOUND)
|
||||
target_compile_definitions(osslsigncode PRIVATE ENABLE_CURL=1)
|
||||
target_include_directories(osslsigncode PRIVATE ${CURL_INCLUDE_DIRS})
|
||||
target_link_libraries(osslsigncode PRIVATE ${CURL_LIBRARIES})
|
||||
message(STATUS "cURL support enabled")
|
||||
else(CURL_FOUND)
|
||||
message(STATUS "cURL support disabled (library not found)")
|
||||
endif(CURL_FOUND)
|
||||
endif(OPENSSL_VERSION VERSION_LESS "3.0.0")
|
||||
|
||||
if(NOT ZLIB_FOUND)
|
||||
message(FATAL_ERROR "Zlib library not found")
|
||||
endif(NOT ZLIB_FOUND)
|
||||
target_include_directories(osslsigncode PRIVATE ${ZLIB_INCLUDE_DIR})
|
||||
target_link_libraries(osslsigncode PRIVATE ${ZLIB_LIBRARIES})
|
||||
|
||||
if(NOT UNIX)
|
||||
# https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-shutdown
|
||||
target_link_libraries(osslsigncode PRIVATE Ws2_32.lib crypt32.lib)
|
||||
endif(NOT UNIX)
|
||||
|
||||
# add paths to linker search and installed rpath
|
||||
set_target_properties(osslsigncode PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
# testing with CTest
|
||||
include(CMakeTest)
|
||||
|
||||
# installation rules for a project
|
||||
set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin")
|
||||
install(TARGETS osslsigncode RUNTIME DESTINATION ${BINDIR})
|
||||
if(UNIX)
|
||||
include(CMakeDist)
|
||||
else(UNIX)
|
||||
install(
|
||||
DIRECTORY ${PROJECT_BINARY_DIR}/ DESTINATION ${BINDIR}
|
||||
FILES_MATCHING
|
||||
PATTERN "*.dll"
|
||||
PATTERN "vcpkg_installed" EXCLUDE
|
||||
PATTERN "CMakeFiles" EXCLUDE
|
||||
PATTERN "Testing" EXCLUDE)
|
||||
endif(UNIX)
|
||||
|
||||
#[[
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
]]
|
50
CMakeSettings.json
Normal file
50
CMakeSettings.json
Normal file
@ -0,0 +1,50 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "x86-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x86" ]
|
||||
},
|
||||
{
|
||||
"name": "x86-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x86" ]
|
||||
},
|
||||
{
|
||||
"name": "x64-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"variables": []
|
||||
},
|
||||
{
|
||||
"name": "x64-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"variables": []
|
||||
}
|
||||
]
|
||||
}
|
10
Config.h.in
Normal file
10
Config.h.in
Normal file
@ -0,0 +1,10 @@
|
||||
/* the configured options and settings for osslsigncode */
|
||||
#define VERSION_MAJOR "@osslsigncode_VERSION_MAJOR@"
|
||||
#define VERSION_MINOR "@osslsigncode_VERSION_MINOR@"
|
||||
#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
|
||||
#cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
|
||||
#cmakedefine HAVE_TERMIOS_H
|
||||
#cmakedefine HAVE_GETPASS
|
||||
#cmakedefine HAVE_SYS_MMAN_H
|
||||
#cmakedefine HAVE_MMAP
|
||||
#cmakedefine HAVE_MAPVIEWOFFILE
|
32
Dockerfile
Normal file
32
Dockerfile
Normal file
@ -0,0 +1,32 @@
|
||||
# Stage 1: Build osslsigncode on Alpine
|
||||
FROM alpine:latest AS builder
|
||||
|
||||
# Install build dependencies
|
||||
RUN apk add --no-cache build-base cmake openssl-dev zlib-dev
|
||||
|
||||
# Copy osslsigncode source code into the image
|
||||
COPY . /source
|
||||
|
||||
# Build osslsigncode
|
||||
RUN cd /source && \
|
||||
mkdir -p build && \
|
||||
cd build && \
|
||||
rm -f CMakeCache.txt && \
|
||||
cmake -S .. && \
|
||||
cmake --build . && \
|
||||
cmake --install .
|
||||
|
||||
# Stage 2: Create final image without build environment
|
||||
FROM alpine:latest
|
||||
|
||||
# Copy compiled binary from builder stage
|
||||
COPY --from=builder /usr/local/bin/osslsigncode /usr/local/bin/osslsigncode
|
||||
|
||||
# Install necessary runtime libraries (latest version)
|
||||
RUN apk add --no-cache libcrypto3
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /workdir
|
||||
|
||||
# Declare volume to mount files
|
||||
VOLUME [ "/workdir" ]
|
117
INSTALL.W32.md
117
INSTALL.W32.md
@ -3,55 +3,40 @@
|
||||
### Building osslsigncode source with MSYS2 MinGW 64-bit and MSYS2 packages:
|
||||
|
||||
1) Download and install MSYS2 from https://msys2.github.io/ and follow installation instructions.
|
||||
Once up and running install even mingw-w64-x86_64-gcc, mingw-w64-x86_64-curl, mingw-w64-x86_64-libgsf.
|
||||
Once up and running install the following packages:
|
||||
```
|
||||
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-curl mingw-w64-x86_64-libgsf
|
||||
pacman -S make mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-openssl mingw-w64-x86_64-python-cryptography
|
||||
```
|
||||
mingw-w64-x86_64-openssl and mingw-w64-x86_64-zlib packages are installed with dependencies.
|
||||
mingw-w64-x86_64-zlib package is installed with dependencies.
|
||||
|
||||
2) Run "MSYS2 MinGW 64-bit" and build 64-bit Windows executables.
|
||||
```
|
||||
cd osslsigncode-folder
|
||||
x86_64-w64-mingw32-gcc osslsigncode.c -o osslsigncode.exe \
|
||||
-lcrypto -lssl -lcurl -lgsf-1 -lgobject-2.0 -lglib-2.0 -lxml2 \
|
||||
-I 'C:/msys64/mingw64/include/libgsf-1' \
|
||||
-I 'C:/msys64/mingw64/include/glib-2.0' \
|
||||
-I 'C:/msys64/mingw64/lib/glib-2.0/include' \
|
||||
-D 'PACKAGE_STRING="osslsigncode 2.1.0"' \
|
||||
-D 'PACKAGE_BUGREPORT="Michal.Trojnara@stunnel.org"' \
|
||||
-D ENABLE_CURL \
|
||||
-D WITH_GSF
|
||||
mkdir build && cd build && cmake -S .. -DCMAKE_BUILD_TYPE=Release -G "MSYS Makefiles"
|
||||
cmake --build . --verbose
|
||||
```
|
||||
|
||||
3) Run "Command prompt" and include "c:\msys64\mingw64\bin" folder as part of the path.
|
||||
3) Make tests.
|
||||
```
|
||||
ctest
|
||||
```
|
||||
|
||||
4) Run "Command prompt" and include "c:\msys64\mingw64\bin" folder as part of the path.
|
||||
```
|
||||
path=%path%;c:\msys64\mingw64\bin
|
||||
cd osslsigncode-folder
|
||||
|
||||
osslsigncode.exe -v
|
||||
osslsigncode 2.1.0, using:
|
||||
OpenSSL 1.1.1g 21 Apr 2020
|
||||
libcurl/7.70.0 OpenSSL/1.1.1g (Schannel) zlib/1.2.11 brotli/1.0.7 libidn2/2.3.0
|
||||
libpsl/0.21.0 (+libidn2/2.3.0) libssh2/1.9.0 nghttp2/1.40.0 libgsf 1.14.46
|
||||
osslsigncode 2.8, using:
|
||||
OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)
|
||||
No default -CAfile location detected
|
||||
```
|
||||
|
||||
|
||||
### Building OpenSSL, Curl and osslsigncode sources with MSYS2 MinGW 64-bit:
|
||||
### Building OpenSSL and osslsigncode sources with MSYS2 MinGW 64-bit:
|
||||
|
||||
1) Download and install MSYS2 from https://msys2.github.io/ and follow installation instructions.
|
||||
Once up and running install even: perl make autoconf automake libtool pkg-config.
|
||||
```
|
||||
pacman -S perl make autoconf automake libtool pkg-config
|
||||
```
|
||||
Make sure there are no curl, brotli, libpsl, libidn2 and nghttp2 packages installed:
|
||||
```
|
||||
pacman -R mingw-w64-x86_64-curl \
|
||||
mingw-w64-x86_64-brotli \
|
||||
mingw-w64-x86_64-libpsl \
|
||||
mingw-w64-x86_64-libidn2 \
|
||||
mingw-w64-x86_64-nghttp2
|
||||
```
|
||||
|
||||
Run "MSYS2 MinGW 64-bit" in the administrator mode.
|
||||
|
||||
2) Build and install OpenSSL.
|
||||
@ -60,42 +45,52 @@
|
||||
./config --prefix='C:/OpenSSL' --openssldir='C:/OpenSSL'
|
||||
make && make install
|
||||
```
|
||||
3) Build and install curl.
|
||||
```
|
||||
cd curl-(version)
|
||||
./buildconf
|
||||
./configure --prefix='C:/curl' --with-ssl='C:/OpenSSL' \
|
||||
--disable-ftp --disable-tftp --disable-file --disable-dict \
|
||||
--disable-telnet --disable-imap --disable-smb --disable-smtp \
|
||||
--disable-gopher --disable-pop --disable-pop3 --disable-rtsp \
|
||||
--disable-ldap --disable-ldaps --disable-unix-sockets --disable-pthreads
|
||||
make && make install
|
||||
```
|
||||
|
||||
3) Build 64-bit Windows executables.
|
||||
3) Configure a CMake project.
|
||||
```
|
||||
cd osslsigncode-folder
|
||||
x86_64-w64-mingw32-gcc osslsigncode.c -o osslsigncode.exe \
|
||||
-L 'C:/OpenSSL/lib/' -lcrypto -lssl \
|
||||
-I 'C:/OpenSSL/include/' \
|
||||
-L 'C:/curl/lib' -lcurl \
|
||||
-I 'C:/curl/include' \
|
||||
-D 'PACKAGE_STRING="osslsigncode 2.1.0"' \
|
||||
-D 'PACKAGE_BUGREPORT="Michal.Trojnara@stunnel.org"' \
|
||||
-D ENABLE_CURL
|
||||
mkdir build && cd build && cmake -S .. -DCMAKE_BUILD_TYPE=Release -G "MSYS Makefiles" -DCMAKE_PREFIX_PATH="C:\OpenSSL"
|
||||
```
|
||||
|
||||
4) Run "Command prompt" and copy required libraries.
|
||||
```
|
||||
cd osslsigncode-folder
|
||||
copy C:\OpenSSL\bin\libssl-1_1-x64.dll
|
||||
copy C:\OpenSSL\bin\libcrypto-1_1-x64.dll
|
||||
copy C:\curl\bin\libcurl-4.dll
|
||||
copy C:\msys64\mingw64\bin\zlib1.dll
|
||||
|
||||
osslsigncode.exe -v
|
||||
osslsigncode 2.1.0, using:
|
||||
OpenSSL 1.1.1g 21 Apr 2020
|
||||
libcurl/7.70.0 OpenSSL/1.1.1g zlib/1.2.11
|
||||
no libgsf available
|
||||
copy C:\OpenSSL\bin\libssl-3-x64.dll
|
||||
copy C:\OpenSSL\bin\libcrypto-3-x64.dll
|
||||
```
|
||||
|
||||
5) Build 64-bit Windows executables.
|
||||
```
|
||||
cmake --build . --verbose
|
||||
```
|
||||
|
||||
6) Make tests.
|
||||
```
|
||||
ctest
|
||||
```
|
||||
|
||||
### Building OpenSSL and osslsigncode sources with Microsoft Visual Studio:
|
||||
|
||||
1) Install and integrate vcpkg: https://vcpkg.io/en/getting-started.html
|
||||
|
||||
2) Git clone osslsigncode: https://github.com/mtrojnar/osslsigncode/
|
||||
|
||||
3) Build osslsigncode with GUI or cmake.
|
||||
Navigate to the build directory and run CMake to configure the osslsigncode project
|
||||
and generate a native build system:
|
||||
```
|
||||
mkdir build && cd build && cmake -S .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=[installation directory] -DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake
|
||||
```
|
||||
Then call that build system to actually compile/link the osslsigncode project:
|
||||
```
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
4) Make tests.
|
||||
```
|
||||
ctest -C Release
|
||||
```
|
||||
|
||||
5) Make install (with administrative privileges if necessary).
|
||||
```
|
||||
cmake --install .
|
||||
```
|
||||
|
@ -1,7 +1,7 @@
|
||||
OpenSSL based Authenticode signing for PE/MSI/Java CAB files.
|
||||
|
||||
Copyright (C) 2005-2014 Per Allansson <pallansson@gmail.com>
|
||||
Copyright (C) 2018-2019 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
Copyright (C) 2018-2022 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
16
Makefile.am
16
Makefile.am
@ -1,16 +0,0 @@
|
||||
AUTOMAKE_OPTIONS = foreign 1.10
|
||||
MAINTAINERCLEANFILES = \
|
||||
config.log config.status \
|
||||
$(srcdir)/Makefile.in \
|
||||
$(srcdir)/config.h.in $(srcdir)/config.h.in~ $(srcdir)/configure \
|
||||
$(srcdir)/install-sh $(srcdir)/ltmain.sh $(srcdir)/missing \
|
||||
$(srcdir)/depcomp $(srcdir)/aclocal.m4 $(srcdir)/ylwrap \
|
||||
$(srcdir)/config.guess $(srcdir)/config.sub
|
||||
EXTRA_DIST = .gitignore
|
||||
|
||||
AM_CFLAGS = $(GSF_CFLAGS) $(OPENSSL_CFLAGS) $(OPTIONAL_LIBCURL_CFLAGS)
|
||||
|
||||
bin_PROGRAMS = osslsigncode
|
||||
|
||||
osslsigncode_SOURCES = osslsigncode.c
|
||||
osslsigncode_LDADD = $(GSF_LIBS) $(OPENSSL_LIBS) $(OPTIONAL_LIBCURL_LIBS)
|
227
NEWS.md
Normal file
227
NEWS.md
Normal file
@ -0,0 +1,227 @@
|
||||
# osslsigncode change log
|
||||
|
||||
### 2.10 (unreleased)
|
||||
|
||||
- added compatiblity with the CNG engine version 1.1 or later
|
||||
- added the "-engineCtrl" option to control hardware and CNG engines
|
||||
- improved unauthenticated blob support (thanks to Asger Hautop Drewsen)
|
||||
- added the '-blobFile' option to specify a file containing the blob content
|
||||
- added PKCS#11 provider support (requires OpenSSL 3.0)
|
||||
|
||||
### 2.9 (2024.06.29)
|
||||
|
||||
- added a 64 bit long pseudo-random NONCE in the TSA request
|
||||
- missing NID_pkcs9_signingTime is no longer an error
|
||||
- added support for PEM-encoded CRLs
|
||||
- fixed the APPX central directory sorting order
|
||||
- added a special "-" file name to read the passphrase from stdin
|
||||
(by Steve McIntyre)
|
||||
- used native HTTP client with OpenSSL 3.x, removing libcurl dependency
|
||||
- added '-login' option to force a login to PKCS11 engines
|
||||
(by Brad Hughes)
|
||||
- added the "-ignore-crl" option to disable fetching and verifying
|
||||
CRL Distribution Points
|
||||
- changed error output to stderr instead of stdout
|
||||
- various testing framework improvements
|
||||
- various memory corruption fixes
|
||||
|
||||
### 2.8 (2024.03.03)
|
||||
|
||||
- Microsoft PowerShell signing sponsored by Cisco Systems, Inc.
|
||||
- fixed setting unauthenticated attributes (Countersignature, Unauthenticated
|
||||
Data Blob) in a nested signature
|
||||
- added the "-index" option to verify a specific signature or modify its
|
||||
unauthenticated attributes
|
||||
- added CAT file verification
|
||||
- added listing the contents of a CAT file with the "-verbose" option
|
||||
- added the new "extract-data" command to extract a PKCS#7 data content to be
|
||||
signed with "sign" and attached with "attach-signature"
|
||||
- added PKCS9_SEQUENCE_NUMBER authenticated attribute support
|
||||
- added the "-ignore-cdp" option to disable CRL Distribution Points (CDP)
|
||||
online verification
|
||||
- unsuccessful CRL retrieval and verification changed into a critical error
|
||||
- the "-p" option modified to also use to configured proxy to connect CRL
|
||||
Distribution Points
|
||||
- added implicit allowlisting of the Microsoft Root Authority serial number
|
||||
00C1008B3C3C8811D13EF663ECDF40
|
||||
- added listing of certificate chain retrieved from the signature in case of
|
||||
verification failure
|
||||
|
||||
### 2.7 (2023.09.19)
|
||||
|
||||
- fixed signing CAB files (by Michael Brown)
|
||||
- fixed handling of unsupported commands (by Maxim Bagryantsev)
|
||||
- fixed writing DIFAT sectors
|
||||
- added APPX support (by Maciej Panek and Małgorzata Olszówka)
|
||||
- added a built-in TSA response generation (-TSA-certs, -TSA-key
|
||||
and -TSA-time options)
|
||||
|
||||
### 2.6 (2023.05.29)
|
||||
|
||||
- modular architecture implemented to simplify adding file formats
|
||||
- added verification of CRLs specified in the signing certificate
|
||||
- added MSI DIFAT sectors support (by Max Bagryantsev)
|
||||
- added legacy provider support for OpenSSL 3.0.0 and later
|
||||
- fixed numerous bugs
|
||||
|
||||
### 2.5 (2022.08.12)
|
||||
|
||||
- fixed the Unix executable install path
|
||||
- fixed the hardcoded "pkcs11" engine id
|
||||
- fixed building with MinGW
|
||||
- fixed testing with the python3 distributed with Ubuntu 18.04
|
||||
|
||||
### 2.4 (2022.08.02)
|
||||
|
||||
- migrated the build system from GNU Autoconf to CMake
|
||||
- added the "-h" option to set the cryptographic hash function
|
||||
for the "attach -signature" and "add" commands
|
||||
- set the default hash function to "sha256"
|
||||
- added the "attach-signature" option to compute and compare the
|
||||
leaf certificate hash for the "add" command
|
||||
- renamed the "-st" option "-time" (the old name is accepted for
|
||||
compatibility)
|
||||
- updated the "-time" option to also set explicit verification time
|
||||
- added the "-ignore-timestamp" option to disable timestamp server
|
||||
signature verification
|
||||
- removed the "-timestamp-expiration" option
|
||||
- fixed several bugs
|
||||
- updated the included documentation
|
||||
- enabled additional compiler/linker hardening options
|
||||
- added CI based on GitHub Actions
|
||||
|
||||
### 2.3 (2022.03.06)
|
||||
|
||||
**CRITICAL SECURITY VULNERABILITIES**
|
||||
|
||||
This release fixes several critical memory corruption vulnerabilities.
|
||||
A malicious attacker could create a file, which, when processed with
|
||||
osslsigncode, triggers arbitrary code execution. Any previous version
|
||||
of osslsigncode should be immediately upgraded if the tool is used for
|
||||
processing of untrusted files.
|
||||
|
||||
- fixed several memory safety issues
|
||||
- fixed non-interactive PVK (MSBLOB) key decryption
|
||||
- added a bash completion script
|
||||
- added CA bundle path auto-detection
|
||||
|
||||
### 2.2 (2021.08.15)
|
||||
|
||||
- CAT files support (thanks to James McKenzie)
|
||||
- MSI support rewritten without libgsf dependency, which allows
|
||||
for handling of all the needed MSI metadata, such as dates
|
||||
- "-untrusted" option renamed to "-TSA-CAfile"
|
||||
- "-CRLuntrusted" option renamed to "-TSA-CRLfile"
|
||||
- numerous bug fixes and improvements
|
||||
|
||||
### 2.1 (2020-10-11)
|
||||
|
||||
- certificate chain verification support
|
||||
- timestamp verification support
|
||||
- CRL verification support ("-CRLfile" option)
|
||||
- improved CAB signature support
|
||||
- nested signatures support
|
||||
- user-specified signing time ("-st" option) by vszakats
|
||||
- added more tests
|
||||
- fixed numerous bugs
|
||||
- dropped OpenSSL 1.1.0 support
|
||||
|
||||
### 2.0 (2018-12-04)
|
||||
|
||||
- orphaned project adopted by Michał Trojnara
|
||||
- ported to OpenSSL 1.1.x
|
||||
- ported to SoftHSM2
|
||||
- add support for pkcs11-based hardware tokens
|
||||
(Patch from Leif Johansson)
|
||||
- improved error reporting of timestamping errors
|
||||
(Patch from Carlo Teubner)
|
||||
|
||||
### 1.7.1 (2014-07-11)
|
||||
|
||||
- MSI: added -add-msi-dse option
|
||||
(Patch from Mikkel Krautz)
|
||||
- MSI: fix build when GSF_CAN_READ_MSI_METADATA defined
|
||||
(Patch from Mikkel Krautz)
|
||||
|
||||
### 1.7 (2014-07-10)
|
||||
|
||||
- add support for nested signatures
|
||||
(Patch from Mikkel Krautz)
|
||||
- fix compilation problem with OpenSSL < 1.0.0
|
||||
- added OpenSSL linkage exception to license
|
||||
|
||||
### 1.6 (2014-01-21)
|
||||
|
||||
- add support for reading password from file
|
||||
- add support for asking for password (on systems that
|
||||
provide support for it)
|
||||
- add support for compiling and running on Windows
|
||||
(Patch from Heiko Hund)
|
||||
- fix compilation without curl
|
||||
(Fix from Heiko Hund)
|
||||
- added support for giving multiple timestamp servers
|
||||
as arguments (first one that succeeds will be used)
|
||||
- signatures on hierarchical MSI files were broken
|
||||
(Fix from Mikkel Krautz)
|
||||
- MSI: Add support for MsiDigitalSignatureEx signature
|
||||
(Patch from Mikkel Krautz)
|
||||
- add support for adding additional/cross certificates
|
||||
through -ac option
|
||||
(Thanks to Lars Munch for idea + testing)
|
||||
- MSI: Add support for signature extract/remove/verify
|
||||
(Patches from Mikkel Krautz)
|
||||
- PE/MSI: Implement -require-leaf-hash for verify.
|
||||
(Patch from Mikkel Krautz)
|
||||
|
||||
### 1.5.2 (2013-03-13)
|
||||
|
||||
- added support for signing with SHA-384 and SHA-512
|
||||
- added support for page hashing (-ph option)
|
||||
|
||||
### 1.5.1 (2013-03-12)
|
||||
|
||||
- forgot to bump version number...
|
||||
|
||||
### 1.5 (2013-03-12)
|
||||
|
||||
- added support for signing MSI files (patch from Marc-André Lureau)
|
||||
- calculate correct PE checksum instead of setting it to 0
|
||||
(patch from Roland Schwingel)
|
||||
- added support for RFC3161 timestamping (-ts option)
|
||||
- added support for extracting/removing/verifying signature on PE files
|
||||
- fixed problem with not being able to decode timestamps with no newlines
|
||||
- added stricter checks for PE file validity
|
||||
- added support for reading keys from PVK files (requires OpenSSL 1.0.0 or later)
|
||||
- added support for reading certificates from PEM files
|
||||
- renamed program option: -spc to -certs (old option name still valid)
|
||||
|
||||
### 1.4 (2011-08-12)
|
||||
|
||||
- improved build system (patch from Alon Bar-Lev)
|
||||
- support reading cert+key from PKCS12 file (patch from Alon Bar-Lev)
|
||||
- support reading key from PEM file
|
||||
- added support for sha1/sha256 - default hash is now sha1
|
||||
- added flag for commercial signing (default is individual)
|
||||
|
||||
### 1.3.1 (2009-08-07)
|
||||
|
||||
- support signing of 64-bit executables (fix from Paul Kendall)
|
||||
|
||||
### 1.3 (2008-01-31)
|
||||
|
||||
- fixed padding problem (fix from Ryan Rubley)
|
||||
- allow signing of already signed files (fix from Ryan Rubley)
|
||||
- added Ryan Rubley's PVK-to-DER guide into the README
|
||||
|
||||
### 1.2 (2005-01-21)
|
||||
|
||||
- autoconf:ed (Thanks to Roy Keene)
|
||||
- added documentation
|
||||
- don't override PKCS7_get_signed_attribute, it wasn't
|
||||
actually needed, it was me being confused.
|
||||
- compiles without curl, which means no timestamping
|
||||
- version number output
|
||||
|
||||
### 1.1 (2005-01-19)
|
||||
|
||||
- Initial release
|
168
README.md
168
README.md
@ -1,6 +1,10 @@
|
||||
osslsigncode
|
||||
============
|
||||
|
||||
## BUILD STATUS
|
||||
|
||||
[](https://github.com/mtrojnar/osslsigncode/actions/workflows/ci.yml)
|
||||
|
||||
## WHAT IS IT?
|
||||
|
||||
osslsigncode is a small tool that implements part of the functionality
|
||||
@ -19,28 +23,62 @@ tool would fail. And, so, osslsigncode was born.
|
||||
|
||||
## WHAT CAN IT DO?
|
||||
|
||||
It can sign and timestamp PE (EXE/SYS/DLL/etc), CAB and MSI files. It supports
|
||||
the equivalent of signtool.exe's "-j javasign.dll -jp low", i.e. add a
|
||||
valid signature for a CAB file containing Java files. It supports getting
|
||||
the timestamp through a proxy as well. It also supports signature verification,
|
||||
removal and extraction.
|
||||
It can sign and timestamp PE (EXE/SYS/DLL/etc), CAB, CAT and MSI files.
|
||||
It supports the equivalent of signtool.exe's "-j javasign.dll -jp low",
|
||||
i.e. add a valid signature for a CAB file containing Java files.
|
||||
It supports getting the timestamp through a proxy as well. It also
|
||||
supports signature verification, removal and extraction.
|
||||
|
||||
## BUILDING
|
||||
|
||||
This build technique works on Linux and macOS, if you have the necessary tools installed:
|
||||
```
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
```
|
||||
This section covers building osslsigncode for [Unix-like](https://en.wikipedia.org/wiki/Unix-like) operating systems.
|
||||
See [INSTALL.W32.md](https://github.com/mtrojnar/osslsigncode/blob/master/INSTALL.W32.md) for Windows notes.
|
||||
We highly recommend downloading a [release tarball](https://github.com/mtrojnar/osslsigncode/releases) instead of cloning from a git repository.
|
||||
|
||||
* On Linux, (tested on Debian/Ubuntu) you may need `sudo apt-get update && sudo apt-get install build-essential autoconf libtool libssl-dev python3-pkgconfig libcurl4-gnutls-dev`
|
||||
* On macOS with Homebrew, you probably need to do these things before autogen.sh and configure:
|
||||
### Configure, build, make tests and install osslsigncode
|
||||
|
||||
* Install prerequisites on a Debian-based distributions, such as Ubuntu:
|
||||
```
|
||||
brew install openssl@1.1 automake pkg-config libtool
|
||||
sudo apt update && sudo apt install cmake libssl-dev libcurl4-openssl-dev zlib1g-dev python3
|
||||
```
|
||||
* Install prerequisites on macOS with Homebrew:
|
||||
```
|
||||
brew install cmake pkg-config openssl@1.1
|
||||
export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"
|
||||
```
|
||||
**NOTE:** osslsigncode requires CMake 3.17 or newer.
|
||||
|
||||
You may need to use `cmake3` instead of `cmake` to complete the following steps on your system.
|
||||
* Navigate to the build directory and run CMake to configure the osslsigncode project
|
||||
and generate a native build system:
|
||||
```
|
||||
mkdir build && cd build && cmake -S ..
|
||||
```
|
||||
optional CMake parameters:
|
||||
```
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DCMAKE_C_COMPILER=clang
|
||||
-DCMAKE_PREFIX_PATH=[openssl directory];[curl directory]
|
||||
-DCMAKE_INSTALL_PREFIX=[installation directory]
|
||||
-DBASH_COMPLETION_USER_DIR=[bash completion installation directory]
|
||||
|
||||
```
|
||||
* Then call that build system to actually compile/link the osslsigncode project (alias `make`):
|
||||
```
|
||||
cmake --build .
|
||||
```
|
||||
* Make test:
|
||||
```
|
||||
ctest -C Release
|
||||
```
|
||||
* Make install:
|
||||
```
|
||||
sudo cmake --install .
|
||||
```
|
||||
* Make tarball (simulate autotools' `make dist`):
|
||||
```
|
||||
cmake --build . --target package_source
|
||||
```
|
||||
|
||||
## USAGE
|
||||
|
||||
@ -75,7 +113,7 @@ or if you want to add a timestamp as well:
|
||||
```
|
||||
osslsigncode sign -certs <cert-file> -key <key-file> \
|
||||
-n "Your Application" -i http://www.yourwebsite.com/ \
|
||||
-t http://timestamp.verisign.com/scripts/timstamp.dll \
|
||||
-t http://timestamp.digicert.com \
|
||||
-in yourapp.exe -out yourapp-signed.exe
|
||||
```
|
||||
You can use a certificate and key stored in a PKCS#12 container:
|
||||
@ -93,17 +131,50 @@ To sign a CAB file containing java class files:
|
||||
```
|
||||
Only the 'low' parameter is currently supported.
|
||||
|
||||
If you want to use PKCS11 token, you should indicate PKCS11 engine and module.
|
||||
If you want to use a PKCS#11 token, you should specify the PKCS#11 engine and module.
|
||||
An example of using osslsigncode with SoftHSM:
|
||||
```
|
||||
osslsigncode sign \
|
||||
-pkcs11engine /usr/lib64/engines-1.1/pkcs11.so \
|
||||
-engine /usr/lib64/engines-1.1/pkcs11.so \
|
||||
-pkcs11module /usr/lib64/pkcs11/libsofthsm2.so \
|
||||
-certs <cert-file> \
|
||||
-pkcs11cert 'pkcs11:token=softhsm-token;object=cert' \
|
||||
-key 'pkcs11:token=softhsm-token;object=key' \
|
||||
-in yourapp.exe -out yourapp-signed.exe
|
||||
```
|
||||
osslsigncode currently does not support reading certificates from engines.
|
||||
|
||||
Since OpenSSL 3.0, you can use a PKCS#11 token with the PKCS#11 provider.
|
||||
An example of using osslsigncode with OpenSC:
|
||||
```
|
||||
osslsigncode sign \
|
||||
-provider /usr/lib64/ossl-modules/pkcs11prov.so \
|
||||
-pkcs11module /usr/lib64/opensc-pkcs11.so \
|
||||
-pkcs11cert 'pkcs11:token=my-token;object=cert' \
|
||||
-key 'pkcs11:token=my-token;object=key' \
|
||||
-in yourapp.exe -out yourapp-signed.exe
|
||||
```
|
||||
|
||||
You can use a certificate and key stored in the Windows Certificate Store with
|
||||
the CNG engine version 1.1 or later. For more information, refer to
|
||||
|
||||
https://www.stunnel.org/cng-engine.html
|
||||
|
||||
A non-commercial edition of CNG engine is available for testing, personal,
|
||||
educational, or research purposes.
|
||||
|
||||
To use the CNG engine with osslsigncode, ensure that the `cng.dll` library is
|
||||
placed in the same directory as the `osslsigncode.exe` executable.
|
||||
|
||||
Below is an example of how to use osslsigncode with the CNG engine:
|
||||
```
|
||||
osslsigncode sign \
|
||||
-engine cng \
|
||||
-pkcs11cert osslsigncode_cert \
|
||||
-key osslsigncode_cert \
|
||||
-engineCtrl store_flags:0 \
|
||||
-engineCtrl store_name:MY \
|
||||
-engineCtrl PIN:yourpass \
|
||||
-in yourapp.exe -out yourapp-signed.exe
|
||||
```
|
||||
|
||||
You can check that the signed file is correct by right-clicking
|
||||
on it in Windows and choose Properties --> Digital Signatures,
|
||||
@ -111,41 +182,40 @@ and then choose the signature from the list, and click on
|
||||
Details. You should then be presented with a dialog that says
|
||||
amongst other things that "This digital signature is OK".
|
||||
|
||||
## CONVERTING FROM PVK TO DER
|
||||
## UNAUTHENTICATED BLOBS
|
||||
|
||||
(This guide was written by Ryan Rubley)
|
||||
The "-addUnauthenticatedBlob" parameter adds a 1024-byte unauthenticated blob
|
||||
of data to the signature in the same area as the timestamp. This can be used
|
||||
while signing, while timestamping, after a file has been code signed, or by
|
||||
itself. This technique (but not this project) is used by Dropbox, GoToMeeting,
|
||||
and Summit Route.
|
||||
|
||||
If you've managed to finally find osslsigncode from some searches,
|
||||
you're most likely going to have a heck of a time getting your SPC
|
||||
and PVK files into the formats osslsigncode wants.
|
||||
### Example 1. Sign and add blob to unsigned file
|
||||
|
||||
On the computer where you originally purchased your certificate, you
|
||||
probably had to use IE to get it. Run IE and select Tools/Internet
|
||||
Options from the menu, then under the Content tab, click the Certificates
|
||||
button. Under the Personal tab, select your certificate and click the
|
||||
Export button. On the second page of the wizard, select the PKCS #7
|
||||
Certificate (.P7B) format. This file you export as a *.p7b is what you
|
||||
use instead of your *.spc file. It's the same basic thing, in a different format.
|
||||
|
||||
For your PVK file, you will need to download a little utility called
|
||||
PVK.EXE. This can currently be downloaded at
|
||||
|
||||
http://support.globalsign.net/en/objectsign/PVK.zip
|
||||
|
||||
Run:
|
||||
```
|
||||
pvk -in foo.pvk -nocrypt -out foo.pem
|
||||
```shell
|
||||
osslsigncode sign -addUnauthenticatedBlob -pkcs12 yourcert.pfx -pass your_password -n "Your Company" -i https://YourSite.com/ -in srepp.msi -out srepp_added.msi
|
||||
```
|
||||
|
||||
This will convert your PVK file to a PEM file.
|
||||
From there, you can copy the PEM file to a Linux box, and run:
|
||||
```
|
||||
openssl rsa -outform der -in foo.pem -out foo.der
|
||||
```
|
||||
This will convert your PEM file to a DER file.
|
||||
### Example 2. Timestamp and add blob to signed file
|
||||
|
||||
You need the *.p7b and *.der files to use osslsigncode, instead of your
|
||||
*.spc and *.pvk files.
|
||||
```shell
|
||||
osslsigncode.exe add -addUnauthenticatedBlob -t http://timestamp.digicert.com -in your_signed_file.exe -out out.exe
|
||||
```
|
||||
|
||||
### Example 3. Add blob to signed and time-stamped file
|
||||
|
||||
```shell
|
||||
osslsigncode.exe add -addUnauthenticatedBlob -in your_signed_file.exe -out out.exe
|
||||
```
|
||||
|
||||
### WARNING
|
||||
|
||||
This feature allows for doing dumb things. Be very careful with what you put
|
||||
in the unauthenticated blob, as an attacker could modify this. Do NOT, under
|
||||
any circumstances, put a URL here that you will use to download an additional
|
||||
file. If you do do that, you would need to check the newly downloaded file is
|
||||
code signed AND that it has been signed with your cert AND that it is the
|
||||
version you expect.
|
||||
|
||||
## BUGS, QUESTIONS etc.
|
||||
|
||||
|
@ -1,58 +0,0 @@
|
||||
# This is NOT the official repo for osslsigncode
|
||||
|
||||
This project was copied from osslsigncode 1.7.1 to apply some patches for compiling with cygwin and being able to add unauthenticated blobs. The official source for the project is at: http://sourceforge.net/projects/osslsigncode/
|
||||
|
||||
## Features added
|
||||
|
||||
Adds the argument "-addUnauthenticatedBlob" to add a 1024 byte unauthenticated blob of data to the signature in the same area as the timestamp. This can be used while signing, while timestamping (new `add` command added to allow just time-stamping, after a file has been code signed, or by itself.
|
||||
|
||||
Examples:
|
||||
```
|
||||
# Example 1. Sign and add blob to unsigned file
|
||||
osslsigncode sign -addUnauthenticatedBlob -pkcs12 yourcert.pfx -pass your_password -n "Your Company" -i https://YourSite.com/ -in srepp.msi -out srepp_added.msi
|
||||
```
|
||||
|
||||
```
|
||||
# Example 2. Timestamp and add blob to signed file
|
||||
osslsigncode.exe add -addUnauthenticatedBlob -t http://timestamp.verisign.com/scripts/timstamp.dll -in your_signed_file.exe -out out.exe
|
||||
```
|
||||
|
||||
```
|
||||
# Example 3. Add blob to signed and time-stamped file
|
||||
osslsigncode.exe add -addUnauthenticatedBlob -in your_signed_file.exe -out out.exe
|
||||
```
|
||||
|
||||
```
|
||||
# Example 4. Sign, timestamp, and add blob
|
||||
# Technically you can do this, but this would mean your signing certificate
|
||||
# is on a computer that is connected the Internet,
|
||||
# which means you are doing something wrong,
|
||||
# so I'm not going to show how to do that.
|
||||
|
||||
```
|
||||
|
||||
This technique (but not this project) is used by Dropbox, GoToMeeting, and Summit Route. You can read more about this technique here:
|
||||
|
||||
- https://tech.dropbox.com/2014/08/tech-behind-dropboxs-new-user-experience-for-mobile/
|
||||
- http://blogs.msdn.com/b/ieinternals/archive/2014/09/04/personalizing-installers-using-unauthenticated-data-inside-authenticode-signed-binaries.aspx
|
||||
|
||||
## WARNING
|
||||
|
||||
The capability this adds can allow you to do dumb things. Be very careful with what you put in the unauthenticated blob, as an attacker could modify this. Do NOT under any circumstances put a URL here that you will use to download an additional file. If you do do that, you would need to check the newly downloaded file is code signed AND that it has been signed with your cert AND that it is the version you expect. You should consider using asymmetrical encryption for the data you put in the blob, such that the executable contains the public key to decrypt the data. Basically, be VERY careful.
|
||||
|
||||
## Compiling under cygwin
|
||||
|
||||
- Ensure you install the development libraries for openssl, libgfs, and curl.
|
||||
- Install pkg-config
|
||||
- Run
|
||||
```
|
||||
export SHELLOPTS
|
||||
set -o igncr
|
||||
./configure
|
||||
make
|
||||
```
|
||||
|
||||
## Download
|
||||
|
||||
- Compiled binary for cygwin: https://summitroute.com/downloads/osslsigncode.exe
|
||||
- Compiled binary plus all the required DLL's (self-extracting exe): https://summitroute.com/downloads/osslsigncode-cygwin_files.exe
|
145
applink.c
Normal file
145
applink.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#define APPLINK_STDIN 1
|
||||
#define APPLINK_STDOUT 2
|
||||
#define APPLINK_STDERR 3
|
||||
#define APPLINK_FPRINTF 4
|
||||
#define APPLINK_FGETS 5
|
||||
#define APPLINK_FREAD 6
|
||||
#define APPLINK_FWRITE 7
|
||||
#define APPLINK_FSETMOD 8
|
||||
#define APPLINK_FEOF 9
|
||||
#define APPLINK_FCLOSE 10 /* should not be used */
|
||||
|
||||
#define APPLINK_FOPEN 11 /* solely for completeness */
|
||||
#define APPLINK_FSEEK 12
|
||||
#define APPLINK_FTELL 13
|
||||
#define APPLINK_FFLUSH 14
|
||||
#define APPLINK_FERROR 15
|
||||
#define APPLINK_CLEARERR 16
|
||||
#define APPLINK_FILENO 17 /* to be used with below */
|
||||
|
||||
#define APPLINK_OPEN 18 /* formally can't be used, as flags can vary */
|
||||
#define APPLINK_READ 19
|
||||
#define APPLINK_WRITE 20
|
||||
#define APPLINK_LSEEK 21
|
||||
#define APPLINK_CLOSE 22
|
||||
#define APPLINK_MAX 22 /* always same as last macro */
|
||||
|
||||
#ifndef APPMACROS_ONLY
|
||||
# include <stdio.h>
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
|
||||
# ifdef __BORLANDC__
|
||||
/* _lseek in <io.h> is a function-like macro so we can't take its address */
|
||||
# undef _lseek
|
||||
# define _lseek lseek
|
||||
# endif
|
||||
|
||||
static void *app_stdin(void)
|
||||
{
|
||||
return stdin;
|
||||
}
|
||||
|
||||
static void *app_stdout(void)
|
||||
{
|
||||
return stdout;
|
||||
}
|
||||
|
||||
static void *app_stderr(void)
|
||||
{
|
||||
return stderr;
|
||||
}
|
||||
|
||||
static int app_feof(FILE *fp)
|
||||
{
|
||||
return feof(fp);
|
||||
}
|
||||
|
||||
static int app_ferror(FILE *fp)
|
||||
{
|
||||
return ferror(fp);
|
||||
}
|
||||
|
||||
static void app_clearerr(FILE *fp)
|
||||
{
|
||||
clearerr(fp);
|
||||
}
|
||||
|
||||
static int app_fileno(FILE *fp)
|
||||
{
|
||||
return _fileno(fp);
|
||||
}
|
||||
|
||||
static int app_fsetmod(FILE *fp, char mod)
|
||||
{
|
||||
return _setmode(_fileno(fp), mod == 'b' ? _O_BINARY : _O_TEXT);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__declspec(dllexport)
|
||||
void **
|
||||
# if defined(__BORLANDC__)
|
||||
/*
|
||||
* __stdcall appears to be the only way to get the name
|
||||
* decoration right with Borland C. Otherwise it works
|
||||
* purely incidentally, as we pass no parameters.
|
||||
*/
|
||||
__stdcall
|
||||
# else
|
||||
__cdecl
|
||||
# endif
|
||||
#pragma warning(push, 2)
|
||||
OPENSSL_Applink(void)
|
||||
{
|
||||
static int once = 1;
|
||||
static void *OPENSSL_ApplinkTable[APPLINK_MAX + 1] =
|
||||
{ (void *)APPLINK_MAX };
|
||||
|
||||
if (once) {
|
||||
OPENSSL_ApplinkTable[APPLINK_STDIN] = app_stdin;
|
||||
OPENSSL_ApplinkTable[APPLINK_STDOUT] = app_stdout;
|
||||
OPENSSL_ApplinkTable[APPLINK_STDERR] = app_stderr;
|
||||
OPENSSL_ApplinkTable[APPLINK_FPRINTF] = fprintf;
|
||||
OPENSSL_ApplinkTable[APPLINK_FGETS] = fgets;
|
||||
OPENSSL_ApplinkTable[APPLINK_FREAD] = fread;
|
||||
OPENSSL_ApplinkTable[APPLINK_FWRITE] = fwrite;
|
||||
OPENSSL_ApplinkTable[APPLINK_FSETMOD] = app_fsetmod;
|
||||
OPENSSL_ApplinkTable[APPLINK_FEOF] = app_feof;
|
||||
OPENSSL_ApplinkTable[APPLINK_FCLOSE] = fclose;
|
||||
|
||||
OPENSSL_ApplinkTable[APPLINK_FOPEN] = fopen;
|
||||
OPENSSL_ApplinkTable[APPLINK_FSEEK] = fseek;
|
||||
OPENSSL_ApplinkTable[APPLINK_FTELL] = ftell;
|
||||
OPENSSL_ApplinkTable[APPLINK_FFLUSH] = fflush;
|
||||
OPENSSL_ApplinkTable[APPLINK_FERROR] = app_ferror;
|
||||
OPENSSL_ApplinkTable[APPLINK_CLEARERR] = app_clearerr;
|
||||
OPENSSL_ApplinkTable[APPLINK_FILENO] = app_fileno;
|
||||
|
||||
OPENSSL_ApplinkTable[APPLINK_OPEN] = _open;
|
||||
OPENSSL_ApplinkTable[APPLINK_READ] = _read;
|
||||
OPENSSL_ApplinkTable[APPLINK_WRITE] = _write;
|
||||
OPENSSL_ApplinkTable[APPLINK_LSEEK] = _lseek;
|
||||
OPENSSL_ApplinkTable[APPLINK_CLOSE] = _close;
|
||||
|
||||
once = 0;
|
||||
}
|
||||
|
||||
return OPENSSL_ApplinkTable;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
1578
autogen.sh
1578
autogen.sh
File diff suppressed because it is too large
Load Diff
505
cat.c
Normal file
505
cat.c
Normal file
@ -0,0 +1,505 @@
|
||||
/*
|
||||
* CAT file support library
|
||||
*
|
||||
* Copyright (C) 2021-2023 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
* Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
|
||||
*
|
||||
* Catalog files are a bit odd, in that they are only a PKCS7 blob.
|
||||
* CAT files do not support nesting (multiple signature)
|
||||
*/
|
||||
|
||||
#include "osslsigncode.h"
|
||||
#include "helpers.h"
|
||||
|
||||
typedef struct {
|
||||
ASN1_BMPSTRING *tag;
|
||||
ASN1_INTEGER *flags;
|
||||
ASN1_OCTET_STRING *value;
|
||||
} CatNameValueContent;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(CatNameValueContent)
|
||||
|
||||
ASN1_SEQUENCE(CatNameValueContent) = {
|
||||
ASN1_SIMPLE(CatNameValueContent, tag, ASN1_BMPSTRING),
|
||||
ASN1_SIMPLE(CatNameValueContent, flags, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(CatNameValueContent, value, ASN1_OCTET_STRING)
|
||||
} ASN1_SEQUENCE_END(CatNameValueContent)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(CatNameValueContent)
|
||||
|
||||
struct cat_ctx_st {
|
||||
uint32_t sigpos;
|
||||
uint32_t siglen;
|
||||
uint32_t fileend;
|
||||
PKCS7 *p7;
|
||||
};
|
||||
|
||||
/* FILE_FORMAT method prototypes */
|
||||
static FILE_FORMAT_CTX *cat_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *outdata);
|
||||
static int cat_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7);
|
||||
static PKCS7 *cat_pkcs7_extract(FILE_FORMAT_CTX *ctx);
|
||||
static PKCS7 *cat_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash);
|
||||
static int cat_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7);
|
||||
static void cat_bio_free(BIO *hash, BIO *outdata);
|
||||
static void cat_ctx_cleanup(FILE_FORMAT_CTX *ctx);
|
||||
|
||||
FILE_FORMAT file_format_cat = {
|
||||
.ctx_new = cat_ctx_new,
|
||||
.verify_digests = cat_verify_digests,
|
||||
.pkcs7_extract = cat_pkcs7_extract,
|
||||
.pkcs7_signature_new = cat_pkcs7_signature_new,
|
||||
.append_pkcs7 = cat_append_pkcs7,
|
||||
.bio_free = cat_bio_free,
|
||||
.ctx_cleanup = cat_ctx_cleanup,
|
||||
};
|
||||
|
||||
/* Prototypes */
|
||||
static CAT_CTX *cat_ctx_get(char *indata, uint32_t filesize);
|
||||
static int cat_add_content_type(PKCS7 *p7, PKCS7 *cursig);
|
||||
static int cat_sign_content(PKCS7 *p7, PKCS7 *contents);
|
||||
static int cat_list_content(PKCS7 *p7);
|
||||
static int cat_print_content_member_digest(ASN1_TYPE *content);
|
||||
static int cat_print_content_member_name(ASN1_TYPE *content);
|
||||
static void cat_print_base64(ASN1_OCTET_STRING *value);
|
||||
static void cat_print_utf16_as_ascii(ASN1_OCTET_STRING *value);
|
||||
static int cat_check_file(FILE_FORMAT_CTX *ctx);
|
||||
|
||||
/*
|
||||
* FILE_FORMAT method definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Allocate and return a CAT file format context.
|
||||
* [in, out] options: structure holds the input data
|
||||
* [out] hash: message digest BIO (unused)
|
||||
* [in] outdata: outdata file BIO (unused)
|
||||
* [returns] pointer to CAT file format context
|
||||
*/
|
||||
static FILE_FORMAT_CTX *cat_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *outdata)
|
||||
{
|
||||
FILE_FORMAT_CTX *ctx;
|
||||
CAT_CTX *cat_ctx;
|
||||
uint32_t filesize;
|
||||
|
||||
if (options->cmd == CMD_REMOVE || options->cmd==CMD_ATTACH || options->cmd == CMD_EXTRACT_DATA) {
|
||||
fprintf(stderr, "Unsupported command\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
filesize = get_file_size(options->infile);
|
||||
if (filesize == 0)
|
||||
return NULL; /* FAILED */
|
||||
|
||||
options->indata = map_file(options->infile, filesize);
|
||||
if (!options->indata) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
cat_ctx = cat_ctx_get(options->indata, filesize);
|
||||
if (!cat_ctx) {
|
||||
unmap_file(options->indata, filesize);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
ctx = OPENSSL_malloc(sizeof(FILE_FORMAT_CTX));
|
||||
ctx->format = &file_format_cat;
|
||||
ctx->options = options;
|
||||
ctx->cat_ctx = cat_ctx;
|
||||
|
||||
/* Push hash on outdata, if hash is NULL the function does nothing */
|
||||
BIO_push(hash, outdata);
|
||||
|
||||
if (options->cmd == CMD_VERIFY)
|
||||
printf("Warning: Use -catalog option to verify that a file, listed in catalog file, is signed\n");
|
||||
if (options->jp >= 0)
|
||||
printf("Warning: -jp option is only valid for CAB files\n");
|
||||
if (options->pagehash == 1)
|
||||
printf("Warning: -ph option is only valid for PE files\n");
|
||||
if (options->add_msi_dse == 1)
|
||||
printf("Warning: -add-msi-dse option is only valid for MSI files\n");
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/*
|
||||
* ContentInfo value is the inner content of pkcs7-signedData.
|
||||
* An extra verification is not necessary when a content type data
|
||||
* is the inner content of the signed-data type.
|
||||
*/
|
||||
static int cat_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
||||
{
|
||||
/* squash unused parameter warnings */
|
||||
(void)ctx;
|
||||
(void)p7;
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract existing signature in DER format.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *cat_pkcs7_extract(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
if (!cat_check_file(ctx)) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
return PKCS7_dup(ctx->cat_ctx->p7);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new PKCS#7 signature.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO (unused)
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *cat_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
|
||||
{
|
||||
PKCS7 *p7 = NULL;
|
||||
|
||||
/* squash unused parameter warnings */
|
||||
(void)hash;
|
||||
|
||||
p7 = pkcs7_create(ctx);
|
||||
if (!p7) {
|
||||
fprintf(stderr, "Creating a new signature failed\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!ctx->cat_ctx->p7 || !ctx->cat_ctx->p7->d.sign || !ctx->cat_ctx->p7->d.sign->contents) {
|
||||
fprintf(stderr, "Failed to get content\n");
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!cat_add_content_type(p7, ctx->cat_ctx->p7)) {
|
||||
fprintf(stderr, "Adding content type failed\n");
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!cat_sign_content(p7, ctx->cat_ctx->p7->d.sign->contents)) {
|
||||
fprintf(stderr, "Failed to set signed content\n");
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
return p7; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Append signature to the outfile.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] outdata: outdata file BIO
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int cat_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
||||
{
|
||||
return data_write_pkcs7(ctx, outdata, p7);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up an entire message digest BIO chain.
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO (unused)
|
||||
* [returns] none
|
||||
*/
|
||||
static void cat_bio_free(BIO *hash, BIO *outdata)
|
||||
{
|
||||
/* squash the unused parameter warning */
|
||||
(void)outdata;
|
||||
BIO_free_all(hash);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocate a FILE_FORMAT_CTX structure and CAT format specific structure,
|
||||
* unmap indata file.
|
||||
* [in, out] ctx: structure holds all input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [in] outdata: outdata file BIO
|
||||
* [returns] none
|
||||
*/
|
||||
static void cat_ctx_cleanup(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
unmap_file(ctx->options->indata, ctx->cat_ctx->fileend);
|
||||
PKCS7_free(ctx->cat_ctx->p7);
|
||||
OPENSSL_free(ctx->cat_ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* CAT helper functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Verify mapped PKCS#7 (CAT) file and create CAT format specific structure.
|
||||
* [in] indata: mapped file
|
||||
* [in] filesize: size of file
|
||||
* [returns] pointer to CAT format specific structure
|
||||
*/
|
||||
static CAT_CTX *cat_ctx_get(char *indata, uint32_t filesize)
|
||||
{
|
||||
CAT_CTX *cat_ctx;
|
||||
PKCS7 *p7;
|
||||
|
||||
p7 = pkcs7_read_data(indata, filesize);
|
||||
if (!p7)
|
||||
return NULL; /* FAILED */
|
||||
if (!PKCS7_type_is_signed(p7)) {
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
cat_ctx = OPENSSL_zalloc(sizeof(CAT_CTX));
|
||||
cat_ctx->p7 = p7;
|
||||
cat_ctx->sigpos = 0;
|
||||
cat_ctx->siglen = filesize;
|
||||
cat_ctx->fileend = filesize;
|
||||
return cat_ctx; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a content type OID to the PKCS#7 signature structure.
|
||||
* The content type can be:
|
||||
* - "1.3.6.1.4.1.311.10.1" (MS_CTL_OBJID) for Certificate Trust Lists (CTL),
|
||||
* - "1.3.6.1.4.1.311.2.1.4" (SPC_INDIRECT_DATA_OBJID) for Authenticode data.
|
||||
* [in, out] p7: new PKCS#7 signature
|
||||
* [in] cursig: current PKCS#7 signature to determine content type
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cat_add_content_type(PKCS7 *p7, PKCS7 *cursig)
|
||||
{
|
||||
const char *content_type;
|
||||
STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
|
||||
PKCS7_SIGNER_INFO *si;
|
||||
|
||||
if (is_content_type(cursig, SPC_INDIRECT_DATA_OBJID)) {
|
||||
/* Authenticode content */
|
||||
content_type = SPC_INDIRECT_DATA_OBJID;
|
||||
} else if (is_content_type(cursig, MS_CTL_OBJID)) {
|
||||
/* Certificate Trust List (CTL) */
|
||||
content_type = MS_CTL_OBJID;
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported content type\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
signer_info = PKCS7_get_signer_info(p7);
|
||||
if (!signer_info)
|
||||
return 0; /* FAILED */
|
||||
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
|
||||
if (!si)
|
||||
return 0; /* FAILED */
|
||||
if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
|
||||
V_ASN1_OBJECT, OBJ_txt2obj(content_type, 1)))
|
||||
return 0; /* FAILED */
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Sign the MS CTL blob.
|
||||
* Certificate Trust List (CTL) is a list of file names or thumbprints.
|
||||
* All the items in this list are authenticated (approved) by the signing entity.
|
||||
* [in, out] p7: new PKCS#7 signature
|
||||
* [in] contents: Certificate Trust List (CTL)
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cat_sign_content(PKCS7 *p7, PKCS7 *contents)
|
||||
{
|
||||
u_char *content;
|
||||
int seqhdrlen, content_length;
|
||||
|
||||
if (!contents->d.other || !contents->d.other->value.sequence
|
||||
|| !contents->d.other->value.sequence->data) {
|
||||
fprintf(stderr, "Failed to get content value\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
seqhdrlen = asn1_simple_hdr_len(contents->d.other->value.sequence->data,
|
||||
contents->d.other->value.sequence->length);
|
||||
content = contents->d.other->value.sequence->data + seqhdrlen;
|
||||
content_length = contents->d.other->value.sequence->length - seqhdrlen;
|
||||
|
||||
if (!pkcs7_sign_content(p7, content, content_length)) {
|
||||
fprintf(stderr, "Failed to sign content\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (!PKCS7_set_content(p7, PKCS7_dup(contents))) {
|
||||
fprintf(stderr, "PKCS7_set_content failed\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Print each member of the CAT file by using the "-verbose" option.
|
||||
* [in, out] p7: catalog file to verify
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int cat_list_content(PKCS7 *p7)
|
||||
{
|
||||
MsCtlContent *ctlc;
|
||||
int i;
|
||||
|
||||
ctlc = ms_ctl_content_get(p7);
|
||||
if (!ctlc) {
|
||||
fprintf(stderr, "Failed to extract MS_CTL_OBJID data\n");
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
printf("\nCatalog members:\n");
|
||||
for (i = 0; i < sk_CatalogInfo_num(ctlc->header_attributes); i++) {
|
||||
int j, found = 0;
|
||||
CatalogInfo *header_attr = sk_CatalogInfo_value(ctlc->header_attributes, i);
|
||||
if (header_attr == NULL)
|
||||
continue;
|
||||
for (j = 0; j < sk_CatalogAuthAttr_num(header_attr->attributes); j++) {
|
||||
char object_txt[128];
|
||||
CatalogAuthAttr *attribute;
|
||||
ASN1_TYPE *content;
|
||||
|
||||
attribute = sk_CatalogAuthAttr_value(header_attr->attributes, j);
|
||||
if (!attribute)
|
||||
continue;
|
||||
content = catalog_content_get(attribute);
|
||||
if (!content)
|
||||
continue;
|
||||
object_txt[0] = 0x00;
|
||||
OBJ_obj2txt(object_txt, sizeof object_txt, attribute->type, 1);
|
||||
if (!strcmp(object_txt, CAT_NAMEVALUE_OBJID)) {
|
||||
/* CAT_NAMEVALUE_OBJID OID: 1.3.6.1.4.1.311.12.2.1 */
|
||||
found |= cat_print_content_member_name(content);
|
||||
} else if (!strcmp(object_txt, SPC_INDIRECT_DATA_OBJID)) {
|
||||
/* SPC_INDIRECT_DATA_OBJID OID: 1.3.6.1.4.1.311.2.1.4 */
|
||||
found |= cat_print_content_member_digest(content);
|
||||
}
|
||||
ASN1_TYPE_free(content);
|
||||
}
|
||||
if (found)
|
||||
printf("\n");
|
||||
}
|
||||
MsCtlContent_free(ctlc);
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a hash algorithm and a message digest from the SPC_INDIRECT_DATA_OBJID attribute.
|
||||
* [in] content: catalog file content
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cat_print_content_member_digest(ASN1_TYPE *content)
|
||||
{
|
||||
SpcIndirectDataContent *idc;
|
||||
u_char mdbuf[EVP_MAX_MD_SIZE];
|
||||
const u_char *data ;
|
||||
int mdtype = -1;
|
||||
ASN1_STRING *value;
|
||||
|
||||
value = content->value.sequence;
|
||||
data = ASN1_STRING_get0_data(value);
|
||||
idc = d2i_SpcIndirectDataContent(NULL, &data, ASN1_STRING_length(value));
|
||||
if (!idc)
|
||||
return 0; /* FAILED */
|
||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
||||
/* get a digest algorithm a message digest of the file from the content */
|
||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
||||
}
|
||||
SpcIndirectDataContent_free(idc);
|
||||
if (mdtype == -1) {
|
||||
fprintf(stderr, "Failed to extract current message digest\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
printf("\tHash algorithm: %s\n", OBJ_nid2sn(mdtype));
|
||||
print_hash("\tMessage digest", "", mdbuf, EVP_MD_size(EVP_get_digestbynid(mdtype)));
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a file name from the CAT_NAMEVALUE_OBJID attribute.
|
||||
* [in] content: catalog file content
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cat_print_content_member_name(ASN1_TYPE *content)
|
||||
{
|
||||
CatNameValueContent *nvc;
|
||||
const u_char *data = NULL;
|
||||
ASN1_STRING *value;
|
||||
|
||||
value = content->value.sequence;
|
||||
data = ASN1_STRING_get0_data(value);
|
||||
nvc = d2i_CatNameValueContent(NULL, &data, ASN1_STRING_length(value));
|
||||
if (!nvc) {
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
printf("\tFile name: ");
|
||||
if (ASN1_INTEGER_get(nvc->flags) & 0x00020000) {
|
||||
cat_print_base64(nvc->value);
|
||||
} else {
|
||||
cat_print_utf16_as_ascii(nvc->value);
|
||||
}
|
||||
printf("\n");
|
||||
CatNameValueContent_free(nvc);
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a CAT_NAMEVALUE_OBJID attribute represented in base-64 encoding.
|
||||
* [in] value: catalog member file name
|
||||
* [returns] none
|
||||
*/
|
||||
static void cat_print_base64(ASN1_OCTET_STRING *value)
|
||||
{
|
||||
BIO *stdbio, *b64;
|
||||
stdbio = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
b64 = BIO_new(BIO_f_base64());
|
||||
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
stdbio = BIO_push(b64, stdbio);
|
||||
ASN1_STRING_print_ex(stdbio, value, 0);
|
||||
BIO_free_all(stdbio);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a CAT_NAMEVALUE_OBJID attribute represented in plaintext.
|
||||
* [in] value: catalog member file name
|
||||
* [returns] none
|
||||
*/
|
||||
static void cat_print_utf16_as_ascii(ASN1_OCTET_STRING *value)
|
||||
{
|
||||
const u_char *data;
|
||||
int len, i;
|
||||
|
||||
data = ASN1_STRING_get0_data(value);
|
||||
len = ASN1_STRING_length(value);
|
||||
for (i = 0; i < len && (data[i] || data[i+1]); i+=2)
|
||||
putchar(isprint(data[i]) && !data[i+1] ? data[i] : '.');
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the signature exists.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cat_check_file(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
|
||||
PKCS7_SIGNER_INFO *si;
|
||||
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "Init error\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
signer_info = PKCS7_get_signer_info(ctx->cat_ctx->p7);
|
||||
if (!signer_info) {
|
||||
fprintf(stderr, "Failed catalog file\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
|
||||
if (!si) {
|
||||
fprintf(stderr, "No signature found\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (ctx->options->verbose) {
|
||||
(void)cat_list_content(ctx->cat_ctx->p7);
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
vim: set ts=4 expandtab:
|
||||
*/
|
36
cmake/CMakeDist.cmake
Normal file
36
cmake/CMakeDist.cmake
Normal file
@ -0,0 +1,36 @@
|
||||
# make dist
|
||||
# cmake --build . --target package_source
|
||||
|
||||
set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
|
||||
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OpenSSL based Authenticode signing for PE, CAB, CAT and MSI files")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
|
||||
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.txt")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||
set(CPACK_SOURCE_GENERATOR "TGZ")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "\.git/;\.gitignore")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "Makefile")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "CMakeCache.txt")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "CMakeFiles")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "CPackConfig.cmake")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "CPackSourceConfig.cmake")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "CTestTestfile.cmake")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "cmake_install.cmake")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "config.h")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "/CMakeFiles/")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "/Testing/")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "/_CPack_Packages/")
|
||||
list(APPEND CPACK_SOURCE_IGNORE_FILES "/build/")
|
||||
|
||||
include(CPack)
|
||||
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
|
||||
|
||||
#[[
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
]]
|
625
cmake/CMakeTest.cmake
Normal file
625
cmake/CMakeTest.cmake
Normal file
@ -0,0 +1,625 @@
|
||||
# make test
|
||||
# ctest -C Release
|
||||
|
||||
########## Configure ##########
|
||||
|
||||
include(FindPython3)
|
||||
|
||||
if(Python3_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} "check_cryptography.py"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests"
|
||||
OUTPUT_VARIABLE cryptography_output
|
||||
RESULT_VARIABLE cryptography_error)
|
||||
|
||||
if(NOT cryptography_error)
|
||||
message(STATUS "Using python3-cryptography version ${cryptography_output}")
|
||||
option(STOP_SERVER "Stop HTTP server after tests" ON)
|
||||
|
||||
# Remove http proxy configuration that may change behavior
|
||||
unset(ENV{HTTP_PROXY})
|
||||
unset(ENV{http_proxy})
|
||||
|
||||
set(TEST_DIR "${PROJECT_BINARY_DIR}/Testing")
|
||||
if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
|
||||
set(OSSLSIGNCODE "${PROJECT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/osslsigncode")
|
||||
else(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
|
||||
set(OSSLSIGNCODE "${PROJECT_BINARY_DIR}/osslsigncode")
|
||||
endif(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
|
||||
set(EXEC "${TEST_DIR}/exec.py")
|
||||
set(FILES "${TEST_DIR}/files")
|
||||
set(CERTS "${TEST_DIR}/certs")
|
||||
set(CONF "${TEST_DIR}/conf")
|
||||
set(LOGS "${TEST_DIR}/logs")
|
||||
|
||||
file(MAKE_DIRECTORY "${LOGS}")
|
||||
|
||||
file(COPY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/certs/ca-bundle.crt"
|
||||
DESTINATION "${CONF}")
|
||||
|
||||
file(COPY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/files"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/conf"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/client_http.py"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/make_certificates.py"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/start_server.py"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/exec.py"
|
||||
DESTINATION "${TEST_DIR}/")
|
||||
|
||||
if(UNIX)
|
||||
file(COPY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/server_http.py"
|
||||
DESTINATION "${TEST_DIR}/")
|
||||
set(SERVER_HTTP "${TEST_DIR}/server_http.py")
|
||||
set(Python3w_EXECUTABLE ${Python3_EXECUTABLE})
|
||||
else(UNIX)
|
||||
file(COPY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/server_http.pyw"
|
||||
DESTINATION "${TEST_DIR}/")
|
||||
set(SERVER_HTTP "${TEST_DIR}/server_http.pyw")
|
||||
get_filename_component(PYTHON_DIRECTORY ${Python3_EXECUTABLE} DIRECTORY)
|
||||
set(Python3w_EXECUTABLE "${PYTHON_DIRECTORY}/pythonw.exe")
|
||||
endif(UNIX)
|
||||
|
||||
if(EXISTS "${LOGS}/url.log")
|
||||
# Stop HTTP server if running
|
||||
message(STATUS "Try to kill HTTP server")
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} "${TEST_DIR}/client_http.py"
|
||||
OUTPUT_VARIABLE client_output
|
||||
RESULT_VARIABLE client_result)
|
||||
if(NOT client_result)
|
||||
# Successfully closed
|
||||
message(STATUS "${client_output}")
|
||||
endif(NOT client_result)
|
||||
endif(EXISTS "${LOGS}/url.log")
|
||||
|
||||
set(extensions_all "exe" "ex_" "msi" "256appx" "512appx" "cat" "ps1" "psc1" "mof")
|
||||
set(extensions_nocat "exe" "ex_" "msi" "256appx" "512appx" "ps1" "psc1" "mof")
|
||||
set(extensions_nocatappx "exe" "ex_" "msi" "ps1" "psc1" "mof")
|
||||
set(formats "pem" "der")
|
||||
|
||||
else(NOT cryptography_error)
|
||||
message(STATUS "CTest skips tests: ${cryptography_output}")
|
||||
endif(NOT cryptography_error)
|
||||
|
||||
else(Python3_FOUND)
|
||||
message(STATUS "CTest skips tests: Python3 not found")
|
||||
endif(Python3_FOUND)
|
||||
|
||||
|
||||
########## Testing ##########
|
||||
|
||||
enable_testing()
|
||||
|
||||
### osslsigncode version ###
|
||||
if(Python3_FOUND AND NOT cryptography_error)
|
||||
|
||||
### Start ###
|
||||
add_test(NAME "version"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE}
|
||||
"--version")
|
||||
|
||||
add_test(NAME "start_server"
|
||||
COMMAND ${Python3_EXECUTABLE} "${TEST_DIR}/start_server.py"
|
||||
"--exe" ${Python3w_EXECUTABLE}
|
||||
"--script" ${SERVER_HTTP})
|
||||
set_tests_properties("start_server" PROPERTIES
|
||||
TIMEOUT 60)
|
||||
set(ALL_TESTS "version" "start_server")
|
||||
|
||||
### Sign ###
|
||||
|
||||
# Sign with PKCS#12 container with private key and certificate encryption algorithm
|
||||
# Signing time: May 1 00:00:00 2019 GMT (1556668800)
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "signed_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "sign"
|
||||
"-pkcs12" "${CERTS}/cert.p12"
|
||||
"-readpass" "${CERTS}/password.txt"
|
||||
"-ac" "${CERTS}/CAcross.pem"
|
||||
"-time" "1556668800"
|
||||
"-add-msi-dse"
|
||||
"-comm"
|
||||
"-ph"
|
||||
"-jp" "low"
|
||||
"-h" "sha512" "-i" "https://www.osslsigncode.com/"
|
||||
"-n" "osslsigncode"
|
||||
"-in" "${FILES}/unsigned.${ext}"
|
||||
"-out" "${FILES}/signed.${ext}")
|
||||
set_tests_properties("signed_${ext}" PROPERTIES
|
||||
DEPENDS "start_server")
|
||||
list(APPEND ALL_TESTS "signed_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
# Sign with revoked certificate
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "revoked_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "sign"
|
||||
"-certs" "${CERTS}/revoked.pem"
|
||||
"-key" "${CERTS}/keyp.pem"
|
||||
"-readpass" "${CERTS}/password.txt"
|
||||
"-ac" "${CERTS}/CAcross.pem"
|
||||
"-time" "1556668800" # Signing time: May 1 00:00:00 2019 GMT
|
||||
"-add-msi-dse"
|
||||
"-comm"
|
||||
"-ph"
|
||||
"-jp" "low"
|
||||
"-h" "sha512" "-i" "https://www.osslsigncode.com/"
|
||||
"-n" "osslsigncode"
|
||||
"-in" "${FILES}/unsigned.${ext}"
|
||||
"-out" "${FILES}/revoked.${ext}")
|
||||
set_tests_properties("revoked_${ext}" PROPERTIES
|
||||
DEPENDS "start_server")
|
||||
list(APPEND ALL_TESTS "revoked_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
# Remove signature
|
||||
# Unsupported command for CAT files
|
||||
foreach(ext ${extensions_nocat})
|
||||
add_test(NAME "removed_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "remove-signature"
|
||||
"-in" "${FILES}/signed.${ext}"
|
||||
"-out" "${FILES}/removed.${ext}")
|
||||
set_tests_properties("removed_${ext}" PROPERTIES
|
||||
DEPENDS "signed_${ext}")
|
||||
list(APPEND ALL_TESTS "removed_${ext}")
|
||||
endforeach(ext ${extensions_nocat})
|
||||
|
||||
# Extract PKCS#7 signature in PEM format
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "extract_pem_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "extract-signature"
|
||||
"-pem" # PEM format
|
||||
"-in" "${FILES}/signed.${ext}"
|
||||
"-out" "${FILES}/${ext}.pem")
|
||||
set_tests_properties("extract_pem_${ext}" PROPERTIES
|
||||
DEPENDS "signed_${ext}")
|
||||
list(APPEND ALL_TESTS "extract_pem_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
# Extract PKCS#7 signature in default DER format
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "extract_der_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "extract-signature"
|
||||
"-in" "${FILES}/signed.${ext}"
|
||||
"-out" "${FILES}/${ext}.der")
|
||||
set_tests_properties("extract_der_${ext}" PROPERTIES
|
||||
DEPENDS "signed_${ext}")
|
||||
list(APPEND ALL_TESTS "extract_der_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
# Attach a nested signature in PEM or DER format
|
||||
# Unsupported command for CAT files
|
||||
foreach(ext ${extensions_nocat})
|
||||
foreach(format ${formats})
|
||||
add_test(NAME "attached_${format}_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "attach-signature"
|
||||
# sign options
|
||||
"-add-msi-dse"
|
||||
"-h" "sha512"
|
||||
"-nest"
|
||||
"-sigin" "${FILES}/${ext}.${format}"
|
||||
"-in" "${FILES}/signed.${ext}"
|
||||
"-out" "${FILES}/attached_${format}.${ext}"
|
||||
# verify options
|
||||
"-require-leaf-hash" "FILE ${CERTS}/leafhash.txt"
|
||||
"-time" "1567296000" # Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-CRLfile" "${CERTS}/CACertCRL.pem")
|
||||
set_tests_properties("attached_${format}_${ext}" PROPERTIES
|
||||
DEPENDS "signed_${ext};extract_pem_${ext};extract_der_${ext}")
|
||||
list(APPEND ALL_TESTS "attached_${format}_${ext}")
|
||||
endforeach(format ${formats})
|
||||
endforeach(ext ${extensions_nocat})
|
||||
|
||||
# Add an unauthenticated blob to a previously-signed file
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "added_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "add"
|
||||
"-addUnauthenticatedBlob"
|
||||
"-blobFile" "${FILES}/unsigned.exe"
|
||||
"-add-msi-dse" "-h" "sha512"
|
||||
"-in" "${FILES}/signed.${ext}"
|
||||
"-out" "${FILES}/added.${ext}")
|
||||
set_tests_properties("added_${ext}" PROPERTIES
|
||||
DEPENDS "signed_${ext}")
|
||||
list(APPEND ALL_TESTS "added_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
# Add the new nested signature instead of replacing the first one
|
||||
# APPX files do not support nesting (multiple signature)
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "nested_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "sign"
|
||||
"-nest"
|
||||
"-certs" "${CERTS}/cert.pem"
|
||||
"-key" "${CERTS}/key.der"
|
||||
"-pass" "passme"
|
||||
"-ac" "${CERTS}/CAcross.pem"
|
||||
"-time" "1556755200" # Signing time: May 2 00:00:00 2019 GMT
|
||||
"-add-msi-dse"
|
||||
"-comm"
|
||||
"-ph"
|
||||
"-jp" "low"
|
||||
"-h" "sha512"
|
||||
"-i" "https://www.osslsigncode.com/"
|
||||
"-n" "osslsigncode"
|
||||
"-in" "${FILES}/signed.${ext}"
|
||||
"-out" "${FILES}/nested.${ext}")
|
||||
set_tests_properties("nested_${ext}" PROPERTIES
|
||||
DEPENDS "signed_${ext}")
|
||||
list(APPEND ALL_TESTS "nested_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
|
||||
### Verify signature ###
|
||||
|
||||
# Verify PE/MSI/CAB files signed in the catalog file
|
||||
# CAT and APPX files do not support detached PKCS#7 signature
|
||||
foreach(ext ${extensions_nocatappx})
|
||||
add_test(NAME "verify_catalog_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "verify"
|
||||
"-catalog" "${FILES}/signed.cat" # catalog file
|
||||
"-time" "1567296000" # Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
"-require-leaf-hash" "FILE ${CERTS}/leafhash.txt"
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-CRLfile" "${CERTS}/CACertCRL.pem"
|
||||
"-in" "${FILES}/unsigned.${ext}")
|
||||
set_tests_properties("verify_catalog_${ext}" PROPERTIES
|
||||
DEPENDS "signed_${ext}")
|
||||
list(APPEND ALL_TESTS "verify_catalog_${ext}")
|
||||
endforeach(ext ${extensions_nocatappx})
|
||||
|
||||
# Verify signature
|
||||
set(files "signed" "nested" "added" "revoked")
|
||||
foreach(file ${files})
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "verify_${file}_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "verify"
|
||||
"-time" "1567296000" # Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-CRLfile" "${CERTS}/CACertCRL.pem"
|
||||
"-in" "${FILES}/${file}.${ext}")
|
||||
set_tests_properties("verify_${file}_${ext}" PROPERTIES
|
||||
DEPENDS "${file}_${ext}")
|
||||
list(APPEND ALL_TESTS "verify_${file}_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
endforeach(file ${files})
|
||||
|
||||
# "revoked" tests are expected to fail
|
||||
set(files "revoked")
|
||||
foreach(file ${files})
|
||||
foreach(ext ${extensions_all})
|
||||
set_tests_properties("verify_${file}_${ext}" PROPERTIES
|
||||
WILL_FAIL TRUE)
|
||||
endforeach(ext ${extensions_all})
|
||||
endforeach(file ${files})
|
||||
|
||||
# Verify removed signature
|
||||
# "removed" tests are expected to fail
|
||||
# "remove-signature" command is unsupported for CAT files
|
||||
set(files "removed")
|
||||
foreach(file ${files})
|
||||
foreach(ext ${extensions_nocat})
|
||||
add_test(NAME "verify_${file}_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "verify"
|
||||
"-time" "1567296000" # Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-CRLfile" "${CERTS}/CACertCRL.pem"
|
||||
"-in" "${FILES}/${file}.${ext}")
|
||||
set_tests_properties("verify_${file}_${ext}" PROPERTIES
|
||||
DEPENDS "${file}_${ext}"
|
||||
WILL_FAIL TRUE)
|
||||
list(APPEND ALL_TESTS "verify_${file}_${ext}")
|
||||
endforeach(ext ${extensions_nocat})
|
||||
endforeach(file ${files})
|
||||
|
||||
# Verify attached signature
|
||||
# "attach-signature" command is unsupported for CAT files
|
||||
set(files "attached_pem" "attached_der")
|
||||
foreach(file ${files})
|
||||
foreach(ext ${extensions_nocat})
|
||||
add_test(NAME "verify_${file}_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "verify"
|
||||
"-time" "1567296000" # Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-CRLfile" "${CERTS}/CACertCRL.pem"
|
||||
"-in" "${FILES}/${file}.${ext}")
|
||||
set_tests_properties("verify_${file}_${ext}" PROPERTIES
|
||||
DEPENDS "${file}_${ext}")
|
||||
list(APPEND ALL_TESTS "verify_${file}_${ext}")
|
||||
endforeach(ext ${extensions_nocat})
|
||||
endforeach(file ${files})
|
||||
|
||||
|
||||
### Extract a data content to be signed ###
|
||||
|
||||
# Unsupported command "extract-data" for CAT files
|
||||
foreach(ext ${extensions_nocat})
|
||||
# Extract PKCS#7 with data content, output in PEM format
|
||||
add_test(NAME "data_${ext}_pem"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "extract-data"
|
||||
"-ph"
|
||||
"-h" "sha384"
|
||||
"-add-msi-dse"
|
||||
"-pem" # PEM format
|
||||
"-in" "${FILES}/unsigned.${ext}"
|
||||
"-out" "${FILES}/data_${ext}.pem")
|
||||
|
||||
# Extract PKCS#7 with data content, output in default DER format
|
||||
add_test(NAME "data_${ext}_der"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "extract-data"
|
||||
"-ph"
|
||||
"-h" "sha384"
|
||||
"-add-msi-dse"
|
||||
"-in" "${FILES}/unsigned.${ext}"
|
||||
"-out" "${FILES}/data_${ext}.der")
|
||||
|
||||
foreach(data_format ${formats})
|
||||
set_tests_properties("data_${ext}_${data_format}" PROPERTIES
|
||||
DEPENDS "start_server")
|
||||
list(APPEND ALL_TESTS "data_${ext}_${data_format}")
|
||||
endforeach(data_format ${formats})
|
||||
|
||||
# Sign a data content, output in DER format
|
||||
foreach(data_format ${formats})
|
||||
add_test(NAME "signed_data_${ext}_${data_format}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "sign"
|
||||
"-pkcs12" "${CERTS}/cert.p12"
|
||||
"-readpass" "${CERTS}/password.txt"
|
||||
"-ac" "${CERTS}/CAcross.pem"
|
||||
"-time" "1556668800" # Signing time: May 1 00:00:00 2019 GMT
|
||||
"-add-msi-dse"
|
||||
"-comm"
|
||||
"-ph"
|
||||
"-jp" "low"
|
||||
"-h" "sha384"
|
||||
"-i" "https://www.osslsigncode.com/"
|
||||
"-n" "osslsigncode"
|
||||
"-in" "${FILES}/data_${ext}.${data_format}"
|
||||
"-out" "${FILES}/signed_data_${ext}_${data_format}.der")
|
||||
set_tests_properties("signed_data_${ext}_${data_format}" PROPERTIES
|
||||
DEPENDS "data_${ext}_pem;data_${ext}_der")
|
||||
list(APPEND ALL_TESTS "signed_data_${ext}_${data_format}")
|
||||
endforeach(data_format ${formats})
|
||||
|
||||
# Sign a data content, output in PEM format
|
||||
foreach(data_format ${formats})
|
||||
add_test(NAME "signed_data_pem_${ext}_${data_format}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "sign"
|
||||
"-pkcs12" "${CERTS}/cert.p12"
|
||||
"-readpass" "${CERTS}/password.txt"
|
||||
"-ac" "${CERTS}/CAcross.pem"
|
||||
"-time" "1556668800" # Signing time: May 1 00:00:00 2019 GMT
|
||||
"-add-msi-dse"
|
||||
"-comm"
|
||||
"-ph"
|
||||
"-jp" "low"
|
||||
"-h" "sha384"
|
||||
"-i" "https://www.osslsigncode.com/"
|
||||
"-n" "osslsigncode"
|
||||
"-pem" # PEM format
|
||||
"-in" "${FILES}/data_${ext}.${data_format}"
|
||||
"-out" "${FILES}/signed_data_${ext}_${data_format}.pem")
|
||||
set_tests_properties("signed_data_pem_${ext}_${data_format}" PROPERTIES
|
||||
DEPENDS "data_${ext}_${data_format}")
|
||||
list(APPEND ALL_TESTS "signed_data_pem_${ext}_${data_format}")
|
||||
endforeach(data_format ${formats})
|
||||
|
||||
# Attach signature in PEM or DER format
|
||||
foreach(data_format ${formats})
|
||||
foreach(format ${formats})
|
||||
add_test(NAME "attached_data_${ext}_${data_format}_${format}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "attach-signature"
|
||||
# sign options
|
||||
"-add-msi-dse"
|
||||
"-h" "sha384"
|
||||
"-sigin" "${FILES}/signed_data_${ext}_${data_format}.${format}"
|
||||
"-in" "${FILES}/unsigned.${ext}"
|
||||
"-out" "${FILES}/attached_data_${data_format}_${format}.${ext}"
|
||||
# verify options
|
||||
"-require-leaf-hash" "FILE ${CERTS}/leafhash.txt"
|
||||
"-time" "1567296000" # Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-CRLfile" "${CERTS}/CACertCRL.pem")
|
||||
set_tests_properties("attached_data_${ext}_${data_format}_${format}" PROPERTIES
|
||||
DEPENDS "signed_data_${ext}_${data_format};signed_data_pem_${ext}_${data_format}")
|
||||
list(APPEND ALL_TESTS "attached_data_${ext}_${data_format}_${format}")
|
||||
endforeach(format ${formats})
|
||||
endforeach(data_format ${formats})
|
||||
endforeach(ext ${extensions_nocat})
|
||||
|
||||
|
||||
if(OPENSSL_VERSION VERSION_GREATER_EQUAL "3.0.0" OR CURL_FOUND)
|
||||
|
||||
### Sign with Time-Stamp Authority ###
|
||||
|
||||
# Sign with the RFC3161 Time-Stamp Authority
|
||||
set(pem_certs "cert" "expired" "revoked")
|
||||
foreach(ext ${extensions_all})
|
||||
foreach(cert ${pem_certs})
|
||||
add_test(NAME "sign_ts_${cert}_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "sign"
|
||||
"-certs" "${CERTS}/${cert}.pem"
|
||||
"-key" "${CERTS}/key.pem"
|
||||
"-ac" "${CERTS}/CAcross.pem"
|
||||
"-comm"
|
||||
"-ph"
|
||||
"-jp" "low"
|
||||
"-h" "sha384"
|
||||
"-i" "https://www.osslsigncode.com/"
|
||||
"-n" "osslsigncode"
|
||||
"-time" "1556668800" # Signing time: May 1 00:00:00 2019 GMT
|
||||
"-ts" "FILE ${LOGS}/url.log"
|
||||
"-in" "${FILES}/unsigned.${ext}"
|
||||
"-out" "${FILES}/ts_${cert}.${ext}")
|
||||
set_tests_properties("sign_ts_${cert}_${ext}" PROPERTIES
|
||||
ENVIRONMENT "HTTP_PROXY=;http_proxy="
|
||||
DEPENDS "start_server")
|
||||
list(APPEND ALL_TESTS "sign_ts_${cert}_${ext}")
|
||||
endforeach(cert ${pem_certs})
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
|
||||
### Verify Time-Stamp Authority ###
|
||||
|
||||
# Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "verify_ts_cert_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "verify"
|
||||
"-time" "1567296000" # Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-TSA-CAfile" "${CERTS}/TSACA.pem"
|
||||
"-in" "${FILES}/ts_cert.${ext}")
|
||||
set_tests_properties("verify_ts_cert_${ext}" PROPERTIES
|
||||
ENVIRONMENT "HTTP_PROXY=;http_proxy=;"
|
||||
DEPENDS "sign_ts_cert_${ext}")
|
||||
list(APPEND ALL_TESTS "verify_ts_cert_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
# Signature verification time: Jan 1 00:00:00 2035 GMT
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "verify_ts_future_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "verify"
|
||||
"-time" "2051222400" # Signature verification time: Jan 1 00:00:00 2035 GMT
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-TSA-CAfile" "${CERTS}/TSACA.pem"
|
||||
"-in" "${FILES}/ts_cert.${ext}")
|
||||
set_tests_properties("verify_ts_future_${ext}" PROPERTIES
|
||||
ENVIRONMENT "HTTP_PROXY=;http_proxy=;"
|
||||
DEPENDS "sign_ts_cert_${ext}")
|
||||
list(APPEND ALL_TESTS "verify_ts_future_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
# Verify with ignored timestamp
|
||||
# This tests are expected to fail
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "verify_ts_ignore_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "verify"
|
||||
"-time" "2051222400" # Signature verification time: Jan 1 00:00:00 2035 GMT
|
||||
"-ignore-timestamp"
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-TSA-CAfile" "${CERTS}/TSACA.pem"
|
||||
"-in" "${FILES}/ts_cert.${ext}")
|
||||
set_tests_properties("verify_ts_ignore_${ext}" PROPERTIES
|
||||
ENVIRONMENT "HTTP_PROXY=;http_proxy=;"
|
||||
DEPENDS "sign_ts_cert_${ext}"
|
||||
WILL_FAIL TRUE)
|
||||
list(APPEND ALL_TESTS "verify_ts_ignore_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
|
||||
### Verify CRL Distribution Points ###
|
||||
|
||||
# Verify file signed with X509v3 CRL Distribution Points extension
|
||||
# Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
# Check X509v3 CRL Distribution Points extension, don't use "-CRLfile" and "-TSA-CRLfile" options
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "verify_ts_cert_crldp_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "verify"
|
||||
"-time" "1567296000" # Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-TSA-CAfile" "${CERTS}/TSACA.pem"
|
||||
"-in" "${FILES}/ts_cert.${ext}")
|
||||
set_tests_properties("verify_ts_cert_crldp_${ext}" PROPERTIES
|
||||
ENVIRONMENT "HTTP_PROXY=;http_proxy=;"
|
||||
DEPENDS "sign_ts_cert_${ext}")
|
||||
list(APPEND ALL_TESTS "verify_ts_cert_crldp_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
# Verify with expired or revoked certificate, ignore X509v3 CRL Distribution Points extension
|
||||
# This tests are expected to fail
|
||||
set(failed_certs "expired" "revoked")
|
||||
foreach(ext ${extensions_all})
|
||||
foreach(cert ${failed_certs})
|
||||
add_test(NAME "verify_ts_${cert}_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "verify"
|
||||
"-time" "1567296000" # Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-CRLfile" "${CERTS}/CACertCRL.pem"
|
||||
"-ignore-cdp"
|
||||
"-TSA-CAfile" "${CERTS}/TSACA.pem"
|
||||
"-in" "${FILES}/ts_${cert}.${ext}")
|
||||
set_tests_properties("verify_ts_${cert}_${ext}" PROPERTIES
|
||||
ENVIRONMENT "HTTP_PROXY=;http_proxy=;"
|
||||
DEPENDS "sign_ts_${cert}_${ext}"
|
||||
WILL_FAIL TRUE)
|
||||
list(APPEND ALL_TESTS "verify_ts_${cert}_${ext}")
|
||||
endforeach(cert ${failed_certs})
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
# Verify with revoked certificate contains X509v3 CRL Distribution Points extension
|
||||
# Check X509v3 CRL Distribution Points extension, don't use "-CRLfile" and "-TSA-CRLfile" options
|
||||
# This test is expected to fail
|
||||
foreach(ext ${extensions_all})
|
||||
add_test(NAME "verify_ts_revoked_crldp_${ext}"
|
||||
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "verify"
|
||||
"-time" "1567296000" # Signature verification time: Sep 1 00:00:00 2019 GMT
|
||||
"-CAfile" "${CERTS}/CACert.pem"
|
||||
"-TSA-CAfile" "${CERTS}/TSACA.pem"
|
||||
"-in" "${FILES}/ts_revoked.${ext}")
|
||||
set_tests_properties("verify_ts_revoked_crldp_${ext}" PROPERTIES
|
||||
ENVIRONMENT "HTTP_PROXY=;http_proxy=;"
|
||||
DEPENDS "sign_ts_revoked_${ext}"
|
||||
WILL_FAIL TRUE)
|
||||
list(APPEND ALL_TESTS "verify_ts_revoked_crldp_${ext}")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
### Cleanup ###
|
||||
# Stop HTTP server
|
||||
if(STOP_SERVER)
|
||||
add_test(NAME "stop_server"
|
||||
COMMAND ${Python3_EXECUTABLE} "${TEST_DIR}/client_http.py")
|
||||
set_tests_properties("stop_server" PROPERTIES
|
||||
DEPENDS "${ALL_TESTS}")
|
||||
list(APPEND ALL_TESTS "stop_server")
|
||||
else(STOP_SERVER)
|
||||
message(STATUS "Keep HTTP server after tests")
|
||||
endif(STOP_SERVER)
|
||||
|
||||
else(OPENSSL_VERSION VERSION_GREATER_EQUAL "3.0.0" OR CURL_FOUND)
|
||||
message(STATUS "CTest skips some tests")
|
||||
endif(OPENSSL_VERSION VERSION_GREATER_EQUAL "3.0.0" OR CURL_FOUND)
|
||||
|
||||
# Delete test files
|
||||
set(names "signed" "nested" "revoked" "removed" "added")
|
||||
foreach(ext ${extensions_all})
|
||||
foreach(name ${names})
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} "${FILES}/${name}.${ext}")
|
||||
endforeach(name ${names})
|
||||
foreach(cert ${pem_certs})
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} "${FILES}/ts_${cert}.${ext}")
|
||||
endforeach(cert ${pem_certs})
|
||||
foreach(format ${formats})
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} "${FILES}/${ext}.${format}")
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} "${FILES}/${ext}.${format}")
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} "${FILES}/attached_${format}.${ext}")
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} "${FILES}/data_${ext}.${format}")
|
||||
foreach(data_format ${formats})
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} "${FILES}/signed_data_${ext}_${format}.${data_format}")
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} "${FILES}/attached_data_${data_format}_${format}.${ext}")
|
||||
endforeach(data_format ${formats})
|
||||
endforeach(format ${formats})
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} "${FILES}/jreq.tsq")
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} "${FILES}/jresp.tsr")
|
||||
endforeach(ext ${extensions_all})
|
||||
|
||||
add_test(NAME "remove_files"
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -f ${OUTPUT_FILES})
|
||||
|
||||
set_tests_properties("remove_files" PROPERTIES
|
||||
DEPENDS "${ALL_TESTS}")
|
||||
|
||||
endif(Python3_FOUND AND NOT cryptography_error)
|
||||
|
||||
|
||||
#[[
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
]]
|
26
cmake/FindHeaders.cmake
Normal file
26
cmake/FindHeaders.cmake
Normal file
@ -0,0 +1,26 @@
|
||||
include(CheckIncludeFile)
|
||||
include(CheckFunctionExists)
|
||||
|
||||
if(UNIX)
|
||||
check_function_exists(getpass HAVE_GETPASS)
|
||||
check_include_file(termios.h HAVE_TERMIOS_H)
|
||||
check_include_file(sys/mman.h HAVE_SYS_MMAN_H)
|
||||
if(HAVE_SYS_MMAN_H)
|
||||
check_function_exists(mmap HAVE_MMAP)
|
||||
endif(HAVE_SYS_MMAN_H)
|
||||
else(UNIX)
|
||||
check_include_file(windows.h HAVE_MAPVIEWOFFILE)
|
||||
endif(UNIX)
|
||||
|
||||
if(NOT (HAVE_MMAP OR HAVE_MAPVIEWOFFILE))
|
||||
message(FATAL_ERROR "Error: Need file mapping function to build.")
|
||||
endif(NOT (HAVE_MMAP OR HAVE_MAPVIEWOFFILE))
|
||||
|
||||
#[[
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
]]
|
32
cmake/SetBashCompletion.cmake
Normal file
32
cmake/SetBashCompletion.cmake
Normal file
@ -0,0 +1,32 @@
|
||||
# This list describes the default variables included in the bash-completion package:
|
||||
# BASH_COMPLETION_VERSION "@VERSION@"
|
||||
# BASH_COMPLETION_PREFIX "@prefix@"
|
||||
# BASH_COMPLETION_COMPATDIR "@sysconfdir@/bash_completion.d"
|
||||
# BASH_COMPLETION_COMPLETIONSDIR "@datadir@/@PACKAGE@/completions"
|
||||
# BASH_COMPLETION_HELPERSDIR "@datadir@/@PACKAGE@/helpers"
|
||||
# BASH_COMPLETION_FOUND "TRUE"
|
||||
# https://github.com/scop/bash-completion/blob/master/bash-completion-config.cmake.in
|
||||
|
||||
if(NOT MSVC)
|
||||
if(BASH_COMPLETION_USER_DIR)
|
||||
set(BASH_COMPLETION_COMPLETIONSDIR "${BASH_COMPLETION_USER_DIR}/bash-completion/completions")
|
||||
else(BASH_COMPLETION_USER_DIR)
|
||||
find_package(bash-completion QUIET)
|
||||
if(NOT BASH_COMPLETION_FOUND)
|
||||
set(SHAREDIR "${CMAKE_INSTALL_PREFIX}/share")
|
||||
set(BASH_COMPLETION_COMPLETIONSDIR "${SHAREDIR}/bash-completion/completions")
|
||||
endif(NOT BASH_COMPLETION_FOUND)
|
||||
endif(BASH_COMPLETION_USER_DIR)
|
||||
|
||||
message(STATUS "Using bash completions dir ${BASH_COMPLETION_COMPLETIONSDIR}")
|
||||
install(FILES "osslsigncode.bash" DESTINATION ${BASH_COMPLETION_COMPLETIONSDIR})
|
||||
endif(NOT MSVC)
|
||||
|
||||
#[[
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
]]
|
123
cmake/SetCompilerFlags.cmake
Normal file
123
cmake/SetCompilerFlags.cmake
Normal file
@ -0,0 +1,123 @@
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
set(CMAKE_REQUIRED_QUIET ON)
|
||||
|
||||
function(add_debug_flag_if_supported flagname targets)
|
||||
check_c_compiler_flag("${flagname}" HAVE_FLAG_${flagname})
|
||||
if (HAVE_FLAG_${flagname})
|
||||
foreach(target ${targets})
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:DEBUG>:${flagname}>)
|
||||
endforeach(target ${targets})
|
||||
endif(HAVE_FLAG_${flagname})
|
||||
endfunction(add_debug_flag_if_supported flagname targets)
|
||||
|
||||
function(add_compile_flag_to_targets targets)
|
||||
set(CHECKED_DEBUG_FLAGS
|
||||
"-ggdb"
|
||||
"-g"
|
||||
"-O2"
|
||||
"-pedantic"
|
||||
"-Wall"
|
||||
"-Wextra"
|
||||
"-Wno-long-long"
|
||||
"-Wconversion"
|
||||
"-D_FORTIFY_SOURCE=2"
|
||||
"-Wformat=2"
|
||||
"-Wredundant-decls"
|
||||
"-Wcast-qual"
|
||||
"-Wnull-dereference"
|
||||
"-Wno-deprecated-declarations"
|
||||
"-Wmissing-declarations"
|
||||
"-Wmissing-prototypes"
|
||||
"-Wmissing-noreturn"
|
||||
"-Wmissing-braces"
|
||||
"-Wparentheses"
|
||||
"-Wstrict-aliasing=3"
|
||||
"-Wstrict-overflow=2"
|
||||
"-Wlogical-op"
|
||||
"-Wwrite-strings"
|
||||
"-Wcast-align=strict"
|
||||
"-Wdisabled-optimization"
|
||||
"-Wshift-overflow=2"
|
||||
"-Wundef"
|
||||
"-Wshadow"
|
||||
"-Wmisleading-indentation"
|
||||
"-Wabsolute-value"
|
||||
"-Wunused-parameter"
|
||||
"-Wunused-function")
|
||||
foreach(flag ${CHECKED_DEBUG_FLAGS})
|
||||
add_debug_flag_if_supported(${flag} ${targets})
|
||||
endforeach(flag ${CHECKED_DEBUG_FLAGS})
|
||||
endfunction(add_compile_flag_to_targets targets)
|
||||
|
||||
function(add_compile_flags target)
|
||||
if(MSVC)
|
||||
# Enable parallel builds
|
||||
target_compile_options(${target} PRIVATE /MP)
|
||||
# Use address space layout randomization, generate PIE code for ASLR (default on)
|
||||
target_link_options(${target} PRIVATE /DYNAMICBASE)
|
||||
# Create terminal server aware application (default on)
|
||||
target_link_options(${target} PRIVATE /TSAWARE)
|
||||
# Mark the binary as compatible with Intel Control-flow Enforcement Technology (CET) Shadow Stack
|
||||
target_link_options(${target} PRIVATE /CETCOMPAT)
|
||||
# Enable compiler generation of Control Flow Guard security checks
|
||||
target_compile_options(${target} PRIVATE /guard:cf)
|
||||
target_link_options(${target} PRIVATE /guard:cf)
|
||||
# Buffer Security Check
|
||||
target_compile_options(${target} PRIVATE /GS)
|
||||
# Suppress startup banner
|
||||
target_link_options(${target} PRIVATE /NOLOGO)
|
||||
# Generate debug info
|
||||
target_link_options(${target} PRIVATE /DEBUG)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
# High entropy ASLR for 64 bits targets (default on)
|
||||
target_link_options(${target} PRIVATE /HIGHENTROPYVA)
|
||||
# Enable generation of EH Continuation (EHCONT) metadata by the compiler
|
||||
#target_compile_options(${target} PRIVATE /guard:ehcont)
|
||||
#target_link_options(${target} PRIVATE /guard:ehcont)
|
||||
else("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
# Can handle addresses larger than 2 gigabytes
|
||||
target_link_options(${target} PRIVATE /LARGEADDRESSAWARE)
|
||||
# Safe structured exception handlers (x86 only)
|
||||
target_link_options(${target} PRIVATE /SAFESEH)
|
||||
endif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:DEBUG>:/D_FORTIFY_SOURCE=2>)
|
||||
# Unrecognized compiler options are errors
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:DEBUG>:/options:strict>)
|
||||
else(MSVC)
|
||||
check_c_compiler_flag("-fstack-protector-all" HAVE_STACK_PROTECTOR_ALL)
|
||||
if(HAVE_STACK_PROTECTOR_ALL)
|
||||
target_link_options(${target} PRIVATE -fstack-protector-all)
|
||||
else(HAVE_STACK_PROTECTOR_ALL)
|
||||
check_c_compiler_flag("-fstack-protector" HAVE_STACK_PROTECTOR)
|
||||
if(HAVE_STACK_PROTECTOR)
|
||||
target_link_options(${target} PRIVATE -fstack-protector)
|
||||
else(HAVE_STACK_PROTECTOR)
|
||||
message(WARNING "No stack protection supported")
|
||||
endif(HAVE_STACK_PROTECTOR)
|
||||
endif(HAVE_STACK_PROTECTOR_ALL)
|
||||
# Support address space layout randomization (ASLR)
|
||||
if(NOT (MINGW OR CYGWIN OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
|
||||
OR ((CMAKE_SYSTEM_NAME MATCHES Darwin) AND (CMAKE_C_COMPILER_ID MATCHES Clang))))
|
||||
target_compile_options(${target} PRIVATE -fPIE)
|
||||
target_link_options(${target} PRIVATE -fPIE -pie)
|
||||
target_link_options(${target} PRIVATE -Wl,-z,relro)
|
||||
target_link_options(${target} PRIVATE -Wl,-z,now)
|
||||
target_link_options(${target} PRIVATE -Wl,-z,noexecstack)
|
||||
endif(NOT (MINGW OR CYGWIN OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
|
||||
OR ((CMAKE_SYSTEM_NAME MATCHES Darwin) AND (CMAKE_C_COMPILER_ID MATCHES Clang))))
|
||||
target_link_options(${target} PRIVATE -fstack-check)
|
||||
add_compile_flag_to_targets(${target})
|
||||
endif(MSVC)
|
||||
endfunction(add_compile_flags target)
|
||||
|
||||
add_compile_flags(osslsigncode)
|
||||
|
||||
#[[
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
]]
|
9038
code_signing_ca.pem
Normal file
9038
code_signing_ca.pem
Normal file
File diff suppressed because it is too large
Load Diff
140
configure.ac
140
configure.ac
@ -1,140 +0,0 @@
|
||||
AC_PREREQ(2.60)
|
||||
|
||||
AC_INIT([osslsigncode], [2.1.0], [Michal.Trojnara@stunnel.org])
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
AC_CONFIG_SRCDIR([osslsigncode.c])
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[strict],
|
||||
[AS_HELP_STRING([--enable-strict],[enable strict compile mode @<:@disabled@:>@])],
|
||||
,
|
||||
[enable_strict="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[pedantic],
|
||||
[AS_HELP_STRING([--enable-pedantic],[enable pedantic compile mode @<:@disabled@:>@])],
|
||||
,
|
||||
[enable_pedantic="no"]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(
|
||||
[curl],
|
||||
[AS_HELP_STRING([--with-curl],[enable curl @<:@enabled@:>@])],
|
||||
,
|
||||
[with_curl="yes"]
|
||||
)
|
||||
|
||||
if test "${enable_pedantic}" = "yes"; then
|
||||
enable_strict="yes";
|
||||
CFLAGS="${CFLAGS} -pedantic"
|
||||
fi
|
||||
if test "${enable_strict}" = "yes"; then
|
||||
CFLAGS="${CFLAGS} -Wall -Wextra"
|
||||
fi
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MKDIR_P
|
||||
AC_PROG_SED
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
AC_C_CONST
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_TIME
|
||||
AC_CHECK_HEADERS(
|
||||
[sys/mman.h],
|
||||
[AC_CHECK_FUNC(
|
||||
[mmap],
|
||||
[AC_DEFINE(HAVE_MMAP, [1], [Define to 1 if you have mmap])],
|
||||
[AC_MSG_ERROR([Need mmap to build.])]
|
||||
)],
|
||||
[have_mmap=no]
|
||||
)
|
||||
AC_CHECK_HEADERS(
|
||||
[windows.h],
|
||||
[],
|
||||
[have_MapViewOfFile=no]
|
||||
)
|
||||
AS_IF([test "x$have_mmap$have_MapViewOfFile" = "xnono"],
|
||||
[AC_MSG_ERROR([Need file mapping function to buid.])])
|
||||
|
||||
AC_CHECK_LIB(
|
||||
[dl],
|
||||
[dlopen],
|
||||
[DL_LIBS="-ldl"]
|
||||
)
|
||||
|
||||
AC_CHECK_HEADERS([termios.h])
|
||||
AC_CHECK_FUNCS(getpass)
|
||||
|
||||
AC_ARG_WITH([gsf],
|
||||
AS_HELP_STRING([--without-gsf], [Ignore presence of libgsf and disable it])
|
||||
)
|
||||
AS_IF([test "x$with_gsf" != "xno"],
|
||||
[PKG_CHECK_MODULES([GSF], [libgsf-1], [have_gsf=yes], [have_gsf=no])],
|
||||
[have_gsf=no]
|
||||
)
|
||||
AS_IF([test "x$have_gsf" = "xyes"],
|
||||
[AC_DEFINE([WITH_GSF], 1, [Have libgsf?])],
|
||||
[AS_IF([test "x$with_gsf" = "xyes"],
|
||||
[AC_MSG_ERROR([libgsf requested but not found])])]
|
||||
)
|
||||
|
||||
|
||||
PKG_CHECK_MODULES(
|
||||
[OPENSSL],
|
||||
[libcrypto >= 1.1.1],
|
||||
,
|
||||
[PKG_CHECK_MODULES(
|
||||
[OPENSSL],
|
||||
[openssl >= 1.1.1],
|
||||
,
|
||||
[AC_CHECK_LIB(
|
||||
[crypto],
|
||||
[EVP_MD_CTX_new],
|
||||
[OPENSSL_LIBS="-lcrypto ${SOCKETS_LIBS} ${DL_LIBS}"],
|
||||
[AC_MSG_ERROR([OpenSSL 1.1.1 or later is required. https://www.openssl.org/])],
|
||||
[${DL_LIBS}]
|
||||
)]
|
||||
)]
|
||||
)
|
||||
|
||||
PKG_CHECK_MODULES(
|
||||
[LIBCURL],
|
||||
[libcurl >= 7.12.0],
|
||||
,
|
||||
[AC_CHECK_LIB(
|
||||
[curl],
|
||||
[curl_easy_strerror],
|
||||
[LIBCURL_LIBS="-lcurl"],
|
||||
,
|
||||
[${DL_LIBS}]
|
||||
)]
|
||||
)
|
||||
|
||||
if test "${with_curl}" = "yes"; then
|
||||
test -z "${LIBCURL_LIBS}" && AC_MSG_ERROR([Curl 7.12.0 or later is required for timestamping support. http://curl.haxx.se/])
|
||||
OPTIONAL_LIBCURL_CFLAGS="${LIBCURL_CFLAGS}"
|
||||
OPTIONAL_LIBCURL_LIBS="${LIBCURL_LIBS}"
|
||||
AC_DEFINE([ENABLE_CURL], [1], [libcurl is enabled])
|
||||
fi
|
||||
|
||||
AC_SUBST([OPTIONAL_LIBCURL_CFLAGS])
|
||||
AC_SUBST([OPTIONAL_LIBCURL_LIBS])
|
||||
|
||||
AC_DEFINE_UNQUOTED([CA_BUNDLE_PATH], ["$(curl-config --ca 2>/dev/null)"], [CA bundle install path])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
# vim: set ts=4 noexpandtab:
|
41
get_code_signing_ca.py
Executable file
41
get_code_signing_ca.py
Executable file
@ -0,0 +1,41 @@
|
||||
#!/usr/bin/python3
|
||||
# © 2024 Michal Trojnara
|
||||
# This script downloads Microsoft code signing certificates
|
||||
# Tor is required for this script to work
|
||||
# Redirect the script output to a PEM file
|
||||
|
||||
from sys import stderr
|
||||
from time import sleep
|
||||
from csv import reader
|
||||
from requests import get
|
||||
from requests.exceptions import RequestException
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
def download_cert(hash):
|
||||
for attempt in range(10):
|
||||
if attempt > 0:
|
||||
sleep(10)
|
||||
try:
|
||||
creds = f'{attempt}{hash}:{attempt}{hash}'
|
||||
resp = get(f'https://crt.sh/?d={hash}',
|
||||
proxies=dict(https=f'socks5://{creds}@127.0.0.1:9050'))
|
||||
resp.raise_for_status()
|
||||
print('.', file=stderr, end='')
|
||||
stderr.flush()
|
||||
return resp.content.decode('utf-8')
|
||||
except RequestException as e:
|
||||
print(f'\nAttempt {attempt}: {e}', file=stderr)
|
||||
print('\nGiving up on', hash, file=stderr)
|
||||
|
||||
resp = get('https://ccadb-public.secure.force.com/microsoft/IncludedCACertificateReportForMSFTCSV')
|
||||
resp.raise_for_status()
|
||||
lines = resp.content.decode('utf-8').splitlines()[1:]
|
||||
hashes = [row[4] for row in reader(lines)
|
||||
if row[0] != 'Disabled'
|
||||
or row[4] == 'F38406E540D7A9D90CB4A9479299640FFB6DF9E224ECC7A01C0D9558D8DAD77D']
|
||||
with ThreadPoolExecutor(max_workers=20) as executor:
|
||||
certs = executor.map(download_cert, hashes)
|
||||
for cert in certs:
|
||||
if cert is not None:
|
||||
print(cert)
|
||||
print('\nDone', file=stderr)
|
805
helpers.c
Normal file
805
helpers.c
Normal file
@ -0,0 +1,805 @@
|
||||
/*
|
||||
* osslsigncode support library
|
||||
*
|
||||
* Copyright (C) 2021-2023 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
* Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
|
||||
*/
|
||||
|
||||
#include "osslsigncode.h"
|
||||
#include "helpers.h"
|
||||
|
||||
/* Prototypes */
|
||||
static SpcSpOpusInfo *spc_sp_opus_info_create(FILE_FORMAT_CTX *ctx);
|
||||
static int spc_indirect_data_content_create(u_char **blob, int *len, FILE_FORMAT_CTX *ctx);
|
||||
static int pkcs7_signer_info_add_spc_sp_opus_info(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||
static int pkcs7_signer_info_add_signing_time(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||
static int pkcs7_signer_info_add_purpose(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||
static int pkcs7_signer_info_add_sequence_number(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||
static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer);
|
||||
static int X509_compare(const X509 *const *a, const X509 *const *b);
|
||||
|
||||
/*
|
||||
* Common functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* [in] infile
|
||||
* [returns] file size
|
||||
*/
|
||||
uint32_t get_file_size(const char *infile)
|
||||
{
|
||||
int ret;
|
||||
#ifdef _WIN32
|
||||
struct _stat64 st;
|
||||
ret = _stat64(infile, &st);
|
||||
#else
|
||||
struct stat st;
|
||||
ret = stat(infile, &st);
|
||||
#endif
|
||||
if (ret) {
|
||||
fprintf(stderr, "Failed to open file: %s\n", infile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (st.st_size < 4) {
|
||||
fprintf(stderr, "Unrecognized file type - file is too short: %s\n", infile);
|
||||
return 0;
|
||||
}
|
||||
if (st.st_size > UINT32_MAX) {
|
||||
fprintf(stderr, "Unsupported file - too large: %s\n", infile);
|
||||
return 0;
|
||||
}
|
||||
return (uint32_t)st.st_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] infile: starting address for the new mapping
|
||||
* [returns] pointer to the mapped area
|
||||
*/
|
||||
char *map_file(const char *infile, const size_t size)
|
||||
{
|
||||
char *indata = NULL;
|
||||
#ifdef WIN32
|
||||
HANDLE fhandle, fmap;
|
||||
(void)size;
|
||||
fhandle = CreateFile(infile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (fhandle == INVALID_HANDLE_VALUE) {
|
||||
return NULL;
|
||||
}
|
||||
fmap = CreateFileMapping(fhandle, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
CloseHandle(fhandle);
|
||||
if (fmap == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
indata = (char *)MapViewOfFile(fmap, FILE_MAP_READ, 0, 0, 0);
|
||||
CloseHandle(fmap);
|
||||
#else
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
int fd = open(infile, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
indata = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (indata == MAP_FAILED) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
close(fd);
|
||||
#else
|
||||
fprintf(stderr, "No file mapping function\n");
|
||||
return NULL;
|
||||
#endif /* HAVE_SYS_MMAN_H */
|
||||
#endif /* WIN32 */
|
||||
return indata;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] indata: starting address space
|
||||
* [in] size: mapped area length
|
||||
* [returns] none
|
||||
*/
|
||||
void unmap_file(char *indata, const size_t size)
|
||||
{
|
||||
if (!indata)
|
||||
return;
|
||||
#ifdef WIN32
|
||||
(void)size;
|
||||
UnmapViewOfFile(indata);
|
||||
#else
|
||||
munmap(indata, size);
|
||||
#endif /* WIN32 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve a decoded PKCS#7 structure
|
||||
* [in] data: encoded PEM or DER data
|
||||
* [in] size: data size
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
PKCS7 *pkcs7_read_data(char *data, uint32_t size)
|
||||
{
|
||||
PKCS7 *p7 = NULL;
|
||||
BIO *bio;
|
||||
const char pemhdr[] = "-----BEGIN PKCS7-----";
|
||||
|
||||
bio = BIO_new_mem_buf(data, (int)size);
|
||||
if (size >= sizeof pemhdr && !memcmp(data, pemhdr, sizeof pemhdr - 1)) {
|
||||
/* PEM format */
|
||||
p7 = PEM_read_bio_PKCS7(bio, NULL, NULL, NULL);
|
||||
} else { /* DER format */
|
||||
p7 = d2i_PKCS7_bio(bio, NULL);
|
||||
}
|
||||
BIO_free_all(bio);
|
||||
return p7;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] outdata: BIO outdata file
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
int data_write_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
||||
{
|
||||
int ret;
|
||||
|
||||
(void)BIO_reset(outdata);
|
||||
if (ctx->options->output_pkcs7) {
|
||||
/* PEM format */
|
||||
ret = !PEM_write_bio_PKCS7(outdata, p7);
|
||||
} else {
|
||||
/* default DER format */
|
||||
ret = !i2d_PKCS7_bio(outdata, p7);
|
||||
}
|
||||
if (ret) {
|
||||
fprintf(stderr, "Unable to write pkcs7 object\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate, set type, add content and return a new PKCS#7 signature
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
int i, signer = -1;
|
||||
PKCS7_SIGNER_INFO *si = NULL;
|
||||
STACK_OF(X509) *chain = NULL;
|
||||
PKCS7 *p7 = PKCS7_new();
|
||||
|
||||
if (!p7)
|
||||
return NULL;
|
||||
|
||||
PKCS7_set_type(p7, NID_pkcs7_signed);
|
||||
PKCS7_content_new(p7, NID_pkcs7_data);
|
||||
|
||||
/* find the signer's certificate located somewhere in the whole certificate chain */
|
||||
for (i=0; i<sk_X509_num(ctx->options->certs); i++) {
|
||||
X509 *signcert = sk_X509_value(ctx->options->certs, i);
|
||||
|
||||
if (X509_check_private_key(signcert, ctx->options->pkey)) {
|
||||
si = PKCS7_add_signature(p7, signcert, ctx->options->pkey, ctx->options->md);
|
||||
signer = i;
|
||||
if (signer > 0)
|
||||
printf("Warning: For optimal performance, consider placing the signer certificate at the beginning of the certificate chain.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!si) {
|
||||
fprintf(stderr, "Failed to checking the consistency of a private key: %s\n",
|
||||
ctx->options->keyfile);
|
||||
fprintf(stderr, " with a public key in any X509 certificate: %s\n\n",
|
||||
#if !defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER>=0x30000000L
|
||||
ctx->options->certfile ? ctx->options->certfile : ctx->options->p11cert);
|
||||
#else
|
||||
ctx->options->certfile);
|
||||
#endif /* !defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER>=0x30000000L */
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!pkcs7_signer_info_add_signing_time(si, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (!pkcs7_signer_info_add_purpose(si, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if ((ctx->options->desc || ctx->options->url) &&
|
||||
!pkcs7_signer_info_add_spc_sp_opus_info(si, ctx)) {
|
||||
fprintf(stderr, "Couldn't allocate memory for opus info\n");
|
||||
goto err;
|
||||
}
|
||||
if ((ctx->options->nested_number >= 0) &&
|
||||
!pkcs7_signer_info_add_sequence_number(si, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
/* create X509 chain sorted in ascending order by their DER encoding */
|
||||
chain = X509_chain_get_sorted(ctx, signer);
|
||||
if (!chain) {
|
||||
fprintf(stderr, "Failed to create a sorted certificate chain\n");
|
||||
goto err;
|
||||
}
|
||||
/* add sorted certificate chain */
|
||||
for (i=0; i<sk_X509_num(chain); i++) {
|
||||
(void)PKCS7_add_certificate(p7, sk_X509_value(chain, i));
|
||||
}
|
||||
/* add crls */
|
||||
if (ctx->options->crls) {
|
||||
for (i=0; i<sk_X509_CRL_num(ctx->options->crls); i++)
|
||||
(void)PKCS7_add_crl(p7, sk_X509_CRL_value(ctx->options->crls, i));
|
||||
}
|
||||
sk_X509_free(chain);
|
||||
return p7; /* OK */
|
||||
|
||||
err:
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
|
||||
/*
|
||||
* PE, MSI, CAB and APPX file specific
|
||||
* Add "1.3.6.1.4.1.311.2.1.4" SPC_INDIRECT_DATA_OBJID signed attribute
|
||||
* [in, out] p7: new PKCS#7 signature
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
int add_indirect_data_object(PKCS7 *p7)
|
||||
{
|
||||
STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
|
||||
PKCS7_SIGNER_INFO *si;
|
||||
|
||||
signer_info = PKCS7_get_signer_info(p7);
|
||||
if (!signer_info)
|
||||
return 0; /* FAILED */
|
||||
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
|
||||
if (!si)
|
||||
return 0; /* FAILED */
|
||||
if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
|
||||
V_ASN1_OBJECT, OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1)))
|
||||
return 0; /* FAILED */
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* PE, MSI, CAB and APPX format specific
|
||||
* Sign the MS Authenticode spcIndirectDataContent blob.
|
||||
* The spcIndirectDataContent structure is used in Authenticode signatures
|
||||
* to store the digest and other attributes of the signed file.
|
||||
* [in, out] p7: new PKCS#7 signature
|
||||
* [in] content: spcIndirectDataContent
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content)
|
||||
{
|
||||
int len, inf, tag, class;
|
||||
long plen;
|
||||
const u_char *data, *p;
|
||||
PKCS7 *td7;
|
||||
|
||||
p = data = ASN1_STRING_get0_data(content);
|
||||
len = ASN1_STRING_length(content);
|
||||
inf = ASN1_get_object(&p, &plen, &tag, &class, len);
|
||||
if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE
|
||||
|| !pkcs7_sign_content(p7, p, (int)plen)) {
|
||||
fprintf(stderr, "Failed to sign spcIndirectDataContent\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
td7 = PKCS7_new();
|
||||
if (!td7) {
|
||||
fprintf(stderr, "PKCS7_new failed\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
td7->type = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1);
|
||||
td7->d.other = ASN1_TYPE_new();
|
||||
td7->d.other->type = V_ASN1_SEQUENCE;
|
||||
td7->d.other->value.sequence = ASN1_STRING_new();
|
||||
ASN1_STRING_set(td7->d.other->value.sequence, data, len);
|
||||
if (!PKCS7_set_content(p7, td7)) {
|
||||
fprintf(stderr, "PKCS7_set_content failed\n");
|
||||
PKCS7_free(td7);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Add encapsulated content to signed PKCS7 structure.
|
||||
* [in] content: spcIndirectDataContent
|
||||
* [returns] new PKCS#7 signature with encapsulated content
|
||||
*/
|
||||
PKCS7 *pkcs7_set_content(ASN1_OCTET_STRING *content)
|
||||
{
|
||||
PKCS7 *p7, *td7;
|
||||
|
||||
p7 = PKCS7_new();
|
||||
if (!p7) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!PKCS7_set_type(p7, NID_pkcs7_signed)) {
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!PKCS7_content_new(p7, NID_pkcs7_data)) {
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
td7 = PKCS7_new();
|
||||
if (!td7) {
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
td7->type = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1);
|
||||
td7->d.other = ASN1_TYPE_new();
|
||||
td7->d.other->type = V_ASN1_SEQUENCE;
|
||||
td7->d.other->value.sequence = content;
|
||||
if (!PKCS7_set_content(p7, td7)) {
|
||||
PKCS7_free(td7);
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
return p7;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return spcIndirectDataContent.
|
||||
* [in] hash: message digest BIO
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] content
|
||||
*/
|
||||
ASN1_OCTET_STRING *spc_indirect_data_content_get(BIO *hash, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
ASN1_OCTET_STRING *content;
|
||||
u_char mdbuf[5 * EVP_MAX_MD_SIZE + 24];
|
||||
int mdlen, hashlen, len = 0;
|
||||
u_char *data, *p = NULL;
|
||||
|
||||
content = ASN1_OCTET_STRING_new();
|
||||
if (!content) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!spc_indirect_data_content_create(&p, &len, ctx)) {
|
||||
ASN1_OCTET_STRING_free(content);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
hashlen = ctx->format->hash_length_get(ctx);
|
||||
if (hashlen > EVP_MAX_MD_SIZE) {
|
||||
/* APPX format specific */
|
||||
mdlen = BIO_read(hash, (char*)mdbuf, hashlen);
|
||||
} else {
|
||||
mdlen = BIO_gets(hash, (char*)mdbuf, EVP_MAX_MD_SIZE);
|
||||
}
|
||||
data = OPENSSL_malloc((size_t)(len + mdlen));
|
||||
memcpy(data, p, (size_t)len);
|
||||
OPENSSL_free(p);
|
||||
memcpy(data + len, mdbuf, (size_t)mdlen);
|
||||
if (!ASN1_OCTET_STRING_set(content, data, len + mdlen)) {
|
||||
ASN1_OCTET_STRING_free(content);
|
||||
OPENSSL_free(data);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
OPENSSL_free(data);
|
||||
return content;
|
||||
}
|
||||
|
||||
/*
|
||||
* Signs the data and place the signature in p7
|
||||
* [in, out] p7: new PKCS#7 signature
|
||||
* [in] data: content data
|
||||
* [in] len: content length
|
||||
*/
|
||||
int pkcs7_sign_content(PKCS7 *p7, const u_char *data, int len)
|
||||
{
|
||||
BIO *p7bio;
|
||||
|
||||
if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
|
||||
fprintf(stderr, "PKCS7_dataInit failed\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
BIO_write(p7bio, data, len);
|
||||
(void)BIO_flush(p7bio);
|
||||
if (!PKCS7_dataFinal(p7, p7bio)) {
|
||||
fprintf(stderr, "PKCS7_dataFinal failed\n");
|
||||
BIO_free_all(p7bio);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
BIO_free_all(p7bio);
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/* Return the header length (tag and length octets) of the ASN.1 type
|
||||
* [in] p: ASN.1 data
|
||||
* [in] len: ASN.1 data length
|
||||
* [returns] header length
|
||||
*/
|
||||
int asn1_simple_hdr_len(const u_char *p, int len)
|
||||
{
|
||||
if (len <= 2 || p[0] > 0x31)
|
||||
return 0;
|
||||
return (p[1]&0x80) ? (2 + (p[1]&0x7f)) : 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in, out] hash: BIO with message digest method
|
||||
* [in] indata: starting address space
|
||||
* [in] idx: offset
|
||||
* [in] fileend: the length of the hashed area
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
int bio_hash_data(BIO *hash, char *indata, size_t idx, size_t fileend)
|
||||
{
|
||||
while (idx < fileend) {
|
||||
size_t want, written;
|
||||
want = fileend - idx;
|
||||
if (want > SIZE_64K)
|
||||
want = SIZE_64K;
|
||||
if (!BIO_write_ex(hash, indata + idx, want, &written))
|
||||
return 0; /* FAILED */
|
||||
idx += written;
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] descript1, descript2: descriptions
|
||||
* [in] mdbuf: message digest
|
||||
* [in] len: message digest length
|
||||
* [returns] none
|
||||
*/
|
||||
void print_hash(const char *descript1, const char *descript2, const u_char *mdbuf, int len)
|
||||
{
|
||||
char *hexbuf = NULL;
|
||||
int size, i, j = 0;
|
||||
|
||||
size = 2 * len + 1;
|
||||
hexbuf = OPENSSL_malloc((size_t)size);
|
||||
for (i = 0; i < len; i++) {
|
||||
#ifdef WIN32
|
||||
j += sprintf_s(hexbuf + j, size - j, "%02X", mdbuf[i]);
|
||||
#else
|
||||
j += sprintf(hexbuf + j, "%02X", mdbuf[i]);
|
||||
#endif /* WIN32 */
|
||||
}
|
||||
printf("%s: %s %s\n", descript1, hexbuf, descript2);
|
||||
OPENSSL_free(hexbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [in] objid: Microsoft OID Authenticode
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
int is_content_type(PKCS7 *p7, const char *objid)
|
||||
{
|
||||
ASN1_OBJECT *indir_objid;
|
||||
int ret;
|
||||
|
||||
indir_objid = OBJ_txt2obj(objid, 1);
|
||||
ret = p7 && PKCS7_type_is_signed(p7) &&
|
||||
!OBJ_cmp(p7->d.sign->contents->type, indir_objid) &&
|
||||
(p7->d.sign->contents->d.other->type == V_ASN1_SEQUENCE ||
|
||||
p7->d.sign->contents->d.other->type == V_ASN1_OCTET_STRING);
|
||||
ASN1_OBJECT_free(indir_objid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] p7: new PKCS#7 signature
|
||||
* [returns] pointer to MsCtlContent structure
|
||||
*/
|
||||
MsCtlContent *ms_ctl_content_get(PKCS7 *p7)
|
||||
{
|
||||
ASN1_STRING *value;
|
||||
const u_char *data;
|
||||
|
||||
if (!is_content_type(p7, MS_CTL_OBJID)) {
|
||||
fprintf(stderr, "Failed to find MS_CTL_OBJID\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
value = p7->d.sign->contents->d.other->value.sequence;
|
||||
data = ASN1_STRING_get0_data(value);
|
||||
return d2i_MsCtlContent(NULL, &data, ASN1_STRING_length(value));
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] attribute: catalog attribute
|
||||
* [returns] catalog content
|
||||
*/
|
||||
ASN1_TYPE *catalog_content_get(CatalogAuthAttr *attribute)
|
||||
{
|
||||
ASN1_STRING *value;
|
||||
STACK_OF(ASN1_TYPE) *contents;
|
||||
ASN1_TYPE *content;
|
||||
const u_char *contents_data;
|
||||
|
||||
value = attribute->contents->value.sequence;
|
||||
contents_data = ASN1_STRING_get0_data(value);
|
||||
contents = d2i_ASN1_SET_ANY(NULL, &contents_data, ASN1_STRING_length(value));
|
||||
if (!contents)
|
||||
return 0; /* FAILED */
|
||||
content = sk_ASN1_TYPE_value(contents, 0);
|
||||
sk_ASN1_TYPE_free(contents);
|
||||
return content;
|
||||
}
|
||||
|
||||
/*
|
||||
* PE and CAB format specific
|
||||
* [in] none
|
||||
* [returns] pointer to SpcLink
|
||||
*/
|
||||
SpcLink *spc_link_obsolete_get(void)
|
||||
{
|
||||
const u_char obsolete[] = {
|
||||
0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x4f,
|
||||
0x00, 0x62, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x6c,
|
||||
0x00, 0x65, 0x00, 0x74, 0x00, 0x65, 0x00, 0x3e,
|
||||
0x00, 0x3e, 0x00, 0x3e
|
||||
};
|
||||
SpcLink *link = SpcLink_new();
|
||||
link->type = 2;
|
||||
link->value.file = SpcString_new();
|
||||
link->value.file->type = 0;
|
||||
link->value.file->value.unicode = ASN1_BMPSTRING_new();
|
||||
ASN1_STRING_set(link->value.file->value.unicode, obsolete, sizeof obsolete);
|
||||
return link;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] mdbuf, cmdbuf: message digests
|
||||
* [in] mdtype: message digest algorithm type
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
int compare_digests(u_char *mdbuf, u_char *cmdbuf, int mdtype)
|
||||
{
|
||||
int mdlen = EVP_MD_size(EVP_get_digestbynid(mdtype));
|
||||
int mdok = !memcmp(mdbuf, cmdbuf, (size_t)mdlen);
|
||||
printf("Message digest algorithm : %s\n", OBJ_nid2sn(mdtype));
|
||||
print_hash("Current message digest ", "", mdbuf, mdlen);
|
||||
print_hash("Calculated message digest ", mdok ? "\n" : " MISMATCH!!!\n", cmdbuf, mdlen);
|
||||
return mdok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* [in] ctx: FILE_FORMAT_CTX structure
|
||||
* [returns] pointer to SpcSpOpusInfo structure
|
||||
*/
|
||||
static SpcSpOpusInfo *spc_sp_opus_info_create(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
SpcSpOpusInfo *info = SpcSpOpusInfo_new();
|
||||
|
||||
if (ctx->options->desc) {
|
||||
info->programName = SpcString_new();
|
||||
info->programName->type = 1;
|
||||
info->programName->value.ascii = ASN1_IA5STRING_new();
|
||||
ASN1_STRING_set((ASN1_STRING *)info->programName->value.ascii,
|
||||
ctx->options->desc, (int)strlen(ctx->options->desc));
|
||||
}
|
||||
if (ctx->options->url) {
|
||||
info->moreInfo = SpcLink_new();
|
||||
info->moreInfo->type = 0;
|
||||
info->moreInfo->value.url = ASN1_IA5STRING_new();
|
||||
ASN1_STRING_set((ASN1_STRING *)info->moreInfo->value.url,
|
||||
ctx->options->url, (int)strlen(ctx->options->url));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/*
|
||||
* [out] blob: SpcIndirectDataContent data
|
||||
* [out] len: SpcIndirectDataContent data length
|
||||
* [in] ctx: FILE_FORMAT_CTX structure
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int spc_indirect_data_content_create(u_char **blob, int *len, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
u_char *p = NULL;
|
||||
int mdtype, hashlen, l = 0;
|
||||
void *hash;
|
||||
SpcIndirectDataContent *idc = SpcIndirectDataContent_new();
|
||||
|
||||
if (!ctx->format->data_blob_get || !ctx->format->hash_length_get) {
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (ctx->format->md_get) {
|
||||
/* APPX file specific - use a hash algorithm specified in the AppxBlockMap.xml file */
|
||||
mdtype = EVP_MD_nid(ctx->format->md_get(ctx));
|
||||
} else {
|
||||
mdtype = EVP_MD_nid(ctx->options->md);
|
||||
}
|
||||
idc->data->value = ASN1_TYPE_new();
|
||||
idc->data->value->type = V_ASN1_SEQUENCE;
|
||||
idc->data->value->value.sequence = ASN1_STRING_new();
|
||||
idc->data->type = ctx->format->data_blob_get(&p, &l, ctx);
|
||||
idc->data->value->value.sequence->data = p;
|
||||
idc->data->value->value.sequence->length = l;
|
||||
idc->messageDigest->digestAlgorithm->algorithm = OBJ_nid2obj(mdtype);
|
||||
idc->messageDigest->digestAlgorithm->parameters = ASN1_TYPE_new();
|
||||
idc->messageDigest->digestAlgorithm->parameters->type = V_ASN1_NULL;
|
||||
|
||||
hashlen = ctx->format->hash_length_get(ctx);
|
||||
hash = OPENSSL_zalloc((size_t)hashlen);
|
||||
ASN1_OCTET_STRING_set(idc->messageDigest->digest, hash, hashlen);
|
||||
OPENSSL_free(hash);
|
||||
|
||||
*len = i2d_SpcIndirectDataContent(idc, NULL);
|
||||
*blob = OPENSSL_malloc((size_t)*len);
|
||||
p = *blob;
|
||||
i2d_SpcIndirectDataContent(idc, &p);
|
||||
SpcIndirectDataContent_free(idc);
|
||||
*len -= hashlen;
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* [in, out] si: PKCS7_SIGNER_INFO structure
|
||||
* [in] ctx: FILE_FORMAT_CTX structure
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int pkcs7_signer_info_add_spc_sp_opus_info(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
SpcSpOpusInfo *opus;
|
||||
ASN1_STRING *astr;
|
||||
int len;
|
||||
u_char *p = NULL;
|
||||
|
||||
opus = spc_sp_opus_info_create(ctx);
|
||||
if ((len = i2d_SpcSpOpusInfo(opus, NULL)) <= 0
|
||||
|| (p = OPENSSL_malloc((size_t)len)) == NULL) {
|
||||
SpcSpOpusInfo_free(opus);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
i2d_SpcSpOpusInfo(opus, &p);
|
||||
p -= len;
|
||||
astr = ASN1_STRING_new();
|
||||
ASN1_STRING_set(astr, p, len);
|
||||
OPENSSL_free(p);
|
||||
SpcSpOpusInfo_free(opus);
|
||||
return PKCS7_add_signed_attribute(si, OBJ_txt2nid(SPC_SP_OPUS_INFO_OBJID),
|
||||
V_ASN1_SEQUENCE, astr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a custom, non-trusted time to the PKCS7 structure to prevent OpenSSL
|
||||
* adding the _current_ time. This allows to create a deterministic signature
|
||||
* when no trusted timestamp server was specified, making osslsigncode
|
||||
* behaviour closer to signtool.exe (which doesn't include any non-trusted
|
||||
* time in this case.)
|
||||
* [in, out] si: PKCS7_SIGNER_INFO structure
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int pkcs7_signer_info_add_signing_time(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
if (ctx->options->time == INVALID_TIME) /* -time option was not specified */
|
||||
return 1; /* SUCCESS */
|
||||
return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, V_ASN1_UTCTIME,
|
||||
ASN1_TIME_adj(NULL, ctx->options->time, 0, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* [in, out] si: PKCS7_SIGNER_INFO structure
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int pkcs7_signer_info_add_purpose(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
static const u_char purpose_ind[] = {
|
||||
0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
|
||||
0x01, 0x82, 0x37, 0x02, 0x01, 0x15
|
||||
};
|
||||
static const u_char purpose_comm[] = {
|
||||
0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
|
||||
0x01, 0x82, 0x37, 0x02, 0x01, 0x16
|
||||
};
|
||||
ASN1_STRING *purpose = ASN1_STRING_new();
|
||||
|
||||
if (ctx->options->comm) {
|
||||
ASN1_STRING_set(purpose, purpose_comm, sizeof purpose_comm);
|
||||
} else {
|
||||
ASN1_STRING_set(purpose, purpose_ind, sizeof purpose_ind);
|
||||
}
|
||||
return PKCS7_add_signed_attribute(si, OBJ_txt2nid(SPC_STATEMENT_TYPE_OBJID),
|
||||
V_ASN1_SEQUENCE, purpose);
|
||||
}
|
||||
|
||||
/*
|
||||
* [in, out] si: PKCS7_SIGNER_INFO structure
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int pkcs7_signer_info_add_sequence_number(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
ASN1_INTEGER *number = ASN1_INTEGER_new();
|
||||
|
||||
if (!number)
|
||||
return 0; /* FAILED */
|
||||
if (!ASN1_INTEGER_set(number, ctx->options->nested_number + 1)) {
|
||||
ASN1_INTEGER_free(number);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
return PKCS7_add_signed_attribute(si, OBJ_txt2nid(PKCS9_SEQUENCE_NUMBER),
|
||||
V_ASN1_INTEGER, number);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create certificate chain sorted in ascending order by their DER encoding.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] signer: signer's certificate number in the certificate chain
|
||||
* [returns] sorted certificate chain
|
||||
*/
|
||||
static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer)
|
||||
{
|
||||
int i;
|
||||
STACK_OF(X509) *chain = sk_X509_new(X509_compare);
|
||||
|
||||
if (signer != -1 && !sk_X509_push(chain, sk_X509_value(ctx->options->certs, signer))) {
|
||||
sk_X509_free(chain);
|
||||
return NULL;
|
||||
}
|
||||
/* add the certificate chain */
|
||||
for (i=0; i<sk_X509_num(ctx->options->certs); i++) {
|
||||
if (i == signer)
|
||||
continue;
|
||||
if (!sk_X509_push(chain, sk_X509_value(ctx->options->certs, i))) {
|
||||
sk_X509_free(chain);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* add all cross certificates */
|
||||
if (ctx->options->xcerts) {
|
||||
for (i=0; i<sk_X509_num(ctx->options->xcerts); i++) {
|
||||
if (!sk_X509_push(chain, sk_X509_value(ctx->options->xcerts, i))) {
|
||||
sk_X509_free(chain);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* sort certificate chain using the supplied comparison function */
|
||||
sk_X509_sort(chain);
|
||||
return chain;
|
||||
}
|
||||
|
||||
/*
|
||||
* X.690-compliant certificate comparison function
|
||||
* Windows requires catalog files to use PKCS#7
|
||||
* content ordering specified in X.690 section 11.6
|
||||
* https://support.microsoft.com/en-us/topic/october-13-2020-kb4580358-security-only-update-d3f6eb3c-d7c4-a9cb-0de6-759386bf7113
|
||||
* This algorithm is different from X509_cmp()
|
||||
* [in] a_ptr, b_ptr: pointers to X509 certificates
|
||||
* [returns] certificates order
|
||||
*/
|
||||
static int X509_compare(const X509 *const *a, const X509 *const *b)
|
||||
{
|
||||
u_char *a_data, *b_data, *a_tmp, *b_tmp;
|
||||
size_t a_len, b_len;
|
||||
int ret;
|
||||
|
||||
a_len = (size_t)i2d_X509(*a, NULL);
|
||||
a_tmp = a_data = OPENSSL_malloc(a_len);
|
||||
i2d_X509(*a, &a_tmp);
|
||||
|
||||
b_len = (size_t)i2d_X509(*b, NULL);
|
||||
b_tmp = b_data = OPENSSL_malloc(b_len);
|
||||
i2d_X509(*b, &b_tmp);
|
||||
|
||||
ret = memcmp(a_data, b_data, MIN(a_len, b_len));
|
||||
OPENSSL_free(a_data);
|
||||
OPENSSL_free(b_data);
|
||||
|
||||
if (ret == 0 && a_len != b_len) /* identical up to the length of the shorter DER */
|
||||
ret = a_len < b_len ? -1 : 1; /* shorter is smaller */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
vim: set ts=4 expandtab:
|
||||
*/
|
37
helpers.h
Normal file
37
helpers.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* osslsigncode support library
|
||||
*
|
||||
* Copyright (C) 2021-2023 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
* Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
|
||||
*/
|
||||
|
||||
/* Common functions */
|
||||
uint32_t get_file_size(const char *infile);
|
||||
char *map_file(const char *infile, const size_t size);
|
||||
void unmap_file(char *indata, const size_t size);
|
||||
PKCS7 *pkcs7_read_data(char *indata, uint32_t size);
|
||||
int data_write_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7);
|
||||
PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx);
|
||||
int add_indirect_data_object(PKCS7 *p7);
|
||||
int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content);
|
||||
PKCS7 *pkcs7_set_content(ASN1_OCTET_STRING *content);
|
||||
ASN1_OCTET_STRING *spc_indirect_data_content_get(BIO *hash, FILE_FORMAT_CTX *ctx);
|
||||
int pkcs7_sign_content(PKCS7 *p7, const u_char *data, int len);
|
||||
int asn1_simple_hdr_len(const u_char *p, int len);
|
||||
int bio_hash_data(BIO *hash, char *indata, size_t idx, size_t fileend);
|
||||
void print_hash(const char *descript1, const char *descript2, const u_char *hashbuf, int length);
|
||||
int is_content_type(PKCS7 *p7, const char *objid);
|
||||
MsCtlContent *ms_ctl_content_get(PKCS7 *p7);
|
||||
ASN1_TYPE *catalog_content_get(CatalogAuthAttr *attribute);
|
||||
SpcLink *spc_link_obsolete_get(void);
|
||||
int compare_digests(u_char *mdbuf, u_char *cmdbuf, int mdtype);
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
vim: set ts=4 expandtab:
|
||||
*/
|
76
osslsigncode.bash
Normal file
76
osslsigncode.bash
Normal file
@ -0,0 +1,76 @@
|
||||
# bash completion for osslsigncode -*- shell-script -*-
|
||||
# Copyright (C) 2021-2022 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
# Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
|
||||
|
||||
bind 'set show-all-if-ambiguous on'
|
||||
bind 'set completion-ignore-case on'
|
||||
COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
|
||||
|
||||
_comp_cmd_osslsigncode()
|
||||
{
|
||||
local cur prev words cword
|
||||
_init_completion || return
|
||||
|
||||
local commands command options timestamps rfc3161
|
||||
|
||||
commands="--help --version -v
|
||||
sign add attach-signature extract-signature remove-signature verify"
|
||||
|
||||
timestamps="http://timestamp.digicert.com
|
||||
http://time.certum.pl
|
||||
http://timestamp.sectigo.com
|
||||
http://timestamp.globalsign.com/?signature=sha2"
|
||||
|
||||
rfc3161="http://timestamp.digicert.com
|
||||
http://time.certum.pl
|
||||
http://timestamp.entrust.net/TSS/RFC3161sha2TS
|
||||
http://tss.accv.es:8318/tsa
|
||||
http://kstamp.keynectis.com/KSign/
|
||||
http://sha256timestamp.ws.symantec.com/sha256/timestamp"
|
||||
|
||||
|
||||
if ((cword == 1)); then
|
||||
COMPREPLY=($(compgen -W "${commands}" -- ${cur}))
|
||||
else
|
||||
command=${words[1]}
|
||||
case $prev in
|
||||
-ac | -c | -catalog | -certs | -spc | -key | -pkcs12 | -pass | \
|
||||
-readpass | -pkcs11engine | -pkcs11module | -in | -out | -sigin | \
|
||||
-n | -CAfile | -CRLfile | -TSA-CAfile | -TSA-CRLfile)
|
||||
_filedir
|
||||
return
|
||||
;;
|
||||
-h | -require-leaf-hash)
|
||||
COMPREPLY=($(compgen -W 'md5 sha1 sha2 sha256 sha384 sha512' \
|
||||
-- "$cur"))
|
||||
return
|
||||
;;
|
||||
-jp)
|
||||
COMPREPLY=($(compgen -W 'low medium high' -- "$cur"))
|
||||
return
|
||||
;;
|
||||
-t)
|
||||
COMPREPLY=($(compgen -W "${timestamps}" -- "$cur"))
|
||||
return
|
||||
;;
|
||||
-ts)
|
||||
COMPREPLY=($(compgen -W "${rfc3161}" -- "$cur"))
|
||||
return
|
||||
;;
|
||||
-i | -p)
|
||||
_known_hosts_real -- "$cur"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ $cur == -* ]]; then
|
||||
# possible options for the command
|
||||
options=$(_parse_help "$1" "$command --help" 2>/dev/null)
|
||||
COMPREPLY=($(compgen -W "${options}" -- ${cur}))
|
||||
fi
|
||||
fi
|
||||
|
||||
} &&
|
||||
complete -F _comp_cmd_osslsigncode osslsigncode
|
||||
|
||||
# ex: filetype=sh
|
10310
osslsigncode.c
10310
osslsigncode.c
File diff suppressed because it is too large
Load Diff
572
osslsigncode.h
Normal file
572
osslsigncode.h
Normal file
@ -0,0 +1,572 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2023 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
* Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
|
||||
*/
|
||||
|
||||
#define OPENSSL_API_COMPAT 0x10100000L
|
||||
#define OPENSSL_NO_DEPRECATED
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#define HAVE_WINDOWS_H
|
||||
#endif /* _MSC_VER || __MINGW32__ */
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#define NOCRYPT
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#endif /* HAVE_WINDOWS_H */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif /* HAVE_SYS_MMAN_H */
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
#include <termios.h>
|
||||
#endif /* HAVE_TERMIOS_H */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/crypto.h>
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
#endif /* OPENSSL_NO_ENGINE */
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#if OPENSSL_VERSION_NUMBER>=0x30000000L
|
||||
#include <openssl/provider.h>
|
||||
#endif /* OPENSSL_VERSION_NUMBER>=0x30000000L */
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/safestack.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/store.h>
|
||||
#include <openssl/ts.h>
|
||||
#include <openssl/ui.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h> /* X509_PURPOSE */
|
||||
|
||||
#ifdef ENABLE_CURL
|
||||
#ifdef __CYGWIN__
|
||||
#ifndef SOCKET
|
||||
#define SOCKET UINT_PTR
|
||||
#endif /* SOCKET */
|
||||
#endif /* __CYGWIN__ */
|
||||
#include <curl/curl.h>
|
||||
#endif /* ENABLE_CURL */
|
||||
|
||||
/* Request nonce length, in bits (must be a multiple of 8). */
|
||||
#define NONCE_LENGTH 64
|
||||
#define MAX_TS_SERVERS 256
|
||||
|
||||
#if defined (HAVE_TERMIOS_H) || defined (HAVE_GETPASS)
|
||||
#define PROVIDE_ASKPASS 1
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* not WIN32, because strcasecmp exists in MinGW */
|
||||
#define strcasecmp _stricmp
|
||||
#define fseeko _fseeki64
|
||||
#define ftello _ftelli64
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#ifdef WIN32
|
||||
#define remove_file(filename) _unlink(filename)
|
||||
#else
|
||||
#define remove_file(filename) unlink(filename)
|
||||
#endif /* WIN32 */
|
||||
|
||||
#define GET_UINT8_LE(p) ((const u_char *)(p))[0]
|
||||
|
||||
#define GET_UINT16_LE(p) (uint16_t)(((const u_char *)(p))[0] | \
|
||||
(((const u_char *)(p))[1] << 8))
|
||||
|
||||
#define GET_UINT32_LE(p) (uint32_t)(((const u_char *)(p))[0] | \
|
||||
(((const u_char *)(p))[1] << 8) | \
|
||||
(((const u_char *)(p))[2] << 16) | \
|
||||
(((const u_char *)(p))[3] << 24))
|
||||
|
||||
#define PUT_UINT8_LE(i, p) ((u_char *)(p))[0] = (u_char)((i) & 0xff);
|
||||
|
||||
#define PUT_UINT16_LE(i,p) ((u_char *)(p))[0] = (u_char)((i) & 0xff); \
|
||||
((u_char *)(p))[1] = (u_char)(((i) >> 8) & 0xff)
|
||||
|
||||
#define PUT_UINT32_LE(i,p) ((u_char *)(p))[0] = (u_char)((i) & 0xff); \
|
||||
((u_char *)(p))[1] = (u_char)(((i) >> 8) & 0xff); \
|
||||
((u_char *)(p))[2] = (u_char)(((i) >> 16) & 0xff); \
|
||||
((u_char *)(p))[3] = (u_char)(((i) >> 24) & 0xff)
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#define SIZE_64K 65536 /* 2^16 */
|
||||
#define SIZE_16M 16777216 /* 2^24 */
|
||||
|
||||
/*
|
||||
* Macro names:
|
||||
* linux: __BYTE_ORDER == __LITTLE_ENDIAN | __BIG_ENDIAN
|
||||
* BYTE_ORDER == LITTLE_ENDIAN | BIG_ENDIAN
|
||||
* bsd: _BYTE_ORDER == _LITTLE_ENDIAN | _BIG_ENDIAN
|
||||
* BYTE_ORDER == LITTLE_ENDIAN | BIG_ENDIAN
|
||||
* solaris: _LITTLE_ENDIAN | _BIG_ENDIAN
|
||||
*/
|
||||
|
||||
#ifndef BYTE_ORDER
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#define BIG_ENDIAN 4321
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif /* BYTE_ORDER */
|
||||
|
||||
#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN)
|
||||
#error "Cannot determine the endian-ness of this platform"
|
||||
#endif
|
||||
|
||||
#ifndef LOWORD
|
||||
#define LOWORD(x) ((x) & 0xFFFF)
|
||||
#endif /* LOWORD */
|
||||
#ifndef HIWORD
|
||||
#define HIWORD(x) (((x) >> 16) & 0xFFFF)
|
||||
#endif /* HIWORD */
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define LE_UINT16(x) ((((x) >> 8) & 0x00FF) | \
|
||||
(((x) << 8) & 0xFF00))
|
||||
#define LE_UINT32(x) (((x) >> 24) | \
|
||||
(((x) & 0x00FF0000) >> 8) | \
|
||||
(((x) & 0x0000FF00) << 8) | \
|
||||
((x) << 24))
|
||||
#else
|
||||
#define LE_UINT16(x) (x)
|
||||
#define LE_UINT32(x) (x)
|
||||
#endif /* BYTE_ORDER == BIG_ENDIAN */
|
||||
|
||||
#define MIN(a,b) ((a) < (b) ? a : b)
|
||||
#define INVALID_TIME ((time_t)-1)
|
||||
|
||||
/* Microsoft OID Authenticode */
|
||||
#define SPC_INDIRECT_DATA_OBJID "1.3.6.1.4.1.311.2.1.4"
|
||||
#define SPC_STATEMENT_TYPE_OBJID "1.3.6.1.4.1.311.2.1.11"
|
||||
#define SPC_SP_OPUS_INFO_OBJID "1.3.6.1.4.1.311.2.1.12"
|
||||
#define SPC_PE_IMAGE_DATA_OBJID "1.3.6.1.4.1.311.2.1.15"
|
||||
#define SPC_CAB_DATA_OBJID "1.3.6.1.4.1.311.2.1.25"
|
||||
#define SPC_SIPINFO_OBJID "1.3.6.1.4.1.311.2.1.30"
|
||||
#define SPC_PE_IMAGE_PAGE_HASHES_V1 "1.3.6.1.4.1.311.2.3.1" /* SHA1 */
|
||||
#define SPC_PE_IMAGE_PAGE_HASHES_V2 "1.3.6.1.4.1.311.2.3.2" /* SHA256 */
|
||||
#define SPC_NESTED_SIGNATURE_OBJID "1.3.6.1.4.1.311.2.4.1"
|
||||
/* Microsoft OID Time Stamping */
|
||||
#define SPC_TIME_STAMP_REQUEST_OBJID "1.3.6.1.4.1.311.3.2.1"
|
||||
#define SPC_RFC3161_OBJID "1.3.6.1.4.1.311.3.3.1"
|
||||
/* Microsoft OID Crypto 2.0 */
|
||||
#define MS_CTL_OBJID "1.3.6.1.4.1.311.10.1"
|
||||
/* Microsoft OID Catalog */
|
||||
#define CAT_NAMEVALUE_OBJID "1.3.6.1.4.1.311.12.2.1"
|
||||
/* Microsoft OID Microsoft_Java */
|
||||
#define MS_JAVA_SOMETHING "1.3.6.1.4.1.311.15.1"
|
||||
|
||||
#define SPC_UNAUTHENTICATED_DATA_BLOB_OBJID "1.3.6.1.4.1.42921.1.2.1"
|
||||
|
||||
/* Public Key Cryptography Standards PKCS#9 */
|
||||
#define PKCS9_MESSAGE_DIGEST "1.2.840.113549.1.9.4"
|
||||
#define PKCS9_SIGNING_TIME "1.2.840.113549.1.9.5"
|
||||
#define PKCS9_COUNTER_SIGNATURE "1.2.840.113549.1.9.6"
|
||||
#define PKCS9_SEQUENCE_NUMBER "1.2.840.113549.1.9.25.4"
|
||||
|
||||
/* WIN_CERTIFICATE structure declared in Wintrust.h */
|
||||
#define WIN_CERT_REVISION_2_0 0x0200
|
||||
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
|
||||
|
||||
/*
|
||||
* FLAG_PREV_CABINET is set if the cabinet file is not the first in a set
|
||||
* of cabinet files. When this bit is set, the szCabinetPrev and szDiskPrev
|
||||
* fields are present in this CFHEADER.
|
||||
*/
|
||||
#define FLAG_PREV_CABINET 0x0001
|
||||
/*
|
||||
* FLAG_NEXT_CABINET is set if the cabinet file is not the last in a set of
|
||||
* cabinet files. When this bit is set, the szCabinetNext and szDiskNext
|
||||
* fields are present in this CFHEADER.
|
||||
*/
|
||||
#define FLAG_NEXT_CABINET 0x0002
|
||||
/*
|
||||
* FLAG_RESERVE_PRESENT is set if the cabinet file contains any reserved
|
||||
* fields. When this bit is set, the cbCFHeader, cbCFFolder, and cbCFData
|
||||
* fields are present in this CFHEADER.
|
||||
*/
|
||||
#define FLAG_RESERVE_PRESENT 0x0004
|
||||
|
||||
#define DO_EXIT_0(x) { fprintf(stderr, x); goto err_cleanup; }
|
||||
#define DO_EXIT_1(x, y) { fprintf(stderr, x, y); goto err_cleanup; }
|
||||
#define DO_EXIT_2(x, y, z) { fprintf(stderr, x, y, z); goto err_cleanup; }
|
||||
|
||||
/* Default policy if request did not specify it. */
|
||||
#define TSA_POLICY1 "1.2.3.4.1"
|
||||
|
||||
typedef enum {
|
||||
CMD_SIGN,
|
||||
CMD_EXTRACT,
|
||||
CMD_EXTRACT_DATA,
|
||||
CMD_REMOVE,
|
||||
CMD_VERIFY,
|
||||
CMD_ADD,
|
||||
CMD_ATTACH,
|
||||
CMD_HELP,
|
||||
CMD_DEFAULT
|
||||
} cmd_type_t;
|
||||
|
||||
typedef unsigned char u_char;
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
typedef struct {
|
||||
ASN1_OCTET_STRING *cmd;
|
||||
ASN1_OCTET_STRING *param;
|
||||
} EngineControl;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(EngineControl)
|
||||
DEFINE_STACK_OF(EngineControl)
|
||||
#endif /* OPENSSL_NO_ENGINE */
|
||||
|
||||
typedef struct {
|
||||
char *infile;
|
||||
char *outfile;
|
||||
char *sigfile;
|
||||
char *certfile;
|
||||
char *xcertfile;
|
||||
char *keyfile;
|
||||
char *pvkfile;
|
||||
char *pkcs12file;
|
||||
int output_pkcs7;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
char *p11engine;
|
||||
char *p11module;
|
||||
char *p11cert;
|
||||
int login;
|
||||
STACK_OF(EngineControl) *engine_ctrls;
|
||||
#endif /* OPENSSL_NO_ENGINE */
|
||||
int askpass;
|
||||
char *readpass;
|
||||
char *pass;
|
||||
int comm;
|
||||
int pagehash;
|
||||
char *desc;
|
||||
const EVP_MD *md;
|
||||
char *url;
|
||||
time_t time;
|
||||
char *turl[MAX_TS_SERVERS];
|
||||
int nturl;
|
||||
char *tsurl[MAX_TS_SERVERS];
|
||||
int ntsurl;
|
||||
char *proxy;
|
||||
int noverifypeer;
|
||||
int addBlob;
|
||||
const char *blob_file;
|
||||
int nest;
|
||||
int index;
|
||||
int ignore_timestamp;
|
||||
int ignore_cdp;
|
||||
int ignore_crl;
|
||||
int verbose;
|
||||
int add_msi_dse;
|
||||
char *catalog;
|
||||
char *cafile;
|
||||
char *crlfile;
|
||||
char *https_cafile;
|
||||
char *https_crlfile;
|
||||
char *tsa_cafile;
|
||||
char *tsa_crlfile;
|
||||
char *leafhash;
|
||||
int jp;
|
||||
#if OPENSSL_VERSION_NUMBER>=0x30000000L
|
||||
int legacy;
|
||||
char *provider;
|
||||
#endif /* OPENSSL_VERSION_NUMBER>=0x30000000L */
|
||||
EVP_PKEY *pkey;
|
||||
STACK_OF(X509) *certs;
|
||||
STACK_OF(X509) *xcerts;
|
||||
STACK_OF(X509_CRL) *crls;
|
||||
cmd_type_t cmd;
|
||||
char *indata;
|
||||
char *tsa_certfile;
|
||||
char *tsa_keyfile;
|
||||
time_t tsa_time;
|
||||
int nested_number;
|
||||
} GLOBAL_OPTIONS;
|
||||
|
||||
/*
|
||||
* ASN.1 definitions (more or less from official MS Authenticode docs)
|
||||
*/
|
||||
typedef struct {
|
||||
int type;
|
||||
union {
|
||||
ASN1_BMPSTRING *unicode;
|
||||
ASN1_IA5STRING *ascii;
|
||||
} value;
|
||||
} SpcString;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcString)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OCTET_STRING *classId;
|
||||
ASN1_OCTET_STRING *serializedData;
|
||||
} SpcSerializedObject;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcSerializedObject)
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
union {
|
||||
ASN1_IA5STRING *url;
|
||||
SpcSerializedObject *moniker;
|
||||
SpcString *file;
|
||||
} value;
|
||||
} SpcLink;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcLink)
|
||||
|
||||
typedef struct {
|
||||
SpcString *programName;
|
||||
SpcLink *moreInfo;
|
||||
} SpcSpOpusInfo;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcSpOpusInfo)
|
||||
|
||||
typedef struct {
|
||||
ASN1_INTEGER *a;
|
||||
ASN1_OCTET_STRING *string;
|
||||
ASN1_INTEGER *b;
|
||||
ASN1_INTEGER *c;
|
||||
ASN1_INTEGER *d;
|
||||
ASN1_INTEGER *e;
|
||||
ASN1_INTEGER *f;
|
||||
} SpcSipInfo;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcSipInfo)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OBJECT *type;
|
||||
ASN1_TYPE *value;
|
||||
} SpcAttributeTypeAndOptionalValue;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcAttributeTypeAndOptionalValue)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OBJECT *algorithm;
|
||||
ASN1_TYPE *parameters;
|
||||
} AlgorithmIdentifier;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(AlgorithmIdentifier)
|
||||
|
||||
typedef struct {
|
||||
AlgorithmIdentifier *digestAlgorithm;
|
||||
ASN1_OCTET_STRING *digest;
|
||||
} DigestInfo;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(DigestInfo)
|
||||
|
||||
typedef struct {
|
||||
SpcAttributeTypeAndOptionalValue *data;
|
||||
DigestInfo *messageDigest;
|
||||
} SpcIndirectDataContent;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcIndirectDataContent)
|
||||
|
||||
typedef struct CatalogAuthAttr_st {
|
||||
ASN1_OBJECT *type;
|
||||
ASN1_TYPE *contents;
|
||||
} CatalogAuthAttr;
|
||||
|
||||
DEFINE_STACK_OF(CatalogAuthAttr)
|
||||
DECLARE_ASN1_FUNCTIONS(CatalogAuthAttr)
|
||||
|
||||
typedef struct {
|
||||
AlgorithmIdentifier *digestAlgorithm;
|
||||
ASN1_OCTET_STRING *digest;
|
||||
} MessageImprint;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(MessageImprint)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OBJECT *type;
|
||||
ASN1_OCTET_STRING *signature;
|
||||
} TimeStampRequestBlob;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampRequestBlob)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OBJECT *type;
|
||||
TimeStampRequestBlob *blob;
|
||||
} TimeStampRequest;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampRequest)
|
||||
|
||||
/* RFC3161 Time stamping */
|
||||
|
||||
typedef struct {
|
||||
ASN1_INTEGER *status;
|
||||
STACK_OF(ASN1_UTF8STRING) *statusString;
|
||||
ASN1_BIT_STRING *failInfo;
|
||||
} PKIStatusInfo;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(PKIStatusInfo)
|
||||
|
||||
typedef struct {
|
||||
PKIStatusInfo *status;
|
||||
PKCS7 *token;
|
||||
} TimeStampResp;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampResp)
|
||||
|
||||
typedef struct {
|
||||
ASN1_INTEGER *version;
|
||||
MessageImprint *messageImprint;
|
||||
ASN1_OBJECT *reqPolicy;
|
||||
ASN1_INTEGER *nonce;
|
||||
ASN1_BOOLEAN certReq;
|
||||
STACK_OF(X509_EXTENSION) *extensions;
|
||||
} TimeStampReq;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampReq)
|
||||
|
||||
typedef struct {
|
||||
ASN1_INTEGER *seconds;
|
||||
ASN1_INTEGER *millis;
|
||||
ASN1_INTEGER *micros;
|
||||
} TimeStampAccuracy;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampAccuracy)
|
||||
|
||||
typedef struct {
|
||||
ASN1_INTEGER *version;
|
||||
ASN1_OBJECT *policy_id;
|
||||
MessageImprint *messageImprint;
|
||||
ASN1_INTEGER *serial;
|
||||
ASN1_GENERALIZEDTIME *time;
|
||||
TimeStampAccuracy *accuracy;
|
||||
ASN1_BOOLEAN ordering;
|
||||
ASN1_INTEGER *nonce;
|
||||
GENERAL_NAME *tsa;
|
||||
STACK_OF(X509_EXTENSION) *extensions;
|
||||
} TimeStampToken;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampToken)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OCTET_STRING *digest;
|
||||
STACK_OF(CatalogAuthAttr) *attributes;
|
||||
} CatalogInfo;
|
||||
|
||||
DEFINE_STACK_OF(CatalogInfo)
|
||||
DECLARE_ASN1_FUNCTIONS(CatalogInfo)
|
||||
|
||||
typedef struct {
|
||||
/* 1.3.6.1.4.1.311.12.1.1 MS_CATALOG_LIST */
|
||||
SpcAttributeTypeAndOptionalValue *type;
|
||||
ASN1_OCTET_STRING *identifier;
|
||||
ASN1_UTCTIME *time;
|
||||
/* 1.3.6.1.4.1.311.12.1.2 CatalogVersion = 1
|
||||
* 1.3.6.1.4.1.311.12.1.3 CatalogVersion = 2 */
|
||||
SpcAttributeTypeAndOptionalValue *version;
|
||||
STACK_OF(CatalogInfo) *header_attributes;
|
||||
/* 1.3.6.1.4.1.311.12.2.1 CAT_NAMEVALUE_OBJID */
|
||||
ASN1_TYPE *filename;
|
||||
} MsCtlContent;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(MsCtlContent)
|
||||
|
||||
typedef struct {
|
||||
char *server;
|
||||
const char *port;
|
||||
int use_proxy;
|
||||
int timeout;
|
||||
SSL_CTX *ssl_ctx;
|
||||
} HTTP_TLS_Info;
|
||||
|
||||
typedef struct file_format_st FILE_FORMAT;
|
||||
|
||||
typedef struct script_ctx_st SCRIPT_CTX;
|
||||
typedef struct msi_ctx_st MSI_CTX;
|
||||
typedef struct pe_ctx_st PE_CTX;
|
||||
typedef struct cab_ctx_st CAB_CTX;
|
||||
typedef struct cat_ctx_st CAT_CTX;
|
||||
typedef struct appx_ctx_st APPX_CTX;
|
||||
|
||||
typedef struct {
|
||||
FILE_FORMAT *format;
|
||||
GLOBAL_OPTIONS *options;
|
||||
union {
|
||||
SCRIPT_CTX *script_ctx;
|
||||
MSI_CTX *msi_ctx;
|
||||
PE_CTX *pe_ctx;
|
||||
CAB_CTX *cab_ctx;
|
||||
CAT_CTX *cat_ctx;
|
||||
APPX_CTX *appx_ctx;
|
||||
};
|
||||
} FILE_FORMAT_CTX;
|
||||
|
||||
extern FILE_FORMAT file_format_script;
|
||||
extern FILE_FORMAT file_format_msi;
|
||||
extern FILE_FORMAT file_format_pe;
|
||||
extern FILE_FORMAT file_format_cab;
|
||||
extern FILE_FORMAT file_format_cat;
|
||||
extern FILE_FORMAT file_format_appx;
|
||||
|
||||
struct file_format_st {
|
||||
FILE_FORMAT_CTX *(*ctx_new) (GLOBAL_OPTIONS *option, BIO *hash, BIO *outdata);
|
||||
const EVP_MD *(*md_get) (FILE_FORMAT_CTX *ctx);
|
||||
ASN1_OBJECT *(*data_blob_get) (u_char **p, int *plen, FILE_FORMAT_CTX *ctx);
|
||||
PKCS7 *(*pkcs7_contents_get) (FILE_FORMAT_CTX *ctx, BIO *hash, const EVP_MD *md);
|
||||
int (*hash_length_get) (FILE_FORMAT_CTX *ctx);
|
||||
u_char *(*digest_calc) (FILE_FORMAT_CTX *ctx, const EVP_MD *md);
|
||||
int (*verify_digests) (FILE_FORMAT_CTX *ctx, PKCS7 *p7);
|
||||
int (*verify_indirect_data) (FILE_FORMAT_CTX *ctx, SpcAttributeTypeAndOptionalValue *obj);
|
||||
PKCS7 *(*pkcs7_extract) (FILE_FORMAT_CTX *ctx);
|
||||
PKCS7 *(*pkcs7_extract_to_nest) (FILE_FORMAT_CTX *ctx);
|
||||
int (*remove_pkcs7) (FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
|
||||
int (*process_data) (FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
|
||||
PKCS7 *(*pkcs7_signature_new) (FILE_FORMAT_CTX *ctx, BIO *hash);
|
||||
int (*append_pkcs7) (FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7);
|
||||
void (*update_data_size) (FILE_FORMAT_CTX *data, BIO *outdata, PKCS7 *p7);
|
||||
void (*bio_free) (BIO *hash, BIO *outdata);
|
||||
void (*ctx_cleanup) (FILE_FORMAT_CTX *ctx);
|
||||
int (*is_detaching_supported) (void);
|
||||
};
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
vim: set ts=4 expandtab:
|
||||
*/
|
875
script.c
Normal file
875
script.c
Normal file
@ -0,0 +1,875 @@
|
||||
/*
|
||||
* Script file support library
|
||||
*
|
||||
* Copyright (C) 2021-2024 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
*/
|
||||
|
||||
#include "osslsigncode.h"
|
||||
#include "helpers.h"
|
||||
#include "utf.h"
|
||||
|
||||
typedef enum {comment_hash, comment_xml, comment_c, comment_not_found} comment_style;
|
||||
|
||||
typedef struct {
|
||||
const char *extension;
|
||||
comment_style comment;
|
||||
} SCRIPT_FORMAT;
|
||||
|
||||
const SCRIPT_FORMAT supported_formats[] = {
|
||||
{".ps1", comment_hash},
|
||||
{".ps1xml", comment_xml},
|
||||
{".psc1", comment_xml},
|
||||
{".psd1", comment_hash},
|
||||
{".psm1", comment_hash},
|
||||
{".cdxml", comment_xml},
|
||||
{".mof", comment_c},
|
||||
{NULL, comment_not_found},
|
||||
};
|
||||
|
||||
const char *signature_header = "SIG # Begin signature block";
|
||||
const char *signature_footer = "SIG # End signature block";
|
||||
|
||||
typedef struct {
|
||||
const char *open;
|
||||
const char *close;
|
||||
} SCRIPT_COMMENT;
|
||||
|
||||
const SCRIPT_COMMENT comment_text[] = {
|
||||
[comment_hash] = {"# ", ""},
|
||||
[comment_xml] = {"<!-- ", " -->"},
|
||||
[comment_c] = {"/* ", " */"}
|
||||
};
|
||||
|
||||
struct script_ctx_st {
|
||||
const SCRIPT_COMMENT *comment_text;
|
||||
int utf;
|
||||
uint32_t sigpos;
|
||||
uint32_t fileend;
|
||||
};
|
||||
|
||||
#define LINE_MAX_LEN 100
|
||||
|
||||
/* FILE_FORMAT method prototypes */
|
||||
static FILE_FORMAT_CTX *script_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *outdata);
|
||||
static ASN1_OBJECT *script_spc_sip_info_get(u_char **p, int *plen, FILE_FORMAT_CTX *ctx);
|
||||
static PKCS7 *script_pkcs7_contents_get(FILE_FORMAT_CTX *ctx, BIO *hash, const EVP_MD *md);
|
||||
static int script_hash_length_get(FILE_FORMAT_CTX *ctx);
|
||||
static u_char *script_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md);
|
||||
static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7);
|
||||
static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx);
|
||||
static PKCS7 *script_pkcs7_extract_to_nest(FILE_FORMAT_CTX *ctx);
|
||||
static int script_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
|
||||
static int script_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
|
||||
static PKCS7 *script_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash);
|
||||
static int script_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7);
|
||||
static void script_bio_free(BIO *hash, BIO *outdata);
|
||||
static void script_ctx_cleanup(FILE_FORMAT_CTX *ctx);
|
||||
static int script_is_detaching_supported(void);
|
||||
|
||||
FILE_FORMAT file_format_script = {
|
||||
.ctx_new = script_ctx_new,
|
||||
.data_blob_get = script_spc_sip_info_get,
|
||||
.pkcs7_contents_get = script_pkcs7_contents_get,
|
||||
.hash_length_get = script_hash_length_get,
|
||||
.digest_calc = script_digest_calc,
|
||||
.verify_digests = script_verify_digests,
|
||||
.pkcs7_extract = script_pkcs7_extract,
|
||||
.pkcs7_extract_to_nest = script_pkcs7_extract_to_nest,
|
||||
.remove_pkcs7 = script_remove_pkcs7,
|
||||
.process_data = script_process_data,
|
||||
.pkcs7_signature_new = script_pkcs7_signature_new,
|
||||
.append_pkcs7 = script_append_pkcs7,
|
||||
.bio_free = script_bio_free,
|
||||
.ctx_cleanup = script_ctx_cleanup,
|
||||
.is_detaching_supported = script_is_detaching_supported
|
||||
};
|
||||
|
||||
/* helper functions */
|
||||
static SCRIPT_CTX *script_ctx_get(char *indata, uint32_t filesize, const SCRIPT_COMMENT *comment, int utf);
|
||||
static int write_commented(FILE_FORMAT_CTX *ctx, BIO *outdata, const char *data, size_t length);
|
||||
static int write_in_encoding(FILE_FORMAT_CTX *ctx, BIO *outdata, const char *line, size_t length);
|
||||
static size_t utf8_to_utf16(const char *data, size_t len, uint16_t **out_utf16);
|
||||
static size_t utf16_to_utf8(const uint16_t *data, size_t len, char **out_utf8);
|
||||
static BIO *script_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md);
|
||||
static int script_digest_convert(BIO *hash, FILE_FORMAT_CTX *ctx, size_t len);
|
||||
static int script_write_bio(BIO *data, char *indata, size_t len);
|
||||
static int script_check_file(FILE_FORMAT_CTX *ctx);
|
||||
|
||||
/*
|
||||
* Allocate and return a script file format context.
|
||||
* [in, out] options: structure holds the input data
|
||||
* [out] hash: message digest BIO
|
||||
* [in] outdata: outdata file BIO (unused)
|
||||
* [returns] pointer to script file format context
|
||||
*/
|
||||
static FILE_FORMAT_CTX *script_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *outdata)
|
||||
{
|
||||
FILE_FORMAT_CTX *ctx;
|
||||
SCRIPT_CTX *script_ctx;
|
||||
const SCRIPT_FORMAT *fmt;
|
||||
uint32_t filesize;
|
||||
const uint8_t utf16_bom[] = {0xff, 0xfe};
|
||||
size_t name_len;
|
||||
int utf;
|
||||
|
||||
/* squash the unused parameter warning */
|
||||
(void)outdata;
|
||||
|
||||
/* find out whether our format is supported */
|
||||
name_len = strlen(options->infile);
|
||||
for (fmt = supported_formats; fmt->comment != comment_not_found; fmt++) {
|
||||
size_t ext_len = strlen(fmt->extension);
|
||||
if(name_len > ext_len && !strcasecmp(options->infile + name_len - ext_len, fmt->extension))
|
||||
break;
|
||||
}
|
||||
if (fmt->comment == comment_not_found)
|
||||
return NULL;
|
||||
printf("Script file format: %s\n", fmt->extension);
|
||||
|
||||
filesize = get_file_size(options->infile);
|
||||
if (filesize == 0)
|
||||
return NULL; /* FAILED */
|
||||
|
||||
options->indata = map_file(options->infile, filesize);
|
||||
if (!options->indata) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
utf = memcmp(options->indata, utf16_bom, sizeof utf16_bom) ? 8 : 16;
|
||||
|
||||
/* initialize script context */
|
||||
script_ctx = script_ctx_get(options->indata, filesize, comment_text + fmt->comment, utf);
|
||||
if (!script_ctx) {
|
||||
unmap_file(options->indata, filesize);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
|
||||
/* initialize file format context */
|
||||
ctx = OPENSSL_malloc(sizeof(FILE_FORMAT_CTX));
|
||||
memset(ctx, 0, sizeof(FILE_FORMAT_CTX));
|
||||
ctx->format = &file_format_script;
|
||||
ctx->options = options;
|
||||
ctx->script_ctx = script_ctx;
|
||||
|
||||
if (hash)
|
||||
BIO_push(hash, BIO_new(BIO_s_null()));
|
||||
|
||||
/* FIXME: user interface logic belongs to osslsigncode.c */
|
||||
if (options->pagehash == 1)
|
||||
printf("Warning: -ph option is only valid for PE files\n");
|
||||
if (options->jp >= 0)
|
||||
printf("Warning: -jp option is only valid for CAB files\n");
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and return SpcSipInfo object.
|
||||
* Subject Interface Package (SIP) is an internal Microsoft API for
|
||||
* transforming arbitrary files into a digestible stream.
|
||||
* These ClassIDs are found in the indirect data section and identify
|
||||
* the type of processor needed to validate the signature.
|
||||
* https://github.com/sassoftware/relic/blob/620d0b75ec67c0158a8a9120950abe04327d922f/lib/authenticode/structs.go#L154
|
||||
* [out] p: SpcSipInfo data
|
||||
* [out] plen: SpcSipInfo data length
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] pointer to ASN1_OBJECT structure corresponding to SPC_SIPINFO_OBJID
|
||||
*/
|
||||
static ASN1_OBJECT *script_spc_sip_info_get(u_char **p, int *plen, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
const u_char SpcUUIDSipInfoPs[] = {
|
||||
0x1f, 0xcc, 0x3b, 0x60, 0x59, 0x4b, 0x08, 0x4e,
|
||||
0xb7, 0x24, 0xd2, 0xc6, 0x29, 0x7e, 0xf3, 0x51
|
||||
};
|
||||
ASN1_OBJECT *dtype;
|
||||
SpcSipInfo *si = SpcSipInfo_new();
|
||||
|
||||
/* squash the unused parameter warning */
|
||||
(void)ctx;
|
||||
|
||||
ASN1_INTEGER_set(si->a, 65536);
|
||||
ASN1_INTEGER_set(si->b, 0);
|
||||
ASN1_INTEGER_set(si->c, 0);
|
||||
ASN1_INTEGER_set(si->d, 0);
|
||||
ASN1_INTEGER_set(si->e, 0);
|
||||
ASN1_INTEGER_set(si->f, 0);
|
||||
ASN1_OCTET_STRING_set(si->string, SpcUUIDSipInfoPs, sizeof SpcUUIDSipInfoPs);
|
||||
*plen = i2d_SpcSipInfo(si, NULL);
|
||||
*p = OPENSSL_malloc((size_t)*plen);
|
||||
i2d_SpcSipInfo(si, p);
|
||||
*p -= *plen;
|
||||
dtype = OBJ_txt2obj(SPC_SIPINFO_OBJID, 1);
|
||||
SpcSipInfo_free(si);
|
||||
return dtype; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and return a data content to be signed.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] hash: message digest BIO
|
||||
* [in] md: message digest algorithm
|
||||
* [returns] data content
|
||||
*/
|
||||
static PKCS7 *script_pkcs7_contents_get(FILE_FORMAT_CTX *ctx, BIO *hash, const EVP_MD *md)
|
||||
{
|
||||
ASN1_OCTET_STRING *content;
|
||||
BIO *bhash;
|
||||
|
||||
/* squash the unused parameter warning */
|
||||
(void)hash;
|
||||
|
||||
bhash = script_digest_calc_bio(ctx, md);
|
||||
if (!bhash) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
content = spc_indirect_data_content_get(bhash, ctx);
|
||||
BIO_free_all(bhash);
|
||||
return pkcs7_set_content(content);
|
||||
}
|
||||
|
||||
static int script_hash_length_get(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
return EVP_MD_size(ctx->options->md);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute a simple sha1/sha256 message digest of the MSI file
|
||||
* for use with a catalog file.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] md: message digest algorithm
|
||||
* [returns] pointer to calculated message digest
|
||||
*/
|
||||
static u_char *script_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
|
||||
{
|
||||
u_char *mdbuf;
|
||||
BIO *hash = BIO_new(BIO_f_md());
|
||||
|
||||
if (!BIO_set_md(hash, md)) {
|
||||
fprintf(stderr, "Unable to set the message digest of BIO\n");
|
||||
BIO_free_all(hash);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
BIO_push(hash, BIO_new(BIO_s_null()));
|
||||
if (!script_write_bio(hash, ctx->options->indata, ctx->script_ctx->fileend)) {
|
||||
BIO_free_all(hash);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
mdbuf = OPENSSL_malloc((size_t)EVP_MD_size(md));
|
||||
BIO_gets(hash, (char*)mdbuf, EVP_MD_size(md));
|
||||
BIO_free_all(hash);
|
||||
return mdbuf; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the hash and compare to PKCS#7 signedData.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
||||
{
|
||||
int mdtype = -1;
|
||||
u_char mdbuf[EVP_MAX_MD_SIZE];
|
||||
u_char *cmdbuf = NULL;
|
||||
const EVP_MD *md;
|
||||
BIO *bhash;
|
||||
|
||||
/* FIXME: this shared code most likely belongs in osslsigncode.c */
|
||||
if (is_content_type(p7, SPC_INDIRECT_DATA_OBJID)) {
|
||||
ASN1_STRING *content_val = p7->d.sign->contents->d.other->value.sequence;
|
||||
const u_char *p = content_val->data;
|
||||
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, content_val->length);
|
||||
if (idc) {
|
||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
||||
}
|
||||
SpcIndirectDataContent_free(idc);
|
||||
}
|
||||
}
|
||||
if (mdtype == -1) {
|
||||
fprintf(stderr, "Failed to extract current message digest\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
md = EVP_get_digestbynid(mdtype);
|
||||
bhash = script_digest_calc_bio(ctx, md);
|
||||
if (!bhash)
|
||||
return 0; /* FAILED */
|
||||
|
||||
cmdbuf = OPENSSL_malloc((size_t)EVP_MD_size(md));
|
||||
BIO_gets(bhash, (char*)cmdbuf, EVP_MD_size(md));
|
||||
BIO_free_all(bhash);
|
||||
|
||||
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
|
||||
fprintf(stderr, "Signature verification: failed\n\n");
|
||||
OPENSSL_free(cmdbuf);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
OPENSSL_free(cmdbuf);
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract existing signature in DER format.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
const char *signature_data = ctx->options->indata + ctx->script_ctx->sigpos;
|
||||
size_t signature_len = ctx->script_ctx->fileend - ctx->script_ctx->sigpos;
|
||||
size_t base64_len;
|
||||
char *ptr;
|
||||
BIO *bio_mem, *bio_b64 = NULL;
|
||||
char *base64_data = NULL;
|
||||
char *clean_base64 = NULL;
|
||||
int clean_base64_len = 0;
|
||||
const char *open_tag = ctx->script_ctx->comment_text->open;
|
||||
const char *close_tag = ctx->script_ctx->comment_text->close;
|
||||
size_t open_tag_len = strlen(open_tag);
|
||||
size_t close_tag_len = strlen(close_tag);
|
||||
size_t signature_header_len = strlen(signature_header);
|
||||
size_t signature_footer_len = strlen(signature_footer);
|
||||
PKCS7 *retval = NULL;
|
||||
|
||||
if (!script_check_file(ctx)) {
|
||||
return NULL; /* FAILED, no signature */
|
||||
}
|
||||
/* extract Base64 signature */
|
||||
if (ctx->script_ctx->utf == 8) {
|
||||
base64_len = signature_len;
|
||||
base64_data = OPENSSL_malloc(base64_len);
|
||||
memcpy(base64_data, signature_data, base64_len);
|
||||
} else {
|
||||
base64_len = utf16_to_utf8((const void *)signature_data,
|
||||
signature_len, &base64_data);
|
||||
}
|
||||
|
||||
/* allocate memory for cleaned Base64 */
|
||||
clean_base64 = OPENSSL_malloc(base64_len);
|
||||
if (!clean_base64) {
|
||||
fprintf(stderr, "Malloc failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* copy clean Base64 data */
|
||||
for (ptr = base64_data;;) {
|
||||
/* find the opening tag */
|
||||
for(;;) {
|
||||
if (ptr + open_tag_len >= base64_data + base64_len) {
|
||||
fprintf(stderr, "Signature line too long\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if (!memcmp(ptr, open_tag, (size_t)open_tag_len)) {
|
||||
ptr += open_tag_len;
|
||||
break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
/* process signature_header and signature_footer */
|
||||
if (ptr + signature_header_len < base64_data + base64_len &&
|
||||
!memcmp(ptr, signature_header, signature_header_len))
|
||||
ptr += signature_header_len;
|
||||
if (ptr + signature_footer_len <= base64_data + base64_len &&
|
||||
!memcmp(ptr, signature_footer, signature_footer_len))
|
||||
break; /* success */
|
||||
|
||||
/* copy until the closing tag */
|
||||
for(;;) {
|
||||
if (ptr + close_tag_len >= base64_data + base64_len) {
|
||||
fprintf(stderr, "Signature line too long\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if (close_tag_len) {
|
||||
if (!memcmp(ptr, close_tag, (size_t)close_tag_len)) {
|
||||
ptr += close_tag_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*ptr == '\r') {
|
||||
ptr++;
|
||||
} else if (*ptr == '\n') {
|
||||
ptr++;
|
||||
break;
|
||||
} else {
|
||||
clean_base64[clean_base64_len++] = *ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* prepare for Base64 decoding */
|
||||
bio_mem = BIO_new_mem_buf(clean_base64, clean_base64_len);
|
||||
bio_b64 = BIO_new(BIO_f_base64());
|
||||
BIO_push(bio_b64, bio_mem);
|
||||
BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
|
||||
/* decode DER */
|
||||
retval = d2i_PKCS7_bio(bio_b64, NULL);
|
||||
|
||||
cleanup:
|
||||
OPENSSL_free(base64_data);
|
||||
OPENSSL_free(clean_base64);
|
||||
BIO_free_all(bio_b64);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract existing signature in DER format.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *script_pkcs7_extract_to_nest(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
return script_pkcs7_extract(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove existing signature.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int script_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
||||
{
|
||||
/* squash the unused parameter warning */
|
||||
(void)hash;
|
||||
if (!script_check_file(ctx)) {
|
||||
return 1; /* FAILED, no signature */
|
||||
}
|
||||
if (!script_write_bio(outdata, ctx->options->indata, ctx->script_ctx->sigpos)) {
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize outdata file and calculate a hash (message digest) of data.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int script_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
||||
{
|
||||
if (ctx->script_ctx->sigpos > 0) {
|
||||
/* Strip current signature */
|
||||
ctx->script_ctx->fileend = ctx->script_ctx->sigpos;
|
||||
}
|
||||
if (!script_write_bio(outdata, ctx->options->indata, ctx->script_ctx->fileend))
|
||||
return 0; /* FAILED */
|
||||
if (!script_digest_convert(hash, ctx, ctx->script_ctx->fileend))
|
||||
return 0; /* FAILED */
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new PKCS#7 signature.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *script_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
|
||||
{
|
||||
ASN1_OCTET_STRING *content;
|
||||
PKCS7 *p7 = pkcs7_create(ctx);
|
||||
|
||||
if (!p7) {
|
||||
fprintf(stderr, "Creating a new signature failed\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!add_indirect_data_object(p7)) {
|
||||
fprintf(stderr, "Adding SPC_INDIRECT_DATA_OBJID failed\n");
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
content = spc_indirect_data_content_get(hash, ctx);
|
||||
if (!content) {
|
||||
fprintf(stderr, "Failed to get spcIndirectDataContent\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!sign_spc_indirect_data_content(p7, content)) {
|
||||
fprintf(stderr, "Failed to set signed content\n");
|
||||
PKCS7_free(p7);
|
||||
ASN1_OCTET_STRING_free(content);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
ASN1_OCTET_STRING_free(content);
|
||||
return p7;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append signature to the outfile.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] outdata: outdata file BIO
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int script_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
||||
{
|
||||
BIO *bio, *b64;
|
||||
BUF_MEM *buffer;
|
||||
size_t i;
|
||||
static const char crlf[] = {0x0d, 0x0a};
|
||||
int ret = 1;
|
||||
|
||||
/* convert to BASE64 */
|
||||
b64 = BIO_new(BIO_f_base64()); /* BIO for base64 encoding */
|
||||
if (!b64)
|
||||
return 1; /* FAILED */
|
||||
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
bio = BIO_new(BIO_s_mem()); /* BIO to hold the base64 data */
|
||||
if (!bio) {
|
||||
BIO_free(b64);
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
bio = BIO_push(b64, bio); /* chain base64 BIO onto memory BIO */
|
||||
if (!i2d_PKCS7_bio(bio, p7)) {
|
||||
BIO_free_all(bio);
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
(void)BIO_flush(bio);
|
||||
BIO_get_mem_ptr(bio, &buffer);
|
||||
(void)BIO_set_close(bio, BIO_NOCLOSE);
|
||||
|
||||
/* split to individual lines and write to outdata */
|
||||
if (!write_commented(ctx, outdata, signature_header, strlen(signature_header)))
|
||||
goto cleanup;
|
||||
for (i = 0; i < buffer->length; i += 64) {
|
||||
if (!write_commented(ctx, outdata, buffer->data + i,
|
||||
buffer->length - i < 64 ? buffer->length - i : 64)) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (!write_commented(ctx, outdata, signature_footer, strlen(signature_footer)))
|
||||
goto cleanup;
|
||||
|
||||
/* signtool expects CRLF terminator at the end of the text file */
|
||||
if (!write_in_encoding(ctx, outdata, crlf, sizeof crlf))
|
||||
goto cleanup;
|
||||
ret = 0; /* OK */
|
||||
|
||||
cleanup:
|
||||
BUF_MEM_free(buffer);
|
||||
BIO_free_all(bio);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up an entire outdata BIO chain.
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] none
|
||||
*/
|
||||
static void script_bio_free(BIO *hash, BIO *outdata)
|
||||
{
|
||||
BIO_free_all(hash);
|
||||
BIO_free_all(outdata);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocate a FILE_FORMAT_CTX structure and script format specific structures.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] none
|
||||
*/
|
||||
static void script_ctx_cleanup(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
unmap_file(ctx->options->indata, ctx->script_ctx->fileend);
|
||||
OPENSSL_free(ctx->script_ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
static int script_is_detaching_supported(void)
|
||||
{
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Script helper functions
|
||||
*/
|
||||
|
||||
static SCRIPT_CTX *script_ctx_get(char *indata, uint32_t filesize, const SCRIPT_COMMENT *comment, int utf)
|
||||
{
|
||||
SCRIPT_CTX *script_ctx;
|
||||
|
||||
const char *input_pos, *signature_pos, *ptr;
|
||||
uint32_t line[LINE_MAX_LEN], commented_header[40], cr, lf;
|
||||
size_t sig_pos = 0, line_pos = 0, commented_header_len = 0;
|
||||
size_t commented_header_size = sizeof commented_header / sizeof(uint32_t);
|
||||
|
||||
utf8DecodeRune("\r", 1, &cr);
|
||||
utf8DecodeRune("\n", 1, &lf);
|
||||
|
||||
/* compute runes for the commented signature header */
|
||||
for (ptr = comment->open;
|
||||
*ptr && commented_header_len < commented_header_size;
|
||||
commented_header_len++)
|
||||
ptr = utf8DecodeRune(ptr, 1, commented_header + commented_header_len);
|
||||
for (ptr = signature_header;
|
||||
*ptr && commented_header_len < commented_header_size;
|
||||
commented_header_len++)
|
||||
ptr = utf8DecodeRune(ptr, 1, commented_header + commented_header_len);
|
||||
for (ptr = comment->close;
|
||||
*ptr && commented_header_len < commented_header_size;
|
||||
commented_header_len++)
|
||||
ptr = utf8DecodeRune(ptr, 1, commented_header + commented_header_len);
|
||||
|
||||
/* find the signature header */
|
||||
for (signature_pos = input_pos = indata; input_pos < indata + filesize; ) {
|
||||
const char *input_prev = input_pos;
|
||||
|
||||
input_pos = utf == 8 ?
|
||||
utf8DecodeRune(input_pos,
|
||||
(size_t)(indata + filesize - input_pos),
|
||||
line + line_pos) :
|
||||
(const char *)utf16DecodeRune((const void *)input_pos,
|
||||
(size_t)(indata + filesize - input_pos)/2,
|
||||
line + line_pos);
|
||||
|
||||
if (!memcmp(line + line_pos, &lf, sizeof lf)) {
|
||||
if (line_pos >= commented_header_len &&
|
||||
!memcmp(line, commented_header, commented_header_len * sizeof(uint32_t))) {
|
||||
sig_pos = (size_t)(signature_pos - indata);
|
||||
if (!memcmp(line + line_pos - 1, &cr, sizeof cr))
|
||||
sig_pos -= (size_t)utf / 8;
|
||||
break; /* SUCCEEDED */
|
||||
}
|
||||
line_pos = 0;
|
||||
signature_pos = input_prev; /* previous line */
|
||||
} else if (line_pos < LINE_MAX_LEN - 1) {
|
||||
line_pos++; /* we can ignore lines longer than our buffer */
|
||||
}
|
||||
}
|
||||
printf("Signature position: %zu\n", sig_pos);
|
||||
|
||||
script_ctx = OPENSSL_malloc(sizeof(SCRIPT_CTX));
|
||||
script_ctx->comment_text = comment;
|
||||
script_ctx->utf = utf;
|
||||
script_ctx->fileend = filesize;
|
||||
script_ctx->sigpos = (uint32_t)sig_pos;
|
||||
return script_ctx; /* OK */
|
||||
}
|
||||
|
||||
/* write a commented line to the bio:
|
||||
* - prepend with CRLF ("\r\n")
|
||||
* - add opening/closing comment tags
|
||||
* - adjust encoding if needed
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int write_commented(FILE_FORMAT_CTX *ctx, BIO *outdata, const char *data, size_t length)
|
||||
{
|
||||
const char *open_tag = ctx->script_ctx->comment_text->open;
|
||||
const char *close_tag = ctx->script_ctx->comment_text->close;
|
||||
size_t open_tag_len = strlen(open_tag);
|
||||
size_t close_tag_len = strlen(close_tag);
|
||||
char *line;
|
||||
|
||||
/* the buffer needs to be long enough for:
|
||||
* - CRLF ("\r\n")
|
||||
* - opening tag
|
||||
* - up to 64 bytes of data
|
||||
* - closing tag
|
||||
* - trailing NUL ("\0") */
|
||||
line = OPENSSL_malloc(2 + open_tag_len + length + close_tag_len + 1);
|
||||
strcpy(line, "\r\n");
|
||||
strcat(line, open_tag);
|
||||
memcpy(line + 2 + open_tag_len, data, length);
|
||||
line[2 + open_tag_len + length] = '\0';
|
||||
strcat(line, close_tag);
|
||||
|
||||
/* adjust encoding */
|
||||
if (!write_in_encoding(ctx, outdata, line, strlen(line))) {
|
||||
OPENSSL_free(line);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
OPENSSL_free(line);
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/* adjust encoding if needed
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int write_in_encoding(FILE_FORMAT_CTX *ctx, BIO *outdata, const char *line, size_t length)
|
||||
{
|
||||
size_t written;
|
||||
if (ctx->script_ctx->utf == 8) {
|
||||
if (!BIO_write_ex(outdata, line, length, &written)
|
||||
|| written != length) {
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
} else {
|
||||
uint16_t *utf16_data = NULL;
|
||||
size_t utf16_len = utf8_to_utf16(line, length, &utf16_data);
|
||||
|
||||
if (!BIO_write_ex(outdata, utf16_data, utf16_len, &written)
|
||||
|| written != utf16_len) {
|
||||
OPENSSL_free(utf16_data);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
OPENSSL_free(utf16_data);
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/* convert len bytes of UTF-8 to UTF-16
|
||||
* return the number of output bytes
|
||||
*/
|
||||
static size_t utf8_to_utf16(const char *data, size_t len, uint16_t **out_utf16)
|
||||
{
|
||||
size_t utf16_len = utf8UTF16Count(data, len);
|
||||
*out_utf16 = OPENSSL_malloc(utf16_len * sizeof(uint16_t));
|
||||
if (!*out_utf16)
|
||||
return 0; /* memory allocation failed */
|
||||
|
||||
const char *s = data;
|
||||
uint16_t *d = *out_utf16;
|
||||
uint32_t rune;
|
||||
size_t remaining_len = len;
|
||||
|
||||
while (remaining_len > 0) {
|
||||
s = utf8DecodeRune(s, remaining_len, &rune);
|
||||
if (!s || s < data)
|
||||
break; /* invalid UTF-8 sequence */
|
||||
size_t consumed = (size_t)(s - data);
|
||||
|
||||
remaining_len -= consumed;
|
||||
data = s;
|
||||
d += utf16EncodeRune(rune, d);
|
||||
}
|
||||
return (size_t)(2 * (d - *out_utf16));
|
||||
}
|
||||
|
||||
/* convert len bytes of UTF-16 to UTF-8
|
||||
* return the number of output bytes
|
||||
*/
|
||||
static size_t utf16_to_utf8(const uint16_t *data, size_t len, char **out_utf8)
|
||||
{
|
||||
size_t utf8_len = utf16UTF8Count(data, len/2);
|
||||
*out_utf8 = OPENSSL_malloc(utf8_len);
|
||||
if (!*out_utf8)
|
||||
return 0; /* memory allocation failed */
|
||||
|
||||
const uint16_t *s = data;
|
||||
char *d = *out_utf8;
|
||||
uint32_t rune;
|
||||
size_t remaining_len = len/2;
|
||||
|
||||
while (remaining_len > 0) {
|
||||
s = utf16DecodeRune(s, remaining_len, &rune);
|
||||
if (!s || s < data)
|
||||
break; /* invalid UTF-16 sequence */
|
||||
size_t consumed = (size_t)(s - data);
|
||||
|
||||
remaining_len -= consumed;
|
||||
data = s;
|
||||
d += utf8EncodeRune(rune, d);
|
||||
}
|
||||
return (size_t)(d - *out_utf8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute a message digest value of a signed or unsigned script file.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] md: message digest algorithm
|
||||
* [returns] calculated message digest BIO
|
||||
*/
|
||||
static BIO *script_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
|
||||
{
|
||||
size_t fileend;
|
||||
BIO *hash = BIO_new(BIO_f_md());
|
||||
|
||||
if (ctx->script_ctx->sigpos)
|
||||
fileend = ctx->script_ctx->sigpos;
|
||||
else
|
||||
fileend = ctx->script_ctx->fileend;
|
||||
|
||||
if (!BIO_set_md(hash, md)) {
|
||||
fprintf(stderr, "Unable to set the message digest of BIO\n");
|
||||
BIO_free_all(hash);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
BIO_push(hash, BIO_new(BIO_s_null()));
|
||||
if (!script_digest_convert(hash, ctx, fileend)) {
|
||||
fprintf(stderr, "Unable calc a message digest value\n");
|
||||
BIO_free_all(hash);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute a message digest value
|
||||
* [in, out] hash: message digest BIO
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] len: mapped file length
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int script_digest_convert(BIO *hash, FILE_FORMAT_CTX *ctx, size_t len)
|
||||
{
|
||||
if (ctx->script_ctx->utf == 8) { /* need to convert to UTF-16 */
|
||||
uint16_t *utf16_data = NULL;
|
||||
size_t utf16_len = utf8_to_utf16(ctx->options->indata,
|
||||
len, &utf16_data);
|
||||
|
||||
if (!script_write_bio(hash, (char *)utf16_data, utf16_len)) {
|
||||
OPENSSL_free(utf16_data);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
OPENSSL_free(utf16_data);
|
||||
} else { /* already UTF-16 -> no need to convert */
|
||||
if (!script_write_bio(hash, ctx->options->indata, len)) {
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Write len bytes from data to BIO
|
||||
* [in, out] bio: message digest or outdata BIO
|
||||
* [in] indata: mapped file
|
||||
* [in] len: indata length
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int script_write_bio(BIO *bio, char *indata, size_t len)
|
||||
{
|
||||
size_t i = 0, written;
|
||||
|
||||
while (len > 0) {
|
||||
if (!BIO_write_ex(bio, indata + i, len, &written))
|
||||
return 0; /* FAILED */
|
||||
len -= written;
|
||||
i += written;
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the signature exists.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int script_check_file(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "Init error\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (ctx->script_ctx->sigpos == 0
|
||||
|| ctx->script_ctx->sigpos > ctx->script_ctx->fileend) {
|
||||
fprintf(stderr, "No signature found\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
vim: set ts=4 expandtab:
|
||||
*/
|
2
tests/.gitignore
vendored
Normal file
2
tests/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
__pycache__
|
||||
.pylintrc
|
6
tests/certs/.gitignore
vendored
6
tests/certs/.gitignore
vendored
@ -1,6 +0,0 @@
|
||||
*.der
|
||||
*.pem
|
||||
*.pvk
|
||||
*.p12
|
||||
*.spc
|
||||
*.txt
|
47
tests/certs/ca-bundle.crt
Normal file
47
tests/certs/ca-bundle.crt
Normal file
@ -0,0 +1,47 @@
|
||||
# Certum Trusted Network CA
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
|
||||
MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
|
||||
ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
|
||||
cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
|
||||
WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
|
||||
Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
|
||||
IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
|
||||
AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
|
||||
UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
|
||||
TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
|
||||
BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
|
||||
kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
|
||||
AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
|
||||
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
|
||||
HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
|
||||
sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
|
||||
I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
|
||||
J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
|
||||
VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
|
||||
03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# DigiCert Assured ID Root CA
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
|
||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
|
||||
b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
|
||||
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
|
||||
cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
|
||||
JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
|
||||
mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
|
||||
wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
|
||||
VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
|
||||
AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
|
||||
AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
|
||||
BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
|
||||
pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
|
||||
dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
|
||||
fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
|
||||
NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
|
||||
H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
|
||||
+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
|
||||
-----END CERTIFICATE-----
|
@ -1,218 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
result=0
|
||||
|
||||
test_result() {
|
||||
if test "$1" -eq 0
|
||||
then
|
||||
printf "Succeeded\n" >> "makecerts.log"
|
||||
else
|
||||
printf "Failed\n" >> "makecerts.log"
|
||||
fi
|
||||
}
|
||||
|
||||
make_certs() {
|
||||
password=passme
|
||||
result_path=$(pwd)
|
||||
cd $(dirname "$0")
|
||||
script_path=$(pwd)
|
||||
cd "${result_path}"
|
||||
mkdir "tmp/"
|
||||
|
||||
# OpenSSL settings
|
||||
CONF="${script_path}/openssl_intermediate.cnf"
|
||||
TEMP_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
|
||||
if test -n "$1"
|
||||
then
|
||||
OPENSSL="$1/bin/openssl"
|
||||
LD_LIBRARY_PATH="$1/lib"
|
||||
else
|
||||
OPENSSL=openssl
|
||||
fi
|
||||
|
||||
mkdir "demoCA/" 2>> "makecerts.log" 1>&2
|
||||
touch "demoCA/index.txt"
|
||||
touch "demoCA/index.txt.attr"
|
||||
echo 1000 > "demoCA/serial"
|
||||
date > "makecerts.log"
|
||||
$OPENSSL version 2>> "makecerts.log" 1>&2
|
||||
echo -n "$password" > "password.txt"
|
||||
|
||||
printf "\nGenerate root CA certificate\n" >> "makecerts.log"
|
||||
$OPENSSL genrsa -out demoCA/CA.key \
|
||||
2>> "makecerts.log" 1>&2
|
||||
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
OPENSSL=openssl
|
||||
CONF="${script_path}/openssl_root.cnf"
|
||||
$OPENSSL req -config $CONF -new -x509 -days 3600 -key demoCA/CA.key -out tmp/CACert.pem \
|
||||
-subj "/C=PL/O=osslsigncode/OU=Certification Authority/CN=Root CA" \
|
||||
2>> "makecerts.log" 1>&2'
|
||||
test_result $?
|
||||
|
||||
printf "\nGenerate intermediate CA certificate\n" >> "makecerts.log"
|
||||
$OPENSSL genrsa -out demoCA/intermediate.key \
|
||||
2>> "makecerts.log" 1>&2
|
||||
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
OPENSSL=openssl
|
||||
CONF="${script_path}/openssl_intermediate.cnf"
|
||||
$OPENSSL req -config $CONF -new -key demoCA/intermediate.key -out demoCA/intermediate.csr \
|
||||
-subj "/C=PL/O=osslsigncode/OU=Certification Authority/CN=Intermediate CA" \
|
||||
2>> "makecerts.log" 1>&2'
|
||||
test_result $?
|
||||
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
OPENSSL=openssl
|
||||
CONF="${script_path}/openssl_root.cnf"
|
||||
$OPENSSL ca -config $CONF -batch -in demoCA/intermediate.csr -out demoCA/intermediate.cer \
|
||||
2>> "makecerts.log" 1>&2'
|
||||
test_result $?
|
||||
$OPENSSL x509 -in demoCA/intermediate.cer -out tmp/intermediate.pem \
|
||||
2>> "makecerts.log" 1>&2
|
||||
|
||||
printf "\nGenerate private RSA encrypted key\n" >> "makecerts.log"
|
||||
$OPENSSL genrsa -des3 -out demoCA/private.key -passout pass:$password \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
cat demoCA/private.key >> tmp/keyp.pem 2>> "makecerts.log"
|
||||
|
||||
printf "\nGenerate private RSA decrypted key\n" >> "makecerts.log"
|
||||
$OPENSSL rsa -in demoCA/private.key -passin pass:$password -out tmp/key.pem \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nGenerate a certificate to revoke\n" >> "makecerts.log"
|
||||
$OPENSSL req -config $CONF -new -key demoCA/private.key -passin pass:$password -out demoCA/revoked.csr \
|
||||
-subj "/C=PL/O=osslsigncode/OU=CSP/CN=Revoked/emailAddress=osslsigncode@example.com" \
|
||||
2>> "makecerts.log" 1>&2
|
||||
$OPENSSL ca -config $CONF -batch -in demoCA/revoked.csr -out demoCA/revoked.cer \
|
||||
2>> "makecerts.log" 1>&2
|
||||
$OPENSSL x509 -in demoCA/revoked.cer -out tmp/revoked.pem \
|
||||
2>> "makecerts.log" 1>&2
|
||||
|
||||
printf "\nRevoke above certificate\n" >> "makecerts.log"
|
||||
$OPENSSL ca -config $CONF -revoke demoCA/1001.pem \
|
||||
2>> "makecerts.log" 1>&2
|
||||
|
||||
printf "\nAttach intermediate certificate to revoked certificate\n" >> "makecerts.log"
|
||||
cat tmp/intermediate.pem >> tmp/revoked.pem
|
||||
|
||||
printf "\nGenerate CRL file\n" >> "makecerts.log"
|
||||
TZ=GMT faketime -f '@2019-01-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
OPENSSL=openssl
|
||||
CONF="${script_path}/openssl_intermediate.cnf"
|
||||
$OPENSSL ca -config $CONF -gencrl -crldays 8766 -out tmp/CACertCRL.pem \
|
||||
2>> "makecerts.log" 1>&2'
|
||||
|
||||
printf "\nConvert revoked certificate to SPC format\n" >> "makecerts.log"
|
||||
$OPENSSL crl2pkcs7 -in tmp/CACertCRL.pem -certfile tmp/revoked.pem -outform DER -out tmp/revoked.spc \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nGenerate CSP Cross-Certificate\n" >> "makecerts.log"
|
||||
$OPENSSL genrsa -out demoCA/cross.key \
|
||||
2>> "makecerts.log" 1>&2
|
||||
TZ=GMT faketime -f '@2018-01-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
OPENSSL=openssl
|
||||
CONF="${script_path}/openssl_intermediate.cnf"
|
||||
$OPENSSL req -config $CONF -new -x509 -days 900 -key demoCA/cross.key -out tmp/crosscert.pem \
|
||||
-subj "/C=PL/O=osslsigncode/OU=CSP/CN=crosscert/emailAddress=osslsigncode@example.com" \
|
||||
2>> "makecerts.log" 1>&2'
|
||||
test_result $?
|
||||
|
||||
printf "\nGenerate code signing certificate\n" >> "makecerts.log"
|
||||
$OPENSSL req -config $CONF -new -key demoCA/private.key -passin pass:$password -out demoCA/cert.csr \
|
||||
-subj "/C=PL/ST=Mazovia Province/L=Warsaw/O=osslsigncode/OU=CSP/CN=Certificate/emailAddress=osslsigncode@example.com" \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
$OPENSSL ca -config $CONF -batch -in demoCA/cert.csr -out demoCA/cert.cer \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
$OPENSSL x509 -in demoCA/cert.cer -out tmp/cert.pem \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nConvert the key to DER format\n" >> "makecerts.log"
|
||||
$OPENSSL rsa -in tmp/key.pem -outform DER -out tmp/key.der -passout pass:$password \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nConvert the key to PVK format\n" >> "makecerts.log"
|
||||
$OPENSSL rsa -in tmp/key.pem -outform PVK -out tmp/key.pvk -pvk-none \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nConvert the certificate to DER format\n" >> "makecerts.log"
|
||||
$OPENSSL x509 -in tmp/cert.pem -outform DER -out tmp/cert.der \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nAttach intermediate certificate to code signing certificate\n" >> "makecerts.log"
|
||||
cat tmp/intermediate.pem >> tmp/cert.pem
|
||||
|
||||
printf "\nConvert the certificate to SPC format\n" >> "makecerts.log"
|
||||
$OPENSSL crl2pkcs7 -nocrl -certfile tmp/cert.pem -outform DER -out tmp/cert.spc \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nConvert the certificate and the key into a PKCS#12 container\n" >> "makecerts.log"
|
||||
$OPENSSL pkcs12 -export -in tmp/cert.pem -inkey tmp/key.pem -out tmp/cert.p12 -passout pass:$password \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nGenerate expired certificate\n" >> "makecerts.log"
|
||||
$OPENSSL req -config $CONF -new -key demoCA/private.key -passin pass:$password -out demoCA/expired.csr \
|
||||
-subj "/C=PL/ST=Mazovia Province/L=Warsaw/O=osslsigncode/OU=CSP/CN=Expired/emailAddress=osslsigncode@example.com" \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
$OPENSSL ca -config $CONF -enddate "190101000000Z" -batch -in demoCA/expired.csr -out demoCA/expired.cer \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
$OPENSSL x509 -in demoCA/expired.cer -out tmp/expired.pem \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nAttach intermediate certificate to expired certificate\n" >> "makecerts.log"
|
||||
cat tmp/intermediate.pem >> tmp/expired.pem
|
||||
|
||||
# copy new files
|
||||
if test -s tmp/intermediate.pem -a -s tmp/CACert.pem -a -s tmp/CACertCRL.pem \
|
||||
-a -s tmp/key.pem -a -s tmp/keyp.pem -a -s tmp/key.der -a -s tmp/key.pvk \
|
||||
-a -s tmp/cert.pem -a -s tmp/cert.p12 -a -s tmp/cert.der -a -s tmp/cert.spc \
|
||||
-a -s tmp/crosscert.pem -a -s tmp/expired.pem -a -s tmp/revoked.pem -a -s tmp/revoked.spc
|
||||
then
|
||||
cp tmp/* ./
|
||||
printf "%s\n" "keys & certificates successfully generated"
|
||||
printf "%s\n" "makecerts.sh finished"
|
||||
rm -f "makecerts.log"
|
||||
else
|
||||
printf "%s\n" "makecerts.sh failed"
|
||||
printf "%s\n" "error logs ${result_path}/makecerts.log"
|
||||
result=1
|
||||
fi
|
||||
|
||||
# remove the working directory
|
||||
rm -rf "demoCA/"
|
||||
rm -rf "tmp/"
|
||||
|
||||
# restore settings
|
||||
LD_LIBRARY_PATH=$TEMP_LD_LIBRARY_PATH
|
||||
|
||||
exit $result
|
||||
}
|
||||
|
||||
# Tests requirement
|
||||
if test -n "$(command -v faketime)"
|
||||
then
|
||||
make_certs $1
|
||||
result=$?
|
||||
else
|
||||
printf "%s\n" "faketime not found in \$PATH"
|
||||
printf "%s\n" "tests skipped, please install faketime package"
|
||||
result=1
|
||||
fi
|
||||
|
||||
exit $result
|
@ -1,61 +0,0 @@
|
||||
# OpenSSL intermediate CA configuration file
|
||||
|
||||
[ ca ]
|
||||
default_ca = CA_default
|
||||
|
||||
[ CA_default ]
|
||||
# Directory and file locations
|
||||
dir = .
|
||||
certs = $dir/demoCA
|
||||
crl_dir = $dir/demoCA
|
||||
new_certs_dir = $dir/demoCA
|
||||
database = $dir/demoCA/index.txt
|
||||
serial = $dir/demoCA/serial
|
||||
private_key = $dir/demoCA/intermediate.key
|
||||
certificate = $dir/tmp/intermediate.pem
|
||||
crl_extensions = crl_ext
|
||||
default_md = sha256
|
||||
preserve = no
|
||||
policy = policy_loose
|
||||
default_startdate = 180101000000Z
|
||||
default_enddate = 210101000000Z
|
||||
|
||||
[ req ]
|
||||
# Options for the `req` tool
|
||||
encrypt_key = no
|
||||
default_bits = 2048
|
||||
default_md = sha256
|
||||
string_mask = utf8only
|
||||
distinguished_name = req_distinguished_name
|
||||
x509_extensions = usr_extensions
|
||||
|
||||
[ crl_ext ]
|
||||
# Extension for CRLs
|
||||
authorityKeyIdentifier = keyid:always
|
||||
|
||||
[ usr_extensions ]
|
||||
# Extension to add when the -x509 option is used
|
||||
basicConstraints = CA:FALSE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid, issuer
|
||||
extendedKeyUsage = codeSigning
|
||||
|
||||
[ policy_loose ]
|
||||
# Allow the intermediate CA to sign a more diverse range of certificates.
|
||||
# See the POLICY FORMAT section of the `ca` man page.
|
||||
countryName = optional
|
||||
stateOrProvinceName = optional
|
||||
localityName = optional
|
||||
organizationName = optional
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
[ req_distinguished_name ]
|
||||
countryName = Country Name (2 letter code)
|
||||
stateOrProvinceName = State or Province Name
|
||||
localityName = Locality Name
|
||||
0.organizationName = Organization Name
|
||||
organizationalUnitName = Organizational Unit Name
|
||||
commonName = Common Name
|
||||
emailAddress = Email Address
|
@ -1,61 +0,0 @@
|
||||
# OpenSSL root CA configuration file
|
||||
|
||||
[ ca ]
|
||||
default_ca = CA_default
|
||||
|
||||
[ CA_default ]
|
||||
# Directory and file locations.
|
||||
dir = .
|
||||
certs = $dir/demoCA
|
||||
crl_dir = $dir/demoCA
|
||||
new_certs_dir = $dir/demoCA
|
||||
database = $dir/demoCA/index.txt
|
||||
serial = $dir/demoCA/serial
|
||||
private_key = $dir/demoCA/CA.key
|
||||
certificate = $dir/tmp/CACert.pem
|
||||
crl_extensions = crl_ext
|
||||
default_md = sha256
|
||||
preserve = no
|
||||
policy = policy_match
|
||||
default_startdate = 180101000000Z
|
||||
default_enddate = 260101000000Z
|
||||
x509_extensions = v3_intermediate_ca
|
||||
|
||||
[ req ]
|
||||
# Options for the `req` tool
|
||||
encrypt_key = no
|
||||
default_bits = 2048
|
||||
default_md = sha256
|
||||
string_mask = utf8only
|
||||
x509_extensions = ca_extensions
|
||||
distinguished_name = req_distinguished_name
|
||||
|
||||
[ ca_extensions ]
|
||||
# Extension to add when the -x509 option is used
|
||||
basicConstraints = critical, CA:true
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always,issuer
|
||||
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
|
||||
|
||||
[ v3_intermediate_ca ]
|
||||
# Extensions for a typical intermediate CA (`man x509v3_config`)
|
||||
basicConstraints = critical, CA:true, pathlen:0
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always,issuer
|
||||
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
|
||||
|
||||
[ policy_match ]
|
||||
countryName = match
|
||||
organizationName = match
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
[ req_distinguished_name ]
|
||||
countryName = Country Name (2 letter code)
|
||||
stateOrProvinceName = State or Province Name
|
||||
localityName = Locality Name
|
||||
0.organizationName = Organization Name
|
||||
organizationalUnitName = Organizational Unit Name
|
||||
commonName = Common Name
|
||||
emailAddress = Email Address
|
@ -1,61 +0,0 @@
|
||||
# OpenSSL root CA configuration file
|
||||
|
||||
[ ca ]
|
||||
default_ca = CA_default
|
||||
|
||||
[ CA_default ]
|
||||
# Directory and file locations.
|
||||
dir = .
|
||||
certs = $dir/demoCA
|
||||
crl_dir = $dir/demoCA
|
||||
new_certs_dir = $dir/demoCA
|
||||
database = $dir/demoCA/index.txt
|
||||
serial = $dir/demoCA/serial
|
||||
crl_extensions = crl_ext
|
||||
default_md = sha256
|
||||
preserve = no
|
||||
policy = policy_match
|
||||
x509_extensions = usr_cert
|
||||
private_key = $dir/demoCA/CA.key
|
||||
certificate = $dir/tmp/CACert.pem
|
||||
default_startdate = 180101000000Z
|
||||
default_enddate = 210101000000Z
|
||||
|
||||
[ req ]
|
||||
encrypt_key = no
|
||||
default_bits = 2048
|
||||
default_md = sha256
|
||||
string_mask = utf8only
|
||||
x509_extensions = ca_extensions
|
||||
distinguished_name = req_distinguished_name
|
||||
|
||||
[ crl_ext ]
|
||||
authorityKeyIdentifier = keyid:always
|
||||
|
||||
[ usr_cert ]
|
||||
basicConstraints = CA:FALSE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid, issuer
|
||||
extendedKeyUsage = codeSigning
|
||||
|
||||
[ ca_extensions ]
|
||||
basicConstraints = critical, CA:true
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always,issuer
|
||||
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
|
||||
|
||||
[ policy_match ]
|
||||
countryName = match
|
||||
organizationName = match
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
[ req_distinguished_name ]
|
||||
countryName = Country Name (2 letter code)
|
||||
stateOrProvinceName = State or Province Name
|
||||
localityName = Locality Name
|
||||
0.organizationName = Organization Name
|
||||
organizationalUnitName = Organizational Unit Name
|
||||
commonName = Common Name
|
||||
emailAddress = Email Address
|
40
tests/check_cryptography.py
Normal file
40
tests/check_cryptography.py
Normal file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/python3
|
||||
"""Check cryptography module."""
|
||||
|
||||
import sys
|
||||
|
||||
try:
|
||||
import cryptography
|
||||
print(cryptography.__version__, end="")
|
||||
except ModuleNotFoundError as ierr:
|
||||
print("Module not installed: {}".format(ierr))
|
||||
sys.exit(1)
|
||||
except ImportError as ierr:
|
||||
print("Module not found: {}".format(ierr))
|
||||
sys.exit(1)
|
||||
|
||||
class UnsupportedVersion(Exception):
|
||||
"""Unsupported version"""
|
||||
|
||||
def main() -> None:
|
||||
"""Check python3-cryptography version"""
|
||||
try:
|
||||
version = tuple(int(num) for num in cryptography.__version__.split('.'))
|
||||
if version < (37, 0, 2):
|
||||
raise UnsupportedVersion("unsupported python3-cryptography version")
|
||||
except UnsupportedVersion as err:
|
||||
print(" {}".format(err), end="")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
# pylint: disable=pointless-string-statement
|
||||
"""Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
"""
|
51
tests/client_http.py
Normal file
51
tests/client_http.py
Normal file
@ -0,0 +1,51 @@
|
||||
#!/usr/bin/python3
|
||||
"""Implementation of a HTTP client"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import http.client
|
||||
|
||||
RESULT_PATH = os.getcwd()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Creating a POST Request"""
|
||||
ret = 0
|
||||
try:
|
||||
file_path = os.path.join(RESULT_PATH, "./Testing/logs/url.log")
|
||||
with open(file_path, mode="r", encoding="utf-8") as file:
|
||||
url = file.readline()
|
||||
host, port = url.split(":")
|
||||
conn = http.client.HTTPConnection(host, port)
|
||||
conn.request('POST', '/kill_server')
|
||||
response = conn.getresponse()
|
||||
print("HTTP status code:", response.getcode(), end=', ')
|
||||
try:
|
||||
text = response.read()
|
||||
print(text.decode("UTF-8"), end='', flush=True)
|
||||
except OSError as err:
|
||||
print(f"Warning: {err}")
|
||||
conn.close()
|
||||
except OSError as err:
|
||||
print(f"OSError: {err}")
|
||||
ret = err.errno
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
print(f"HTTP client error: {err}")
|
||||
ret = err
|
||||
finally:
|
||||
sys.exit(ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
# pylint: disable=pointless-string-statement
|
||||
"""
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
"""
|
1
tests/conf/.gitignore
vendored
Normal file
1
tests/conf/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.log
|
47
tests/conf/openssl_tsa.cnf
Normal file
47
tests/conf/openssl_tsa.cnf
Normal file
@ -0,0 +1,47 @@
|
||||
# OpenSSL Timestamp Authority configuration file
|
||||
|
||||
oid_section = new_oids
|
||||
|
||||
[ new_oids ]
|
||||
tsa_policy1 = 1.2.3.4.1
|
||||
tsa_policy2 = 1.2.3.4.5.6
|
||||
tsa_policy3 = 1.2.3.4.5.7
|
||||
|
||||
[ req ]
|
||||
# Options for the `req` tool
|
||||
default_bits = 2048
|
||||
encrypt_key = yes
|
||||
default_md = sha256
|
||||
utf8 = yes
|
||||
string_mask = utf8only
|
||||
prompt = no
|
||||
distinguished_name = ca_distinguished_name
|
||||
|
||||
[ ca_distinguished_name ]
|
||||
countryName = "PL"
|
||||
organizationName = "osslsigncode"
|
||||
organizationalUnitName = "Timestamp Authority"
|
||||
commonName = "Test TSA"
|
||||
|
||||
|
||||
# Time Stamping Authority command "openssl-ts"
|
||||
|
||||
[ tsa ]
|
||||
default_tsa = tsa_config
|
||||
|
||||
[ tsa_config ]
|
||||
dir = ./Testing/certs
|
||||
signer_cert = $dir/TSA.pem
|
||||
signer_key = $dir/TSA.key
|
||||
certs = $dir/tsa-chain.pem
|
||||
serial = $dir/tsa-serial
|
||||
default_policy = tsa_policy1
|
||||
other_policies = tsa_policy2, tsa_policy3
|
||||
signer_digest = sha256
|
||||
digests = sha256, sha384, sha512
|
||||
accuracy = secs:1, millisecs:500, microsecs:100
|
||||
ordering = yes
|
||||
tsa_name = yes
|
||||
ess_cert_id_chain = yes
|
||||
ess_cert_id_alg = sha256
|
||||
crypto_device = builtin
|
47
tests/exec.py
Normal file
47
tests/exec.py
Normal file
@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python3
|
||||
"""Implementation of a single ctest script."""
|
||||
|
||||
import sys
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
|
||||
def parse(value):
|
||||
"""Read parameter from file."""
|
||||
prefix = 'FILE '
|
||||
if value.startswith(prefix):
|
||||
with open(value[len(prefix):], mode="r", encoding="utf-8") as file:
|
||||
return file.read().strip()
|
||||
return value
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Run osslsigncode with its options."""
|
||||
if len(sys.argv) > 1:
|
||||
try:
|
||||
params = map(parse, sys.argv[1:])
|
||||
proc = Popen(params, stdout=PIPE, stderr=PIPE, text=True)
|
||||
stdout, stderr = proc.communicate()
|
||||
print(stdout, file=sys.stderr)
|
||||
if stderr:
|
||||
print("Error:\n" + "-" * 58 + "\n" + stderr, file=sys.stderr)
|
||||
sys.exit(proc.returncode)
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
# all exceptions are critical
|
||||
print(err, file=sys.stderr)
|
||||
else:
|
||||
print("Usage:\n\t{} COMMAND [ARG]...'".format(sys.argv[0]), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
# pylint: disable=pointless-string-statement
|
||||
"""Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
"""
|
BIN
tests/files/unsigned.256appx
Normal file
BIN
tests/files/unsigned.256appx
Normal file
Binary file not shown.
BIN
tests/files/unsigned.512appx
Normal file
BIN
tests/files/unsigned.512appx
Normal file
Binary file not shown.
BIN
tests/files/unsigned.cat
Normal file
BIN
tests/files/unsigned.cat
Normal file
Binary file not shown.
BIN
tests/files/unsigned.ex_
Normal file
BIN
tests/files/unsigned.ex_
Normal file
Binary file not shown.
BIN
tests/files/unsigned.exe
Normal file
BIN
tests/files/unsigned.exe
Normal file
Binary file not shown.
BIN
tests/files/unsigned.mof
Normal file
BIN
tests/files/unsigned.mof
Normal file
Binary file not shown.
BIN
tests/files/unsigned.msi
Normal file
BIN
tests/files/unsigned.msi
Normal file
Binary file not shown.
2
tests/files/unsigned.ps1
Normal file
2
tests/files/unsigned.ps1
Normal file
@ -0,0 +1,2 @@
|
||||
cls
|
||||
Write-Host "żółć"
|
5
tests/files/unsigned.psc1
Normal file
5
tests/files/unsigned.psc1
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PSConsoleFile ConsoleSchemaVersion="1.0">
|
||||
<PSVersion>5.1.19041.3930</PSVersion>
|
||||
<PSSnapIns />
|
||||
</PSConsoleFile>
|
581
tests/make_certificates.py
Normal file
581
tests/make_certificates.py
Normal file
@ -0,0 +1,581 @@
|
||||
#!/usr/bin/python3
|
||||
"""Make test certificates"""
|
||||
|
||||
import os
|
||||
import datetime
|
||||
import cryptography
|
||||
|
||||
# Explicit imports of cryptography submodules
|
||||
import cryptography.x509
|
||||
import cryptography.x509.oid
|
||||
import cryptography.hazmat.primitives.hashes
|
||||
import cryptography.hazmat.primitives.asymmetric.rsa
|
||||
import cryptography.hazmat.primitives.serialization
|
||||
import cryptography.hazmat.primitives.serialization.pkcs12
|
||||
|
||||
# Import classes and functions from the cryptography module
|
||||
from cryptography.x509 import (
|
||||
AuthorityKeyIdentifier,
|
||||
BasicConstraints,
|
||||
Certificate,
|
||||
CertificateBuilder,
|
||||
CertificateRevocationListBuilder,
|
||||
CRLDistributionPoints,
|
||||
CRLNumber,
|
||||
CRLReason,
|
||||
DistributionPoint,
|
||||
DNSName,
|
||||
ExtendedKeyUsage,
|
||||
KeyUsage,
|
||||
Name,
|
||||
NameAttribute,
|
||||
NameConstraints,
|
||||
random_serial_number,
|
||||
RevokedCertificateBuilder,
|
||||
ReasonFlags,
|
||||
SubjectKeyIdentifier,
|
||||
UniformResourceIdentifier
|
||||
)
|
||||
from cryptography.x509.oid import (
|
||||
ExtendedKeyUsageOID,
|
||||
NameOID
|
||||
)
|
||||
from cryptography.hazmat.primitives.hashes import SHA256
|
||||
from cryptography.hazmat.primitives.asymmetric.rsa import (
|
||||
generate_private_key,
|
||||
RSAPrivateKey
|
||||
)
|
||||
from cryptography.hazmat.primitives.serialization import (
|
||||
BestAvailableEncryption,
|
||||
Encoding,
|
||||
NoEncryption,
|
||||
PrivateFormat
|
||||
)
|
||||
from cryptography.hazmat.primitives.serialization.pkcs12 import serialize_key_and_certificates
|
||||
|
||||
try:
|
||||
if cryptography.__version__ >= '38.0.0':
|
||||
from cryptography.hazmat.primitives.serialization.pkcs12 import PBES
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
RESULT_PATH = os.getcwd()
|
||||
CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
|
||||
|
||||
date_20170101 = datetime.datetime(2017, 1, 1)
|
||||
date_20180101 = datetime.datetime(2018, 1, 1)
|
||||
date_20190101 = datetime.datetime(2019, 1, 1)
|
||||
|
||||
PASSWORD='passme'
|
||||
|
||||
|
||||
class X509Extensions():
|
||||
"""Base class for X509 Extensions"""
|
||||
|
||||
def __init__(self, unit_name, cdp_port, cdp_name):
|
||||
self.unit_name = unit_name
|
||||
self.port = cdp_port
|
||||
self.name = cdp_name
|
||||
|
||||
def create_x509_name(self, common_name) -> Name:
|
||||
"""Return x509.Name"""
|
||||
return Name(
|
||||
[
|
||||
NameAttribute(NameOID.COUNTRY_NAME, "PL"),
|
||||
NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Mazovia Province"),
|
||||
NameAttribute(NameOID.LOCALITY_NAME, "Warsaw"),
|
||||
NameAttribute(NameOID.ORGANIZATION_NAME, "osslsigncode"),
|
||||
NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, self.unit_name),
|
||||
NameAttribute(NameOID.COMMON_NAME, common_name)
|
||||
]
|
||||
)
|
||||
|
||||
def create_x509_crldp(self) -> CRLDistributionPoints:
|
||||
"""Return x509.CRLDistributionPoints"""
|
||||
return CRLDistributionPoints(
|
||||
[
|
||||
DistributionPoint(
|
||||
full_name=[UniformResourceIdentifier(
|
||||
"http://127.0.0.1:" + str(self.port) + "/" + str(self.name))
|
||||
],
|
||||
relative_name=None,
|
||||
reasons=None,
|
||||
crl_issuer=None
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
def create_x509_name_constraints(self) -> NameConstraints:
|
||||
"""Return x509.NameConstraints"""
|
||||
return NameConstraints(
|
||||
permitted_subtrees = [DNSName('test.com'), DNSName('test.org')],
|
||||
excluded_subtrees = None
|
||||
)
|
||||
|
||||
class IntermediateCACertificate(X509Extensions):
|
||||
"""Base class for Intermediate CA certificate"""
|
||||
|
||||
def __init__(self, issuer_cert, issuer_key):
|
||||
self.issuer_cert = issuer_cert
|
||||
self.issuer_key = issuer_key
|
||||
super().__init__("Certification Authority", 0, None)
|
||||
|
||||
def make_cert(self) -> (Certificate, RSAPrivateKey):
|
||||
"""Generate intermediate CA certificate"""
|
||||
key = generate_private_key(public_exponent=65537, key_size=2048)
|
||||
key_public = key.public_key()
|
||||
authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
|
||||
self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
|
||||
)
|
||||
key_usage = KeyUsage(
|
||||
digital_signature=True,
|
||||
content_commitment=False,
|
||||
key_encipherment=False,
|
||||
data_encipherment=False,
|
||||
key_agreement=False,
|
||||
key_cert_sign=True,
|
||||
crl_sign=True,
|
||||
encipher_only=False,
|
||||
decipher_only=False
|
||||
)
|
||||
cert = (
|
||||
CertificateBuilder()
|
||||
.subject_name(self.create_x509_name("Intermediate CA"))
|
||||
.issuer_name(self.issuer_cert.subject)
|
||||
.public_key(key_public)
|
||||
.serial_number(random_serial_number())
|
||||
.not_valid_before(date_20180101)
|
||||
.not_valid_after(date_20180101 + datetime.timedelta(days=7300))
|
||||
.add_extension(BasicConstraints(ca=True, path_length=0), critical=True)
|
||||
.add_extension(SubjectKeyIdentifier.from_public_key(key_public), critical=False)
|
||||
.add_extension(authority_key, critical=False)
|
||||
.add_extension(key_usage, critical=True)
|
||||
.sign(self.issuer_key, SHA256())
|
||||
)
|
||||
file_path=os.path.join(CERTS_PATH, "intermediateCA.pem")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(cert.public_bytes(encoding=Encoding.PEM))
|
||||
|
||||
return cert, key
|
||||
|
||||
|
||||
class RootCACertificate(X509Extensions):
|
||||
"""Base class for Root CA certificate"""
|
||||
|
||||
def __init__(self):
|
||||
self.key_usage = KeyUsage(
|
||||
digital_signature=True,
|
||||
content_commitment=False,
|
||||
key_encipherment=False,
|
||||
data_encipherment=False,
|
||||
key_agreement=False,
|
||||
key_cert_sign=True,
|
||||
crl_sign=True,
|
||||
encipher_only=False,
|
||||
decipher_only=False
|
||||
)
|
||||
super().__init__("Certification Authority", 0, None)
|
||||
|
||||
def make_cert(self) -> (Certificate, RSAPrivateKey):
|
||||
"""Generate CA certificates"""
|
||||
ca_root, root_key = self.make_ca_cert("Trusted Root CA", "CAroot.pem")
|
||||
ca_cert, ca_key = self.make_ca_cert("Root CA", "CACert.pem")
|
||||
self.make_cross_cert(ca_root, root_key, ca_cert, ca_key)
|
||||
return ca_cert, ca_key
|
||||
|
||||
def make_ca_cert(self, common_name, file_name) -> None:
|
||||
"""Generate self-signed root CA certificate"""
|
||||
ca_key = generate_private_key(public_exponent=65537, key_size=2048)
|
||||
ca_public = ca_key.public_key()
|
||||
authority_key = AuthorityKeyIdentifier.from_issuer_public_key(ca_public)
|
||||
name = self.create_x509_name(common_name)
|
||||
ca_cert = (
|
||||
CertificateBuilder()
|
||||
.subject_name(name)
|
||||
.issuer_name(name)
|
||||
.public_key(ca_public)
|
||||
.serial_number(random_serial_number())
|
||||
.not_valid_before(date_20170101)
|
||||
.not_valid_after(date_20170101 + datetime.timedelta(days=7300))
|
||||
.add_extension(BasicConstraints(ca=True, path_length=None), critical=True)
|
||||
.add_extension(SubjectKeyIdentifier.from_public_key(ca_public), critical=False)
|
||||
.add_extension(authority_key, critical=False)
|
||||
.add_extension(self.key_usage, critical=True)
|
||||
.sign(ca_key, SHA256())
|
||||
)
|
||||
file_path=os.path.join(CERTS_PATH, file_name)
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(ca_cert.public_bytes(encoding=Encoding.PEM))
|
||||
return ca_cert, ca_key
|
||||
|
||||
def make_cross_cert(self, ca_root, root_key, ca_cert, ca_key) -> None:
|
||||
"""Generate cross-signed root CA certificate"""
|
||||
ca_public = ca_key.public_key()
|
||||
authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
|
||||
ca_root.extensions.get_extension_for_class(SubjectKeyIdentifier).value
|
||||
)
|
||||
ca_cross = (
|
||||
CertificateBuilder()
|
||||
.subject_name(ca_cert.subject)
|
||||
.issuer_name(ca_root.subject)
|
||||
.public_key(ca_public)
|
||||
.serial_number(ca_cert.serial_number)
|
||||
.not_valid_before(date_20180101)
|
||||
.not_valid_after(date_20180101 + datetime.timedelta(days=7300))
|
||||
.add_extension(BasicConstraints(ca=True, path_length=None), critical=True)
|
||||
.add_extension(SubjectKeyIdentifier.from_public_key(ca_public), critical=False)
|
||||
.add_extension(authority_key, critical=False)
|
||||
.add_extension(self.key_usage, critical=True)
|
||||
.sign(root_key, SHA256())
|
||||
)
|
||||
file_path=os.path.join(CERTS_PATH, "CAcross.pem")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(ca_cross.public_bytes(encoding=Encoding.PEM))
|
||||
|
||||
def write_key(self, key, file_name) -> None:
|
||||
"""Write a private RSA key"""
|
||||
# Write password
|
||||
file_path = os.path.join(CERTS_PATH, "password.txt")
|
||||
with open(file_path, mode="w", encoding="utf-8") as file:
|
||||
file.write("{}".format(PASSWORD))
|
||||
|
||||
# Write encrypted key in PEM format
|
||||
file_path = os.path.join(CERTS_PATH, file_name + "p.pem")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(key.private_bytes(
|
||||
encoding=Encoding.PEM,
|
||||
format=PrivateFormat.PKCS8,
|
||||
encryption_algorithm=BestAvailableEncryption(PASSWORD.encode())
|
||||
)
|
||||
)
|
||||
# Write decrypted key in PEM format
|
||||
file_path = os.path.join(CERTS_PATH, file_name + ".pem")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(key.private_bytes(
|
||||
encoding=Encoding.PEM,
|
||||
format=PrivateFormat.PKCS8,
|
||||
encryption_algorithm=NoEncryption()
|
||||
)
|
||||
)
|
||||
# Write the key in DER format
|
||||
file_path = os.path.join(CERTS_PATH, file_name + ".der")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(key.private_bytes(
|
||||
encoding=Encoding.DER,
|
||||
format=PrivateFormat.PKCS8,
|
||||
encryption_algorithm=NoEncryption()
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class TSARootCACertificate(X509Extensions):
|
||||
"""Base class for TSA certificates"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("Timestamp Authority Root CA", 0, None)
|
||||
|
||||
def make_cert(self) -> (Certificate, RSAPrivateKey):
|
||||
"""Generate a Time Stamp Authority certificate"""
|
||||
ca_key = generate_private_key(public_exponent=65537, key_size=2048)
|
||||
ca_public = ca_key.public_key()
|
||||
authority_key = AuthorityKeyIdentifier.from_issuer_public_key(ca_public)
|
||||
name = self.create_x509_name("TSA Root CA")
|
||||
key_usage = KeyUsage(
|
||||
digital_signature=False,
|
||||
content_commitment=False,
|
||||
key_encipherment=False,
|
||||
data_encipherment=False,
|
||||
key_agreement=False,
|
||||
key_cert_sign=True,
|
||||
crl_sign=True,
|
||||
encipher_only=False,
|
||||
decipher_only=False
|
||||
)
|
||||
ca_cert = (
|
||||
CertificateBuilder()
|
||||
.subject_name(name)
|
||||
.issuer_name(name)
|
||||
.public_key(ca_public)
|
||||
.serial_number(random_serial_number())
|
||||
.not_valid_before(date_20170101)
|
||||
.not_valid_after(date_20170101 + datetime.timedelta(days=7300))
|
||||
.add_extension(BasicConstraints(ca=True, path_length=None), critical=True)
|
||||
.add_extension(SubjectKeyIdentifier.from_public_key(ca_public), critical=False)
|
||||
.add_extension(authority_key, critical=False)
|
||||
.add_extension(key_usage, critical=True)
|
||||
.sign(ca_key, SHA256())
|
||||
)
|
||||
file_path=os.path.join(CERTS_PATH, "TSACA.pem")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(ca_cert.public_bytes(encoding=Encoding.PEM))
|
||||
|
||||
return ca_cert, ca_key
|
||||
|
||||
def write_key(self, key, file_name) -> None:
|
||||
"""Write decrypted private RSA key into PEM format"""
|
||||
file_path = os.path.join(CERTS_PATH, file_name + ".key")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(key.private_bytes(
|
||||
encoding=Encoding.PEM,
|
||||
format=PrivateFormat.PKCS8,
|
||||
encryption_algorithm=NoEncryption()
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class LeafCertificate(X509Extensions):
|
||||
"""Base class for a leaf certificate"""
|
||||
|
||||
def __init__(self, issuer_cert, issuer_key, unit_name, common_name, cdp_port, cdp_name):
|
||||
#pylint: disable=too-many-arguments
|
||||
self.issuer_cert = issuer_cert
|
||||
self.issuer_key = issuer_key
|
||||
self.common_name = common_name
|
||||
super().__init__(unit_name, cdp_port, cdp_name)
|
||||
|
||||
def make_cert(self, public_key, not_before, days) -> Certificate:
|
||||
"""Generate a leaf certificate"""
|
||||
authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
|
||||
self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
|
||||
)
|
||||
extended_key_usage = ExtendedKeyUsage(
|
||||
[ExtendedKeyUsageOID.CODE_SIGNING]
|
||||
)
|
||||
cert = (
|
||||
CertificateBuilder()
|
||||
.subject_name(self.create_x509_name(self.common_name))
|
||||
.issuer_name(self.issuer_cert.subject)
|
||||
.public_key(public_key)
|
||||
.serial_number(random_serial_number())
|
||||
.not_valid_before(not_before)
|
||||
.not_valid_after(not_before + datetime.timedelta(days=days))
|
||||
.add_extension(BasicConstraints(ca=False, path_length=None), critical=False)
|
||||
.add_extension(SubjectKeyIdentifier.from_public_key(public_key), critical=False)
|
||||
.add_extension(authority_key, critical=False)
|
||||
.add_extension(extended_key_usage, critical=False)
|
||||
.add_extension(self.create_x509_crldp(), critical=False)
|
||||
.sign(self.issuer_key, SHA256())
|
||||
)
|
||||
# Write PEM file and attach intermediate certificate
|
||||
file_path = os.path.join(CERTS_PATH, self.common_name + ".pem")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(cert.public_bytes(encoding=Encoding.PEM))
|
||||
file.write(self.issuer_cert.public_bytes(encoding=Encoding.PEM))
|
||||
|
||||
return cert
|
||||
|
||||
def revoke_cert(self, serial_number, file_name) -> None:
|
||||
"""Revoke a certificate"""
|
||||
revoked = (
|
||||
RevokedCertificateBuilder()
|
||||
.serial_number(serial_number)
|
||||
.revocation_date(date_20190101)
|
||||
.add_extension(CRLReason(ReasonFlags.superseded), critical=False)
|
||||
.build()
|
||||
)
|
||||
# Generate CRL
|
||||
authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
|
||||
self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
|
||||
)
|
||||
crl = (
|
||||
CertificateRevocationListBuilder()
|
||||
.issuer_name(self.issuer_cert.subject)
|
||||
.last_update(date_20190101)
|
||||
.next_update(date_20190101 + datetime.timedelta(days=7300))
|
||||
.add_extension(authority_key, critical=False)
|
||||
.add_extension(CRLNumber(4097), critical=False)
|
||||
.add_revoked_certificate(revoked)
|
||||
.sign(self.issuer_key, SHA256())
|
||||
)
|
||||
# Write CRL file
|
||||
file_path = os.path.join(CERTS_PATH, file_name + ".pem")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(crl.public_bytes(encoding=Encoding.PEM))
|
||||
|
||||
file_path = os.path.join(CERTS_PATH, file_name + ".der")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(crl.public_bytes(encoding=Encoding.DER))
|
||||
|
||||
|
||||
class LeafCACertificate(LeafCertificate):
|
||||
"""Base class for a leaf certificate"""
|
||||
|
||||
def __init__(self, issuer_cert, issuer_key, common, cdp_port):
|
||||
super().__init__(issuer_cert, issuer_key, "CSP", common, cdp_port, "intermediateCA")
|
||||
|
||||
|
||||
class LeafTSACertificate(LeafCertificate):
|
||||
"""Base class for a TSA leaf certificate"""
|
||||
|
||||
def __init__(self, issuer_cert, issuer_key, common, cdp_port):
|
||||
self.issuer_cert = issuer_cert
|
||||
self.issuer_key = issuer_key
|
||||
self.common_name = common
|
||||
super().__init__(issuer_cert, issuer_key, "Timestamp Root CA", common, cdp_port, "TSACA")
|
||||
|
||||
def make_cert(self, public_key, not_before, days) -> Certificate:
|
||||
"""Generate a TSA leaf certificate"""
|
||||
|
||||
authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
|
||||
self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
|
||||
)
|
||||
|
||||
# The TSA signing certificate must have exactly one extended key usage
|
||||
# assigned to it: timeStamping. The extended key usage must also be critical,
|
||||
# otherwise the certificate is going to be refused.
|
||||
extended_key_usage = ExtendedKeyUsage(
|
||||
[ExtendedKeyUsageOID.TIME_STAMPING]
|
||||
)
|
||||
cert = (
|
||||
CertificateBuilder()
|
||||
.subject_name(self.create_x509_name(self.common_name))
|
||||
.issuer_name(self.issuer_cert.subject)
|
||||
.public_key(public_key)
|
||||
.serial_number(random_serial_number())
|
||||
.not_valid_before(not_before)
|
||||
.not_valid_after(not_before + datetime.timedelta(days=days))
|
||||
.add_extension(BasicConstraints(ca=False, path_length=None), critical=True)
|
||||
.add_extension(SubjectKeyIdentifier.from_public_key(public_key), critical=False)
|
||||
.add_extension(authority_key, critical=False)
|
||||
.add_extension(extended_key_usage, critical=True)
|
||||
.add_extension(self.create_x509_crldp(), critical=False)
|
||||
.add_extension(self.create_x509_name_constraints(), critical=False)
|
||||
.sign(self.issuer_key, SHA256())
|
||||
)
|
||||
# Write PEM file and attach intermediate certificate
|
||||
file_path = os.path.join(CERTS_PATH, self.common_name + ".pem")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(cert.public_bytes(encoding=Encoding.PEM))
|
||||
file.write(self.issuer_cert.public_bytes(encoding=Encoding.PEM))
|
||||
|
||||
return cert
|
||||
|
||||
|
||||
class CertificateMaker():
|
||||
"""Base class for test certificates"""
|
||||
|
||||
def __init__(self, cdp_port, logs):
|
||||
self.cdp_port = cdp_port
|
||||
self.logs = logs
|
||||
|
||||
def make_certs(self) -> None:
|
||||
"""Make test certificates"""
|
||||
try:
|
||||
self.make_ca_certs()
|
||||
self.make_tsa_certs()
|
||||
logs = os.path.join(CERTS_PATH, "./cert.log")
|
||||
with open(logs, mode="w", encoding="utf-8") as file:
|
||||
file.write("Test certificates generation succeeded")
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
with open(self.logs, mode="a", encoding="utf-8") as file:
|
||||
file.write("Error: {}".format(err))
|
||||
|
||||
def make_ca_certs(self):
|
||||
"""Make test certificates"""
|
||||
|
||||
# Generate root CA certificate
|
||||
root = RootCACertificate()
|
||||
ca_cert, ca_key = root.make_cert()
|
||||
|
||||
# Generate intermediate root CA certificate
|
||||
intermediate = IntermediateCACertificate(ca_cert, ca_key)
|
||||
issuer_cert, issuer_key = intermediate.make_cert()
|
||||
|
||||
# Generate private RSA key
|
||||
private_key = generate_private_key(public_exponent=65537, key_size=2048)
|
||||
public_key = private_key.public_key()
|
||||
root.write_key(key=private_key, file_name="key")
|
||||
|
||||
# Generate expired certificate
|
||||
expired = LeafCACertificate(issuer_cert, issuer_key, "expired", self.cdp_port)
|
||||
expired.make_cert(public_key, date_20180101, 365)
|
||||
|
||||
# Generate revoked certificate
|
||||
revoked = LeafCACertificate(issuer_cert, issuer_key, "revoked", self.cdp_port)
|
||||
cert = revoked.make_cert(public_key, date_20180101, 5840)
|
||||
revoked.revoke_cert(cert.serial_number, "CACertCRL")
|
||||
|
||||
# Generate code signing certificate
|
||||
signer = LeafCACertificate(issuer_cert, issuer_key, "cert", self.cdp_port)
|
||||
cert = signer.make_cert(public_key, date_20180101, 5840)
|
||||
|
||||
# Write a certificate and a key into PKCS#12 container
|
||||
self.write_pkcs12_container(
|
||||
cert=cert,
|
||||
key=private_key,
|
||||
issuer=issuer_cert
|
||||
)
|
||||
|
||||
# Write DER file and attach intermediate certificate
|
||||
file_path = os.path.join(CERTS_PATH, "cert.der")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(cert.public_bytes(encoding=Encoding.DER))
|
||||
|
||||
def make_tsa_certs(self):
|
||||
"""Make test TSA certificates"""
|
||||
|
||||
# Time Stamp Authority certificate
|
||||
root = TSARootCACertificate()
|
||||
issuer_cert, issuer_key = root.make_cert()
|
||||
|
||||
# Generate private RSA key
|
||||
private_key = generate_private_key(public_exponent=65537, key_size=2048)
|
||||
public_key = private_key.public_key()
|
||||
root.write_key(key=private_key, file_name="TSA")
|
||||
|
||||
# Generate revoked TSA certificate
|
||||
revoked = LeafTSACertificate(issuer_cert, issuer_key, "TSA_revoked", self.cdp_port)
|
||||
cert = revoked.make_cert(public_key, date_20180101, 7300)
|
||||
revoked.revoke_cert(cert.serial_number, "TSACertCRL")
|
||||
|
||||
# Generate TSA certificate
|
||||
signer = LeafTSACertificate(issuer_cert, issuer_key, "TSA", self.cdp_port)
|
||||
cert = signer.make_cert(public_key, date_20180101, 7300)
|
||||
|
||||
# Save the chain to be included in the TSA response
|
||||
file_path = os.path.join(CERTS_PATH, "tsa-chain.pem")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(cert.public_bytes(encoding=Encoding.PEM))
|
||||
file.write(issuer_cert.public_bytes(encoding=Encoding.PEM))
|
||||
|
||||
|
||||
def write_pkcs12_container(self, cert, key, issuer) -> None:
|
||||
"""Write a certificate and a key into a PKCS#12 container"""
|
||||
|
||||
# Set an encryption algorithm
|
||||
if cryptography.__version__ >= "38.0.0":
|
||||
# For OpenSSL legacy mode use the default algorithm for certificate
|
||||
# and private key encryption: DES-EDE3-CBC (vel 3DES_CBC)
|
||||
# pylint: disable=no-member
|
||||
encryption = (
|
||||
PrivateFormat.PKCS12.encryption_builder()
|
||||
.key_cert_algorithm(PBES.PBESv1SHA1And3KeyTripleDESCBC)
|
||||
.kdf_rounds(5000)
|
||||
.build(PASSWORD.encode())
|
||||
)
|
||||
else:
|
||||
encryption = BestAvailableEncryption(PASSWORD.encode())
|
||||
|
||||
# Generate PKCS#12 struct
|
||||
pkcs12 = serialize_key_and_certificates(
|
||||
name=b'certificate',
|
||||
key=key,
|
||||
cert=cert,
|
||||
cas=(issuer,),
|
||||
encryption_algorithm=encryption
|
||||
)
|
||||
|
||||
# Write into a PKCS#12 container
|
||||
file_path = os.path.join(CERTS_PATH, "cert.p12")
|
||||
with open(file_path, mode="wb") as file:
|
||||
file.write(pkcs12)
|
||||
|
||||
|
||||
# pylint: disable=pointless-string-statement
|
||||
"""Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
"""
|
@ -1,56 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with the certificate and private key files in the PEM format.
|
||||
# -st 1556668800 is the Unix time of May 1 00:00:00 2019 GMT
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="011. Sign a PE file with the certificate and private key files in the PEM format"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_011.exe"
|
||||
verify_signature "$?" "011" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="012. Sign a CAB file with the certificate and private key files in the PEM format"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_012.ex_"
|
||||
verify_signature "$?" "012" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="013. Sign a MSI file with the certificate and private key files in the PEM format"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_013.msi"
|
||||
verify_signature "$?" "013" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,58 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with the encrypted private key file in the PEM format.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="021. Sign a PE file with the encrypted private key file in the PEM format"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/keyp.pem" \
|
||||
-pass passme \
|
||||
-in "test.exe" -out "test_021.exe"
|
||||
verify_signature "$?" "021" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="022. Sign a CAB file with the encrypted private key file in the PEM format"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/keyp.pem" \
|
||||
-pass passme \
|
||||
-in "test.ex_" -out "test_022.ex_"
|
||||
verify_signature "$?" "022" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="023. Sign a MSI file with the encrypted private key file in the PEM format"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/keyp.pem" \
|
||||
-pass passme \
|
||||
-in "sample.msi" -out "test_023.msi"
|
||||
verify_signature "$?" "023" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,59 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with the encrypted private key file in the DER format.
|
||||
# Requires OpenSSL 1.0.0 or later
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="031. Sign a PE file with the encrypted private key file in the DER format"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.der" \
|
||||
-pass passme \
|
||||
-in "test.exe" -out "test_031.exe"
|
||||
verify_signature "$?" "031" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="032. Sign a CAB file with the encrypted private key file in the DER format"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.der" \
|
||||
-pass passme \
|
||||
-in "test.ex_" -out "test_032.ex_"
|
||||
verify_signature "$?" "032" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="033. Sign a MSI file with the encrypted private key file in the DER format"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.der" \
|
||||
-pass passme \
|
||||
-in "sample.msi" -out "test_033.msi"
|
||||
verify_signature "$?" "033" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,59 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with the certificate file in the SPC format
|
||||
# and the private key file in the Microsoft Private Key (PVK) format.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="041. Sign a PE file a SPC certificate file and a PVK private key file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-spc "${script_path}/../certs/cert.spc" -key "${script_path}/../certs/key.pvk" \
|
||||
-pass passme \
|
||||
-in "test.exe" -out "test_041.exe"
|
||||
verify_signature "$?" "041" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="042. Sign a CAB file a SPC certificate file and a PVK private key file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-spc "${script_path}/../certs/cert.spc" -key "${script_path}/../certs/key.pvk" \
|
||||
-pass passme \
|
||||
-in "test.ex_" -out "test_042.ex_"
|
||||
verify_signature "$?" "042" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="043. Sign a MSI file a SPC certificate file and a PVK private key file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-spc "${script_path}/../certs/cert.spc" -key "${script_path}/../certs/key.pvk" \
|
||||
-pass passme \
|
||||
-in "sample.msi" -out "test_043.msi"
|
||||
verify_signature "$?" "043" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,57 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with the certificate and key stored in a PKCS#12 container.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="051. Sign a PE file with a certificate and key stored in a PKCS#12 container"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-pkcs12 "${script_path}/../certs/cert.p12" -pass passme \
|
||||
-in "test.exe" -out "test_051.exe"
|
||||
verify_signature "$?" "051" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="052. Sign a CAB file with a certificate and key stored in a PKCS#12 container"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-pkcs12 "${script_path}/../certs/cert.p12" \
|
||||
-pass passme \
|
||||
-in "test.ex_" -out "test_052.ex_"
|
||||
verify_signature "$?" "052" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="053. Sign a MSI file with a certificate and key stored in a PKCS#12 container"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-pkcs12 "${script_path}/../certs/cert.p12" \
|
||||
-pass passme \
|
||||
-in "sample.msi" -out "test_053.msi"
|
||||
verify_signature "$?" "053" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,54 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Checking SHA256 message digests for 01x-05x tests
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
res=0
|
||||
skip=0
|
||||
test_name="061. Checking SHA256 message digests for 01x-05x tests"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
if test $(cat "sha256sum_exe.log" | cut -d' ' -f1 | uniq | wc -l) -ne 1
|
||||
then
|
||||
res=1
|
||||
cat "sha256sum_exe.log" >> "results.log"
|
||||
printf "Non-unique SHA256 message digests found\n" >> "results.log"
|
||||
fi
|
||||
rm -f "sha256sum_exe.log"
|
||||
else
|
||||
skip=$(($skip+1))
|
||||
fi
|
||||
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
if test $(cat "sha256sum_ex_.log" | cut -d' ' -f1 | uniq | wc -l) -ne 1
|
||||
then
|
||||
res=1
|
||||
cat "sha256sum_ex_.log" >> "results.log"
|
||||
printf "Non-unique SHA256 message digests found\n" >> "results.log"
|
||||
fi
|
||||
rm -f "sha256sum_ex_.log"
|
||||
else
|
||||
skip=$(($skip+1))
|
||||
fi
|
||||
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
if test $(cat "sha256sum_msi.log" | cut -d' ' -f1 | uniq | wc -l) -ne 1
|
||||
then
|
||||
res=1
|
||||
cat "sha256sum_msi.log" >> "results.log"
|
||||
printf "Non-unique SHA256 message digests found\n" >> "results.log"
|
||||
fi
|
||||
rm -f "sha256sum_msi.log"
|
||||
else
|
||||
skip=$(($skip+1))
|
||||
fi
|
||||
|
||||
if test $skip -lt 3
|
||||
then
|
||||
test_result "$res" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
exit 0
|
@ -1,64 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with Authenticode timestamping
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="071. Sign a PE file with Authenticode timestamping"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-t http://time.certum.pl/ \
|
||||
-t http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test.exe" -out "test_071.exe" 2>> "results.log" 1>&2
|
||||
verify_signature "$?" "071" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="072. Sign a CAB file with Authenticode timestamping"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-t http://time.certum.pl/ \
|
||||
-t http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test.ex_" -out "test_072.ex_" 2>> "results.log" 1>&2
|
||||
verify_signature "$?" "072" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="073. Sign a MSI file with Authenticode timestamping"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-t http://time.certum.pl/ \
|
||||
-t http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "sample.msi" -out "test_073.msi"
|
||||
verify_signature "$?" "073" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,68 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with RFC 3161 timestamping
|
||||
# An RFC3161 timestamp server provides an essential function in protecting
|
||||
# data records for the long-term. It provides proof that the data existed
|
||||
# at a particular moment in time and that it has not changed, even by
|
||||
# a single binary bit, since it was notarized and time-stamped.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="081. Sign a PE file with RFC 3161 timestamping"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-ts http://time.certum.pl/ \
|
||||
-ts http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test.exe" -out "test_081.exe"
|
||||
verify_signature "$?" "081" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="082. Sign a CAB file with RFC 3161 timestamping"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-ts http://time.certum.pl/ \
|
||||
-ts http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test.ex_" -out "test_082.ex_"
|
||||
verify_signature "$?" "082" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="083. Sign a MSI file with RFC 3161 timestamping"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-ts http://time.certum.pl/ \
|
||||
-ts http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "sample.msi" -out "test_083.msi"
|
||||
verify_signature "$?" "083" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,29 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Generate page hashes for a PE file
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="091. Generate page hashes for a PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 -ph \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_091.exe"
|
||||
verify_signature "$?" "091" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
# Warning: -ph option is only valid for PE files
|
||||
|
||||
# MSI file
|
||||
# Warning: -ph option is only valid for PE files
|
||||
|
||||
exit 0
|
@ -1,58 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with addUnauthenticatedBlob.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="101. Sign a PE file with addUnauthenticatedBlob"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-addUnauthenticatedBlob \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_101.exe" 2>> "results.log" 1>&2
|
||||
verify_signature "$?" "101" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "BEGIN_BLOB" "MODIFY"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="102. Sign a CAB file with addUnauthenticatedBlob"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-addUnauthenticatedBlob \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_102.ex_" 2>> "results.log" 1>&2
|
||||
verify_signature "$?" "102" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "BEGIN_BLOB" "MODIFY"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="103. Sign a MSI file with addUnauthenticatedBlob"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-addUnauthenticatedBlob \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_103.msi" 2>> "results.log" 1>&2
|
||||
verify_signature "$?" "103" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "BEGIN_BLOB" "MODIFY"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,71 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file twice with the "nest" flag in the second time
|
||||
# in order to add the new signature instead of replacing the first one.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="111. Sign a PE file with the nest flag"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_111_signed.exe"
|
||||
../../osslsigncode sign -h sha512 \
|
||||
-nest \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test_111_signed.exe" -out "test_111.exe"
|
||||
verify_signature "$?" "111" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="112. Sign a CAB file with the nest flag"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_112_signed.ex_"
|
||||
../../osslsigncode sign -h sha512 \
|
||||
-nest \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test_112_signed.ex_" -out "test_112.ex_"
|
||||
verify_signature "$?" "112" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="113. Sign a MSI file with the nest flag"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_113_signed.msi"
|
||||
../../osslsigncode sign -h sha512 \
|
||||
-nest \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test_113_signed.msi" -out "test_113.msi"
|
||||
verify_signature "$?" "113" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,58 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with a PEM key file and a password read from password.txt file.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="121. Sign a PE file with the PEM key file and the file with a password"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-readpass "${script_path}/../certs/password.txt" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_121.exe"
|
||||
verify_signature "$?" "121" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="122. Sign a CAB file with a PEM key file and the file with a password"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-readpass "${script_path}/../certs/password.txt" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/keyp.pem" \
|
||||
-in "test.ex_" -out "test_122.ex_"
|
||||
verify_signature "$?" "122" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="123. Sign a MSI file with a PEM key file and the file with a password"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-readpass "${script_path}/../certs/password.txt" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/keyp.pem" \
|
||||
-in "sample.msi" -out "test_123.msi"
|
||||
verify_signature "$?" "123" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,59 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with the certificate and key stored in a PKCS#12 container
|
||||
# and a password read from password.txt file.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="131. Sign a PE file with a PKCS#12 container and the file with a password"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-readpass "${script_path}/../certs/password.txt" \
|
||||
-pkcs12 "${script_path}/../certs/cert.p12" \
|
||||
-in "test.exe" -out "test_131.exe"
|
||||
verify_signature "$?" "131" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="132. Sign a CAB file with a PKCS#12 container and the file with a password"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-readpass "${script_path}/../certs/password.txt" \
|
||||
-pkcs12 "${script_path}/../certs/cert.p12" \
|
||||
-in "test.ex_" -out "test_132.ex_"
|
||||
verify_signature "$?" "132" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="133. Sign a MSI file with a PKCS#12 container and the file with a password"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-readpass "${script_path}/../certs/password.txt" \
|
||||
-pkcs12 "${script_path}/../certs/cert.p12" \
|
||||
-in "sample.msi" -out "test_133.msi"
|
||||
verify_signature "$?" "133" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "osslsigncode" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,58 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with a descryption
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="141. Sign a PE file with a descryption"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-n "DESCRYPTION_TEXT" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_141.exe"
|
||||
verify_signature "$?" "141" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "DESCRYPTION_TEXT" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="142. Sign a CAB file with a descryption"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-n "DESCRYPTION_TEXT" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_142.ex_"
|
||||
verify_signature "$?" "142" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "DESCRYPTION_TEXT" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="143. Sign a MSI file with a descryption"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-n "DESCRYPTION_TEXT" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_143.msi"
|
||||
verify_signature "$?" "143" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "DESCRYPTION_TEXT" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,59 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with specified URL for expanded description of the signed content
|
||||
# https://docs.microsoft.com/en-us/windows-hardware/drivers/install/authenticode-signing-of-csps
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="151. Sign a PE file with specified URL"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-i "https://www.osslsigncode.com/" \
|
||||
-in "test.exe" -out "test_151.exe"
|
||||
verify_signature "$?" "151" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "https://www.osslsigncode.com/" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="152. Sign a CAB file with specified URL"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-i "https://www.osslsigncode.com/" \
|
||||
-in "test.ex_" -out "test_152.ex_"
|
||||
verify_signature "$?" "152" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "https://www.osslsigncode.com/" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="153. Sign a MSI file with specified URL"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-i "https://www.osslsigncode.com/" \
|
||||
-in "sample.msi" -out "test_153.msi"
|
||||
verify_signature "$?" "153" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "https://www.osslsigncode.com/" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,61 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE/CAB/MSI file with the commercial purpose set for SPC_STATEMENT_TYPE_OBJID
|
||||
# object ID numbers (OIDs) "1.3.6.1.4.1.311.2.1.11"
|
||||
# changes default Individual Code Signing: "0x30, 0x0c, x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x15"
|
||||
# sets Commercial Code Signing: "0x30, 0x0c, x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x16"
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="161. Sign a PE file with the common purpose set"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-comm \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_161.exe"
|
||||
verify_signature "$?" "161" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "HEX" "300c060a2b060104018237020116" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="162. Sign a CAB file with the common purpose set"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-comm \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_162.ex_"
|
||||
verify_signature "$?" "162" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "HEX" "300c060a2b060104018237020116" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="163. Sign a MSI file with the common purpose set"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-comm \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_163.msi"
|
||||
verify_signature "$?" "163" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "HEX" "300c060a2b060104018237020116" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,60 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Add an additional certificate to the signature block of the PE/CAB/MSI file.
|
||||
# https://docs.microsoft.com/en-us/windows-hardware/drivers/install/authenticode-signing-of-csps
|
||||
# https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-cross-certification
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="171. Add an additional certificate to the signature block of the PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-ac "${script_path}/../certs/crosscert.pem" \
|
||||
-in "test.exe" -out "test_171.exe"
|
||||
verify_signature "$?" "171" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "crosscert" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="172. Add an additional certificate to the signature block of the CAB file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-ac "${script_path}/../certs/crosscert.pem" \
|
||||
-in "test.ex_" -out "test_172.ex_"
|
||||
verify_signature "$?" "172" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "crosscert" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="173. Add an additional certificate to the signature block of the MSI file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-ac "${script_path}/../certs/crosscert.pem" \
|
||||
-in "sample.msi" -out "test_173.msi"
|
||||
verify_signature "$?" "173" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "crosscert" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE file with MD5 set of cryptographic hash functions.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="211. Sign a PE file with MD5 set of cryptographic hash functions"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h md5 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_211.exe"
|
||||
verify_signature "$?" "211" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "MD5" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
|
||||
# MSI file
|
||||
|
||||
exit 0
|
@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE file with SHA1 set of cryptographic hash functions.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="221. Sign a PE file with SHA1 set of cryptographic hash functions"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha1 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_221.exe"
|
||||
verify_signature "$?" "221" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "SHA1" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
|
||||
# MSI file
|
||||
|
||||
exit 0
|
@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Signing a PE file with SHA1 set of cryptographic hash functions.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="231. Signing a PE file with SHA1 set of cryptographic hash functions"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha2 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_231.exe"
|
||||
verify_signature "$?" "231" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "SHA2" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
|
||||
# MSI file
|
||||
|
||||
exit 0
|
@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE file with SHA384 set of cryptographic hash functions.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="241. Sign a PE file with SHA384 set of cryptographic hash functions"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha384 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_241.exe"
|
||||
verify_signature "$?" "241" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "SHA384" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
|
||||
# MSI file
|
||||
|
||||
exit 0
|
@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a PE file with SHA512 set of cryptographic hash functions.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="251. Sign a PE file with SHA512 set of cryptographic hash functions"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha512 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_251.exe"
|
||||
verify_signature "$?" "251" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
|
||||
# MSI file
|
||||
|
||||
exit 0
|
@ -1,61 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Extract the signature in the PEM format from the PE/CAB/MSI file.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="261. Extract the PEM signature from the PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha512 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_261.exe" && \
|
||||
../../osslsigncode extract-signature -pem \
|
||||
-in "test_261.exe" -out "sign_pe.pem"
|
||||
verify_signature "$?" "261" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="262. Extract the PEM signature from the CAB file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if [ -s "test.ex_" ]
|
||||
then
|
||||
../../osslsigncode sign -h sha512 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_262.ex_" && \
|
||||
../../osslsigncode extract-signature -pem \
|
||||
-in "test_262.ex_" -out "sign_cab.pem"
|
||||
verify_signature "$?" "262" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="263. Extract the PEM signature from the MSI file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha512 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_263.msi" && \
|
||||
../../osslsigncode extract-signature -pem \
|
||||
-in "test_263.msi" -out "sign_msi.pem"
|
||||
verify_signature "$?" "263" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,61 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Extract the signature in the DER format from the PE/CAB/MSI file.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="271. Extract the DER signature from the PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha512 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_271.exe" && \
|
||||
../../osslsigncode extract-signature \
|
||||
-in "test_271.exe" -out "sign_pe.der"
|
||||
verify_signature "$?" "271" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="272. Extract the DER signature from the CAB file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if [ -s "test.ex_" ]
|
||||
then
|
||||
../../osslsigncode sign -h sha512 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_272.ex_" && \
|
||||
../../osslsigncode extract-signature \
|
||||
-in "test_272.ex_" -out "sign_cab.der"
|
||||
verify_signature "$?" "272" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="273. Extract the DER signature from the MSI file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha512 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_273.msi" && \
|
||||
../../osslsigncode extract-signature \
|
||||
-in "test_273.msi" -out "sign_msi.der"
|
||||
verify_signature "$?" "273" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,58 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Attach the DER signature to the PE/CAB/MSI file.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="311. Attach the DER signature to the PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode attach-signature \
|
||||
-sigin "sign_pe.der" \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "test.exe" -out "test_311.exe"
|
||||
verify_signature "$?" "311" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="312. Attach the DER signature to the CAB file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if [ -s "test.ex_" ]
|
||||
then
|
||||
../../osslsigncode attach-signature \
|
||||
-sigin "sign_cab.der" \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "test.ex_" -out "test_312.ex_"
|
||||
verify_signature "$?" "312" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="313. Attach the DER signature to the MSI file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode attach-signature \
|
||||
-sigin "sign_msi.der" \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "sample.msi" -out "test_313.msi"
|
||||
verify_signature "$?" "313" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,58 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Attach the PEM signature to the PE/CAB/MSI file.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="321. Attach the PEM signature to the PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode attach-signature \
|
||||
-sigin "sign_pe.pem" \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "test.exe" -out "test_321.exe"
|
||||
verify_signature "$?" "321" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="322. Attach the PEM signature to the CAB file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if [ -s "test.ex_" ]
|
||||
then
|
||||
../../osslsigncode attach-signature \
|
||||
-sigin "sign_cab.pem" \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "test.ex_" -out "test_322.ex_"
|
||||
verify_signature "$?" "322" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="323. Attach the PEM signature to the MSI file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode attach-signature \
|
||||
-sigin "sign_msi.pem" \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "sample.msi" -out "test_323.msi"
|
||||
verify_signature "$?" "323" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,69 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Attach the signature to the signed PE/CAB/MSI file.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="331. Attach the signature to the signed PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_331_signed.exe"
|
||||
../../osslsigncode attach-signature \
|
||||
-sigin "sign_pe.pem" \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "test_331_signed.exe" -out "test_331.exe"
|
||||
verify_signature "$?" "331" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="332. Attach the signature to the signed CAB file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if [ -s "test.ex_" ]
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_332_signed.ex_"
|
||||
../../osslsigncode attach-signature \
|
||||
-sigin "sign_cab.pem" \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "test_332_signed.ex_" -out "test_332.ex_"
|
||||
verify_signature "$?" "332" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="333. Attach the signature to the signed MSI file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_333_signed.msi"
|
||||
../../osslsigncode attach-signature -sigin "sign_msi.pem" \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "test_333_signed.msi" -out "test_333.msi"
|
||||
verify_signature "$?" "333" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"sha256sum" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,74 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Attach the signature to the signed PE/CAB/MSI file with the "nest" flag
|
||||
# in order to attach the new signature instead of replacing the first one.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="341. Attach the signature to the signed PE file with the nest flag"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_341_signed.exe"
|
||||
../../osslsigncode attach-signature \
|
||||
-sigin "sign_pe.pem" \
|
||||
-nest \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "test_341_signed.exe" -out "test_341.exe"
|
||||
verify_signature "$?" "341" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="342. Attach the signature to the signed CAB file with the nest flag"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_342_signed.ex_"
|
||||
../../osslsigncode attach-signature \
|
||||
-sigin "sign_cab.pem" \
|
||||
-nest \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "test_342_signed.ex_" -out "test_342.ex_"
|
||||
verify_signature "$?" "342" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="343. Attach the signature to the signed MSI file with the nest flag"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_343_signed.msi"
|
||||
../../osslsigncode attach-signature \
|
||||
-sigin "sign_msi.pem" \
|
||||
-nest \
|
||||
-CAfile "${script_path}/../certs/CACert.pem" \
|
||||
-CRLfile "${script_path}/../certs/CACertCRL.pem" \
|
||||
-in "test_343_signed.msi" -out "test_343.msi"
|
||||
verify_signature "$?" "343" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "SHA512" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,61 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Remove the signature from the PE/CAB/MSI file.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="351. Remove the signature from the PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_351_signed.exe" && \
|
||||
../../osslsigncode remove-signature \
|
||||
-in "test_351_signed.exe" -out "test_351.exe"
|
||||
verify_signature "$?" "351" "exe" "fail" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="352. Remove the signature from the CAB file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if [ -s "test.ex_" ]
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_352_signed.ex_" && \
|
||||
../../osslsigncode remove-signature \
|
||||
-in "test_352_signed.ex_" -out "test_352.ex_"
|
||||
verify_signature "$?" "352" "ex_" "fail" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="353. Remove the signature from the MSI file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_353_signed.msi" && \
|
||||
../../osslsigncode remove-signature \
|
||||
-in "test_353_signed.msi" -out "test_353.msi"
|
||||
verify_signature "$?" "353" "msi" "fail" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,55 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Checking SHA256 message digests for 31x-33x tests.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
res=0
|
||||
res=0
|
||||
skip=0
|
||||
test_name="361. Checking SHA256 message digests for 31x-33x tests"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
if test $(cat "sha256sum_exe.log" | cut -d' ' -f1 | uniq | wc -l) -ne 1
|
||||
then
|
||||
res=1
|
||||
cat "sha256sum_exe.log" >> "results.log"
|
||||
printf "Non-unique SHA256 message digests found\n" >> "results.log"
|
||||
fi
|
||||
rm -f "sha256sum_exe.log"
|
||||
else
|
||||
skip=$(($skip+1))
|
||||
fi
|
||||
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
if test $(cat "sha256sum_ex_.log" | cut -d' ' -f1 | uniq | wc -l) -ne 1
|
||||
then
|
||||
res=1
|
||||
cat "sha256sum_ex_.log" >> "results.log"
|
||||
printf "Non-unique SHA256 message digests found\n" >> "results.log"
|
||||
fi
|
||||
rm -f "sha256sum_ex_.log"
|
||||
else
|
||||
skip=$(($skip+1))
|
||||
fi
|
||||
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
if test $(cat "sha256sum_msi.log" | cut -d' ' -f1 | uniq | wc -l) -ne 1
|
||||
then
|
||||
res=1
|
||||
cat "sha256sum_msi.log" >> "results.log"
|
||||
printf "Non-unique SHA256 message digests found\n" >> "results.log"
|
||||
fi
|
||||
rm -f "sha256sum_msi.log"
|
||||
else
|
||||
skip=$(($skip+1))
|
||||
fi
|
||||
|
||||
if test $skip -lt 2
|
||||
then
|
||||
test_result "$res" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
exit 0
|
@ -1,70 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Add an authenticode timestamp to the PE/CAB/MSI file.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="371. Add an authenticode timestamp to the PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_371_signed.exe" && \
|
||||
../../osslsigncode add \
|
||||
-t http://time.certum.pl/ \
|
||||
-t http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test_371_signed.exe" -out "test_371.exe"
|
||||
verify_signature "$?" "371" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="372. Add an authenticode timestamp to the CAB file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_372_signed.ex_" && \
|
||||
../../osslsigncode add \
|
||||
-t http://time.certum.pl/ \
|
||||
-t http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test_372_signed.ex_" -out "test_372.ex_"
|
||||
verify_signature "$?" "372" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="373. Add an authenticode timestamp to the MSI file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_373_signed.msi" && \
|
||||
../../osslsigncode add \
|
||||
-t http://time.certum.pl/ \
|
||||
-t http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test_373_signed.msi" -out "test_373.msi"
|
||||
verify_signature "$?" "373" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,70 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Add an RFC 3161 timestamp to signed PE/CAB/MSI file.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="381. Add RFC 3161 timestamp to signed PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_381_signed.exe"
|
||||
../../osslsigncode add \
|
||||
-ts http://time.certum.pl/ \
|
||||
-ts http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test_381_signed.exe" -out "test_381.exe"
|
||||
verify_signature "$?" "381" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="382. Add RFC 3161 timestamp to signed CAB file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_382_signed.ex_"
|
||||
../../osslsigncode add \
|
||||
-ts http://time.certum.pl/ \
|
||||
-ts http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test_382_signed.ex_" -out "test_382.ex_"
|
||||
verify_signature "$?" "382" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="383. Add RFC 3161 timestamp to signed MSI file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_383_signed.msi"
|
||||
../../osslsigncode add \
|
||||
-ts http://time.certum.pl/ \
|
||||
-ts http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test_383_signed.msi" -out "test_383.msi"
|
||||
verify_signature "$?" "383" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Timestamp Server Signature" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,64 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Add an unauthenticated blob to the PE/CAB/MSI file.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="391. Add an unauthenticated blob to the PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_391_signed.exe"
|
||||
../../osslsigncode add \
|
||||
-addUnauthenticatedBlob \
|
||||
-in "test_391_signed.exe" -out "test_391.exe"
|
||||
verify_signature "$?" "391" "exe" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "BEGIN_BLOB" "MODIFY"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="392. Add an unauthenticated blob to the CAB file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_392_signed.ex_"
|
||||
../../osslsigncode add \
|
||||
-addUnauthenticatedBlob \
|
||||
-in "test_392_signed.ex_" -out "test_392.ex_"
|
||||
verify_signature "$?" "392" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "BEGIN_BLOB" "MODIFY"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="393. Add an unauthenticated blob to the MSI file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_393_signed.msi"
|
||||
../../osslsigncode add \
|
||||
-addUnauthenticatedBlob \
|
||||
-in "test_393_signed.msi" -out "test_393.msi"
|
||||
verify_signature "$?" "393" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "BEGIN_BLOB" "MODIFY"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,52 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Compare the leaf certificate hash against specified SHA256 message digest for the PE/CAB/MSI file
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="401. Compare the leaf certificate hash against specified SHA256 message digest for the PE file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.der" \
|
||||
-in "test.exe" -out "test_401.exe"
|
||||
verify_leaf_hash "$?" "401" "exe" "@2019-05-01 00:00:00"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="402. Compare the leaf certificate hash against specified SHA256 message digest for the CAB file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.der" \
|
||||
-in "test.ex_" -out "test_402.ex_"
|
||||
verify_leaf_hash "$?" "402" "ex_" "@2019-05-01 00:00:00"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="403. Compare the leaf certificate hash against specified SHA256 message digest for the MSI file"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.der" \
|
||||
-in "sample.msi" -out "test_403.msi"
|
||||
verify_leaf_hash "$?" "403" "msi" "@2019-05-01 00:00:00"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,35 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a MSI file with the add-msi-dse option.
|
||||
# MsiDigitalSignatureEx (msi-dse) is an enhanced signature type that can be used
|
||||
# when signing MSI files. In addition to file content, it also hashes some file metadata,
|
||||
# specifically file names, file sizes, creation times and modification times.
|
||||
# https://www.unboundtech.com/docs/UKC/UKC_Code_Signing_IG/HTML/Content/Products/UKC-EKM/UKC_Code_Signing_IG/Sign_Windows_PE_and_msi_Files.htm
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
# Warning: -add-msi-dse option is only valid for MSI files
|
||||
|
||||
# CAB file
|
||||
# Warning: -add-msi-dse option is only valid for MSI files
|
||||
|
||||
# MSI file
|
||||
test_name="411. Sign a MSI file with the add-msi-dse option"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-add-msi-dse \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/keyp.pem" \
|
||||
-pass passme \
|
||||
-in "sample.msi" -out "test_411.msi"
|
||||
verify_signature "$?" "411" "msi" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "HEX" "MsiDigitalSignatureEx" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,31 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Sign a CAB file with "jp low" option
|
||||
# https://support.microsoft.com/en-us/help/193877
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
# Warning: -jp option is only valid for CAB files
|
||||
|
||||
# CAB file
|
||||
test_name="421. Sign a CAB file with jp low option"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-jp low \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_421.ex_"
|
||||
verify_signature "$?" "421" "ex_" "success" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "HEX" "3006030200013000" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
# Warning: -jp option is only valid for CAB files
|
||||
|
||||
exit 0
|
@ -1,30 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Verify changed PE file after signing.
|
||||
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="451. Verify changed PE file after signing"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_451.exe"
|
||||
verify_signature "$?" "451" "exe" "fail" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Hello world!" "MODIFY"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
# Command is not supported for non-PE files
|
||||
|
||||
# MSI file
|
||||
# Command is not supported for non-PE files
|
||||
|
||||
exit 0
|
@ -1,33 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Verify changed PE file after signing with Authenticode timestamping.
|
||||
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="461. Verify changed PE file after signing with Authenticode timestamping"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-t http://time.certum.pl/ \
|
||||
-t http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test.exe" -out "test_461.exe"
|
||||
verify_signature "$?" "461" "exe" "fail" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Hello world!" "MODIFY"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
# Command is not supported for non-PE files
|
||||
|
||||
# MSI file
|
||||
# Command is not supported for non-PE files
|
||||
|
||||
exit 0
|
@ -1,34 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Verify changed PE file after signing with RFC 3161 timestamping.
|
||||
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
script_path=$(pwd)
|
||||
|
||||
# PE file
|
||||
test_name="471. Verify changed PE file after signing with RFC 3161 timestamping"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-st "1556668800" \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-ts http://time.certum.pl/ \
|
||||
-ts http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test.exe" -out "test_471.exe"
|
||||
verify_signature "$?" "471" "exe" "fail" "@2019-09-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "ASCII" "Hello world!" "MODIFY"
|
||||
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
# Command is not supported for non-PE files
|
||||
|
||||
# MSI file
|
||||
# Command is not supported for non-PE files
|
||||
|
||||
exit 0
|
@ -1,57 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Verify PE/CAB/MSI file signature after the cert has been expired.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
|
||||
# PE file
|
||||
test_name="511. Verify PE file signature after the cert has been expired"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe"
|
||||
then
|
||||
TZ=GMT faketime -f '@2019-05-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.exe" -out "test_511.exe" 2>> "results.log" 1>&2'
|
||||
verify_signature "$?" "511" "exe" "fail" "@2025-01-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="512. Verify CAB file signature after the cert has been expired"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_"
|
||||
then
|
||||
TZ=GMT faketime -f '@2019-05-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "test.ex_" -out "test_512.ex_" 2>> "results.log" 1>&2'
|
||||
verify_signature "$?" "512" "ex_" "fail" "@2025-01-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="513. Verify MSI file signature after the cert has been expired"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi"
|
||||
then
|
||||
TZ=GMT faketime -f '@2019-05-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-in "sample.msi" -out "test_513.msi"'
|
||||
verify_signature "$?" "513" "msi" "fail" "@2025-01-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,66 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Verify PE/CAB/MSI file signature with Authenticode timestamping after the cert has been expired.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
|
||||
# PE file
|
||||
test_name="521. Verify PE file signature with timestamping after the cert has been expired"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
TZ=GMT faketime -f '@2019-05-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-t http://time.certum.pl/ \
|
||||
-t http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test.exe" -out "test_521.exe" 2>> "results.log" 1>&2'
|
||||
verify_signature "$?" "521" "exe" "success" "@2025-01-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="522. Verify CAB file signature with timestamping after the cert has been expired"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
TZ=GMT faketime -f '@2019-05-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-t http://time.certum.pl/ \
|
||||
-t http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test.ex_" -out "test_522.ex_" 2>> "results.log" 1>&2'
|
||||
verify_signature "$?" "522" "ex_" "success" "@2025-01-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="523. Verify MSI file signature with timestamping after the cert has been expired"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
TZ=GMT faketime -f '@2019-05-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-t http://time.certum.pl/ \
|
||||
-t http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "sample.msi" -out "test_523.msi"'
|
||||
verify_signature "$?" "523" "msi" "success" "@2025-01-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
@ -1,66 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Verify PE/CAB/MSI file signature with RFC3161 timestamping after the cert has been expired.
|
||||
|
||||
. $(dirname $0)/../test_library
|
||||
|
||||
# PE file
|
||||
test_name="531. Verify PE file signature with RFC3161 after the cert has been expired"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.exe" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
TZ=GMT faketime -f '@2019-05-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-ts http://time.certum.pl/ \
|
||||
-ts http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test.exe" -out "test_531.exe" 2>> "results.log" 1>&2'
|
||||
verify_signature "$?" "531" "exe" "success" "@2025-01-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# CAB file
|
||||
test_name="532. Verify CAB file signature with RFC3161 after the cert has been expired"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "test.ex_" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
TZ=GMT faketime -f '@2019-05-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-ts http://time.certum.pl/ \
|
||||
-ts http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "test.ex_" -out "test_532.ex_" 2>> "results.log" 1>&2'
|
||||
verify_signature "$?" "532" "ex_" "success" "@2025-01-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
# MSI file
|
||||
test_name="533. Verify MSI file signature with RFC3161 after the cert has been expired"
|
||||
printf "\n%s\n" "$test_name"
|
||||
if test -s "sample.msi" && ! grep -q "no libcurl available" "results.log"
|
||||
then
|
||||
TZ=GMT faketime -f '@2019-05-01 00:00:00' /bin/bash -c '
|
||||
script_path=$(pwd)
|
||||
../../osslsigncode sign -h sha256 \
|
||||
-certs "${script_path}/../certs/cert.pem" -key "${script_path}/../certs/key.pem" \
|
||||
-ts http://time.certum.pl/ \
|
||||
-ts http://timestamp.digicert.com/ \
|
||||
-verbose \
|
||||
-in "sample.msi" -out "test_533.msi"'
|
||||
verify_signature "$?" "533" "msi" "success" "@2025-01-01 12:00:00" \
|
||||
"UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN" "UNUSED_PATTERN"
|
||||
test_result "$?" "$test_name"
|
||||
else
|
||||
printf "Test skipped\n"
|
||||
fi
|
||||
|
||||
exit 0
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user