60 Commits
2.9 ... 2.10

Author SHA1 Message Date
8329a14f8b Release 2.10
Signed-off-by: Michał Trojnara <Michal.Trojnara@stunnel.org>
2025-06-23 21:36:13 +02:00
343b0af1fe Put globs in quotes 2025-06-23 21:21:34 +02:00
d440f32780 Codespell Action 2025-06-23 21:13:47 +02:00
fb082942d2 Descriptive Action name 2025-06-23 21:05:51 +02:00
025e808c01 docs: fix typos in README 2025-06-20 16:26:18 +02:00
23b6d7782c docs: fix typo in appx comments 2025-06-20 16:14:25 +02:00
4c3a1e887c docs: fix typos in README 2025-06-20 16:04:36 +02:00
97ee163e31 Document script file support 2025-06-20 14:06:05 +02:00
dfc3e46a77 Typos 2025-06-20 12:28:43 +02:00
ff9a6d3593 Check for invalid OID in is_content_type 2025-06-20 10:32:30 +02:00
e81b08e02d Fix a comment 2025-06-20 09:58:45 +02:00
0c85d54800 Handle missing certificate names 2025-06-19 17:56:54 +02:00
772bc22c94 Handle null return from curl_easy_init 2025-06-19 14:32:24 +02:00
d65a2b5286 Fix various typos 2025-06-19 14:18:26 +02:00
a3fcf41e1a Check memory allocation 2025-06-19 12:00:29 +02:00
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
dd9b81281f Support loading OpenSSL 3.0+ providers without -pkcs11module option (e.g., CNG) 2025-06-05 17:13:10 +02:00
6b56aef073 Add tests for handling JavaScript files 2025-06-05 14:41:36 +02:00
52bfff5756 Avoid variable reuse 2025-06-04 18:42:41 +02:00
4d52e9cc4b JavaScript format fix. 2025-06-04 18:38:28 +02:00
3292b02650 JavaScript support
Resolves #437
2025-06-04 10:04:17 +02:00
50c23daa4c Code simplification
No functional change intended.
2025-06-03 08:20:52 +02:00
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
62438908cb Skip the "lib" prefix when guessing engine ID
Fix #436
2025-05-30 16:59:25 +02:00
829e770250 Use _WIN32 instead of USE_WIN32 for MinGW compatibility 2025-05-27 10:17:03 +02:00
a6c7c25dae Update NEWS 2025-05-14 11:29:13 +02:00
10ca3a06ea Suppress compiler warnings 2025-05-06 10:42:53 +02:00
9ea7e85468 Fix engine-less builds 2025-05-06 10:42:53 +02:00
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
475ea95ba3 Fix control flow and braces for engine and provider support 2025-05-01 11:21:29 +02:00
d352dcc1a5 Do not try to load engine twice 2025-04-18 10:46:20 +02:00
7734382436 Remove Ubuntu 20.04 from CI as it's no longer supported 2025-04-16 11:48:05 +02:00
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
4568c890cc Fixed resource leaks, CID 1639164, 1639165, 1639167, 1639168, 1639169 2025-03-31 13:19:35 +02:00
4bd167a8be Fixed directly dereferencing parameter p7, CID 1576008 2025-03-31 13:19:35 +02:00
e7405fa839 Simplify error handling in PKCS#7 certificate loading, CID 1639170 2025-03-31 13:19:35 +02:00
776e2ec7b6 Fix memory management for ministream and difat in MSI output, CID 1639166 2025-03-31 13:19:35 +02:00
838aaaee8d libp11 PKCS#11 provider support 2025-03-28 14:05:12 +01:00
e8f19a6efe Added verbose output for digest encryption algorithm and signature during verification 2024-12-31 13:53:46 +01:00
3a8e25e5bb Added support for multiple OID types in signer info attribute 2024-12-17 17:27:50 +01:00
7d1b460dfe Style updates 2024-12-06 22:19:00 +01:00
bc3e9e2172 Disable environment updates for Python setup 2024-12-06 22:19:00 +01:00
21bce757ef Remove specific CMake version setup for macOS 2024-12-06 22:19:00 +01:00
6a43f62835 Remove Python3_EXECUTABLE 2024-12-06 22:19:00 +01:00
8780e6f8e4 Fixed pip install 2024-12-06 22:19:00 +01:00
78a23caa54 Retain needrestart package in Linux dependency installation 2024-12-06 22:19:00 +01:00
d92927aff4 Switch to venv on Linux 2024-12-06 22:19:00 +01:00
4f412b5989 Removed VIRTUAL_ENV 2024-12-06 22:19:00 +01:00
e6f3ff631d Switch to venv on Windows 2024-12-06 22:19:00 +01:00
09135aabb8 Check Python and cryptography version in Windows CI workflow 2024-12-06 22:19:00 +01:00
de983e680f Configured macOS environment for arm64 architecture 2024-12-06 22:19:00 +01:00
dc827b94e5 Switch to venv on macOS 2024-12-06 22:19:00 +01:00
40ce811701 Fixed conditional compilation for CURL and proxy support 2024-10-25 17:48:01 +02:00
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
4ee429792d Refactor imports to use explicit submodule imports and organize class/function imports 2024-09-06 11:58:28 +02:00
27686c0b0c Missing part of 4dd836bab1 2024-09-05 11:43:25 +02:00
21133f9c3b Added the '-blobFile' option to specify a file containing the blob content 2024-09-04 17:51:35 +02:00
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
4dd836bab1 Initial 2.10-dev commit 2024-06-29 21:58:55 +02:00
f57c213207 Use the installed version of Python 2024-06-29 20:52:55 +02:00
27 changed files with 1304 additions and 681 deletions

View File

@ -1,4 +1,4 @@
name: CI name: Continuous Integration
on: on:
push: push:
@ -7,7 +7,7 @@ on:
env: env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release BUILD_TYPE: Release
version: osslsigncode-2.9 version: osslsigncode-2.10
jobs: jobs:
build: build:
@ -27,14 +27,8 @@ jobs:
os: ubuntu-22.04 os: ubuntu-22.04
generator: Unix Makefiles generator: Unix Makefiles
vcpkg_root: vcpkg_root:
- id: ubuntu-20.04
triplet: x64-linux
compiler: gcc
os: ubuntu-20.04
generator: Unix Makefiles
vcpkg_root:
- id: macOS - id: macOS
triplet: x64-osx triplet: arm64-osx
compiler: clang compiler: clang
os: macOS-latest os: macOS-latest
generator: Unix Makefiles generator: Unix Makefiles
@ -107,17 +101,23 @@ jobs:
if: matrix.compiler == 'mingw' if: matrix.compiler == 'mingw'
run: echo "D:/a/_temp/msys64/mingw64/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append run: echo "D:/a/_temp/msys64/mingw64/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Install apt dependencies (Linux) - name: Set up Python (macOS)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get remove needrestart || echo Ignored
sudo apt-get install -y libssl-dev zlib1g-dev python3-cryptography
- name: Install brew dependencies (macOS)
if: runner.os == '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: | 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) - name: Install Xcode (macOS)
if: runner.os == 'macOS' if: runner.os == 'macOS'
@ -128,46 +128,66 @@ jobs:
- name: Setup the oldest supported version of cmake (macOS) - name: Setup the oldest supported version of cmake (macOS)
if: runner.os == 'macOS' if: runner.os == 'macOS'
uses: jwlawson/actions-setup-cmake@v2.0 uses: jwlawson/actions-setup-cmake@v2.0
with:
cmake-version: '3.17.0' - name: Install python3 cryptography module (Linux)
if: runner.os == 'Linux'
run: |
source venv/bin/activate
python -m pip install --upgrade pip
python -m pip install --upgrade cryptography
python -c "import sys; print(sys.executable)"
python --version
python -c "import cryptography; print(f'Python3 cryptography version {cryptography.__version__}')"
- name: Install python3 cryptography module (macOS) - name: Install python3 cryptography module (macOS)
if: runner.os == 'macOS' if: runner.os == 'macOS'
run: | run: |
python3.8 -m ensurepip source venv/bin/activate
python3.8 -m pip install --upgrade pip python -m pip install --upgrade pip
python3.8 -m pip install cryptography 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) - name: Install python3 cryptography module (Windows)
if: runner.os == 'Windows' if: runner.os == 'Windows'
run: | run: |
C:/hostedtoolcache/windows/Python/3.12.3/x64/python3.exe -m ensurepip .\venv\Scripts\Activate.ps1
C:/hostedtoolcache/windows/Python/3.12.3/x64/python.exe -m pip install --upgrade pip python.exe -m ensurepip
C:/hostedtoolcache/windows/Python/3.12.3/x64/python.exe -m pip install cryptography 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 - name: Configure CMake (Linux/macOS)
run: cmake if: runner.os != 'Windows'
-G "${{matrix.generator}}" run: |
-S ${{github.workspace}} source venv/bin/activate
-B ${{github.workspace}}/build cmake \
-DCMAKE_OSX_ARCHITECTURES=arm64 -G "${{matrix.generator}}" \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -S "${{github.workspace}}" \
-DCMAKE_INSTALL_PREFIX=${{github.workspace}}/dist -B "${{github.workspace}}/build" \
-DVCPKG_TARGET_TRIPLET=${{matrix.triplet}} -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 - name: Build
run: cmake run: cmake
--build ${{github.workspace}}/build --build ${{github.workspace}}/build
--config ${{env.BUILD_TYPE}} --config ${{env.BUILD_TYPE}}
- name: Show python version (macOS)
working-directory: ${{github.workspace}}/build
if: runner.os == 'macOS'
run: |
python3.8 --version
python3.8 -c "import sys; print(sys.executable)"
python3.8 -c "import cryptography; print(f'Python3 cryptography version {cryptography.__version__}')"
- name: List files (Linux/macOS) - name: List files (Linux/macOS)
if: runner.os != 'Windows' if: runner.os != 'Windows'
run: find .. -ls run: find .. -ls
@ -176,9 +196,19 @@ jobs:
if: runner.os == 'Windows' if: runner.os == 'Windows'
run: Get-ChildItem -Recurse -Name .. run: Get-ChildItem -Recurse -Name ..
- name: Test - name: Test (Linux/macOS)
if: runner.os != 'Windows'
working-directory: ${{github.workspace}}/build 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 - name: Upload the errors
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4

16
.github/workflows/codespell.yml vendored Normal file
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'

View File

@ -10,8 +10,8 @@ set(BUILTIN_SOCKET ON CACHE BOOL "") # for static Python
# configure basic project information # configure basic project information
project(osslsigncode project(osslsigncode
VERSION 2.9 VERSION 2.10
DESCRIPTION "OpenSSL based Authenticode signing for PE, CAB, CAT and MSI files" DESCRIPTION "OpenSSL based Authenticode signing for PE, CAB, CAT, MSI, APPX and script files"
HOMEPAGE_URL "https://github.com/mtrojnar/osslsigncode" HOMEPAGE_URL "https://github.com/mtrojnar/osslsigncode"
LANGUAGES C) LANGUAGES C)
@ -29,6 +29,9 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
# load CMake library modules # load CMake library modules
include(FindOpenSSL) include(FindOpenSSL)
if(OPENSSL_VERSION VERSION_LESS "1.1.1")
message(FATAL_ERROR "OpenSSL version must be at least 1.1.1")
endif()
if(OPENSSL_VERSION VERSION_LESS "3.0.0") if(OPENSSL_VERSION VERSION_LESS "3.0.0")
include(FindCURL) include(FindCURL)
endif(OPENSSL_VERSION VERSION_LESS "3.0.0") endif(OPENSSL_VERSION VERSION_LESS "3.0.0")
@ -85,7 +88,7 @@ target_link_libraries(osslsigncode PRIVATE ${ZLIB_LIBRARIES})
if(NOT UNIX) if(NOT UNIX)
# https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-shutdown # https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-shutdown
target_link_libraries(osslsigncode PRIVATE Ws2_32.lib crypt32.lib) target_link_libraries(osslsigncode PRIVATE ws2_32.lib crypt32.lib)
endif(NOT UNIX) endif(NOT UNIX)
# add paths to linker search and installed rpath # add paths to linker search and installed rpath

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) 2005-2014 Per Allansson <pallansson@gmail.com>
Copyright (C) 2018-2022 Michał Trojnara <Michal.Trojnara@stunnel.org> Copyright (C) 2018-2022 Michał Trojnara <Michal.Trojnara@stunnel.org>

