137 Commits

Author SHA1 Message Date
olszomal bf209e0fc8 Refactor SpcIndirectDataContent parsing helpers 2026-05-26 17:27:46 +02:00
olszomal 68a6826cd1 Use ASN1_STRING and ASN1_INTEGER APIs instead of direct struct access 2026-05-26 17:27:46 +02:00
olszomal ea5d15862d cmake: add documentation generation, GNU install dirs, and uninstall target 2026-05-26 17:27:46 +02:00
olszomal bdde95635f attach-signature flow moved to digest-only verification semantics
attach-signature now uses digest-only verification instead of full
signature validation; output file is not kept if digest verification fails
2026-04-02 17:43:43 +02:00
olszomal d0ef178a9a Remove redundant NULL assignments, CID 1669015 2026-02-25 14:07:58 +01:00
olszomal e126ab3e4a Fix memory leak of compressedData on error paths, CID 1669014 2026-02-25 14:07:58 +01:00
Michał Trojnara a1fb6600fb Fix handling OpenSSL initialization errors 2026-02-11 16:23:57 +01:00
Michał Trojnara 8227c68ceb Do not export osslsigncode.c consts 2026-02-11 15:50:25 +01:00
Michał Trojnara c988b48063 Refactor UI method cleanup 2026-02-11 15:48:17 +01:00
Michał Trojnara 6cf70b4af2 Initial 2.14-dev commit 2026-02-10 23:17:56 +01:00
Michał Trojnara 97a9ade6ec Release 2.13
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2026-02-10 22:51:25 +01:00
Michał Trojnara f2f33bb131 Move providers_cleanup() back 2026-02-10 19:10:00 +01:00
Michał Trojnara 202b2c2866 Separate OpenSSL and functional initialization 2026-02-10 18:37:48 +01:00
olszomal 2a5409b7c4 Fix header bounds validation in PE page hash calculation 2026-02-09 16:15:21 +01:00
olszomal 87bce8e372 Fix memory leaks on error paths in PE signing 2026-02-09 16:15:21 +01:00
olszomal f7ace57c81 Validate PE attribute certificate table bounds 2026-02-09 16:15:21 +01:00
olszomal 92f8761b47 Fix heap corruption in PE page hash calculation 2026-02-06 15:41:01 +01:00
Antoni Klajn 09d3312fd9 Fixed integer overflow, integer underflow and Out-of-Bounds Read 2026-02-06 11:39:49 +01:00
olszomal 9d02a20aec Fix unsafe ZIP size handling and allocation checks 2026-02-04 10:13:03 +01:00
olszomal f190ec5d87 Fix double free in ZIP local header 2026-02-04 10:13:03 +01:00
Michał Trojnara 4b30d6be28 Initial 2.12-dev commit 2026-02-03 17:20:29 +01:00
Michał Trojnara fac8164622 Release 2.12
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2026-02-02 17:53:25 +01:00
Michał Trojnara cbee1e723c Fixed buffer overflow while extracting msg digest
Reported and fixed by Antoni Klajn, Opera
2026-02-02 17:37:45 +01:00
Michał Trojnara f90327df09 Initial 2.12-dev commit 2026-01-21 00:08:58 +01:00
Michał Trojnara f3a590be69 Release 2.11
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2026-01-20 23:53:33 +01:00
Michał Trojnara 6631a5f10b Update trusted certificate list 2026-01-20 23:21:33 +01:00
Michał Trojnara 9924f0c085 Minor style improvements
- Reorder checks by corresponding RFC 5280 section numbers.
- Simplify comments.
2026-01-20 23:21:33 +01:00
olszomal 7d85ac5f04 Add GitHub issue and PR templates 2026-01-09 14:41:02 +01:00
olszomal feebbcd4d9 Print current CRL during certificate verification 2026-01-07 13:36:43 +01:00
olszomal d787541107 tests: add digitalSignature keyUsage to leaf certificate 2025-12-31 11:38:21 +01:00
olszomal 6390ae2746 Add keyUsage digitalSignature validation for signer certificate 2025-12-31 11:38:21 +01:00
Michał Trojnara a472d7fbff Comment returned CRL Content-Type 2025-12-22 19:26:21 +01:00
Chris Thibodeaux 27172a07ca Patch CRL fetch failure from expected file type
`application/octet-stream` response types caused CRL/TSA-CRL fetch failures
2025-12-22 19:22:01 +01:00
olszomal d77ddb9443 Disable keep-alive and remove the shutdown workaround.
Some RFC 3161 TSA servers (e.g. time.certum.pl) advertise
"Connection: close" but delay closing the connection,
when keep-alive was requested. The client waited for EOF and
attempted to work around this by explicitly shutting down the socket.
2025-12-19 15:11:12 +01:00
olszomal 988f72249b Simplify ASLR/PIE flags check for macOS 2025-12-16 06:42:01 +01:00
olszomal c23f92ca68 Improve PKCS#11 and CNG usage instructions in README 2025-09-22 11:16:29 +02:00
olszomal 842bd94aaf Remove duplicate certs from sorted X509 chain 2025-09-19 17:02:21 +02:00
olszomal 1d72c3da8c Improve key/cert loading logic and standardize usage file argument names 2025-09-19 17:02:21 +02:00
olszomal d792e8d0db Use bio_new_file() wrapper instead of BIO_new_file() for consistent file handling 2025-09-19 17:01:02 +02:00
olszomal bbdfc1d98a Avoid undefined behavior with BIO_get_fp by replacing BIO_new_file with fopen + BIO_new_fp 2025-09-19 17:01:02 +02:00
olszomal 5ac11e9f58 Fix -Wsign-conversion warning in x509_name_to_utf8() 2025-07-01 12:21:44 +02:00
Michał Trojnara 55541c6ace Initial 2.11-dev commit 2025-06-23 21:42:26 +02:00
Michał Trojnara 8329a14f8b Release 2.10
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2025-06-23 21:36:13 +02:00
Michał Trojnara 343b0af1fe Put globs in quotes 2025-06-23 21:21:34 +02:00
Michał Trojnara d440f32780 Codespell Action 2025-06-23 21:13:47 +02:00
Michał Trojnara fb082942d2 Descriptive Action name 2025-06-23 21:05:51 +02:00
Michał Trojnara 025e808c01 docs: fix typos in README 2025-06-20 16:26:18 +02:00
Michał Trojnara 23b6d7782c docs: fix typo in appx comments 2025-06-20 16:14:25 +02:00
Michał Trojnara 4c3a1e887c docs: fix typos in README 2025-06-20 16:04:36 +02:00
Michał Trojnara 97ee163e31 Document script file support 2025-06-20 14:06:05 +02:00
Michał Trojnara dfc3e46a77 Typos 2025-06-20 12:28:43 +02:00
Michał Trojnara ff9a6d3593 Check for invalid OID in is_content_type 2025-06-20 10:32:30 +02:00
Michał Trojnara e81b08e02d Fix a comment 2025-06-20 09:58:45 +02:00
Michał Trojnara 0c85d54800 Handle missing certificate names 2025-06-19 17:56:54 +02:00
Michał Trojnara 772bc22c94 Handle null return from curl_easy_init 2025-06-19 14:32:24 +02:00
Michał Trojnara d65a2b5286 Fix various typos 2025-06-19 14:18:26 +02:00
Michał Trojnara a3fcf41e1a Check memory allocation 2025-06-19 12:00:29 +02:00
fanquake e00caac3db cmake: drop USE_WIN32 define
This was added in #423, but it's only use was then removed in #435.
2025-06-18 18:46:28 +02:00
olszomal dd9b81281f Support loading OpenSSL 3.0+ providers without -pkcs11module option (e.g., CNG) 2025-06-05 17:13:10 +02:00
olszomal 6b56aef073 Add tests for handling JavaScript files 2025-06-05 14:41:36 +02:00
Michał Trojnara 52bfff5756 Avoid variable reuse 2025-06-04 18:42:41 +02:00
Michał Trojnara 4d52e9cc4b JavaScript format fix. 2025-06-04 18:38:28 +02:00
Michał Trojnara 3292b02650 JavaScript support
Resolves #437
2025-06-04 10:04:17 +02:00
Michał Trojnara 50c23daa4c Code simplification
No functional change intended.
2025-06-03 08:20:52 +02:00
Michał Trojnara 9b7dae4572 Support loading arbitrary engines via ENGINE_by_id()
Use ENGINE_by_id() for any engine name that doesn't contain a dot,
assuming it's an engine ID. If the name includes a dot (e.g., a file
extension), treat it as a path to a dynamic engine module.

See #436 for discussion.
2025-06-02 20:32:26 +02:00
Michał Trojnara 62438908cb Skip the "lib" prefix when guessing engine ID
Fix #436
2025-05-30 16:59:25 +02:00
olszomal 829e770250 Use _WIN32 instead of USE_WIN32 for MinGW compatibility 2025-05-27 10:17:03 +02:00
olszomal a6c7c25dae Update NEWS 2025-05-14 11:29:13 +02:00
olszomal 10ca3a06ea Suppress compiler warnings 2025-05-06 10:42:53 +02:00
olszomal 9ea7e85468 Fix engine-less builds 2025-05-06 10:42:53 +02:00
olszomal 68e8845ef1 Improve PKCS#7 verification with OpenSSL 3.5
Enhanced verification logic for PKCS#7 signedData structures by introducing a dedicated `verify_pkcs7_data()` function. This update addresses compatibility with older OpenSSL versions (< 3.0.5) and ensures correct handling of detached signed content using a BIO buffer.
The change enables support for PKCS#7 inner content (RFC 2315, section 7), as per OpenSSL PR#22575.
Refactored timestamp and authenticode verification functions to reduce duplication and properly manage X509_STORE and X509_CRL structures.
2025-05-01 11:21:29 +02:00
olszomal 475ea95ba3 Fix control flow and braces for engine and provider support 2025-05-01 11:21:29 +02:00
Maxim Bagryantsev d352dcc1a5 Do not try to load engine twice 2025-04-18 10:46:20 +02:00
olszomal 7734382436 Remove Ubuntu 20.04 from CI as it's no longer supported 2025-04-16 11:48:05 +02:00
Jānis Erdmanis d425d8bf25 fix capitalization ws2_32.lib
Windows and MacOS are both case-insensitive, and hence the issue of wrong capitalisation may not have surfaced. 

I am forming a recipe for cross-compilation for the Julia BinarBuilder environment, which uses Linux x86_64 as the host system. However, as it uses a sensitive filesystem, I hit a linking error that could only be fixed by changing the capitalization of `Ws2_32.lib` to lowercase. 

