Compare commits

...

434 Commits
2.1 ... master

Author SHA1 Message Date
olszomal
4568c890cc Fixed resource leaks, CID 1639164, 1639165, 1639167, 1639168, 1639169 2025-03-31 13:19:35 +02:00
olszomal
4bd167a8be Fixed directly dereferencing parameter p7, CID 1576008 2025-03-31 13:19:35 +02:00
olszomal
e7405fa839 Simplify error handling in PKCS#7 certificate loading, CID 1639170 2025-03-31 13:19:35 +02:00
olszomal
776e2ec7b6 Fix memory management for ministream and difat in MSI output, CID 1639166 2025-03-31 13:19:35 +02:00
olszomal
838aaaee8d libp11 PKCS#11 provider support 2025-03-28 14:05:12 +01:00
olszomal
e8f19a6efe Added verbose output for digest encryption algorithm and signature during verification 2024-12-31 13:53:46 +01:00
olszomal
3a8e25e5bb Added support for multiple OID types in signer info attribute 2024-12-17 17:27:50 +01:00
olszomal
7d1b460dfe Style updates 2024-12-06 22:19:00 +01:00
olszomal
bc3e9e2172 Disable environment updates for Python setup 2024-12-06 22:19:00 +01:00
olszomal
21bce757ef Remove specific CMake version setup for macOS 2024-12-06 22:19:00 +01:00
olszomal
6a43f62835 Remove Python3_EXECUTABLE 2024-12-06 22:19:00 +01:00
olszomal
8780e6f8e4 Fixed pip install 2024-12-06 22:19:00 +01:00
olszomal
78a23caa54 Retain needrestart package in Linux dependency installation 2024-12-06 22:19:00 +01:00
olszomal
d92927aff4 Switch to venv on Linux 2024-12-06 22:19:00 +01:00
olszomal
4f412b5989 Removed VIRTUAL_ENV 2024-12-06 22:19:00 +01:00
olszomal
e6f3ff631d Switch to venv on Windows 2024-12-06 22:19:00 +01:00
olszomal
09135aabb8 Check Python and cryptography version in Windows CI workflow 2024-12-06 22:19:00 +01:00
olszomal
de983e680f Configured macOS environment for arm64 architecture 2024-12-06 22:19:00 +01:00
Michał Trojnara
dc827b94e5 Switch to venv on macOS 2024-12-06 22:19:00 +01:00
olszomal
40ce811701 Fixed conditional compilation for CURL and proxy support 2024-10-25 17:48:01 +02:00
Małgorzata Olszówka
db5b4c4dc0
Add the "-engineCtrl" option to control hardware and CNG engines (#405)
Documentation updated for CNG engine 1.1 compatibility.
2024-09-08 19:23:38 +02:00
olszomal
4ee429792d Refactor imports to use explicit submodule imports and organize class/function imports 2024-09-06 11:58:28 +02:00
Michał Trojnara
27686c0b0c Missing part of 4dd836bab1832b8a87331f2e73356cda4f01e998 2024-09-05 11:43:25 +02:00
olszomal
21133f9c3b Added the '-blobFile' option to specify a file containing the blob content 2024-09-04 17:51:35 +02:00
Petr Vaněk
64305d6415 tests: add import for python-cryptography >= 43.0.0
write_pkcs12_container method raises following error message with
python-cryptography-43.0.0:

  Error: module 'cryptography.hazmat.primitives.serialization' has no attribute 'pkcs12'

Explicit import of the pkcs12 module resolves the issue.
2024-09-02 13:05:55 +02:00
Michał Trojnara
4dd836bab1 Initial 2.10-dev commit 2024-06-29 21:58:55 +02:00
Michał Trojnara
f57c213207 Use the installed version of Python 2024-06-29 20:52:55 +02:00
Michał Trojnara
76ee550c9d Release 2.9
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2024-06-29 20:16:47 +02:00
olszomal
2b3228d549 Changed error output to stderr instead of stdout 2024-06-05 16:54:21 +02:00
Michał Trojnara
bad6e96e0f Not only include Code Signing certificates 2024-06-04 13:25:51 +02:00
olszomal
3c8c74a8c3 Handled memory reallocation error 2024-06-03 14:16:39 +02:00
olszomal
771014a41e Fixed uint32_t overflow when attaching a new MSI sector 2024-06-03 14:16:39 +02:00
olszomal
476168e09e Added the "-ignore-crl" option to disable CRL online verification 2024-06-03 12:16:02 +02:00
olszomal
be4f010535 Fixed to get CAT content value 2024-06-03 08:44:02 +02:00
Michał Trojnara
2c27e2e37d Fix Ubuntu 24.04 build 2024-06-02 00:07:37 +02:00
Michał Trojnara
b829e7a802 Fix macos build with GitHub Actions 2024-05-31 20:52:03 +02:00
olszomal
d0ae214cb4 Verified number of MSI sectors 2024-05-31 16:47:31 +02:00
olszomal
9b1a6c9fb8 Failed to get CAT content 2024-05-31 16:47:31 +02:00
olszomal
41b662a8fe Checked cFolders value 2024-05-31 16:47:31 +02:00
olszomal
5232734071 Fix fuzzer error - failed to sort central directory entry 2024-05-29 14:22:26 +02:00
olszomal
996cf20fa9 Fixed msi dirent memory leak 2024-05-29 14:22:26 +02:00
Brad Hughes
825c9dad7c Add '-login' option to force a login to PKCS11 engines 2024-05-22 19:06:06 +02:00
Małgorzata Olszówka
6e5bef14e9
Rewrite making test certificates (#393)
Also updates obsolete curl dependencies with zlib.
2024-05-22 18:59:53 +02:00
Michał Trojnara
a53bd2bdb3 Diagnostic formatting improvements 2024-04-18 09:49:55 +02:00
Michał Trojnara
e4d471b885 Code signing CA certificates
Based on:
https://learn.microsoft.com/en-us/security/trusted-root/participants-list
2024-04-16 16:50:25 +02:00
Michał Trojnara
bcb9737dda Remove the "openssl version" step from CI
We will likely link a different version of OpenSSL anyway,
so printing the version of the first OpenSSL command-line
executable on the PATH only adds to confusion.
2024-04-15 19:34:50 +02:00
olszomal
7a5389b719 Fixed cmake test cURL support 2024-04-10 17:09:01 +02:00
olszomal
d9f0a8dade Fixed missing Crypt32.lib when linking openssl statically 2024-04-10 17:09:01 +02:00
olszomal
aa8c8dd720 Type casting of the read() return value 2024-04-10 17:09:01 +02:00
olszomal
16c5e5aa4a Squashed logically dead code for curl response code for openssl version 3.0.0 and later, CID 1585046 2024-04-10 17:09:01 +02:00
Michał Trojnara
ded1f7aa67
Use native HTTP client with OpenSSL 3.0 or later (#378)
Co-authored-by: olszomal <Malgorzata.Olszowka@stunnel.org>
2024-04-09 19:33:31 +02:00
Steve McIntyre
6ad2679f17 Read the password from stdin if desired
Use the common convention: "-" means to use stdin

Signed-off-by: Steve McIntyre <steve.mcintyre@pexip.com>
2024-03-28 21:33:01 +01:00
olszomal
4776f43f04 Improved manual 2024-03-26 18:28:02 +01:00
olszomal
d9db038c65 Sort central directory entries in ascending order by offset 2024-03-20 11:19:46 +01:00
Michał Trojnara
e8ef027776 Simplify base64 decoding in script.c 2024-03-11 12:10:20 +01:00
olszomal
0a0761746f Fixed memory corruption 2024-03-08 16:59:34 +01:00
olszomal
f51e2a4869 Intercepted X509_V_FLAG_CHECK_SS_SIGNATURE verify error 2024-03-08 16:59:34 +01:00
olszomal
093ed12c66 Supported CRL decoding in DER and PEM format 2024-03-08 16:59:34 +01:00
olszomal
71a046a2d0 Ignore missing PKCS#9 signing time field (NID_pkcs9_signingTime: 1.2.840.113549.1.9.5) in the CMS_ContentInfo structure.
Timestamping time for verification is get from embedded content in this CMS_ContentInfo structure.
2024-03-08 16:59:34 +01:00
olszomal
c73f82b558 Set the NONCE field in a TSA request 2024-03-08 16:59:34 +01:00
Michał Trojnara
b294f5d18f Initial 2.9-dev commit 2024-03-05 16:34:32 +01:00
Michał Trojnara
e07bb7d6b2 Update workflow components 2024-03-05 15:51:29 +01:00
Michał Trojnara
699bc85d0a Release 2.8
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2024-03-03 23:32:15 +01:00
olszomal
192e7a732b Fixed memory leaks 2024-03-01 17:50:20 +01:00
olszomal
656051676f Changelog update 2024-02-29 17:57:22 +01:00
olszomal
3998bcabb2 Simplify BIO chain free up and FILE_FORMAT_CTX cleanup 2024-02-28 15:55:25 +01:00
olszomal
fa40c57f80 Simplify checking whether a signature exists 2024-02-28 11:55:21 +01:00
olszomal
0b93a94ffa Fixed cross-signed root CA certificate 2024-02-28 11:52:49 +01:00
olszomal
105fd3af4a Fix handling of printf format specifiers 2024-02-27 10:47:58 +01:00
Michał Trojnara
86a594b087 NEWS.md entry for Microsoft PowerShell signing
Closes #37
2024-02-22 16:39:57 +01:00
olszomal
1dea73b038 Install python@3.8 on macOS required for the Github Actions CI 2024-02-22 16:14:35 +01:00
olszomal
b661ed08ed Fix fuzzer error - corrupted data content 2024-02-20 17:48:55 +01:00
olszomal
ead0584611 Disable curl dependence 2024-02-20 17:48:31 +01:00
Michał Trojnara
bd7751147e Update Windows build documentation 2024-02-20 10:03:47 +01:00
olszomal
1bc7fc36b8 Connect to CRL Distribution Points through the configured proxy when verifying 2024-02-19 12:19:44 +01:00
Zeijlon (ThinLinc Team)
42e9733916
Fix python 3 compatibility in server_http.py (#350)
Building osslsigncode fails on systems with older versions of Python 3 due to the server_http.py script, part of the test procedure. This script requires the ThreadingHTTPServer module, introduced in Python version 3.7.

A workaround has been implemented to create a ThreadingHTTPServer locally, ensuring backward compatibility with older Python versions.
2024-02-16 12:39:48 +01:00
olszomal
b2024cee9d Add -ignore-cdp option to help 2024-02-16 12:30:29 +01:00
olszomal
9d152b8477 Fix url resource leak, CID 1583652, 1583653 2024-02-16 12:30:29 +01:00
olszomal
7a02d51a83 Print failed certificate chain retrieved from the signature 2024-02-15 13:07:02 +01:00
olszomal
dac68a3a4d Disable CRL Distribution Points online verification 2024-02-15 12:30:50 +01:00
Michał Trojnara
bd1ab77f44 Improve variable names and comments
No functional change intended.
2024-02-13 17:39:01 +01:00
olszomal
5ee859db2c Fixed out-of-bounds access, CID 1583604 2024-02-13 17:20:29 +01:00
olszomal
ee3c51f6d5 Check BIO_write_ex() return value, CID 1583605 2024-02-13 17:20:29 +01:00
Michał Trojnara
cedb8b5798 Print default -CAfile in "osslsigncode -v"
Fix #344
2024-02-12 12:31:57 +01:00
olszomal
dcf58a00e7 Fixed getting content 2024-02-12 11:41:08 +01:00
Michał Trojnara
4576895718 Initial script (text) format support
See #37 for details.
2024-02-12 10:54:18 +01:00
olszomal
1bdcad619e Remove http proxy configuration that may change behavior 2024-02-07 13:38:01 +01:00
olszomal
31b046cf98 Fix dereference after null check, CID 1576008 2024-01-24 09:23:55 +01:00
olszomal
f3ac2c0c6f Fix resource leak, CID 1576007 2024-01-24 09:23:55 +01:00
olszomal
f22c83514c Simplify obtaining an existing signature and creating a new one 2024-01-23 19:00:22 +01:00
olszomal
44ca1f38e6 PKCS9_SEQUENCE_NUMBER authenticated attribute support 2024-01-23 19:00:22 +01:00
olszomal
0985c47990 Add a new "-index" option to enable verification or addition of attributes to the signature at a certain position 2024-01-23 19:00:22 +01:00
olszomal
aa158e40ec Fix BIO memory leak 2024-01-10 16:03:08 +01:00
olszomal
5da62de5ef Fixed adding signing time 2024-01-08 11:48:10 +01:00
Michał Trojnara
4d08fbb2c1 Only use IPv4 127.0.0.1 for tests
Fix #331
2023-12-21 11:33:48 +01:00
Michał Trojnara
98b004edda Ignore garbage in PE sigpos/siglen 2023-12-20 11:26:50 +01:00
olszomal
34bf3bc525 tests for extract-data command 2023-12-19 13:07:19 +01:00
olszomal
64e1bba96b Add a new command extract-data to extract a PKCS#7 data content to be signed 2023-12-19 13:07:19 +01:00
olszomal
46bcaa9d88 Skip a null stream warning 2023-12-18 10:14:51 +01:00
olszomal
867e0d446d Fixed APPX file specific: attach-signature command 2023-12-18 10:14:29 +01:00
olszomal
7285778cb0 Use X509_LOOKUP_load_file() to load certificates with a lookup using the implementation X509_LOOKUP_file() 2023-12-03 18:33:50 +01:00
olszomal
c909ba82d7 tests: fixed string formatting in Python version earlier than 2.6 2023-11-22 17:53:50 +01:00
olszomal
7b60d6447d tests: initialize resp_data 2023-11-22 17:53:50 +01:00
olszomal
588a1a0b5f Use default certificates when the HTTP server fails 2023-11-22 17:53:50 +01:00
olszomal
8a9b275494 Fixed unmap_file() segmentation fault 2023-11-21 10:54:44 +01:00
olszomal
0db17be606 Listing each member of the CAT file 2023-11-20 17:20:03 +01:00
olszomal
f9ad19d4a2 Signature index presentation 2023-11-14 10:33:04 +01:00
olszomal
b9ca24d423 Check MsiDigitalSignatureEx 2023-11-14 10:33:04 +01:00
olszomal
8d2b562244 Group warnings for CAT files 2023-11-14 10:33:04 +01:00
olszomal
6f4e9ab597 Fix dereference after null check, CID 1570976 2023-11-14 10:33:04 +01:00
olszomal
6d6270094e Simplify unlinking outfile 2023-11-13 13:50:41 +01:00
olszomal
57563716d1 Enable x mode modifier if available 2023-11-13 13:50:41 +01:00
olszomal
8ab8a133f7 Overwriting an existing file is not supported 2023-11-13 13:50:41 +01:00
olszomal
ef5047038e Delete the output file in case of error 2023-11-13 13:50:41 +01:00
olszomal
e290e03341 tests: Add more tests for catalog files. 2023-11-07 14:56:48 +01:00
olszomal
900ffed596 Enable verification that a catalog file was signed by a valid certificate.
Simplify setting and signing a content blob.
Clean up a support library.
2023-11-07 14:56:48 +01:00
Michał Trojnara
33253afb5e Remove unneeded variables 2023-10-17 17:10:28 +02:00
Michał Trojnara
3aba55e5e0 Code simplification 2023-10-17 16:58:57 +02:00
olszomal
898a53b2a7 Create a certificate chain sorted in ascending order by DER encoding 2023-10-17 16:21:26 +02:00
Joe Tylka
75ce1dadf5 Add missing dependencies for install in fresh ubuntu 2023-10-10 16:19:42 +02:00
Michał Trojnara
4166476030 Initial Dockerfile 2023-10-09 17:24:22 +02:00
olszomal
a5690f2d19 Fixed resource leak, CID 1566947, 1566965, 1566967, 1568542, 1568543 2023-10-09 17:21:16 +02:00
olszomal
cdb75578e9 fixed windows segmentation fault 2023-10-06 19:41:43 +02:00
olszomal
e2ab4a152d improved verify callbacks 2023-10-06 19:41:31 +02:00
Michał Trojnara
b8e690f3bd Work around a GitHub Actions regression 2023-10-06 19:08:50 +02:00
olszomal
c89d6b43aa description of built-in TSA options 2023-09-25 15:22:11 +02:00
Michał Trojnara
9faed39931 Add builtin-baseline 2023-09-20 16:25:30 +02:00
Michał Trojnara
ecb17709fc Initial 2.8-dev commit 2023-09-19 22:03:02 +02:00
Michał Trojnara
9ebd79ad18 Release 2.7
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2023-09-19 21:51:05 +02:00
Michał Trojnara
1700455533
APPX support (#303)
Co-authored-by: Maciej Panek <Maciej.panek@punxworks.com>
Co-authored-by: olszomal <Malgorzata.Olszowka@stunnel.org>
2023-09-19 21:23:32 +02:00
Michał Trojnara
a6f767f5a3 Mark the result as not tainted 2023-09-08 14:09:53 +02:00
olszomal
4c5b329bc4 fixed mixed declarations and code 2023-09-08 11:51:20 +02:00
olszomal
5626482e82 fixed a function declaration with a void parameter 2023-09-08 11:51:20 +02:00
olszomal
2d21a2121c squash gcc debugger warnings
remove nsections>UINT16_MAX check
2023-09-08 11:51:20 +02:00
Michał Trojnara
5d2bf2c80f Fix insufficient MSI_ENTRY comparison 2023-09-04 16:10:25 +02:00
Michael Brown
5b8376ce32 Fix construction of signed CAB header
Commit 0f51a06 ("Separate common and format-dependent functions")
performed a substantial amount of refactoring.  Within the CFFOLDER
header construction loop in cab_add_header(), the line

   tmp = GET_UINT32_LE(indata + i);

seems to have been accidentally deleted, instead of being refactored
to become

   tmp = GET_UINT32_LE(ctx->options->indata + i);

with the result that adding a signature to a .cab file will currently
produce an invalid .cab file.

Fix by adding back in the missing line of code.

Signed-off-by: Michael Brown <mbrown@fensystems.co.uk>
2023-08-31 12:27:01 +02:00
Michał Trojnara
1fc2c937f2 Secrets are not available in PRs 2023-08-25 09:49:10 +02:00
olszomal
2ed54490a6 Use TS_TST_INFO struct 2023-07-31 17:46:01 +02:00
olszomal
a096aa8a33 Set signing digest to generate RFC3161 response 2023-07-31 17:46:01 +02:00
olszomal
aa08566a63 Use TS_REQ struct 2023-07-31 17:46:01 +02:00
Małgorzata Olszówka (she/her)
c04b229ce2
Built-in TSA response generation (#281) 2023-07-28 16:03:04 +02:00
Michał Trojnara
adcfd9a33f Apply suggestions from code review
Added more detailed error messages.
Fixed formatting and indentation.

Co-authored-by: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
2023-07-21 11:44:55 +02:00
Maxim Bagryantsev
f2f3a8891c Fixed validation of supported command 2023-07-21 11:44:55 +02:00
olszomal
29eedf9059 Fixed DIFAT sectors writing 2023-06-30 11:30:02 +02:00
fanquake
d6f94d71f7 doc: correct minimum CMake version in README.md
It's 3.17, not 3.6.
2023-06-01 19:43:42 +02:00
Michał Trojnara
a509a66c65 Initial 2.7-dev commit 2023-05-30 17:23:46 +02:00
Michał Trojnara
7bf4c92d83 Fixed CI version 2023-05-29 23:25:42 +02:00
Michał Trojnara
0a0fdfe96a Release 2.6
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2023-05-29 23:10:39 +02:00
olszomal
199f2b4586 Check X509_ATTRIBUTE_get0_data() return value 2023-05-26 15:07:03 +02:00
olszomal
a92c4a5522 Do not return corrupted CMS_ContentInfo 2023-05-26 15:07:03 +02:00
olszomal
dc44ed5f5b Fix CFFOLDER hashing 2023-05-26 15:07:03 +02:00
olszomal
c6990878c2 Check the length of the attribute certificate entry 2023-05-25 15:45:52 +02:00
olszomal
abbbfabdc7 Move some functions from common to main code 2023-05-23 19:07:00 +02:00
olszomal
2a4b75842a Add connection logging 2023-05-23 19:07:00 +02:00
yjh-styx
56e7a72e8a
Fix timestamping nested signatures (#266) 2023-05-14 22:32:56 +02:00
Max Bagryantsev
b61bcaac2e
Added DIFAT sectors support (#265) 2023-05-14 20:33:57 +02:00
olszomal
924af9e783 Remove duplicated CURLcode error code 2023-05-09 21:14:19 +02:00
olszomal
cb80c7d188 Initialize indata variable 2023-05-09 21:14:19 +02:00
olszomal
76bb06bf7e Squash unused parameter warning 2023-05-09 21:14:19 +02:00
olszomal
4b6027a4f7 Fix CURLINFO_RESPONSE_CODE 2023-05-09 21:14:19 +02:00
olszomal
de6a65cc67 Fix github workflows 2023-05-09 21:14:19 +02:00
olszomal
c90166ba8d Fix cTest script 2023-05-09 21:14:19 +02:00
olszomal
b00ceee310 Tests: add port argument to python HTTP server 2023-05-09 21:14:19 +02:00
olszomal
54e61cb76a New CMakeTest script 2023-05-01 11:59:06 +02:00
olszomal
fb731f2b5e Use indentations 2023-05-01 11:59:06 +02:00
olszomal
eec5a0755d Tests: new HTTP server and client 2023-05-01 11:59:06 +02:00
olszomal
41d98c3917 Tests: fix openssl configuration files and makecerts bash script to set X509v3 CRL Distribution Points extension 2023-05-01 11:59:06 +02:00
olszomal
7fa0b21ddd Tests: new certificates with X509v3 CRL Distribution Points extension 2023-05-01 11:59:06 +02:00
yjh-styx
e0eb331baf
Postpone stripping old signature after it is extracted (#260) 2023-04-28 11:59:07 +02:00
olszomal
7bb21c3539 Tests: generate new certificates and keys 2023-04-16 10:43:24 +02:00
olszomal
edcb18d63f Tests: use TSA-CRLfile 2023-04-16 10:43:24 +02:00
olszomal
3d7b8d2a21 Get Certificate Revocation List from a CRL distribution point 2023-04-16 10:43:24 +02:00
olszomal
7bfe3b5db9 Fix update_data_size() 2023-03-30 20:57:38 +02:00
olszomal
dd365d68c4 Calculate padding length 2023-03-30 20:57:38 +02:00
olszomal
09555e8c05 Inspect PE attribute certificate table 2023-03-30 20:57:38 +02:00
olszomal
e4aa06f0c0 Check PE checksum 2023-03-30 20:57:38 +02:00
olszomal
46e9ee447f Fix pagehash resource leak, CID 1536895 2023-03-29 08:51:01 +02:00
olszomal
3e7247d9dc Fix pe_page_hash_get(), CID 1536895, 1536897 2023-03-28 21:02:12 +02:00
olszomal
d2f1b9c035 Fix leafhash resource leak, CID 1536899 2023-03-28 21:00:42 +02:00
olszomal
4199310cdf Fix indata resource leak, CID 1536896 2023-03-28 20:59:57 +02:00
Michał Trojnara
0204d04a25 Stop using tabs for indentation 2023-03-25 23:39:52 +01:00
olszomal
246f0abbfc Optional CMake parameters 2023-03-25 20:34:25 +01:00
Małgorzata Olszówka
0f51a06b8f
Separate common and format-dependent functions (#241) 2023-03-25 20:32:58 +01:00
Charles Duffy
44a6768089 Avoid link failures on Darwin when AppleClang not matched (#246) 2023-03-14 14:37:24 +01:00
olszomal
93f5f800d6 Fix resource leak, CID 1535262 2023-02-28 08:27:46 +01:00
olszomal
4db6ed0cad Fix memory leak 2023-02-26 21:12:07 +01:00
olszomal
32b65659be Use big/little-endian conversion in pe_calc_realchecksum() 2023-02-26 21:12:07 +01:00
olszomal
8e74a05b40 msi_calc_digest() with FILE_HEADER parameter 2023-02-26 21:12:07 +01:00
olszomal
83e47e0252 Specify the maximum NumberOfSections value 2023-02-26 21:12:07 +01:00
olszomal
41e6042c26 Specify the maximum SizeOfOptionalHeader value 2023-02-26 21:12:07 +01:00
olszomal
33c1fdaa85 Remove wrong type casting 2023-02-26 21:12:07 +01:00
olszomal
11eb76d4f3 Use bio_hash_data() to compute a message digest value of a CAB file 2023-02-26 21:12:07 +01:00
olszomal
b0391244a6 New function bio_hash_data() 2023-02-26 21:12:07 +01:00
olszomal
83f6ceeaea Fix compiler warnings 2023-02-26 21:12:07 +01:00
olszomal
b96a7a2232 Use BIO_f_md instead of EVP_MD_CTX to compute a message digest value of the PE and CAB file 2023-02-26 21:12:07 +01:00
olszomal
ff8034af2e Use BIO_f_md instead of EVP_MD_CTX to compute a message digest value of the MSI file 2023-02-26 21:12:07 +01:00
olszomal
bde67ec1e2 Use BIO_f_md instead of EVP_MD_CTX to calculate timestamp, page hash and leaf hash 2023-02-26 21:12:07 +01:00
Julien Cristau
c5ad70d31a Fix asn1_get_time_t timezone offset
mktime takes an input in local time, but what we have is UTC.  timegm
does the right thing but is a nonstandard GNU and BSD extension, while
Windows has _mkgmtime.
2023-02-24 11:03:08 +01:00
Michał Trojnara
27a2a2bfa3 Install Xcode 2023-02-22 16:38:32 +01:00
olszomal
827f167f8b Fix default command "sign" 2023-02-22 15:40:18 +01:00
Michał Trojnara
4098a5efc7
Install missing "make" in the CI on macOS (#236) 2023-02-22 15:39:03 +01:00
Michał Trojnara
e88bc1ca14 Remove an automake dependency 2023-01-24 10:09:35 +01:00
olszomal
dd2aaf0804 Provide a non-zero divisor, CID 1519382 2023-01-23 18:04:37 +01:00
olszomal
08113a08cb Check pagesize upper bound, CID 1519382 2023-01-23 14:13:43 +01:00
olszomal
29843ccf40 Fix resource leak, CID 1530764, 1530765 2023-01-23 11:14:06 +01:00
olszomal
5fef4faf47 Check PE header value ranges, CID 1519382 2023-01-20 15:26:18 +01:00
olszomal
5981c740c9 Check signature length, CID 1519389 2023-01-20 15:20:52 +01:00
olszomal
f3af509973 Unsupported input file type to use with -catalog option 2023-01-20 10:53:49 +01:00
olszomal
c29e14e697 Reset calculated message digest, CID 1519395 2023-01-20 10:53:49 +01:00
olszomal
4da5526c05 Unmap a file in case of error, CID 1519391 2023-01-19 17:52:28 +01:00
olszomal
4ec23dbaa5 Fix resource leak, CID 1519397 2023-01-19 17:51:35 +01:00
olszomal
d9979c4bc6 Check a value range, CID 1519382 2023-01-19 17:51:08 +01:00
olszomal
695892b8bf Check sector location, CID 1519384 2023-01-19 17:50:27 +01:00
olszomal
192ff59916 Fix use after free null url, CID 1530710 2023-01-19 17:48:39 +01:00
Michał Trojnara
506daf84ac Discover engine ID if full path was specified
Fix #180
2023-01-19 11:58:52 +01:00
olszomal
bb6322e378 Close a file descriptor, CID 1208035 2023-01-18 21:19:35 +01:00
olszomal
b0eaa96d45 Squash the uninitialized pointer read warning, CID 1519385, 1519387 2023-01-18 21:17:50 +01:00
olszomal
fade782e58 Fix memory leak in stream_handle(), CID 1519397, 1519388, 1519402, 1519403 2023-01-18 21:16:34 +01:00
olszomal
199a852c12 Check DigitalSignature and MsiDigitalSignatureEx stream lengths, CID 1519400, 1519381, 1519386 2023-01-18 21:05:00 +01:00
olszomal
95a8a9d9c1 Check stream data length, CID 1519393 2023-01-18 21:03:16 +01:00
olszomal
c197d7727c close file and file mapping handles 2023-01-15 22:37:45 +01:00
olszomal
efbe570f27 Fix out-of-bounds read, CID 1519383 2023-01-15 22:35:48 +01:00
olszomal
fef65536f6 remove warning 2023-01-15 22:34:34 +01:00
olszomal
1155a9c338 False positive CID 1519394: Operands don't affect result 2023-01-15 22:33:15 +01:00
olszomal
f67ca8aac5 Fix unchecked return value, CID 1519390 2023-01-15 22:29:57 +01:00
olszomal
d59601f2b9 Fix CRL distribution point memory leak, CID 1519398 2023-01-15 22:24:56 +01:00
olszomal
7f87f930f7 Unmap a mapped view of a file , CID 1519391 2023-01-15 22:21:23 +01:00
olszomal
dadca2516d Fix memory leak, CID 1519392 2023-01-15 22:20:20 +01:00
Michał Trojnara
a862378280 Reduce expression complexity 2023-01-15 22:09:08 +01:00
olszomal
c4ec6debe5 Squash the unchecked return value from CURL library warning, CID 1519399 2023-01-15 21:57:15 +01:00
olszomal
08c205a02f Remove reduplicated checking for outdata file exists, CID 1519404 2023-01-15 21:54:16 +01:00
olszomal
acfece2c26 Fix dereference before null check, CID 1519396 2023-01-13 12:42:24 +01:00
olszomal
61cf89f26f typo 2023-01-11 12:24:26 +01:00
Michał Trojnara
07a927f34a Update the APT package database 2023-01-10 17:56:48 +01:00
olszomal
257cb1fb08 Add missing parentheses 2023-01-10 17:40:09 +01:00
olszomal
c48a6cdef0 Legacy pkcs12 ciphers tests
Use legacy PKCS#12 container with RC2-40-CBC private key and certificate encryption algorithm
2023-01-10 17:39:53 +01:00
olszomal
8bba4496c0 Legacy pkcs12 ciphers support 2023-01-10 17:39:53 +01:00
olszomal
dfc13c9bf8 simplify bash completion 2023-01-10 17:38:58 +01:00
olszomal
f57b469c29 Add an option override the autodetected directory for installing bash completions 2023-01-10 17:38:58 +01:00
olszomal
c718882ffb Fix macro redefinition 2022-11-29 13:40:06 +01:00
Michał Trojnara
3109bdf0ab Add makecerts.log to CI error artifacts 2022-11-28 17:52:44 +01:00
olszomal
7aca21b481 Use big/little-endian conversion.
Improve checksum calculation.
2022-11-28 09:26:00 +01:00
olszomal
8c113b3a86 Fix generating timestamp query
The TSA is expected to include its signing certificate in the response
2022-11-28 09:26:00 +01:00
olszomal
f3a5ecce9c fix resource leaks 2022-11-23 11:44:02 +01:00
Jon Turney
1c678bf926 Don't use ELF-specific linker options on Cygwin, either 2022-11-22 16:55:29 +01:00
olszomal
454e15326d large CAB file support 2022-11-22 16:50:45 +01:00
olszomal
db556d0a2d large PE file support 2022-11-22 16:50:45 +01:00
Michał Trojnara
8bdd22c183 Remove a deprecated testing platform 2022-09-22 14:58:14 +02:00
olszomal
cc4e5a5076 fix year 2038 problem 2022-09-21 10:41:51 +02:00
Michał Trojnara
b8cb44fa47 initial 2.6 commit 2022-08-12 22:09:34 +02:00
Michał Trojnara
36cdea56de
release 2.5
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2022-08-12 21:59:52 +02:00
Michał Trojnara
77e63fa0cb more type conversion fixes 2022-08-12 21:56:39 +02:00
olszomal
225ce9bbd6 update building osslsigncode for Unix-like operating systems 2022-08-12 20:45:57 +02:00
olszomal
a5011a00c5 set install prefix 2022-08-12 20:45:57 +02:00
olszomal
f9006f099a remove ENABLE_CURL macro from the config.h file 2022-08-12 20:45:31 +02:00
olszomal
b9664394a5 Pre-defined _WIN32 macro defined by the MSVC compiler removed from the config.h file 2022-08-12 20:45:31 +02:00
olszomal
68c4163332 Fix clang/OS X warnings about embedded directives within macro arguments to sprintf 2022-08-12 20:45:31 +02:00
olszomal
c143eff68f set a result of multiplication cast to the wider type 2022-08-12 20:45:31 +02:00
Michał Trojnara
cbdbd9dbd0 Check for a Coverity token before scanning 2022-08-12 13:53:26 +02:00
Michał Trojnara
20bfc0ffeb Coverity Scan 2022-08-10 10:45:13 +02:00
Michał Trojnara
8e075d625d yet another python 3.6 fix 2022-08-08 09:19:19 +02:00
Michał Trojnara
4eeaee4c16 support python 3.6 (and possibly older) 2022-08-08 09:06:45 +02:00
Michał Trojnara
6da29943ea prevent vcpkg cache path collisions 2022-08-08 06:51:54 +02:00
Michał Trojnara
431d6ab1bd show OpenSSL version 2022-08-08 06:40:29 +02:00
Michał Trojnara
5d51f0e2c7 Test on different versions of Ubuntu 2022-08-07 17:33:03 +02:00
Michał Trojnara
4d476213d4 Identify runner OS with runner.os instead of matrix.os 2022-08-07 17:32:56 +02:00
Michał Trojnara
21c196342f
CodeQL analysis 2022-08-05 12:51:39 +02:00
Michał Trojnara
b8d83bb15e fix the hardcoded "pkcs11" engine id
Use the `-pkcs11engine` value if available for the engine id
instead of the hardcoded `pkcs11` string.
This should address #152.
2022-08-04 11:56:57 +02:00
Michał Trojnara
abf5aa68f8 simplify CI 2022-08-04 11:34:37 +02:00
Michał Trojnara
762dd8a21b add mingw to CI 2022-08-04 11:34:37 +02:00
Michał Trojnara
86e4eb9252 fix mingw support 2022-08-04 11:34:37 +02:00
Michał Trojnara
7510e3c553 initial 2.5 commit 2022-08-02 21:43:44 +02:00
Michał Trojnara
225a8f78fa
release 2.4
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2022-08-02 21:29:07 +02:00
Michał Trojnara
23288f5a00 use the new option name for tests 2022-08-02 21:26:09 +02:00
Michał Trojnara
0e80573c58 limit platforms installing python 2022-08-01 20:59:02 +02:00
Michał Trojnara
8f6d1617eb enable built-in socket module in Python 2022-08-01 20:59:02 +02:00
Michał Trojnara
15185acb0a do not enable EH continuation metadata 2022-08-01 20:59:02 +02:00
Michał Trojnara
703ae70602 static CI build 2022-08-01 20:59:02 +02:00
Michał Trojnara
c59f5dd02c use the first cmake release that passes CI 2022-07-30 20:42:30 +02:00
Michał Trojnara
0a9dcbda6c fix the minimum required cmake 2022-07-30 12:15:50 +02:00
Michał Trojnara
f87618326f explicit cmake source path 2022-07-30 11:43:18 +02:00
Michał Trojnara
80de8e7738 create the build directory for older cmake 2022-07-30 11:37:30 +02:00
Michał Trojnara
306d467a29 try the latest supported version of cmake 2022-07-30 10:28:51 +02:00
Michał Trojnara
d0a958919d autodetect vcpkg 2022-07-30 09:53:16 +02:00
Michał Trojnara
81b58f744d simplify custom builds 2022-07-29 23:06:45 +02:00
Michał Trojnara
8f30bf28e7 set the project language 2022-07-29 19:06:00 +02:00
olszomal
a12b5c0951 suppress check compiler flag messages 2022-07-29 18:42:35 +02:00
olszomal
5bf24b34a2 remove certs directory 2022-07-29 18:42:35 +02:00
olszomal
7871e28141 fix AppleClang linker flags 2022-07-29 18:42:35 +02:00
olszomal
d7daf98db8 improve add compile and linker flags 2022-07-29 18:42:35 +02:00
olszomal
1d0918c84d Squash -Wcast-qual and -Wconversion warnings 2022-07-29 18:42:35 +02:00
olszomal
f42459ff09 Squash -Wwrite-strings warnings:
simplify PEM_read_certs()
fix setting SpcPeImageData flags
2022-07-29 18:42:35 +02:00
olszomal
66a6a1ced5 Squash ASN1_STRING_get0_data() returne value warning 2022-07-29 18:42:35 +02:00
olszomal
a44c8decbc Fixed clang -Wembedded-directive warning:
embedding a directive within macro arguments has undefined behavior
2022-07-29 18:42:35 +02:00
olszomal
d556fb78dc Add missing static specifiers 2022-07-29 18:42:35 +02:00
Michał Trojnara
4c856f3a1e Additional excludes for Windows installation 2022-07-27 16:56:34 +02:00
Michał Trojnara
1bf5f9a07b Avoid hardcoding DLL names 2022-07-27 16:41:26 +02:00
Michał Trojnara
c930d9aa7a smarter vcpkg cache restore 2022-07-27 10:10:25 +02:00
olszomal
5df8d7c181 enable python3 vcpkg dependence 2022-07-27 09:43:19 +02:00
olszomal
cf20354b91 fix sizeof java_attrs_low 2022-07-27 09:43:19 +02:00
Michał Trojnara
665ecfb64c fix Win32 builds 2022-07-27 09:30:08 +02:00
Michał Trojnara
6430bf0036 rebuild vcpkg cache on vcpkg.json changes 2022-07-26 16:56:00 +02:00
Michał Trojnara
92673b8f00 Add a build status badge 2022-07-26 16:38:08 +02:00
Michał Trojnara
3d0640a2cc
CI for Linux/macOS/Windows (#166) 2022-07-26 16:27:46 +02:00
olszomal
28c68aeebf find osslsigncode path 2022-07-22 14:17:59 +02:00
olszomal
26b7d5f617 change makecers.sh mode 2022-07-21 12:21:19 +02:00
olszomal
88bf99dec8 Microsoft Visual Studio install notes 2022-07-21 12:21:19 +02:00
olszomal
757d9c39a4 fix and simplify cmake 2022-07-21 12:21:19 +02:00
olszomal
ce2d586956 Squash applink.c compilation warnings 2022-07-21 12:21:19 +02:00
olszomal
396318dcd1 Find headers 2022-07-21 12:21:19 +02:00
olszomal
24ed108099 Set bash completion 2022-07-21 12:21:19 +02:00
olszomal
7b29b45348 Set compiler and linker flags 2022-07-21 12:21:19 +02:00
olszomal
6b3450ada8 add test certificates 2022-07-21 12:21:19 +02:00
olszomal
ac3e8e5221 improve tests 2022-07-21 12:21:19 +02:00
Michał Trojnara
99400d92d6 add vcpkg.json 2022-07-18 11:38:29 +02:00
mtrojnar
b63b023c5c add 64-bit Windows targets 2022-07-17 07:48:33 +02:00
Michał Trojnara
6ffe7fa0de add faketime to ci dependencies 2022-07-16 23:22:03 +02:00
Michał Trojnara
b7d4c72756
Create ci.yml 2022-07-16 23:18:14 +02:00
mtrojnar
fb19651926 re-enable tests/install/dist on Unix 2022-07-16 21:55:04 +02:00
mtrojnar
213ea27f99 setup default 32-bit targets for MSVC 2022-07-16 21:23:48 +02:00
mtrojnar
a19d77a8a7 MSVC fixes and workarounds 2022-07-16 21:10:56 +02:00
Michał Trojnara
6a873c3a49 simplify cmake 2022-07-16 20:01:11 +02:00
fanquake
a892c50147 doc: CMAKE_C_STANDARD is C not C++ 2022-07-15 21:17:01 +02:00
olszomal
95615faf1d check PE file size 2022-07-15 21:16:07 +02:00
olszomal
860e8d6f4e cmake3 note 2022-06-20 12:13:00 +02:00
olszomal
60fe5d15fe use CMake instead of Makefile 2022-05-25 20:27:21 +02:00
olszomal
b96717506c RFC3161 section-4.3 comment 2022-04-12 11:41:27 +02:00
olszomal
157bb78a6e fix sprintf_s error stack corruption 2022-04-12 11:41:27 +02:00
olszomal
4396c451eb Revert "use a memory allocation instead of a static variable to fix sprintf_s error stack corruption"
This reverts commit fb59d92f3cc48413992a744f4a779ffda2cc0f19.
2022-04-12 11:41:27 +02:00
olszomal
40bd33ee01 fix Windows build with MSVC compiler 2022-04-12 11:41:27 +02:00
olszomal
d7ae7c90f9 Revert "fix Windows build with MSVC compiler"
This reverts commit 78220c144c476775c2ef7408c562ae3292d84cf2.
2022-04-12 11:41:27 +02:00
olszomal
247a82232c windows read password from file 2022-04-12 11:41:27 +02:00
olszomal
3a84987107 use a memory allocation instead of a static variable to fix sprintf_s error stack corruption 2022-04-12 11:41:27 +02:00
olszomal
afda3cc810 remove zlib dependency 2022-04-12 11:41:27 +02:00
olszomal
44eeeb1515 updated NEWS.md 2022-04-12 11:41:27 +02:00
olszomal
1c523ed616 disable verification of the Timestamp Server signature 2022-04-12 11:41:27 +02:00
olszomal
8ba94fafd9 user-specified signing and/or verifying time (-time option) 2022-04-12 11:41:27 +02:00
olszomal
82185eef18 enable "-h {md5,sha1,sha2(56),sha384,sha512}" option for "attach -signature" and "add" commands
enable "-require-leaf-hash" option for "attach-signature" command
2022-04-12 11:41:27 +02:00
olszomal
bec2ae2eed fix Windows build with MSVC compiler 2022-04-12 11:41:27 +02:00
olszomal
c5c23cefac more verbose timestamp response status info 2022-04-12 11:41:27 +02:00
olszomal
4c1b972f9e set the default message digest to sha256 2022-04-12 11:41:27 +02:00
Jon Turney
1bd9a87e2f Don't '#include <windows.h>' on Cygwin
On Cygwin, don't '#include <windows.h>', so WIN32 isn't defined, so we
don't end up trying to use various MSVC functions, which don't exist in
our C runtime library.

The whole point of the Cygwin C runtime library is to try to look like
POSIX, so we always want the POSIX code in those pre-processor
conditionals.
2022-04-10 18:00:36 +02:00
olszomal
65d17836ab disable the confusing error created while searching for the certificate 2022-04-10 17:46:30 +02:00
Dirk Müller
6a1a884f3c Add license declarations to dist tarball
This is GPLv3, we should include the license in the sources.
2022-04-10 17:29:24 +02:00
Michał Trojnara
98308f2e0a remove PVK conversion notes from README.md
This is no longer needed since release 1.5, which added native support
for PVK keys.
2022-03-06 21:57:43 +01:00
Michał Trojnara
da4413d0c7 move unauth blob documentation to README.md
Removed dead links and references to a fork that was merged long time
ago.
2022-03-06 21:46:47 +01:00
Michał Trojnara
c08b8cb3d5 git ignore GPG signature files 2022-03-06 21:14:26 +01:00
Michał Trojnara
5af84745de add markdown files to distribution tarballs 2022-03-06 21:11:02 +01:00
Michał Trojnara
0459fb99ef initial 2.4 commit 2022-03-06 21:00:38 +01:00
Michał Trojnara
73d7cf011e release 2.3
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2022-03-06 20:11:25 +01:00
Michał Trojnara
7affd85c46 Fix non-interactive PVK (MSBLOB) key decryption
Fix #130
2022-03-06 18:54:51 +01:00
Michał Trojnara
d8a182614c remove trailing tabulators 2022-03-06 17:41:36 +01:00
olszomal
ac672640be
Clean up arrays (#139)
- move large arrays to the heap
 - use the `const` type qualifier with constant arrays
2022-03-06 16:50:23 +01:00
olszomal
5d68e8699a update change log 2022-02-28 19:50:39 +01:00
olszomal
b48458499b fix pe_calc_checksum bufor
revert part of 45fedd9e501a44f9fdbb6e702a94168e400970fc
2022-02-28 19:50:39 +01:00
olszomal
4731667c35 msi const names 2022-02-25 21:42:24 +01:00
olszomal
85594d9fb2 fix memory leak 2022-02-25 21:42:24 +01:00
olszomal
5f60cc6563 use msi_dirent_free() when failed to parse the MSI_DIRENT structure 2022-02-25 21:42:24 +01:00
olszomal
77b2b30d1f check Root Directory Entry's Name 2022-02-25 21:42:24 +01:00
olszomal
e0d652b987 timestamp error 2022-02-24 23:08:24 +01:00
Michał Trojnara
b774a56aa9 Floyd's cycle-finding algorithm 2022-02-23 22:35:40 +01:00
Michał Trojnara
6eaf0d9368 fixed MSI recursion loop detection 2022-02-22 18:56:20 +01:00
olszomal
d471b51db5 add only a non-stream child to the tree 2022-02-22 18:16:21 +01:00
olszomal
7b12abf21f NOSTREAM error handling 2022-02-22 18:16:21 +01:00
olszomal
f248286d6f verify corrupted SpcPeImageData struct 2022-02-22 18:16:21 +01:00
olszomal
5db237f242 Revert "verbose msi file verification errors"
This reverts commit 4eeeec32b44a64914fe90828854c5e9228322e0c.
2022-02-22 18:16:21 +01:00
Michał Trojnara
95c5a4451b simplify MSI parsing recursion 2022-02-22 10:08:15 +01:00
olszomal
f0207411b9 fix parse MSI_FILE_HDR struct 2022-02-21 19:24:32 +01:00
Michał Trojnara
aef958f880 modelines 2022-02-19 17:07:51 +01:00
Michał Trojnara
a6d3be739e detect recursion loop 2022-02-18 22:33:03 +01:00
olszomal
4eeeec32b4 verbose msi file verification errors 2022-02-18 18:54:48 +01:00
olszomal
ce196ce147 improve cab files verification 2022-02-18 18:54:48 +01:00
olszomal
289c345280 fix double free in msi_dirent_new() 2022-02-18 18:54:48 +01:00
olszomal
bdea1d1c2a fixed MSI_DIRENT structure parsing 2022-02-17 15:37:15 +01:00
olszomal
45fedd9e50 Fix more fuzzer errors 2022-02-11 23:32:27 +01:00
olszomal
e177ded9a5 Fix some fuzzer errors and VS2022 compiler warnings and errors 2022-02-04 17:35:46 +01:00
olszomal
5a2d0affc1 validate both header->sigpos and header->siglen 2022-01-30 22:14:21 +01:00
olszomal
5afafecc23 check a signature length in the WIN_CERTIFICATE structure 2022-01-30 22:14:21 +01:00
olszomal
07bf24911d
Add bash completion script (#125) 2022-01-11 20:46:52 +01:00
Stephen Kitt
357747d2fc Typo fix: Errror
Signed-off-by: Stephen Kitt <steve@sk2.org>
2021-12-26 22:00:53 +01:00
olszomal
28f6ffbc42 Return the number of failed tests from make_tests 2021-12-26 21:58:44 +01:00
olszomal
fb75eee385 Put the pkcs11cert option in the usage syntax 2021-12-26 21:58:04 +01:00
olszomal
6e2fb03b7b Edit Windows install notes 2021-12-26 21:58:04 +01:00
olszomal
46d43d70b3 Test certificates support requirements of openssl 3.0:
- AES-256-CBC encryption algorithm for PKCS#12 files
- required configuration file options
Export LD_LIBRARY_PATH
2021-12-26 21:58:04 +01:00
olszomal
407579ca58 CA bundle auto-detection 2021-12-26 21:57:07 +01:00
olszomal
96df1a709f libcurl development package availability 2021-12-21 20:07:10 +01:00
Michał Trojnara
8c37b00d83 release 2.2
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2021-08-15 21:42:01 +02:00
aesx86
f2559972f3 fix gcc command line 2021-07-06 08:48:43 +02:00
Michał Trojnara
057d38ee76 Additional test dependency checks 2021-06-27 10:10:01 +02:00
Michał Trojnara
ed8ee4194b typo 2021-06-19 12:29:05 +02:00
Michał Trojnara
c64add388b
Separate section for bootstrapping 2021-06-13 21:57:09 +02:00
sebaxakerhtc
2912eb054c missing autoconf for MacOS 2021-06-13 20:47:38 +02:00
olszomal
de05123adc update documentation 2021-06-09 23:36:17 +02:00
olszomal
180b352102 tests improvements 2021-06-09 23:36:17 +02:00
olszomal
72de045151 Add the bootstrap file 2021-06-09 23:36:17 +02:00
olszomal
95d77c9b98 help and version commands return code 0 (success) 2021-06-09 23:34:57 +02:00
olszomal
64e7e26eba free up BIO outdata only for MSI files 2021-05-30 22:14:35 +02:00
olszomal
e26a50a618 clarifying comments 2021-05-30 22:13:34 +02:00
olszomal
d2aa35a7f6 verify the content blob with the type set to OCTET STRING 2021-05-30 22:13:34 +02:00
Michał Trojnara
1c175c4339
Merge pull request #90 from olszomal/style
Handle unsuccessful termination exit(-1)
2021-05-04 09:40:12 +02:00
olszomal
3dad092be9
Merge branch 'master' into style 2021-05-04 09:20:12 +02:00
olszomal
de0bf341a5 free up the SIGNATURE structure 2021-05-04 09:02:20 +02:00
olszomal
4d5052c3f4 remove trailing newlines 2021-05-04 08:51:07 +02:00
olszomal
04823393f2 renamed options:
"-untrusted" --> "-TSA-CAfile"
"-CRLuntrusted" --> "-TSA-CRLfile"
2021-05-04 08:49:39 +02:00
olszomal
cfb897a902 handle unsuccessful termination exit (-1) 2021-04-26 11:35:19 +02:00
olszomal
8b064ca814 sizeof style 2021-04-26 10:48:53 +02:00
egonk
1bdfcc8940 fix crl nullptr crash in read_certfile 2021-04-25 21:59:36 +02:00
olszomal
bcdc5b7030 fixed width integer types 2021-04-25 21:43:00 +02:00
olszomal
3908e874a4 sizeof style 2021-04-25 21:38:57 +02:00
olszomal
a161efdb25 fix buffer overflow 2021-04-25 21:38:57 +02:00
olszomal
b01a2f5cd7 C89 standard compatibility 2021-04-25 21:38:57 +02:00
olszomal
b6e6165782 moral rights 2021-04-25 21:38:57 +02:00
olszomal
9b3697ad76 update changelog 2021-04-25 21:38:57 +02:00
olszomal
758003156e MSI file signing support
DIFAT sectors are not supported
2021-04-25 21:38:57 +02:00
olszomal
4f590989ce remove libgsf library dependency
MSI file verify and remove-signature support
2021-04-25 21:38:57 +02:00
olszomal
6df4c12624 verify msi metadata 2021-04-25 21:38:57 +02:00
Michał Trojnara
315357f092 Update a dead link in the documentation
Closes #84
2021-04-05 20:32:38 +02:00
olszomal
c0d9569c4f disable GSF_CAN_READ_MSI_METADATA 2021-01-11 21:21:02 +01:00
olszomal
352ef49b3a unicode description support 2021-01-11 21:20:18 +01:00
olszomal
f004aa3f48 new testing framework 2021-01-11 21:20:18 +01:00
olszomal
6edd56bfac Print the message digest algorithm from the signer info structure 2021-01-11 21:20:18 +01:00
olszomal
67e4edfe45 Print authenticated attributes:
- message digest
- signing time
- URL description
- text description
- level of permissions for CAB files
2021-01-11 21:20:18 +01:00
olszomal
5ad5260351 update copyright year 2021-01-11 21:20:18 +01:00
tdyer
790abf66da update documentation for timestamp server
- verisign timestamp server is no longer in service
   update docs to point to alternative service
2021-01-06 21:25:41 +01:00
olszomal
1dc209baa8 fix the default end date and extended key usage for test certificates 2021-01-06 21:24:40 +01:00
olszomal
2f011cfc31 p11engine and p11module need to be orthogonal (independent of each other) 2021-01-06 21:24:05 +01:00
olszomal
e8fe3e934d code simplification 2021-01-06 21:20:56 +01:00
olszomal
f8849b8048 new option -c specifies the catalog file by name 2021-01-06 21:20:56 +01:00
olszomal
86d593f264 Create a MsCtlContent structure to decode the Microsoft MS_CTL_OBJID object 2021-01-06 21:20:56 +01:00
olszomal
5e064233a3 increase the maximum size of supported CAT files 2020-11-10 04:28:43 +01:00
olszomal
fb1bc06440 CAT file tests 2020-11-02 10:11:10 +01:00
olszomal
80d5948eeb CAT files support 2020-11-02 10:11:10 +01:00
olszomal
0d6d0071d3 sort Microsoft and Generic OIDs 2020-11-02 10:11:10 +01:00
Artem Polishchuk
250521e07f fix(tests): swallows the exit code 2020-10-15 18:15:59 +02:00
114 changed files with 27976 additions and 10707 deletions

237
.github/workflows/ci.yml vendored Normal file
View 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
View 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
View 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
View File

@ -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

View File

@ -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
View 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
View 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
View 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
View 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" ]

View File

@ -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 .
```

View File

@ -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

View File

@ -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
View 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
View File

@ -1,6 +1,10 @@
osslsigncode
============
## BUILD STATUS
[![CI](https://github.com/mtrojnar/osslsigncode/actions/workflows/ci.yml/badge.svg)](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.

View File

@ -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
View 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

2823
appx.c Normal file

File diff suppressed because it is too large Load Diff

1578
autogen.sh

File diff suppressed because it is too large Load Diff

1005
cab.c Normal file

File diff suppressed because it is too large Load Diff

505
cat.c Normal file
View 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
View 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
View 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
View 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:
]]

View 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:
]]

View 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

File diff suppressed because it is too large Load Diff

View File

@ -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
View 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
View 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
View 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:
*/

2433
msi.c Normal file

File diff suppressed because it is too large Load Diff

76
osslsigncode.bash Normal file
View 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

File diff suppressed because it is too large Load Diff

572
osslsigncode.h Normal file
View 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:
*/

1222
pe.c Normal file

File diff suppressed because it is too large Load Diff

875
script.c Normal file
View 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
View File

@ -0,0 +1,2 @@
__pycache__
.pylintrc

View File

@ -1,6 +0,0 @@
*.der
*.pem
*.pvk
*.p12
*.spc
*.txt

47
tests/certs/ca-bundle.crt Normal file
View 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-----

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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
View 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
View File

@ -0,0 +1 @@
*.log

View 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
View 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:
"""

Binary file not shown.

Binary file not shown.

BIN
tests/files/unsigned.cat Normal file

Binary file not shown.

BIN
tests/files/unsigned.ex_ Normal file

Binary file not shown.

BIN
tests/files/unsigned.exe Normal file

Binary file not shown.

BIN
tests/files/unsigned.mof Normal file

Binary file not shown.

BIN
tests/files/unsigned.msi Normal file

Binary file not shown.

2
tests/files/unsigned.ps1 Normal file
View File

@ -0,0 +1,2 @@
cls
Write-Host "żółć"

View 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
View 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:
"""

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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