14
NEWS.md
View File

@ -1,5 +1,19 @@
# osslsigncode change log # osslsigncode change log
### 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) ### 2.9 (2024.06.29)
- added a 64 bit long pseudo-random NONCE in the TSA request - added a 64 bit long pseudo-random NONCE in the TSA request

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 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 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 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? ## 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", 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. 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 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/ \ -n "Your Application" -i http://www.yourwebsite.com/ \
-in yourapp.exe -out yourapp-signed.exe -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> \ osslsigncode sign -certs <cert-file> -key <key-file> \
-n "Your Application" -i http://www.yourwebsite.com/ \ -n "Your Application" -i http://www.yourwebsite.com/ \
@ -131,17 +133,51 @@ To sign a CAB file containing java class files:
``` ```
Only the 'low' parameter is currently supported. Only the 'low' parameter is currently supported.
If you want to use PKCS11 token, you should indicate PKCS11 engine and module. If you want to use a PKCS#11 token, you should specify the PKCS#11 engine and module.
An example of using osslsigncode with SoftHSM: An example of using osslsigncode with SoftHSM:
``` ```
osslsigncode sign \ osslsigncode sign \
-pkcs11engine /usr/lib64/engines-1.1/pkcs11.so \ -engine /usr/lib64/engines-1.1/pkcs11.so \
-pkcs11module /usr/lib64/pkcs11/libsofthsm2.so \ -pkcs11module /usr/lib64/pkcs11/libsofthsm2.so \
-pkcs11cert 'pkcs11:token=softhsm-token;object=cert' \ -pkcs11cert 'pkcs11:token=softhsm-token;object=cert' \
-key 'pkcs11:token=softhsm-token;object=key' \ -key 'pkcs11:token=softhsm-token;object=key' \
-in yourapp.exe -out yourapp-signed.exe -in yourapp.exe -out yourapp-signed.exe
``` ```
Since OpenSSL 3.0, you can use a PKCS#11 token with the PKCS#11 provider.
An example of using osslsigncode with OpenSC:
```
osslsigncode sign \
-provider /usr/lib64/ossl-modules/pkcs11prov.so \
-pkcs11module /usr/lib64/opensc-pkcs11.so \
-pkcs11cert 'pkcs11:token=my-token;object=cert' \
-key 'pkcs11:token=my-token;object=key' \
-in yourapp.exe -out yourapp-signed.exe
```
You can use a certificate and key stored in the Windows Certificate Store with
the CNG engine version 1.1 or later. For more information, refer to
https://www.stunnel.org/cng-engine.html
A non-commercial edition of CNG engine is available for testing, personal,
educational, or research purposes.
To use the CNG engine with osslsigncode, ensure that the `cng.dll` library is
placed in the same directory as the `osslsigncode.exe` executable.
Below is an example of how to use osslsigncode with the CNG engine:
```
osslsigncode sign \
-engine cng \
-pkcs11cert osslsigncode_cert \
-key osslsigncode_cert \
-engineCtrl store_flags:0 \
-engineCtrl store_name:MY \
-engineCtrl PIN:yourpass \
-in yourapp.exe -out yourapp-signed.exe
```
You can check that the signed file is correct by right-clicking You can check that the signed file is correct by right-clicking
on it in Windows and choose Properties --> Digital Signatures, on it in Windows and choose Properties --> Digital Signatures,
and then choose the signature from the list, and click on and then choose the signature from the list, and click on
@ -179,13 +215,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 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 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 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 code signed AND that it has been signed with your cert AND that it is the
version you expect. version you expect.
## BUGS, QUESTIONS etc. ## 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. discussed on https://github.com/mtrojnar/osslsigncode/issues.
Otherwise, open a new issue. Otherwise, open a new issue.

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 - clean up / untangle code
- separate timestamping - separate timestamping
- remove mmap usage to increase portability - remove mmap usage to increase portability

66
appx.c
View File