More on that can be found in the pull request:
https://github.com/JuliaPackaging/Yggdrasil/pull/10950
2025-04-16 11:47:49 +02:00
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 4dd836bab1 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
85 changed files with 15474 additions and 3694 deletions
+8
View File
@@ -0,0 +1,8 @@
<!--
Please use one of the available issue templates.
Bug reports without required information may be closed.
-->
If you are reporting a bug or crash, please use the appropriate issue template.
For questions or support, use please use [Discussions](<https://github.com/mtrojnar/osslsigncode/discussions>).
+74
View File
@@ -0,0 +1,74 @@
---
name: Crash report
about: Report a segmentation fault or other crash
labels: crash
---
<!--
Thank you for your crash report.
Note: Please search to see if an issue already exists for the bug you encountered.
-->
### Segmentation Fault / Crash Details
<!--
Provide exact, reproducible steps.
Include the complete command, exactly as executed.
-->
- Signal / exit code: <!-- SIGSEGV, SIGABRT -->
- Reproducibility: <!-- always / sometimes / once -->
- Affected command or operation: <!-- e.g. `osslsigncode sign`, `osslsigncode verify` -->
- First observed version:
- Last known working version (if any):
#### Backtrace
<!--
Provide a backtrace from gdb or lldb.
Build with debug symbols if possible. Use `bt full` if possible.
Crash reports without a backtrace may be closed without investigation.
-->
- `(gdb) bt`
#### Memory / Sanitizers
<!--
Attach relevant output if available.
-->
- [ ] Valgrind
- [ ] ASan / UBSan
- [ ] Other tools
#### Crash Context
<!--
Anything that may be relevant:
- OpenSSL provider / engine in use
- PKCS#11 modules
- Custom OpenSSL configuration
- Threading or concurrency
-->
### Environment
- Operating system and version (e.g. Ubuntu 24.04):
- Architecture (x86_64, arm64, etc.):
### Versions
<!--
Please verify that the issue is reproducible with the current upstream master.
-->
- osslsigncode built from:
- [ ] upstream master
- [ ] upstream release (tag):
- [ ] distribution package (name and version):
- `openssl version -a`
- `osslsigncode --version`
### Configuration / Settings
<!--
Anything that could affect signing or verification:
- Custom OpenSSL configuration
- Engine / provider settings
- Environment variables (OPENSSL_CONF, etc.)
-->
### Anything else
<!--
Links, references, related issues, workarounds or additional observations.
-->
@@ -0,0 +1,26 @@
---
name: Documentation
about: Report an error in (or missing) documentation
labels: documentation
---
<!--
Thank you for taking the time to report a documentation issue.
-->
### Documentation Location
<!--
Where is the problem located?
Provide a link, file path, or section name.
-->
### Issue Description
<!--
Describe what is wrong or missing.
-->
### Suggested Improvement (optional)
<!--
If you know how it should be fixed, describe it here.
Proposed wording or examples are especially helpful.
-->
@@ -0,0 +1,30 @@
---
name: Feature request
about: Suggest a new feature or improvement
labels: feature
---
<!--
Thank you for your feature request.
Please describe the use case and motivation as clearly as possible.
-->
### Use Case / Motivation
<!--
What problem are you trying to solve?
Why is this feature needed?
-->
### Proposed Change
<!--
Describe the feature or improvement you are proposing.
High-level description is sufficient.
-->
### Additional Notes (optional)
<!--
Anything else that may help:
- examples
- references
- related issues
-->
+17
View File
@@ -0,0 +1,17 @@
---
name: Questions / Support
about: Please use Q&A in Discussions instead
labels: question
---
### Questions and Support
Please do **not** use GitHub issues for general questions or support requests.
For:
- usage questions
- "how do I..." questions
please use [Q&A category in Discussions](<https://github.com/mtrojnar/osslsigncode/discussions/new?category=q-a>)
Bug reports and crashes should be reported using the appropriate issue templates.
+77
View File
@@ -0,0 +1,77 @@
---
name: Other bug report
about: Report a bug
labels: bug
---
<!--
Thank you for your bug report.
Note: Please search to see if an issue already exists for the bug you encountered.
-->
### Current Behavior
<!--
A concise description of what is happening.
Include error messages or incorrect results.
-->
### Expected Behavior
<!--
A concise description of what you expected to happen instead.
-->
### Steps To Reproduce & Observed Output
<!--
Provide exact, reproducible steps together with full stdout/stderr for each.
-->
1. Signing with osslsigncode
<!--
Full `osslsigncode sign` command and complete stdout/stderr output.
-->
2. Verification with osslsigncode
<!--
Full `osslsigncode verify` command and complete stdout/stderr output.
-->
3. Signing / verification with Windows signtool (if applicable)
<!--
Full signtool command (`signtool verify /pa /v`) and complete stdout/stderr output.
-->
### Environment
- Operating system and version (e.g. Ubuntu 24.04):
- Architecture (x86_64, arm64, etc.):
### Versions
<!--
Please verify that the issue is reproducible with the current upstream master.
-->
- osslsigncode built from:
- [ ] upstream master
- [ ] upstream release (tag):
- [ ] distribution package (name and version):
- `openssl version -a`
- `osslsigncode --version`
### Files
<!--
Attach files if possible, or mention that you will share them privately.
-->
- [ ] unsigned file
- [ ] file signed with osslsigncode
- [ ] file signed with signtool or the other tool (for comparison)
- [ ] certificate chain used for verification (PEM format)
### Configuration / Settings
<!--
Anything that could affect signing or verification:
- Custom OpenSSL configuration
- Engine / provider settings
- Environment variables (OPENSSL_CONF, etc.)
-->
### Anything else
<!--
Links, references, related issues, workarounds or additional observations.
-->
+65
View File
@@ -0,0 +1,65 @@
<!--
Thank you for your pull request.
Provide a concise summary of the changes in the PR title.
-->
### Pull Request Type
<!--
Limit this PR to a single type. If necessary, split changes into multiple PRs.
-->
- [ ] Bug fix
- [ ] New feature
- [ ] Code style / formatting / renaming
- [ ] Refactoring (no functional or API changes)
- [ ] Build / CI related changes
- [ ] Documentation
- [ ] Other (please describe):
### Related Issue
<!--
If this fixes a GitHub issue, make sure to have a line saying 'Fixes #XXXX' (without quotes) in the commit message.
-->
Issue number: N/A
### Current Behavior
<!--
Describe the current behavior or limitation this PR addresses.
Include error messages or crash symptoms if relevant.
-->
### New Behavior
<!--
Describe the new or changed behavior introduced by this PR.
-->
### Scope of Changes
<!--
Briefly describe what was changed and why.
Focus on relevant parts only.
-->
### Testing
<!--
Describe how the changes were tested.
Include commands, environments, or platforms if relevant.
-->
- [ ] Existing tests
- [ ] New tests added
- [ ] Manual testing
### Additional Notes
<!--
Any additional information relevant for reviewers:
- design decisions
- backward compatibility
- known limitations
-->
## License Declaration
<!--
All contributions to this project are licensed under the project's license.
By submitting this pull request, you confirm that you have the right to submit
the code and agree to license it accordingly.
-->
- [ ] I hereby agree to license my contribution under the project's license.
+93 -55
View File
@@ -1,4 +1,4 @@
name: CI
name: Continuous Integration
on:
push:
@@ -7,7 +7,7 @@ on:
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
version: osslsigncode-2.8
version: osslsigncode-2.14-dev
jobs:
build:
@@ -15,20 +15,20 @@ jobs:
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: x64-osx
triplet: arm64-osx
compiler: clang
os: macOS-latest
generator: Unix Makefiles
@@ -72,11 +72,11 @@ jobs:
VCPKG_ROOT: ${{matrix.vcpkg_root}}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Cache the vcpkg archives
if: matrix.cache != ''
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{matrix.cache}}
key: ${{matrix.id}}-${{hashFiles('vcpkg.json')}}
@@ -101,16 +101,23 @@ jobs:
if: matrix.compiler == 'mingw'
run: echo "D:/a/_temp/msys64/mingw64/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Install apt dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y libssl-dev libcurl4-openssl-dev faketime
- name: Install brew dependencies (macOS)
- 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: |
brew install python@3.8
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'
@@ -120,46 +127,67 @@ jobs:
- name: Setup the oldest supported version of cmake (macOS)
if: runner.os == 'macOS'
uses: jwlawson/actions-setup-cmake@v1.12
with:
cmake-version: '3.17.0'
uses: jwlawson/actions-setup-cmake@v2.0
- name: Show OpenSSL version
run: openssl version -a
- 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: Configure CMake
run: cmake
-G "${{matrix.generator}}"
-S ${{github.workspace}}
-B ${{github.workspace}}/build
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
-DCMAKE_INSTALL_PREFIX=${{github.workspace}}/dist
-DVCPKG_TARGET_TRIPLET=${{matrix.triplet}}
- 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: Start HTTP server (macOS)
working-directory: ${{github.workspace}}/build
if: runner.os == 'macOS'
run: |
python3.8 --version
python3.8 ./Testing/server_http.py --port 19254
while test ! -s ./Testing/logs/port.log; do sleep 1; done
- name: Start HTTP server (Windows)
working-directory: ${{github.workspace}}\build
if: runner.os == 'Windows'
run: |
python.exe --version
$Args = '.\Testing\server_http.pyw --port 19254'
$File = '.\Testing\logs\port.log'
Start-Process -FilePath pythonw.exe -ArgumentList $Args
while(-not(Test-Path -Path $File -PathType Leaf) -or [String]::IsNullOrWhiteSpace((Get-Content $File))) {Start-Sleep -Seconds 1}
Get-Content '.\Testing\logs\server.log'
- name: List files (Linux/macOS)
if: runner.os != 'Windows'
run: find .. -ls
@@ -168,12 +196,22 @@ jobs:
if: runner.os == 'Windows'
run: Get-ChildItem -Recurse -Name ..
- name: Test
- name: Test (Linux/macOS)
if: runner.os != 'Windows'
working-directory: ${{github.workspace}}/build
run: ctest -C ${{env.BUILD_TYPE}}
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@v3
uses: actions/upload-artifact@v4
if: failure()
with:
name: errors-${{matrix.id}}
@@ -187,7 +225,7 @@ jobs:
run: cmake --install ${{github.workspace}}/build
- name: Upload the executables
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{env.version}}-${{matrix.id}}
path: ${{github.workspace}}/dist
+4 -4
View File
@@ -25,11 +25,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
@@ -43,7 +43,7 @@ jobs:
# 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@v2
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
@@ -56,4 +56,4 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
+16
View File
@@ -0,0 +1,16 @@
name: Codespell
on:
pull_request:
push:
jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: codespell-project/actions-codespell@master
with:
skip: '*.pem'
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
env:
token: ${{secrets.COVERITY_SCAN_TOKEN}}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
if: env.token
- name: Get ready for scanning
if: env.token
+41 -9
View File
@@ -3,20 +3,20 @@ 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(DEFINED ENV{VCPKG_ROOT} AND NOT $ENV{VCPKG_ROOT} STREQUAL "" AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
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(DEFINED ENV{VCPKG_ROOT} AND NOT $ENV{VCPKG_ROOT} STREQUAL "" AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
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.8
DESCRIPTION "OpenSSL based Authenticode signing for PE, CAB, CAT and MSI files"
VERSION 2.14
DESCRIPTION "OpenSSL based Authenticode signing for PE, CAB, CAT, MSI, APPX and script files"
HOMEPAGE_URL "https://github.com/mtrojnar/osslsigncode"
LANGUAGES C)
# force nonstandard version format for development packages
set(DEV "")
set(DEV "-dev")
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}${DEV}")
# version and contact information
@@ -29,7 +29,12 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
# load CMake library modules
include(FindOpenSSL)
include(FindCURL)
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
@@ -64,6 +69,7 @@ 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})
@@ -72,6 +78,7 @@ if(CURL_FOUND)
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")
@@ -79,20 +86,36 @@ 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)
# documentation with Pandoc
include(CMakeDoc)
# installation rules for a project
set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin")
install(TARGETS osslsigncode RUNTIME DESTINATION ${BINDIR})
include(GNUInstallDirs)
install(TARGETS osslsigncode RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES
"${PROJECT_SOURCE_DIR}/README.md"
"${PROJECT_SOURCE_DIR}/NEWS.md"
DESTINATION "${CMAKE_INSTALL_DOCDIR}")
if(UNIX)
include(CMakeDist)
else(UNIX)
install(
DIRECTORY ${PROJECT_BINARY_DIR}/ DESTINATION ${BINDIR}
DIRECTORY ${PROJECT_BINARY_DIR}/
DESTINATION ${CMAKE_INSTALL_BINDIR}
FILES_MATCHING
PATTERN "*.dll"
PATTERN "vcpkg_installed" EXCLUDE
@@ -100,6 +123,15 @@ else(UNIX)
PATTERN "Testing" EXCLUDE)
endif(UNIX)
# uninstall target
configure_file(
"${PROJECT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${PROJECT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P "${PROJECT_BINARY_DIR}/cmake_uninstall.cmake")
#[[
Local Variables:
c-basic-offset: 4
+2 -2
View File
@@ -2,7 +2,7 @@
FROM alpine:latest AS builder
# Install build dependencies
RUN apk add --no-cache build-base cmake openssl-dev curl-dev
RUN apk add --no-cache build-base cmake openssl-dev zlib-dev
# Copy osslsigncode source code into the image
COPY . /source
@@ -23,7 +23,7 @@ FROM alpine:latest
COPY --from=builder /usr/local/bin/osslsigncode /usr/local/bin/osslsigncode
# Install necessary runtime libraries (latest version)
RUN apk add --no-cache libcrypto3 libcurl
RUN apk add --no-cache libcrypto3
# Set working directory
WORKDIR /workdir
+30 -56
View File
@@ -3,50 +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.
Once up and running install the following packages:
```
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-curl
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 *.c -o osslsigncode.exe \
-lcrypto -lssl -lcurl \
-D 'PACKAGE_STRING="osslsigncode x.y"' \
-D 'PACKAGE_BUGREPORT="Your.Email@example.com"' \
-D ENABLE_CURL
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.4, using:
OpenSSL 1.1.1g 21 Apr 2020 (Library: 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
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.
@@ -55,46 +45,30 @@
./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 --without-zstd --without-zlib
make && make install
```
3) Build 64-bit Windows executables.
3) Configure a CMake project.
```
cd osslsigncode-folder
x86_64-w64-mingw32-gcc *.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 x.y"' \
-D 'PACKAGE_BUGREPORT="Your.Email@example.com"' \
-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
osslsigncode.exe -v
osslsigncode 2.4, using:
OpenSSL 1.1.1k 25 Mar 2021 (Library: OpenSSL 1.1.1k 25 Mar 2021)
libcurl/7.78.0 OpenSSL/1.1.1k
copy C:\OpenSSL\bin\libssl-3-x64.dll
copy C:\OpenSSL\bin\libcrypto-3-x64.dll
```
### Building OpenSSL, Curl and osslsigncode sources with Microsoft Visual Studio:
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
+1 -1
View File
@@ -1,4 +1,4 @@
OpenSSL based Authenticode signing for PE/MSI/Java CAB files.
OpenSSL based Authenticode signing for PE, CAB, CAT, MSI, APPX and script files.
Copyright (C) 2005-2014 Per Allansson <pallansson@gmail.com>
Copyright (C) 2018-2022 Michał Trojnara <Michal.Trojnara@stunnel.org>
+74
View File
@@ -1,5 +1,79 @@
# osslsigncode change log
### 2.14 (unreleased)
- attach-signature now uses digest-only verification instead of full signature
validation; output file is not kept if digest verification fails
### 2.13 (2026.02.10)
**MULTIPLE SECURITY VULNERABILITIES**
This release includes important security fixes. Users are strongly encouraged
to upgrade, as the issues below may be exploitable when processing untrusted
files.
- fixed integer overflows when processing APPX compressed data streams
(by Małgorzata Olszówka)
- fixed double-free vulnerabilities in APPX file processing
(by Małgorzata Olszówka)
- fixed multiple memory corruption issues in PE page hash computation
(by Antoni Klajn (Opera) and Małgorzata Olszówka)
### 2.12 (2026.02.02)
**CRITICAL SECURITY VULNERABILITY**
This release fixes a critical memory corruption vulnerability. A malicious
attacker could create a signed file, which, when verified with osslsigncode,
triggers arbitrary code execution. Any previous version of osslsigncode should
be immediately upgraded if the tool is used for verification of untrusted
files.
- fixed a buffer overflow while extracting message digests
(reported and fixed by Antoni Klajn, Opera)
### 2.11 (2026.01.20)
- added keyUsage validation for signer certificate
(thanks to Hanqing Zhao and Zi-Quan You for reporting the issue)
- added printing CRL details during signature verification
- implemented a workaround for CRL servers returning the HTTP Content-Type
header other than application/pkix-crl (thanks to Chris Thibodeaux)
- fixed HTTP keep-alive handling
- fixed macOS compiler and linker flags
- fixed undefined BIO_get_fp() behavior with BIO_FLAGS_UPLINK_INTERNAL
### 2.10 (2025.06.23)
- added JavaScript signing
- added PKCS#11 provider support (requires OpenSSL 3.0+)
- added support for providers without specifying "-pkcs11module" option
(OpenSSL 3.0+, e.g., for the upcoming CNG provider)
- added compatibility with the CNG engine version 1.1 or later
- added the "-engineCtrl" option to control hardware and CNG engines
- added the '-blobFile' option to specify a file containing the blob content
- improved unauthenticated blob support (thanks to Asger Hautop Drewsen)
- improved UTF-8 handling for certificate subjects and issuers
- fixed support for multiple signerInfo contentType OIDs (CTL and Authenticode)
- fixed tests for python-cryptography >= 43.0.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.
+61 -8
View File
@@ -19,11 +19,13 @@ machine every time I need to sign a binary - I can compile and build
the binaries using Wine on my Linux machine, but I can't sign them
since the signtool.exe makes good use of the CryptoAPI in Windows, and
these APIs aren't (yet?) fully implemented in Wine, so the signtool.exe
tool would fail. And, so, osslsigncode was born.
tool would fail. And, so, osslsigncode was born.
## WHAT CAN IT DO?
It can sign and timestamp PE (EXE/SYS/DLL/etc), CAB, CAT and MSI files.
It can sign and timestamp PE (EXE/SYS/DLL/etc), CAB, CAT, MSI and APPX files,
as well as script files with extensions `.ps1`, `.ps1xml`, `.psc1`, `.psd1`,
`.psm1`, `.cdxml`, `.mof`, and `.js`.
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
@@ -122,7 +124,7 @@ You can use a certificate and key stored in a PKCS#12 container:
-n "Your Application" -i http://www.yourwebsite.com/ \
-in yourapp.exe -out yourapp-signed.exe
```
To sign a CAB file containing java class files:
To sign a CAB file containing Java class files:
```
osslsigncode sign -certs <cert-file> -key <key-file> \
-n "Your Application" -i http://www.yourwebsite.com/ \
@@ -131,17 +133,68 @@ 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.
An example of using osslsigncode with SoftHSM:
### Using the PKCS#11 Engine with osslsigncode
If you want to use a PKCS#11 token, specify the PKCS#11 engine and module.
Example usage 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 \
-pkcs11cert 'pkcs11:token=softhsm-token;object=cert' \
-key 'pkcs11:token=softhsm-token;object=key' \
-in yourapp.exe -out yourapp-signed.exe
```
### Using the PKCS#11 Provider with osslsigncode (OpenSSL 3.x only)
OpenSSL 3.0 introduced a new provider-based architecture. To use a PKCS#11 token
with `osslsigncode`, specify the PKCS#11 provider and module.
Example usage 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
```
### Using the CNG Engine with osslsigncode (Windows only)
The CNG engine allows using certificates and keys stored in the Windows
Certificate Store. It requires 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 ensure `osslsigncode` can locate and load the CNG engine module (`cng.dll`)
even when it is not installed in the default system engine directory, you can:
- Specify the full or relative path to `cng.dll`:
```
osslsigncode sign -engine C:\my\engines\cng.dll ...
```
- Or set the `OPENSSL_ENGINES` environment variable to the directory containing
`cng.dll`, and refer to the engine by its ID:
```
set OPENSSL_ENGINES=C:\my\engines
osslsigncode sign -engine cng ...
```
Below is an example of how to use `osslsigncode` with the CNG engine on Windows:
```
set OPENSSL_ENGINES=C:\my\engines
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,
and then choose the signature from the list, and click on
@@ -179,13 +232,13 @@ osslsigncode.exe add -addUnauthenticatedBlob -in your_signed_file.exe -out out.e
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
file. If you 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.
Check whether your your question or suspected bug was already
Check whether your question or suspected bug was already
discussed on https://github.com/mtrojnar/osslsigncode/issues.
Otherwise, open a new issue.
+1 -1
View File
@@ -1,4 +1,4 @@
- signature extraction/removal/verificaton on MSI/CAB files
- signature extraction/removal/verification on MSI/CAB files
- clean up / untangle code
- separate timestamping
- remove mmap usage to increase portability
+279 -145
View File
File diff suppressed because it is too large Load Diff
+86 -63
View File
@@ -205,11 +205,18 @@ static u_char *cab_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
u_char *mdbuf = NULL;
BIO *bhash = BIO_new(BIO_f_md());
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n");
fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash);
return 0; /* FAILED */
}
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(bhash, BIO_new(BIO_s_null()));
/* u1 signature[4] 4643534D MSCF: 0-3 */
@@ -296,7 +303,7 @@ static u_char *cab_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
nfolders--;
}
if (idx != coffFiles) {
printf("Corrupt coffFiles value: 0x%08X\n", coffFiles);
fprintf(stderr, "Corrupt coffFiles value: 0x%08X\n", coffFiles);
BIO_free_all(bhash);
return 0; /* FAILED */
}
@@ -307,7 +314,7 @@ static u_char *cab_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
}
/* (variable) ab - the compressed data bytes */
if (!bio_hash_data(bhash, ctx->options->indata, idx, fileend)) {
printf("Unable to calculate digest\n");
fprintf(stderr, "Unable to calculate digest\n");
BIO_free_all(bhash);
return 0; /* FAILED */
}
@@ -330,30 +337,18 @@ static int cab_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
u_char mdbuf[EVP_MAX_MD_SIZE];
u_char *cmdbuf;
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) {
printf("Failed to extract current message digest\n\n");
if (!pkcs7_get_content_digest(p7, mdbuf, &mdtype)) {
fprintf(stderr, "Failed to extract current message digest\n\n");
return 0; /* FAILED */
}
md = EVP_get_digestbynid(mdtype);
cmdbuf = cab_digest_calc(ctx, md);
if (!cmdbuf) {
printf("Failed to calculate message digest\n\n");
fprintf(stderr, "Failed to calculate message digest\n\n");
return 0; /* FAILED */
}
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
printf("Signature verification: failed\n\n");
fprintf(stderr, "Signature verification: failed\n\n");
OPENSSL_free(cmdbuf);
return 0; /* FAILED */
}
@@ -396,7 +391,7 @@ static PKCS7 *cab_pkcs7_extract_to_nest(FILE_FORMAT_CTX *ctx)
*/
static int cab_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
{
size_t i, written, len;
size_t idx, written, len;
uint32_t tmp;
uint16_t nfolders, flags;
char *buf;
@@ -441,29 +436,39 @@ static int cab_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
* u2 iCabinet - number of this cabinet file in a set: 34-35
*/
BIO_write(outdata, ctx->options->indata + 32, 4);
i = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
idx = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
if (idx >= ctx->cab_ctx->fileend) {
fprintf(stderr, "Corrupt CAB file - too short\n");
OPENSSL_free(buf);
return 0; /* FAILED */
}
/*
* (u8 * cFolders) CFFOLDER - structure contains information about
* one of the folders or partial folders stored in this cabinet file
*/
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) {
fprintf(stderr, "Corrupt cFolders value: 0x%08X\n", nfolders);
OPENSSL_free(buf);
return 0; /* FAILED */
}
while (nfolders) {
tmp = GET_UINT32_LE(ctx->options->indata + i);
tmp = GET_UINT32_LE(ctx->options->indata + idx);
tmp -= 24;
PUT_UINT32_LE(tmp, buf);
BIO_write(outdata, buf, 4);
BIO_write(outdata, ctx->options->indata + i + 4, 4);
i+=8;
BIO_write(outdata, ctx->options->indata + idx + 4, 4);
idx += 8;
nfolders--;
}
OPENSSL_free(buf);
/* Write what's left - the compressed data bytes */
len = ctx->cab_ctx->fileend - ctx->cab_ctx->siglen - i;
len = ctx->cab_ctx->fileend - ctx->cab_ctx->siglen - idx;
while (len > 0) {
if (!BIO_write_ex(outdata, ctx->options->indata + i, len, &written))
if (!BIO_write_ex(outdata, ctx->options->indata + idx, len, &written))
return 1; /* FAILED */
len -= written;
i += written;
idx += written;
}
return 0; /* OK */
}
@@ -480,12 +485,12 @@ static int cab_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
/* Strip current signature and modify header */
if (ctx->cab_ctx->header_size == 20) {
if (!cab_modify_header(ctx, hash, outdata))
return 1; /* FAILED */
return 0; /* FAILED */
} else {
if (!cab_add_header(ctx, hash, outdata))
return 1; /* FAILED */
return 0; /* FAILED */
}
return 0; /* OK */
return 1; /* OK */
}
/*
@@ -500,26 +505,26 @@ static PKCS7 *cab_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
PKCS7 *p7 = pkcs7_create(ctx);
if (!p7) {
printf("Creating a new signature failed\n");
fprintf(stderr, "Creating a new signature failed\n");
return NULL; /* FAILED */
}
if (ctx->options->jp >= 0 && !cab_add_jp_attribute(p7, ctx->options->jp)) {
printf("Adding jp attribute failed\n");
fprintf(stderr, "Adding jp attribute failed\n");
PKCS7_free(p7);
return NULL; /* FAILED */
}
if (!add_indirect_data_object(p7)) {
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n");
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) {
printf("Failed to get spcIndirectDataContent\n");
fprintf(stderr, "Failed to get spcIndirectDataContent\n");
return NULL; /* FAILED */
}
if (!sign_spc_indirect_data_content(p7, content)) {
printf("Failed to set signed content\n");
fprintf(stderr, "Failed to set signed content\n");
PKCS7_free(p7);
ASN1_OCTET_STRING_free(content);
return NULL; /* FAILED */
@@ -546,7 +551,7 @@ static int cab_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
if (((len = i2d_PKCS7(p7, NULL)) <= 0)
|| (p = OPENSSL_malloc((size_t)len)) == NULL) {
printf("i2d_PKCS memory allocation failed: %d\n", len);
fprintf(stderr, "i2d_PKCS memory allocation failed: %d\n", len);
return 1; /* FAILED */
}
i2d_PKCS7(p7, &p);
@@ -643,19 +648,19 @@ static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize)
uint16_t flags;
if (filesize < 44) {
printf("CAB file is too short\n");
fprintf(stderr, "CAB file is too short\n");
return NULL; /* FAILED */
}
reserved = GET_UINT32_LE(indata + 4);
if (reserved) {
printf("Reserved1: 0x%08X\n", reserved);
fprintf(stderr, "Reserved1: 0x%08X\n", reserved);
return NULL; /* FAILED */
}
/* flags specify bit-mapped values that indicate the presence of optional data */
flags = GET_UINT16_LE(indata + 30);
if (flags & FLAG_PREV_CABINET) {
/* FLAG_NEXT_CABINET works */
printf("Multivolume cabinet file is unsupported: flags 0x%04X\n", flags);
fprintf(stderr, "Multivolume cabinet file is unsupported: flags 0x%04X\n", flags);
return NULL; /* FAILED */
}
if (flags & FLAG_RESERVE_PRESENT) {
@@ -665,12 +670,12 @@ static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize)
*/
header_size = GET_UINT32_LE(indata + 36);
if (header_size != 20) {
printf("Additional header size: 0x%08X\n", header_size);
fprintf(stderr, "Additional header size: 0x%08X\n", header_size);
return NULL; /* FAILED */
}
reserved = GET_UINT32_LE(indata + 40);
if (reserved != 0x00100000) {
printf("abReserved: 0x%08X\n", reserved);
fprintf(stderr, "abReserved: 0x%08X\n", reserved);
return NULL; /* FAILED */
}
/*
@@ -679,19 +684,19 @@ static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize)
* and consist of 4 bytes (little-endian order)
* siglen - additional data size is located at offset 48 (from file beginning)
* and consist of 4 bytes (little-endian order)
* If there are additional headers, size of the CAB archive file is calcualted
* If there are additional headers, size of the CAB archive file is calculated
* as additional data offset plus additional data size.
*/
sigpos = GET_UINT32_LE(indata + 44);
siglen = GET_UINT32_LE(indata + 48);
if ((sigpos < filesize && sigpos + siglen != filesize) || (sigpos >= filesize)) {
printf("Additional data offset:\t%u bytes\nAdditional data size:\t%u bytes\n",
fprintf(stderr, "Additional data offset:\t%u bytes\nAdditional data size:\t%u bytes\n",
sigpos, siglen);
printf("File size:\t\t%u bytes\n", filesize);
fprintf(stderr, "File size:\t\t%u bytes\n", filesize);
return NULL; /* FAILED */
}
if ((sigpos > 0 && siglen == 0) || (sigpos == 0 && siglen > 0)) {
printf("Corrupt signature\n");
fprintf(stderr, "Corrupt signature\n");
return NULL; /* FAILED */
}
}
@@ -802,7 +807,7 @@ static size_t cab_write_optional_names(BIO *outdata, char *indata, size_t i, uin
*/
static int cab_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
{
size_t i, written, len;
size_t idx, written, len;
uint16_t nfolders, flags;
u_char buf[] = {0x00, 0x00};
@@ -840,24 +845,32 @@ static int cab_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
/* u4 abReserve: 56-59 */
BIO_write(hash, ctx->options->indata + 56, 4);
i = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
idx = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
if (idx >= ctx->cab_ctx->fileend) {
fprintf(stderr, "Corrupt CAB file - too short\n");
return 0; /* FAILED */
}
/*
* (u8 * cFolders) CFFOLDER - structure contains information about
* one of the folders or partial folders stored in this cabinet file
*/
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) {
fprintf(stderr, "Corrupt cFolders value: 0x%08X\n", nfolders);
return 0; /* FAILED */
}
while (nfolders) {
BIO_write(hash, ctx->options->indata + i, 8);
i += 8;
BIO_write(hash, ctx->options->indata + idx, 8);
idx += 8;
nfolders--;
}
/* Write what's left - the compressed data bytes */
len = ctx->cab_ctx->sigpos - i;
len = ctx->cab_ctx->sigpos - idx;
while (len > 0) {
if (!BIO_write_ex(hash, ctx->options->indata + i, len, &written))
if (!BIO_write_ex(hash, ctx->options->indata + idx, len, &written))
return 0; /* FAILED */
len -= written;
i += written;
idx += written;
}
return 1; /* OK */
}
@@ -871,7 +884,7 @@ static int cab_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
*/
static int cab_add_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
{
size_t i, written, len;
size_t idx, written, len;
uint32_t tmp;
uint16_t nfolders, flags;
u_char cabsigned[] = {
@@ -916,29 +929,39 @@ static int cab_add_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
BIO_write(outdata, cabsigned, 20);
BIO_write(hash, cabsigned+20, 4);
i = cab_write_optional_names(outdata, ctx->options->indata, 36, flags);
idx = cab_write_optional_names(outdata, ctx->options->indata, 36, flags);
if (idx >= ctx->cab_ctx->fileend) {
fprintf(stderr, "Corrupt CAB file - too short\n");
OPENSSL_free(buf);
return 0; /* FAILED */
}
/*
* (u8 * cFolders) CFFOLDER - structure contains information about
* one of the folders or partial folders stored in this cabinet file
*/
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) {
fprintf(stderr, "Corrupt cFolders value: 0x%08X\n", nfolders);
OPENSSL_free(buf);
return 0; /* FAILED */
}
while (nfolders) {
tmp = GET_UINT32_LE(ctx->options->indata + i);
tmp = GET_UINT32_LE(ctx->options->indata + idx);
tmp += 24;
PUT_UINT32_LE(tmp, buf);
BIO_write(hash, buf, 4);
BIO_write(hash, ctx->options->indata + i + 4, 4);
i += 8;
BIO_write(hash, ctx->options->indata + idx + 4, 4);
idx += 8;
nfolders--;
}
OPENSSL_free(buf);
/* Write what's left - the compressed data bytes */
len = ctx->cab_ctx->fileend - i;
len = ctx->cab_ctx->fileend - idx;
while (len > 0) {
if (!BIO_write_ex(hash, ctx->options->indata + i, len, &written))
if (!BIO_write_ex(hash, ctx->options->indata + idx, len, &written))
return 0; /* FAILED */
len -= written;
i += written;
idx += written;
}
return 1; /* OK */
}
@@ -951,16 +974,16 @@ static int cab_add_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
static int cab_check_file(FILE_FORMAT_CTX *ctx)
{
if (!ctx) {
printf("Init error\n\n");
fprintf(stderr, "Init error\n");
return 0; /* FAILED */
}
if (ctx->cab_ctx->header_size != 20) {
printf("No signature found\n\n");
fprintf(stderr, "No signature found\n");
return 0; /* FAILED */
}
if (ctx->cab_ctx->sigpos == 0 || ctx->cab_ctx->siglen == 0
|| ctx->cab_ctx->sigpos > ctx->cab_ctx->fileend) {
printf("No signature found\n\n");
fprintf(stderr, "No signature found\n");
return 0; /* FAILED */
}
return 1; /* OK */
+71 -39
View File
@@ -55,8 +55,8 @@ FILE_FORMAT file_format_cat = {
/* Prototypes */
static CAT_CTX *cat_ctx_get(char *indata, uint32_t filesize);
static int cat_add_ms_ctl_object(PKCS7 *p7);
static int cat_sign_ms_ctl_content(PKCS7 *p7, PKCS7 *contents);
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);
@@ -82,7 +82,7 @@ static FILE_FORMAT_CTX *cat_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *out
uint32_t filesize;
if (options->cmd == CMD_REMOVE || options->cmd==CMD_ATTACH || options->cmd == CMD_EXTRACT_DATA) {
printf("Unsupported command\n");
fprintf(stderr, "Unsupported command\n");
return NULL; /* FAILED */
}
filesize = get_file_size(options->infile);
@@ -158,18 +158,23 @@ static PKCS7 *cat_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
p7 = pkcs7_create(ctx);
if (!p7) {
printf("Creating a new signature failed\n");
fprintf(stderr, "Creating a new signature failed\n");
return NULL; /* FAILED */
}
if (!cat_add_ms_ctl_object(p7)) {
printf("Adding MS_CTL_OBJID failed\n");
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_sign_ms_ctl_content(p7, ctx->cat_ctx->p7->d.sign->contents)) {
printf("Failed to set signed content\n");
if (!cat_add_content_type(p7, ctx->cat_ctx->p7)) {
fprintf(stderr, "Adding content type failed\n");
PKCS7_free(p7);
return 0; /* FAILED */
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 */
}
@@ -246,15 +251,30 @@ static CAT_CTX *cat_ctx_get(char *indata, uint32_t filesize)
}
/*
* Add "1.3.6.1.4.1.311.10.1" MS_CTL_OBJID signed attribute
* 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_ms_ctl_object(PKCS7 *p7)
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 */
@@ -262,7 +282,7 @@ static int cat_add_ms_ctl_object(PKCS7 *p7)
if (!si)
return 0; /* FAILED */
if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
V_ASN1_OBJECT, OBJ_txt2obj(MS_CTL_OBJID, 1)))
V_ASN1_OBJECT, OBJ_txt2obj(content_type, 1)))
return 0; /* FAILED */
return 1; /* OK */
}
@@ -275,24 +295,41 @@ static int cat_add_ms_ctl_object(PKCS7 *p7)
* [in] contents: Certificate Trust List (CTL)
* [returns] 0 on error or 1 on success
*/
static int cat_sign_ms_ctl_content(PKCS7 *p7, PKCS7 *contents)
static int cat_sign_content(PKCS7 *p7, PKCS7 *contents)
{
u_char *content;
int seqhdrlen, content_length;
const unsigned char *sequence_data;
const unsigned char *content;
ASN1_STRING *sequence;
int seqhdrlen, sequence_len, content_length;
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 (!contents->d.other || !contents->d.other->value.sequence) {
fprintf(stderr, "Failed to get content value\n");
return 0; /* FAILED */
}
sequence = contents->d.other->value.sequence;
sequence_data = ASN1_STRING_get0_data(sequence);
sequence_len = ASN1_STRING_length(sequence);
if (!sequence_data) {
fprintf(stderr, "Failed to get content value\n");
return 0; /* FAILED */
}
seqhdrlen = asn1_simple_hdr_len(sequence_data, sequence_len);
content = (const unsigned char *)sequence_data + seqhdrlen;
content_length = sequence_len - seqhdrlen;
if (!pkcs7_sign_content(p7, content, content_length)) {
printf("Failed to sign content\n");
fprintf(stderr, "Failed to sign content\n");
return 0; /* FAILED */
}
if (!PKCS7_set_content(p7, PKCS7_dup(contents))) {
printf("PKCS7_set_content failed\n");
fprintf(stderr, "PKCS7_set_content failed\n");
return 0; /* FAILED */
}
return 1; /* OK */
}
@@ -308,7 +345,7 @@ static int cat_list_content(PKCS7 *p7)
ctlc = ms_ctl_content_get(p7);
if (!ctlc) {
printf("Failed to extract MS_CTL_OBJID data\n");
fprintf(stderr, "Failed to extract MS_CTL_OBJID data\n");
return 1; /* FAILED */
}
printf("\nCatalog members:\n");
@@ -343,7 +380,7 @@ static int cat_list_content(PKCS7 *p7)
printf("\n");
}
MsCtlContent_free(ctlc);
ERR_print_errors_fp(stdout);
ERR_print_errors_fp(stderr);
return 0; /* OK */
}
@@ -356,27 +393,22 @@ 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));
idc = asn1_type_get_indirect_data_content(content);
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) {
printf("Failed to extract current message digest\n\n");
if (spc_indirect_data_content_get_digest(idc, mdbuf, &mdtype) < 0) {
fprintf(stderr, "Failed to extract message digest from signature\n\n");
SpcIndirectDataContent_free(idc);
return 0; /* FAILED */
}
SpcIndirectDataContent_free(idc);
printf("\tHash algorithm: %s\n", OBJ_nid2sn(mdtype));
print_hash("\tMessage digest", "", mdbuf, EVP_MD_size(EVP_get_digestbynid(mdtype)));
return 1; /* OK */
}
@@ -451,17 +483,17 @@ static int cat_check_file(FILE_FORMAT_CTX *ctx)
PKCS7_SIGNER_INFO *si;
if (!ctx) {
printf("Init error\n\n");
fprintf(stderr, "Init error\n");
return 0; /* FAILED */
}
signer_info = PKCS7_get_signer_info(ctx->cat_ctx->p7);
if (!signer_info) {
printf("Failed catalog file\n\n");
fprintf(stderr, "Failed catalog file\n");
return 0; /* FAILED */
}
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
if (!si) {
printf("No signature found\n\n");
fprintf(stderr, "No signature found\n");
return 0; /* FAILED */
}
if (ctx->options->verbose) {
+1 -1
View File
@@ -3,7 +3,7 @@
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_DESCRIPTION_SUMMARY "OpenSSL based Authenticode signing for PE, CAB, CAT, MSI, APPX and script 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")
+44
View File
@@ -0,0 +1,44 @@
# documentation with Pandoc
# cmake --build .
find_program(PANDOC pandoc)
if(NOT PANDOC)
message(WARNING "CMakeDoc: pandoc not found, documentation disabled")
return()
endif(NOT PANDOC)
set(DOC_MD "${PROJECT_SOURCE_DIR}/osslsigncode.md")
if(NOT EXISTS "${DOC_MD}")
message(WARNING "CMakeDoc: markdown source not found: ${DOC_MD}")
return()
endif(NOT EXISTS "${DOC_MD}")
set(MAN_PAGE "${PROJECT_BINARY_DIR}/osslsigncode.1")
set(HTML_PAGE "${PROJECT_BINARY_DIR}/osslsigncode.html")
add_custom_command(
OUTPUT "${MAN_PAGE}"
COMMAND "${PANDOC}" -s "${DOC_MD}" -t man -o "${MAN_PAGE}"
DEPENDS "${DOC_MD}"
COMMENT "CMakeDoc: generating man page"
VERBATIM)
add_custom_command(
OUTPUT "${HTML_PAGE}"
COMMAND "${PANDOC}" -s --toc --toc-depth=2 "${DOC_MD}" -t html -o "${HTML_PAGE}"
DEPENDS "${DOC_MD}"
COMMENT "CMakeDoc: generating HTML documentation"
VERBATIM)
add_custom_target(docs ALL DEPENDS "${MAN_PAGE}" "${HTML_PAGE}")
#[[
Local Variables:
c-basic-offset: 4
tab-width: 4
indent-tabs-mode: nil
End:
vim: set ts=4 expandtab:
]]
+513 -664
View File
File diff suppressed because it is too large Load Diff
+4 -9
View File
@@ -96,16 +96,11 @@ function(add_compile_flags target)
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))))
# Support address space layout randomization (ASLR) / PIE
if(UNIX AND NOT APPLE)
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 -fPIE -pie -Wl,-z,relro,-z,now,-z,noexecstack)
endif(UNIX AND NOT APPLE)
target_link_options(${target} PRIVATE -fstack-check)
add_compile_flag_to_targets(${target})
endif(MSVC)
+24
View File
@@ -0,0 +1,24 @@
# uninstall target
#
# CMake does not provide a built-in uninstall target.
# This target removes files listed in install_manifest.txt,
# generated by the install step.
#
# cmake --build . --target uninstall
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest")
endif()
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Removing ${file}")
if(EXISTS "${file}" OR IS_SYMLINK "${file}")
file(REMOVE "${file}")
else()
message(STATUS "File does not exist: ${file}")
endif()
endforeach()
+9741
View File
File diff suppressed because it is too large Load Diff
+52
View File
@@ -0,0 +1,52 @@
#!/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
from re import search
def download_cert(hash):
for attempt in range(10):
if attempt > 0:
sleep(10)
try:
creds = f'{attempt}{hash}:{attempt}{hash}'
proxies = dict(https=f'socks5://{creds}@127.0.0.1:9050')
url = f'https://crt.sh/?sha1={hash}&match=='
resp = get(url, proxies=proxies)
resp.raise_for_status()
m = search(r'\bid=(\d+)\b', resp.content.decode('ascii', 'replace'))
id = m.group(1)
url = f'https://crt.sh/?d={id}'
resp = get(url, proxies=proxies)
resp.raise_for_status()
print('.', file=stderr, end='')
stderr.flush()
return resp.content.decode('utf-8', 'replace')
except Exception as e:
print(f'\n{url} attempt {attempt}: {e}', file=stderr)
print('\nGiving up on', hash, file=stderr)
resp = get('https://ccadb.my.salesforce-sites.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=10) as executor:
certs = executor.map(download_cert, hashes)
for cert in certs:
if cert is not None:
print(cert)
print('\nDone', file=stderr)
+237 -56
View File
@@ -17,6 +17,7 @@ static int pkcs7_signer_info_add_purpose(PKCS7_SIGNER_INFO *si, FILE_FORMAT_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);
static void sk_X509_remove_duplicates(STACK_OF(X509) *chain);
/*
* Common functions
@@ -37,16 +38,16 @@ uint32_t get_file_size(const char *infile)
ret = stat(infile, &st);
#endif
if (ret) {
printf("Failed to open file: %s\n", infile);
fprintf(stderr, "Failed to open file: %s\n", infile);
return 0;
}
if (st.st_size < 4) {
printf("Unrecognized file type - file is too short: %s\n", infile);
fprintf(stderr, "Unrecognized file type - file is too short: %s\n", infile);
return 0;
}
if (st.st_size > UINT32_MAX) {
printf("Unsupported file - too large: %s\n", infile);
fprintf(stderr, "Unsupported file - too large: %s\n", infile);
return 0;
}
return (uint32_t)st.st_size;
@@ -86,7 +87,7 @@ char *map_file(const char *infile, const size_t size)
}
close(fd);
#else
printf("No file mapping function\n");
fprintf(stderr, "No file mapping function\n");
return NULL;
#endif /* HAVE_SYS_MMAN_H */
#endif /* WIN32 */
@@ -152,7 +153,7 @@ int data_write_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
ret = !i2d_PKCS7_bio(outdata, p7);
}
if (ret) {
printf("Unable to write pkcs7 object\n");
fprintf(stderr, "Unable to write pkcs7 object\n");
}
return ret;
}
@@ -165,73 +166,76 @@ int data_write_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx)
{
int i, signer = -1;
PKCS7 *p7;
PKCS7_SIGNER_INFO *si = NULL;
STACK_OF(X509) *chain = NULL;
PKCS7 *p7 = PKCS7_new();
if (!p7)
return NULL;
p7 = PKCS7_new();
PKCS7_set_type(p7, NID_pkcs7_signed);
PKCS7_content_new(p7, NID_pkcs7_data);
if (ctx->options->cert != NULL) {
/*
* the private key and corresponding certificate are parsed from the PKCS12
* structure or loaded from the security token, so we may omit to check
* the consistency of a private key with the public key in an X509 certificate
*/
si = PKCS7_add_signature(p7, ctx->options->cert, ctx->options->pkey,
ctx->options->md);
if (si == NULL)
return NULL; /* FAILED */
} else {
/* 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;
break;
}
}
if (si == NULL) {
printf("Failed to checking the consistency of a private key: %s\n",
ctx->options->keyfile);
printf(" with a public key in any X509 certificate: %s\n\n",
ctx->options->certfile);
return NULL; /* FAILED */
/* 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)) {
return NULL; /* FAILED */
goto err;
}
if (!pkcs7_signer_info_add_purpose(si, ctx)) {
return NULL; /* FAILED */
goto err;
}
if ((ctx->options->desc || ctx->options->url) &&
!pkcs7_signer_info_add_spc_sp_opus_info(si, ctx)) {
printf("Couldn't allocate memory for opus info\n");
return NULL; /* FAILED */
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)) {
return NULL; /* FAILED */
goto err;
}
/* create X509 chain sorted in ascending order by their DER encoding */
chain = X509_chain_get_sorted(ctx, signer);
if (chain == NULL) {
printf("Failed to create a sorted certificate chain\n");
return NULL; /* FAILED */
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++) {
PKCS7_add_certificate(p7, sk_X509_value(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++)
PKCS7_add_crl(p7, sk_X509_CRL_value(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 */
}
/*
@@ -278,11 +282,12 @@ int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *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)) {
printf("Failed to sign spcIndirectDataContent\n");
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);
@@ -291,7 +296,7 @@ int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content)
td7->d.other->value.sequence = ASN1_STRING_new();
ASN1_STRING_set(td7->d.other->value.sequence, data, len);
if (!PKCS7_set_content(p7, td7)) {
printf("PKCS7_set_content failed\n");
fprintf(stderr, "PKCS7_set_content failed\n");
PKCS7_free(td7);
return 0; /* FAILED */
}
@@ -336,6 +341,91 @@ PKCS7 *pkcs7_set_content(ASN1_OCTET_STRING *content)
return p7;
}
/*
* Retrieve the message digest and digest algorithm from PKCS7
* SpcIndirectDataContent.
*
* [in] p7: PKCS7 structure containing SPC_INDIRECT_DATA_OBJID content
* [out] mdbuf: message digest buffer, at least EVP_MAX_MD_SIZE bytes
* [out] mdtype: OpenSSL NID of the digest algorithm
* [returns] 0 on error or 1 on success
*/
int pkcs7_get_content_digest(PKCS7 *p7, u_char *mdbuf, int *mdtype)
{
SpcIndirectDataContent *idc;
if (!mdbuf || !mdtype)
return 0; /* FAILED */
*mdtype = -1;
idc = pkcs7_get_indirect_data_content(p7);
if (!idc) {
fprintf(stderr, "Failed to decode SpcIndirectDataContent\n\n");
return 0; /* FAILED */
}
if (spc_indirect_data_content_get_digest(idc, mdbuf, mdtype) < 0) {
fprintf(stderr, "Failed to extract message digest from signature\n\n");
SpcIndirectDataContent_free(idc);
return 0; /* FAILED */
}
SpcIndirectDataContent_free(idc);
if (*mdtype == -1) {
fprintf(stderr, "Failed to extract current message digest\n\n");
return 0; /* FAILED */
}
return 1; /* OK */
}
/*
* Decode SpcIndirectDataContent from a PKCS7 signedData content.
*
* [in] p7: PKCS7 structure containing SPC_INDIRECT_DATA_OBJID content
* [returns] newly allocated SpcIndirectDataContent, or NULL on error
*
* The caller is responsible for freeing the returned object with
* SpcIndirectDataContent_free().
*/
SpcIndirectDataContent *pkcs7_get_indirect_data_content(PKCS7 *p7)
{
if (!is_content_type(p7, SPC_INDIRECT_DATA_OBJID))
return NULL;
if (!p7->d.sign || !p7->d.sign->contents || !p7->d.sign->contents->d.other)
return NULL;
return asn1_type_get_indirect_data_content(p7->d.sign->contents->d.other);
}
/*
* Decode SpcIndirectDataContent from an ASN1_TYPE object.
* The ASN1_TYPE is expected to contain a V_ASN1_SEQUENCE value.
*
* [in] content: ASN1_TYPE containing DER-encoded SpcIndirectDataContent
* [returns] newly allocated SpcIndirectDataContent, or NULL on error
*
* The caller is responsible for freeing the returned object with
* SpcIndirectDataContent_free().
*/
SpcIndirectDataContent *asn1_type_get_indirect_data_content(ASN1_TYPE *content)
{
ASN1_STRING *value;
const unsigned char *data;
int len;
if (!content || content->type != V_ASN1_SEQUENCE)
return NULL;
value = content->value.sequence;
if (!value)
return NULL;
data = ASN1_STRING_get0_data(value);
len = ASN1_STRING_length(value);
return d2i_SpcIndirectDataContent(NULL, &data, len);
}
/*
* Return spcIndirectDataContent.
* [in] hash: message digest BIO
@@ -388,13 +478,13 @@ int pkcs7_sign_content(PKCS7 *p7, const u_char *data, int len)
BIO *p7bio;
if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
printf("PKCS7_dataInit failed\n");
fprintf(stderr, "PKCS7_dataInit failed\n");
return 0; /* FAILED */
}
BIO_write(p7bio, data, len);
(void)BIO_flush(p7bio);
if (!PKCS7_dataFinal(p7, p7bio)) {
printf("PKCS7_dataFinal failed\n");
fprintf(stderr, "PKCS7_dataFinal failed\n");
BIO_free_all(p7bio);
return 0; /* FAILED */
}
@@ -460,7 +550,7 @@ void print_hash(const char *descript1, const char *descript2, const u_char *mdbu
}
/*
* [in] p7: new PKCS#7 signature
* [in] p7: PKCS#7 signature
* [in] objid: Microsoft OID Authenticode
* [returns] 0 on error or 1 on success
*/
@@ -470,6 +560,10 @@ int is_content_type(PKCS7 *p7, const char *objid)
int ret;
indir_objid = OBJ_txt2obj(objid, 1);
if (!indir_objid) {
fprintf(stderr, "Invalid object identifier: %s\n", objid);
return 0; /* FAILED */
}
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 ||
@@ -488,7 +582,7 @@ MsCtlContent *ms_ctl_content_get(PKCS7 *p7)
const u_char *data;
if (!is_content_type(p7, MS_CTL_OBJID)) {
printf("Failed to find MS_CTL_OBJID\n");
fprintf(stderr, "Failed to find MS_CTL_OBJID\n");
return NULL; /* FAILED */
}
value = p7->d.sign->contents->d.other->value.sequence;
@@ -554,6 +648,42 @@ int compare_digests(u_char *mdbuf, u_char *cmdbuf, int mdtype)
return mdok;
}
/*
* Safely extract digest from SpcIndirectDataContent with bounds checking.
* This function validates that the digest length from the ASN.1 structure
* does not exceed the destination buffer size, preventing buffer overflows
* from maliciously crafted signatures.
* [in] idc: parsed SpcIndirectDataContent structure
* [out] mdbuf: output buffer (must be at least EVP_MAX_MD_SIZE bytes)
* [out] mdtype: digest algorithm NID
* [returns] digest length on success, -1 on error
*/
int spc_indirect_data_content_get_digest(SpcIndirectDataContent *idc, u_char *mdbuf, int *mdtype)
{
ASN1_OCTET_STRING *digest_asn1;
const unsigned char *digest_data;
int digest_len;
if (!idc || !idc->messageDigest || !idc->messageDigest->digest ||
!idc->messageDigest->digestAlgorithm) {
return -1; /* FAILED */
}
digest_asn1 = idc->messageDigest->digest;
digest_len = ASN1_STRING_length((ASN1_STRING *)digest_asn1);
/* Validate digest length to prevent buffer overflow */
if (digest_len <= 0 || digest_len > EVP_MAX_MD_SIZE) {
fprintf(stderr, "Invalid digest length in signature: %d (expected 1-%d)\n",
digest_len, EVP_MAX_MD_SIZE);
return -1; /* FAILED */
}
digest_data = ASN1_STRING_get0_data((ASN1_STRING *)digest_asn1);
*mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
memcpy(mdbuf, digest_data, (size_t)digest_len);
return digest_len; /* OK */
}
/*
* Helper functions
*/
@@ -609,8 +739,16 @@ static int spc_indirect_data_content_create(u_char **blob, int *len, FILE_FORMAT
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;
if (!idc->data->type) {
SpcIndirectDataContent_free(idc);
return 0; /* FAILED */
}
if (!ASN1_STRING_set(idc->data->value->value.sequence, p, l)) {
OPENSSL_free(p);
SpcIndirectDataContent_free(idc);
return 0; /* FAILED */
}
OPENSSL_free(p);
idc->messageDigest->digestAlgorithm->algorithm = OBJ_nid2obj(mdtype);
idc->messageDigest->digestAlgorithm->parameters = ASN1_TYPE_new();
idc->messageDigest->digestAlgorithm->parameters->type = V_ASN1_NULL;
@@ -731,11 +869,6 @@ 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);
/* add the signer's certificate */
if (ctx->options->cert != NULL && !sk_X509_push(chain, ctx->options->cert)) {
sk_X509_free(chain);
return NULL;
}
if (signer != -1 && !sk_X509_push(chain, sk_X509_value(ctx->options->certs, signer))) {
sk_X509_free(chain);
return NULL;
@@ -760,6 +893,9 @@ static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer)
}
/* sort certificate chain using the supplied comparison function */
sk_X509_sort(chain);
/* remove duplicates */
sk_X509_remove_duplicates(chain);
return chain;
}
@@ -778,6 +914,15 @@ static int X509_compare(const X509 *const *a, const X509 *const *b)
size_t a_len, b_len;
int ret;
#if OPENSSL_VERSION_NUMBER<0x30000000L
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
#endif
#endif /* OPENSSL_VERSION_NUMBER<0x30000000L */
a_len = (size_t)i2d_X509(*a, NULL);
a_tmp = a_data = OPENSSL_malloc(a_len);
i2d_X509(*a, &a_tmp);
@@ -785,6 +930,13 @@ static int X509_compare(const X509 *const *a, const X509 *const *b)
b_len = (size_t)i2d_X509(*b, NULL);
b_tmp = b_data = OPENSSL_malloc(b_len);
i2d_X509(*b, &b_tmp);
#if OPENSSL_VERSION_NUMBER<0x30000000L
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#endif /* OPENSSL_VERSION_NUMBER<0x30000000L */
ret = memcmp(a_data, b_data, MIN(a_len, b_len));
OPENSSL_free(a_data);
@@ -795,6 +947,35 @@ static int X509_compare(const X509 *const *a, const X509 *const *b)
return ret;
}
/*
* Remove duplicate certificates from a sorted STACK_OF(X509).
*
* This function assumes the stack is sorted according to X.690-compliant
* certificate comparison, so duplicate certificates appear consecutively.
* It iterates through the stack and removes any duplicate certificates
* by comparing each element with its immediate predecessor.
* The stack is modified in place.
*/
static void sk_X509_remove_duplicates(STACK_OF(X509) *chain)
{
int i, n = sk_X509_num(chain);
if (n < 2)
return;
/* start from the second element */
for (i = 1; i < n; ) {
if (!X509_cmp(sk_X509_value(chain, i - 1), sk_X509_value(chain, i))) {
/* duplicate found: remove the certificate at index i */
(void)sk_X509_delete(chain, i);
n--; /* reduce stack size since one element was removed */
/* do not increment i, as next element shifts into index i */
} else {
i++; /* advance only if no removal was done */
}
}
}
/*
Local Variables:
c-basic-offset: 4
+4
View File
@@ -15,6 +15,9 @@ 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);
int pkcs7_get_content_digest(PKCS7 *p7, u_char *mdbuf, int *mdtype);
SpcIndirectDataContent *pkcs7_get_indirect_data_content(PKCS7 *p7);
SpcIndirectDataContent *asn1_type_get_indirect_data_content(ASN1_TYPE *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);
@@ -25,6 +28,7 @@ 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);
int spc_indirect_data_content_get_digest(SpcIndirectDataContent *idc, u_char *mdbuf, int *mdtype);
/*
Local Variables:
+268 -154
View File
File diff suppressed because it is too large Load Diff
+1636 -817
View File
File diff suppressed because it is too large Load Diff
+41 -6
View File
@@ -14,6 +14,7 @@
#define NOCRYPT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#endif /* HAVE_WINDOWS_H */
#ifdef HAVE_CONFIG_H
@@ -32,6 +33,7 @@
#ifndef _WIN32
#include <unistd.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif /* HAVE_SYS_MMAN_H */
@@ -63,7 +65,10 @@
#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 */
@@ -76,6 +81,8 @@
#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)
@@ -85,7 +92,9 @@
#ifdef _MSC_VER
/* not WIN32, because strcasecmp exists in MinGW */
#define strcasecmp _stricmp
#endif
#define fseeko _fseeki64
#define ftello _ftelli64
#endif /* _MSC_VER */
#ifdef WIN32
#define remove_file(filename) _unlink(filename)
@@ -216,9 +225,9 @@
*/
#define FLAG_RESERVE_PRESENT 0x0004
#define DO_EXIT_0(x) { printf(x); goto err_cleanup; }
#define DO_EXIT_1(x, y) { printf(x, y); goto err_cleanup; }
#define DO_EXIT_2(x, y, z) { printf(x, y, z); goto err_cleanup; }
#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"
@@ -237,6 +246,16 @@ typedef enum {
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;
@@ -249,9 +268,13 @@ typedef struct {
int output_pkcs7;
#ifndef OPENSSL_NO_ENGINE
char *p11engine;
STACK_OF(EngineControl) *engine_ctrls;
int login;
#endif /* OPENSSL_NO_ENGINE */
#if !defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER>=0x30000000L
char *p11module;
char *p11cert;
#endif /* OPENSSL_NO_ENGINE */
#endif /* !defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER>=0x30000000L */
int askpass;
char *readpass;
char *pass;
@@ -268,24 +291,28 @@ typedef struct {
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;
X509 *cert;
STACK_OF(X509) *certs;
STACK_OF(X509) *xcerts;
STACK_OF(X509_CRL) *crls;
@@ -478,6 +505,14 @@ typedef struct {
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;
+554
View File
@@ -0,0 +1,554 @@
---
title: osslsigncode
lang: en-US
---
# NAME
osslsigncode - Authenticode signing, timestamping, extraction, attachment, removal, and verification tool
# SYNOPSIS
`osslsigncode` [`--help`] [`--version`]
`osslsigncode` `sign`
[`-certs` *file* | `-spc` *file* | `-pkcs12` *file*]
[`-key` *file-or-URI*]
[`-ac` *file*]
[`-pass` *password* | `-readpass` *file* | `-askpass`]
[`-pkcs11module` *module*] [`-pkcs11cert` *URI*]
[`-engine` *engine*] [`-provider` *provider*]
[`-login`] [`-engineCtrl` *command*[:*parameter*]]
[`-h` *digest*]
[`-n` *description*] [`-i` *URL*]
[`-jp` `low`] [`-comm`] [`-ph`]
[`-t` *URL* ... | `-ts` *URL* ...]
[`-TSA-certs` *file* `-TSA-key` *file-or-URI* [`-TSA-time` *unix-time*]]
[`-HTTPS-CAfile` *file*] [`-HTTPS-CRLfile` *file*]
[`-time` *unix-time*]
[`-addUnauthenticatedBlob` [`-blobFile` *file*]]
[`-nest`] [`-add-msi-dse`] [`-verbose`] [`-pem`]
`-in` *input* `-out` *output*
`osslsigncode` `extract-data`
[`-pem`] [`-h` *digest*] [`-ph`] [`-add-msi-dse`]
`-in` *input* `-out` *output*
`osslsigncode` `add`
[`-addUnauthenticatedBlob` [`-blobFile` *file*]]
[`-t` *URL* ... | `-ts` *URL* ...]
[`-TSA-certs` *file* `-TSA-key` *file-or-URI* [`-TSA-time` *unix-time*]]
[`-HTTPS-CAfile` *file*] [`-HTTPS-CRLfile` *file*]
[`-h` *digest*] [`-index` *n*] [`-verbose`] [`-add-msi-dse`]
`-in` *input* `-out` *output*
`osslsigncode` `attach-signature`
`-sigin` *signature*
[`-h` *digest*] [`-nest`] [`-add-msi-dse`]
`-in` *input* `-out` *output*
`osslsigncode` `extract-signature`
[`-pem`]
`-in` *input* `-out` *output*
`osslsigncode` `remove-signature`
`-in` *input* `-out` *output*
`osslsigncode` `verify`
`-in` *input*
[`-c` | `-catalog` *catalog-file*]
[`-CAfile` *file*] [`-CRLfile` *file*]
[`-HTTPS-CAfile` *file*] [`-HTTPS-CRLfile` *file*]
[`-TSA-CAfile` *file*] [`-TSA-CRLfile` *file*]
[`-p` *proxy*] [`-index` *n*]
[`-ignore-timestamp`] [`-ignore-cdp`] [`-ignore-crl`]
[`-time` *unix-time*]
[`-require-leaf-hash` *alg*:*hex*]
[`-verbose`]
# DESCRIPTION
`osslsigncode` signs and verifies Microsoft Authenticode signatures on
supported file formats. It can also extract data for detached signing,
attach an externally produced signature, add timestamps or unauthenticated
blobs to an existing signature, and remove an embedded signature.
Supported input formats include PE files such as EXE, DLL, and SYS, CAB,
CAT, MSI, APPX, and several script file types, including `.ps1`, `.ps1xml`,
`.psc1`, `.psd1`, `.psm1`, `.cdxml`, `.mof`, and `.js`.
The program supports these common workflows:
- direct signing of an unsigned file
- detached signing via `extract-data`, `sign`, and `attach-signature`
- post-sign timestamping with `add`
- verification of embedded signatures or catalog signatures with `verify`
If no subcommand is given, `sign` is assumed.
# FORMATS
Support is not identical across all file formats.
In particular, detached-signature workflows, nested signatures, catalog-based
verification, and signature removal are format-dependent features. A command
that is valid for one supported file type may be unsupported for another.
CAT files are a special case. They are detached catalog containers for
hashes of other files, not ordinary embedded-signature payloads. A CAT
file is itself a PKCS#7 structure containing authenticated entries for one
or more external files. In practice, the catalog signs file digests
recorded in the catalog, rather than embedding a signature into each
covered file.
Because of this, CAT files behave differently from embedded-signature
formats. They do not support `attach-signature`, `remove-signature`,
`extract-data`, or nested signatures.
MSI files are also a special case. They support an extended signature mode
controlled by `-add-msi-dse`. In this mode, the MSI signature covers file
metadata as well as file content. Detached-signing workflows and any later
re-signing or nesting operations must use a mode consistent with the MSI
file's existing signature structure.
# COMMANDS
## `sign`
Create a new Authenticode signature.
This command can sign a normal unsigned file, or it can sign PKCS#7 data
previously produced by `extract-data`.
## `extract-data`
Extract the PKCS#7 content to be signed later. This is used for detached
signing workflows.
## `add`
Add unauthenticated attributes to an existing signature, typically an
Authenticode timestamp, an RFC 3161 timestamp, or an unauthenticated blob.
With `-index`, the selected signature in a multi-signature file is updated.
## `attach-signature`
Attach a detached PKCS#7 signature to an input file.
With `-nest`, the new signature is attached as a nested signature instead of
replacing the primary one, if the file format supports nested signatures.
## `extract-signature`
Extract the embedded PKCS#7 signature from a signed file.
## `remove-signature`
Remove the embedded signature from a signed file.
## `verify`
Verify an embedded signature or a catalog signature.
Verification may include digest consistency, certificate chain validation,
certificate revocation checking, timestamp validation, and optional checking
of the signer's leaf certificate hash.
When verifying that a file is covered by a catalog, use `verify -catalog
catalog.cat -in file`. Verifying the CAT file by itself validates the
catalog signature; verifying with `-catalog` checks whether the specified
input file is covered by that catalog.
# OPTIONS
Some options are available only in particular builds or OpenSSL versions.
In particular, `-askpass` is build-dependent, `-provider` and `-nolegacy`
require OpenSSL 3, and engine-related options depend on engine support in the
build.
## General options
`--help`
: Show help text. With a subcommand, show help for that subcommand.
`-v`, `--version`
: Show version information.
`-in` *file*
: Input file.
`-out` *file*
: Output file. Required for all commands except `verify`.
`-verbose`
: Produce more detailed diagnostic output.
## Signing material
`-pkcs12` *file*
: Read the signing certificate and private key from a PKCS#12 container.
`-certs`, `-spc` *file*
: Read the signing certificate chain. The historical alias `-spc` is accepted.
`-key` *file-or-URI*
: Read the private key. This may also be a store or PKCS#11 URI.
`-ac` *file*
: Add extra certificates to the signature block.
`-pass` *password*
: Password or PIN for the key, token, or PKCS#12 container.
`-readpass` *file*
: Read the password or PIN from *file*. Use `-` to read from standard input.
`-askpass`
: Prompt for the password interactively.
## PKCS#11, engines, and providers
`-pkcs11module` *module*
: Path to a PKCS#11 module.
`-pkcs11cert` *URI*
: PKCS#11 URI identifying the certificate object.
`-provider` *provider*
: OpenSSL 3 provider to load. This is the preferred modern interface for
provider-based PKCS#11 use.
`-engine`, `-pkcs11engine` *engine*
: OpenSSL engine identifier or path to a dynamic engine module. This
interface is retained for compatibility with builds and deployments that
still support engines.
`-login`
: Force login to the token for engine-based PKCS#11 use.
`-engineCtrl` *command*[:*parameter*]
: Pass a control command to the selected engine.
`-nolegacy`
: On OpenSSL 3 builds, do not automatically load the legacy provider.
## Signature contents and digest control
`-h` `md5` | `sha1` | `sha2` | `sha256` | `sha384` | `sha512`
: Select the digest algorithm. The default is `sha256`. `sha2` and
`sha256` are equivalent.
`-n` *description*
: Description of the signed content.
`-i` *URL*
: Informational URL associated with the signed content.
`-comm`
: Use Microsoft Commercial Code Signing purpose instead of the default
individual purpose.
`-jp` `low`
: Add the Java CAB permission attribute. Only `low` is currently supported.
`-ph`
: Generate page hashes for executable files.
`-add-msi-dse`
: For MSI files, enable the `MsiDigitalSignatureEx` signing mode. In this
mode, the signature covers MSI metadata as well as file content. The
metadata portion includes stream names, sizes, and selected timestamps in
the MSI structure. This option changes the MSI signature format and should
be used consistently in any detached-signing workflow involving
`extract-data`, `sign`, `attach-signature`, or `add`.
For a newly signed MSI, this mode is generally preferred because it extends
signing coverage beyond file content alone. For an already signed MSI,
however, the chosen mode must match the file's existing signature
structure. Switching between basic MSI signing and `MsiDigitalSignatureEx`
during re-signing or nested-signature operations can invalidate the
existing signature.
`-pem`
: Write PKCS#7 output in PEM format instead of DER.
## Timestamping and network options
The following timestamping modes are **mutually exclusive** within a single
`sign` or `add` invocation:
- Authenticode timestamping with `-t`
- RFC 3161 timestamping with `-ts`
- built-in RFC 3161 timestamp generation with `-TSA-certs` and `-TSA-key`
`-t` *URL*
: Add an Authenticode timestamp from the specified URL. May be repeated.
`-ts` *URL*
: Add an RFC 3161 timestamp from the specified URL. May be repeated.
`-p` *proxy*
: Proxy used for timestamp or CRL retrieval.
`-noverifypeer`
: Do not verify the TLS certificate of the remote timestamp service.
`-HTTPS-CAfile` *file*
: PEM bundle used to verify HTTPS peers contacted by `osslsigncode`.
`-HTTPS-CRLfile` *file*
: PEM CRL file used while verifying HTTPS peers.
`-TSA-certs` *file*
: PEM certificate chain for locally generated RFC 3161 timestamps.
`-TSA-key` *file-or-URI*
: Private key for locally generated RFC 3161 timestamps.
`-TSA-time` *unix-time*
: Timestamp time for locally generated RFC 3161 responses.
## Nested signatures and indexed operations
`-nest`
: Add a nested signature instead of replacing the primary signature.
`-index` *n*
: Select a signature by index for `add` or `verify`. Index 0 is the primary
signature.
## Unauthenticated blob options
`-addUnauthenticatedBlob`
: Add an unauthenticated blob to the signature.
`-blobFile` *file*
: Read blob contents from *file*. If omitted, a placeholder blob is created.
## Verification options
`-c`, `-catalog` *file*
: Verify the input file against the specified catalog file.
`-CAfile` *file*
: PEM bundle of trusted CA certificates for signer validation.
`-CRLfile` *file*
: PEM file containing CRLs for signer validation.
`-TSA-CAfile`, `-untrusted` *file*
: PEM bundle of trusted CA certificates for timestamp validation.
`-TSA-CRLfile`, `-CRLuntrusted` *file*
: PEM file containing CRLs for timestamp validation.
`-time`, `-st` *unix-time*
: Verification time. If a valid timestamp is present and used, chain
validation is normally performed at the timestamp time.
`-ignore-timestamp`
: Skip verification of the timestamp signature.
`-ignore-cdp`
: Do not fetch CRLs from CRL Distribution Points.
`-ignore-crl`
: Disable CRL retrieval and CRL validation.
`-require-leaf-hash` *alg*:*hex*
: Require the signer's leaf certificate to hash to the specified value.
The hash is computed over the DER encoding of the leaf certificate.
# EXIT STATUS
`0`
: Success.
non-zero
: Failure.
# DIAGNOSTICS
Common causes of failure include:
missing CA trust bundle
: On Unix-like systems, `verify` expects a readable CA bundle, either from
`-CAfile` or from a detected system default.
detached-signing mismatch
: `extract-data`, `sign`, and `attach-signature` must use compatible
digest-affecting options such as `-h`, and where relevant `-ph` and
`-add-msi-dse`.
unsupported format feature
: Some file formats do not support every subcommand or every signature mode.
missing TSA trust chain
: Timestamp verification may fail unless the appropriate TSA trust anchors
are supplied with `-TSA-CAfile`, and where needed `-TSA-CRLfile`.
conflicting timestamp modes
: `-t`, `-ts`, and built-in TSA signing cannot be combined in one command.
MSI signature mode mismatch
: Re-signing or nesting an MSI signature must be consistent with whether the
file already uses `MsiDigitalSignatureEx`. Mixing modes may invalidate the
existing signature.
# ENVIRONMENT
`HTTP_PROXY`, `http_proxy`
: Default proxy for HTTP access if `-p` is not given.
`HTTPS_PROXY`, `https_proxy`
: Default proxy for HTTPS access if `-p` is not given.
`OPENSSL_ENGINES`
: May help OpenSSL find engine modules.
# FILES
On Unix-like systems, `osslsigncode` tries common CA bundle locations for
its default `-CAfile`, including:
- `/etc/ssl/certs/ca-certificates.crt`
- `/etc/pki/tls/certs/ca-bundle.crt`
- `/usr/share/ssl/certs/ca-bundle.crt`
- `/usr/local/share/certs/ca-root-nss.crt`
- `/etc/ssl/cert.pem`
If no readable CA bundle is available, `verify` may require an explicit
`-CAfile`.
# NOTES
Use `extract-data` when you need to create a new detached signature object.
Use `extract-signature` when you need to copy an existing embedded PKCS#7
signature out of a file.
For safer secret handling, prefer `-readpass` or `-askpass` over `-pass`.
Data added with `-addUnauthenticatedBlob` is not protected by the signature
and must not be treated as trusted.
For new MSI signatures, `-add-msi-dse` is generally preferred because it
extends signing coverage to MSI metadata as well as file content. However,
it is format-affecting rather than cosmetic, so existing signed MSI files
should be re-signed only in a mode consistent with their current signature
structure.
Output files are not overwritten.
# EXAMPLES
## Sign and verify a file
```sh
osslsigncode sign \
-pkcs12 signer.p12 \
-readpass p12-pass.txt \
-n "Example Application" \
-i "https://example.com/" \
-ts "https://tsa.example.net/" \
-in app.exe \
-out app-signed.exe
osslsigncode verify \
-CAfile ca-bundle.pem \
-TSA-CAfile tsa-ca-bundle.pem \
-in app-signed.exe
```
## Detached signing workflow
```sh
osslsigncode extract-data \
-h sha384 \
-ph \
-in app.exe \
-out app-data.der
osslsigncode sign \
-pkcs12 signer.p12 \
-readpass p12-pass.txt \
-h sha384 \
-in app-data.der \
-out app-sig.der
osslsigncode attach-signature \
-h sha384 \
-sigin app-sig.der \
-in app.exe \
-out app-signed.exe
osslsigncode verify \
-CAfile ca-bundle.pem \
-in app-signed.exe
```
## Sign a new MSI with extended MSI metadata coverage
```sh
osslsigncode sign \
-pkcs12 signer.p12 \
-readpass p12-pass.txt \
-add-msi-dse \
-in installer.msi \
-out installer-signed.msi
```
## Use a PKCS#11 provider
```sh
osslsigncode sign \
-provider /path/to/pkcs11prov.so \
-pkcs11module /path/to/opensc-pkcs11.so \
-pkcs11cert 'pkcs11:token=my-token;object=cert' \
-key 'pkcs11:token=my-token;object=key' \
-readpass pin.txt \
-in app.exe \
-out app-signed.exe
```
## Add a timestamp to an already signed file
```sh
osslsigncode add \
-ts "https://tsa.example.net/" \
-in app-signed.exe \
-out app-signed-ts.exe
```
## Verify that a file is covered by a catalog
```sh
osslsigncode verify \
-catalog drivers.cat \
-CAfile ca-bundle.pem \
-CRLfile ca-crl.pem \
-in driver.sys
```
# REPORTING BUGS
Report bugs and suspected issues via the project issue tracker:
<https://github.com/mtrojnar/osslsigncode/issues>
# AUTHORS
Originally written by Per Allansson.
Maintained and extended by Michał Trojnara.
Major contributions by Małgorzata Olszówka.
Additional contributions by other project contributors.
# SEE ALSO
**OpenSSL** Library
<https://openssl-library.org/>
+361 -123
View File
@@ -87,6 +87,7 @@ static uint32_t pe_calc_checksum(BIO *bio, uint32_t header_size);
static uint32_t pe_calc_realchecksum(FILE_FORMAT_CTX *ctx);
static int pe_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md);
static int pkcs7_get_page_hash(PKCS7 *p7, u_char **ph, int *phlen, int *phtype);
static int pe_page_hash_get(u_char **ph, int *phlen, int *phtype, SpcAttributeTypeAndOptionalValue *obj);
static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype);
static int pe_verify_page_hash(FILE_FORMAT_CTX *ctx, u_char *ph, int phlen, int phtype);
@@ -163,8 +164,10 @@ static ASN1_OBJECT *pe_spc_image_data_get(u_char **p, int *plen, FILE_FORMAT_CTX
if (EVP_MD_size(ctx->options->md) > EVP_MD_size(EVP_sha1()))
phtype = NID_sha256;
link = pe_page_hash_link_get(ctx, phtype);
if (!link)
if (!link) {
SpcPeImageData_free(pid);
return NULL; /* FAILED */
}
pid->file = link;
} else {
pid->file = spc_link_obsolete_get();
@@ -245,49 +248,34 @@ static int pe_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
u_char *cmdbuf = NULL;
u_char *ph = NULL;
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 (!pe_page_hash_get(&ph, &phlen, &phtype, idc->data)) {
printf("Failed to extract a page hash\n\n");
SpcIndirectDataContent_free(idc);
return 0; /* FAILED */
}
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) {
printf("Failed to extract current message digest\n\n");
OPENSSL_free(ph);
if (!pkcs7_get_content_digest(p7, mdbuf, &mdtype)) {
fprintf(stderr, "Failed to extract current message digest\n\n");
return 0; /* FAILED */
}
md = EVP_get_digestbynid(mdtype);
cmdbuf = pe_digest_calc(ctx, md);
if (!cmdbuf) {
printf("Failed to calculate message digest\n\n");
OPENSSL_free(ph);
fprintf(stderr, "Failed to calculate message digest\n\n");
return 0; /* FAILED */
}
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
printf("Signature verification: failed\n\n");
OPENSSL_free(ph);
fprintf(stderr, "Signature verification: failed\n\n");
OPENSSL_free(cmdbuf);
return 0; /* FAILED */
}
OPENSSL_free(cmdbuf);
if (!pkcs7_get_page_hash(p7, &ph, &phlen, &phtype)) {
fprintf(stderr, "Failed to extract page hash\n\n");
return 0; /* FAILED */
}
if (!pe_verify_page_hash(ctx, ph, phlen, phtype)) {
printf("Signature verification: failed\n\n");
fprintf(stderr, "Signature verification: failed\n\n");
OPENSSL_free(ph);
OPENSSL_free(cmdbuf);
return 0; /* FAILED */
}
OPENSSL_free(ph);
OPENSSL_free(cmdbuf);
return 1; /* OK */
}
@@ -303,11 +291,11 @@ static int pe_verify_indirect_data(FILE_FORMAT_CTX *ctx, SpcAttributeTypeAndOpti
u_char *ph = NULL;
if (!pe_page_hash_get(&ph, &phlen, &phtype, obj)) {
printf("Failed to extract a page hash\n\n");
fprintf(stderr, "Failed to extract a page hash\n\n");
return 0; /* FAILED */
}
if (!pe_verify_page_hash(ctx, ph, phlen, phtype)) {
printf("Page hash verification: failed\n\n");
fprintf(stderr, "Page hash verification: failed\n\n");
OPENSSL_free(ph);
return 0; /* FAILED */
}
@@ -353,7 +341,7 @@ static int pe_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
/* Strip current signature */
ctx->pe_ctx->fileend = ctx->pe_ctx->sigpos;
if (!pe_modify_header(ctx, hash, outdata)) {
printf("Unable to modify file header\n");
fprintf(stderr, "Unable to modify file header\n");
return 1; /* FAILED */
}
return 0; /* OK */
@@ -373,10 +361,10 @@ static int pe_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
ctx->pe_ctx->fileend = ctx->pe_ctx->sigpos;
}
if (!pe_modify_header(ctx, hash, outdata)) {
printf("Unable to modify file header\n");
return 1; /* FAILED */
fprintf(stderr, "Unable to modify file header\n");
return 0; /* FAILED */
}
return 0; /* OK */
return 1; /* OK */
}
/*
@@ -391,21 +379,22 @@ static PKCS7 *pe_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
PKCS7 *p7 = pkcs7_create(ctx);
if (!p7) {
printf("Creating a new signature failed\n");
fprintf(stderr, "Creating a new signature failed\n");
return NULL; /* FAILED */
}
if (!add_indirect_data_object(p7)) {
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n");
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) {
printf("Failed to get spcIndirectDataContent\n");
fprintf(stderr, "Failed to get spcIndirectDataContent\n");
PKCS7_free(p7);
return NULL; /* FAILED */
}
if (!sign_spc_indirect_data_content(p7, content)) {
printf("Failed to set signed content\n");
fprintf(stderr, "Failed to set signed content\n");
PKCS7_free(p7);
ASN1_OCTET_STRING_free(content);
return NULL; /* FAILED */
@@ -435,7 +424,7 @@ static int pe_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
if (((len = i2d_PKCS7(p7, NULL)) <= 0)
|| (p = OPENSSL_malloc((size_t)len)) == NULL) {
printf("i2d_PKCS memory allocation failed: %d\n", len);
fprintf(stderr, "i2d_PKCS memory allocation failed: %d\n", len);
return 1; /* FAILED */
}
i2d_PKCS7(p7, &p);
@@ -540,7 +529,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
uint16_t magic;
if (filesize < 64) {
printf("Corrupt DOS file - too short\n");
fprintf(stderr, "Corrupt DOS file - too short\n");
return NULL; /* FAILED */
}
/* SizeOfHeaders field specifies the combined size of an MS-DOS stub, PE header,
@@ -549,15 +538,15 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
* because of a bug when checking section names for compatibility purposes */
header_size = GET_UINT32_LE(indata + 60);
if (header_size < 44 || header_size > filesize) {
printf("Unexpected SizeOfHeaders field: 0x%08X\n", header_size);
fprintf(stderr, "Unexpected SizeOfHeaders field: 0x%08X\n", header_size);
return NULL; /* FAILED */
}
if (filesize < header_size + 176) {
printf("Corrupt PE file - too short\n");
fprintf(stderr, "Corrupt PE file - too short\n");
return NULL; /* FAILED */
}
if (memcmp(indata + header_size, "PE\0\0", 4)) {
printf("Unrecognized DOS file type\n");
fprintf(stderr, "Unrecognized DOS file type\n");
return NULL; /* FAILED */
}
/* Magic field identifies the state of the image file. The most common number is
@@ -570,7 +559,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
} else if (magic == 0x10b) {
pe32plus = 0;
} else {
printf("Corrupt PE file - found unknown magic %04X\n", magic);
fprintf(stderr, "Corrupt PE file - found unknown magic %04X\n", magic);
return NULL; /* FAILED */
}
/* The image file checksum */
@@ -579,7 +568,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
* in the remainder of the optional header. Each describes a location and size. */
nrvas = GET_UINT32_LE(indata + header_size + 116 + pe32plus * 16);
if (nrvas < 5) {
printf("Can not handle PE files without certificate table resource\n");
fprintf(stderr, "Can not handle PE files without certificate table resource\n");
return NULL; /* FAILED */
}
/* Certificate Table field specifies the attribute certificate table address (4 bytes) and size (4 bytes) */
@@ -589,7 +578,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
that signature should be last part of file */
if ((sigpos != 0 || siglen != 0) &&
(sigpos == 0 || siglen == 0 || sigpos >= filesize || sigpos + siglen != filesize)) {
printf("Ignoring PE signature not at the end of the file\n");
printf("Warning: Ignoring PE signature not at the end of the file\n");
sigpos = 0;
siglen = 0;
}
@@ -617,7 +606,7 @@ static PKCS7 *pe_pkcs7_get_file(char *indata, PE_CTX *pe_ctx)
uint32_t pos = 0;
if (pe_ctx->siglen == 0 || pe_ctx->siglen > pe_ctx->fileend) {
printf("Corrupted signature length: 0x%08X\n", pe_ctx->siglen);
fprintf(stderr, "Corrupted signature length: 0x%08X\n", pe_ctx->siglen);
return NULL; /* FAILED */
}
while (pos < pe_ctx->siglen) {
@@ -779,11 +768,18 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
uint32_t idx = 0, fileend;
BIO *bhash = BIO_new(BIO_f_md());
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n");
fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash);
return 0; /* FAILED */
}
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(bhash, BIO_new(BIO_s_null()));
if (ctx->pe_ctx->sigpos)
fileend = ctx->pe_ctx->sigpos;
@@ -805,7 +801,7 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
}
idx += (uint32_t)written + 8;
if (!bio_hash_data(bhash, ctx->options->indata, idx, fileend)) {
printf("Unable to calculate digest\n");
fprintf(stderr, "Unable to calculate digest\n");
BIO_free_all(bhash);
return 0; /* FAILED */
}
@@ -827,6 +823,36 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
* Page hash support
*/
/*
* Retrieve a page hash from PKCS7 SPC_INDIRECT_DATA structure.
* [in] p7: PKCS7 signature
* [out] ph: page hash
* [out] phlen: page hash length
* [out] phtype: NID_sha1 or NID_sha256
* [returns] 0 on error or 1 on success
*/
static int pkcs7_get_page_hash(PKCS7 *p7, u_char **ph, int *phlen, int *phtype)
{
SpcIndirectDataContent *idc = pkcs7_get_indirect_data_content(p7);
if (!idc) {
fprintf(stderr, "Failed to decode SpcIndirectDataContent\n\n");
return 0; /* FAILED */
}
if (!idc->data) {
fprintf(stderr, "Missing SpcIndirectDataContent data\n\n");
SpcIndirectDataContent_free(idc);
return 0; /* FAILED */
}
if (!pe_page_hash_get(ph, phlen, phtype, idc->data)) {
fprintf(stderr, "Failed to extract a page hash\n\n");
SpcIndirectDataContent_free(idc);
return 0; /* FAILED */
}
SpcIndirectDataContent_free(idc);
return 1; /* OK */
}
/*
* Retrieve a page hash from SPC_INDIRECT_DATA structure.
* [out] ph: page hash
@@ -835,43 +861,71 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
* [in] obj: SPC_INDIRECT_DATA OID: 1.3.6.1.4.1.311.2.1.4 containing page hash
* [returns] 0 on error or 1 on success
*/
static int pe_page_hash_get(u_char **ph, int *phlen, int *phtype, SpcAttributeTypeAndOptionalValue *obj)
static int pe_page_hash_get(u_char **ph, int *phlen, int *phtype,
SpcAttributeTypeAndOptionalValue *obj)
{
const u_char *blob;
const unsigned char *blob;
const unsigned char *sequence_data;
const unsigned char *classid_data;
const unsigned char *serialized_data;
SpcPeImageData *id;
SpcSerializedObject *so;
int l, l2;
int sequence_len, classid_len, serialized_len, l, l2;
char buf[128];
/* Validate input object */
if (!obj || !obj->value)
return 0; /* FAILED */
blob = obj->value->value.sequence->data;
id = d2i_SpcPeImageData(NULL, &blob, obj->value->value.sequence->length);
if (!id) {
/* Decode SpcPeImageData from ASN.1 sequence */
sequence_data = ASN1_STRING_get0_data(obj->value->value.sequence);
sequence_len = ASN1_STRING_length(obj->value->value.sequence);
/* d2i_* modifies the input pointer, so use a temporary variable */
blob = sequence_data;
id = d2i_SpcPeImageData(NULL, &blob, sequence_len);
if (!id)
return 0; /* FAILED */
}
/* Validate SpcPeImageData contents */
if (!id->file) {
SpcPeImageData_free(id);
return 0; /* FAILED */
}
/* Type 1 means SpcSerializedObject */
if (id->file->type != 1) {
SpcPeImageData_free(id);
return 1; /* OK - This is not SpcSerializedObject structure that contains page hashes */
return 1; /* OK - no page hashes present */
}
so = id->file->value.moniker;
if (so->classId->length != sizeof classid_page_hash ||
memcmp(so->classId->data, classid_page_hash, sizeof classid_page_hash)) {
/* Validate serialized object class ID */
classid_data = ASN1_STRING_get0_data((ASN1_STRING *)so->classId);
classid_len = ASN1_STRING_length((ASN1_STRING *)so->classId);
if (classid_len != sizeof classid_page_hash ||
memcmp(classid_data, classid_page_hash, sizeof classid_page_hash)) {
SpcPeImageData_free(id);
return 0; /* FAILED */
}
/* skip ASN.1 SET hdr */
l = asn1_simple_hdr_len(so->serializedData->data, so->serializedData->length);
blob = so->serializedData->data + l;
obj = d2i_SpcAttributeTypeAndOptionalValue(NULL, &blob, so->serializedData->length - l);
/*Get serialized ASN.1 blob */
serialized_data = ASN1_STRING_get0_data((ASN1_STRING *)so->serializedData);
serialized_len = ASN1_STRING_length((ASN1_STRING *)so->serializedData);
/* Skip ASN.1 SET header */
l = asn1_simple_hdr_len(serialized_data, serialized_len);
blob = serialized_data + l;
/* Decode nested SpcAttributeTypeAndOptionalValue */
obj = d2i_SpcAttributeTypeAndOptionalValue(NULL, &blob, serialized_len - l);
SpcPeImageData_free(id);
if (!obj)
return 0; /* FAILED */
/* Determine page hash algorithm */
*phtype = 0;
buf[0] = 0x00;
OBJ_obj2txt(buf, sizeof buf, obj->type, 1);
@@ -883,15 +937,30 @@ static int pe_page_hash_get(u_char **ph, int *phlen, int *phtype, SpcAttributeTy
SpcAttributeTypeAndOptionalValue_free(obj);
return 0; /* FAILED */
}
/* Skip ASN.1 SET hdr */
l2 = asn1_simple_hdr_len(obj->value->value.sequence->data, obj->value->value.sequence->length);
/* Skip ASN.1 OCTET STRING hdr */
l = asn1_simple_hdr_len(obj->value->value.sequence->data + l2, obj->value->value.sequence->length - l2);
/* IMPORTANT:
* obj now points to the newly decoded structure,
* so refresh sequence_data/sequence_len */
sequence_data = ASN1_STRING_get0_data(obj->value->value.sequence);
sequence_len = ASN1_STRING_length(obj->value->value.sequence);
/* Skip ASN.1 SET header */
l2 = asn1_simple_hdr_len(sequence_data, sequence_len);
/* Skip ASN.1 OCTET STRING header */
l = asn1_simple_hdr_len(sequence_data + l2, sequence_len - l2);
l += l2;
*phlen = obj->value->value.sequence->length - l;
/* Extract raw page hash blob */
*phlen = sequence_len - l;
*ph = OPENSSL_malloc((size_t)*phlen);
memcpy(*ph, obj->value->value.sequence->data + l, (size_t)*phlen);
if (!*ph) {
SpcAttributeTypeAndOptionalValue_free(obj);
return 0; /* FAILED */
}
memcpy(*ph, sequence_data + l, (size_t)*phlen);
SpcAttributeTypeAndOptionalValue_free(obj);
return 1; /* OK */
}
@@ -907,18 +976,31 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
uint16_t nsections, opthdr_size;
uint32_t alignment, pagesize, hdrsize;
uint32_t rs, ro, l, lastpos = 0;
int pphlen, phlen, i, pi = 1;
size_t written;
u_char *res, *zeroes;
int mdlen, pphlen, phlen, i, pi = 1;
size_t written, off, sect_off, sect_tbl, need;
u_char *res = NULL, *zeroes = NULL;
char *sections;
const EVP_MD *md = EVP_get_digestbynid(phtype);
BIO *bhash;
BIO *bhash = NULL;
uint32_t filebound;
size_t pphlen_sz, sections_factor;
if (rphlen == NULL || ctx == NULL || ctx->options == NULL || ctx->pe_ctx == NULL
|| ctx->options->indata == NULL)
return NULL;
if (md == NULL)
return NULL;
mdlen = EVP_MD_size(md);
if (mdlen <= 0)
return NULL;
/* NumberOfSections indicates the size of the section table,
* which immediately follows the headers, can be up to 65535 under Vista and later */
nsections = GET_UINT16_LE(ctx->options->indata + ctx->pe_ctx->header_size + 6);
if (nsections == 0) {
printf("Corrupted number of sections: 0x%08X\n", nsections);
fprintf(stderr, "Corrupted number of sections: 0x%08X\n", nsections);
return NULL; /* FAILED */
}
/* FileAlignment is the alignment factor (in bytes) that is used to align
@@ -926,7 +1008,7 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
* of 2 between 512 and 64 K, inclusive. The default is 512. */
alignment = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 60);
if (alignment < 512 || alignment > UINT16_MAX) {
printf("Corrupted file alignment factor: 0x%08X\n", alignment);
fprintf(stderr, "Corrupted file alignment factor: 0x%08X\n", alignment);
return NULL; /* FAILED */
}
/* SectionAlignment is the alignment (in bytes) of sections when they are
@@ -936,14 +1018,14 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
* https://devblogs.microsoft.com/oldnewthing/20210510-00/?p=105200 */
pagesize = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 56);
if (pagesize == 0 || pagesize < alignment || pagesize > 4194304) {
printf("Corrupted page size: 0x%08X\n", pagesize);
fprintf(stderr, "Corrupted page size: 0x%08X\n", pagesize);
return NULL; /* FAILED */
}
/* SizeOfHeaders is the combined size of an MS-DOS stub, PE header,
* and section headers rounded up to a multiple of FileAlignment. */
hdrsize = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 84);
if (hdrsize < ctx->pe_ctx->header_size || hdrsize > UINT32_MAX) {
printf("Corrupted headers size: 0x%08X\n", hdrsize);
fprintf(stderr, "Corrupted headers size: 0x%08X\n", hdrsize);
return NULL; /* FAILED */
}
/* SizeOfOptionalHeader is the size of the optional header, which is
@@ -951,19 +1033,65 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
* and can't be bigger than the file */
opthdr_size = GET_UINT16_LE(ctx->options->indata + ctx->pe_ctx->header_size + 20);
if (opthdr_size == 0 || opthdr_size > ctx->pe_ctx->fileend) {
printf("Corrupted optional header size: 0x%08X\n", opthdr_size);
fprintf(stderr, "Corrupted optional header size: 0x%08X\n", opthdr_size);
return NULL; /* FAILED */
}
pphlen = 4 + EVP_MD_size(md);
phlen = pphlen * (3 + (int)nsections + (int)(ctx->pe_ctx->fileend / pagesize));
/* Validate that pagesize >= hdrsize to prevent integer underflow */
if (pagesize < hdrsize) {
fprintf(stderr, "Page size (0x%08X) is smaller than header size (0x%08X)\n",
pagesize, hdrsize);
return NULL; /* FAILED */
}
pphlen = 4 + mdlen;
/* Compute an upper bound for result size and guard overflow */
pphlen_sz = (size_t)pphlen;
sections_factor = 3 + (size_t)nsections + ((size_t)ctx->pe_ctx->fileend / pagesize);
if (sections_factor > SIZE_MAX / pphlen_sz) {
fprintf(stderr, "Page hash allocation size would overflow\n");
return NULL; /* FAILED */
}
phlen = (int)(pphlen_sz * sections_factor);
/* Sanity limit - page hash shouldn't exceed reasonable size (16 MB) */
if (phlen < 0 || (size_t)phlen > SIZE_16M) {
fprintf(stderr, "Page hash size exceeds limit: %d\n", phlen);
return NULL; /* FAILED */
}
/* Determine the file boundary for section data validation */
filebound = ctx->pe_ctx->sigpos ? ctx->pe_ctx->sigpos : ctx->pe_ctx->fileend;
/* Validate section table bounds before reading section headers */
sect_off = (size_t)ctx->pe_ctx->header_size + 24u + (size_t)opthdr_size;
sect_tbl = (size_t)nsections * 40u;
if (sect_off > (size_t)filebound || sect_tbl > (size_t)filebound - sect_off) {
fprintf(stderr, "Section table out of bounds: off=%zu size=%zu filebound=%u\n",
sect_off, sect_tbl, filebound);
return NULL; /* FAILED */
}
sections = (char *)ctx->options->indata + sect_off;
bhash = BIO_new(BIO_f_md());
if (bhash == NULL)
return NULL;
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n");
fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash);
return NULL; /* FAILED */
}
BIO_push(bhash, BIO_new(BIO_s_null()));
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
if (BIO_push(bhash, BIO_new(BIO_s_null())) == NULL) {
BIO_free_all(bhash);
return NULL;
}
if (!BIO_write_ex(bhash, ctx->options->indata, ctx->pe_ctx->header_size + 88, &written)
|| written != ctx->pe_ctx->header_size + 88) {
BIO_free_all(bhash);
@@ -975,54 +1103,115 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
BIO_free_all(bhash);
return NULL; /* FAILED */
}
if (!BIO_write_ex(bhash,
ctx->options->indata + ctx->pe_ctx->header_size + 160 + ctx->pe_ctx->pe32plus*16,
hdrsize - (ctx->pe_ctx->header_size + 160 + ctx->pe_ctx->pe32plus*16), &written)
|| written != hdrsize - (ctx->pe_ctx->header_size + 160 + ctx->pe_ctx->pe32plus*16)) {
off = ctx->pe_ctx->header_size + 160 + (size_t)ctx->pe_ctx->pe32plus * 16;
if (hdrsize < off || hdrsize > filebound) {
BIO_free_all(bhash);
return NULL; /* FAILED: header too small */
}
if (!BIO_write_ex(bhash, ctx->options->indata + off, (size_t)hdrsize - off, &written)
|| written != hdrsize - off) {
BIO_free_all(bhash);
return NULL; /* FAILED */
}
if (pagesize < hdrsize) {
BIO_free_all(bhash);
return NULL; /* FAILED: header larger than page */
}
zeroes = OPENSSL_zalloc((size_t)pagesize);
if (!BIO_write_ex(bhash, zeroes, pagesize - hdrsize, &written)
|| written != pagesize - hdrsize) {
if (zeroes == NULL) {
BIO_free_all(bhash);
return NULL; /* FAILED */
}
if (!BIO_write_ex(bhash, zeroes, (size_t)pagesize - (size_t)hdrsize, &written)
|| written != (size_t)pagesize - (size_t)hdrsize) {
BIO_free_all(bhash);
OPENSSL_free(zeroes);
return NULL; /* FAILED */
}
res = OPENSSL_malloc((size_t)phlen);
if (res == NULL) {
BIO_free_all(bhash);
OPENSSL_free(zeroes);
return NULL; /* FAILED */
}
memset(res, 0, 4);
BIO_gets(bhash, (char*)res + 4, EVP_MD_size(md));
if (BIO_gets(bhash, (char *)res + 4, mdlen) != mdlen) {
BIO_free_all(bhash);
OPENSSL_free(zeroes);
OPENSSL_free(res);
return NULL; /* FAILED */
}
BIO_free_all(bhash);
sections = ctx->options->indata + ctx->pe_ctx->header_size + 24 + opthdr_size;
for (i=0; i<nsections; i++) {
/* Resource Table address and size */
for (i = 0; i < (int)nsections; i++) {
/* SizeOfRawData and PointerToRawData from section header */
rs = GET_UINT32_LE(sections + 16);
ro = GET_UINT32_LE(sections + 20);
if (rs == 0 || rs >= UINT32_MAX) {
if (rs == 0) {
sections += 40;
continue;
}
for (l=0; l<rs; l+=pagesize, pi++) {
PUT_UINT32_LE(ro + l, res + pi*pphlen);
/* Validate section bounds against file size to prevent OOB read */
if (ro >= filebound || rs > filebound - ro) {
fprintf(stderr, "Section %d has invalid bounds: offset=0x%08X, size=0x%08X, fileend=0x%08X\n",
i, ro, rs, filebound);
OPENSSL_free(zeroes);
OPENSSL_free(res);
return NULL; /* FAILED */
}
for (l = 0; l < rs; l += pagesize, pi++) {
need = (size_t)(pi + 1) * (size_t)pphlen;
/* Prevent OOB write into res if pi grows beyond allocated factor */
if (need > (size_t)phlen) {
fprintf(stderr, "Page hash buffer overflow prevented: pi=%d need=%zu phlen=%d\n",
pi, need, phlen);
OPENSSL_free(zeroes);
OPENSSL_free(res);
return NULL; /* FAILED */
}
PUT_UINT32_LE(ro + l, res + (size_t)pi * (size_t)pphlen);
bhash = BIO_new(BIO_f_md());
if (bhash == NULL) {
OPENSSL_free(zeroes);
OPENSSL_free(res);
return NULL;
}
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
if (!BIO_set_md(bhash, md)) {
printf("Unable to set the message digest of BIO\n");
fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash);
OPENSSL_free(zeroes);
OPENSSL_free(res);
return NULL; /* FAILED */
}
BIO_push(bhash, BIO_new(BIO_s_null()));
if (rs - l < pagesize) {
if (!BIO_write_ex(bhash, ctx->options->indata + ro + l, rs - l, &written)
|| written != rs - l) {
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
if (BIO_push(bhash, BIO_new(BIO_s_null())) == NULL) {
BIO_free_all(bhash);
OPENSSL_free(zeroes);
OPENSSL_free(res);
return NULL;
}
if (l < rs && rs - l < pagesize) {
size_t tail = (size_t)(rs - l);
if (!BIO_write_ex(bhash, ctx->options->indata + ro + l, tail, &written)
|| written != tail) {
BIO_free_all(bhash);
OPENSSL_free(zeroes);
OPENSSL_free(res);
return NULL; /* FAILED */
}
if (!BIO_write_ex(bhash, zeroes, pagesize - (rs - l), &written)
|| written != pagesize - (rs - l)) {
if (!BIO_write_ex(bhash, zeroes, pagesize - tail, &written)
|| written != pagesize - tail) {
BIO_free_all(bhash);
OPENSSL_free(zeroes);
OPENSSL_free(res);
@@ -1037,17 +1226,34 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
return NULL; /* FAILED */
}
}
BIO_gets(bhash, (char*)res + pi*pphlen + 4, EVP_MD_size(md));
if (BIO_gets(bhash, (char *)res + (size_t)pi * (size_t)pphlen + 4, mdlen) != mdlen) {
BIO_free_all(bhash);
OPENSSL_free(zeroes);
OPENSSL_free(res);
return NULL; /* FAILED */
}
BIO_free_all(bhash);
}
lastpos = ro + rs;
sections += 40;
}
PUT_UINT32_LE(lastpos, res + pi*pphlen);
memset(res + pi*pphlen + 4, 0, (size_t)EVP_MD_size(md));
/* Final entry */
need = (size_t)(pi + 1) * (size_t)pphlen;
if (need > (size_t)phlen) {
fprintf(stderr, "Page hash buffer overflow prevented at final entry: pi=%d need=%zu phlen=%d\n",
pi, need, phlen);
OPENSSL_free(zeroes);
OPENSSL_free(res);
return NULL; /* FAILED */
}
PUT_UINT32_LE(lastpos, res + (size_t)pi * (size_t)pphlen);
memset(res + (size_t)pi * (size_t)pphlen + 4, 0, (size_t)mdlen);
pi++;
OPENSSL_free(zeroes);
*rphlen = pi*pphlen;
*rphlen = pi * pphlen;
return res;
}
@@ -1067,6 +1273,10 @@ static int pe_verify_page_hash(FILE_FORMAT_CTX *ctx, u_char *ph, int phlen, int
if (!ph)
return 1; /* OK */
cph = pe_page_hash_calc(&cphlen, ctx, phtype);
if (!cph) {
fprintf(stderr, "Page hash verification failed: could not calculate page hash\n");
return 0; /* FAILED */
}
mdok = (phlen == cphlen) && !memcmp(ph, cph, (size_t)phlen);
printf("Page hash algorithm : %s\n", OBJ_nid2sn(phtype));
if (ctx->options->verbose) {
@@ -1099,7 +1309,7 @@ static SpcLink *pe_page_hash_link_get(FILE_FORMAT_CTX *ctx, int phtype)
ph = pe_page_hash_calc(&phlen, ctx, phtype);
if (!ph) {
printf("Failed to calculate page hash\n");
fprintf(stderr, "Failed to calculate page hash\n");
return NULL; /* FAILED */
}
if (ctx->options->verbose)
@@ -1169,43 +1379,71 @@ static int pe_check_file(FILE_FORMAT_CTX *ctx)
{
uint32_t real_pe_checksum, sum = 0;
if (!ctx) {
printf("Init error\n\n");
if (ctx == NULL || ctx->pe_ctx == NULL || ctx->options == NULL
|| ctx->options->indata == NULL) {
fprintf(stderr, "Init error\n");
return 0; /* FAILED */
}
real_pe_checksum = pe_calc_realchecksum(ctx);
if (ctx->pe_ctx->pe_checksum == real_pe_checksum) {
printf("PE checksum : %08X\n\n", real_pe_checksum);
printf("PE checksum : %08X\n", real_pe_checksum);
} else {
printf("Current PE checksum : %08X\n", ctx->pe_ctx->pe_checksum);
printf("Calculated PE checksum: %08X\n", real_pe_checksum);
printf("Warning: invalid PE checksum\n\n");
printf("Warning: invalid PE checksum\n");
}
/* Signature directory bounds */
if (ctx->pe_ctx->sigpos == 0 || ctx->pe_ctx->siglen == 0
|| ctx->pe_ctx->sigpos > ctx->pe_ctx->fileend) {
printf("No signature found\n\n");
|| ctx->pe_ctx->sigpos > ctx->pe_ctx->fileend
|| ctx->pe_ctx->siglen > ctx->pe_ctx->fileend - ctx->pe_ctx->sigpos) {
fprintf(stderr, "No signature found\n");
return 0; /* FAILED */
}
/*
* Validate WIN_CERTIFICATE chain.
* If the sum of the rounded dwLength values does not equal the Size value,
* then either the attribute certificate table or the Size field is corrupted.
*/
while (sum < ctx->pe_ctx->siglen) {
uint32_t len = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->sigpos + sum);
if (ctx->pe_ctx->siglen - len > 8) {
printf("Corrupted attribute certificate table\n");
printf("Attribute certificate table size : %08X\n", ctx->pe_ctx->siglen);
printf("Attribute certificate entry length: %08X\n\n", len);
uint32_t len, off;
/* Prevent overflow in sigpos + sum */
if (sum > UINT32_MAX - ctx->pe_ctx->sigpos) {
fprintf(stderr, "Corrupted attribute certificate table\n");
return 0; /* FAILED */
}
/* quadword align data */
len += len % 8 ? 8 - len % 8 : 0;
off = ctx->pe_ctx->sigpos + sum;
/* Need at least 4 bytes to read dwLength */
if (off > ctx->pe_ctx->fileend || ctx->pe_ctx->fileend - off < 4) {
fprintf(stderr, "Corrupted attribute certificate table\n");
return 0; /* FAILED */
}
len = GET_UINT32_LE(ctx->options->indata + off);
/* dwLength must include the 8-byte WIN_CERTIFICATE header */
if (len < 8 || len > ctx->pe_ctx->siglen - sum || len > ctx->pe_ctx->fileend - off) {
fprintf(stderr, "Corrupted attribute certificate table\n");
return 0; /* FAILED */
}
/* Quadword align data */
if (len % 8) {
uint32_t pad = 8 - (len % 8);
/* Ensure quadword alignment does not overflow or exceed remaining table size */
if (pad > ctx->pe_ctx->siglen - sum - len) {
fprintf(stderr, "Corrupted attribute certificate table\n");
return 0; /* FAILED */
}
len += pad;
}
sum += len;
}
if (sum != ctx->pe_ctx->siglen) {
printf("Corrupted attribute certificate table\n");
printf("Attribute certificate table size : %08X\n", ctx->pe_ctx->siglen);
printf("Sum of the rounded dwLength values: %08X\n\n", sum);
fprintf(stderr, "Corrupted attribute certificate table\n");
fprintf(stderr, "Attribute certificate table size : %08X\n", ctx->pe_ctx->siglen);
fprintf(stderr, "Sum of the rounded dwLength values: %08X\n\n", sum);
return 0; /* FAILED */
}
return 1; /* OK */
+71 -70
View File
@@ -8,11 +8,17 @@
#include "helpers.h"
#include "utf.h"
typedef enum {comment_hash, comment_xml, comment_c, comment_not_found} comment_style;
typedef enum {
comment_hash,
comment_xml,
comment_c,
comment_js,
comment_not_found
} COMMENT_STYLE;
typedef struct {
const char *extension;
comment_style comment;
COMMENT_STYLE comment;
} SCRIPT_FORMAT;
const SCRIPT_FORMAT supported_formats[] = {
@@ -23,21 +29,24 @@ const SCRIPT_FORMAT supported_formats[] = {
{".psm1", comment_hash},
{".cdxml", comment_xml},
{".mof", comment_c},
{".js", comment_js},
{NULL, comment_not_found},
};
const char *signature_header = "SIG # Begin signature block";
const char *signature_footer = "SIG # End signature block";
#define header_hash "SIG # Begin signature block"
#define footer_hash "SIG # End signature block"
#define header_js "Begin signature block"
#define footer_js "End signature block"
typedef struct {
const char *open;
const char *close;
const char *open, *close, *header, *footer;
} SCRIPT_COMMENT;
const SCRIPT_COMMENT comment_text[] = {
[comment_hash] = {"# ", ""},
[comment_xml] = {"<!-- ", " -->"},
[comment_c] = {"/* ", " */"}
[comment_hash] = {"# ", "", header_hash, footer_hash},
[comment_xml] = {"<!-- ", " -->", header_hash, footer_hash},
[comment_c] = {"/* ", " */", header_hash, footer_hash},
[comment_js] = {"// SIG // ", "", header_js, footer_js}
};
struct script_ctx_st {
@@ -242,11 +251,18 @@ 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 defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
if (!BIO_set_md(hash, md)) {
printf("Unable to set the message digest of BIO\n");
fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(hash);
return NULL; /* FAILED */
}
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(hash, BIO_new(BIO_s_null()));
if (!script_write_bio(hash, ctx->options->indata, ctx->script_ctx->fileend)) {
BIO_free_all(hash);
@@ -272,21 +288,8 @@ static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
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) {
printf("Failed to extract current message digest\n\n");
if (!pkcs7_get_content_digest(p7, mdbuf, &mdtype)) {
fprintf(stderr, "Failed to extract current message digest\n\n");
return 0; /* FAILED */
}
md = EVP_get_digestbynid(mdtype);
@@ -299,7 +302,7 @@ static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
BIO_free_all(bhash);
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
printf("Signature verification: failed\n\n");
fprintf(stderr, "Signature verification: failed\n\n");
OPENSSL_free(cmdbuf);
return 0; /* FAILED */
}
@@ -316,20 +319,18 @@ 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, der_max_length, der_length;
size_t base64_len;
char *ptr;
BIO *bio_mem, *bio_b64 = NULL;
char *base64_data = NULL;
char *der_data = NULL;
const char *der_tmp;
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);
size_t header_len = strlen(ctx->script_ctx->comment_text->header);
size_t footer_len = strlen(ctx->script_ctx->comment_text->footer);
PKCS7 *retval = NULL;
if (!script_check_file(ctx)) {
@@ -339,6 +340,8 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
if (ctx->script_ctx->utf == 8) {
base64_len = signature_len;
base64_data = OPENSSL_malloc(base64_len);
if (!base64_data)
return NULL; /* memory allocation failed */
memcpy(base64_data, signature_data, base64_len);
} else {
base64_len = utf16_to_utf8((const void *)signature_data,
@@ -348,7 +351,7 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
/* allocate memory for cleaned Base64 */
clean_base64 = OPENSSL_malloc(base64_len);
if (!clean_base64) {
printf("Malloc failed\n");
fprintf(stderr, "Malloc failed\n");
goto cleanup;
}
@@ -357,7 +360,7 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
/* find the opening tag */
for(;;) {
if (ptr + open_tag_len >= base64_data + base64_len) {
printf("Signature line too long\n");
fprintf(stderr, "Signature line too long\n");
goto cleanup;
}
if (!memcmp(ptr, open_tag, (size_t)open_tag_len)) {
@@ -366,18 +369,18 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
}
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))
/* process header and footer */
if (ptr + header_len < base64_data + base64_len &&
!memcmp(ptr, ctx->script_ctx->comment_text->header, header_len))
ptr += header_len;
if (ptr + footer_len <= base64_data + base64_len &&
!memcmp(ptr, ctx->script_ctx->comment_text->footer, footer_len))
break; /* success */
/* copy until the closing tag */
for(;;) {
if (ptr + close_tag_len >= base64_data + base64_len) {
printf("Signature line too long\n");
fprintf(stderr, "Signature line too long\n");
goto cleanup;
}
if (close_tag_len) {
@@ -403,26 +406,12 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
BIO_push(bio_b64, bio_mem);
BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
/* allocate memory for DER output */
der_max_length = BIO_ctrl_pending(bio_b64);
der_data = OPENSSL_malloc(der_max_length);
if (!der_data)
goto cleanup;
/* decode Base64 to DER */
if (!BIO_read_ex(bio_b64, der_data, der_max_length, &der_length))
goto cleanup;
if (der_length <= 0)
goto cleanup;
/* decode DER */
der_tmp = der_data;
retval = d2i_PKCS7(NULL, (const unsigned char **)&der_tmp, (int)der_length);
retval = d2i_PKCS7_bio(bio_b64, NULL);
cleanup:
OPENSSL_free(base64_data);
OPENSSL_free(clean_base64);
OPENSSL_free(der_data);
BIO_free_all(bio_b64);
return retval;
}
@@ -471,10 +460,10 @@ static int script_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
ctx->script_ctx->fileend = ctx->script_ctx->sigpos;
}
if (!script_write_bio(outdata, ctx->options->indata, ctx->script_ctx->fileend))
return 1; /* FAILED */
return 0; /* FAILED */
if (!script_digest_convert(hash, ctx, ctx->script_ctx->fileend))
return 1; /* FAILED */
return 0; /* OK */
return 0; /* FAILED */
return 1; /* OK */
}
/*
@@ -489,21 +478,21 @@ static PKCS7 *script_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
PKCS7 *p7 = pkcs7_create(ctx);
if (!p7) {
printf("Creating a new signature failed\n");
fprintf(stderr, "Creating a new signature failed\n");
return NULL; /* FAILED */
}
if (!add_indirect_data_object(p7)) {
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n");
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) {
printf("Failed to get spcIndirectDataContent\n");
fprintf(stderr, "Failed to get spcIndirectDataContent\n");
return NULL; /* FAILED */
}
if (!sign_spc_indirect_data_content(p7, content)) {
printf("Failed to set signed content\n");
fprintf(stderr, "Failed to set signed content\n");
PKCS7_free(p7);
ASN1_OCTET_STRING_free(content);
return NULL; /* FAILED */
@@ -547,7 +536,9 @@ static int script_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
(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)))
if (!write_commented(ctx, outdata,
ctx->script_ctx->comment_text->header,
strlen(ctx->script_ctx->comment_text->header)))
goto cleanup;
for (i = 0; i < buffer->length; i += 64) {
if (!write_commented(ctx, outdata, buffer->data + i,
@@ -555,7 +546,9 @@ static int script_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
goto cleanup;
}
}
if (!write_commented(ctx, outdata, signature_footer, strlen(signature_footer)))
if (!write_commented(ctx, outdata,
ctx->script_ctx->comment_text->footer,
strlen(ctx->script_ctx->comment_text->footer)))
goto cleanup;
/* signtool expects CRLF terminator at the end of the text file */
@@ -621,7 +614,7 @@ static SCRIPT_CTX *script_ctx_get(char *indata, uint32_t filesize, const SCRIPT_
*ptr && commented_header_len < commented_header_size;
commented_header_len++)
ptr = utf8DecodeRune(ptr, 1, commented_header + commented_header_len);
for (ptr = signature_header;
for (ptr = comment->header;
*ptr && commented_header_len < commented_header_size;
commented_header_len++)
ptr = utf8DecodeRune(ptr, 1, commented_header + commented_header_len);
@@ -687,6 +680,8 @@ static int write_commented(FILE_FORMAT_CTX *ctx, BIO *outdata, const char *data,
* - closing tag
* - trailing NUL ("\0") */
line = OPENSSL_malloc(2 + open_tag_len + length + close_tag_len + 1);
if (!line)
return 0; /* memory allocation failed */
strcpy(line, "\r\n");
strcat(line, open_tag);
memcpy(line + 2 + open_tag_len, data, length);
@@ -798,15 +793,21 @@ static BIO *script_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
fileend = ctx->script_ctx->sigpos;
else
fileend = ctx->script_ctx->fileend;
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
if (!BIO_set_md(hash, md)) {
printf("Unable to set the message digest of BIO\n");
fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(hash);
return NULL; /* FAILED */
}
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(hash, BIO_new(BIO_s_null()));
if (!script_digest_convert(hash, ctx, fileend)) {
printf("Unable calc a message digest value\n");
fprintf(stderr, "Unable calc a message digest value\n");
BIO_free_all(hash);
return NULL; /* FAILED */
}
@@ -868,12 +869,12 @@ static int script_write_bio(BIO *bio, char *indata, size_t len)
static int script_check_file(FILE_FORMAT_CTX *ctx)
{
if (!ctx) {
printf("Init error\n\n");
fprintf(stderr, "Init error\n");
return 0; /* FAILED */
}
if (ctx->script_ctx->sigpos == 0
|| ctx->script_ctx->sigpos > ctx->script_ctx->fileend) {
printf("No signature found\n\n");
fprintf(stderr, "No signature found\n");
return 0; /* FAILED */
}
+2
View File
@@ -0,0 +1,2 @@
__pycache__
.pylintrc
-22
View File
@@ -1,22 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDoTCCAomgAwIBAgIUVD6Q+gnrOmJWbEnmfydpUg2JNmswDQYJKoZIhvcNAQEL
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
MTcwMTAxMDAwMDAwWhcNMzYxMjI3MDAwMDAwWjBYMQswCQYDVQQGEwJQTDEVMBMG
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEQMA4GA1UEAwwHUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAMUvCAWI9LrgtVw9RARZLFb/qB1868H86eyr8oITzXl6u9FSQwvGH1MG
szRhuD9TJAjy1uIiVPJ7ez2VjKXm2G9lUZMPJQRt50XTGbsGGDi4ITU1W3P+HI5u
45I0IL14Qv/R8X26lndBzlY4ImoCTAN4KzdfvoGLaMpNvbC1P7a4mlukrumi3WKT
RAq46Mj5DAqr63NOolWimtTB+h0ZWv+xxngR7cfo+EimvhPB7y3xhY9OJ/27l6mJ
uQJohz5PmzhZByluMhicTsd2cJEKQb7jnih492okCj6vH/FJmKg+DzXKTyue5Ki4
2jhzM9v1npyIkd7s/gnZVEsHH6oQIt8CAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB
/zAdBgNVHQ4EFgQUGjxG/vql0oJgItr7HsLaW+koiMgwHwYDVR0jBBgwFoAUGjxG
/vql0oJgItr7HsLaW+koiMgwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUA
A4IBAQAy7AKbO8B8Njseqjy2LAj2sKHCLc1jsQa7izOAtr852NYFAfpBvkqQfxne
8k5iPKmcJE+Sm4wv3V/lzx2AHEXAPa7BgiAo7yeo9UbrDgRRGw4MirQ/djp44ekv
KCc54bSE/paUZyEWKr8NbdBy7SZfZ/Dd+XUY2lbm3Mue3AzWl4xp4StoT6oaw6VI
H6bIhZupond/RWp4jmHHEfvl4T6YLzl5FC+Ec2xBbpk5vAVZgyfrlv+W6V/il/X9
KTZl5ax4FJAm7vPn6fsgdAM5y24zJUAkeakKFsBYtoVoGg1iiFuMEGwFRn7EZYl1
8D16qEH+YPLCzujH1PhzjmmAfKl2
-----END CERTIFICATE-----
Binary file not shown.
-13
View File
@@ -1,13 +0,0 @@
-----BEGIN X509 CRL-----
MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJQTDEVMBMGA1UE
CgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBFw0xOTAxMDEwMDAwMDBaFw00MzAx
MDEwMDAwMDBaMCcwJQIUazbrVgbYb+IN803UmJJa0DPHQsAXDTI0MDIyNzE1MzAx
NFqgMDAuMB8GA1UdIwQYMBaAFGQQ8as5N9zB/bsdyD9BWHdiJ+8pMAsGA1UdFAQE
AgIQATANBgkqhkiG9w0BAQsFAAOCAQEAV+Ce8WaNN/PXbVT9rOy/TS2EDrM/oFPG
vwZr2IQDcBtgFV5DpNZRKJo2m4mjPPt1eCjE404U2r6081bvq3PtwSPwezV+uCzF
dDUafeR0eZhmzxD8M2Jmi5hGp3fQevDrA4+RR33DneYSNfzGx35VN8v/L7/TuA5X
0PG8b5hL9f3vsVXvFRj6hMkRy5m+gxFfWW/Uw3fXIt9sDLJ+eAKURdqn1c3CEwD6
bzh0s6dSXT4wp5/l96x8fKAv5hMqDC7KufvwjhhSXdYXDOHDQcv0g5aLo8Ug8dHg
NJHqbTAAViyGfvsS9/pYb8kHpAWvaADK84tzaMzj7uCDXlCZEjIr7w==
-----END X509 CRL-----
-14
View File
@@ -1,14 +0,0 @@
-----BEGIN X509 CRL-----
MIICMzCCARsCAQEwDQYJKoZIhvcNAQELBQAwZzELMAkGA1UEBhMCUEwxFTATBgNV
BAoMDG9zc2xzaWduY29kZTEgMB4GA1UECwwXQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkxHzAdBgNVBAMMFkludGVybWVkaWF0ZSBDQSBDUkwgRFAXDTE5MDEwMTAwMDAw
MFoXDTQzMDEwMTAwMDAwMFowTjAlAhQcZvYIe2b1FreAKfoi/uGkSGJCthcNMjQw
MjI3MTUzMDE0WjAlAhRrNutWBthv4g3zTdSYklrQM8dCwBcNMjQwMjI3MTUzMDE0
WqAwMC4wHwYDVR0jBBgwFoAUFDxiqeJxiJbmZ4erKH0pBIhq7SMwCwYDVR0UBAQC
AhACMA0GCSqGSIb3DQEBCwUAA4IBAQBZzGXEP4XdKuJ8ANIBGPu1Z+7T+4ln+nu3
MEPC9BexVAA02YPZx6i4c3cHC87aOL7zsr/K9OeF5MAYzi2QJwsenF4b9QL2rzQV
sCAb3sY5ImAxN38GTJ+oI+uTeOefNE0wS7pP4phRmYNZwyDhxA2iT76+luoygyth
NesiGalMFDrJvUM1DADTZGQrz9cQVgFq9WTcta9rdTYqSNctxkbpQaY0hgssH1Sh
hWlSiFttciA2XVD7Ju/Qv9zN4nCQC0LskgKhqsefsOukpo6jqJ92OmNrrNaERfqs
Yavzuj6DlcnE46ZxA0y2Du1apz0WDlbcAnsEqfNSDDCid09v+V9a
-----END X509 CRL-----
-22
View File
@@ -1,22 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDqTCCApGgAwIBAgIUKFKqG3FwQAmy4HgYyO4mGEiQ8QAwDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD1RydXN0ZWQgUm9v
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0zNzEyMjcwMDAwMDBaMFgxCzAJBgNVBAYT
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxIDAeBgNVBAsMF0NlcnRpZmljYXRp
b24gQXV0aG9yaXR5MRAwDgYDVQQDDAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAxS8IBYj0uuC1XD1EBFksVv+oHXzrwfzp7KvyghPNeXq7
0VJDC8YfUwazNGG4P1MkCPLW4iJU8nt7PZWMpebYb2VRkw8lBG3nRdMZuwYYOLgh
NTVbc/4cjm7jkjQgvXhC/9HxfbqWd0HOVjgiagJMA3grN1++gYtoyk29sLU/tria
W6Su6aLdYpNECrjoyPkMCqvrc06iVaKa1MH6HRla/7HGeBHtx+j4SKa+E8HvLfGF
j04n/buXqYm5AmiHPk+bOFkHKW4yGJxOx3ZwkQpBvuOeKHj3aiQKPq8f8UmYqD4P
NcpPK57kqLjaOHMz2/WenIiR3uz+CdlUSwcfqhAi3wIDAQABo2MwYTAPBgNVHRMB
Af8EBTADAQH/MB0GA1UdDgQWBBQaPEb++qXSgmAi2vsewtpb6SiIyDAfBgNVHSME
GDAWgBSzLyt07qrH3+rgkQCvS/YZ3jR+fzAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZI
hvcNAQELBQADggEBADCY4hadNyzoz0CpdpBcFjyglxOkgcitIAgvoc2N5zwHrkg7
BgJM1BJmCyki0AhXRKwl7sYbzNHgAhP1pBNjZqO13+cRcqPKvrxpYnsv11HaPS2E
Ee/8EwHB3JlWlmWd6PHaJV0usRjDOuJnV/I/9mdFfIUcY0aoA36o2CCRJRKcvvVp
Ztomnvw8IqFTn3GCNK3TRmVf2RYMhsDNQoEEidJENwCCRlcojmk1Ld95T89QsGOR
cWJAHzyfbMQxRD7kQPZ4B2M8MvU3uD6nsamzvVM7H0UkSNuYLVkpU/wTUR8eQ2LI
wFyi9JhKP4hF/RBuSzIHpXWO46GvzAO5dXZPLm0=
-----END CERTIFICATE-----
-22
View File
@@ -1,22 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDsTCCApmgAwIBAgIUQQOniemvgowXmc2hZSZoIWEF8DUwDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD1RydXN0ZWQgUm9v
dCBDQTAeFw0xNzAxMDEwMDAwMDBaFw0zNjEyMjcwMDAwMDBaMGAxCzAJBgNVBAYT
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxIDAeBgNVBAsMF0NlcnRpZmljYXRp
b24gQXV0aG9yaXR5MRgwFgYDVQQDDA9UcnVzdGVkIFJvb3QgQ0EwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCL2tfObRQcJ4fo/jarNfQVmeqjulYkLLNG
UtYmFSAxkcYbmpfHpsSxnW9sbDZV8Cp6tFa97V7XATCNL/r671lpZjkYEj0NkjBE
84OI0pkAEwWC5m3+dl3wehu977OcV7cMxNTmAHJwEadXR3jmZV625/lja1QqgkqK
MqOty2pJNmsRUEogjFoh00eulnapW5u72ovq9IDgjjhdvAClwkTY5jsLTeDwgvfS
MRjAmef2qExI/l760Bl0xe4XDdROgN90npS/zuKcCkThtvmffiUZsyeel1kto1pF
zkYGJroWSJl0Jt+dpJHcpSXOXP5M+LnuLV4nl5vqwksdPzswQvuZAgMBAAGjYzBh
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLMvK3Tuqsff6uCRAK9L9hneNH5/
MB8GA1UdIwQYMBaAFLMvK3Tuqsff6uCRAK9L9hneNH5/MA4GA1UdDwEB/wQEAwIB
hjANBgkqhkiG9w0BAQsFAAOCAQEAesmiOEl8OA+T4DDOgjfhY6+pUZDDKpsx//mj
/1bxr+akfwL3dN5IBq8g8tJJHOLqrl7Lard7onDRnz8GZmpkPvFa87QD2PU2addo
DAQWdYsDrNMWkAE37Wk7FZ0RyFHiBopRUMspKmx/XwvJf+rhkidjJYxCo317i/Z8
fWi//wGsI6ogezOsMCxNEcIn2PltGfDiVFklmwsXhyfvGYfctqepu661a/7hFUaP
uN0iEboTDcQuiWwwEEwMe55L1rjDlpRkGUBah5FteGmVwk0AoT4b+1FVrj9Q6sEa
Ge6gsrhu2syUF9CErTW/CiV+jONe2ygw4welOBo598QW71w7Vw==
-----END CERTIFICATE-----
-28
View File
@@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCplbeNvGrZmTDz
p48TyvpOX36bGPMfyTVc8ZfAoh0SG86EFc1LHBV2K52dshHYqniQ6lE14jhsRPps
YRBUFXO7I84Jd5CVcrvBWGuL8wXxjMwIW5buzY4x5oKowlyQGIasNiC8Mgx8TncJ
kVWE6ekgoP4i1f4PVsFyG8zVNpI5VzHArAemYhvDjuA5jgTisfP8ph2pxUKTzYAI
SaKm2YkBFvyhhTxtqnXHt8S0NnfDSCedKSzl1caN1TAKSbWoeChb+Tq8rycjPXh/
/7TkYgxmlSHiQhRcyEaZs54Ud8Q0nsnfRMhEtewr2IACmuKrFnoS+GtY5glPilR5
ScZ+7A9TAgMBAAECggEABOI/XIzFYMzeg2Rg8DAquQlyc92NE5zPtW0/WxhhizdT
bPF3EISXh9DdMimCBeH8XxIzWFfSeFaoNFHp1GCf9ckYRuptk8ppz3OKVhOIbxqr
YNY9UVVCrEFmjJ0Vxj7Be5M9TTEU4mxLVX4FtmDVClubeOxyX/oqcr4uwme0Az6A
tjBVzl+YEYvZrbhao5d09LVQ3zj1T1EQ+XU5iTTV5Two86FQ6NQ9txe7jxcB8x8S
BbD/PakmZj+oIdVBp4xnrhCJ3mYdzXy3qHWxq/BtHgS5fY3/tq3xtVSNxw7QJG7j
CT2Cps3/99Lq2CPi8OkQKgjJwWqCZ0jOwHahEMlWIQKBgQDneq4LH0zfPJIW2zsi
C7U813hV4NuQXd5EW2bmNe4KKnlrcbt3ZtJv8v3Ff5lMm1i8jDCeaeGhZOi/Ag/z
aTtM1STFFEQg3QktcSAvS7hXufvAeufSrPOZdpBO51wqZl5wLMp2lsq885R3wnRl
FtIErdmsLigVMC8RZ++gFNIjMQKBgQC7jJE93wV3j36QA7NAgxNH0AW5p5foWuA8
gR8MA9cpFI7X7q6hW9HYXw30kD3IzN6UW4U5LT4Pandxx484G1KENcyW2TzeGtpC
MWBWHF4Mbxb/2pEkQoPk1dZmUxF5hvaGGHQYJn/pnJFavGUoNBlNjaIfgStzd1IO
68ceo5URwwKBgGjHJjrQmzo9L5968sRRamM04Tp2QsyRQMfOW8B+ztX5LebNn17H
wx97bRVV0a1UcBFAn81E/iXRCG1VYKT8kCQSIse2ibQaeUoBd+EQtEu5WtRgjcjW
Epn3ihC9NwHWPo8mJysQzIpE84JWGducPcpyayI97lTQ761AT741Tn0xAoGARtG2
ioFrhBEoPmNXTZXxMt3HO6qgPvoJ0G8FdTkCBx4fLkSPppiQbb6++0l4Oxm5NpY0
gTmnRJT0U3+CgjI2/3t9LL0NMeU742DXusxtaw6LxcMXqXSAb2mb0vmtEJG5Bzu2
ouPuyxz2+idHn13E7Db+MB1Ldgdpcf7wKo6knJcCgYBwbcjW0MwCah3w4N4VLXBX
Q5wPSw7cRcytHqrrWkT/nTI3fxwd7UW6ZdM0IwGIAwYgBYD5B78KH0aP6BlUmYWu
8vut6S/MsNyCzHQVbcR9BUK3drByzhysVE3TUQKjCA33v6M/tTixhpyPf+ZZtjlK
b1+6D1aGpwt+11f9ubd+Nw==
-----END PRIVATE KEY-----
-25
View File
@@ -1,25 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEMzCCAxugAwIBAgIUAQ9lOMiuXUZuKaxzEpwQmCzU7aowDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0zODAxMDEwMDAwMDBaMFUxCzAJBgNVBAYT
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxHDAaBgNVBAsME1RpbWVzdGFtcCBB
dXRob3JpdHkxETAPBgNVBAMMCFRlc3QgVFNBMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAqZW3jbxq2Zkw86ePE8r6Tl9+mxjzH8k1XPGXwKIdEhvOhBXN
SxwVdiudnbIR2Kp4kOpRNeI4bET6bGEQVBVzuyPOCXeQlXK7wVhri/MF8YzMCFuW
7s2OMeaCqMJckBiGrDYgvDIMfE53CZFVhOnpIKD+ItX+D1bBchvM1TaSOVcxwKwH
pmIbw47gOY4E4rHz/KYdqcVCk82ACEmiptmJARb8oYU8bap1x7fEtDZ3w0gnnSks
5dXGjdUwCkm1qHgoW/k6vK8nIz14f/+05GIMZpUh4kIUXMhGmbOeFHfENJ7J30TI
RLXsK9iAApriqxZ6EvhrWOYJT4pUeUnGfuwPUwIDAQABo4HvMIHsMAwGA1UdEwEB
/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwHQYDVR0OBBYEFKryJiH4Y0KO
x2nCc4cOvih1VzjmMB8GA1UdIwQYMBaAFD8ujz0I9Y7079ZMe9X7cO3/rSj5MC0G
A1UdHwQmMCQwIqAgoB6GHGh0dHA6Ly8xMjcuMC4wLjE6MTkyNTQvVFNBQ0EwVQYD
VR0eBE4wTKAYMAqCCHRlc3QuY29tMAqCCHRlc3Qub3JnoTAwCocIAAAAAAAAAAAw
IocgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwDQYJKoZIhvcNAQEL
BQADggEBAAhzijhC1kvBV75rxRqj27gtYRG8dNkHc5umzwXyNNMn2tI/kO2Rf+ES
9RamQE9sfvOgg3UqfXIfRPsC4cBHnjT+ELdqbt4byk3LPtstJGFuLy0iNRNY9f1j
lBJrldLZNNsIpNMQa0u5h/z4m0CAA8j6ayUvcoR11y2zYHkHlSScTq/s7gSQzXlK
z4DRiiYif2OEdKVeRCqlDV8AOlhm1+9am74dkfO71aT0G2hko2u19NWZvjc/DqI1
V+e2g5TDE7V65d9vvf9tA26i0At/VazvnhsgdpgUkwS6mjUvx+gW3i5YJhtXjdAX
hpE0ajpKT0x/dNa/qCwl/9zc8XxGnPk=
-----END CERTIFICATE-----
-22
View File
@@ -1,22 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDkDCCAnigAwIBAgIULFuB5HWsyba6VHu2Ygv2vt4R4/swDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
dCBDQTAeFw0xNzAxMDEwMDAwMDBaFw0zNjEyMjcwMDAwMDBaMGAxCzAJBgNVBAYT
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxJDAiBgNVBAsMG1RpbWVzdGFtcCBB
dXRob3JpdHkgUm9vdCBDQTEUMBIGA1UEAwwLVFNBIFJvb3QgQ0EwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBo8JJDwVm6UTZvA2g/tOZ3xIbKYXI92Rn
T/FCCUycsB5tmoSWcmy1AB6UDv7bFMGy4mdbxnErtdytGj+hEIO3O2EBbpBLAmlJ
CEVNRrz/YbxGoJmeAii9s3jignUpTr/qLMSKkLowuqABZl2XtCp7Q83YlZPkVhFL
kCAny89cG/QGAUxViN7HB4jWzhcBTTfD4PFvSU1HZNhPM0Y6BCpv2qrof3/tPnQr
xM2zVZoIonQpf6paga61O9fM4wc1GqxGGwARz6Bxq6w2OxRDsV/biqP9gVUj0XmF
6o/draf3MkDswOUZyKpujOUIf12ezXJFPWaCRN1Rl0vwV2CyVxkvAgMBAAGjQjBA
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFD8ujz0I9Y7079ZMe9X7cO3/rSj5
MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAtHmPfVgu6Y7uWcpq
AdawOTZ/2ICOvAMmQ0LcXKmSpgsneHiyAL1Wwe2/XxTwmrpHylOapIIuV3irHCXU
CxaTMUyZGfXoUWsxnR8bcb5ac/aFKkC3ynE2/IfFyJOQ724cK5FRK1+piVleP4Rx
C04KQiuxuVLedyvGh5OPU/94ZW2JuuBjImVAO/lUbYhAUSpwueX2lYKSSPLkPfDx
AsIp55x70iQ+EsgARvseVY2JRzvRnuh66V4P15wn3dIzjtWQ1/t007wMk5Lji5dQ
iSvdyqULBytBqDtLPLzRuma1KJEPRIamF1j6Or6HaHSVUorRhqI3XuxEUGdO4LxZ
QepMyA==
-----END CERTIFICATE-----
Binary file not shown.
-15
View File
@@ -1,15 +0,0 @@
-----BEGIN X509 CRL-----
MIICUzCCATsCAQEwDQYJKoZIhvcNAQELBQAwYDELMAkGA1UEBhMCUEwxFTATBgNV
BAoMDG9zc2xzaWduY29kZTEkMCIGA1UECwwbVGltZXN0YW1wIEF1dGhvcml0eSBS
b290IENBMRQwEgYDVQQDDAtUU0EgUm9vdCBDQRcNMTkwMTAxMDAwMDAwWhcNNDMw
MTAxMDAwMDAwWjB1MCUCFA5lCWy+o133yMUTfqtWmkigL1MeFw0yNDAyMjcxNTMw
MTVaMCUCFBxm9gh7ZvUWt4Ap+iL+4aRIYkK2Fw0yNDAyMjcxNTMwMTRaMCUCFGs2
61YG2G/iDfNN1JiSWtAzx0LAFw0yNDAyMjcxNTMwMTRaoDAwLjAfBgNVHSMEGDAW
gBQ/Lo89CPWO9O/WTHvV+3Dt/60o+TALBgNVHRQEBAICEAMwDQYJKoZIhvcNAQEL
BQADggEBAJ1HK2LepVJyOfqbODFxD6GJo5jr1HEnoaZ1h/iJTZZyDYfRf8d8Y/VG
Iva00gj2KVy8tOlO0FrUR1Tqk42IjaPld0lXqKl4hkmCUWLpLgual5JcQPHhDUnT
hiIDvbI5UHGCWeN+unXFRuT9CvtAM+3FOhuL9bBnXwdlOxZPWL8wnYT0jB/HzdKP
KOWfN7eEXo6tTL8XxRJ5LxjwbrK1eZCdQqL2Rt2W8JTMweeqv9PkNqzYeDAvKc0s
UCkKj+aNxQlNPy+Tw/MckJK1NE921b8LwuV0uzBrOg0Gr62RnnPGa6Z5YLArczWo
aZlLVsJuQrOxxyXe/kygCu9lqjaf4CI=
-----END X509 CRL-----
-28
View File
@@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDxU8lwCceWEesm
HIQu9M8mIznHFWmxFF55E16DseWr1K2FbOKnNv1ddNhUHFhBQChcGPn/CvwfOMR7
DbCETrty9HUtoK3fCVZQuYIjZwRLZZB2ryLgO4PK+j07Z61yABi7NKBKv8oHISLU
QcNg7rBAZhmAurKpNu2Gpz/jFpFXwd6O+8xnsYFLT0zyjrq0rEvLmWQd5FBQaVt7
P+U9GH3GCg0kmdhIXAfdfSnqzj0OMnnzVdnEYrd1mYx+ZA7m0CmVJw330QXWiyax
wimNHUvlpIiZA8ol17tAybinhPL5nSM/LRZ2PN90EgyX1bv3x/cKCEiOYPSZ7xXV
mrRGjCtjAgMBAAECggEAHj01fIh9LdzI7lmcZpXebxTy5HNWbw3yWJGIwk/ES6e2
poViUTmevdsqUD/M/0AezouCp+akePUQCatJdwq2ikz/cdw0bUIqQqs8F1uNOjVb
yMNhR1+tv/1jNtJi9Wn1r1+ExlkJ46LPTnF/HeJKy4b/oxXB1VpAoSLL6pSlWa1+
+iEWM+s6xlxyFkeWPq3L3u1QGkuW58KqQae86mR8Mgc0kOVuTCqWpHgNjfxt7tnt
L/oBE9zEJmS3iZcGh1X5VR4CUQmtrCp7ldNdhSNk5WcNCNSsuIX+B13s658a0sRB
AnPIX08moB5VHZ/danblny5Zo6SrobWBBcTabwjnYQKBgQD/BHktS70tQj3yBqVL
xXmaO5ozqMLqF9A2o4EiJ/pF07ecHXmbiGaP9Nf/FJemuU5OHjw8akuxKn2M+DTu
gHYOHwByA9/SOeAiD8bp/dJNE+2BO2zygoG/adhEV5tLK8IYdz241t8oVZbQLwql
ZCs1uFab6E/cZEJgSQ0QuC8vtwKBgQDyQc+MX56UFFCP1QpWLIwFVdoPbOj/3cVZ
FIjQO9rNYNIscS36nISIBh0voubI2xFvO7/s+WS1pD1bOmn6qwsndewFGdmMtjnN
YguakmHAUmcF33f+gXVzwR91QvGPTjI2Fzd59OwOrZofO1+hajQiBKIP2B9VHJNP
khspe44JtQKBgFqTTyrMZNOnXHMS8zC3Ydpq4vkILrqQXK6bYiksg9K7QNKdEW0x
hCQLNZBu0vIvjOVoDcLzihDR46fnHH29eLDJSBI22A9F6RqP+flv4nrn4gptfeOg
gM7onByh9RE86IJiD7UP9FDSHW+x1Zkqu8Inx/M2Du9bWMv0BkTy9id/AoGBAOEy
oDcDZCyPPdyW1AcLXhZPmmegfG/tvlhyqEO6gElO6dF6XJ2NBf5UgKkZq6OnUWuv
hVhK9X2M8aRuhroIalQCYKbVQtB1TQJJVDQaQ1g+wZpKBAfIXGCAdDfTRS5MKIzz
xBRQw2dZpd3Gmb05NsEwwV4tL+M0rxPW4/0J6B3JAoGAB1vlzPsfKVvV9jwVpfdO
W2MWAqPF4iI716zLt2F30WNe/42MudQGvMYUEPTYQMu3hhpQk/6UFY2Mfux6+OKk
zG1khRdlq9BkCczfSVjkUvf4wTUUY5b66i4EpeJ//8OArZEx67LhmW715h/LExzG
jkdwUMLiaSrpf8KSTL3NxM0=
-----END PRIVATE KEY-----
-25
View File
@@ -1,25 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEIjCCAwqgAwIBAgIUDmUJbL6jXffIxRN+q1aaSKAvUx4wDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0zODAxMDEwMDAwMDBaMEQxCzAJBgNVBAYT
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNVBAsMA1RTQTEQMA4GA1UE
AwwHUmV2b2tlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPFTyXAJ
x5YR6yYchC70zyYjOccVabEUXnkTXoOx5avUrYVs4qc2/V102FQcWEFAKFwY+f8K
/B84xHsNsIROu3L0dS2grd8JVlC5giNnBEtlkHavIuA7g8r6PTtnrXIAGLs0oEq/
ygchItRBw2DusEBmGYC6sqk27YanP+MWkVfB3o77zGexgUtPTPKOurSsS8uZZB3k
UFBpW3s/5T0YfcYKDSSZ2EhcB919KerOPQ4yefNV2cRit3WZjH5kDubQKZUnDffR
BdaLJrHCKY0dS+WkiJkDyiXXu0DJuKeE8vmdIz8tFnY833QSDJfVu/fH9woISI5g
9JnvFdWatEaMK2MCAwEAAaOB7zCB7DAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQM
MAoGCCsGAQUFBwMIMB0GA1UdDgQWBBTTuQ7LmtwtVydASwFBXd4xUIEh3jAfBgNV
HSMEGDAWgBQ/Lo89CPWO9O/WTHvV+3Dt/60o+TAtBgNVHR8EJjAkMCKgIKAehhxo
dHRwOi8vMTI3LjAuMC4xOjE5MjU0L1RTQUNBMFUGA1UdHgROMEygGDAKggh0ZXN0
LmNvbTAKggh0ZXN0Lm9yZ6EwMAqHCAAAAAAAAAAAMCKHIAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAMA0GCSqGSIb3DQEBCwUAA4IBAQBMiBltqGRRLmK9
0RymCJ4oxmX2jwZ4SM7fem39Ozei7NIQIw5nlkPJ7ZWyfQQNFMIujfwJJGzDguax
mMJHWngzbKjkbdSHnQswxT79RRwenlIKkExck6p2OUT82nGu/6TBIYutMJlITwKF
5OEmu+WneCvTkvEs0wussIug7E7dV6jJO9/TbwWyrtqU/t9GNRbu/4FIdQ9p9pK9
BcqaPmjn7IqnLs94THFfMFH0HVkqpLOfa9Wa8uc/C7WyIMTkchXb4U7/8B/hsDj7
BfKwN/F+IMNw4Rfqytk2JSWuV4pr7MiBweLKBwGgt4DhvfZj32Y/WFNANxtYkE9e
55mIPqG5
-----END CERTIFICATE-----
Binary file not shown.
Binary file not shown.
-46
View File
@@ -1,46 +0,0 @@
-----BEGIN CERTIFICATE-----
MIID7jCCAtagAwIBAgIUKiF/FG2pQjlbId3ox+nQHL/tJ4UwDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD0ludGVybWVkaWF0
ZSBDQTAeFw0xODAxMDEwMDAwMDBaFw0zNDEyMzEwMDAwMDBaMIGdMQswCQYDVQQG
EwJQTDEZMBcGA1UECAwQTWF6b3ZpYSBQcm92aW5jZTEPMA0GA1UEBwwGV2Fyc2F3
MRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNVBAsMA0NTUDEUMBIGA1UEAwwL
Q2VydGlmaWNhdGUxJzAlBgkqhkiG9w0BCQEWGG9zc2xzaWduY29kZUBleGFtcGxl
LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdBCaytt9xsrUx0
2Fekq+IrsR2cC1pL9NANN3TbBv8RKt1IefMh8TjA1uPaOYZvz3o2ml9qKGmJ+uxH
kzLojKbg98bcmxBrkWemLQwmRv1hZIO8D4xiYRd0O0KZizrvwWwlNADzXXWw7iz+
MPPWkXj2nT5MpOTi3S851SwOc/c9SYCazCP8rMGItKHLO7iCjK3sFwBDI9eaTd2N
EjqEHadIymHRizeTOaYv34FokQiRgR/zk4flT6+b6DQHxnlbIivV61OP4bBlFtXX
jC4iGdHLIahhVMlw6ixGqR6910psIp0ST0KM8ly+N+1rPhoNkNSLqkzGUudKo7mV
t+Cp4EMCAwEAAaNiMGAwCQYDVR0TBAIwADAdBgNVHQ4EFgQU6a4Ta3t0UCTG04bC
WMCotMPLyWUwHwYDVR0jBBgwFoAUZBDxqzk33MH9ux3IP0FYd2In7ykwEwYDVR0l
BAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAN2Sad4rLRSKWmaRRUCn
syRO45y7zzvCRApHVSoeBUmtHP+n/OZ3rJTixfluqiGFAqbaXgTN8IantyfqoTjV
XgCP1qzSM3staLCkeAiZ0/OLW+hyHopP8aXX2ez/hMojB/J1b457+vkuudnNiLx8
by44nonUnJb3zyxmCSxcBklNP1wlxYjbbq5hFJ/et2/Y5Ct6igYAEMsYZUEUq3e7
g2GWbqNN/i2tnJyGjDPrNRdOuODuclfIDnYSPn83a40XHn+Hgl9SmoXuSdDutAXC
b017GsOa7OV3ZPildcIa3d/yk4S3L56SdoY+Py4NIIDmxcjji1e91qCrrFfGYwmg
TkQ=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA5yrw3i+fvxBSODvCoQb+9ibWRozmphJBp57tKv9ZraQ5
THK+PkCdjNiJuxZn8F1QLsjJo6JqrrXufYln7wixK0Seu4uV6I2TRzcRyJx29D89
0G9GrTXKn7v8z32QAqCgtwSZ17uWYTFmRAYPllWXcWDONsVyw3UF2nClndL7GMqM
gDizlwsfg8HmRpZegn82I7Y2DXccm9a7pFHuBHpwenKqfBnMsXo3Jj4Xlr1cLTrh
+6ksS5YogOsOd9b5Dfz6FaGmmwrlUWHwdi+EzdnSpOnXzmgflF23sZQ0ynsVvmpl
iD4rXBWnxnQ6Ken3wVPNrA/0ZYGbgSKrcv+/olkh5QIDAQABo2YwZDASBgNVHRMB
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRkEPGrOTfcwf27Hcg/QVh3YifvKTAfBgNV
HSMEGDAWgBQaPEb++qXSgmAi2vsewtpb6SiIyDAOBgNVHQ8BAf8EBAMCAYYwDQYJ
KoZIhvcNAQELBQADggEBAL22kK3SDGnr3lhRE7ipptlKalrQKfpght0XEKm5hxCL
tougN2wtaTEWMwr2YfGJohcKBaGKQ+Bv6WY+EV+hJE4qEUFh6BGqRMtuZdiAbkG+
EveEMhZWQzgf9rUID+Y9Eg+NfCxlpkdQPjUxUV9OkGIshlxkUP8Y+C0h0xIcwq5v
hAfNiJAdcw4fUvtLkpEOFoOjThB8zxOu+Cl3xLCcNOMPLdSxd3YXjy6CMuuOk4RB
gOc8YCyyEvwb9KmARZpMOcQJmucMhs+aC3DF+n71g+agFhDl3Z0QkyyyRjAcD04+
sAR9C8PbqSCQAdydHbAFViEX6x3oGJ7L6zEDcIS10wg=
-----END CERTIFICATE-----
Binary file not shown.
-47
View File
@@ -1,47 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEPTCCAyWgAwIBAgIUe8Im9GuMCHMi3/FDfLgzoE8vTKgwDQYJKoZIhvcNAQEL
BQAwZzELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNVBAMMFkludGVybWVkaWF0
ZSBDQSBDUkwgRFAwHhcNMTgwMTAxMDAwMDAwWhcNMzQxMjMxMDAwMDAwWjCBqzEL
MAkGA1UEBhMCUEwxGTAXBgNVBAgMEE1hem92aWEgUHJvdmluY2UxDzANBgNVBAcM
BldhcnNhdzEVMBMGA1UECgwMb3NzbHNpZ25jb2RlMQwwCgYDVQQLDANDU1AxIjAg
BgNVBAMMGUNlcnRpZmljYXRlIFg1MDl2MyBDUkwgRFAxJzAlBgkqhkiG9w0BCQEW
GG9zc2xzaWduY29kZUBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAMdBCaytt9xsrUx02Fekq+IrsR2cC1pL9NANN3TbBv8RKt1IefMh
8TjA1uPaOYZvz3o2ml9qKGmJ+uxHkzLojKbg98bcmxBrkWemLQwmRv1hZIO8D4xi
YRd0O0KZizrvwWwlNADzXXWw7iz+MPPWkXj2nT5MpOTi3S851SwOc/c9SYCazCP8
rMGItKHLO7iCjK3sFwBDI9eaTd2NEjqEHadIymHRizeTOaYv34FokQiRgR/zk4fl
T6+b6DQHxnlbIivV61OP4bBlFtXXjC4iGdHLIahhVMlw6ixGqR6910psIp0ST0KM
8ly+N+1rPhoNkNSLqkzGUudKo7mVt+Cp4EMCAwEAAaOBmzCBmDAJBgNVHRMEAjAA
MB0GA1UdDgQWBBTprhNre3RQJMbThsJYwKi0w8vJZTAfBgNVHSMEGDAWgBQUPGKp
4nGIluZnh6sofSkEiGrtIzATBgNVHSUEDDAKBggrBgEFBQcDAzA2BgNVHR8ELzAt
MCugKaAnhiVodHRwOi8vMTI3LjAuMC4xOjE5MjU0L2ludGVybWVkaWF0ZUNBMA0G
CSqGSIb3DQEBCwUAA4IBAQBlJrcOaJQQ3TuYaVtmH8VbCdF3GQE+255g0Kq4sWoO
ZgZm6LmRkchuoOXqeZ7aAV6HnGGpZf64ShPSZ3KPt4/UVYkRyS0UihN2ACsGrS4o
ZjOaaoM2xDxttngKV3lAF4xbx18RvAsx9QIzQhzowaSUBQNuu5W4tne/6h7htuwA
KNc0go4fqpCqQjNRVeB1IN50BzUrlHu3zQzfH0LDyUTt2gnObLHMl566Ft0azAG9
emHRM+BOUjKY3ZTjM+JEzpwWgse6e4r+J2fYVYIEtkSfm4ZZnAs5WFWI5o8tqr4b
ruBN7l6oP6R3ugOtPk7tW4x7OO0QoDnfa418MkBlXeqL
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDszCCApugAwIBAgIUN3RBnJCUJ8HmbeNjJZ/6jsXJLGEwDQYJKoZIhvcNAQEL
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBnMQswCQYDVQQGEwJQTDEVMBMG
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEfMB0GA1UEAwwWSW50ZXJtZWRpYXRlIENBIENSTCBEUDCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAME32IBpxW4FhVuZe1PTarEskVHP233QjZtx
poC67/lUK44gtFmsxYsMrDYmmny5pfoM/Byxl5/rorEddLqtDe1kd1SpXUvEYxox
s5rizRd5sZPgkwNoJkSVyNZFwj7gKZHeg6IQHSxNgmTybZ+eZqiNvEveksj3lGpM
Xrbiew7cXUyIP636GPtYxLyIbwDVP0jScqcA/dmSAqofFVUi0SW3OS1hpyXAmmx8
hQHJRKPjPgitZVgjwf5X8/eMTa+ca9dRlRFLk7AcbkF6NcbLm+cRo816nO0EBFV4
Sn2dW9uYqJIfZcpRQ7wbv4fUCghwrk9h3gXrb7AweyK8nyYlmosCAwEAAaNmMGQw
EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUFDxiqeJxiJbmZ4erKH0pBIhq
7SMwHwYDVR0jBBgwFoAUGjxG/vql0oJgItr7HsLaW+koiMgwDgYDVR0PAQH/BAQD
AgGGMA0GCSqGSIb3DQEBCwUAA4IBAQAlI/1XnGc9WzL53rRascZc1EgWAnej9YFS
Dax5+nozYTihC8BRxGfSh1FGRVsmFWhZ0z0XogJJC2bZrQ/36+vwoILItcsWHrQr
rFoZa6s1Uo7ZCd9SfmXjbhMLQgydocCh9YIF66CAkQLwRXc1QIpF7nuZ+rxk0ru1
uGjjBrFRfdSdzlFnyK6wfFzi6LtYDVgVEHC7zzL9E/cyuGo7qQ++SoOg99HjTVY1
PS3ea522bRO2bJpYwZJvvbg020DAfm686VXwAadODdBkI2h6U5SwTxp4SkSmq9SI
mjtERFtnAKD0R2YrX4RzuIckezvwsqLDkQjMnI9XQmv5HWUZimcC
-----END CERTIFICATE-----
-45
View File
@@ -1,45 +0,0 @@
-----BEGIN CERTIFICATE-----
MIID6jCCAtKgAwIBAgIUcgUgRT1Lx8XLdgp7xcWxVl9YBjYwDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD0ludGVybWVkaWF0
ZSBDQTAeFw0xODAxMDEwMDAwMDBaFw0xOTAxMDEwMDAwMDBaMIGZMQswCQYDVQQG
EwJQTDEZMBcGA1UECAwQTWF6b3ZpYSBQcm92aW5jZTEPMA0GA1UEBwwGV2Fyc2F3
MRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNVBAsMA0NTUDEQMA4GA1UEAwwH
RXhwaXJlZDEnMCUGCSqGSIb3DQEJARYYb3NzbHNpZ25jb2RlQGV4YW1wbGUuY29t
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx0EJrK233GytTHTYV6Sr
4iuxHZwLWkv00A03dNsG/xEq3Uh58yHxOMDW49o5hm/PejaaX2ooaYn67EeTMuiM
puD3xtybEGuRZ6YtDCZG/WFkg7wPjGJhF3Q7QpmLOu/BbCU0APNddbDuLP4w89aR
ePadPkyk5OLdLznVLA5z9z1JgJrMI/yswYi0ocs7uIKMrewXAEMj15pN3Y0SOoQd
p0jKYdGLN5M5pi/fgWiRCJGBH/OTh+VPr5voNAfGeVsiK9XrU4/hsGUW1deMLiIZ
0cshqGFUyXDqLEapHr3XSmwinRJPQozyXL437Ws+Gg2Q1IuqTMZS50qjuZW34Kng
QwIDAQABo2IwYDAJBgNVHRMEAjAAMB0GA1UdDgQWBBTprhNre3RQJMbThsJYwKi0
w8vJZTAfBgNVHSMEGDAWgBRkEPGrOTfcwf27Hcg/QVh3YifvKTATBgNVHSUEDDAK
BggrBgEFBQcDAzANBgkqhkiG9w0BAQsFAAOCAQEA0AxgPkboWfIOMYFOP6kQ4nxY
jQ+kAH842ALjm/5z20fYPS0k3LiCNS0FfBPzygeWQLwDGcH2QX6Lfec62CeIe9R9
IAdsX+nNxn9FeIZssfMK3EPgksGUybUNub78mXPrnhCNjYf/GmDY/Cf7jhBtNphK
6zCPOC0WDrupnLW7r4FyrB1j2CEgaHhiSmlQ+19rqbvcNfaCOMfe7IfiwkvVIzE6
tQhnudB/HnW3+pWT83n/KQk0F8lu00fahkak/0bPidTe4zOvepabiWYQXKJ9ZXhm
UW7FHHSM5Vbn2A6zyEht7rcK/gkpHbkckoIi6bDMFMp+K9o3qV7PzZPkaau7fg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA5yrw3i+fvxBSODvCoQb+9ibWRozmphJBp57tKv9ZraQ5
THK+PkCdjNiJuxZn8F1QLsjJo6JqrrXufYln7wixK0Seu4uV6I2TRzcRyJx29D89
0G9GrTXKn7v8z32QAqCgtwSZ17uWYTFmRAYPllWXcWDONsVyw3UF2nClndL7GMqM
gDizlwsfg8HmRpZegn82I7Y2DXccm9a7pFHuBHpwenKqfBnMsXo3Jj4Xlr1cLTrh
+6ksS5YogOsOd9b5Dfz6FaGmmwrlUWHwdi+EzdnSpOnXzmgflF23sZQ0ynsVvmpl
iD4rXBWnxnQ6Ken3wVPNrA/0ZYGbgSKrcv+/olkh5QIDAQABo2YwZDASBgNVHRMB
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRkEPGrOTfcwf27Hcg/QVh3YifvKTAfBgNV
HSMEGDAWgBQaPEb++qXSgmAi2vsewtpb6SiIyDAOBgNVHQ8BAf8EBAMCAYYwDQYJ
KoZIhvcNAQELBQADggEBAL22kK3SDGnr3lhRE7ipptlKalrQKfpght0XEKm5hxCL
tougN2wtaTEWMwr2YfGJohcKBaGKQ+Bv6WY+EV+hJE4qEUFh6BGqRMtuZdiAbkG+
EveEMhZWQzgf9rUID+Y9Eg+NfCxlpkdQPjUxUV9OkGIshlxkUP8Y+C0h0xIcwq5v
hAfNiJAdcw4fUvtLkpEOFoOjThB8zxOu+Cl3xLCcNOMPLdSxd3YXjy6CMuuOk4RB
gOc8YCyyEvwb9KmARZpMOcQJmucMhs+aC3DF+n71g+agFhDl3Z0QkyyyRjAcD04+
sAR9C8PbqSCQAdydHbAFViEX6x3oGJ7L6zEDcIS10wg=
-----END CERTIFICATE-----
-22
View File
@@ -1,22 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA5yrw3i+fvxBSODvCoQb+9ibWRozmphJBp57tKv9ZraQ5
THK+PkCdjNiJuxZn8F1QLsjJo6JqrrXufYln7wixK0Seu4uV6I2TRzcRyJx29D89
0G9GrTXKn7v8z32QAqCgtwSZ17uWYTFmRAYPllWXcWDONsVyw3UF2nClndL7GMqM
gDizlwsfg8HmRpZegn82I7Y2DXccm9a7pFHuBHpwenKqfBnMsXo3Jj4Xlr1cLTrh
+6ksS5YogOsOd9b5Dfz6FaGmmwrlUWHwdi+EzdnSpOnXzmgflF23sZQ0ynsVvmpl
iD4rXBWnxnQ6Ken3wVPNrA/0ZYGbgSKrcv+/olkh5QIDAQABo2YwZDASBgNVHRMB
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRkEPGrOTfcwf27Hcg/QVh3YifvKTAfBgNV
HSMEGDAWgBQaPEb++qXSgmAi2vsewtpb6SiIyDAOBgNVHQ8BAf8EBAMCAYYwDQYJ
KoZIhvcNAQELBQADggEBAL22kK3SDGnr3lhRE7ipptlKalrQKfpght0XEKm5hxCL
tougN2wtaTEWMwr2YfGJohcKBaGKQ+Bv6WY+EV+hJE4qEUFh6BGqRMtuZdiAbkG+
EveEMhZWQzgf9rUID+Y9Eg+NfCxlpkdQPjUxUV9OkGIshlxkUP8Y+C0h0xIcwq5v
hAfNiJAdcw4fUvtLkpEOFoOjThB8zxOu+Cl3xLCcNOMPLdSxd3YXjy6CMuuOk4RB
gOc8YCyyEvwb9KmARZpMOcQJmucMhs+aC3DF+n71g+agFhDl3Z0QkyyyRjAcD04+
sAR9C8PbqSCQAdydHbAFViEX6x3oGJ7L6zEDcIS10wg=
-----END CERTIFICATE-----
-22
View File
@@ -1,22 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDszCCApugAwIBAgIUN3RBnJCUJ8HmbeNjJZ/6jsXJLGEwDQYJKoZIhvcNAQEL
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBnMQswCQYDVQQGEwJQTDEVMBMG
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEfMB0GA1UEAwwWSW50ZXJtZWRpYXRlIENBIENSTCBEUDCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAME32IBpxW4FhVuZe1PTarEskVHP233QjZtx
poC67/lUK44gtFmsxYsMrDYmmny5pfoM/Byxl5/rorEddLqtDe1kd1SpXUvEYxox
s5rizRd5sZPgkwNoJkSVyNZFwj7gKZHeg6IQHSxNgmTybZ+eZqiNvEveksj3lGpM
Xrbiew7cXUyIP636GPtYxLyIbwDVP0jScqcA/dmSAqofFVUi0SW3OS1hpyXAmmx8
hQHJRKPjPgitZVgjwf5X8/eMTa+ca9dRlRFLk7AcbkF6NcbLm+cRo816nO0EBFV4
Sn2dW9uYqJIfZcpRQ7wbv4fUCghwrk9h3gXrb7AweyK8nyYlmosCAwEAAaNmMGQw
EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUFDxiqeJxiJbmZ4erKH0pBIhq
7SMwHwYDVR0jBBgwFoAUGjxG/vql0oJgItr7HsLaW+koiMgwDgYDVR0PAQH/BAQD
AgGGMA0GCSqGSIb3DQEBCwUAA4IBAQAlI/1XnGc9WzL53rRascZc1EgWAnej9YFS
Dax5+nozYTihC8BRxGfSh1FGRVsmFWhZ0z0XogJJC2bZrQ/36+vwoILItcsWHrQr
rFoZa6s1Uo7ZCd9SfmXjbhMLQgydocCh9YIF66CAkQLwRXc1QIpF7nuZ+rxk0ru1
uGjjBrFRfdSdzlFnyK6wfFzi6LtYDVgVEHC7zzL9E/cyuGo7qQ++SoOg99HjTVY1
PS3ea522bRO2bJpYwZJvvbg020DAfm686VXwAadODdBkI2h6U5SwTxp4SkSmq9SI
mjtERFtnAKD0R2YrX4RzuIckezvwsqLDkQjMnI9XQmv5HWUZimcC
-----END CERTIFICATE-----
Binary file not shown.
-28
View File
@@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHQQmsrbfcbK1M
dNhXpKviK7EdnAtaS/TQDTd02wb/ESrdSHnzIfE4wNbj2jmGb896Nppfaihpifrs
R5My6Iym4PfG3JsQa5Fnpi0MJkb9YWSDvA+MYmEXdDtCmYs678FsJTQA8111sO4s
/jDz1pF49p0+TKTk4t0vOdUsDnP3PUmAmswj/KzBiLShyzu4goyt7BcAQyPXmk3d
jRI6hB2nSMph0Ys3kzmmL9+BaJEIkYEf85OH5U+vm+g0B8Z5WyIr1etTj+GwZRbV
14wuIhnRyyGoYVTJcOosRqkevddKbCKdEk9CjPJcvjftaz4aDZDUi6pMxlLnSqO5
lbfgqeBDAgMBAAECggEABtHIBfvwFgA2Mi6xlNZS96utJSlJDi8ZUuGQ61Pvul0Z
DXfEjLi1q86VzDiUzXAYNsOVpvxYI7yQNPQCKrTg03lRoaG9QOOdl2GNmyPYPCXQ
Ld4K3jAjyIy21oGwzTSVdyES1ZF+ul9y12FfxYirc+tk2FQBNMA697nP/PEFsQl9
cMxBB5CIGH7jSI6UIbp99Kd90ScbnE2mLACM3d0s0sRq783P9yJGpM9a71XE/K2p
CxoRxwqmNRGvI5LrGs1zIF2BSZZgNT71cdfMnAIJBeaoNY7QTKDQlg9xQojE+0if
is16mMhrHQbIFBSxHDRR4uVdiY4iKDB6Lg2pMGcjUQKBgQDzWI2O8bh+YvaEM9QN
uUC1LI6oGzj7+wxkIhjXhCX680EFeJk6AQqNfu5VoBN/nrCXxqjNGKhjqDmtzxjD
y9LYTCJ8rM9eCkrgcdCFkTQNcdNT/zqkHeOIxsoXgsFLhYozWcbiW+8oe9MTrXX/
m9u9kTHkSjKziof7wxGXu3pAmQKBgQDRnYd+urSG0bulBccqT06pJpQMjYIi6CqQ
LYEkLlELxOT+EPeEH1ZdgYkDzzgKoO5L/Jp0Ic6kKEQv+o4l+g1gJp6V5wwX81nv
FJApcg51Yma6WQb6PEJ8HiZ531JQpGZZPmJvRIvEdqw+Dz/dferTApvOlD9s4PfM
xG4R/EoFOwKBgQCEQdW2IhQWxOycj5qp1syfa1chcKI4+YoThiCgSZdm2/yz34bP
6q70lk8sxHK0gugRpYwq5ELo3w5yM8OO7uFqY36+6iFOSCPH9rPRVEjJIdsspOQX
PJNkzD4cJxmtVSf2ns2kSzkhdKMU58rhILF+R0Kpg9YolJsxrySJpgBcyQKBgQCC
KCTYRiqOhHDVuU7AMNqRIclQOhYSgsLbH8ZOpwvgGPRv5i0rNyIzkZl4ahVMVD1j
pYhqkAt11yLv/86AOlJP3+sc/Yh+3rZ7Q/N4KMBdlypej6VLgFtwInCVwFumg06i
H6CToqZ+6YluR53KdMN5HueMUHVJsC9uUJJgTJ3RvQKBgFPi8mgG4zcdoKBhqyq2
x3VQEe0VYnzBsIz42E/NFpuB4ZwC7j0Uez+QFUj76UKMsoE6fX9/lGNdg/zitRBc
M21R9HeWuQHSM6nJ/ScK7C0vqQVsGOr/DKGEydvSjkPsyIbCw8qEdOq8idAULEKj
GlIpzzm+MYzra4yB4VpRw5ES
-----END PRIVATE KEY-----
Binary file not shown.
-30
View File
@@ -1,30 +0,0 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIY7PpABd5xsYCAggA
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECC8FH8kZE5H/BIIEyK9LnEmc3VYK
kqwBBX15exPIRrsmeGkoSSrnHUeLzV0E2CN9bEL1XwJtX6d4YGYHnH7MopV9LPgl
Fdu2CvWXt5XLOMb3FJ38zZGtNnbYWZLbVlgQANZaTRCZaoWHS57KulgbtbJnn3PQ
DdYHaCiRh95pgPrdklEs0PhvBe98kR4xGJPoiGn+gJ75Ik4kwW/vJTcQeKbcU4oQ
MGIVXV66NU+Pc1d3CTYm9hwIys70+J9QtT1aSoENeYr1e+sHgzN7ykDalfAir/dZ
/E91Zg4RFV4clvvVmoAyXmZFpMxj5pLYGvdjBxTURh+8mdulfJMpKHjJldx7N9+I
cusGwKVXQcIXI76lxvKo08oENq0C6112+++s6bYtwzuk/Auk+dQ2mn2/gLgs6fsy
pi1ZKUoO8pdm8N4QzqPsFc2/ny5oSy6A6EKDC/tKoP59r6qJtoYselfypFsWemIo
F/W0HmZzC5OJMEqUxbKIuH7Xhx0ufs4TytzYMEnUVH0ChLan67VvFIcq4sLoMaW0
d2jyDdIe4WcmVckJtjudbIhcRsXtoSVB8PYjdHOmI9YZVksPreeKk7stf06V3PBU
/hsBpzlWu8xO6+cMGrlvoqOov3WAmD1/LW/ITggjLb28r7LnUrYTbj95xZ8Zd8s9
hx60MZpTJKni/Kfd5yVZw7xZWLHxNWdBbZxlCkvvFN5Ik0FjULLblfIfYa38zwp1
P6Dbw0wBSNhpsdsGcnkB+YWlzyIJzC99EZqgC3cGmb+9UGuj2bmvzx0hlIY4APCf
lfiFNXUHxxRZCV/Cp3TXqh3h7t99KvVoIzEIV8iUDMLG7dsnf2Y1z7AQ3cfL8tmC
qTlKH8QdMn87ntjcU1fynE3X/bL4+Fy8ZWeCWHHPLU2TP6Z7xBkXVB77gm0rK2cU
lJVZKB3kVemSvu9OennBAiE7yjusqCLyTJo9GlI3H7xM+jHf0CZM149n2yV7w98Z
Nag2b4iYnbVa1CRcL+4Y5zfA6AwCXvkqKcqyUqK4ZEvd1VnN9L+pTWrxaAxukC5f
KyKXKd+HdiS2b8fFVYKmpq+lK02zxuIJpLh7JlcztNinm67irwg+7VZczpX46Za1
waPuAnJ6zA6pVdRKxpXx5AnAh9vlCtlyakREx6NajG7f2nCe6IrznyVQ45jlkmwp
od0kAjsd/xp0NyvWI5A9ICU+pJ5xqhUGkXPvIxj1IqTFa7k4lYKiKgqeKoyLnzYA
+R1iQikwewxEahamhjiBH2xPYmZ77EjIF3EtLbpI02fxHR8LjyIBJ/HNnarKqJp0
HYhLJQ8z7uyAESfXY997UnTtgLQHEX5/6DKYqlNWdzRiIEGfleujHmaAb9kf9Xrr
r2EVc0E4q2/wvgMHn8GRSv6K7pQC//vNmBuNGCAMBl8t6y1QxDrX+UBn97HGk96Z
LqRoVM2mz1cS/tiP4+MSB0zqzGbHsk9xoEY0QeRPvjJfGc1skRWwdo8LA8Hf1pi1
/exyJzHNdxVdxM4CKMnXbTNCxKlhhZhUaWzELNjI5bQ5oQfechEypsFYAQETU5NS
182MgLMhkxqqcxLHcHIGE1ApZKXhY5siO0k4TTb2Kqxgn2fBUyLQLMVaVrHhZwxg
XwiQ2Rt3JBHrzPy9wXL8hw==
-----END ENCRYPTED PRIVATE KEY-----
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
passme
-45
View File
@@ -1,45 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDvTCCAqWgAwIBAgIUazbrVgbYb+IN803UmJJa0DPHQsAwDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD0ludGVybWVkaWF0
ZSBDQTAeFw0xODAxMDEwMDAwMDBaFw0zNDEyMzEwMDAwMDBaMG0xCzAJBgNVBAYT
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNVBAsMA0NTUDEQMA4GA1UE
AwwHUmV2b2tlZDEnMCUGCSqGSIb3DQEJARYYb3NzbHNpZ25jb2RlQGV4YW1wbGUu
Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx0EJrK233GytTHTY
V6Sr4iuxHZwLWkv00A03dNsG/xEq3Uh58yHxOMDW49o5hm/PejaaX2ooaYn67EeT
MuiMpuD3xtybEGuRZ6YtDCZG/WFkg7wPjGJhF3Q7QpmLOu/BbCU0APNddbDuLP4w
89aRePadPkyk5OLdLznVLA5z9z1JgJrMI/yswYi0ocs7uIKMrewXAEMj15pN3Y0S
OoQdp0jKYdGLN5M5pi/fgWiRCJGBH/OTh+VPr5voNAfGeVsiK9XrU4/hsGUW1deM
LiIZ0cshqGFUyXDqLEapHr3XSmwinRJPQozyXL437Ws+Gg2Q1IuqTMZS50qjuZW3
4KngQwIDAQABo2IwYDAJBgNVHRMEAjAAMB0GA1UdDgQWBBTprhNre3RQJMbThsJY
wKi0w8vJZTAfBgNVHSMEGDAWgBRkEPGrOTfcwf27Hcg/QVh3YifvKTATBgNVHSUE
DDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQsFAAOCAQEAFJjwxpYA2jzrmF1mdKx/
up8gl6iISsHDc7oLAv63oUYXpFwzpNfvi1TGqYVhntAH2t/1XdA1HKdBp2LDsEnt
Av66c6HxyNPka26ZGD70+w5q8uHrIOO6MZw0eaLwu9bJI4cLbRXlKwxkGSzXHGYs
1hGR2YwAiMrqtVMPetlpd62y6qUZc0lEOhjJ6DsIfqSgO8AsdyI7Ao+cDqEZ1I/Q
Oi1Agn8kz8TtfWKxkX06EoL4DrZCDb1/w0CGQJATq77pKst+zw+B+2EKqlpuG3s/
FE7RkCjG7bEFIDEK2909BXQNyQJzp7ih9X8QeEx5fnPr9lDfe/75YjRqoHkfmcTC
Hw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEA5yrw3i+fvxBSODvCoQb+9ibWRozmphJBp57tKv9ZraQ5
THK+PkCdjNiJuxZn8F1QLsjJo6JqrrXufYln7wixK0Seu4uV6I2TRzcRyJx29D89
0G9GrTXKn7v8z32QAqCgtwSZ17uWYTFmRAYPllWXcWDONsVyw3UF2nClndL7GMqM
gDizlwsfg8HmRpZegn82I7Y2DXccm9a7pFHuBHpwenKqfBnMsXo3Jj4Xlr1cLTrh
+6ksS5YogOsOd9b5Dfz6FaGmmwrlUWHwdi+EzdnSpOnXzmgflF23sZQ0ynsVvmpl
iD4rXBWnxnQ6Ken3wVPNrA/0ZYGbgSKrcv+/olkh5QIDAQABo2YwZDASBgNVHRMB
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRkEPGrOTfcwf27Hcg/QVh3YifvKTAfBgNV
HSMEGDAWgBQaPEb++qXSgmAi2vsewtpb6SiIyDAOBgNVHQ8BAf8EBAMCAYYwDQYJ
KoZIhvcNAQELBQADggEBAL22kK3SDGnr3lhRE7ipptlKalrQKfpght0XEKm5hxCL
tougN2wtaTEWMwr2YfGJohcKBaGKQ+Bv6WY+EV+hJE4qEUFh6BGqRMtuZdiAbkG+
EveEMhZWQzgf9rUID+Y9Eg+NfCxlpkdQPjUxUV9OkGIshlxkUP8Y+C0h0xIcwq5v
hAfNiJAdcw4fUvtLkpEOFoOjThB8zxOu+Cl3xLCcNOMPLdSxd3YXjy6CMuuOk4RB
gOc8YCyyEvwb9KmARZpMOcQJmucMhs+aC3DF+n71g+agFhDl3Z0QkyyyRjAcD04+
sAR9C8PbqSCQAdydHbAFViEX6x3oGJ7L6zEDcIS10wg=
-----END CERTIFICATE-----
-46
View File
@@ -1,46 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEDDCCAvSgAwIBAgIUHGb2CHtm9Ra3gCn6Iv7hpEhiQrYwDQYJKoZIhvcNAQEL
BQAwZzELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNVBAMMFkludGVybWVkaWF0
ZSBDQSBDUkwgRFAwHhcNMTgwMTAxMDAwMDAwWhcNMzQxMjMxMDAwMDAwWjB7MQsw
CQYDVQQGEwJQTDEVMBMGA1UECgwMb3NzbHNpZ25jb2RlMQwwCgYDVQQLDANDU1Ax
HjAcBgNVBAMMFVJldm9rZWQgWDUwOXYzIENSTCBEUDEnMCUGCSqGSIb3DQEJARYY
b3NzbHNpZ25jb2RlQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAx0EJrK233GytTHTYV6Sr4iuxHZwLWkv00A03dNsG/xEq3Uh58yHx
OMDW49o5hm/PejaaX2ooaYn67EeTMuiMpuD3xtybEGuRZ6YtDCZG/WFkg7wPjGJh
F3Q7QpmLOu/BbCU0APNddbDuLP4w89aRePadPkyk5OLdLznVLA5z9z1JgJrMI/ys
wYi0ocs7uIKMrewXAEMj15pN3Y0SOoQdp0jKYdGLN5M5pi/fgWiRCJGBH/OTh+VP
r5voNAfGeVsiK9XrU4/hsGUW1deMLiIZ0cshqGFUyXDqLEapHr3XSmwinRJPQozy
XL437Ws+Gg2Q1IuqTMZS50qjuZW34KngQwIDAQABo4GbMIGYMAkGA1UdEwQCMAAw
HQYDVR0OBBYEFOmuE2t7dFAkxtOGwljAqLTDy8llMB8GA1UdIwQYMBaAFBQ8Yqni
cYiW5meHqyh9KQSIau0jMBMGA1UdJQQMMAoGCCsGAQUFBwMDMDYGA1UdHwQvMC0w
K6ApoCeGJWh0dHA6Ly8xMjcuMC4wLjE6MTkyNTQvaW50ZXJtZWRpYXRlQ0EwDQYJ
KoZIhvcNAQELBQADggEBAJ5WxnDiAiRPr7EvTRD7iaxixAY/2wgASXWekQLpvJ8Y
/ehaVdZWE8ft76y73F4NC62JfjWgAZHE+we3LSO+eB5kznM+Ctzrf/brR1MorSOu
iq78uz2pjwmQBpby6uDMii9r1txR62GYiLrZJizE+13AOVKBo5EW0PuwX3wKjk+s
Z5Mp9y7+GVzCSXwJC4wNMw/ZJZgr+o5D8msMh3UPgxUfT1rZ7THW3IwXao3ZtTXw
EA6uJoLVNb8FLfAVA1CFL0MlPgyiM2iNs+jIuhF7hPmMc8Je2qAr97ADdLCHWnRv
Majsbns7OCCFROF2qSQiyzVO5Hn1kiPSP7qmLMak610=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDszCCApugAwIBAgIUN3RBnJCUJ8HmbeNjJZ/6jsXJLGEwDQYJKoZIhvcNAQEL
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBnMQswCQYDVQQGEwJQTDEVMBMG
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
cml0eTEfMB0GA1UEAwwWSW50ZXJtZWRpYXRlIENBIENSTCBEUDCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAME32IBpxW4FhVuZe1PTarEskVHP233QjZtx
poC67/lUK44gtFmsxYsMrDYmmny5pfoM/Byxl5/rorEddLqtDe1kd1SpXUvEYxox
s5rizRd5sZPgkwNoJkSVyNZFwj7gKZHeg6IQHSxNgmTybZ+eZqiNvEveksj3lGpM
Xrbiew7cXUyIP636GPtYxLyIbwDVP0jScqcA/dmSAqofFVUi0SW3OS1hpyXAmmx8
hQHJRKPjPgitZVgjwf5X8/eMTa+ca9dRlRFLk7AcbkF6NcbLm+cRo816nO0EBFV4
Sn2dW9uYqJIfZcpRQ7wbv4fUCghwrk9h3gXrb7AweyK8nyYlmosCAwEAAaNmMGQw
EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUFDxiqeJxiJbmZ4erKH0pBIhq
7SMwHwYDVR0jBBgwFoAUGjxG/vql0oJgItr7HsLaW+koiMgwDgYDVR0PAQH/BAQD
AgGGMA0GCSqGSIb3DQEBCwUAA4IBAQAlI/1XnGc9WzL53rRascZc1EgWAnej9YFS
Dax5+nozYTihC8BRxGfSh1FGRVsmFWhZ0z0XogJJC2bZrQ/36+vwoILItcsWHrQr
rFoZa6s1Uo7ZCd9SfmXjbhMLQgydocCh9YIF66CAkQLwRXc1QIpF7nuZ+rxk0ru1
uGjjBrFRfdSdzlFnyK6wfFzi6LtYDVgVEHC7zzL9E/cyuGo7qQ++SoOg99HjTVY1
PS3ea522bRO2bJpYwZJvvbg020DAfm686VXwAadODdBkI2h6U5SwTxp4SkSmq9SI
mjtERFtnAKD0R2YrX4RzuIckezvwsqLDkQjMnI9XQmv5HWUZimcC
-----END CERTIFICATE-----
-47
View File
@@ -1,47 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEMzCCAxugAwIBAgIUAQ9lOMiuXUZuKaxzEpwQmCzU7aowDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0zODAxMDEwMDAwMDBaMFUxCzAJBgNVBAYT
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxHDAaBgNVBAsME1RpbWVzdGFtcCBB
dXRob3JpdHkxETAPBgNVBAMMCFRlc3QgVFNBMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAqZW3jbxq2Zkw86ePE8r6Tl9+mxjzH8k1XPGXwKIdEhvOhBXN
SxwVdiudnbIR2Kp4kOpRNeI4bET6bGEQVBVzuyPOCXeQlXK7wVhri/MF8YzMCFuW
7s2OMeaCqMJckBiGrDYgvDIMfE53CZFVhOnpIKD+ItX+D1bBchvM1TaSOVcxwKwH
pmIbw47gOY4E4rHz/KYdqcVCk82ACEmiptmJARb8oYU8bap1x7fEtDZ3w0gnnSks
5dXGjdUwCkm1qHgoW/k6vK8nIz14f/+05GIMZpUh4kIUXMhGmbOeFHfENJ7J30TI
RLXsK9iAApriqxZ6EvhrWOYJT4pUeUnGfuwPUwIDAQABo4HvMIHsMAwGA1UdEwEB
/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwHQYDVR0OBBYEFKryJiH4Y0KO
x2nCc4cOvih1VzjmMB8GA1UdIwQYMBaAFD8ujz0I9Y7079ZMe9X7cO3/rSj5MC0G
A1UdHwQmMCQwIqAgoB6GHGh0dHA6Ly8xMjcuMC4wLjE6MTkyNTQvVFNBQ0EwVQYD
VR0eBE4wTKAYMAqCCHRlc3QuY29tMAqCCHRlc3Qub3JnoTAwCocIAAAAAAAAAAAw
IocgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwDQYJKoZIhvcNAQEL
BQADggEBAAhzijhC1kvBV75rxRqj27gtYRG8dNkHc5umzwXyNNMn2tI/kO2Rf+ES
9RamQE9sfvOgg3UqfXIfRPsC4cBHnjT+ELdqbt4byk3LPtstJGFuLy0iNRNY9f1j
lBJrldLZNNsIpNMQa0u5h/z4m0CAA8j6ayUvcoR11y2zYHkHlSScTq/s7gSQzXlK
z4DRiiYif2OEdKVeRCqlDV8AOlhm1+9am74dkfO71aT0G2hko2u19NWZvjc/DqI1
V+e2g5TDE7V65d9vvf9tA26i0At/VazvnhsgdpgUkwS6mjUvx+gW3i5YJhtXjdAX
hpE0ajpKT0x/dNa/qCwl/9zc8XxGnPk=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDkDCCAnigAwIBAgIULFuB5HWsyba6VHu2Ygv2vt4R4/swDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
dCBDQTAeFw0xNzAxMDEwMDAwMDBaFw0zNjEyMjcwMDAwMDBaMGAxCzAJBgNVBAYT
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxJDAiBgNVBAsMG1RpbWVzdGFtcCBB
dXRob3JpdHkgUm9vdCBDQTEUMBIGA1UEAwwLVFNBIFJvb3QgQ0EwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBo8JJDwVm6UTZvA2g/tOZ3xIbKYXI92Rn
T/FCCUycsB5tmoSWcmy1AB6UDv7bFMGy4mdbxnErtdytGj+hEIO3O2EBbpBLAmlJ
CEVNRrz/YbxGoJmeAii9s3jignUpTr/qLMSKkLowuqABZl2XtCp7Q83YlZPkVhFL
kCAny89cG/QGAUxViN7HB4jWzhcBTTfD4PFvSU1HZNhPM0Y6BCpv2qrof3/tPnQr
xM2zVZoIonQpf6paga61O9fM4wc1GqxGGwARz6Bxq6w2OxRDsV/biqP9gVUj0XmF
6o/draf3MkDswOUZyKpujOUIf12ezXJFPWaCRN1Rl0vwV2CyVxkvAgMBAAGjQjBA
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFD8ujz0I9Y7079ZMe9X7cO3/rSj5
MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAtHmPfVgu6Y7uWcpq
AdawOTZ/2ICOvAMmQ0LcXKmSpgsneHiyAL1Wwe2/XxTwmrpHylOapIIuV3irHCXU
CxaTMUyZGfXoUWsxnR8bcb5ac/aFKkC3ynE2/IfFyJOQ724cK5FRK1+piVleP4Rx
C04KQiuxuVLedyvGh5OPU/94ZW2JuuBjImVAO/lUbYhAUSpwueX2lYKSSPLkPfDx
AsIp55x70iQ+EsgARvseVY2JRzvRnuh66V4P15wn3dIzjtWQ1/t007wMk5Lji5dQ
iSvdyqULBytBqDtLPLzRuma1KJEPRIamF1j6Or6HaHSVUorRhqI3XuxEUGdO4LxZ
QepMyA==
-----END CERTIFICATE-----
-1
View File
@@ -1 +0,0 @@
bb7fd13ddf056e0a3e621d3537b25478
+40
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:
"""
+7 -6
View File
@@ -1,21 +1,22 @@
"""Implementation of a HTTP client"""
#!/usr/bin/python3
"""Implementation of an HTTP client"""
import os
import sys
import http.client
RESULT_PATH = os.getcwd()
LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/")
PORT_LOG = os.path.join(LOGS_PATH, "./port.log")
def main() -> None:
"""Creating a POST Request"""
ret = 0
try:
with open(PORT_LOG, 'r') as file:
port = file.readline()
conn = http.client.HTTPConnection('127.0.0.1', port)
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=', ')
-448
View File
@@ -1,448 +0,0 @@
#!/bin/bash
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
################################################################################
if test -n "$1"
then
OPENSSL="$1/bin/openssl"
export LD_LIBRARY_PATH="$1/lib:$1/lib64"
else
OPENSSL=openssl
fi
mkdir "CA/" 2>> "makecerts.log" 1>&2
touch "CA/index.txt"
echo -n "unique_subject = no" > "CA/index.txt.attr"
$OPENSSL rand -hex 16 > "CA/serial"
$OPENSSL rand -hex 16 > "tmp/tsa-serial"
echo 1001 > "CA/crlnumber"
date > "makecerts.log"
"$OPENSSL" version 2>> "makecerts.log" 1>&2
echo -n "$password" > tmp/password.txt
################################################################################
# Root CA certificates
################################################################################
printf "\nGenerate trusted root CA certificate\n" >> "makecerts.log"
"$OPENSSL" genrsa -out CA/CAroot.key \
2>> "makecerts.log" 1>&2
test_result $?
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_root.cnf"
"$OPENSSL" req -config "$CONF" -new -x509 -days 7300 -key CA/CAroot.key -out tmp/CAroot.pem \
-subj "/C=PL/O=osslsigncode/OU=Certification Authority/CN=Trusted Root CA" \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
printf "\nPrepare the Certificate Signing Request (CSR)\n" >> "makecerts.log"
"$OPENSSL" genrsa -out CA/CA.key \
2>> "makecerts.log" 1>&2
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_root.cnf"
"$OPENSSL" req -config "$CONF" -new -key CA/CA.key -out CA/CACert.csr \
-subj "/C=PL/O=osslsigncode/OU=Certification Authority/CN=Root CA" \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
printf "\nGenerate Self-signed root CA certificate\n" >> "makecerts.log"
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_root.cnf"
"$OPENSSL" x509 -req -days 7300 -extfile "$CONF" -extensions ca_extensions \
-signkey CA/CA.key \
-in CA/CACert.csr -out tmp/CACert.pem \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
printf "\nGenerate Cross-signed root CA certificate\n" >> "makecerts.log"
TZ=GMT faketime -f '@2018-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_root.cnf"
"$OPENSSL" x509 -req -days 7300 -extfile "$CONF" -extensions ca_extensions \
-CA tmp/CAroot.pem -CAkey CA/CAroot.key -CAserial CA/CAroot.srl \
-CAcreateserial -in CA/CACert.csr -out tmp/CAcross.pem \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
################################################################################
# Private RSA keys
################################################################################
printf "\nGenerate private RSA encrypted key\n" >> "makecerts.log"
"$OPENSSL" genrsa -des3 -out CA/private.key -passout pass:"$password" \
2>> "makecerts.log" 1>&2
test_result $?
cat CA/private.key >> tmp/keyp.pem 2>> "makecerts.log"
test_result $?
printf "\nGenerate private RSA decrypted key\n" >> "makecerts.log"
"$OPENSSL" rsa -in CA/private.key -passin pass:"$password" -out tmp/key.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 $?
################################################################################
# Intermediate CA certificates
################################################################################
CONF="${script_path}/openssl_intermediate.cnf"
printf "\nGenerate intermediate CA certificate\n" >> "makecerts.log"
"$OPENSSL" genrsa -out CA/intermediateCA.key \
2>> "makecerts.log" 1>&2
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_intermediate.cnf"
"$OPENSSL" req -config "$CONF" -new -key CA/intermediateCA.key -out CA/intermediateCA.csr \
-subj "/C=PL/O=osslsigncode/OU=Certification Authority/CN=Intermediate CA" \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_root.cnf"
"$OPENSSL" ca -config "$CONF" -batch -in CA/intermediateCA.csr -out CA/intermediateCA.cer \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
"$OPENSSL" x509 -in CA/intermediateCA.cer -out tmp/intermediateCA.pem \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nGenerate a certificate to revoke\n" >> "makecerts.log"
"$OPENSSL" req -config "$CONF" -new -key CA/private.key -passin pass:"$password" -out CA/revoked.csr \
-subj "/C=PL/O=osslsigncode/OU=CSP/CN=Revoked/emailAddress=osslsigncode@example.com" \
2>> "makecerts.log" 1>&2
test_result $?
"$OPENSSL" ca -config "$CONF" -batch -in CA/revoked.csr -out CA/revoked.cer \
2>> "makecerts.log" 1>&2
test_result $?
"$OPENSSL" x509 -in CA/revoked.cer -out tmp/revoked.pem \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nRevoke above certificate\n" >> "makecerts.log"
"$OPENSSL" ca -config "$CONF" -revoke CA/revoked.cer \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nAttach intermediate certificate to revoked certificate\n" >> "makecerts.log"
cat tmp/intermediateCA.pem >> tmp/revoked.pem 2>> "makecerts.log"
test_result $?
printf "\nGenerate CRL file\n" >> "makecerts.log"
TZ=GMT faketime -f '@2019-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_intermediate.cnf"
"$OPENSSL" ca -config "$CONF" -gencrl -crldays 8766 -out tmp/CACertCRL.pem \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
printf "\nGenerate code signing certificate\n" >> "makecerts.log"
"$OPENSSL" req -config "$CONF" -new -key CA/private.key -passin pass:"$password" -out CA/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 CA/cert.csr -out CA/cert.cer \
2>> "makecerts.log" 1>&2
test_result $?
"$OPENSSL" x509 -in CA/cert.cer -out tmp/cert.pem \
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/intermediateCA.pem >> tmp/cert.pem 2>> "makecerts.log"
test_result $?
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 $?
ssl_version=$("$OPENSSL" version)
if test "${ssl_version:8:1}" -eq 3
then
printf "\nConvert the certificate and the key into legacy PKCS#12 container with\
RC2-40-CBC private key and certificate encryption algorithm\n" >> "makecerts.log"
"$OPENSSL" pkcs12 -export -in tmp/cert.pem -inkey tmp/key.pem -out tmp/legacy.p12 -passout pass:"$password" \
-keypbe rc2-40-cbc -certpbe rc2-40-cbc -legacy \
2>> "makecerts.log" 1>&2
else
printf "\nConvert the certificate and the key into legacy PKCS#12 container with\
RC2-40-CBC private key and certificate encryption algorithm\n" >> "makecerts.log"
"$OPENSSL" pkcs12 -export -in tmp/cert.pem -inkey tmp/key.pem -out tmp/legacy.p12 -passout pass:"$password" \
-keypbe rc2-40-cbc -certpbe rc2-40-cbc \
2>> "makecerts.log" 1>&2
fi
test_result $?
printf "\nConvert the certificate and the key into a PKCS#12 container with\
AES-256-CBC private key and certificate encryption algorithm\n" >> "makecerts.log"
"$OPENSSL" pkcs12 -export -in tmp/cert.pem -inkey tmp/key.pem -out tmp/cert.p12 -passout pass:"$password" \
-keypbe aes-256-cbc -certpbe aes-256-cbc \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nGenerate expired certificate\n" >> "makecerts.log"
"$OPENSSL" req -config "$CONF" -new -key CA/private.key -passin pass:"$password" -out CA/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 CA/expired.csr -out CA/expired.cer \
2>> "makecerts.log" 1>&2
test_result $?
"$OPENSSL" x509 -in CA/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/intermediateCA.pem >> tmp/expired.pem 2>> "makecerts.log"
test_result $?
################################################################################
# Intermediate CA certificates with CRL distribution point
################################################################################
CONF="${script_path}/openssl_intermediate_crldp.cnf"
printf "\nGenerate intermediate CA certificate with CRL distribution point\n" >> "makecerts.log"
"$OPENSSL" genrsa -out CA/intermediateCA_crldp.key \
2>> "makecerts.log" 1>&2
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_intermediate_crldp.cnf"
"$OPENSSL" req -config "$CONF" -new -key CA/intermediateCA_crldp.key -out CA/intermediateCA_crldp.csr \
-subj "/C=PL/O=osslsigncode/OU=Certification Authority/CN=Intermediate CA CRL DP" \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_root.cnf"
"$OPENSSL" ca -config "$CONF" -batch -in CA/intermediateCA_crldp.csr -out CA/intermediateCA_crldp.cer \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
"$OPENSSL" x509 -in CA/intermediateCA_crldp.cer -out tmp/intermediateCA_crldp.pem \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nGenerate a certificate with X509v3 CRL Distribution Points extension to revoke\n" >> "makecerts.log"
"$OPENSSL" req -config "$CONF" -new -key CA/private.key -passin pass:"$password" -out CA/revoked_crldp.csr \
-subj "/C=PL/O=osslsigncode/OU=CSP/CN=Revoked X509v3 CRL DP/emailAddress=osslsigncode@example.com" \
2>> "makecerts.log" 1>&2
test_result $?
"$OPENSSL" ca -config "$CONF" -batch -in CA/revoked_crldp.csr -out CA/revoked_crldp.cer \
2>> "makecerts.log" 1>&2
test_result $?
"$OPENSSL" x509 -in CA/revoked_crldp.cer -out tmp/revoked_crldp.pem \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nRevoke above certificate\n" >> "makecerts.log"
"$OPENSSL" ca -config "$CONF" -revoke CA/revoked_crldp.cer \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nAttach intermediate certificate to revoked certificate\n" >> "makecerts.log"
cat tmp/intermediateCA_crldp.pem >> tmp/revoked_crldp.pem 2>> "makecerts.log"
test_result $?
printf "\nGenerate CRL file\n" >> "makecerts.log"
TZ=GMT faketime -f '@2019-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_intermediate_crldp.cnf"
"$OPENSSL" ca -config "$CONF" -gencrl -crldays 8766 -out tmp/CACertCRL_crldp.pem \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
printf "\nConvert CRL file from PEM to DER (for CRL Distribution Points server to use) \n" >> "makecerts.log"
"$OPENSSL" crl -in tmp/CACertCRL_crldp.pem -inform PEM -out tmp/CACertCRL.der -outform DER \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nGenerate code signing certificate with X509v3 CRL Distribution Points extension\n" >> "makecerts.log"
"$OPENSSL" req -config "$CONF" -new -key CA/private.key -passin pass:"$password" -out CA/cert_crldp.csr \
-subj "/C=PL/ST=Mazovia Province/L=Warsaw/O=osslsigncode/OU=CSP/CN=Certificate X509v3 CRL DP/emailAddress=osslsigncode@example.com" \
2>> "makecerts.log" 1>&2
test_result $?
"$OPENSSL" ca -config "$CONF" -batch -in CA/cert_crldp.csr -out CA/cert_crldp.cer \
2>> "makecerts.log" 1>&2
test_result $?
"$OPENSSL" x509 -in CA/cert_crldp.cer -out tmp/cert_crldp.pem \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nAttach intermediate certificate to code signing certificate\n" >> "makecerts.log"
cat tmp/intermediateCA_crldp.pem >> tmp/cert_crldp.pem 2>> "makecerts.log"
test_result $?
################################################################################
# Time Stamp Authority certificates
################################################################################
printf "\nGenerate Root CA TSA certificate\n" >> "makecerts.log"
"$OPENSSL" genrsa -out CA/TSACA.key \
2>> "makecerts.log" 1>&2
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_tsa_root.cnf"
"$OPENSSL" req -config "$CONF" -new -x509 -days 7300 -key CA/TSACA.key -out tmp/TSACA.pem \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
printf "\nGenerate TSA certificate to revoke\n" >> "makecerts.log"
CONF="${script_path}/openssl_tsa_root.cnf"
"$OPENSSL" req -config "$CONF" -new -nodes -keyout tmp/TSA_revoked.key -out CA/TSA_revoked.csr \
-subj "/C=PL/O=osslsigncode/OU=TSA/CN=Revoked/emailAddress=osslsigncode@example.com" \
2>> "makecerts.log" 1>&2
test_result $?
CONF="${script_path}/openssl_tsa_root.cnf"
"$OPENSSL" ca -config "$CONF" -batch -in CA/TSA_revoked.csr -out CA/TSA_revoked.cer \
2>> "makecerts.log" 1>&2
test_result $?
"$OPENSSL" x509 -in CA/TSA_revoked.cer -out tmp/TSA_revoked.pem \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nRevoke above certificate\n" >> "makecerts.log"
"$OPENSSL" ca -config "$CONF" -revoke CA/TSA_revoked.cer \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nGenerate TSA CRL file\n" >> "makecerts.log"
TZ=GMT faketime -f '@2019-01-01 00:00:00' /bin/bash -c '
script_path=$(pwd)
OPENSSL="$0"
export LD_LIBRARY_PATH="$1"
CONF="${script_path}/openssl_tsa_root.cnf"
"$OPENSSL" ca -config "$CONF" -gencrl -crldays 8766 -out tmp/TSACertCRL.pem \
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
test_result $?
printf "\nConvert TSA CRL file from PEM to DER (for CRL Distribution Points server to use)\n" >> "makecerts.log"
"$OPENSSL" crl -in tmp/TSACertCRL.pem -inform PEM -out tmp/TSACertCRL.der -outform DER \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nGenerate TSA certificate\n" >> "makecerts.log"
CONF="${script_path}/openssl_tsa.cnf"
"$OPENSSL" req -config "$CONF" -new -nodes -keyout tmp/TSA.key -out CA/TSA.csr \
2>> "makecerts.log" 1>&2
test_result $?
CONF="${script_path}/openssl_tsa_root.cnf"
"$OPENSSL" ca -config "$CONF" -batch -in CA/TSA.csr -out CA/TSA.cer \
2>> "makecerts.log" 1>&2
test_result $?
"$OPENSSL" x509 -in CA/TSA.cer -out tmp/TSA.pem \
2>> "makecerts.log" 1>&2
test_result $?
printf "\nSave the chain to be included in the TSA response\n" >> "makecerts.log"
cat tmp/TSA.pem tmp/TSACA.pem > tmp/tsa-chain.pem 2>> "makecerts.log"
################################################################################
# Copy new files
################################################################################
if test -s tmp/CACert.pem -a -s tmp/CAcross.pem -a -s tmp/CAroot.pem \
-a -s tmp/intermediateCA.pem -a -s tmp/intermediateCA_crldp.pem \
-a -s tmp/CACertCRL.pem -a -s tmp/CACertCRL.der \
-a -s tmp/TSACertCRL.pem -a -s tmp/TSACertCRL.der \
-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.der -a -s tmp/cert.spc \
-a -s tmp/cert.p12 -a -s tmp/legacy.p12 -a -s tmp/cert_crldp.pem\
-a -s tmp/expired.pem \
-a -s tmp/revoked.pem -a -s tmp/revoked_crldp.pem \
-a -s tmp/TSA_revoked.pem \
-a -s tmp/TSA.pem -a -s tmp/TSA.key -a -s tmp/tsa-chain.pem
then
mkdir -p "../certs"
cp tmp/* ../certs
printf "%s" "Keys & certificates successfully generated"
else
printf "%s" "Error logs ${result_path}/makecerts.log"
result=1
fi
################################################################################
# Remove the working directory
################################################################################
rm -rf "CA/"
rm -rf "tmp/"
exit "$result"
}
################################################################################
# Tests requirement and make certs
################################################################################
if test -n "$(command -v faketime)"
then
make_certs "$1"
result=$?
else
printf "%s" "faketime not found in \$PATH, please install faketime package"
result=1
fi
exit "$result"
-73
View File
@@ -1,73 +0,0 @@
# OpenSSL intermediate CA configuration file
[ default ]
name = intermediateCA
default_ca = CA_default
[ CA_default ]
# Directory and file locations
dir = .
certs = $dir/CA
crl_dir = $dir/CA
new_certs_dir = $dir/CA
database = $dir/CA/index.txt
serial = $dir/CA/serial
rand_serial = yes
private_key = $dir/CA/$name.key
certificate = $dir/tmp/$name.pem
crlnumber = $dir/CA/crlnumber
crl_extensions = crl_ext
default_md = sha256
preserve = no
policy = policy_loose
default_startdate = 20180101000000Z
default_enddate = 20341231000000Z
x509_extensions = v3_req
email_in_dn = yes
default_days = 2200
[ 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
[ v3_req ]
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
-79
View File
@@ -1,79 +0,0 @@
# OpenSSL intermediate CA configuration file
[ default ]
name = intermediateCA
default_ca = CA_default
crl_url = http://127.0.0.1:19254/$name
[ CA_default ]
# Directory and file locations
dir = .
certs = $dir/CA
crl_dir = $dir/CA
new_certs_dir = $dir/CA
database = $dir/CA/index.txt
serial = $dir/CA/serial
rand_serial = yes
private_key = $dir/CA/$name\_crldp.key
certificate = $dir/tmp/$name\_crldp.pem
crlnumber = $dir/CA/crlnumber
crl_extensions = crl_ext
default_md = sha256
preserve = no
policy = policy_loose
default_startdate = 20180101000000Z
default_enddate = 20341231000000Z
x509_extensions = v3_req
email_in_dn = yes
default_days = 2200
[ 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
[ v3_req ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid, issuer
extendedKeyUsage = codeSigning
crlDistributionPoints = @crl_info
[ crl_info ]
# X509v3 CRL Distribution Points extension
URI.0 = $crl_url
[ 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
-65
View File
@@ -1,65 +0,0 @@
# OpenSSL root CA configuration file
[ ca ]
default_ca = CA_default
[ CA_default ]
# Directory and file locations.
dir = .
certs = $dir/CA
crl_dir = $dir/CA
new_certs_dir = $dir/CA
database = $dir/CA/index.txt
serial = $dir/CA/serial
rand_serial = yes
private_key = $dir/CA/CA.key
certificate = $dir/tmp/CACert.pem
crl_extensions = crl_ext
default_md = sha256
preserve = no
policy = policy_match
default_startdate = 20180101000000Z
default_enddate = 20360101000000Z
x509_extensions = v3_intermediate_ca
email_in_dn = yes
default_days = 3000
unique_subject = no
[ req ]
# Options for the `req` tool
encrypt_key = no
default_bits = 2048
default_md = sha256
string_mask = utf8only
x509_extensions = ca_extensions
distinguished_name = req_distinguished_name
[ ca_extensions ]
# Extension to add when the -x509 option is used
basicConstraints = critical, CA:true
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`)
basicConstraints = critical, CA:true, pathlen:0
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ policy_match ]
countryName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name
emailAddress = Email Address
+1
View File
@@ -44,3 +44,4 @@ ordering = yes
tsa_name = yes
ess_cert_id_chain = yes
ess_cert_id_alg = sha256
crypto_device = builtin
-83
View File
@@ -1,83 +0,0 @@
# OpenSSL Root Timestamp Authority configuration file
[ default ]
name = TSACA
domain_suffix = timestampauthority
crl_url = http://127.0.0.1:19254/$name
name_opt = utf8, esc_ctrl, multiline, lname, align
default_ca = CA_default
[ CA_default ]
dir = .
certs = $dir/CA
crl_dir = $dir/CA
new_certs_dir = $dir/CA
database = $dir/CA/index.txt
serial = $dir/CA/serial
crlnumber = $dir/CA/crlnumber
crl_extensions = crl_ext
rand_serial = yes
private_key = $dir/CA/$name.key
certificate = $dir/tmp/$name.pem
default_md = sha256
default_days = 3650
default_crl_days = 365
policy = policy_match
default_startdate = 20180101000000Z
default_enddate = 20380101000000Z
unique_subject = no
email_in_dn = no
x509_extensions = tsa_extensions
[ policy_match ]
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ tsa_extensions ]
basicConstraints = critical, CA:false
extendedKeyUsage = critical, timeStamping
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
crlDistributionPoints = @crl_info
nameConstraints = @name_constraints
[ crl_info ]
# X509v3 CRL Distribution Points extension
URI.0 = $crl_url
[ crl_ext ]
# Extension for CRLs
authorityKeyIdentifier = keyid:always
[ name_constraints ]
permitted;DNS.0=test.com
permitted;DNS.1=test.org
excluded;IP.0=0.0.0.0/0.0.0.0
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0
[ 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
x509_extensions = ca_extensions
[ ca_distinguished_name ]
countryName = "PL"
organizationName = "osslsigncode"
organizationalUnitName = "Timestamp Authority Root CA"
commonName = "TSA Root CA"
[ ca_extensions ]
# Extension to add when the -x509 option is used
basicConstraints = critical, CA:true
subjectKeyIdentifier = hash
keyUsage = critical, keyCertSign, cRLSign
+47
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.
+1
View File
@@ -0,0 +1 @@
console.log("Hello, world!");
+593
View File
@@ -0,0 +1,593 @@
#!/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
)
key_usage = KeyUsage(
digital_signature=True,
content_commitment=False,
key_encipherment=False,
data_encipherment=False,
key_agreement=False,
key_cert_sign=False,
crl_sign=False,
encipher_only=False,
decipher_only=False
)
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(key_usage, 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:
"""
+32 -18
View File
@@ -1,4 +1,5 @@
"""Implementation of a HTTP server"""
#!/usr/bin/python3
"""Implementation of an HTTP server"""
import argparse
import os
@@ -8,6 +9,7 @@ import threading
from urllib.parse import urlparse
from http.server import SimpleHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn
from make_certificates import CertificateMaker
RESULT_PATH = os.getcwd()
FILES_PATH = os.path.join(RESULT_PATH, "./Testing/files/")
@@ -15,22 +17,23 @@ CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
CONF_PATH = os.path.join(RESULT_PATH, "./Testing/conf/")
LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/")
REQUEST = os.path.join(FILES_PATH, "./jreq.tsq")
RESPONS = os.path.join(FILES_PATH, "./jresp.tsr")
CACRL = os.path.join(CERTS_PATH, "./CACertCRL.der")
TSACRL = os.path.join(CERTS_PATH, "./TSACertCRL.der")
RESPONSE = os.path.join(FILES_PATH, "./jresp.tsr")
OPENSSL_CONF = os.path.join(CONF_PATH, "./openssl_tsa.cnf")
PORT_LOG = os.path.join(LOGS_PATH, "./port.log")
SERVER_LOG = os.path.join(LOGS_PATH, "./server.log")
URL_LOG = os.path.join(LOGS_PATH, "./url.log")
OPENSSL_TS = ["openssl", "ts",
"-reply", "-config", OPENSSL_CONF,
"-passin", "pass:passme",
"-queryfile", REQUEST,
"-out", RESPONS]
"-out", RESPONSE]
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
"""This variant of HTTPServer creates a new thread for every connection"""
daemon_threads = True
class RequestHandler(SimpleHTTPRequestHandler):
"""Handle the HTTP POST request that arrive at the server"""
@@ -44,15 +47,17 @@ class RequestHandler(SimpleHTTPRequestHandler):
try:
url = urlparse(self.path)
self.send_response(200)
self.send_header("Content-type", "application/crl")
self.send_header("Content-type", "application/pkix-crl")
self.end_headers()
resp_data = b''
# Read the file and send the contents
if url.path == "/intermediateCA":
with open(CACRL, 'rb') as file:
file_path = os.path.join(CERTS_PATH, "./CACertCRL.der")
with open(file_path, 'rb') as file:
resp_data = file.read()
if url.path == "/TSACA":
with open(TSACRL, 'rb') as file:
file_path = os.path.join(CERTS_PATH, "./TSACertCRL.der")
with open(file_path, 'rb') as file:
resp_data = file.read()
self.wfile.write(resp_data)
except Exception as err: # pylint: disable=broad-except
@@ -65,8 +70,8 @@ class RequestHandler(SimpleHTTPRequestHandler):
url = urlparse(self.path)
self.send_response(200)
if url.path == "/kill_server":
self.log_message(f"Deleting file: {PORT_LOG}")
os.remove(f"{PORT_LOG}")
self.log_message(f"Deleting file: {URL_LOG}")
os.remove(f"{URL_LOG}")
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(bytes('Shutting down HTTP server', 'utf-8'))
@@ -76,15 +81,15 @@ class RequestHandler(SimpleHTTPRequestHandler):
post_data = self.rfile.read(content_length)
with open(REQUEST, mode="wb") as file:
file.write(post_data)
openssl = subprocess.run(OPENSSL_TS,
check=True, universal_newlines=True)
openssl = subprocess.run(OPENSSL_TS, check=True, universal_newlines=True)
openssl.check_returncode()
self.send_header("Content-type", "application/timestamp-reply")
self.end_headers()
resp_data = b''
with open(RESPONS, mode="rb") as file:
with open(RESPONSE, mode="rb") as file:
resp_data = file.read()
self.wfile.write(resp_data)
except Exception as err: # pylint: disable=broad-except
print("HTTP POST request error: {}".format(err))
@@ -108,7 +113,8 @@ class HttpServerThread():
def main() -> None:
"""Start HTTP server"""
"""Start HTTP server, make test certificates."""
ret = 0
parser = argparse.ArgumentParser()
parser.add_argument(
@@ -121,11 +127,16 @@ def main() -> None:
try:
server = HttpServerThread()
port = server.start_server(args.port)
with open(PORT_LOG, mode="w") as file:
file.write("{}".format(port))
with open(URL_LOG, mode="w", encoding="utf-8") as file:
file.write("127.0.0.1:{}".format(port))
tests = CertificateMaker(port, SERVER_LOG)
tests.make_certs()
except OSError as err:
print("OSError: {}".format(err))
ret = err.errno
except Exception as err: # pylint: disable=broad-except
print("Error: {}".format(err))
ret = 1
finally:
sys.exit(ret)
@@ -135,6 +146,9 @@ if __name__ == '__main__':
fpid = os.fork()
if fpid > 0:
sys.exit(0)
with open(SERVER_LOG, mode='w', encoding='utf-8') as log:
os.dup2(log.fileno(), sys.stdout.fileno())
os.dup2(log.fileno(), sys.stderr.fileno())
except OSError as ferr:
print("Fork #1 failed: {} {}".format(ferr.errno, ferr.strerror))
sys.exit(1)
+31 -17
View File
@@ -1,11 +1,14 @@
"""Windows: Implementation of a HTTP server"""
#!/usr/bin/python3
"""Windows: Implementation of an HTTP server"""
import argparse
import os
import subprocess
import sys
import threading
from urllib.parse import urlparse
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
from make_certificates import CertificateMaker
RESULT_PATH = os.getcwd()
FILES_PATH = os.path.join(RESULT_PATH, "./Testing/files/")
@@ -13,19 +16,17 @@ CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
CONF_PATH = os.path.join(RESULT_PATH, "./Testing/conf/")
LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/")
REQUEST = os.path.join(FILES_PATH, "./jreq.tsq")
RESPONS = os.path.join(FILES_PATH, "./jresp.tsr")
CACRL = os.path.join(CERTS_PATH, "./CACertCRL.der")
TSACRL = os.path.join(CERTS_PATH, "./TSACertCRL.der")
RESPONSE = os.path.join(FILES_PATH, "./jresp.tsr")
OPENSSL_CONF = os.path.join(CONF_PATH, "./openssl_tsa.cnf")
SERVER_LOG = os.path.join(LOGS_PATH, "./server.log")
PORT_LOG = os.path.join(LOGS_PATH, "./port.log")
URL_LOG = os.path.join(LOGS_PATH, "./url.log")
OPENSSL_TS = ["openssl", "ts",
"-reply", "-config", OPENSSL_CONF,
"-passin", "pass:passme",
"-queryfile", REQUEST,
"-out", RESPONS]
"-out", RESPONSE]
class RequestHandler(SimpleHTTPRequestHandler):
@@ -41,15 +42,17 @@ class RequestHandler(SimpleHTTPRequestHandler):
try:
url = urlparse(self.path)
self.send_response(200)
self.send_header("Content-type", "application/crl")
self.send_header("Content-type", "application/pkix-crl")
self.end_headers()
resp_data = b''
# Read the file and send the contents
if url.path == "/intermediateCA":
with open(CACRL, 'rb') as file:
file_path = os.path.join(CERTS_PATH, "./CACertCRL.der")
with open(file_path, 'rb') as file:
resp_data = file.read()
if url.path == "/TSACA":
with open(TSACRL, 'rb') as file:
file_path = os.path.join(CERTS_PATH, "./TSACertCRL.der")
with open(file_path, 'rb') as file:
resp_data = file.read()
self.wfile.write(resp_data)
except Exception as err: # pylint: disable=broad-except
@@ -62,8 +65,8 @@ class RequestHandler(SimpleHTTPRequestHandler):
url = urlparse(self.path)
self.send_response(200)
if url.path == "/kill_server":
self.log_message(f"Deleting file: {PORT_LOG}")
os.remove(f"{PORT_LOG}")
self.log_message(f"Deleting file: {URL_LOG}")
os.remove(f"{URL_LOG}")
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(bytes('Shutting down HTTP server', 'utf-8'))
@@ -79,7 +82,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
self.send_header("Content-type", "application/timestamp-reply")
self.end_headers()
resp_data = b''
with open(RESPONS, mode="rb") as file:
with open(RESPONSE, mode="rb") as file:
resp_data = file.read()
self.wfile.write(resp_data)
except Exception as err: # pylint: disable=broad-except
@@ -94,9 +97,9 @@ class HttpServerThread():
self.server = None
self.server_thread = None
def start_server(self) -> (int):
def start_server(self, port) -> (int):
"""Starting HTTP server on 127.0.0.1 and a random available port for binding"""
self.server = ThreadingHTTPServer(('127.0.0.1', 19254), RequestHandler)
self.server = ThreadingHTTPServer(('127.0.0.1', port), RequestHandler)
self.server_thread = threading.Thread(target=self.server.serve_forever)
self.server_thread.start()
hostname, port = self.server.server_address[:2]
@@ -106,14 +109,25 @@ class HttpServerThread():
def main() -> None:
"""Start HTTP server"""
ret = 0
parser = argparse.ArgumentParser()
parser.add_argument(
"--port",
type=int,
default=0,
help="port number"
)
args = parser.parse_args()
try:
sys.stdout = open(SERVER_LOG, "w")
sys.stderr = open(SERVER_LOG, "a")
server = HttpServerThread()
port = server.start_server()
with open(PORT_LOG, mode="w") as file:
file.write("{}".format(port))
port = server.start_server(args.port)
with open(URL_LOG, mode="w") as file:
file.write("127.0.0.1:{}".format(port))
tests = CertificateMaker(port, SERVER_LOG)
tests.make_certs()
except OSError as err:
print("OSError: {}".format(err))
ret = err.errno
@@ -55,3 +55,6 @@ CATATTR1=0x11010001:OSAttr:2:6.0
<HASH>MOFfile=..\files\unsigned.mof
<HASH>MOFfileATTR1=0x11010001:File:unsigned.mof
<HASH>JSfile=..\files\unsigned.js
<HASH>JSfileATTR1=0x11010001:File:unsigned.js
+108
View File
@@ -0,0 +1,108 @@
#!/usr/bin/python3
"""Wait for all tests certificate, compute leafhash"""
import argparse
import binascii
import hashlib
import os
import pathlib
import platform
import subprocess
import sys
import time
RESULT_PATH = os.getcwd()
CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/")
SERVER_LOG = os.path.join(LOGS_PATH, "./server.log")
if platform.system() == 'Windows':
DEFAULT_PYTHON = "C:/Program Files/Python/Python311/pythonw.exe"
DEFAULT_PROG = os.path.join(RESULT_PATH, "./Testing/server_http.pyw")
else:
DEFAULT_PYTHON = "/usr/bin/python3"
DEFAULT_PROG = os.path.join(RESULT_PATH, "./Testing/server_http.py")
def compute_sha256(file_name) -> str:
"""Compute a SHA256 hash of the leaf certificate (in DER form)"""
sha256_hash = hashlib.sha256()
file_path = os.path.join(CERTS_PATH, file_name)
with open(file_path, mode="rb") as file:
for bajt in iter(lambda: file.read(4096),b""):
sha256_hash.update(bajt)
return sha256_hash.hexdigest()
def clear_catalog(certs_path) -> None:
""""Clear a test certificates catalog."""
if os.path.exists(certs_path):
#Remove old test certificates
for root, _, files in os.walk(certs_path):
for file in files:
os.remove(os.path.join(root, file))
else:
os.mkdir(certs_path)
# Generate 16 random bytes and convert to hex
random_hex = binascii.b2a_hex(os.urandom(16)).decode()
serial = os.path.join(certs_path, "./tsa-serial")
with open(serial, mode="w", encoding="utf-8") as file:
file.write(random_hex)
def main() -> None:
"""Wait for all test certificates and compute leaf hash"""
parser = argparse.ArgumentParser()
parser.add_argument(
"--exe",
type=pathlib.Path,
default=DEFAULT_PYTHON,
help=f"the path to the python3 executable to use"
f"(default: {DEFAULT_PYTHON})",
)
parser.add_argument(
"--script",
type=pathlib.Path,
default=DEFAULT_PROG,
help=f"the path to the python script to run"
f"(default: {DEFAULT_PROG})",
)
args = parser.parse_args()
try:
clear_catalog(CERTS_PATH)
#pylint: disable=consider-using-with
subprocess.Popen([str(args.exe), str(args.script)])
cert_log = os.path.join(CERTS_PATH, "./cert.log")
while not (os.path.exists(cert_log) and os.path.getsize(cert_log) > 0):
time.sleep(1)
leafhash = compute_sha256("cert.der")
file_path = os.path.join(CERTS_PATH, "./leafhash.txt")
with open(file_path, mode="w", encoding="utf-8") as file:
file.write("SHA256:{}".format(leafhash))
except OSError as err:
with open(SERVER_LOG, mode="w", encoding="utf-8") as file:
file.write("OSError: {}".format(err))
sys.exit(1)
except Exception as err: # pylint: disable=broad-except
with open(SERVER_LOG, mode="w", encoding="utf-8") as file:
file.write("Error: {}".format(err))
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:
"""
+1 -5
View File
@@ -3,11 +3,7 @@
"version-string": "2.4",
"dependencies": [
"openssl",
"curl",
{
"name": "python3",
"platform": "!(windows & static) & !osx"
}
"zlib"
],
"builtin-baseline": "9edb1b8e590cc086563301d735cae4b6e732d2d2"
}