@ -29,11 +29,6 @@
#endif /* _MSC_VER */ #endif /* _MSC_VER */
#endif /* PRIX64 */ #endif /* PRIX64 */
#if defined(_MSC_VER)
#define fseeko _fseeki64
#define ftello _ftelli64
#endif /* _MSC_VER */
#define EOCDR_SIZE 22 #define EOCDR_SIZE 22
#define ZIP64_EOCD_LOCATOR_SIZE 20 #define ZIP64_EOCD_LOCATOR_SIZE 20
#define ZIP64_HEADER 0x01 #define ZIP64_HEADER 0x01
@ -293,7 +288,7 @@ static void zipWriteCentralDirectoryEntry(BIO *bio, uint64_t *sizeOnDisk, ZIP_CE
static int zipAppendSignatureFile(BIO *bio, ZIP_FILE *zip, uint8_t *data, uint64_t dataSize); static int zipAppendSignatureFile(BIO *bio, ZIP_FILE *zip, uint8_t *data, uint64_t dataSize);
static int zipOverrideFileData(ZIP_CENTRAL_DIRECTORY_ENTRY *entry, uint8_t *data, uint64_t dataSize); static int zipOverrideFileData(ZIP_CENTRAL_DIRECTORY_ENTRY *entry, uint8_t *data, uint64_t dataSize);
static int zipRewriteData(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_ENTRY *entry, BIO *bio, uint64_t *sizeOnDisk); static int zipRewriteData(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_ENTRY *entry, BIO *bio, uint64_t *sizeOnDisk);
static void zipWriteLocalHeader(BIO *bio, uint64_t *sizeonDisk, ZIP_LOCAL_HEADER *heade); static void zipWriteLocalHeader(BIO *bio, uint64_t *sizeonDisk, ZIP_LOCAL_HEADER *header);
static int zipEntryExist(ZIP_FILE *zip, const char *name); static int zipEntryExist(ZIP_FILE *zip, const char *name);
static u_char *zipCalcDigest(ZIP_FILE *zip, const char *fileName, const EVP_MD *md); static u_char *zipCalcDigest(ZIP_FILE *zip, const char *fileName, const EVP_MD *md);
static size_t zipReadFileDataByName(uint8_t **pData, ZIP_FILE *zip, const char *name); static size_t zipReadFileDataByName(uint8_t **pData, ZIP_FILE *zip, const char *name);
@ -878,11 +873,18 @@ static uint8_t *appx_calc_zip_central_directory_hash(ZIP_FILE *zip, const EVP_MD
u_char *mdbuf = NULL; u_char *mdbuf = NULL;
BIO *bhash = BIO_new(BIO_f_md()); 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)) { if (!BIO_set_md(bhash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(bhash, BIO_new(BIO_s_null())); BIO_push(bhash, BIO_new(BIO_s_null()));
if (!appx_write_central_directory(bhash, zip, 1, cdOffset)) { if (!appx_write_central_directory(bhash, zip, 1, cdOffset)) {
fprintf(stderr, "Unable to write central directory\n"); fprintf(stderr, "Unable to write central directory\n");
@ -910,7 +912,7 @@ static int appx_write_central_directory(BIO *bio, ZIP_FILE *zip, int removeSigna
uint16_t noEntries = 0; uint16_t noEntries = 0;
for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) { for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) {
/* the signature file is considered non existent for hashing purposes */ /* the signature file is considered nonexistent for hashing purposes */
uint64_t sizeOnDisk = 0; uint64_t sizeOnDisk = 0;
if (noEntries > zip->centralDirectoryRecordCount) { if (noEntries > zip->centralDirectoryRecordCount) {
fprintf(stderr, "Corrupted central directory structure\n"); fprintf(stderr, "Corrupted central directory structure\n");
@ -923,7 +925,7 @@ static int appx_write_central_directory(BIO *bio, ZIP_FILE *zip, int removeSigna
if (removeSignature && !strcmp(entry->fileName, APP_SIGNATURE_FILENAME)) { if (removeSignature && !strcmp(entry->fileName, APP_SIGNATURE_FILENAME)) {
continue; continue;
} }
/* APP_SIGNATURE is nt 'tainted' by offset shift after replacing the contents of [content_types] */ /* APP_SIGNATURE is not 'tainted' by offset shift after replacing the contents of [content_types] */
zipWriteCentralDirectoryEntry(bio, &sizeOnDisk, entry, strcmp(entry->fileName, APP_SIGNATURE_FILENAME) ? offsetDiff : 0); zipWriteCentralDirectoryEntry(bio, &sizeOnDisk, entry, strcmp(entry->fileName, APP_SIGNATURE_FILENAME) ? offsetDiff : 0);
cdSize += sizeOnDisk; cdSize += sizeOnDisk;
if (entry->overrideData) { if (entry->overrideData) {
@ -1005,11 +1007,18 @@ static uint8_t *appx_calc_zip_data_hash(uint64_t *cdOffset, ZIP_FILE *zip, const
BIO *bhash = BIO_new(BIO_f_md()); BIO *bhash = BIO_new(BIO_f_md());
uint64_t noEntries = 0; uint64_t noEntries = 0;
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
if (!BIO_set_md(bhash, md)) { if (!BIO_set_md(bhash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(bhash, BIO_new(BIO_s_null())); BIO_push(bhash, BIO_new(BIO_s_null()));
*cdOffset = 0; *cdOffset = 0;
for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) { for (entry = zip->centralDirectoryHead; entry != NULL; entry = entry->next) {
@ -1178,7 +1187,7 @@ static int appx_compare_hashes(FILE_FORMAT_CTX *ctx)
return 0; /* FAILED */ return 0; /* FAILED */
} }
} else if (!ctx->appx_ctx->calculatedCIHash && !ctx->appx_ctx->existingCIHash) { } else if (!ctx->appx_ctx->calculatedCIHash && !ctx->appx_ctx->existingCIHash) {
/* this is fine, CI file is optional -> if it is missing we expect both hashes to be non existent */ /* this is fine, CI file is optional -> if it is missing we expect both hashes to be nonexistent */
} else { } else {
fprintf(stderr, "Code Integrity hash missing\n"); fprintf(stderr, "Code Integrity hash missing\n");
return 0; /* FAILED */ return 0; /* FAILED */
@ -1421,7 +1430,7 @@ static void zipWriteCentralDirectoryEntry(BIO *bio, uint64_t *sizeOnDisk, ZIP_CE
#if 0 #if 0
if (entry->extraFieldLen > 0 && entry->extraField) if (entry->extraFieldLen > 0 && entry->extraField)
{ {
/* TODO, if override daata, need to rewrite the extra field */ /* TODO, if override data, need to rewrite the extra field */
BIO_write(bio, entry->extraField, entry->extraFieldLen); BIO_write(bio, entry->extraField, entry->extraFieldLen);
} }
#endif #endif
@ -1493,6 +1502,7 @@ static int zipAppendSignatureFile(BIO *bio, ZIP_FILE *zip, uint8_t *data, uint64
if (!get_current_position(bio, &offset)) { if (!get_current_position(bio, &offset)) {
fprintf(stderr, "Unable to get offset\n"); fprintf(stderr, "Unable to get offset\n");
OPENSSL_free(header.fileName);
OPENSSL_free(dataToWrite); OPENSSL_free(dataToWrite);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -1502,6 +1512,7 @@ static int zipAppendSignatureFile(BIO *bio, ZIP_FILE *zip, uint8_t *data, uint64
size_t check; size_t check;
if (!BIO_write_ex(bio, dataToWrite + written, toWrite, &check) if (!BIO_write_ex(bio, dataToWrite + written, toWrite, &check)
|| check != toWrite) { || check != toWrite) {
OPENSSL_free(header.fileName);
OPENSSL_free(dataToWrite); OPENSSL_free(dataToWrite);
return 0; /* FAILED */ return 0; /* FAILED */
} }
@ -1596,6 +1607,7 @@ static int zipRewriteData(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_ENTRY *entry, BIO
{ {
size_t check; size_t check;
ZIP_LOCAL_HEADER header; ZIP_LOCAL_HEADER header;
int ret = 0;
memset(&header, 0, sizeof(header)); memset(&header, 0, sizeof(header));
if (entry->offsetOfLocalHeader >= (uint64_t)zip->fileSize) { if (entry->offsetOfLocalHeader >= (uint64_t)zip->fileSize) {
@ -1606,7 +1618,7 @@ static int zipRewriteData(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_ENTRY *entry, BIO
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (!zipReadLocalHeader(&header, zip, entry->compressedSize)) { if (!zipReadLocalHeader(&header, zip, entry->compressedSize)) {
return 0; /* FAILED */ goto out;
} }
if (entry->overrideData) { if (entry->overrideData) {
header.compressedSize = entry->overrideData->compressedSize; header.compressedSize = entry->overrideData->compressedSize;
@ -1617,14 +1629,14 @@ static int zipRewriteData(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_ENTRY *entry, BIO
if (entry->overrideData) { if (entry->overrideData) {
if (!BIO_write_ex(bio, entry->overrideData->data, entry->overrideData->compressedSize, &check) if (!BIO_write_ex(bio, entry->overrideData->data, entry->overrideData->compressedSize, &check)
|| check != entry->overrideData->compressedSize) { || check != entry->overrideData->compressedSize) {
return 0; /* FAILED */ goto out;
} }
if (entry->compressedSize > (uint64_t)zip->fileSize - entry->offsetOfLocalHeader) { if (entry->compressedSize > (uint64_t)zip->fileSize - entry->offsetOfLocalHeader) {
fprintf(stderr, "Corrupted compressedSize : 0x%08" PRIX64 "\n", entry->compressedSize); fprintf(stderr, "Corrupted compressedSize : 0x%08" PRIX64 "\n", entry->compressedSize);
return 0; /* FAILED */ goto out;
} }
if (fseeko(zip->file, (int64_t)entry->compressedSize, SEEK_CUR) < 0) { if (fseeko(zip->file, (int64_t)entry->compressedSize, SEEK_CUR) < 0) {
return 0; /* FAILED */ goto out;
} }
*sizeOnDisk += entry->overrideData->compressedSize; *sizeOnDisk += entry->overrideData->compressedSize;
} else { } else {
@ -1635,12 +1647,12 @@ static int zipRewriteData(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_ENTRY *entry, BIO
size_t size = fread(data, 1, toWrite, zip->file); size_t size = fread(data, 1, toWrite, zip->file);
if (size != toWrite) { if (size != toWrite) {
OPENSSL_free(data); OPENSSL_free(data);
return 0; /* FAILED */ goto out;
} }
if (!BIO_write_ex(bio, data, toWrite, &check) if (!BIO_write_ex(bio, data, toWrite, &check)
|| check != toWrite) { || check != toWrite) {
OPENSSL_free(data); OPENSSL_free(data);
return 0; /* FAILED */ goto out;
} }
*sizeOnDisk += toWrite; *sizeOnDisk += toWrite;
len -= toWrite; len -= toWrite;
@ -1659,19 +1671,21 @@ static int zipRewriteData(ZIP_FILE *zip, ZIP_CENTRAL_DIRECTORY_ENTRY *entry, BIO
} }
if (zip->isZip64) { if (zip->isZip64) {
if (fseeko(zip->file, 24, SEEK_CUR) < 0) { if (fseeko(zip->file, 24, SEEK_CUR) < 0) {
return 0; /* FAILED */ goto out;
} }
*sizeOnDisk += 24; *sizeOnDisk += 24;
} else { } else {
if (fseeko(zip->file, 16, SEEK_CUR) < 0) { if (fseeko(zip->file, 16, SEEK_CUR) < 0) {
return 0; /* FAILED */ goto out;
} }
*sizeOnDisk += 16; *sizeOnDisk += 16;
} }
} }
ret = 1; /* OK */
out:
OPENSSL_free(header.fileName); OPENSSL_free(header.fileName);
OPENSSL_free(header.extraField); OPENSSL_free(header.extraField);
return 1; /* OK */ return ret;
} }
/* /*
@ -1758,12 +1772,19 @@ static u_char *zipCalcDigest(ZIP_FILE *zip, const char *fileName, const EVP_MD *
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
bhash = BIO_new(BIO_f_md()); 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)) { if (!BIO_set_md(bhash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
OPENSSL_free(data); OPENSSL_free(data);
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(bhash, BIO_new(BIO_s_null())); BIO_push(bhash, BIO_new(BIO_s_null()));
if (!bio_hash_data(bhash, (char *)data, 0, dataSize)) { if (!bio_hash_data(bhash, (char *)data, 0, dataSize)) {
OPENSSL_free(data); OPENSSL_free(data);
@ -1840,6 +1861,8 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
uncompressedSize = entry->uncompressedSize; uncompressedSize = entry->uncompressedSize;
memset(&header, 0, sizeof(header)); memset(&header, 0, sizeof(header));
if (!zipReadLocalHeader(&header, zip, compressedSize)) { if (!zipReadLocalHeader(&header, zip, compressedSize)) {
OPENSSL_free(header.fileName);
OPENSSL_free(header.extraField);
return 0; /* FAILED */ return 0; /* FAILED */
} }
if (header.fileNameLen != entry->fileNameLen if (header.fileNameLen != entry->fileNameLen
@ -1848,6 +1871,8 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
|| header.uncompressedSize != uncompressedSize || header.uncompressedSize != uncompressedSize
|| header.compression != entry->compression) { || header.compression != entry->compression) {
fprintf(stderr, "Local header does not match central directory entry\n"); fprintf(stderr, "Local header does not match central directory entry\n");
OPENSSL_free(header.fileName);
OPENSSL_free(header.extraField);
return 0; /* FAILED */ return 0; /* FAILED */
} }
/* we don't really need those */ /* we don't really need those */
@ -1883,7 +1908,7 @@ static size_t zipReadFileData(ZIP_FILE *zip, uint8_t **pData, ZIP_CENTRAL_DIRECT
OPENSSL_free(compressedData); OPENSSL_free(compressedData);
if (ret != Z_OK) { if (ret != Z_OK) {
fprintf(stderr, "Data decompresssion failed, zlib error: %d\n", ret); fprintf(stderr, "Data decompression failed, zlib error: %d\n", ret);
OPENSSL_free(uncompressedData); OPENSSL_free(uncompressedData);
return 0; /* FAILED */ return 0; /* FAILED */
} else { } else {
@ -2149,6 +2174,7 @@ static int zipDeflate(uint8_t *dest, uint64_t *destLen, uint8_t *source, uLong s
err = deflateInit2(&stream, 8, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY); err = deflateInit2(&stream, 8, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
if (err != Z_OK) { if (err != Z_OK) {
deflateEnd(&stream);
return err; return err;
} }
stream.next_out = dest; stream.next_out = dest;

9
cab.c
View File

@ -205,11 +205,18 @@ static u_char *cab_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
u_char *mdbuf = NULL; u_char *mdbuf = NULL;
BIO *bhash = BIO_new(BIO_f_md()); 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)) { if (!BIO_set_md(bhash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(bhash, BIO_new(BIO_s_null())); BIO_push(bhash, BIO_new(BIO_s_null()));
/* u1 signature[4] 4643534D MSCF: 0-3 */ /* u1 signature[4] 4643534D MSCF: 0-3 */
@ -689,7 +696,7 @@ static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize)
* and consist of 4 bytes (little-endian order) * and consist of 4 bytes (little-endian order)
* siglen - additional data size is located at offset 48 (from file beginning) * siglen - additional data size is located at offset 48 (from file beginning)
* and consist of 4 bytes (little-endian order) * 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. * as additional data offset plus additional data size.
*/ */
sigpos = GET_UINT32_LE(indata + 44); sigpos = GET_UINT32_LE(indata + 44);

39
cat.c
View File

@ -55,8 +55,8 @@ FILE_FORMAT file_format_cat = {
/* Prototypes */ /* Prototypes */
static CAT_CTX *cat_ctx_get(char *indata, uint32_t filesize); static CAT_CTX *cat_ctx_get(char *indata, uint32_t filesize);
static int cat_add_ms_ctl_object(PKCS7 *p7); static int cat_add_content_type(PKCS7 *p7, PKCS7 *cursig);
static int cat_sign_ms_ctl_content(PKCS7 *p7, PKCS7 *contents); static int cat_sign_content(PKCS7 *p7, PKCS7 *contents);
static int cat_list_content(PKCS7 *p7); static int cat_list_content(PKCS7 *p7);
static int cat_print_content_member_digest(ASN1_TYPE *content); static int cat_print_content_member_digest(ASN1_TYPE *content);
static int cat_print_content_member_name(ASN1_TYPE *content); static int cat_print_content_member_name(ASN1_TYPE *content);
@ -161,17 +161,17 @@ static PKCS7 *cat_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
fprintf(stderr, "Creating a new signature failed\n"); fprintf(stderr, "Creating a new signature failed\n");
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!cat_add_ms_ctl_object(p7)) {
fprintf(stderr, "Adding MS_CTL_OBJID failed\n");
PKCS7_free(p7);
return NULL; /* FAILED */
}
if (!ctx->cat_ctx->p7 || !ctx->cat_ctx->p7->d.sign || !ctx->cat_ctx->p7->d.sign->contents) { 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"); fprintf(stderr, "Failed to get content\n");
PKCS7_free(p7); PKCS7_free(p7);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
if (!cat_sign_ms_ctl_content(p7, ctx->cat_ctx->p7->d.sign->contents)) { if (!cat_add_content_type(p7, ctx->cat_ctx->p7)) {
fprintf(stderr, "Adding content type failed\n");
PKCS7_free(p7);
return NULL; /* FAILED */
}
if (!cat_sign_content(p7, ctx->cat_ctx->p7->d.sign->contents)) {
fprintf(stderr, "Failed to set signed content\n"); fprintf(stderr, "Failed to set signed content\n");
PKCS7_free(p7); PKCS7_free(p7);
return NULL; /* FAILED */ return NULL; /* FAILED */
@ -251,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, out] p7: new PKCS#7 signature
* [in] cursig: current PKCS#7 signature to determine content type
* [returns] 0 on error or 1 on success * [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; STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
PKCS7_SIGNER_INFO *si; 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); signer_info = PKCS7_get_signer_info(p7);
if (!signer_info) if (!signer_info)
return 0; /* FAILED */ return 0; /* FAILED */
@ -267,7 +282,7 @@ static int cat_add_ms_ctl_object(PKCS7 *p7)
if (!si) if (!si)
return 0; /* FAILED */ return 0; /* FAILED */
if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, 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 0; /* FAILED */
return 1; /* OK */ return 1; /* OK */
} }
@ -280,7 +295,7 @@ static int cat_add_ms_ctl_object(PKCS7 *p7)
* [in] contents: Certificate Trust List (CTL) * [in] contents: Certificate Trust List (CTL)
* [returns] 0 on error or 1 on success * [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; u_char *content;
int seqhdrlen, content_length; int seqhdrlen, content_length;

View File

@ -3,7 +3,7 @@
set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) 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_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.txt") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.txt")

View File

@ -75,9 +75,9 @@ if(Python3_FOUND)
endif(NOT client_result) endif(NOT client_result)
endif(EXISTS "${LOGS}/url.log") endif(EXISTS "${LOGS}/url.log")
set(extensions_all "exe" "ex_" "msi" "256appx" "512appx" "cat" "ps1" "psc1" "mof") set(extensions_all "exe" "ex_" "msi" "256appx" "512appx" "cat" "ps1" "psc1" "mof" "js")
set(extensions_nocat "exe" "ex_" "msi" "256appx" "512appx" "ps1" "psc1" "mof") set(extensions_nocat "exe" "ex_" "msi" "256appx" "512appx" "ps1" "psc1" "mof" "js")
set(extensions_nocatappx "exe" "ex_" "msi" "ps1" "psc1" "mof") set(extensions_nocatappx "exe" "ex_" "msi" "ps1" "psc1" "mof" "js")
set(formats "pem" "der") set(formats "pem" "der")
else(NOT cryptography_error) else(NOT cryptography_error)
@ -219,6 +219,7 @@ if(Python3_FOUND AND NOT cryptography_error)
add_test(NAME "added_${ext}" add_test(NAME "added_${ext}"
COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "add" COMMAND ${Python3_EXECUTABLE} ${EXEC} ${OSSLSIGNCODE} "add"
"-addUnauthenticatedBlob" "-addUnauthenticatedBlob"
"-blobFile" "${FILES}/unsigned.exe"
"-add-msi-dse" "-h" "sha512" "-add-msi-dse" "-h" "sha512"
"-in" "${FILES}/signed.${ext}" "-in" "${FILES}/signed.${ext}"
"-out" "${FILES}/added.${ext}") "-out" "${FILES}/added.${ext}")

102
helpers.c
View File

@ -165,73 +165,76 @@ int data_write_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx) PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx)
{ {
int i, signer = -1; int i, signer = -1;
PKCS7 *p7;
PKCS7_SIGNER_INFO *si = NULL; PKCS7_SIGNER_INFO *si = NULL;
STACK_OF(X509) *chain = 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_set_type(p7, NID_pkcs7_signed);
PKCS7_content_new(p7, NID_pkcs7_data); PKCS7_content_new(p7, NID_pkcs7_data);
if (ctx->options->cert != NULL) {
/* /* find the signer's certificate located somewhere in the whole certificate chain */
* the private key and corresponding certificate are parsed from the PKCS12 for (i=0; i<sk_X509_num(ctx->options->certs); i++) {
* structure or loaded from the security token, so we may omit to check X509 *signcert = sk_X509_value(ctx->options->certs, i);
* the consistency of a private key with the public key in an X509 certificate
*/ if (X509_check_private_key(signcert, ctx->options->pkey)) {
si = PKCS7_add_signature(p7, ctx->options->cert, ctx->options->pkey, si = PKCS7_add_signature(p7, signcert, ctx->options->pkey, ctx->options->md);
ctx->options->md); signer = i;
if (si == NULL) if (signer > 0)
return NULL; /* FAILED */ printf("Warning: For optimal performance, consider placing the signer certificate at the beginning of the certificate chain.\n");
} else { break;
/* 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) {
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",
ctx->options->certfile);
return NULL; /* FAILED */
} }
} }
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)) { if (!pkcs7_signer_info_add_signing_time(si, ctx)) {
return NULL; /* FAILED */ goto err;
} }
if (!pkcs7_signer_info_add_purpose(si, ctx)) { if (!pkcs7_signer_info_add_purpose(si, ctx)) {
return NULL; /* FAILED */ goto err;
} }
if ((ctx->options->desc || ctx->options->url) && if ((ctx->options->desc || ctx->options->url) &&
!pkcs7_signer_info_add_spc_sp_opus_info(si, ctx)) { !pkcs7_signer_info_add_spc_sp_opus_info(si, ctx)) {
fprintf(stderr, "Couldn't allocate memory for opus info\n"); fprintf(stderr, "Couldn't allocate memory for opus info\n");
return NULL; /* FAILED */ goto err;
} }
if ((ctx->options->nested_number >= 0) && if ((ctx->options->nested_number >= 0) &&
!pkcs7_signer_info_add_sequence_number(si, ctx)) { !pkcs7_signer_info_add_sequence_number(si, ctx)) {
return NULL; /* FAILED */ goto err;
} }
/* create X509 chain sorted in ascending order by their DER encoding */ /* create X509 chain sorted in ascending order by their DER encoding */
chain = X509_chain_get_sorted(ctx, signer); chain = X509_chain_get_sorted(ctx, signer);
if (chain == NULL) { if (!chain) {
fprintf(stderr, "Failed to create a sorted certificate chain\n"); fprintf(stderr, "Failed to create a sorted certificate chain\n");
return NULL; /* FAILED */ goto err;
} }
/* add sorted certificate chain */ /* add sorted certificate chain */
for (i=0; i<sk_X509_num(chain); i++) { 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 */ /* add crls */
if (ctx->options->crls) { if (ctx->options->crls) {
for (i=0; i<sk_X509_CRL_num(ctx->options->crls); i++) 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); sk_X509_free(chain);
return p7; /* OK */ return p7; /* OK */
err:
PKCS7_free(p7);
return NULL; /* FAILED */
} }
/* /*
@ -461,7 +464,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 * [in] objid: Microsoft OID Authenticode
* [returns] 0 on error or 1 on success * [returns] 0 on error or 1 on success
*/ */
@ -471,6 +474,10 @@ int is_content_type(PKCS7 *p7, const char *objid)
int ret; int ret;
indir_objid = OBJ_txt2obj(objid, 1); 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) && ret = p7 && PKCS7_type_is_signed(p7) &&
!OBJ_cmp(p7->d.sign->contents->type, indir_objid) && !OBJ_cmp(p7->d.sign->contents->type, indir_objid) &&
(p7->d.sign->contents->d.other->type == V_ASN1_SEQUENCE || (p7->d.sign->contents->d.other->type == V_ASN1_SEQUENCE ||
@ -732,11 +739,6 @@ static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer)
int i; int i;
STACK_OF(X509) *chain = sk_X509_new(X509_compare); 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))) { if (signer != -1 && !sk_X509_push(chain, sk_X509_value(ctx->options->certs, signer))) {
sk_X509_free(chain); sk_X509_free(chain);
return NULL; return NULL;
@ -779,6 +781,15 @@ static int X509_compare(const X509 *const *a, const X509 *const *b)
size_t a_len, b_len; size_t a_len, b_len;
int ret; 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_len = (size_t)i2d_X509(*a, NULL);
a_tmp = a_data = OPENSSL_malloc(a_len); a_tmp = a_data = OPENSSL_malloc(a_len);
i2d_X509(*a, &a_tmp); i2d_X509(*a, &a_tmp);
@ -786,6 +797,13 @@ static int X509_compare(const X509 *const *a, const X509 *const *b)
b_len = (size_t)i2d_X509(*b, NULL); b_len = (size_t)i2d_X509(*b, NULL);
b_tmp = b_data = OPENSSL_malloc(b_len); b_tmp = b_data = OPENSSL_malloc(b_len);
i2d_X509(*b, &b_tmp); 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)); ret = memcmp(a_data, b_data, MIN(a_len, b_len));
OPENSSL_free(a_data); OPENSSL_free(a_data);

37
msi.c
View File

@ -373,11 +373,18 @@ static u_char *msi_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
u_char *mdbuf = NULL; u_char *mdbuf = NULL;
BIO *bhash = BIO_new(BIO_f_md()); 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)) { if (!BIO_set_md(bhash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(bhash, BIO_new(BIO_s_null())); BIO_push(bhash, BIO_new(BIO_s_null()));
if (!bio_hash_data(bhash, ctx->options->indata, 0, ctx->msi_ctx->fileend)) { if (!bio_hash_data(bhash, ctx->options->indata, 0, ctx->msi_ctx->fileend)) {
fprintf(stderr, "Unable to calculate digest\n"); fprintf(stderr, "Unable to calculate digest\n");
@ -426,11 +433,18 @@ static int msi_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
printf("Message digest algorithm : %s\n", OBJ_nid2sn(mdtype)); printf("Message digest algorithm : %s\n", OBJ_nid2sn(mdtype));
md = EVP_get_digestbynid(mdtype); md = EVP_get_digestbynid(mdtype);
hash = BIO_new(BIO_f_md()); 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)) { if (!BIO_set_md(hash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(hash); BIO_free_all(hash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(hash, BIO_new(BIO_s_null())); BIO_push(hash, BIO_new(BIO_s_null()));
if (ctx->msi_ctx->p_msiex) { if (ctx->msi_ctx->p_msiex) {
BIO *prehash = BIO_new(BIO_f_md()); BIO *prehash = BIO_new(BIO_f_md());
@ -440,12 +454,19 @@ static int msi_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
BIO_free_all(prehash); BIO_free_all(prehash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
if (!BIO_set_md(prehash, md)) { if (!BIO_set_md(prehash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(hash); BIO_free_all(hash);
BIO_free_all(prehash); BIO_free_all(prehash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(prehash, BIO_new(BIO_s_null())); BIO_push(prehash, BIO_new(BIO_s_null()));
print_hash("Current MsiDigitalSignatureEx ", "", (u_char *)ctx->msi_ctx->p_msiex, print_hash("Current MsiDigitalSignatureEx ", "", (u_char *)ctx->msi_ctx->p_msiex,
@ -1785,7 +1806,6 @@ static int ministream_save(MSI_DIRENT *dirent, BIO *outdata, MSI_OUT *out)
dirent->entry->startSectorLocation = out->sectorNum; dirent->entry->startSectorLocation = out->sectorNum;
/* ministream save */ /* ministream save */
BIO_write(outdata, out->ministream, (int)out->miniStreamLen); BIO_write(outdata, out->ministream, (int)out->miniStreamLen);
OPENSSL_free(out->ministream);
/* fill to the end with known data, such as all zeroes */ /* fill to the end with known data, such as all zeroes */
if (out->miniStreamLen % out->sectorSize > 0) { if (out->miniStreamLen % out->sectorSize > 0) {
remain = out->sectorSize - out->miniStreamLen % out->sectorSize; remain = out->sectorSize - out->miniStreamLen % out->sectorSize;
@ -2186,6 +2206,8 @@ static int msiout_set(MSI_FILE *msi, uint32_t len_msi, uint32_t len_msiex, MSI_O
out->header = header_new(msi->m_hdr, out); out->header = header_new(msi->m_hdr, out);
out->minifatMemallocCount = msi->m_hdr->numMiniFATSector; out->minifatMemallocCount = msi->m_hdr->numMiniFATSector;
out->fatMemallocCount = msi->m_hdr->numFATSector; out->fatMemallocCount = msi->m_hdr->numFATSector;
out->difatMemallocCount = 0;
out->difat = NULL;
out->ministream = NULL; out->ministream = NULL;
out->minifat = OPENSSL_malloc((uint64_t)out->minifatMemallocCount * out->sectorSize); out->minifat = OPENSSL_malloc((uint64_t)out->minifatMemallocCount * out->sectorSize);
out->fat = OPENSSL_malloc((uint64_t)out->fatMemallocCount * out->sectorSize); out->fat = OPENSSL_malloc((uint64_t)out->fatMemallocCount * out->sectorSize);
@ -2226,7 +2248,9 @@ static int msi_file_write(MSI_FILE *msi, MSI_DIRENT *dirent, u_char *p_msi, uint
out: out:
OPENSSL_free(out.header); OPENSSL_free(out.header);
OPENSSL_free(out.fat); OPENSSL_free(out.fat);
OPENSSL_free(out.difat);
OPENSSL_free(out.minifat); OPENSSL_free(out.minifat);
OPENSSL_free(out.ministream);
return ret; return ret;
} }
@ -2295,11 +2319,18 @@ static int msi_calc_MsiDigitalSignatureEx(FILE_FORMAT_CTX *ctx, BIO *hash)
size_t written; size_t written;
BIO *prehash = BIO_new(BIO_f_md()); BIO *prehash = BIO_new(BIO_f_md());
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
if (!BIO_set_md(prehash, ctx->options->md)) { if (!BIO_set_md(prehash, ctx->options->md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(prehash); BIO_free_all(prehash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(prehash, BIO_new(BIO_s_null())); BIO_push(prehash, BIO_new(BIO_s_null()));
if (!msi_prehash_dir(ctx->msi_ctx->dirent, prehash, 1)) { if (!msi_prehash_dir(ctx->msi_ctx->dirent, prehash, 1)) {
@ -2368,8 +2399,8 @@ static int msi_hash_length_get(FILE_FORMAT_CTX *ctx)
/* /*
* Get DigitalSignature and MsiDigitalSignatureEx streams * Get DigitalSignature and MsiDigitalSignatureEx streams
* to check if the signature exists. * to check if the signature exists.
* [in, out] ctx: structure holds input and output datafv * [in, out] ctx: structure holds input and output data
* [returns] 0 on error or 1 on successs * [returns] 0 on error or 1 on success
*/ */
static int msi_check_file(FILE_FORMAT_CTX *ctx) static int msi_check_file(FILE_FORMAT_CTX *ctx)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -66,7 +66,9 @@
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/safestack.h> #include <openssl/safestack.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/store.h>
#include <openssl/ts.h> #include <openssl/ts.h>
#include <openssl/ui.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/x509v3.h> /* X509_PURPOSE */ #include <openssl/x509v3.h> /* X509_PURPOSE */
@ -90,7 +92,9 @@
#ifdef _MSC_VER #ifdef _MSC_VER
/* not WIN32, because strcasecmp exists in MinGW */ /* not WIN32, because strcasecmp exists in MinGW */
#define strcasecmp _stricmp #define strcasecmp _stricmp
#endif #define fseeko _fseeki64
#define ftello _ftelli64
#endif /* _MSC_VER */
#ifdef WIN32 #ifdef WIN32
#define remove_file(filename) _unlink(filename) #define remove_file(filename) _unlink(filename)
@ -242,6 +246,16 @@ typedef enum {
typedef unsigned char u_char; 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 { typedef struct {
char *infile; char *infile;
char *outfile; char *outfile;
@ -254,10 +268,13 @@ typedef struct {
int output_pkcs7; int output_pkcs7;
#ifndef OPENSSL_NO_ENGINE #ifndef OPENSSL_NO_ENGINE
char *p11engine; char *p11engine;
char *p11module; STACK_OF(EngineControl) *engine_ctrls;
char *p11cert;
int login; int login;
#endif /* OPENSSL_NO_ENGINE */ #endif /* OPENSSL_NO_ENGINE */
#if !defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER>=0x30000000L
char *p11module;
char *p11cert;
#endif /* !defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER>=0x30000000L */
int askpass; int askpass;
char *readpass; char *readpass;
char *pass; char *pass;
@ -274,6 +291,7 @@ typedef struct {
char *proxy; char *proxy;
int noverifypeer; int noverifypeer;
int addBlob; int addBlob;
const char *blob_file;
int nest; int nest;
int index; int index;
int ignore_timestamp; int ignore_timestamp;
@ -292,9 +310,9 @@ typedef struct {
int jp; int jp;
#if OPENSSL_VERSION_NUMBER>=0x30000000L #if OPENSSL_VERSION_NUMBER>=0x30000000L
int legacy; int legacy;
char *provider;
#endif /* OPENSSL_VERSION_NUMBER>=0x30000000L */ #endif /* OPENSSL_VERSION_NUMBER>=0x30000000L */
EVP_PKEY *pkey; EVP_PKEY *pkey;
X509 *cert;
STACK_OF(X509) *certs; STACK_OF(X509) *certs;
STACK_OF(X509) *xcerts; STACK_OF(X509) *xcerts;
STACK_OF(X509_CRL) *crls; STACK_OF(X509_CRL) *crls;

21
pe.c
View File

@ -779,11 +779,18 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
uint32_t idx = 0, fileend; uint32_t idx = 0, fileend;
BIO *bhash = BIO_new(BIO_f_md()); 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)) { if (!BIO_set_md(bhash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return 0; /* FAILED */ return 0; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(bhash, BIO_new(BIO_s_null())); BIO_push(bhash, BIO_new(BIO_s_null()));
if (ctx->pe_ctx->sigpos) if (ctx->pe_ctx->sigpos)
fileend = ctx->pe_ctx->sigpos; fileend = ctx->pe_ctx->sigpos;
@ -958,11 +965,18 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
phlen = pphlen * (3 + (int)nsections + (int)(ctx->pe_ctx->fileend / pagesize)); phlen = pphlen * (3 + (int)nsections + (int)(ctx->pe_ctx->fileend / pagesize));
bhash = BIO_new(BIO_f_md()); 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)) { if (!BIO_set_md(bhash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(bhash, BIO_new(BIO_s_null())); BIO_push(bhash, BIO_new(BIO_s_null()));
if (!BIO_write_ex(bhash, ctx->options->indata, ctx->pe_ctx->header_size + 88, &written) if (!BIO_write_ex(bhash, ctx->options->indata, ctx->pe_ctx->header_size + 88, &written)
|| written != ctx->pe_ctx->header_size + 88) { || written != ctx->pe_ctx->header_size + 88) {
@ -1005,6 +1019,10 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
for (l=0; l<rs; l+=pagesize, pi++) { for (l=0; l<rs; l+=pagesize, pi++) {
PUT_UINT32_LE(ro + l, res + pi*pphlen); PUT_UINT32_LE(ro + l, res + pi*pphlen);
bhash = BIO_new(BIO_f_md()); 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)) { if (!BIO_set_md(bhash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(bhash); BIO_free_all(bhash);
@ -1012,6 +1030,9 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
OPENSSL_free(res); OPENSSL_free(res);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(bhash, BIO_new(BIO_s_null())); BIO_push(bhash, BIO_new(BIO_s_null()));
if (rs - l < pagesize) { if (rs - l < pagesize) {
if (!BIO_write_ex(bhash, ctx->options->indata + ro + l, rs - l, &written) if (!BIO_write_ex(bhash, ctx->options->indata + ro + l, rs - l, &written)

View File

@ -8,11 +8,17 @@
#include "helpers.h" #include "helpers.h"
#include "utf.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 { typedef struct {
const char *extension; const char *extension;
comment_style comment; COMMENT_STYLE comment;
} SCRIPT_FORMAT; } SCRIPT_FORMAT;
const SCRIPT_FORMAT supported_formats[] = { const SCRIPT_FORMAT supported_formats[] = {
@ -23,21 +29,24 @@ const SCRIPT_FORMAT supported_formats[] = {
{".psm1", comment_hash}, {".psm1", comment_hash},
{".cdxml", comment_xml}, {".cdxml", comment_xml},
{".mof", comment_c}, {".mof", comment_c},
{".js", comment_js},
{NULL, comment_not_found}, {NULL, comment_not_found},
}; };
const char *signature_header = "SIG # Begin signature block"; #define header_hash "SIG # Begin signature block"
const char *signature_footer = "SIG # End signature block"; #define footer_hash "SIG # End signature block"
#define header_js "Begin signature block"
#define footer_js "End signature block"
typedef struct { typedef struct {
const char *open; const char *open, *close, *header, *footer;
const char *close;
} SCRIPT_COMMENT; } SCRIPT_COMMENT;
const SCRIPT_COMMENT comment_text[] = { const SCRIPT_COMMENT comment_text[] = {
[comment_hash] = {"# ", ""}, [comment_hash] = {"# ", "", header_hash, footer_hash},
[comment_xml] = {"<!-- ", " -->"}, [comment_xml] = {"<!-- ", " -->", header_hash, footer_hash},
[comment_c] = {"/* ", " */"} [comment_c] = {"/* ", " */", header_hash, footer_hash},
[comment_js] = {"// SIG // ", "", header_js, footer_js}
}; };
struct script_ctx_st { 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; u_char *mdbuf;
BIO *hash = BIO_new(BIO_f_md()); 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)) { if (!BIO_set_md(hash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(hash); BIO_free_all(hash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(hash, BIO_new(BIO_s_null())); BIO_push(hash, BIO_new(BIO_s_null()));
if (!script_write_bio(hash, ctx->options->indata, ctx->script_ctx->fileend)) { if (!script_write_bio(hash, ctx->options->indata, ctx->script_ctx->fileend)) {
BIO_free_all(hash); BIO_free_all(hash);
@ -326,8 +342,8 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
const char *close_tag = ctx->script_ctx->comment_text->close; const char *close_tag = ctx->script_ctx->comment_text->close;
size_t open_tag_len = strlen(open_tag); size_t open_tag_len = strlen(open_tag);
size_t close_tag_len = strlen(close_tag); size_t close_tag_len = strlen(close_tag);
size_t signature_header_len = strlen(signature_header); size_t header_len = strlen(ctx->script_ctx->comment_text->header);
size_t signature_footer_len = strlen(signature_footer); size_t footer_len = strlen(ctx->script_ctx->comment_text->footer);
PKCS7 *retval = NULL; PKCS7 *retval = NULL;
if (!script_check_file(ctx)) { if (!script_check_file(ctx)) {
@ -337,6 +353,8 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
if (ctx->script_ctx->utf == 8) { if (ctx->script_ctx->utf == 8) {
base64_len = signature_len; base64_len = signature_len;
base64_data = OPENSSL_malloc(base64_len); base64_data = OPENSSL_malloc(base64_len);
if (!base64_data)
return NULL; /* memory allocation failed */
memcpy(base64_data, signature_data, base64_len); memcpy(base64_data, signature_data, base64_len);
} else { } else {
base64_len = utf16_to_utf8((const void *)signature_data, base64_len = utf16_to_utf8((const void *)signature_data,
@ -364,12 +382,12 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
} }
ptr++; ptr++;
} }
/* process signature_header and signature_footer */ /* process header and footer */
if (ptr + signature_header_len < base64_data + base64_len && if (ptr + header_len < base64_data + base64_len &&
!memcmp(ptr, signature_header, signature_header_len)) !memcmp(ptr, ctx->script_ctx->comment_text->header, header_len))
ptr += signature_header_len; ptr += header_len;
if (ptr + signature_footer_len <= base64_data + base64_len && if (ptr + footer_len <= base64_data + base64_len &&
!memcmp(ptr, signature_footer, signature_footer_len)) !memcmp(ptr, ctx->script_ctx->comment_text->footer, footer_len))
break; /* success */ break; /* success */
/* copy until the closing tag */ /* copy until the closing tag */
@ -531,7 +549,9 @@ static int script_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
(void)BIO_set_close(bio, BIO_NOCLOSE); (void)BIO_set_close(bio, BIO_NOCLOSE);
/* split to individual lines and write to outdata */ /* 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; goto cleanup;
for (i = 0; i < buffer->length; i += 64) { for (i = 0; i < buffer->length; i += 64) {
if (!write_commented(ctx, outdata, buffer->data + i, if (!write_commented(ctx, outdata, buffer->data + i,
@ -539,7 +559,9 @@ static int script_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
goto cleanup; 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; goto cleanup;
/* signtool expects CRLF terminator at the end of the text file */ /* signtool expects CRLF terminator at the end of the text file */
@ -605,7 +627,7 @@ static SCRIPT_CTX *script_ctx_get(char *indata, uint32_t filesize, const SCRIPT_
*ptr && commented_header_len < commented_header_size; *ptr && commented_header_len < commented_header_size;
commented_header_len++) commented_header_len++)
ptr = utf8DecodeRune(ptr, 1, commented_header + 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; *ptr && commented_header_len < commented_header_size;
commented_header_len++) commented_header_len++)
ptr = utf8DecodeRune(ptr, 1, commented_header + commented_header_len); ptr = utf8DecodeRune(ptr, 1, commented_header + commented_header_len);
@ -671,6 +693,8 @@ static int write_commented(FILE_FORMAT_CTX *ctx, BIO *outdata, const char *data,
* - closing tag * - closing tag
* - trailing NUL ("\0") */ * - trailing NUL ("\0") */
line = OPENSSL_malloc(2 + open_tag_len + length + close_tag_len + 1); line = OPENSSL_malloc(2 + open_tag_len + length + close_tag_len + 1);
if (!line)
return 0; /* memory allocation failed */
strcpy(line, "\r\n"); strcpy(line, "\r\n");
strcat(line, open_tag); strcat(line, open_tag);
memcpy(line + 2 + open_tag_len, data, length); memcpy(line + 2 + open_tag_len, data, length);
@ -782,12 +806,18 @@ static BIO *script_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
fileend = ctx->script_ctx->sigpos; fileend = ctx->script_ctx->sigpos;
else else
fileend = ctx->script_ctx->fileend; 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)) { if (!BIO_set_md(hash, md)) {
fprintf(stderr, "Unable to set the message digest of BIO\n"); fprintf(stderr, "Unable to set the message digest of BIO\n");
BIO_free_all(hash); BIO_free_all(hash);
return NULL; /* FAILED */ return NULL; /* FAILED */
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
BIO_push(hash, BIO_new(BIO_s_null())); BIO_push(hash, BIO_new(BIO_s_null()));
if (!script_digest_convert(hash, ctx, fileend)) { if (!script_digest_convert(hash, ctx, fileend)) {
fprintf(stderr, "Unable calc a message digest value\n"); fprintf(stderr, "Unable calc a message digest value\n");

View File

@ -1,5 +1,5 @@
#!/usr/bin/python3 #!/usr/bin/python3
"""Implementation of a HTTP client""" """Implementation of an HTTP client"""
import os import os
import sys import sys

View File

@ -29,7 +29,7 @@ def main() -> None:
# all exceptions are critical # all exceptions are critical
print(err, file=sys.stderr) print(err, file=sys.stderr)
else: else:
print("Usage:\n\t{} COMMAND [ARG]...'".format(sys.argv[0]), file=sys.stderr) print("Usage:\n\t{} COMMAND [ARG]...".format(sys.argv[0]), file=sys.stderr)
sys.exit(1) sys.exit(1)

Binary file not shown.

1
tests/files/unsigned.js Normal file
View File

@ -0,0 +1 @@
console.log("Hello, world!");

View File

@ -4,11 +4,60 @@
import os import os
import datetime import datetime
import cryptography import cryptography
from cryptography import x509
from cryptography.x509.oid import NameOID # Explicit imports of cryptography submodules
from cryptography.hazmat.primitives import hashes import cryptography.x509
from cryptography.hazmat.primitives import serialization import cryptography.x509.oid
from cryptography.hazmat.primitives.asymmetric import rsa 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() RESULT_PATH = os.getcwd()
CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/") CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
@ -28,25 +77,25 @@ class X509Extensions():
self.port = cdp_port self.port = cdp_port
self.name = cdp_name self.name = cdp_name
def create_x509_name(self, common_name) -> x509.Name: def create_x509_name(self, common_name) -> Name:
"""Return x509.Name""" """Return x509.Name"""
return x509.Name( return Name(
[ [
x509.NameAttribute(NameOID.COUNTRY_NAME, "PL"), NameAttribute(NameOID.COUNTRY_NAME, "PL"),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Mazovia Province"), NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Mazovia Province"),
x509.NameAttribute(NameOID.LOCALITY_NAME, "Warsaw"), NameAttribute(NameOID.LOCALITY_NAME, "Warsaw"),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "osslsigncode"), NameAttribute(NameOID.ORGANIZATION_NAME, "osslsigncode"),
x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, self.unit_name), NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, self.unit_name),
x509.NameAttribute(NameOID.COMMON_NAME, common_name) NameAttribute(NameOID.COMMON_NAME, common_name)
] ]
) )
def create_x509_crldp(self) -> x509.CRLDistributionPoints: def create_x509_crldp(self) -> CRLDistributionPoints:
"""Return x509.CRLDistributionPoints""" """Return x509.CRLDistributionPoints"""
return x509.CRLDistributionPoints( return CRLDistributionPoints(
[ [
x509.DistributionPoint( DistributionPoint(
full_name=[x509.UniformResourceIdentifier( full_name=[UniformResourceIdentifier(
"http://127.0.0.1:" + str(self.port) + "/" + str(self.name)) "http://127.0.0.1:" + str(self.port) + "/" + str(self.name))
], ],
relative_name=None, relative_name=None,
@ -56,10 +105,10 @@ class X509Extensions():
] ]
) )
def create_x509_name_constraints(self) -> x509.NameConstraints: def create_x509_name_constraints(self) -> NameConstraints:
"""Return x509.NameConstraints""" """Return x509.NameConstraints"""
return x509.NameConstraints( return NameConstraints(
permitted_subtrees = [x509.DNSName('test.com'), x509.DNSName('test.org')], permitted_subtrees = [DNSName('test.com'), DNSName('test.org')],
excluded_subtrees = None excluded_subtrees = None
) )
@ -71,14 +120,14 @@ class IntermediateCACertificate(X509Extensions):
self.issuer_key = issuer_key self.issuer_key = issuer_key
super().__init__("Certification Authority", 0, None) super().__init__("Certification Authority", 0, None)
def make_cert(self) -> (x509.Certificate, rsa.RSAPrivateKey): def make_cert(self) -> (Certificate, RSAPrivateKey):
"""Generate intermediate CA certificate""" """Generate intermediate CA certificate"""
key = rsa.generate_private_key(public_exponent=65537, key_size=2048) key = generate_private_key(public_exponent=65537, key_size=2048)
key_public = key.public_key() key_public = key.public_key()
authority_key = x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier( authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
self.issuer_cert.extensions.get_extension_for_class(x509.SubjectKeyIdentifier).value self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
) )
key_usage = x509.KeyUsage( key_usage = KeyUsage(
digital_signature=True, digital_signature=True,
content_commitment=False, content_commitment=False,
key_encipherment=False, key_encipherment=False,
@ -90,22 +139,22 @@ class IntermediateCACertificate(X509Extensions):
decipher_only=False decipher_only=False
) )
cert = ( cert = (
x509.CertificateBuilder() CertificateBuilder()
.subject_name(self.create_x509_name("Intermediate CA")) .subject_name(self.create_x509_name("Intermediate CA"))
.issuer_name(self.issuer_cert.subject) .issuer_name(self.issuer_cert.subject)
.public_key(key_public) .public_key(key_public)
.serial_number(x509.random_serial_number()) .serial_number(random_serial_number())
.not_valid_before(date_20180101) .not_valid_before(date_20180101)
.not_valid_after(date_20180101 + datetime.timedelta(days=7300)) .not_valid_after(date_20180101 + datetime.timedelta(days=7300))
.add_extension(x509.BasicConstraints(ca=True, path_length=0), critical=True) .add_extension(BasicConstraints(ca=True, path_length=0), critical=True)
.add_extension(x509.SubjectKeyIdentifier.from_public_key(key_public), critical=False) .add_extension(SubjectKeyIdentifier.from_public_key(key_public), critical=False)
.add_extension(authority_key, critical=False) .add_extension(authority_key, critical=False)
.add_extension(key_usage, critical=True) .add_extension(key_usage, critical=True)
.sign(self.issuer_key, hashes.SHA256()) .sign(self.issuer_key, SHA256())
) )
file_path=os.path.join(CERTS_PATH, "intermediateCA.pem") file_path=os.path.join(CERTS_PATH, "intermediateCA.pem")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(cert.public_bytes(encoding=serialization.Encoding.PEM)) file.write(cert.public_bytes(encoding=Encoding.PEM))
return cert, key return cert, key
@ -114,7 +163,7 @@ class RootCACertificate(X509Extensions):
"""Base class for Root CA certificate""" """Base class for Root CA certificate"""
def __init__(self): def __init__(self):
self.key_usage = x509.KeyUsage( self.key_usage = KeyUsage(
digital_signature=True, digital_signature=True,
content_commitment=False, content_commitment=False,
key_encipherment=False, key_encipherment=False,
@ -127,7 +176,7 @@ class RootCACertificate(X509Extensions):
) )
super().__init__("Certification Authority", 0, None) super().__init__("Certification Authority", 0, None)
def make_cert(self) -> (x509.Certificate, rsa.RSAPrivateKey): def make_cert(self) -> (Certificate, RSAPrivateKey):
"""Generate CA certificates""" """Generate CA certificates"""
ca_root, root_key = self.make_ca_cert("Trusted Root CA", "CAroot.pem") 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") ca_cert, ca_key = self.make_ca_cert("Root CA", "CACert.pem")
@ -136,52 +185,52 @@ class RootCACertificate(X509Extensions):
def make_ca_cert(self, common_name, file_name) -> None: def make_ca_cert(self, common_name, file_name) -> None:
"""Generate self-signed root CA certificate""" """Generate self-signed root CA certificate"""
ca_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) ca_key = generate_private_key(public_exponent=65537, key_size=2048)
ca_public = ca_key.public_key() ca_public = ca_key.public_key()
authority_key = x509.AuthorityKeyIdentifier.from_issuer_public_key(ca_public) authority_key = AuthorityKeyIdentifier.from_issuer_public_key(ca_public)
name = self.create_x509_name(common_name) name = self.create_x509_name(common_name)
ca_cert = ( ca_cert = (
x509.CertificateBuilder() CertificateBuilder()
.subject_name(name) .subject_name(name)
.issuer_name(name) .issuer_name(name)
.public_key(ca_public) .public_key(ca_public)
.serial_number(x509.random_serial_number()) .serial_number(random_serial_number())
.not_valid_before(date_20170101) .not_valid_before(date_20170101)
.not_valid_after(date_20170101 + datetime.timedelta(days=7300)) .not_valid_after(date_20170101 + datetime.timedelta(days=7300))
.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True) .add_extension(BasicConstraints(ca=True, path_length=None), critical=True)
.add_extension(x509.SubjectKeyIdentifier.from_public_key(ca_public), critical=False) .add_extension(SubjectKeyIdentifier.from_public_key(ca_public), critical=False)
.add_extension(authority_key, critical=False) .add_extension(authority_key, critical=False)
.add_extension(self.key_usage, critical=True) .add_extension(self.key_usage, critical=True)
.sign(ca_key, hashes.SHA256()) .sign(ca_key, SHA256())
) )
file_path=os.path.join(CERTS_PATH, file_name) file_path=os.path.join(CERTS_PATH, file_name)
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(ca_cert.public_bytes(encoding=serialization.Encoding.PEM)) file.write(ca_cert.public_bytes(encoding=Encoding.PEM))
return ca_cert, ca_key return ca_cert, ca_key
def make_cross_cert(self, ca_root, root_key, ca_cert, ca_key) -> None: def make_cross_cert(self, ca_root, root_key, ca_cert, ca_key) -> None:
"""Generate cross-signed root CA certificate""" """Generate cross-signed root CA certificate"""
ca_public = ca_key.public_key() ca_public = ca_key.public_key()
authority_key = x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier( authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
ca_root.extensions.get_extension_for_class(x509.SubjectKeyIdentifier).value ca_root.extensions.get_extension_for_class(SubjectKeyIdentifier).value
) )
ca_cross = ( ca_cross = (
x509.CertificateBuilder() CertificateBuilder()
.subject_name(ca_cert.subject) .subject_name(ca_cert.subject)
.issuer_name(ca_root.subject) .issuer_name(ca_root.subject)
.public_key(ca_public) .public_key(ca_public)
.serial_number(ca_cert.serial_number) .serial_number(ca_cert.serial_number)
.not_valid_before(date_20180101) .not_valid_before(date_20180101)
.not_valid_after(date_20180101 + datetime.timedelta(days=7300)) .not_valid_after(date_20180101 + datetime.timedelta(days=7300))
.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True) .add_extension(BasicConstraints(ca=True, path_length=None), critical=True)
.add_extension(x509.SubjectKeyIdentifier.from_public_key(ca_public), critical=False) .add_extension(SubjectKeyIdentifier.from_public_key(ca_public), critical=False)
.add_extension(authority_key, critical=False) .add_extension(authority_key, critical=False)
.add_extension(self.key_usage, critical=True) .add_extension(self.key_usage, critical=True)
.sign(root_key, hashes.SHA256()) .sign(root_key, SHA256())
) )
file_path=os.path.join(CERTS_PATH, "CAcross.pem") file_path=os.path.join(CERTS_PATH, "CAcross.pem")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(ca_cross.public_bytes(encoding=serialization.Encoding.PEM)) file.write(ca_cross.public_bytes(encoding=Encoding.PEM))
def write_key(self, key, file_name) -> None: def write_key(self, key, file_name) -> None:
"""Write a private RSA key""" """Write a private RSA key"""
@ -194,27 +243,27 @@ class RootCACertificate(X509Extensions):
file_path = os.path.join(CERTS_PATH, file_name + "p.pem") file_path = os.path.join(CERTS_PATH, file_name + "p.pem")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(key.private_bytes( file.write(key.private_bytes(
encoding=serialization.Encoding.PEM, encoding=Encoding.PEM,
format=serialization.PrivateFormat.PKCS8, format=PrivateFormat.PKCS8,
encryption_algorithm=serialization.BestAvailableEncryption(PASSWORD.encode()) encryption_algorithm=BestAvailableEncryption(PASSWORD.encode())
) )
) )
# Write decrypted key in PEM format # Write decrypted key in PEM format
file_path = os.path.join(CERTS_PATH, file_name + ".pem") file_path = os.path.join(CERTS_PATH, file_name + ".pem")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(key.private_bytes( file.write(key.private_bytes(
encoding=serialization.Encoding.PEM, encoding=Encoding.PEM,
format=serialization.PrivateFormat.PKCS8, format=PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption() encryption_algorithm=NoEncryption()
) )
) )
# Write the key in DER format # Write the key in DER format
file_path = os.path.join(CERTS_PATH, file_name + ".der") file_path = os.path.join(CERTS_PATH, file_name + ".der")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(key.private_bytes( file.write(key.private_bytes(
encoding=serialization.Encoding.DER, encoding=Encoding.DER,
format=serialization.PrivateFormat.PKCS8, format=PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption() encryption_algorithm=NoEncryption()
) )
) )
@ -225,13 +274,13 @@ class TSARootCACertificate(X509Extensions):
def __init__(self): def __init__(self):
super().__init__("Timestamp Authority Root CA", 0, None) super().__init__("Timestamp Authority Root CA", 0, None)
def make_cert(self) -> (x509.Certificate, rsa.RSAPrivateKey): def make_cert(self) -> (Certificate, RSAPrivateKey):
"""Generate a Time Stamp Authority certificate""" """Generate a Time Stamp Authority certificate"""
ca_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) ca_key = generate_private_key(public_exponent=65537, key_size=2048)
ca_public = ca_key.public_key() ca_public = ca_key.public_key()
authority_key = x509.AuthorityKeyIdentifier.from_issuer_public_key(ca_public) authority_key = AuthorityKeyIdentifier.from_issuer_public_key(ca_public)
name = self.create_x509_name("TSA Root CA") name = self.create_x509_name("TSA Root CA")
key_usage = x509.KeyUsage( key_usage = KeyUsage(
digital_signature=False, digital_signature=False,
content_commitment=False, content_commitment=False,
key_encipherment=False, key_encipherment=False,
@ -243,22 +292,22 @@ class TSARootCACertificate(X509Extensions):
decipher_only=False decipher_only=False
) )
ca_cert = ( ca_cert = (
x509.CertificateBuilder() CertificateBuilder()
.subject_name(name) .subject_name(name)
.issuer_name(name) .issuer_name(name)
.public_key(ca_public) .public_key(ca_public)
.serial_number(x509.random_serial_number()) .serial_number(random_serial_number())
.not_valid_before(date_20170101) .not_valid_before(date_20170101)
.not_valid_after(date_20170101 + datetime.timedelta(days=7300)) .not_valid_after(date_20170101 + datetime.timedelta(days=7300))
.add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True) .add_extension(BasicConstraints(ca=True, path_length=None), critical=True)
.add_extension(x509.SubjectKeyIdentifier.from_public_key(ca_public), critical=False) .add_extension(SubjectKeyIdentifier.from_public_key(ca_public), critical=False)
.add_extension(authority_key, critical=False) .add_extension(authority_key, critical=False)
.add_extension(key_usage, critical=True) .add_extension(key_usage, critical=True)
.sign(ca_key, hashes.SHA256()) .sign(ca_key, SHA256())
) )
file_path=os.path.join(CERTS_PATH, "TSACA.pem") file_path=os.path.join(CERTS_PATH, "TSACA.pem")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(ca_cert.public_bytes(encoding=serialization.Encoding.PEM)) file.write(ca_cert.public_bytes(encoding=Encoding.PEM))
return ca_cert, ca_key return ca_cert, ca_key
@ -267,14 +316,14 @@ class TSARootCACertificate(X509Extensions):
file_path = os.path.join(CERTS_PATH, file_name + ".key") file_path = os.path.join(CERTS_PATH, file_name + ".key")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(key.private_bytes( file.write(key.private_bytes(
encoding=serialization.Encoding.PEM, encoding=Encoding.PEM,
format=serialization.PrivateFormat.PKCS8, format=PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption() encryption_algorithm=NoEncryption()
) )
) )
class Certificate(X509Extensions): class LeafCertificate(X509Extensions):
"""Base class for a leaf certificate""" """Base class for a leaf certificate"""
def __init__(self, issuer_cert, issuer_key, unit_name, common_name, cdp_port, cdp_name): def __init__(self, issuer_cert, issuer_key, unit_name, common_name, cdp_port, cdp_name):
@ -284,78 +333,78 @@ class Certificate(X509Extensions):
self.common_name = common_name self.common_name = common_name
super().__init__(unit_name, cdp_port, cdp_name) super().__init__(unit_name, cdp_port, cdp_name)
def make_cert(self, public_key, not_before, days) -> x509.Certificate: def make_cert(self, public_key, not_before, days) -> Certificate:
"""Generate a leaf certificate""" """Generate a leaf certificate"""
authority_key = x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier( authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
self.issuer_cert.extensions.get_extension_for_class(x509.SubjectKeyIdentifier).value self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
) )
extended_key_usage = x509.ExtendedKeyUsage( extended_key_usage = ExtendedKeyUsage(
[x509.oid.ExtendedKeyUsageOID.CODE_SIGNING] [ExtendedKeyUsageOID.CODE_SIGNING]
) )
cert = ( cert = (
x509.CertificateBuilder() CertificateBuilder()
.subject_name(self.create_x509_name(self.common_name)) .subject_name(self.create_x509_name(self.common_name))
.issuer_name(self.issuer_cert.subject) .issuer_name(self.issuer_cert.subject)
.public_key(public_key) .public_key(public_key)
.serial_number(x509.random_serial_number()) .serial_number(random_serial_number())
.not_valid_before(not_before) .not_valid_before(not_before)
.not_valid_after(not_before + datetime.timedelta(days=days)) .not_valid_after(not_before + datetime.timedelta(days=days))
.add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=False) .add_extension(BasicConstraints(ca=False, path_length=None), critical=False)
.add_extension(x509.SubjectKeyIdentifier.from_public_key(public_key), critical=False) .add_extension(SubjectKeyIdentifier.from_public_key(public_key), critical=False)
.add_extension(authority_key, critical=False) .add_extension(authority_key, critical=False)
.add_extension(extended_key_usage, critical=False) .add_extension(extended_key_usage, critical=False)
.add_extension(self.create_x509_crldp(), critical=False) .add_extension(self.create_x509_crldp(), critical=False)
.sign(self.issuer_key, hashes.SHA256()) .sign(self.issuer_key, SHA256())
) )
# Write PEM file and attach intermediate certificate # Write PEM file and attach intermediate certificate
file_path = os.path.join(CERTS_PATH, self.common_name + ".pem") file_path = os.path.join(CERTS_PATH, self.common_name + ".pem")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(cert.public_bytes(encoding=serialization.Encoding.PEM)) file.write(cert.public_bytes(encoding=Encoding.PEM))
file.write(self.issuer_cert.public_bytes(encoding=serialization.Encoding.PEM)) file.write(self.issuer_cert.public_bytes(encoding=Encoding.PEM))
return cert return cert
def revoke_cert(self, serial_number, file_name) -> None: def revoke_cert(self, serial_number, file_name) -> None:
"""Revoke a certificate""" """Revoke a certificate"""
revoked = ( revoked = (
x509.RevokedCertificateBuilder() RevokedCertificateBuilder()
.serial_number(serial_number) .serial_number(serial_number)
.revocation_date(date_20190101) .revocation_date(date_20190101)
.add_extension(x509.CRLReason(x509.ReasonFlags.superseded), critical=False) .add_extension(CRLReason(ReasonFlags.superseded), critical=False)
.build() .build()
) )
# Generate CRL # Generate CRL
authority_key = x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier( authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
self.issuer_cert.extensions.get_extension_for_class(x509.SubjectKeyIdentifier).value self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
) )
crl = ( crl = (
x509.CertificateRevocationListBuilder() CertificateRevocationListBuilder()
.issuer_name(self.issuer_cert.subject) .issuer_name(self.issuer_cert.subject)
.last_update(date_20190101) .last_update(date_20190101)
.next_update(date_20190101 + datetime.timedelta(days=7300)) .next_update(date_20190101 + datetime.timedelta(days=7300))
.add_extension(authority_key, critical=False) .add_extension(authority_key, critical=False)
.add_extension(x509.CRLNumber(4097), critical=False) .add_extension(CRLNumber(4097), critical=False)
.add_revoked_certificate(revoked) .add_revoked_certificate(revoked)
.sign(self.issuer_key, hashes.SHA256()) .sign(self.issuer_key, SHA256())
) )
# Write CRL file # Write CRL file
file_path = os.path.join(CERTS_PATH, file_name + ".pem") file_path = os.path.join(CERTS_PATH, file_name + ".pem")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(crl.public_bytes(encoding=serialization.Encoding.PEM)) file.write(crl.public_bytes(encoding=Encoding.PEM))
file_path = os.path.join(CERTS_PATH, file_name + ".der") file_path = os.path.join(CERTS_PATH, file_name + ".der")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(crl.public_bytes(encoding=serialization.Encoding.DER)) file.write(crl.public_bytes(encoding=Encoding.DER))
class LeafCACertificate(Certificate): class LeafCACertificate(LeafCertificate):
"""Base class for a leaf certificate""" """Base class for a leaf certificate"""
def __init__(self, issuer_cert, issuer_key, common, cdp_port): def __init__(self, issuer_cert, issuer_key, common, cdp_port):
super().__init__(issuer_cert, issuer_key, "CSP", common, cdp_port, "intermediateCA") super().__init__(issuer_cert, issuer_key, "CSP", common, cdp_port, "intermediateCA")
class LeafTSACertificate(Certificate): class LeafTSACertificate(LeafCertificate):
"""Base class for a TSA leaf certificate""" """Base class for a TSA leaf certificate"""
def __init__(self, issuer_cert, issuer_key, common, cdp_port): def __init__(self, issuer_cert, issuer_key, common, cdp_port):
@ -364,40 +413,40 @@ class LeafTSACertificate(Certificate):
self.common_name = common self.common_name = common
super().__init__(issuer_cert, issuer_key, "Timestamp Root CA", common, cdp_port, "TSACA") super().__init__(issuer_cert, issuer_key, "Timestamp Root CA", common, cdp_port, "TSACA")
def make_cert(self, public_key, not_before, days) -> x509.Certificate: def make_cert(self, public_key, not_before, days) -> Certificate:
"""Generate a TSA leaf certificate""" """Generate a TSA leaf certificate"""
authority_key = x509.AuthorityKeyIdentifier.from_issuer_subject_key_identifier( authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
self.issuer_cert.extensions.get_extension_for_class(x509.SubjectKeyIdentifier).value self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
) )
# The TSA signing certificate must have exactly one extended key usage # The TSA signing certificate must have exactly one extended key usage
# assigned to it: timeStamping. The extended key usage must also be critical, # assigned to it: timeStamping. The extended key usage must also be critical,
# otherwise the certificate is going to be refused. # otherwise the certificate is going to be refused.
extended_key_usage = x509.ExtendedKeyUsage( extended_key_usage = ExtendedKeyUsage(
[x509.oid.ExtendedKeyUsageOID.TIME_STAMPING] [ExtendedKeyUsageOID.TIME_STAMPING]
) )
cert = ( cert = (
x509.CertificateBuilder() CertificateBuilder()
.subject_name(self.create_x509_name(self.common_name)) .subject_name(self.create_x509_name(self.common_name))
.issuer_name(self.issuer_cert.subject) .issuer_name(self.issuer_cert.subject)
.public_key(public_key) .public_key(public_key)
.serial_number(x509.random_serial_number()) .serial_number(random_serial_number())
.not_valid_before(not_before) .not_valid_before(not_before)
.not_valid_after(not_before + datetime.timedelta(days=days)) .not_valid_after(not_before + datetime.timedelta(days=days))
.add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True) .add_extension(BasicConstraints(ca=False, path_length=None), critical=True)
.add_extension(x509.SubjectKeyIdentifier.from_public_key(public_key), critical=False) .add_extension(SubjectKeyIdentifier.from_public_key(public_key), critical=False)
.add_extension(authority_key, critical=False) .add_extension(authority_key, critical=False)
.add_extension(extended_key_usage, critical=True) .add_extension(extended_key_usage, critical=True)
.add_extension(self.create_x509_crldp(), critical=False) .add_extension(self.create_x509_crldp(), critical=False)
.add_extension(self.create_x509_name_constraints(), critical=False) .add_extension(self.create_x509_name_constraints(), critical=False)
.sign(self.issuer_key, hashes.SHA256()) .sign(self.issuer_key, SHA256())
) )
# Write PEM file and attach intermediate certificate # Write PEM file and attach intermediate certificate
file_path = os.path.join(CERTS_PATH, self.common_name + ".pem") file_path = os.path.join(CERTS_PATH, self.common_name + ".pem")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(cert.public_bytes(encoding=serialization.Encoding.PEM)) file.write(cert.public_bytes(encoding=Encoding.PEM))
file.write(self.issuer_cert.public_bytes(encoding=serialization.Encoding.PEM)) file.write(self.issuer_cert.public_bytes(encoding=Encoding.PEM))
return cert return cert
@ -433,7 +482,7 @@ class CertificateMaker():
issuer_cert, issuer_key = intermediate.make_cert() issuer_cert, issuer_key = intermediate.make_cert()
# Generate private RSA key # Generate private RSA key
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) private_key = generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key() public_key = private_key.public_key()
root.write_key(key=private_key, file_name="key") root.write_key(key=private_key, file_name="key")
@ -460,7 +509,7 @@ class CertificateMaker():
# Write DER file and attach intermediate certificate # Write DER file and attach intermediate certificate
file_path = os.path.join(CERTS_PATH, "cert.der") file_path = os.path.join(CERTS_PATH, "cert.der")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(cert.public_bytes(encoding=serialization.Encoding.DER)) file.write(cert.public_bytes(encoding=Encoding.DER))
def make_tsa_certs(self): def make_tsa_certs(self):
"""Make test TSA certificates""" """Make test TSA certificates"""
@ -470,7 +519,7 @@ class CertificateMaker():
issuer_cert, issuer_key = root.make_cert() issuer_cert, issuer_key = root.make_cert()
# Generate private RSA key # Generate private RSA key
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) private_key = generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key() public_key = private_key.public_key()
root.write_key(key=private_key, file_name="TSA") root.write_key(key=private_key, file_name="TSA")
@ -486,8 +535,8 @@ class CertificateMaker():
# Save the chain to be included in the TSA response # Save the chain to be included in the TSA response
file_path = os.path.join(CERTS_PATH, "tsa-chain.pem") file_path = os.path.join(CERTS_PATH, "tsa-chain.pem")
with open(file_path, mode="wb") as file: with open(file_path, mode="wb") as file:
file.write(cert.public_bytes(encoding=serialization.Encoding.PEM)) file.write(cert.public_bytes(encoding=Encoding.PEM))
file.write(issuer_cert.public_bytes(encoding=serialization.Encoding.PEM)) file.write(issuer_cert.public_bytes(encoding=Encoding.PEM))
def write_pkcs12_container(self, cert, key, issuer) -> None: def write_pkcs12_container(self, cert, key, issuer) -> None:
@ -499,16 +548,16 @@ class CertificateMaker():
# and private key encryption: DES-EDE3-CBC (vel 3DES_CBC) # and private key encryption: DES-EDE3-CBC (vel 3DES_CBC)
# pylint: disable=no-member # pylint: disable=no-member
encryption = ( encryption = (
serialization.PrivateFormat.PKCS12.encryption_builder() PrivateFormat.PKCS12.encryption_builder()
.key_cert_algorithm(serialization.pkcs12.PBES.PBESv1SHA1And3KeyTripleDESCBC) .key_cert_algorithm(PBES.PBESv1SHA1And3KeyTripleDESCBC)
.kdf_rounds(5000) .kdf_rounds(5000)
.build(PASSWORD.encode()) .build(PASSWORD.encode())
) )
else: else:
encryption = serialization.BestAvailableEncryption(PASSWORD.encode()) encryption = BestAvailableEncryption(PASSWORD.encode())
# Generate PKCS#12 struct # Generate PKCS#12 struct
pkcs12 = serialization.pkcs12.serialize_key_and_certificates( pkcs12 = serialize_key_and_certificates(
name=b'certificate', name=b'certificate',
key=key, key=key,
cert=cert, cert=cert,

View File

@ -1,5 +1,5 @@
#!/usr/bin/python3 #!/usr/bin/python3
"""Implementation of a HTTP server""" """Implementation of an HTTP server"""
import argparse import argparse
import os import os
@ -17,7 +17,7 @@ CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
CONF_PATH = os.path.join(RESULT_PATH, "./Testing/conf/") CONF_PATH = os.path.join(RESULT_PATH, "./Testing/conf/")
LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/") LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/")
REQUEST = os.path.join(FILES_PATH, "./jreq.tsq") REQUEST = os.path.join(FILES_PATH, "./jreq.tsq")
RESPONS = os.path.join(FILES_PATH, "./jresp.tsr") RESPONSE = os.path.join(FILES_PATH, "./jresp.tsr")
OPENSSL_CONF = os.path.join(CONF_PATH, "./openssl_tsa.cnf") OPENSSL_CONF = os.path.join(CONF_PATH, "./openssl_tsa.cnf")
SERVER_LOG = os.path.join(LOGS_PATH, "./server.log") SERVER_LOG = os.path.join(LOGS_PATH, "./server.log")
URL_LOG = os.path.join(LOGS_PATH, "./url.log") URL_LOG = os.path.join(LOGS_PATH, "./url.log")
@ -26,7 +26,7 @@ OPENSSL_TS = ["openssl", "ts",
"-reply", "-config", OPENSSL_CONF, "-reply", "-config", OPENSSL_CONF,
"-passin", "pass:passme", "-passin", "pass:passme",
"-queryfile", REQUEST, "-queryfile", REQUEST,
"-out", RESPONS] "-out", RESPONSE]
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer): class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
@ -86,7 +86,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
self.send_header("Content-type", "application/timestamp-reply") self.send_header("Content-type", "application/timestamp-reply")
self.end_headers() self.end_headers()
resp_data = b'' resp_data = b''
with open(RESPONS, mode="rb") as file: with open(RESPONSE, mode="rb") as file:
resp_data = file.read() resp_data = file.read()
self.wfile.write(resp_data) self.wfile.write(resp_data)

View File

@ -1,5 +1,5 @@
#!/usr/bin/python3 #!/usr/bin/python3
"""Windows: Implementation of a HTTP server""" """Windows: Implementation of an HTTP server"""
import argparse import argparse
import os import os
@ -16,7 +16,7 @@ CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
CONF_PATH = os.path.join(RESULT_PATH, "./Testing/conf/") CONF_PATH = os.path.join(RESULT_PATH, "./Testing/conf/")
LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/") LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/")
REQUEST = os.path.join(FILES_PATH, "./jreq.tsq") REQUEST = os.path.join(FILES_PATH, "./jreq.tsq")
RESPONS = os.path.join(FILES_PATH, "./jresp.tsr") RESPONSE = os.path.join(FILES_PATH, "./jresp.tsr")
OPENSSL_CONF = os.path.join(CONF_PATH, "./openssl_tsa.cnf") OPENSSL_CONF = os.path.join(CONF_PATH, "./openssl_tsa.cnf")
SERVER_LOG = os.path.join(LOGS_PATH, "./server.log") SERVER_LOG = os.path.join(LOGS_PATH, "./server.log")
URL_LOG = os.path.join(LOGS_PATH, "./url.log") URL_LOG = os.path.join(LOGS_PATH, "./url.log")
@ -26,7 +26,7 @@ OPENSSL_TS = ["openssl", "ts",
"-reply", "-config", OPENSSL_CONF, "-reply", "-config", OPENSSL_CONF,
"-passin", "pass:passme", "-passin", "pass:passme",
"-queryfile", REQUEST, "-queryfile", REQUEST,
"-out", RESPONS] "-out", RESPONSE]
class RequestHandler(SimpleHTTPRequestHandler): class RequestHandler(SimpleHTTPRequestHandler):
@ -82,7 +82,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
self.send_header("Content-type", "application/timestamp-reply") self.send_header("Content-type", "application/timestamp-reply")
self.end_headers() self.end_headers()
resp_data = b'' resp_data = b''
with open(RESPONS, mode="rb") as file: with open(RESPONSE, mode="rb") as file:
resp_data = file.read() resp_data = file.read()
self.wfile.write(resp_data) self.wfile.write(resp_data)
except Exception as err: # pylint: disable=broad-except except Exception as err: # pylint: disable=broad-except

View File

@ -55,3 +55,6 @@ CATATTR1=0x11010001:OSAttr:2:6.0
<HASH>MOFfile=..\files\unsigned.mof <HASH>MOFfile=..\files\unsigned.mof
<HASH>MOFfileATTR1=0x11010001:File:unsigned.mof <HASH>MOFfileATTR1=0x11010001:File:unsigned.mof
<HASH>JSfile=..\files\unsigned.js
<HASH>JSfileATTR1=0x11010001:File:unsigned.js

View File

@ -51,7 +51,7 @@ def clear_catalog(certs_path) -> None:
file.write(random_hex) file.write(random_hex)
def main() -> None: def main() -> None:
"""Wait for all tests certificate, compute leafhash""" """Wait for all test certificates and compute leaf hash"""
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument(