mirror of
https://github.com/mtrojnar/osslsigncode
synced 2026-06-08 16:13:39 +00:00
Compare commits
137 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bf209e0fc8 | |||
| 68a6826cd1 | |||
| ea5d15862d | |||
| bdde95635f | |||
| d0ef178a9a | |||
| e126ab3e4a | |||
| a1fb6600fb | |||
| 8227c68ceb | |||
| c988b48063 | |||
| 6cf70b4af2 | |||
| 97a9ade6ec | |||
| f2f33bb131 | |||
| 202b2c2866 | |||
| 2a5409b7c4 | |||
| 87bce8e372 | |||
| f7ace57c81 | |||
| 92f8761b47 | |||
| 09d3312fd9 | |||
| 9d02a20aec | |||
| f190ec5d87 | |||
| 4b30d6be28 | |||
| fac8164622 | |||
| cbee1e723c | |||
| f90327df09 | |||
| f3a590be69 | |||
| 6631a5f10b | |||
| 9924f0c085 | |||
| 7d85ac5f04 | |||
| feebbcd4d9 | |||
| d787541107 | |||
| 6390ae2746 | |||
| a472d7fbff | |||
| 27172a07ca | |||
| d77ddb9443 | |||
| 988f72249b | |||
| c23f92ca68 | |||
| 842bd94aaf | |||
| 1d72c3da8c | |||
| d792e8d0db | |||
| bbdfc1d98a | |||
| 5ac11e9f58 | |||
| 55541c6ace | |||
| 8329a14f8b | |||
| 343b0af1fe | |||
| d440f32780 | |||
| fb082942d2 | |||
| 025e808c01 | |||
| 23b6d7782c | |||
| 4c3a1e887c | |||
| 97ee163e31 | |||
| dfc3e46a77 | |||
| ff9a6d3593 | |||
| e81b08e02d | |||
| 0c85d54800 | |||
| 772bc22c94 | |||
| d65a2b5286 | |||
| a3fcf41e1a | |||
| e00caac3db | |||
| dd9b81281f | |||
| 6b56aef073 | |||
| 52bfff5756 | |||
| 4d52e9cc4b | |||
| 3292b02650 | |||
| 50c23daa4c | |||
| 9b7dae4572 | |||
| 62438908cb | |||
| 829e770250 | |||
| a6c7c25dae | |||
| 10ca3a06ea | |||
| 9ea7e85468 | |||
| 68e8845ef1 | |||
| 475ea95ba3 | |||
| d352dcc1a5 | |||
| 7734382436 | |||
| d425d8bf25 | |||
| 4568c890cc | |||
| 4bd167a8be | |||
| e7405fa839 | |||
| 776e2ec7b6 | |||
| 838aaaee8d | |||
| e8f19a6efe | |||
| 3a8e25e5bb | |||
| 7d1b460dfe | |||
| bc3e9e2172 | |||
| 21bce757ef | |||
| 6a43f62835 | |||
| 8780e6f8e4 | |||
| 78a23caa54 | |||
| d92927aff4 | |||
| 4f412b5989 | |||
| e6f3ff631d | |||
| 09135aabb8 | |||
| de983e680f | |||
| dc827b94e5 | |||
| 40ce811701 | |||
| db5b4c4dc0 | |||
| 4ee429792d | |||
| 27686c0b0c | |||
| 21133f9c3b | |||
| 64305d6415 | |||
| 4dd836bab1 | |||
| f57c213207 | |||
| 76ee550c9d | |||
| 2b3228d549 | |||
| bad6e96e0f | |||
| 3c8c74a8c3 | |||
| 771014a41e | |||
| 476168e09e | |||
| be4f010535 | |||
| 2c27e2e37d | |||
| b829e7a802 | |||
| d0ae214cb4 | |||
| 9b1a6c9fb8 | |||
| 41b662a8fe | |||
| 5232734071 | |||
| 996cf20fa9 | |||
| 825c9dad7c | |||
| 6e5bef14e9 | |||
| a53bd2bdb3 | |||
| e4d471b885 | |||
| bcb9737dda | |||
| 7a5389b719 | |||
| d9f0a8dade | |||
| aa8c8dd720 | |||
| 16c5e5aa4a | |||
| ded1f7aa67 | |||
| 6ad2679f17 | |||
| 4776f43f04 | |||
| d9db038c65 | |||
| e8ef027776 | |||
| 0a0761746f | |||
| f51e2a4869 | |||
| 093ed12c66 | |||
| 71a046a2d0 | |||
| c73f82b558 | |||
| b294f5d18f | |||
| e07bb7d6b2 |
@@ -0,0 +1,8 @@
|
|||||||
|
<!--
|
||||||
|
Please use one of the available issue templates.
|
||||||
|
Bug reports without required information may be closed.
|
||||||
|
-->
|
||||||
|
|
||||||
|
If you are reporting a bug or crash, please use the appropriate issue template.
|
||||||
|
|
||||||
|
For questions or support, use please use [Discussions](<https://github.com/mtrojnar/osslsigncode/discussions>).
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
name: Crash report
|
||||||
|
about: Report a segmentation fault or other crash
|
||||||
|
labels: crash
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Thank you for your crash report.
|
||||||
|
Note: Please search to see if an issue already exists for the bug you encountered.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Segmentation Fault / Crash Details
|
||||||
|
<!--
|
||||||
|
Provide exact, reproducible steps.
|
||||||
|
Include the complete command, exactly as executed.
|
||||||
|
-->
|
||||||
|
- Signal / exit code: <!-- SIGSEGV, SIGABRT -->
|
||||||
|
- Reproducibility: <!-- always / sometimes / once -->
|
||||||
|
- Affected command or operation: <!-- e.g. `osslsigncode sign`, `osslsigncode verify` -->
|
||||||
|
- First observed version:
|
||||||
|
- Last known working version (if any):
|
||||||
|
|
||||||
|
#### Backtrace
|
||||||
|
<!--
|
||||||
|
Provide a backtrace from gdb or lldb.
|
||||||
|
Build with debug symbols if possible. Use `bt full` if possible.
|
||||||
|
Crash reports without a backtrace may be closed without investigation.
|
||||||
|
-->
|
||||||
|
- `(gdb) bt`
|
||||||
|
|
||||||
|
#### Memory / Sanitizers
|
||||||
|
<!--
|
||||||
|
Attach relevant output if available.
|
||||||
|
-->
|
||||||
|
- [ ] Valgrind
|
||||||
|
- [ ] ASan / UBSan
|
||||||
|
- [ ] Other tools
|
||||||
|
|
||||||
|
#### Crash Context
|
||||||
|
<!--
|
||||||
|
Anything that may be relevant:
|
||||||
|
- OpenSSL provider / engine in use
|
||||||
|
- PKCS#11 modules
|
||||||
|
- Custom OpenSSL configuration
|
||||||
|
- Threading or concurrency
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Environment
|
||||||
|
- Operating system and version (e.g. Ubuntu 24.04):
|
||||||
|
- Architecture (x86_64, arm64, etc.):
|
||||||
|
|
||||||
|
### Versions
|
||||||
|
<!--
|
||||||
|
Please verify that the issue is reproducible with the current upstream master.
|
||||||
|
-->
|
||||||
|
- osslsigncode built from:
|
||||||
|
- [ ] upstream master
|
||||||
|
- [ ] upstream release (tag):
|
||||||
|
- [ ] distribution package (name and version):
|
||||||
|
- `openssl version -a`
|
||||||
|
- `osslsigncode --version`
|
||||||
|
|
||||||
|
### Configuration / Settings
|
||||||
|
<!--
|
||||||
|
Anything that could affect signing or verification:
|
||||||
|
- Custom OpenSSL configuration
|
||||||
|
- Engine / provider settings
|
||||||
|
- Environment variables (OPENSSL_CONF, etc.)
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Anything else
|
||||||
|
<!--
|
||||||
|
Links, references, related issues, workarounds or additional observations.
|
||||||
|
-->
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
name: Documentation
|
||||||
|
about: Report an error in (or missing) documentation
|
||||||
|
labels: documentation
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Thank you for taking the time to report a documentation issue.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Documentation Location
|
||||||
|
<!--
|
||||||
|
Where is the problem located?
|
||||||
|
Provide a link, file path, or section name.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Issue Description
|
||||||
|
<!--
|
||||||
|
Describe what is wrong or missing.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Suggested Improvement (optional)
|
||||||
|
<!--
|
||||||
|
If you know how it should be fixed, describe it here.
|
||||||
|
Proposed wording or examples are especially helpful.
|
||||||
|
-->
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest a new feature or improvement
|
||||||
|
labels: feature
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Thank you for your feature request.
|
||||||
|
Please describe the use case and motivation as clearly as possible.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Use Case / Motivation
|
||||||
|
<!--
|
||||||
|
What problem are you trying to solve?
|
||||||
|
Why is this feature needed?
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Proposed Change
|
||||||
|
<!--
|
||||||
|
Describe the feature or improvement you are proposing.
|
||||||
|
High-level description is sufficient.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Additional Notes (optional)
|
||||||
|
<!--
|
||||||
|
Anything else that may help:
|
||||||
|
- examples
|
||||||
|
- references
|
||||||
|
- related issues
|
||||||
|
-->
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: Questions / Support
|
||||||
|
about: Please use Q&A in Discussions instead
|
||||||
|
labels: question
|
||||||
|
---
|
||||||
|
|
||||||
|
### Questions and Support
|
||||||
|
|
||||||
|
Please do **not** use GitHub issues for general questions or support requests.
|
||||||
|
|
||||||
|
For:
|
||||||
|
- usage questions
|
||||||
|
- "how do I..." questions
|
||||||
|
|
||||||
|
please use [Q&A category in Discussions](<https://github.com/mtrojnar/osslsigncode/discussions/new?category=q-a>)
|
||||||
|
|
||||||
|
Bug reports and crashes should be reported using the appropriate issue templates.
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
name: Other bug report
|
||||||
|
about: Report a bug
|
||||||
|
labels: bug
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Thank you for your bug report.
|
||||||
|
Note: Please search to see if an issue already exists for the bug you encountered.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Current Behavior
|
||||||
|
<!--
|
||||||
|
A concise description of what is happening.
|
||||||
|
Include error messages or incorrect results.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Expected Behavior
|
||||||
|
<!--
|
||||||
|
A concise description of what you expected to happen instead.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Steps To Reproduce & Observed Output
|
||||||
|
<!--
|
||||||
|
Provide exact, reproducible steps together with full stdout/stderr for each.
|
||||||
|
-->
|
||||||
|
1. Signing with osslsigncode
|
||||||
|
<!--
|
||||||
|
Full `osslsigncode sign` command and complete stdout/stderr output.
|
||||||
|
-->
|
||||||
|
|
||||||
|
2. Verification with osslsigncode
|
||||||
|
<!--
|
||||||
|
Full `osslsigncode verify` command and complete stdout/stderr output.
|
||||||
|
-->
|
||||||
|
|
||||||
|
3. Signing / verification with Windows signtool (if applicable)
|
||||||
|
<!--
|
||||||
|
Full signtool command (`signtool verify /pa /v`) and complete stdout/stderr output.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Environment
|
||||||
|
- Operating system and version (e.g. Ubuntu 24.04):
|
||||||
|
- Architecture (x86_64, arm64, etc.):
|
||||||
|
|
||||||
|
### Versions
|
||||||
|
<!--
|
||||||
|
Please verify that the issue is reproducible with the current upstream master.
|
||||||
|
-->
|
||||||
|
- osslsigncode built from:
|
||||||
|
- [ ] upstream master
|
||||||
|
- [ ] upstream release (tag):
|
||||||
|
- [ ] distribution package (name and version):
|
||||||
|
- `openssl version -a`
|
||||||
|
- `osslsigncode --version`
|
||||||
|
|
||||||
|
### Files
|
||||||
|
<!--
|
||||||
|
Attach files if possible, or mention that you will share them privately.
|
||||||
|
-->
|
||||||
|
- [ ] unsigned file
|
||||||
|
- [ ] file signed with osslsigncode
|
||||||
|
- [ ] file signed with signtool or the other tool (for comparison)
|
||||||
|
- [ ] certificate chain used for verification (PEM format)
|
||||||
|
|
||||||
|
### Configuration / Settings
|
||||||
|
<!--
|
||||||
|
Anything that could affect signing or verification:
|
||||||
|
- Custom OpenSSL configuration
|
||||||
|
- Engine / provider settings
|
||||||
|
- Environment variables (OPENSSL_CONF, etc.)
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Anything else
|
||||||
|
<!--
|
||||||
|
Links, references, related issues, workarounds or additional observations.
|
||||||
|
-->
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<!--
|
||||||
|
Thank you for your pull request.
|
||||||
|
Provide a concise summary of the changes in the PR title.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Pull Request Type
|
||||||
|
<!--
|
||||||
|
Limit this PR to a single type. If necessary, split changes into multiple PRs.
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] Bug fix
|
||||||
|
- [ ] New feature
|
||||||
|
- [ ] Code style / formatting / renaming
|
||||||
|
- [ ] Refactoring (no functional or API changes)
|
||||||
|
- [ ] Build / CI related changes
|
||||||
|
- [ ] Documentation
|
||||||
|
- [ ] Other (please describe):
|
||||||
|
|
||||||
|
### Related Issue
|
||||||
|
<!--
|
||||||
|
If this fixes a GitHub issue, make sure to have a line saying 'Fixes #XXXX' (without quotes) in the commit message.
|
||||||
|
-->
|
||||||
|
Issue number: N/A
|
||||||
|
|
||||||
|
### Current Behavior
|
||||||
|
<!--
|
||||||
|
Describe the current behavior or limitation this PR addresses.
|
||||||
|
Include error messages or crash symptoms if relevant.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### New Behavior
|
||||||
|
<!--
|
||||||
|
Describe the new or changed behavior introduced by this PR.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Scope of Changes
|
||||||
|
<!--
|
||||||
|
Briefly describe what was changed and why.
|
||||||
|
Focus on relevant parts only.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
<!--
|
||||||
|
Describe how the changes were tested.
|
||||||
|
Include commands, environments, or platforms if relevant.
|
||||||
|
-->
|
||||||
|
- [ ] Existing tests
|
||||||
|
- [ ] New tests added
|
||||||
|
- [ ] Manual testing
|
||||||
|
|
||||||
|
### Additional Notes
|
||||||
|
<!--
|
||||||
|
Any additional information relevant for reviewers:
|
||||||
|
- design decisions
|
||||||
|
- backward compatibility
|
||||||
|
- known limitations
|
||||||
|
-->
|
||||||
|
|
||||||
|
## License Declaration
|
||||||
|
<!--
|
||||||
|
All contributions to this project are licensed under the project's license.
|
||||||
|
By submitting this pull request, you confirm that you have the right to submit
|
||||||
|
the code and agree to license it accordingly.
|
||||||
|
-->
|
||||||
|
- [ ] I hereby agree to license my contribution under the project's license.
|
||||||
+93
-55
@@ -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.8
|
version: osslsigncode-2.14-dev
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -15,20 +15,20 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
- id: ubuntu-24.04
|
||||||
|
triplet: x64-linux
|
||||||
|
compiler: gcc
|
||||||
|
os: ubuntu-24.04
|
||||||
|
generator: Unix Makefiles
|
||||||
|
vcpkg_root:
|
||||||
- id: ubuntu-22.04
|
- id: ubuntu-22.04
|
||||||
triplet: x64-linux
|
triplet: x64-linux
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
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
|
||||||
@@ -72,11 +72,11 @@ jobs:
|
|||||||
VCPKG_ROOT: ${{matrix.vcpkg_root}}
|
VCPKG_ROOT: ${{matrix.vcpkg_root}}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Cache the vcpkg archives
|
- name: Cache the vcpkg archives
|
||||||
if: matrix.cache != ''
|
if: matrix.cache != ''
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ${{matrix.cache}}
|
path: ${{matrix.cache}}
|
||||||
key: ${{matrix.id}}-${{hashFiles('vcpkg.json')}}
|
key: ${{matrix.id}}-${{hashFiles('vcpkg.json')}}
|
||||||
@@ -101,16 +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 install -y libssl-dev libcurl4-openssl-dev faketime
|
|
||||||
|
|
||||||
- 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'
|
||||||
@@ -120,46 +127,67 @@ 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@v1.12
|
uses: jwlawson/actions-setup-cmake@v2.0
|
||||||
with:
|
|
||||||
cmake-version: '3.17.0'
|
|
||||||
|
|
||||||
- name: Show OpenSSL version
|
- name: Install python3 cryptography module (Linux)
|
||||||
run: openssl version -a
|
if: runner.os == 'Linux'
|
||||||
|
run: |
|
||||||
|
source venv/bin/activate
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
python -m pip install --upgrade cryptography
|
||||||
|
python -c "import sys; print(sys.executable)"
|
||||||
|
python --version
|
||||||
|
python -c "import cryptography; print(f'Python3 cryptography version {cryptography.__version__}')"
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Install python3 cryptography module (macOS)
|
||||||
run: cmake
|
if: runner.os == 'macOS'
|
||||||
-G "${{matrix.generator}}"
|
run: |
|
||||||
-S ${{github.workspace}}
|
source venv/bin/activate
|
||||||
-B ${{github.workspace}}/build
|
python -m pip install --upgrade pip
|
||||||
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
ARCHFLAGS="-arch arm64" python -m pip install --upgrade cryptography
|
||||||
-DCMAKE_INSTALL_PREFIX=${{github.workspace}}/dist
|
python -c "import sys; print(sys.executable)"
|
||||||
-DVCPKG_TARGET_TRIPLET=${{matrix.triplet}}
|
python --version
|
||||||
|
python -c "import cryptography; print(f'Python3 cryptography version {cryptography.__version__}')"
|
||||||
|
|
||||||
|
- name: Install python3 cryptography module (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
run: |
|
||||||
|
.\venv\Scripts\Activate.ps1
|
||||||
|
python.exe -m ensurepip
|
||||||
|
python.exe -m pip install --upgrade pip
|
||||||
|
python.exe -m pip install cryptography
|
||||||
|
python.exe -c "import sys; print(sys.executable)"
|
||||||
|
python.exe --version
|
||||||
|
python.exe -c "import cryptography; print(f'Python3 cryptography version {cryptography.__version__}')"
|
||||||
|
|
||||||
|
- name: Configure CMake (Linux/macOS)
|
||||||
|
if: runner.os != 'Windows'
|
||||||
|
run: |
|
||||||
|
source venv/bin/activate
|
||||||
|
cmake \
|
||||||
|
-G "${{matrix.generator}}" \
|
||||||
|
-S "${{github.workspace}}" \
|
||||||
|
-B "${{github.workspace}}/build" \
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=arm64 \
|
||||||
|
-DCMAKE_BUILD_TYPE="${{env.BUILD_TYPE}}" \
|
||||||
|
-DCMAKE_INSTALL_PREFIX="${{github.workspace}}/dist"
|
||||||
|
|
||||||
|
- name: Configure CMake (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
run: |
|
||||||
|
.\venv\Scripts\Activate.ps1
|
||||||
|
cmake `
|
||||||
|
-G "${{matrix.generator}}" `
|
||||||
|
-S "${{github.workspace}}" `
|
||||||
|
-B "${{github.workspace}}/build" `
|
||||||
|
-DCMAKE_BUILD_TYPE="${{env.BUILD_TYPE}}" `
|
||||||
|
-DCMAKE_INSTALL_PREFIX="${{github.workspace}}/dist"
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake
|
run: cmake
|
||||||
--build ${{github.workspace}}/build
|
--build ${{github.workspace}}/build
|
||||||
--config ${{env.BUILD_TYPE}}
|
--config ${{env.BUILD_TYPE}}
|
||||||
|
|
||||||
- name: Start HTTP server (macOS)
|
|
||||||
working-directory: ${{github.workspace}}/build
|
|
||||||
if: runner.os == 'macOS'
|
|
||||||
run: |
|
|
||||||
python3.8 --version
|
|
||||||
python3.8 ./Testing/server_http.py --port 19254
|
|
||||||
while test ! -s ./Testing/logs/port.log; do sleep 1; done
|
|
||||||
|
|
||||||
- name: Start HTTP server (Windows)
|
|
||||||
working-directory: ${{github.workspace}}\build
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
run: |
|
|
||||||
python.exe --version
|
|
||||||
$Args = '.\Testing\server_http.pyw --port 19254'
|
|
||||||
$File = '.\Testing\logs\port.log'
|
|
||||||
Start-Process -FilePath pythonw.exe -ArgumentList $Args
|
|
||||||
while(-not(Test-Path -Path $File -PathType Leaf) -or [String]::IsNullOrWhiteSpace((Get-Content $File))) {Start-Sleep -Seconds 1}
|
|
||||||
Get-Content '.\Testing\logs\server.log'
|
|
||||||
|
|
||||||
- name: List files (Linux/macOS)
|
- name: List files (Linux/macOS)
|
||||||
if: runner.os != 'Windows'
|
if: runner.os != 'Windows'
|
||||||
run: find .. -ls
|
run: find .. -ls
|
||||||
@@ -168,12 +196,22 @@ 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@v3
|
uses: actions/upload-artifact@v4
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: errors-${{matrix.id}}
|
name: errors-${{matrix.id}}
|
||||||
@@ -187,7 +225,7 @@ jobs:
|
|||||||
run: cmake --install ${{github.workspace}}/build
|
run: cmake --install ${{github.workspace}}/build
|
||||||
|
|
||||||
- name: Upload the executables
|
- name: Upload the executables
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{env.version}}-${{matrix.id}}
|
name: ${{env.version}}-${{matrix.id}}
|
||||||
path: ${{github.workspace}}/dist
|
path: ${{github.workspace}}/dist
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v2
|
uses: github/codeql-action/autobuild@v3
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
@@ -56,4 +56,4 @@ jobs:
|
|||||||
# ./location_of_script_within_repo/buildscript.sh
|
# ./location_of_script_within_repo/buildscript.sh
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v3
|
||||||
|
|||||||
@@ -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'
|
||||||
@@ -10,7 +10,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
token: ${{secrets.COVERITY_SCAN_TOKEN}}
|
token: ${{secrets.COVERITY_SCAN_TOKEN}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
if: env.token
|
if: env.token
|
||||||
- name: Get ready for scanning
|
- name: Get ready for scanning
|
||||||
if: env.token
|
if: env.token
|
||||||
|
|||||||
+41
-9
@@ -3,20 +3,20 @@ cmake_minimum_required(VERSION 3.17)
|
|||||||
|
|
||||||
# autodetect vcpkg CMAKE_TOOLCHAIN_FILE if VCPKG_ROOT is defined
|
# autodetect vcpkg CMAKE_TOOLCHAIN_FILE if VCPKG_ROOT is defined
|
||||||
# this needs to be configured before the project() directive
|
# this needs to be configured before the project() directive
|
||||||
if(DEFINED ENV{VCPKG_ROOT} AND NOT $ENV{VCPKG_ROOT} STREQUAL "" AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
if((CMAKE_GENERATOR MATCHES "Ninja") AND DEFINED ENV{VCPKG_ROOT} AND NOT $ENV{VCPKG_ROOT} STREQUAL "" AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||||
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
|
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
|
||||||
endif(DEFINED ENV{VCPKG_ROOT} AND NOT $ENV{VCPKG_ROOT} STREQUAL "" AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
endif((CMAKE_GENERATOR MATCHES "Ninja") AND DEFINED ENV{VCPKG_ROOT} AND NOT $ENV{VCPKG_ROOT} STREQUAL "" AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||||
set(BUILTIN_SOCKET ON CACHE BOOL "") # for static Python
|
set(BUILTIN_SOCKET ON CACHE BOOL "") # for static Python
|
||||||
|
|
||||||
# configure basic project information
|
# configure basic project information
|
||||||
project(osslsigncode
|
project(osslsigncode
|
||||||
VERSION 2.8
|
VERSION 2.14
|
||||||
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)
|
||||||
|
|
||||||
# force nonstandard version format for development packages
|
# force nonstandard version format for development packages
|
||||||
set(DEV "")
|
set(DEV "-dev")
|
||||||
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}${DEV}")
|
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}${DEV}")
|
||||||
|
|
||||||
# version and contact information
|
# version and contact information
|
||||||
@@ -29,7 +29,12 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
|
|||||||
|
|
||||||
# load CMake library modules
|
# load CMake library modules
|
||||||
include(FindOpenSSL)
|
include(FindOpenSSL)
|
||||||
include(FindCURL)
|
if(OPENSSL_VERSION VERSION_LESS "1.1.1")
|
||||||
|
message(FATAL_ERROR "OpenSSL version must be at least 1.1.1")
|
||||||
|
endif()
|
||||||
|
if(OPENSSL_VERSION VERSION_LESS "3.0.0")
|
||||||
|
include(FindCURL)
|
||||||
|
endif(OPENSSL_VERSION VERSION_LESS "3.0.0")
|
||||||
include(FindZLIB)
|
include(FindZLIB)
|
||||||
|
|
||||||
# load CMake project modules
|
# load CMake project modules
|
||||||
@@ -64,6 +69,7 @@ target_include_directories(osslsigncode PRIVATE ${OPENSSL_INCLUDE_DIR})
|
|||||||
target_link_libraries(osslsigncode PRIVATE ${OPENSSL_LIBRARIES})
|
target_link_libraries(osslsigncode PRIVATE ${OPENSSL_LIBRARIES})
|
||||||
|
|
||||||
# set cURL includes/libraries
|
# set cURL includes/libraries
|
||||||
|
if(OPENSSL_VERSION VERSION_LESS "3.0.0")
|
||||||
if(CURL_FOUND)
|
if(CURL_FOUND)
|
||||||
target_compile_definitions(osslsigncode PRIVATE ENABLE_CURL=1)
|
target_compile_definitions(osslsigncode PRIVATE ENABLE_CURL=1)
|
||||||
target_include_directories(osslsigncode PRIVATE ${CURL_INCLUDE_DIRS})
|
target_include_directories(osslsigncode PRIVATE ${CURL_INCLUDE_DIRS})
|
||||||
@@ -72,6 +78,7 @@ if(CURL_FOUND)
|
|||||||
else(CURL_FOUND)
|
else(CURL_FOUND)
|
||||||
message(STATUS "cURL support disabled (library not found)")
|
message(STATUS "cURL support disabled (library not found)")
|
||||||
endif(CURL_FOUND)
|
endif(CURL_FOUND)
|
||||||
|
endif(OPENSSL_VERSION VERSION_LESS "3.0.0")
|
||||||
|
|
||||||
if(NOT ZLIB_FOUND)
|
if(NOT ZLIB_FOUND)
|
||||||
message(FATAL_ERROR "Zlib library not found")
|
message(FATAL_ERROR "Zlib library not found")
|
||||||
@@ -79,20 +86,36 @@ endif(NOT ZLIB_FOUND)
|
|||||||
target_include_directories(osslsigncode PRIVATE ${ZLIB_INCLUDE_DIR})
|
target_include_directories(osslsigncode PRIVATE ${ZLIB_INCLUDE_DIR})
|
||||||
target_link_libraries(osslsigncode PRIVATE ${ZLIB_LIBRARIES})
|
target_link_libraries(osslsigncode PRIVATE ${ZLIB_LIBRARIES})
|
||||||
|
|
||||||
|
if(NOT UNIX)
|
||||||
|
# https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-shutdown
|
||||||
|
target_link_libraries(osslsigncode PRIVATE ws2_32.lib crypt32.lib)
|
||||||
|
endif(NOT UNIX)
|
||||||
|
|
||||||
# add paths to linker search and installed rpath
|
# add paths to linker search and installed rpath
|
||||||
set_target_properties(osslsigncode PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
|
set_target_properties(osslsigncode PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
|
|
||||||
# testing with CTest
|
# testing with CTest
|
||||||
include(CMakeTest)
|
include(CMakeTest)
|
||||||
|
|
||||||
|
# documentation with Pandoc
|
||||||
|
include(CMakeDoc)
|
||||||
|
|
||||||
# installation rules for a project
|
# installation rules for a project
|
||||||
set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin")
|
include(GNUInstallDirs)
|
||||||
install(TARGETS osslsigncode RUNTIME DESTINATION ${BINDIR})
|
|
||||||
|
install(TARGETS osslsigncode RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
"${PROJECT_SOURCE_DIR}/README.md"
|
||||||
|
"${PROJECT_SOURCE_DIR}/NEWS.md"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_DOCDIR}")
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
include(CMakeDist)
|
include(CMakeDist)
|
||||||
else(UNIX)
|
else(UNIX)
|
||||||
install(
|
install(
|
||||||
DIRECTORY ${PROJECT_BINARY_DIR}/ DESTINATION ${BINDIR}
|
DIRECTORY ${PROJECT_BINARY_DIR}/
|
||||||
|
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
FILES_MATCHING
|
FILES_MATCHING
|
||||||
PATTERN "*.dll"
|
PATTERN "*.dll"
|
||||||
PATTERN "vcpkg_installed" EXCLUDE
|
PATTERN "vcpkg_installed" EXCLUDE
|
||||||
@@ -100,6 +123,15 @@ else(UNIX)
|
|||||||
PATTERN "Testing" EXCLUDE)
|
PATTERN "Testing" EXCLUDE)
|
||||||
endif(UNIX)
|
endif(UNIX)
|
||||||
|
|
||||||
|
# uninstall target
|
||||||
|
configure_file(
|
||||||
|
"${PROJECT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||||
|
"${PROJECT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||||
|
IMMEDIATE @ONLY)
|
||||||
|
|
||||||
|
add_custom_target(uninstall
|
||||||
|
COMMAND ${CMAKE_COMMAND} -P "${PROJECT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||||
|
|
||||||
#[[
|
#[[
|
||||||
Local Variables:
|
Local Variables:
|
||||||
c-basic-offset: 4
|
c-basic-offset: 4
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
FROM alpine:latest AS builder
|
FROM alpine:latest AS builder
|
||||||
|
|
||||||
# Install build dependencies
|
# Install build dependencies
|
||||||
RUN apk add --no-cache build-base cmake openssl-dev curl-dev
|
RUN apk add --no-cache build-base cmake openssl-dev zlib-dev
|
||||||
|
|
||||||
# Copy osslsigncode source code into the image
|
# Copy osslsigncode source code into the image
|
||||||
COPY . /source
|
COPY . /source
|
||||||
@@ -23,7 +23,7 @@ FROM alpine:latest
|
|||||||
COPY --from=builder /usr/local/bin/osslsigncode /usr/local/bin/osslsigncode
|
COPY --from=builder /usr/local/bin/osslsigncode /usr/local/bin/osslsigncode
|
||||||
|
|
||||||
# Install necessary runtime libraries (latest version)
|
# Install necessary runtime libraries (latest version)
|
||||||
RUN apk add --no-cache libcrypto3 libcurl
|
RUN apk add --no-cache libcrypto3
|
||||||
|
|
||||||
# Set working directory
|
# Set working directory
|
||||||
WORKDIR /workdir
|
WORKDIR /workdir
|
||||||
|
|||||||
+30
-56
@@ -3,50 +3,40 @@
|
|||||||
### Building osslsigncode source with MSYS2 MinGW 64-bit and MSYS2 packages:
|
### Building osslsigncode source with MSYS2 MinGW 64-bit and MSYS2 packages:
|
||||||
|
|
||||||
1) Download and install MSYS2 from https://msys2.github.io/ and follow installation instructions.
|
1) Download and install MSYS2 from https://msys2.github.io/ and follow installation instructions.
|
||||||
Once up and running install even mingw-w64-x86_64-gcc, mingw-w64-x86_64-curl.
|
Once up and running install the following packages:
|
||||||
```
|
```
|
||||||
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-curl
|
pacman -S make mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-openssl mingw-w64-x86_64-python-cryptography
|
||||||
```
|
```
|
||||||
mingw-w64-x86_64-openssl and mingw-w64-x86_64-zlib packages are installed with dependencies.
|
mingw-w64-x86_64-zlib package is installed with dependencies.
|
||||||
|
|
||||||
2) Run "MSYS2 MinGW 64-bit" and build 64-bit Windows executables.
|
2) Run "MSYS2 MinGW 64-bit" and build 64-bit Windows executables.
|
||||||
```
|
```
|
||||||
cd osslsigncode-folder
|
cd osslsigncode-folder
|
||||||
x86_64-w64-mingw32-gcc *.c -o osslsigncode.exe \
|
mkdir build && cd build && cmake -S .. -DCMAKE_BUILD_TYPE=Release -G "MSYS Makefiles"
|
||||||
-lcrypto -lssl -lcurl \
|
cmake --build . --verbose
|
||||||
-D 'PACKAGE_STRING="osslsigncode x.y"' \
|
|
||||||
-D 'PACKAGE_BUGREPORT="Your.Email@example.com"' \
|
|
||||||
-D ENABLE_CURL
|
|
||||||
```
|
```
|
||||||
|
|
||||||
3) Run "Command prompt" and include "c:\msys64\mingw64\bin" folder as part of the path.
|
3) Make tests.
|
||||||
|
```
|
||||||
|
ctest
|
||||||
|
```
|
||||||
|
|
||||||
|
4) Run "Command prompt" and include "c:\msys64\mingw64\bin" folder as part of the path.
|
||||||
```
|
```
|
||||||
path=%path%;c:\msys64\mingw64\bin
|
path=%path%;c:\msys64\mingw64\bin
|
||||||
cd osslsigncode-folder
|
|
||||||
osslsigncode.exe -v
|
osslsigncode.exe -v
|
||||||
osslsigncode 2.4, using:
|
osslsigncode 2.8, using:
|
||||||
OpenSSL 1.1.1g 21 Apr 2020 (Library: OpenSSL 1.1.1g 21 Apr 2020)
|
OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)
|
||||||
libcurl/7.70.0 OpenSSL/1.1.1g (Schannel) zlib/1.2.11 brotli/1.0.7 libidn2/2.3.0
|
No default -CAfile location detected
|
||||||
libpsl/0.21.0 (+libidn2/2.3.0) libssh2/1.9.0 nghttp2/1.40.0
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Building OpenSSL and osslsigncode sources with MSYS2 MinGW 64-bit:
|
||||||
### Building OpenSSL, Curl and osslsigncode sources with MSYS2 MinGW 64-bit:
|
|
||||||
|
|
||||||
1) Download and install MSYS2 from https://msys2.github.io/ and follow installation instructions.
|
1) Download and install MSYS2 from https://msys2.github.io/ and follow installation instructions.
|
||||||
Once up and running install even: perl make autoconf automake libtool pkg-config.
|
Once up and running install even: perl make autoconf automake libtool pkg-config.
|
||||||
```
|
```
|
||||||
pacman -S perl make autoconf automake libtool pkg-config
|
pacman -S perl make autoconf automake libtool pkg-config
|
||||||
```
|
```
|
||||||
Make sure there are no curl, brotli, libpsl, libidn2 and nghttp2 packages installed:
|
|
||||||
```
|
|
||||||
pacman -R mingw-w64-x86_64-curl \
|
|
||||||
mingw-w64-x86_64-brotli \
|
|
||||||
mingw-w64-x86_64-libpsl \
|
|
||||||
mingw-w64-x86_64-libidn2 \
|
|
||||||
mingw-w64-x86_64-nghttp2
|
|
||||||
```
|
|
||||||
|
|
||||||
Run "MSYS2 MinGW 64-bit" in the administrator mode.
|
Run "MSYS2 MinGW 64-bit" in the administrator mode.
|
||||||
|
|
||||||
2) Build and install OpenSSL.
|
2) Build and install OpenSSL.
|
||||||
@@ -55,46 +45,30 @@
|
|||||||
./config --prefix='C:/OpenSSL' --openssldir='C:/OpenSSL'
|
./config --prefix='C:/OpenSSL' --openssldir='C:/OpenSSL'
|
||||||
make && make install
|
make && make install
|
||||||
```
|
```
|
||||||
3) Build and install curl.
|
|
||||||
```
|
|
||||||
cd curl-(version)
|
|
||||||
./buildconf
|
|
||||||
./configure --prefix='C:/curl' --with-ssl='C:/OpenSSL' \
|
|
||||||
--disable-ftp --disable-tftp --disable-file --disable-dict \
|
|
||||||
--disable-telnet --disable-imap --disable-smb --disable-smtp \
|
|
||||||
--disable-gopher --disable-pop --disable-pop3 --disable-rtsp \
|
|
||||||
--disable-ldap --disable-ldaps --disable-unix-sockets \
|
|
||||||
--disable-pthreads --without-zstd --without-zlib
|
|
||||||
make && make install
|
|
||||||
```
|
|
||||||
|
|
||||||
3) Build 64-bit Windows executables.
|
3) Configure a CMake project.
|
||||||
```
|
```
|
||||||
cd osslsigncode-folder
|
mkdir build && cd build && cmake -S .. -DCMAKE_BUILD_TYPE=Release -G "MSYS Makefiles" -DCMAKE_PREFIX_PATH="C:\OpenSSL"
|
||||||
x86_64-w64-mingw32-gcc *.c -o osslsigncode.exe \
|
|
||||||
-L 'C:/OpenSSL/lib/' -lcrypto -lssl \
|
|
||||||
-I 'C:/OpenSSL/include/' \
|
|
||||||
-L 'C:/curl/lib' -lcurl \
|
|
||||||
-I 'C:/curl/include' \
|
|
||||||
-D 'PACKAGE_STRING="osslsigncode x.y"' \
|
|
||||||
-D 'PACKAGE_BUGREPORT="Your.Email@example.com"' \
|
|
||||||
-D ENABLE_CURL
|
|
||||||
```
|
```
|
||||||
|
|
||||||
4) Run "Command prompt" and copy required libraries.
|
4) Run "Command prompt" and copy required libraries.
|
||||||
```
|
```
|
||||||
cd osslsigncode-folder
|
cd osslsigncode-folder
|
||||||
copy C:\OpenSSL\bin\libssl-1_1-x64.dll
|
copy C:\OpenSSL\bin\libssl-3-x64.dll
|
||||||
copy C:\OpenSSL\bin\libcrypto-1_1-x64.dll
|
copy C:\OpenSSL\bin\libcrypto-3-x64.dll
|
||||||
copy C:\curl\bin\libcurl-4.dll
|
|
||||||
|
|
||||||
osslsigncode.exe -v
|
|
||||||
osslsigncode 2.4, using:
|
|
||||||
OpenSSL 1.1.1k 25 Mar 2021 (Library: OpenSSL 1.1.1k 25 Mar 2021)
|
|
||||||
libcurl/7.78.0 OpenSSL/1.1.1k
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building OpenSSL, Curl and osslsigncode sources with Microsoft Visual Studio:
|
5) Build 64-bit Windows executables.
|
||||||
|
```
|
||||||
|
cmake --build . --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
6) Make tests.
|
||||||
|
```
|
||||||
|
ctest
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building OpenSSL and osslsigncode sources with Microsoft Visual Studio:
|
||||||
|
|
||||||
1) Install and integrate vcpkg: https://vcpkg.io/en/getting-started.html
|
1) Install and integrate vcpkg: https://vcpkg.io/en/getting-started.html
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -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>
|
||||||
|
|||||||
@@ -1,5 +1,79 @@
|
|||||||
# osslsigncode change log
|
# osslsigncode change log
|
||||||
|
|
||||||
|
### 2.14 (unreleased)
|
||||||
|
|
||||||
|
- attach-signature now uses digest-only verification instead of full signature
|
||||||
|
validation; output file is not kept if digest verification fails
|
||||||
|
|
||||||
|
### 2.13 (2026.02.10)
|
||||||
|
|
||||||
|
**MULTIPLE SECURITY VULNERABILITIES**
|
||||||
|
|
||||||
|
This release includes important security fixes. Users are strongly encouraged
|
||||||
|
to upgrade, as the issues below may be exploitable when processing untrusted
|
||||||
|
files.
|
||||||
|
|
||||||
|
- fixed integer overflows when processing APPX compressed data streams
|
||||||
|
(by Małgorzata Olszówka)
|
||||||
|
- fixed double-free vulnerabilities in APPX file processing
|
||||||
|
(by Małgorzata Olszówka)
|
||||||
|
- fixed multiple memory corruption issues in PE page hash computation
|
||||||
|
(by Antoni Klajn (Opera) and Małgorzata Olszówka)
|
||||||
|
|
||||||
|
### 2.12 (2026.02.02)
|
||||||
|
|
||||||
|
**CRITICAL SECURITY VULNERABILITY**
|
||||||
|
|
||||||
|
This release fixes a critical memory corruption vulnerability. A malicious
|
||||||
|
attacker could create a signed file, which, when verified with osslsigncode,
|
||||||
|
triggers arbitrary code execution. Any previous version of osslsigncode should
|
||||||
|
be immediately upgraded if the tool is used for verification of untrusted
|
||||||
|
files.
|
||||||
|
|
||||||
|
- fixed a buffer overflow while extracting message digests
|
||||||
|
(reported and fixed by Antoni Klajn, Opera)
|
||||||
|
|
||||||
|
### 2.11 (2026.01.20)
|
||||||
|
- added keyUsage validation for signer certificate
|
||||||
|
(thanks to Hanqing Zhao and Zi-Quan You for reporting the issue)
|
||||||
|
- added printing CRL details during signature verification
|
||||||
|
- implemented a workaround for CRL servers returning the HTTP Content-Type
|
||||||
|
header other than application/pkix-crl (thanks to Chris Thibodeaux)
|
||||||
|
- fixed HTTP keep-alive handling
|
||||||
|
- fixed macOS compiler and linker flags
|
||||||
|
- fixed undefined BIO_get_fp() behavior with BIO_FLAGS_UPLINK_INTERNAL
|
||||||
|
|
||||||
|
### 2.10 (2025.06.23)
|
||||||
|
|
||||||
|
- added JavaScript signing
|
||||||
|
- added PKCS#11 provider support (requires OpenSSL 3.0+)
|
||||||
|
- added support for providers without specifying "-pkcs11module" option
|
||||||
|
(OpenSSL 3.0+, e.g., for the upcoming CNG provider)
|
||||||
|
- added compatibility with the CNG engine version 1.1 or later
|
||||||
|
- added the "-engineCtrl" option to control hardware and CNG engines
|
||||||
|
- added the '-blobFile' option to specify a file containing the blob content
|
||||||
|
- improved unauthenticated blob support (thanks to Asger Hautop Drewsen)
|
||||||
|
- improved UTF-8 handling for certificate subjects and issuers
|
||||||
|
- fixed support for multiple signerInfo contentType OIDs (CTL and Authenticode)
|
||||||
|
- fixed tests for python-cryptography >= 43.0.0
|
||||||
|
|
||||||
|
### 2.9 (2024.06.29)
|
||||||
|
|
||||||
|
- added a 64 bit long pseudo-random NONCE in the TSA request
|
||||||
|
- missing NID_pkcs9_signingTime is no longer an error
|
||||||
|
- added support for PEM-encoded CRLs
|
||||||
|
- fixed the APPX central directory sorting order
|
||||||
|
- added a special "-" file name to read the passphrase from stdin
|
||||||
|
(by Steve McIntyre)
|
||||||
|
- used native HTTP client with OpenSSL 3.x, removing libcurl dependency
|
||||||
|
- added '-login' option to force a login to PKCS11 engines
|
||||||
|
(by Brad Hughes)
|
||||||
|
- added the "-ignore-crl" option to disable fetching and verifying
|
||||||
|
CRL Distribution Points
|
||||||
|
- changed error output to stderr instead of stdout
|
||||||
|
- various testing framework improvements
|
||||||
|
- various memory corruption fixes
|
||||||
|
|
||||||
### 2.8 (2024.03.03)
|
### 2.8 (2024.03.03)
|
||||||
|
|
||||||
- Microsoft PowerShell signing sponsored by Cisco Systems, Inc.
|
- Microsoft PowerShell signing sponsored by Cisco Systems, Inc.
|
||||||
|
|||||||
@@ -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,68 @@ 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.
|
### Using the PKCS#11 Engine with osslsigncode
|
||||||
An example of using osslsigncode with SoftHSM:
|
If you want to use a PKCS#11 token, specify the PKCS#11 engine and module.
|
||||||
|
Example usage 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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Using the PKCS#11 Provider with osslsigncode (OpenSSL 3.x only)
|
||||||
|
OpenSSL 3.0 introduced a new provider-based architecture. To use a PKCS#11 token
|
||||||
|
with `osslsigncode`, specify the PKCS#11 provider and module.
|
||||||
|
Example usage with OpenSC:
|
||||||
|
```
|
||||||
|
osslsigncode sign \
|
||||||
|
-provider /usr/lib64/ossl-modules/pkcs11prov.so \
|
||||||
|
-pkcs11module /usr/lib64/opensc-pkcs11.so \
|
||||||
|
-pkcs11cert 'pkcs11:token=my-token;object=cert' \
|
||||||
|
-key 'pkcs11:token=my-token;object=key' \
|
||||||
|
-in yourapp.exe -out yourapp-signed.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using the CNG Engine with osslsigncode (Windows only)
|
||||||
|
The CNG engine allows using certificates and keys stored in the Windows
|
||||||
|
Certificate Store. It requires CNG engine version 1.1 or later. For more
|
||||||
|
information, refer to
|
||||||
|
|
||||||
|
https://www.stunnel.org/cng-engine.html
|
||||||
|
|
||||||
|
A non-commercial edition of CNG engine is available for testing, personal,
|
||||||
|
educational, or research purposes.
|
||||||
|
|
||||||
|
To ensure `osslsigncode` can locate and load the CNG engine module (`cng.dll`)
|
||||||
|
even when it is not installed in the default system engine directory, you can:
|
||||||
|
|
||||||
|
- Specify the full or relative path to `cng.dll`:
|
||||||
|
```
|
||||||
|
osslsigncode sign -engine C:\my\engines\cng.dll ...
|
||||||
|
```
|
||||||
|
- Or set the `OPENSSL_ENGINES` environment variable to the directory containing
|
||||||
|
`cng.dll`, and refer to the engine by its ID:
|
||||||
|
```
|
||||||
|
set OPENSSL_ENGINES=C:\my\engines
|
||||||
|
osslsigncode sign -engine cng ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Below is an example of how to use `osslsigncode` with the CNG engine on Windows:
|
||||||
|
```
|
||||||
|
set OPENSSL_ENGINES=C:\my\engines
|
||||||
|
osslsigncode sign ^
|
||||||
|
-engine cng ^
|
||||||
|
-pkcs11cert osslsigncode_cert ^
|
||||||
|
-key osslsigncode_cert ^
|
||||||
|
-engineCtrl store_flags:0 ^
|
||||||
|
-engineCtrl store_name:MY ^
|
||||||
|
-engineCtrl PIN:yourpass ^
|
||||||
|
-in yourapp.exe -out yourapp-signed.exe
|
||||||
|
```
|
||||||
|
|
||||||
You can check that the signed file is correct by right-clicking
|
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 +232,13 @@ osslsigncode.exe add -addUnauthenticatedBlob -in your_signed_file.exe -out out.e
|
|||||||
This feature allows for doing dumb things. Be very careful with what you put
|
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.
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)) {
|
||||||
printf("Unable to set the message digest of BIO\n");
|
fprintf(stderr, "Unable to set the message digest of BIO\n");
|
||||||
BIO_free_all(bhash);
|
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 */
|
||||||
@@ -296,7 +303,7 @@ static u_char *cab_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
|
|||||||
nfolders--;
|
nfolders--;
|
||||||
}
|
}
|
||||||
if (idx != coffFiles) {
|
if (idx != coffFiles) {
|
||||||
printf("Corrupt coffFiles value: 0x%08X\n", coffFiles);
|
fprintf(stderr, "Corrupt coffFiles value: 0x%08X\n", coffFiles);
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
@@ -307,7 +314,7 @@ static u_char *cab_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
|
|||||||
}
|
}
|
||||||
/* (variable) ab - the compressed data bytes */
|
/* (variable) ab - the compressed data bytes */
|
||||||
if (!bio_hash_data(bhash, ctx->options->indata, idx, fileend)) {
|
if (!bio_hash_data(bhash, ctx->options->indata, idx, fileend)) {
|
||||||
printf("Unable to calculate digest\n");
|
fprintf(stderr, "Unable to calculate digest\n");
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
@@ -330,30 +337,18 @@ static int cab_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
|||||||
u_char mdbuf[EVP_MAX_MD_SIZE];
|
u_char mdbuf[EVP_MAX_MD_SIZE];
|
||||||
u_char *cmdbuf;
|
u_char *cmdbuf;
|
||||||
|
|
||||||
if (is_content_type(p7, SPC_INDIRECT_DATA_OBJID)) {
|
if (!pkcs7_get_content_digest(p7, mdbuf, &mdtype)) {
|
||||||
ASN1_STRING *content_val = p7->d.sign->contents->d.other->value.sequence;
|
fprintf(stderr, "Failed to extract current message digest\n\n");
|
||||||
const u_char *p = content_val->data;
|
|
||||||
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, content_val->length);
|
|
||||||
if (idc) {
|
|
||||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
|
||||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
|
||||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
|
||||||
}
|
|
||||||
SpcIndirectDataContent_free(idc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mdtype == -1) {
|
|
||||||
printf("Failed to extract current message digest\n\n");
|
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
md = EVP_get_digestbynid(mdtype);
|
md = EVP_get_digestbynid(mdtype);
|
||||||
cmdbuf = cab_digest_calc(ctx, md);
|
cmdbuf = cab_digest_calc(ctx, md);
|
||||||
if (!cmdbuf) {
|
if (!cmdbuf) {
|
||||||
printf("Failed to calculate message digest\n\n");
|
fprintf(stderr, "Failed to calculate message digest\n\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
|
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
|
||||||
printf("Signature verification: failed\n\n");
|
fprintf(stderr, "Signature verification: failed\n\n");
|
||||||
OPENSSL_free(cmdbuf);
|
OPENSSL_free(cmdbuf);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
@@ -396,7 +391,7 @@ static PKCS7 *cab_pkcs7_extract_to_nest(FILE_FORMAT_CTX *ctx)
|
|||||||
*/
|
*/
|
||||||
static int cab_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
static int cab_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
||||||
{
|
{
|
||||||
size_t i, written, len;
|
size_t idx, written, len;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
uint16_t nfolders, flags;
|
uint16_t nfolders, flags;
|
||||||
char *buf;
|
char *buf;
|
||||||
@@ -441,29 +436,39 @@ static int cab_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
* u2 iCabinet - number of this cabinet file in a set: 34-35
|
* u2 iCabinet - number of this cabinet file in a set: 34-35
|
||||||
*/
|
*/
|
||||||
BIO_write(outdata, ctx->options->indata + 32, 4);
|
BIO_write(outdata, ctx->options->indata + 32, 4);
|
||||||
i = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
|
idx = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
|
||||||
|
if (idx >= ctx->cab_ctx->fileend) {
|
||||||
|
fprintf(stderr, "Corrupt CAB file - too short\n");
|
||||||
|
OPENSSL_free(buf);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* (u8 * cFolders) CFFOLDER - structure contains information about
|
* (u8 * cFolders) CFFOLDER - structure contains information about
|
||||||
* one of the folders or partial folders stored in this cabinet file
|
* one of the folders or partial folders stored in this cabinet file
|
||||||
*/
|
*/
|
||||||
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
|
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
|
||||||
|
if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) {
|
||||||
|
fprintf(stderr, "Corrupt cFolders value: 0x%08X\n", nfolders);
|
||||||
|
OPENSSL_free(buf);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
while (nfolders) {
|
while (nfolders) {
|
||||||
tmp = GET_UINT32_LE(ctx->options->indata + i);
|
tmp = GET_UINT32_LE(ctx->options->indata + idx);
|
||||||
tmp -= 24;
|
tmp -= 24;
|
||||||
PUT_UINT32_LE(tmp, buf);
|
PUT_UINT32_LE(tmp, buf);
|
||||||
BIO_write(outdata, buf, 4);
|
BIO_write(outdata, buf, 4);
|
||||||
BIO_write(outdata, ctx->options->indata + i + 4, 4);
|
BIO_write(outdata, ctx->options->indata + idx + 4, 4);
|
||||||
i+=8;
|
idx += 8;
|
||||||
nfolders--;
|
nfolders--;
|
||||||
}
|
}
|
||||||
OPENSSL_free(buf);
|
OPENSSL_free(buf);
|
||||||
/* Write what's left - the compressed data bytes */
|
/* Write what's left - the compressed data bytes */
|
||||||
len = ctx->cab_ctx->fileend - ctx->cab_ctx->siglen - i;
|
len = ctx->cab_ctx->fileend - ctx->cab_ctx->siglen - idx;
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
if (!BIO_write_ex(outdata, ctx->options->indata + i, len, &written))
|
if (!BIO_write_ex(outdata, ctx->options->indata + idx, len, &written))
|
||||||
return 1; /* FAILED */
|
return 1; /* FAILED */
|
||||||
len -= written;
|
len -= written;
|
||||||
i += written;
|
idx += written;
|
||||||
}
|
}
|
||||||
return 0; /* OK */
|
return 0; /* OK */
|
||||||
}
|
}
|
||||||
@@ -480,12 +485,12 @@ static int cab_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
/* Strip current signature and modify header */
|
/* Strip current signature and modify header */
|
||||||
if (ctx->cab_ctx->header_size == 20) {
|
if (ctx->cab_ctx->header_size == 20) {
|
||||||
if (!cab_modify_header(ctx, hash, outdata))
|
if (!cab_modify_header(ctx, hash, outdata))
|
||||||
return 1; /* FAILED */
|
return 0; /* FAILED */
|
||||||
} else {
|
} else {
|
||||||
if (!cab_add_header(ctx, hash, outdata))
|
if (!cab_add_header(ctx, hash, outdata))
|
||||||
return 1; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
return 0; /* OK */
|
return 1; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -500,26 +505,26 @@ static PKCS7 *cab_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
|
|||||||
PKCS7 *p7 = pkcs7_create(ctx);
|
PKCS7 *p7 = pkcs7_create(ctx);
|
||||||
|
|
||||||
if (!p7) {
|
if (!p7) {
|
||||||
printf("Creating a new signature failed\n");
|
fprintf(stderr, "Creating a new signature failed\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (ctx->options->jp >= 0 && !cab_add_jp_attribute(p7, ctx->options->jp)) {
|
if (ctx->options->jp >= 0 && !cab_add_jp_attribute(p7, ctx->options->jp)) {
|
||||||
printf("Adding jp attribute failed\n");
|
fprintf(stderr, "Adding jp attribute failed\n");
|
||||||
PKCS7_free(p7);
|
PKCS7_free(p7);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (!add_indirect_data_object(p7)) {
|
if (!add_indirect_data_object(p7)) {
|
||||||
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n");
|
fprintf(stderr, "Adding SPC_INDIRECT_DATA_OBJID failed\n");
|
||||||
PKCS7_free(p7);
|
PKCS7_free(p7);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
content = spc_indirect_data_content_get(hash, ctx);
|
content = spc_indirect_data_content_get(hash, ctx);
|
||||||
if (!content) {
|
if (!content) {
|
||||||
printf("Failed to get spcIndirectDataContent\n");
|
fprintf(stderr, "Failed to get spcIndirectDataContent\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (!sign_spc_indirect_data_content(p7, content)) {
|
if (!sign_spc_indirect_data_content(p7, content)) {
|
||||||
printf("Failed to set signed content\n");
|
fprintf(stderr, "Failed to set signed content\n");
|
||||||
PKCS7_free(p7);
|
PKCS7_free(p7);
|
||||||
ASN1_OCTET_STRING_free(content);
|
ASN1_OCTET_STRING_free(content);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
@@ -546,7 +551,7 @@ static int cab_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
|||||||
|
|
||||||
if (((len = i2d_PKCS7(p7, NULL)) <= 0)
|
if (((len = i2d_PKCS7(p7, NULL)) <= 0)
|
||||||
|| (p = OPENSSL_malloc((size_t)len)) == NULL) {
|
|| (p = OPENSSL_malloc((size_t)len)) == NULL) {
|
||||||
printf("i2d_PKCS memory allocation failed: %d\n", len);
|
fprintf(stderr, "i2d_PKCS memory allocation failed: %d\n", len);
|
||||||
return 1; /* FAILED */
|
return 1; /* FAILED */
|
||||||
}
|
}
|
||||||
i2d_PKCS7(p7, &p);
|
i2d_PKCS7(p7, &p);
|
||||||
@@ -643,19 +648,19 @@ static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize)
|
|||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
|
|
||||||
if (filesize < 44) {
|
if (filesize < 44) {
|
||||||
printf("CAB file is too short\n");
|
fprintf(stderr, "CAB file is too short\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
reserved = GET_UINT32_LE(indata + 4);
|
reserved = GET_UINT32_LE(indata + 4);
|
||||||
if (reserved) {
|
if (reserved) {
|
||||||
printf("Reserved1: 0x%08X\n", reserved);
|
fprintf(stderr, "Reserved1: 0x%08X\n", reserved);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
/* flags specify bit-mapped values that indicate the presence of optional data */
|
/* flags specify bit-mapped values that indicate the presence of optional data */
|
||||||
flags = GET_UINT16_LE(indata + 30);
|
flags = GET_UINT16_LE(indata + 30);
|
||||||
if (flags & FLAG_PREV_CABINET) {
|
if (flags & FLAG_PREV_CABINET) {
|
||||||
/* FLAG_NEXT_CABINET works */
|
/* FLAG_NEXT_CABINET works */
|
||||||
printf("Multivolume cabinet file is unsupported: flags 0x%04X\n", flags);
|
fprintf(stderr, "Multivolume cabinet file is unsupported: flags 0x%04X\n", flags);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (flags & FLAG_RESERVE_PRESENT) {
|
if (flags & FLAG_RESERVE_PRESENT) {
|
||||||
@@ -665,12 +670,12 @@ static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize)
|
|||||||
*/
|
*/
|
||||||
header_size = GET_UINT32_LE(indata + 36);
|
header_size = GET_UINT32_LE(indata + 36);
|
||||||
if (header_size != 20) {
|
if (header_size != 20) {
|
||||||
printf("Additional header size: 0x%08X\n", header_size);
|
fprintf(stderr, "Additional header size: 0x%08X\n", header_size);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
reserved = GET_UINT32_LE(indata + 40);
|
reserved = GET_UINT32_LE(indata + 40);
|
||||||
if (reserved != 0x00100000) {
|
if (reserved != 0x00100000) {
|
||||||
printf("abReserved: 0x%08X\n", reserved);
|
fprintf(stderr, "abReserved: 0x%08X\n", reserved);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -679,19 +684,19 @@ static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize)
|
|||||||
* and consist of 4 bytes (little-endian order)
|
* 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);
|
||||||
siglen = GET_UINT32_LE(indata + 48);
|
siglen = GET_UINT32_LE(indata + 48);
|
||||||
if ((sigpos < filesize && sigpos + siglen != filesize) || (sigpos >= filesize)) {
|
if ((sigpos < filesize && sigpos + siglen != filesize) || (sigpos >= filesize)) {
|
||||||
printf("Additional data offset:\t%u bytes\nAdditional data size:\t%u bytes\n",
|
fprintf(stderr, "Additional data offset:\t%u bytes\nAdditional data size:\t%u bytes\n",
|
||||||
sigpos, siglen);
|
sigpos, siglen);
|
||||||
printf("File size:\t\t%u bytes\n", filesize);
|
fprintf(stderr, "File size:\t\t%u bytes\n", filesize);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if ((sigpos > 0 && siglen == 0) || (sigpos == 0 && siglen > 0)) {
|
if ((sigpos > 0 && siglen == 0) || (sigpos == 0 && siglen > 0)) {
|
||||||
printf("Corrupt signature\n");
|
fprintf(stderr, "Corrupt signature\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -802,7 +807,7 @@ static size_t cab_write_optional_names(BIO *outdata, char *indata, size_t i, uin
|
|||||||
*/
|
*/
|
||||||
static int cab_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
static int cab_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
||||||
{
|
{
|
||||||
size_t i, written, len;
|
size_t idx, written, len;
|
||||||
uint16_t nfolders, flags;
|
uint16_t nfolders, flags;
|
||||||
u_char buf[] = {0x00, 0x00};
|
u_char buf[] = {0x00, 0x00};
|
||||||
|
|
||||||
@@ -840,24 +845,32 @@ static int cab_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
/* u4 abReserve: 56-59 */
|
/* u4 abReserve: 56-59 */
|
||||||
BIO_write(hash, ctx->options->indata + 56, 4);
|
BIO_write(hash, ctx->options->indata + 56, 4);
|
||||||
|
|
||||||
i = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
|
idx = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
|
||||||
|
if (idx >= ctx->cab_ctx->fileend) {
|
||||||
|
fprintf(stderr, "Corrupt CAB file - too short\n");
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* (u8 * cFolders) CFFOLDER - structure contains information about
|
* (u8 * cFolders) CFFOLDER - structure contains information about
|
||||||
* one of the folders or partial folders stored in this cabinet file
|
* one of the folders or partial folders stored in this cabinet file
|
||||||
*/
|
*/
|
||||||
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
|
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
|
||||||
|
if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) {
|
||||||
|
fprintf(stderr, "Corrupt cFolders value: 0x%08X\n", nfolders);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
while (nfolders) {
|
while (nfolders) {
|
||||||
BIO_write(hash, ctx->options->indata + i, 8);
|
BIO_write(hash, ctx->options->indata + idx, 8);
|
||||||
i += 8;
|
idx += 8;
|
||||||
nfolders--;
|
nfolders--;
|
||||||
}
|
}
|
||||||
/* Write what's left - the compressed data bytes */
|
/* Write what's left - the compressed data bytes */
|
||||||
len = ctx->cab_ctx->sigpos - i;
|
len = ctx->cab_ctx->sigpos - idx;
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
if (!BIO_write_ex(hash, ctx->options->indata + i, len, &written))
|
if (!BIO_write_ex(hash, ctx->options->indata + idx, len, &written))
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
len -= written;
|
len -= written;
|
||||||
i += written;
|
idx += written;
|
||||||
}
|
}
|
||||||
return 1; /* OK */
|
return 1; /* OK */
|
||||||
}
|
}
|
||||||
@@ -871,7 +884,7 @@ static int cab_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
*/
|
*/
|
||||||
static int cab_add_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
static int cab_add_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
||||||
{
|
{
|
||||||
size_t i, written, len;
|
size_t idx, written, len;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
uint16_t nfolders, flags;
|
uint16_t nfolders, flags;
|
||||||
u_char cabsigned[] = {
|
u_char cabsigned[] = {
|
||||||
@@ -916,29 +929,39 @@ static int cab_add_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
BIO_write(outdata, cabsigned, 20);
|
BIO_write(outdata, cabsigned, 20);
|
||||||
BIO_write(hash, cabsigned+20, 4);
|
BIO_write(hash, cabsigned+20, 4);
|
||||||
|
|
||||||
i = cab_write_optional_names(outdata, ctx->options->indata, 36, flags);
|
idx = cab_write_optional_names(outdata, ctx->options->indata, 36, flags);
|
||||||
|
if (idx >= ctx->cab_ctx->fileend) {
|
||||||
|
fprintf(stderr, "Corrupt CAB file - too short\n");
|
||||||
|
OPENSSL_free(buf);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* (u8 * cFolders) CFFOLDER - structure contains information about
|
* (u8 * cFolders) CFFOLDER - structure contains information about
|
||||||
* one of the folders or partial folders stored in this cabinet file
|
* one of the folders or partial folders stored in this cabinet file
|
||||||
*/
|
*/
|
||||||
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
|
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
|
||||||
|
if (nfolders * 8 >= ctx->cab_ctx->fileend - idx) {
|
||||||
|
fprintf(stderr, "Corrupt cFolders value: 0x%08X\n", nfolders);
|
||||||
|
OPENSSL_free(buf);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
while (nfolders) {
|
while (nfolders) {
|
||||||
tmp = GET_UINT32_LE(ctx->options->indata + i);
|
tmp = GET_UINT32_LE(ctx->options->indata + idx);
|
||||||
tmp += 24;
|
tmp += 24;
|
||||||
PUT_UINT32_LE(tmp, buf);
|
PUT_UINT32_LE(tmp, buf);
|
||||||
BIO_write(hash, buf, 4);
|
BIO_write(hash, buf, 4);
|
||||||
BIO_write(hash, ctx->options->indata + i + 4, 4);
|
BIO_write(hash, ctx->options->indata + idx + 4, 4);
|
||||||
i += 8;
|
idx += 8;
|
||||||
nfolders--;
|
nfolders--;
|
||||||
}
|
}
|
||||||
OPENSSL_free(buf);
|
OPENSSL_free(buf);
|
||||||
/* Write what's left - the compressed data bytes */
|
/* Write what's left - the compressed data bytes */
|
||||||
len = ctx->cab_ctx->fileend - i;
|
len = ctx->cab_ctx->fileend - idx;
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
if (!BIO_write_ex(hash, ctx->options->indata + i, len, &written))
|
if (!BIO_write_ex(hash, ctx->options->indata + idx, len, &written))
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
len -= written;
|
len -= written;
|
||||||
i += written;
|
idx += written;
|
||||||
}
|
}
|
||||||
return 1; /* OK */
|
return 1; /* OK */
|
||||||
}
|
}
|
||||||
@@ -951,16 +974,16 @@ static int cab_add_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
static int cab_check_file(FILE_FORMAT_CTX *ctx)
|
static int cab_check_file(FILE_FORMAT_CTX *ctx)
|
||||||
{
|
{
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
printf("Init error\n\n");
|
fprintf(stderr, "Init error\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
if (ctx->cab_ctx->header_size != 20) {
|
if (ctx->cab_ctx->header_size != 20) {
|
||||||
printf("No signature found\n\n");
|
fprintf(stderr, "No signature found\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
if (ctx->cab_ctx->sigpos == 0 || ctx->cab_ctx->siglen == 0
|
if (ctx->cab_ctx->sigpos == 0 || ctx->cab_ctx->siglen == 0
|
||||||
|| ctx->cab_ctx->sigpos > ctx->cab_ctx->fileend) {
|
|| ctx->cab_ctx->sigpos > ctx->cab_ctx->fileend) {
|
||||||
printf("No signature found\n\n");
|
fprintf(stderr, "No signature found\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
return 1; /* OK */
|
return 1; /* OK */
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -82,7 +82,7 @@ static FILE_FORMAT_CTX *cat_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *out
|
|||||||
uint32_t filesize;
|
uint32_t filesize;
|
||||||
|
|
||||||
if (options->cmd == CMD_REMOVE || options->cmd==CMD_ATTACH || options->cmd == CMD_EXTRACT_DATA) {
|
if (options->cmd == CMD_REMOVE || options->cmd==CMD_ATTACH || options->cmd == CMD_EXTRACT_DATA) {
|
||||||
printf("Unsupported command\n");
|
fprintf(stderr, "Unsupported command\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
filesize = get_file_size(options->infile);
|
filesize = get_file_size(options->infile);
|
||||||
@@ -158,18 +158,23 @@ static PKCS7 *cat_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
|
|||||||
|
|
||||||
p7 = pkcs7_create(ctx);
|
p7 = pkcs7_create(ctx);
|
||||||
if (!p7) {
|
if (!p7) {
|
||||||
printf("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)) {
|
if (!ctx->cat_ctx->p7 || !ctx->cat_ctx->p7->d.sign || !ctx->cat_ctx->p7->d.sign->contents) {
|
||||||
printf("Adding MS_CTL_OBJID failed\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)) {
|
||||||
printf("Failed to set signed content\n");
|
fprintf(stderr, "Adding content type failed\n");
|
||||||
PKCS7_free(p7);
|
PKCS7_free(p7);
|
||||||
return 0; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
|
if (!cat_sign_content(p7, ctx->cat_ctx->p7->d.sign->contents)) {
|
||||||
|
fprintf(stderr, "Failed to set signed content\n");
|
||||||
|
PKCS7_free(p7);
|
||||||
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
return p7; /* OK */
|
return p7; /* OK */
|
||||||
}
|
}
|
||||||
@@ -246,15 +251,30 @@ static CAT_CTX *cat_ctx_get(char *indata, uint32_t filesize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add "1.3.6.1.4.1.311.10.1" MS_CTL_OBJID signed attribute
|
* Add a content type OID to the PKCS#7 signature structure.
|
||||||
|
* The content type can be:
|
||||||
|
* - "1.3.6.1.4.1.311.10.1" (MS_CTL_OBJID) for Certificate Trust Lists (CTL),
|
||||||
|
* - "1.3.6.1.4.1.311.2.1.4" (SPC_INDIRECT_DATA_OBJID) for Authenticode data.
|
||||||
* [in, out] p7: new PKCS#7 signature
|
* [in, 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 */
|
||||||
@@ -262,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 */
|
||||||
}
|
}
|
||||||
@@ -275,24 +295,41 @@ 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;
|
const unsigned char *sequence_data;
|
||||||
int seqhdrlen, content_length;
|
const unsigned char *content;
|
||||||
|
ASN1_STRING *sequence;
|
||||||
|
int seqhdrlen, sequence_len, content_length;
|
||||||
|
|
||||||
seqhdrlen = asn1_simple_hdr_len(contents->d.other->value.sequence->data,
|
if (!contents->d.other || !contents->d.other->value.sequence) {
|
||||||
contents->d.other->value.sequence->length);
|
fprintf(stderr, "Failed to get content value\n");
|
||||||
content = contents->d.other->value.sequence->data + seqhdrlen;
|
return 0; /* FAILED */
|
||||||
content_length = contents->d.other->value.sequence->length - seqhdrlen;
|
}
|
||||||
|
|
||||||
|
sequence = contents->d.other->value.sequence;
|
||||||
|
sequence_data = ASN1_STRING_get0_data(sequence);
|
||||||
|
sequence_len = ASN1_STRING_length(sequence);
|
||||||
|
|
||||||
|
if (!sequence_data) {
|
||||||
|
fprintf(stderr, "Failed to get content value\n");
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
|
||||||
|
seqhdrlen = asn1_simple_hdr_len(sequence_data, sequence_len);
|
||||||
|
content = (const unsigned char *)sequence_data + seqhdrlen;
|
||||||
|
content_length = sequence_len - seqhdrlen;
|
||||||
|
|
||||||
if (!pkcs7_sign_content(p7, content, content_length)) {
|
if (!pkcs7_sign_content(p7, content, content_length)) {
|
||||||
printf("Failed to sign content\n");
|
fprintf(stderr, "Failed to sign content\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PKCS7_set_content(p7, PKCS7_dup(contents))) {
|
if (!PKCS7_set_content(p7, PKCS7_dup(contents))) {
|
||||||
printf("PKCS7_set_content failed\n");
|
fprintf(stderr, "PKCS7_set_content failed\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1; /* OK */
|
return 1; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +345,7 @@ static int cat_list_content(PKCS7 *p7)
|
|||||||
|
|
||||||
ctlc = ms_ctl_content_get(p7);
|
ctlc = ms_ctl_content_get(p7);
|
||||||
if (!ctlc) {
|
if (!ctlc) {
|
||||||
printf("Failed to extract MS_CTL_OBJID data\n");
|
fprintf(stderr, "Failed to extract MS_CTL_OBJID data\n");
|
||||||
return 1; /* FAILED */
|
return 1; /* FAILED */
|
||||||
}
|
}
|
||||||
printf("\nCatalog members:\n");
|
printf("\nCatalog members:\n");
|
||||||
@@ -343,7 +380,7 @@ static int cat_list_content(PKCS7 *p7)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
MsCtlContent_free(ctlc);
|
MsCtlContent_free(ctlc);
|
||||||
ERR_print_errors_fp(stdout);
|
ERR_print_errors_fp(stderr);
|
||||||
return 0; /* OK */
|
return 0; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,27 +393,22 @@ static int cat_print_content_member_digest(ASN1_TYPE *content)
|
|||||||
{
|
{
|
||||||
SpcIndirectDataContent *idc;
|
SpcIndirectDataContent *idc;
|
||||||
u_char mdbuf[EVP_MAX_MD_SIZE];
|
u_char mdbuf[EVP_MAX_MD_SIZE];
|
||||||
const u_char *data ;
|
|
||||||
int mdtype = -1;
|
int mdtype = -1;
|
||||||
ASN1_STRING *value;
|
|
||||||
|
|
||||||
value = content->value.sequence;
|
idc = asn1_type_get_indirect_data_content(content);
|
||||||
data = ASN1_STRING_get0_data(value);
|
|
||||||
idc = d2i_SpcIndirectDataContent(NULL, &data, ASN1_STRING_length(value));
|
|
||||||
if (!idc)
|
if (!idc)
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
|
||||||
/* get a digest algorithm a message digest of the file from the content */
|
if (spc_indirect_data_content_get_digest(idc, mdbuf, &mdtype) < 0) {
|
||||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
fprintf(stderr, "Failed to extract message digest from signature\n\n");
|
||||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
SpcIndirectDataContent_free(idc);
|
||||||
}
|
|
||||||
SpcIndirectDataContent_free(idc);
|
|
||||||
if (mdtype == -1) {
|
|
||||||
printf("Failed to extract current message digest\n\n");
|
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
|
SpcIndirectDataContent_free(idc);
|
||||||
|
|
||||||
printf("\tHash algorithm: %s\n", OBJ_nid2sn(mdtype));
|
printf("\tHash algorithm: %s\n", OBJ_nid2sn(mdtype));
|
||||||
print_hash("\tMessage digest", "", mdbuf, EVP_MD_size(EVP_get_digestbynid(mdtype)));
|
print_hash("\tMessage digest", "", mdbuf, EVP_MD_size(EVP_get_digestbynid(mdtype)));
|
||||||
|
|
||||||
return 1; /* OK */
|
return 1; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,17 +483,17 @@ static int cat_check_file(FILE_FORMAT_CTX *ctx)
|
|||||||
PKCS7_SIGNER_INFO *si;
|
PKCS7_SIGNER_INFO *si;
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
printf("Init error\n\n");
|
fprintf(stderr, "Init error\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
signer_info = PKCS7_get_signer_info(ctx->cat_ctx->p7);
|
signer_info = PKCS7_get_signer_info(ctx->cat_ctx->p7);
|
||||||
if (!signer_info) {
|
if (!signer_info) {
|
||||||
printf("Failed catalog file\n\n");
|
fprintf(stderr, "Failed catalog file\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
|
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
|
||||||
if (!si) {
|
if (!si) {
|
||||||
printf("No signature found\n\n");
|
fprintf(stderr, "No signature found\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
if (ctx->options->verbose) {
|
if (ctx->options->verbose) {
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# documentation with Pandoc
|
||||||
|
# cmake --build .
|
||||||
|
|
||||||
|
find_program(PANDOC pandoc)
|
||||||
|
|
||||||
|
if(NOT PANDOC)
|
||||||
|
message(WARNING "CMakeDoc: pandoc not found, documentation disabled")
|
||||||
|
return()
|
||||||
|
endif(NOT PANDOC)
|
||||||
|
|
||||||
|
set(DOC_MD "${PROJECT_SOURCE_DIR}/osslsigncode.md")
|
||||||
|
|
||||||
|
if(NOT EXISTS "${DOC_MD}")
|
||||||
|
message(WARNING "CMakeDoc: markdown source not found: ${DOC_MD}")
|
||||||
|
return()
|
||||||
|
endif(NOT EXISTS "${DOC_MD}")
|
||||||
|
|
||||||
|
set(MAN_PAGE "${PROJECT_BINARY_DIR}/osslsigncode.1")
|
||||||
|
set(HTML_PAGE "${PROJECT_BINARY_DIR}/osslsigncode.html")
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${MAN_PAGE}"
|
||||||
|
COMMAND "${PANDOC}" -s "${DOC_MD}" -t man -o "${MAN_PAGE}"
|
||||||
|
DEPENDS "${DOC_MD}"
|
||||||
|
COMMENT "CMakeDoc: generating man page"
|
||||||
|
VERBATIM)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${HTML_PAGE}"
|
||||||
|
COMMAND "${PANDOC}" -s --toc --toc-depth=2 "${DOC_MD}" -t html -o "${HTML_PAGE}"
|
||||||
|
DEPENDS "${DOC_MD}"
|
||||||
|
COMMENT "CMakeDoc: generating HTML documentation"
|
||||||
|
VERBATIM)
|
||||||
|
|
||||||
|
add_custom_target(docs ALL DEPENDS "${MAN_PAGE}" "${HTML_PAGE}")
|
||||||
|
|
||||||
|
#[[
|
||||||
|
Local Variables:
|
||||||
|
c-basic-offset: 4
|
||||||
|
tab-width: 4
|
||||||
|
indent-tabs-mode: nil
|
||||||
|
End:
|
||||||
|
vim: set ts=4 expandtab:
|
||||||
|
]]
|
||||||
+513
-664
File diff suppressed because it is too large
Load Diff
@@ -96,16 +96,11 @@ function(add_compile_flags target)
|
|||||||
message(WARNING "No stack protection supported")
|
message(WARNING "No stack protection supported")
|
||||||
endif(HAVE_STACK_PROTECTOR)
|
endif(HAVE_STACK_PROTECTOR)
|
||||||
endif(HAVE_STACK_PROTECTOR_ALL)
|
endif(HAVE_STACK_PROTECTOR_ALL)
|
||||||
# Support address space layout randomization (ASLR)
|
# Support address space layout randomization (ASLR) / PIE
|
||||||
if(NOT (MINGW OR CYGWIN OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
|
if(UNIX AND NOT APPLE)
|
||||||
OR ((CMAKE_SYSTEM_NAME MATCHES Darwin) AND (CMAKE_C_COMPILER_ID MATCHES Clang))))
|
|
||||||
target_compile_options(${target} PRIVATE -fPIE)
|
target_compile_options(${target} PRIVATE -fPIE)
|
||||||
target_link_options(${target} PRIVATE -fPIE -pie)
|
target_link_options(${target} PRIVATE -fPIE -pie -Wl,-z,relro,-z,now,-z,noexecstack)
|
||||||
target_link_options(${target} PRIVATE -Wl,-z,relro)
|
endif(UNIX AND NOT APPLE)
|
||||||
target_link_options(${target} PRIVATE -Wl,-z,now)
|
|
||||||
target_link_options(${target} PRIVATE -Wl,-z,noexecstack)
|
|
||||||
endif(NOT (MINGW OR CYGWIN OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
|
|
||||||
OR ((CMAKE_SYSTEM_NAME MATCHES Darwin) AND (CMAKE_C_COMPILER_ID MATCHES Clang))))
|
|
||||||
target_link_options(${target} PRIVATE -fstack-check)
|
target_link_options(${target} PRIVATE -fstack-check)
|
||||||
add_compile_flag_to_targets(${target})
|
add_compile_flag_to_targets(${target})
|
||||||
endif(MSVC)
|
endif(MSVC)
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# uninstall target
|
||||||
|
#
|
||||||
|
# CMake does not provide a built-in uninstall target.
|
||||||
|
# This target removes files listed in install_manifest.txt,
|
||||||
|
# generated by the install step.
|
||||||
|
#
|
||||||
|
# cmake --build . --target uninstall
|
||||||
|
|
||||||
|
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||||
|
message(FATAL_ERROR "Cannot find install manifest")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||||
|
string(REPLACE "\n" ";" files "${files}")
|
||||||
|
|
||||||
|
foreach(file ${files})
|
||||||
|
message(STATUS "Removing ${file}")
|
||||||
|
|
||||||
|
if(EXISTS "${file}" OR IS_SYMLINK "${file}")
|
||||||
|
file(REMOVE "${file}")
|
||||||
|
else()
|
||||||
|
message(STATUS "File does not exist: ${file}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
+9741
File diff suppressed because it is too large
Load Diff
Executable
+52
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
# © 2024 Michal Trojnara
|
||||||
|
# This script downloads Microsoft code signing certificates
|
||||||
|
# Tor is required for this script to work
|
||||||
|
# Redirect the script output to a PEM file
|
||||||
|
|
||||||
|
from sys import stderr
|
||||||
|
from time import sleep
|
||||||
|
from csv import reader
|
||||||
|
from requests import get
|
||||||
|
from requests.exceptions import RequestException
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
from re import search
|
||||||
|
|
||||||
|
def download_cert(hash):
|
||||||
|
for attempt in range(10):
|
||||||
|
if attempt > 0:
|
||||||
|
sleep(10)
|
||||||
|
try:
|
||||||
|
creds = f'{attempt}{hash}:{attempt}{hash}'
|
||||||
|
proxies = dict(https=f'socks5://{creds}@127.0.0.1:9050')
|
||||||
|
|
||||||
|
url = f'https://crt.sh/?sha1={hash}&match=='
|
||||||
|
resp = get(url, proxies=proxies)
|
||||||
|
resp.raise_for_status()
|
||||||
|
|
||||||
|
m = search(r'\bid=(\d+)\b', resp.content.decode('ascii', 'replace'))
|
||||||
|
id = m.group(1)
|
||||||
|
|
||||||
|
url = f'https://crt.sh/?d={id}'
|
||||||
|
resp = get(url, proxies=proxies)
|
||||||
|
resp.raise_for_status()
|
||||||
|
|
||||||
|
print('.', file=stderr, end='')
|
||||||
|
stderr.flush()
|
||||||
|
return resp.content.decode('utf-8', 'replace')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'\n{url} attempt {attempt}: {e}', file=stderr)
|
||||||
|
print('\nGiving up on', hash, file=stderr)
|
||||||
|
|
||||||
|
resp = get('https://ccadb.my.salesforce-sites.com/microsoft/IncludedCACertificateReportForMSFTCSV')
|
||||||
|
resp.raise_for_status()
|
||||||
|
lines = resp.content.decode('utf-8').splitlines()[1:]
|
||||||
|
hashes = [row[4] for row in reader(lines)
|
||||||
|
if row[0] != 'Disabled'
|
||||||
|
or row[4] == 'F38406E540D7A9D90CB4A9479299640FFB6DF9E224ECC7A01C0D9558D8DAD77D']
|
||||||
|
with ThreadPoolExecutor(max_workers=10) as executor:
|
||||||
|
certs = executor.map(download_cert, hashes)
|
||||||
|
for cert in certs:
|
||||||
|
if cert is not None:
|
||||||
|
print(cert)
|
||||||
|
print('\nDone', file=stderr)
|
||||||
@@ -17,6 +17,7 @@ static int pkcs7_signer_info_add_purpose(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX
|
|||||||
static int pkcs7_signer_info_add_sequence_number(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
static int pkcs7_signer_info_add_sequence_number(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||||
static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer);
|
static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer);
|
||||||
static int X509_compare(const X509 *const *a, const X509 *const *b);
|
static int X509_compare(const X509 *const *a, const X509 *const *b);
|
||||||
|
static void sk_X509_remove_duplicates(STACK_OF(X509) *chain);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common functions
|
* Common functions
|
||||||
@@ -37,16 +38,16 @@ uint32_t get_file_size(const char *infile)
|
|||||||
ret = stat(infile, &st);
|
ret = stat(infile, &st);
|
||||||
#endif
|
#endif
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("Failed to open file: %s\n", infile);
|
fprintf(stderr, "Failed to open file: %s\n", infile);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st.st_size < 4) {
|
if (st.st_size < 4) {
|
||||||
printf("Unrecognized file type - file is too short: %s\n", infile);
|
fprintf(stderr, "Unrecognized file type - file is too short: %s\n", infile);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (st.st_size > UINT32_MAX) {
|
if (st.st_size > UINT32_MAX) {
|
||||||
printf("Unsupported file - too large: %s\n", infile);
|
fprintf(stderr, "Unsupported file - too large: %s\n", infile);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return (uint32_t)st.st_size;
|
return (uint32_t)st.st_size;
|
||||||
@@ -86,7 +87,7 @@ char *map_file(const char *infile, const size_t size)
|
|||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
#else
|
#else
|
||||||
printf("No file mapping function\n");
|
fprintf(stderr, "No file mapping function\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif /* HAVE_SYS_MMAN_H */
|
#endif /* HAVE_SYS_MMAN_H */
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
@@ -152,7 +153,7 @@ int data_write_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
|||||||
ret = !i2d_PKCS7_bio(outdata, p7);
|
ret = !i2d_PKCS7_bio(outdata, p7);
|
||||||
}
|
}
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("Unable to write pkcs7 object\n");
|
fprintf(stderr, "Unable to write pkcs7 object\n");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -165,73 +166,76 @@ int data_write_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
|||||||
PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx)
|
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) {
|
|
||||||
printf("Failed to checking the consistency of a private key: %s\n",
|
|
||||||
ctx->options->keyfile);
|
|
||||||
printf(" with a public key in any X509 certificate: %s\n\n",
|
|
||||||
ctx->options->certfile);
|
|
||||||
return NULL; /* FAILED */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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)) {
|
||||||
printf("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) {
|
||||||
printf("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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -278,11 +282,12 @@ int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content)
|
|||||||
inf = ASN1_get_object(&p, &plen, &tag, &class, len);
|
inf = ASN1_get_object(&p, &plen, &tag, &class, len);
|
||||||
if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE
|
if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE
|
||||||
|| !pkcs7_sign_content(p7, p, (int)plen)) {
|
|| !pkcs7_sign_content(p7, p, (int)plen)) {
|
||||||
printf("Failed to sign spcIndirectDataContent\n");
|
fprintf(stderr, "Failed to sign spcIndirectDataContent\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
td7 = PKCS7_new();
|
td7 = PKCS7_new();
|
||||||
if (!td7) {
|
if (!td7) {
|
||||||
|
fprintf(stderr, "PKCS7_new failed\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
td7->type = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1);
|
td7->type = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1);
|
||||||
@@ -291,7 +296,7 @@ int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content)
|
|||||||
td7->d.other->value.sequence = ASN1_STRING_new();
|
td7->d.other->value.sequence = ASN1_STRING_new();
|
||||||
ASN1_STRING_set(td7->d.other->value.sequence, data, len);
|
ASN1_STRING_set(td7->d.other->value.sequence, data, len);
|
||||||
if (!PKCS7_set_content(p7, td7)) {
|
if (!PKCS7_set_content(p7, td7)) {
|
||||||
printf("PKCS7_set_content failed\n");
|
fprintf(stderr, "PKCS7_set_content failed\n");
|
||||||
PKCS7_free(td7);
|
PKCS7_free(td7);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
@@ -336,6 +341,91 @@ PKCS7 *pkcs7_set_content(ASN1_OCTET_STRING *content)
|
|||||||
return p7;
|
return p7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve the message digest and digest algorithm from PKCS7
|
||||||
|
* SpcIndirectDataContent.
|
||||||
|
*
|
||||||
|
* [in] p7: PKCS7 structure containing SPC_INDIRECT_DATA_OBJID content
|
||||||
|
* [out] mdbuf: message digest buffer, at least EVP_MAX_MD_SIZE bytes
|
||||||
|
* [out] mdtype: OpenSSL NID of the digest algorithm
|
||||||
|
* [returns] 0 on error or 1 on success
|
||||||
|
*/
|
||||||
|
int pkcs7_get_content_digest(PKCS7 *p7, u_char *mdbuf, int *mdtype)
|
||||||
|
{
|
||||||
|
SpcIndirectDataContent *idc;
|
||||||
|
|
||||||
|
if (!mdbuf || !mdtype)
|
||||||
|
return 0; /* FAILED */
|
||||||
|
|
||||||
|
*mdtype = -1;
|
||||||
|
|
||||||
|
idc = pkcs7_get_indirect_data_content(p7);
|
||||||
|
if (!idc) {
|
||||||
|
fprintf(stderr, "Failed to decode SpcIndirectDataContent\n\n");
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
if (spc_indirect_data_content_get_digest(idc, mdbuf, mdtype) < 0) {
|
||||||
|
fprintf(stderr, "Failed to extract message digest from signature\n\n");
|
||||||
|
SpcIndirectDataContent_free(idc);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
SpcIndirectDataContent_free(idc);
|
||||||
|
if (*mdtype == -1) {
|
||||||
|
fprintf(stderr, "Failed to extract current message digest\n\n");
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
return 1; /* OK */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode SpcIndirectDataContent from a PKCS7 signedData content.
|
||||||
|
*
|
||||||
|
* [in] p7: PKCS7 structure containing SPC_INDIRECT_DATA_OBJID content
|
||||||
|
* [returns] newly allocated SpcIndirectDataContent, or NULL on error
|
||||||
|
*
|
||||||
|
* The caller is responsible for freeing the returned object with
|
||||||
|
* SpcIndirectDataContent_free().
|
||||||
|
*/
|
||||||
|
SpcIndirectDataContent *pkcs7_get_indirect_data_content(PKCS7 *p7)
|
||||||
|
{
|
||||||
|
if (!is_content_type(p7, SPC_INDIRECT_DATA_OBJID))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!p7->d.sign || !p7->d.sign->contents || !p7->d.sign->contents->d.other)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return asn1_type_get_indirect_data_content(p7->d.sign->contents->d.other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode SpcIndirectDataContent from an ASN1_TYPE object.
|
||||||
|
* The ASN1_TYPE is expected to contain a V_ASN1_SEQUENCE value.
|
||||||
|
*
|
||||||
|
* [in] content: ASN1_TYPE containing DER-encoded SpcIndirectDataContent
|
||||||
|
* [returns] newly allocated SpcIndirectDataContent, or NULL on error
|
||||||
|
*
|
||||||
|
* The caller is responsible for freeing the returned object with
|
||||||
|
* SpcIndirectDataContent_free().
|
||||||
|
*/
|
||||||
|
SpcIndirectDataContent *asn1_type_get_indirect_data_content(ASN1_TYPE *content)
|
||||||
|
{
|
||||||
|
ASN1_STRING *value;
|
||||||
|
const unsigned char *data;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!content || content->type != V_ASN1_SEQUENCE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
value = content->value.sequence;
|
||||||
|
if (!value)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
data = ASN1_STRING_get0_data(value);
|
||||||
|
len = ASN1_STRING_length(value);
|
||||||
|
|
||||||
|
return d2i_SpcIndirectDataContent(NULL, &data, len);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return spcIndirectDataContent.
|
* Return spcIndirectDataContent.
|
||||||
* [in] hash: message digest BIO
|
* [in] hash: message digest BIO
|
||||||
@@ -388,13 +478,13 @@ int pkcs7_sign_content(PKCS7 *p7, const u_char *data, int len)
|
|||||||
BIO *p7bio;
|
BIO *p7bio;
|
||||||
|
|
||||||
if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
|
if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
|
||||||
printf("PKCS7_dataInit failed\n");
|
fprintf(stderr, "PKCS7_dataInit failed\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
BIO_write(p7bio, data, len);
|
BIO_write(p7bio, data, len);
|
||||||
(void)BIO_flush(p7bio);
|
(void)BIO_flush(p7bio);
|
||||||
if (!PKCS7_dataFinal(p7, p7bio)) {
|
if (!PKCS7_dataFinal(p7, p7bio)) {
|
||||||
printf("PKCS7_dataFinal failed\n");
|
fprintf(stderr, "PKCS7_dataFinal failed\n");
|
||||||
BIO_free_all(p7bio);
|
BIO_free_all(p7bio);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
@@ -460,7 +550,7 @@ void print_hash(const char *descript1, const char *descript2, const u_char *mdbu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* [in] p7: new PKCS#7 signature
|
* [in] p7: PKCS#7 signature
|
||||||
* [in] objid: Microsoft OID Authenticode
|
* [in] objid: Microsoft OID Authenticode
|
||||||
* [returns] 0 on error or 1 on success
|
* [returns] 0 on error or 1 on success
|
||||||
*/
|
*/
|
||||||
@@ -470,6 +560,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 ||
|
||||||
@@ -488,7 +582,7 @@ MsCtlContent *ms_ctl_content_get(PKCS7 *p7)
|
|||||||
const u_char *data;
|
const u_char *data;
|
||||||
|
|
||||||
if (!is_content_type(p7, MS_CTL_OBJID)) {
|
if (!is_content_type(p7, MS_CTL_OBJID)) {
|
||||||
printf("Failed to find MS_CTL_OBJID\n");
|
fprintf(stderr, "Failed to find MS_CTL_OBJID\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
value = p7->d.sign->contents->d.other->value.sequence;
|
value = p7->d.sign->contents->d.other->value.sequence;
|
||||||
@@ -554,6 +648,42 @@ int compare_digests(u_char *mdbuf, u_char *cmdbuf, int mdtype)
|
|||||||
return mdok;
|
return mdok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Safely extract digest from SpcIndirectDataContent with bounds checking.
|
||||||
|
* This function validates that the digest length from the ASN.1 structure
|
||||||
|
* does not exceed the destination buffer size, preventing buffer overflows
|
||||||
|
* from maliciously crafted signatures.
|
||||||
|
* [in] idc: parsed SpcIndirectDataContent structure
|
||||||
|
* [out] mdbuf: output buffer (must be at least EVP_MAX_MD_SIZE bytes)
|
||||||
|
* [out] mdtype: digest algorithm NID
|
||||||
|
* [returns] digest length on success, -1 on error
|
||||||
|
*/
|
||||||
|
int spc_indirect_data_content_get_digest(SpcIndirectDataContent *idc, u_char *mdbuf, int *mdtype)
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING *digest_asn1;
|
||||||
|
const unsigned char *digest_data;
|
||||||
|
int digest_len;
|
||||||
|
|
||||||
|
if (!idc || !idc->messageDigest || !idc->messageDigest->digest ||
|
||||||
|
!idc->messageDigest->digestAlgorithm) {
|
||||||
|
return -1; /* FAILED */
|
||||||
|
}
|
||||||
|
digest_asn1 = idc->messageDigest->digest;
|
||||||
|
digest_len = ASN1_STRING_length((ASN1_STRING *)digest_asn1);
|
||||||
|
|
||||||
|
/* Validate digest length to prevent buffer overflow */
|
||||||
|
if (digest_len <= 0 || digest_len > EVP_MAX_MD_SIZE) {
|
||||||
|
fprintf(stderr, "Invalid digest length in signature: %d (expected 1-%d)\n",
|
||||||
|
digest_len, EVP_MAX_MD_SIZE);
|
||||||
|
return -1; /* FAILED */
|
||||||
|
}
|
||||||
|
|
||||||
|
digest_data = ASN1_STRING_get0_data((ASN1_STRING *)digest_asn1);
|
||||||
|
*mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||||
|
memcpy(mdbuf, digest_data, (size_t)digest_len);
|
||||||
|
return digest_len; /* OK */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper functions
|
* Helper functions
|
||||||
*/
|
*/
|
||||||
@@ -609,8 +739,16 @@ static int spc_indirect_data_content_create(u_char **blob, int *len, FILE_FORMAT
|
|||||||
idc->data->value->type = V_ASN1_SEQUENCE;
|
idc->data->value->type = V_ASN1_SEQUENCE;
|
||||||
idc->data->value->value.sequence = ASN1_STRING_new();
|
idc->data->value->value.sequence = ASN1_STRING_new();
|
||||||
idc->data->type = ctx->format->data_blob_get(&p, &l, ctx);
|
idc->data->type = ctx->format->data_blob_get(&p, &l, ctx);
|
||||||
idc->data->value->value.sequence->data = p;
|
if (!idc->data->type) {
|
||||||
idc->data->value->value.sequence->length = l;
|
SpcIndirectDataContent_free(idc);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
if (!ASN1_STRING_set(idc->data->value->value.sequence, p, l)) {
|
||||||
|
OPENSSL_free(p);
|
||||||
|
SpcIndirectDataContent_free(idc);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
OPENSSL_free(p);
|
||||||
idc->messageDigest->digestAlgorithm->algorithm = OBJ_nid2obj(mdtype);
|
idc->messageDigest->digestAlgorithm->algorithm = OBJ_nid2obj(mdtype);
|
||||||
idc->messageDigest->digestAlgorithm->parameters = ASN1_TYPE_new();
|
idc->messageDigest->digestAlgorithm->parameters = ASN1_TYPE_new();
|
||||||
idc->messageDigest->digestAlgorithm->parameters->type = V_ASN1_NULL;
|
idc->messageDigest->digestAlgorithm->parameters->type = V_ASN1_NULL;
|
||||||
@@ -731,11 +869,6 @@ static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer)
|
|||||||
int i;
|
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;
|
||||||
@@ -760,6 +893,9 @@ static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer)
|
|||||||
}
|
}
|
||||||
/* sort certificate chain using the supplied comparison function */
|
/* sort certificate chain using the supplied comparison function */
|
||||||
sk_X509_sort(chain);
|
sk_X509_sort(chain);
|
||||||
|
/* remove duplicates */
|
||||||
|
sk_X509_remove_duplicates(chain);
|
||||||
|
|
||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,6 +914,15 @@ static int X509_compare(const X509 *const *a, const X509 *const *b)
|
|||||||
size_t a_len, b_len;
|
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);
|
||||||
@@ -785,6 +930,13 @@ static int X509_compare(const X509 *const *a, const X509 *const *b)
|
|||||||
b_len = (size_t)i2d_X509(*b, NULL);
|
b_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);
|
||||||
@@ -795,6 +947,35 @@ static int X509_compare(const X509 *const *a, const X509 *const *b)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove duplicate certificates from a sorted STACK_OF(X509).
|
||||||
|
*
|
||||||
|
* This function assumes the stack is sorted according to X.690-compliant
|
||||||
|
* certificate comparison, so duplicate certificates appear consecutively.
|
||||||
|
* It iterates through the stack and removes any duplicate certificates
|
||||||
|
* by comparing each element with its immediate predecessor.
|
||||||
|
* The stack is modified in place.
|
||||||
|
*/
|
||||||
|
static void sk_X509_remove_duplicates(STACK_OF(X509) *chain)
|
||||||
|
{
|
||||||
|
int i, n = sk_X509_num(chain);
|
||||||
|
|
||||||
|
if (n < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* start from the second element */
|
||||||
|
for (i = 1; i < n; ) {
|
||||||
|
if (!X509_cmp(sk_X509_value(chain, i - 1), sk_X509_value(chain, i))) {
|
||||||
|
/* duplicate found: remove the certificate at index i */
|
||||||
|
(void)sk_X509_delete(chain, i);
|
||||||
|
n--; /* reduce stack size since one element was removed */
|
||||||
|
/* do not increment i, as next element shifts into index i */
|
||||||
|
} else {
|
||||||
|
i++; /* advance only if no removal was done */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Local Variables:
|
Local Variables:
|
||||||
c-basic-offset: 4
|
c-basic-offset: 4
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx);
|
|||||||
int add_indirect_data_object(PKCS7 *p7);
|
int add_indirect_data_object(PKCS7 *p7);
|
||||||
int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content);
|
int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content);
|
||||||
PKCS7 *pkcs7_set_content(ASN1_OCTET_STRING *content);
|
PKCS7 *pkcs7_set_content(ASN1_OCTET_STRING *content);
|
||||||
|
int pkcs7_get_content_digest(PKCS7 *p7, u_char *mdbuf, int *mdtype);
|
||||||
|
SpcIndirectDataContent *pkcs7_get_indirect_data_content(PKCS7 *p7);
|
||||||
|
SpcIndirectDataContent *asn1_type_get_indirect_data_content(ASN1_TYPE *content);
|
||||||
ASN1_OCTET_STRING *spc_indirect_data_content_get(BIO *hash, FILE_FORMAT_CTX *ctx);
|
ASN1_OCTET_STRING *spc_indirect_data_content_get(BIO *hash, FILE_FORMAT_CTX *ctx);
|
||||||
int pkcs7_sign_content(PKCS7 *p7, const u_char *data, int len);
|
int pkcs7_sign_content(PKCS7 *p7, const u_char *data, int len);
|
||||||
int asn1_simple_hdr_len(const u_char *p, int len);
|
int asn1_simple_hdr_len(const u_char *p, int len);
|
||||||
@@ -25,6 +28,7 @@ MsCtlContent *ms_ctl_content_get(PKCS7 *p7);
|
|||||||
ASN1_TYPE *catalog_content_get(CatalogAuthAttr *attribute);
|
ASN1_TYPE *catalog_content_get(CatalogAuthAttr *attribute);
|
||||||
SpcLink *spc_link_obsolete_get(void);
|
SpcLink *spc_link_obsolete_get(void);
|
||||||
int compare_digests(u_char *mdbuf, u_char *cmdbuf, int mdtype);
|
int compare_digests(u_char *mdbuf, u_char *cmdbuf, int mdtype);
|
||||||
|
int spc_indirect_data_content_get_digest(SpcIndirectDataContent *idc, u_char *mdbuf, int *mdtype);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Local Variables:
|
Local Variables:
|
||||||
|
|||||||
+1636
-817
File diff suppressed because it is too large
Load Diff
+41
-6
@@ -14,6 +14,7 @@
|
|||||||
#define NOCRYPT
|
#define NOCRYPT
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
#endif /* HAVE_WINDOWS_H */
|
#endif /* HAVE_WINDOWS_H */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
#ifdef HAVE_SYS_MMAN_H
|
#ifdef HAVE_SYS_MMAN_H
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif /* HAVE_SYS_MMAN_H */
|
#endif /* HAVE_SYS_MMAN_H */
|
||||||
@@ -63,7 +65,10 @@
|
|||||||
#endif /* OPENSSL_VERSION_NUMBER>=0x30000000L */
|
#endif /* OPENSSL_VERSION_NUMBER>=0x30000000L */
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/safestack.h>
|
#include <openssl/safestack.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 */
|
||||||
|
|
||||||
@@ -76,6 +81,8 @@
|
|||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#endif /* ENABLE_CURL */
|
#endif /* ENABLE_CURL */
|
||||||
|
|
||||||
|
/* Request nonce length, in bits (must be a multiple of 8). */
|
||||||
|
#define NONCE_LENGTH 64
|
||||||
#define MAX_TS_SERVERS 256
|
#define MAX_TS_SERVERS 256
|
||||||
|
|
||||||
#if defined (HAVE_TERMIOS_H) || defined (HAVE_GETPASS)
|
#if defined (HAVE_TERMIOS_H) || defined (HAVE_GETPASS)
|
||||||
@@ -85,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)
|
||||||
@@ -216,9 +225,9 @@
|
|||||||
*/
|
*/
|
||||||
#define FLAG_RESERVE_PRESENT 0x0004
|
#define FLAG_RESERVE_PRESENT 0x0004
|
||||||
|
|
||||||
#define DO_EXIT_0(x) { printf(x); goto err_cleanup; }
|
#define DO_EXIT_0(x) { fprintf(stderr, x); goto err_cleanup; }
|
||||||
#define DO_EXIT_1(x, y) { printf(x, y); goto err_cleanup; }
|
#define DO_EXIT_1(x, y) { fprintf(stderr, x, y); goto err_cleanup; }
|
||||||
#define DO_EXIT_2(x, y, z) { printf(x, y, z); goto err_cleanup; }
|
#define DO_EXIT_2(x, y, z) { fprintf(stderr, x, y, z); goto err_cleanup; }
|
||||||
|
|
||||||
/* Default policy if request did not specify it. */
|
/* Default policy if request did not specify it. */
|
||||||
#define TSA_POLICY1 "1.2.3.4.1"
|
#define TSA_POLICY1 "1.2.3.4.1"
|
||||||
@@ -237,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;
|
||||||
@@ -249,9 +268,13 @@ typedef struct {
|
|||||||
int output_pkcs7;
|
int output_pkcs7;
|
||||||
#ifndef OPENSSL_NO_ENGINE
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
char *p11engine;
|
char *p11engine;
|
||||||
|
STACK_OF(EngineControl) *engine_ctrls;
|
||||||
|
int login;
|
||||||
|
#endif /* OPENSSL_NO_ENGINE */
|
||||||
|
#if !defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER>=0x30000000L
|
||||||
char *p11module;
|
char *p11module;
|
||||||
char *p11cert;
|
char *p11cert;
|
||||||
#endif /* OPENSSL_NO_ENGINE */
|
#endif /* !defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER>=0x30000000L */
|
||||||
int askpass;
|
int askpass;
|
||||||
char *readpass;
|
char *readpass;
|
||||||
char *pass;
|
char *pass;
|
||||||
@@ -268,24 +291,28 @@ 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;
|
||||||
int ignore_cdp;
|
int ignore_cdp;
|
||||||
|
int ignore_crl;
|
||||||
int verbose;
|
int verbose;
|
||||||
int add_msi_dse;
|
int add_msi_dse;
|
||||||
char *catalog;
|
char *catalog;
|
||||||
char *cafile;
|
char *cafile;
|
||||||
char *crlfile;
|
char *crlfile;
|
||||||
|
char *https_cafile;
|
||||||
|
char *https_crlfile;
|
||||||
char *tsa_cafile;
|
char *tsa_cafile;
|
||||||
char *tsa_crlfile;
|
char *tsa_crlfile;
|
||||||
char *leafhash;
|
char *leafhash;
|
||||||
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;
|
||||||
@@ -478,6 +505,14 @@ typedef struct {
|
|||||||
|
|
||||||
DECLARE_ASN1_FUNCTIONS(MsCtlContent)
|
DECLARE_ASN1_FUNCTIONS(MsCtlContent)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *server;
|
||||||
|
const char *port;
|
||||||
|
int use_proxy;
|
||||||
|
int timeout;
|
||||||
|
SSL_CTX *ssl_ctx;
|
||||||
|
} HTTP_TLS_Info;
|
||||||
|
|
||||||
typedef struct file_format_st FILE_FORMAT;
|
typedef struct file_format_st FILE_FORMAT;
|
||||||
|
|
||||||
typedef struct script_ctx_st SCRIPT_CTX;
|
typedef struct script_ctx_st SCRIPT_CTX;
|
||||||
|
|||||||
+554
@@ -0,0 +1,554 @@
|
|||||||
|
---
|
||||||
|
title: osslsigncode
|
||||||
|
lang: en-US
|
||||||
|
---
|
||||||
|
|
||||||
|
# NAME
|
||||||
|
|
||||||
|
osslsigncode - Authenticode signing, timestamping, extraction, attachment, removal, and verification tool
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
|
||||||
|
`osslsigncode` [`--help`] [`--version`]
|
||||||
|
|
||||||
|
`osslsigncode` `sign`
|
||||||
|
[`-certs` *file* | `-spc` *file* | `-pkcs12` *file*]
|
||||||
|
[`-key` *file-or-URI*]
|
||||||
|
[`-ac` *file*]
|
||||||
|
[`-pass` *password* | `-readpass` *file* | `-askpass`]
|
||||||
|
[`-pkcs11module` *module*] [`-pkcs11cert` *URI*]
|
||||||
|
[`-engine` *engine*] [`-provider` *provider*]
|
||||||
|
[`-login`] [`-engineCtrl` *command*[:*parameter*]]
|
||||||
|
[`-h` *digest*]
|
||||||
|
[`-n` *description*] [`-i` *URL*]
|
||||||
|
[`-jp` `low`] [`-comm`] [`-ph`]
|
||||||
|
[`-t` *URL* ... | `-ts` *URL* ...]
|
||||||
|
[`-TSA-certs` *file* `-TSA-key` *file-or-URI* [`-TSA-time` *unix-time*]]
|
||||||
|
[`-HTTPS-CAfile` *file*] [`-HTTPS-CRLfile` *file*]
|
||||||
|
[`-time` *unix-time*]
|
||||||
|
[`-addUnauthenticatedBlob` [`-blobFile` *file*]]
|
||||||
|
[`-nest`] [`-add-msi-dse`] [`-verbose`] [`-pem`]
|
||||||
|
`-in` *input* `-out` *output*
|
||||||
|
|
||||||
|
`osslsigncode` `extract-data`
|
||||||
|
[`-pem`] [`-h` *digest*] [`-ph`] [`-add-msi-dse`]
|
||||||
|
`-in` *input* `-out` *output*
|
||||||
|
|
||||||
|
`osslsigncode` `add`
|
||||||
|
[`-addUnauthenticatedBlob` [`-blobFile` *file*]]
|
||||||
|
[`-t` *URL* ... | `-ts` *URL* ...]
|
||||||
|
[`-TSA-certs` *file* `-TSA-key` *file-or-URI* [`-TSA-time` *unix-time*]]
|
||||||
|
[`-HTTPS-CAfile` *file*] [`-HTTPS-CRLfile` *file*]
|
||||||
|
[`-h` *digest*] [`-index` *n*] [`-verbose`] [`-add-msi-dse`]
|
||||||
|
`-in` *input* `-out` *output*
|
||||||
|
|
||||||
|
`osslsigncode` `attach-signature`
|
||||||
|
`-sigin` *signature*
|
||||||
|
[`-h` *digest*] [`-nest`] [`-add-msi-dse`]
|
||||||
|
`-in` *input* `-out` *output*
|
||||||
|
|
||||||
|
`osslsigncode` `extract-signature`
|
||||||
|
[`-pem`]
|
||||||
|
`-in` *input* `-out` *output*
|
||||||
|
|
||||||
|
`osslsigncode` `remove-signature`
|
||||||
|
`-in` *input* `-out` *output*
|
||||||
|
|
||||||
|
`osslsigncode` `verify`
|
||||||
|
`-in` *input*
|
||||||
|
[`-c` | `-catalog` *catalog-file*]
|
||||||
|
[`-CAfile` *file*] [`-CRLfile` *file*]
|
||||||
|
[`-HTTPS-CAfile` *file*] [`-HTTPS-CRLfile` *file*]
|
||||||
|
[`-TSA-CAfile` *file*] [`-TSA-CRLfile` *file*]
|
||||||
|
[`-p` *proxy*] [`-index` *n*]
|
||||||
|
[`-ignore-timestamp`] [`-ignore-cdp`] [`-ignore-crl`]
|
||||||
|
[`-time` *unix-time*]
|
||||||
|
[`-require-leaf-hash` *alg*:*hex*]
|
||||||
|
[`-verbose`]
|
||||||
|
|
||||||
|
# DESCRIPTION
|
||||||
|
|
||||||
|
`osslsigncode` signs and verifies Microsoft Authenticode signatures on
|
||||||
|
supported file formats. It can also extract data for detached signing,
|
||||||
|
attach an externally produced signature, add timestamps or unauthenticated
|
||||||
|
blobs to an existing signature, and remove an embedded signature.
|
||||||
|
|
||||||
|
Supported input formats include PE files such as EXE, DLL, and SYS, CAB,
|
||||||
|
CAT, MSI, APPX, and several script file types, including `.ps1`, `.ps1xml`,
|
||||||
|
`.psc1`, `.psd1`, `.psm1`, `.cdxml`, `.mof`, and `.js`.
|
||||||
|
|
||||||
|
The program supports these common workflows:
|
||||||
|
|
||||||
|
- direct signing of an unsigned file
|
||||||
|
- detached signing via `extract-data`, `sign`, and `attach-signature`
|
||||||
|
- post-sign timestamping with `add`
|
||||||
|
- verification of embedded signatures or catalog signatures with `verify`
|
||||||
|
|
||||||
|
If no subcommand is given, `sign` is assumed.
|
||||||
|
|
||||||
|
# FORMATS
|
||||||
|
|
||||||
|
Support is not identical across all file formats.
|
||||||
|
|
||||||
|
In particular, detached-signature workflows, nested signatures, catalog-based
|
||||||
|
verification, and signature removal are format-dependent features. A command
|
||||||
|
that is valid for one supported file type may be unsupported for another.
|
||||||
|
|
||||||
|
CAT files are a special case. They are detached catalog containers for
|
||||||
|
hashes of other files, not ordinary embedded-signature payloads. A CAT
|
||||||
|
file is itself a PKCS#7 structure containing authenticated entries for one
|
||||||
|
or more external files. In practice, the catalog signs file digests
|
||||||
|
recorded in the catalog, rather than embedding a signature into each
|
||||||
|
covered file.
|
||||||
|
|
||||||
|
Because of this, CAT files behave differently from embedded-signature
|
||||||
|
formats. They do not support `attach-signature`, `remove-signature`,
|
||||||
|
`extract-data`, or nested signatures.
|
||||||
|
|
||||||
|
MSI files are also a special case. They support an extended signature mode
|
||||||
|
controlled by `-add-msi-dse`. In this mode, the MSI signature covers file
|
||||||
|
metadata as well as file content. Detached-signing workflows and any later
|
||||||
|
re-signing or nesting operations must use a mode consistent with the MSI
|
||||||
|
file's existing signature structure.
|
||||||
|
|
||||||
|
# COMMANDS
|
||||||
|
|
||||||
|
## `sign`
|
||||||
|
|
||||||
|
Create a new Authenticode signature.
|
||||||
|
|
||||||
|
This command can sign a normal unsigned file, or it can sign PKCS#7 data
|
||||||
|
previously produced by `extract-data`.
|
||||||
|
|
||||||
|
## `extract-data`
|
||||||
|
|
||||||
|
Extract the PKCS#7 content to be signed later. This is used for detached
|
||||||
|
signing workflows.
|
||||||
|
|
||||||
|
## `add`
|
||||||
|
|
||||||
|
Add unauthenticated attributes to an existing signature, typically an
|
||||||
|
Authenticode timestamp, an RFC 3161 timestamp, or an unauthenticated blob.
|
||||||
|
|
||||||
|
With `-index`, the selected signature in a multi-signature file is updated.
|
||||||
|
|
||||||
|
## `attach-signature`
|
||||||
|
|
||||||
|
Attach a detached PKCS#7 signature to an input file.
|
||||||
|
|
||||||
|
With `-nest`, the new signature is attached as a nested signature instead of
|
||||||
|
replacing the primary one, if the file format supports nested signatures.
|
||||||
|
|
||||||
|
## `extract-signature`
|
||||||
|
|
||||||
|
Extract the embedded PKCS#7 signature from a signed file.
|
||||||
|
|
||||||
|
## `remove-signature`
|
||||||
|
|
||||||
|
Remove the embedded signature from a signed file.
|
||||||
|
|
||||||
|
## `verify`
|
||||||
|
|
||||||
|
Verify an embedded signature or a catalog signature.
|
||||||
|
|
||||||
|
Verification may include digest consistency, certificate chain validation,
|
||||||
|
certificate revocation checking, timestamp validation, and optional checking
|
||||||
|
of the signer's leaf certificate hash.
|
||||||
|
|
||||||
|
When verifying that a file is covered by a catalog, use `verify -catalog
|
||||||
|
catalog.cat -in file`. Verifying the CAT file by itself validates the
|
||||||
|
catalog signature; verifying with `-catalog` checks whether the specified
|
||||||
|
input file is covered by that catalog.
|
||||||
|
|
||||||
|
# OPTIONS
|
||||||
|
|
||||||
|
Some options are available only in particular builds or OpenSSL versions.
|
||||||
|
In particular, `-askpass` is build-dependent, `-provider` and `-nolegacy`
|
||||||
|
require OpenSSL 3, and engine-related options depend on engine support in the
|
||||||
|
build.
|
||||||
|
|
||||||
|
## General options
|
||||||
|
|
||||||
|
`--help`
|
||||||
|
: Show help text. With a subcommand, show help for that subcommand.
|
||||||
|
|
||||||
|
`-v`, `--version`
|
||||||
|
: Show version information.
|
||||||
|
|
||||||
|
`-in` *file*
|
||||||
|
: Input file.
|
||||||
|
|
||||||
|
`-out` *file*
|
||||||
|
: Output file. Required for all commands except `verify`.
|
||||||
|
|
||||||
|
`-verbose`
|
||||||
|
: Produce more detailed diagnostic output.
|
||||||
|
|
||||||
|
## Signing material
|
||||||
|
|
||||||
|
`-pkcs12` *file*
|
||||||
|
: Read the signing certificate and private key from a PKCS#12 container.
|
||||||
|
|
||||||
|
`-certs`, `-spc` *file*
|
||||||
|
: Read the signing certificate chain. The historical alias `-spc` is accepted.
|
||||||
|
|
||||||
|
`-key` *file-or-URI*
|
||||||
|
: Read the private key. This may also be a store or PKCS#11 URI.
|
||||||
|
|
||||||
|
`-ac` *file*
|
||||||
|
: Add extra certificates to the signature block.
|
||||||
|
|
||||||
|
`-pass` *password*
|
||||||
|
: Password or PIN for the key, token, or PKCS#12 container.
|
||||||
|
|
||||||
|
`-readpass` *file*
|
||||||
|
: Read the password or PIN from *file*. Use `-` to read from standard input.
|
||||||
|
|
||||||
|
`-askpass`
|
||||||
|
: Prompt for the password interactively.
|
||||||
|
|
||||||
|
## PKCS#11, engines, and providers
|
||||||
|
|
||||||
|
`-pkcs11module` *module*
|
||||||
|
: Path to a PKCS#11 module.
|
||||||
|
|
||||||
|
`-pkcs11cert` *URI*
|
||||||
|
: PKCS#11 URI identifying the certificate object.
|
||||||
|
|
||||||
|
`-provider` *provider*
|
||||||
|
: OpenSSL 3 provider to load. This is the preferred modern interface for
|
||||||
|
provider-based PKCS#11 use.
|
||||||
|
|
||||||
|
`-engine`, `-pkcs11engine` *engine*
|
||||||
|
: OpenSSL engine identifier or path to a dynamic engine module. This
|
||||||
|
interface is retained for compatibility with builds and deployments that
|
||||||
|
still support engines.
|
||||||
|
|
||||||
|
`-login`
|
||||||
|
: Force login to the token for engine-based PKCS#11 use.
|
||||||
|
|
||||||
|
`-engineCtrl` *command*[:*parameter*]
|
||||||
|
: Pass a control command to the selected engine.
|
||||||
|
|
||||||
|
`-nolegacy`
|
||||||
|
: On OpenSSL 3 builds, do not automatically load the legacy provider.
|
||||||
|
|
||||||
|
## Signature contents and digest control
|
||||||
|
|
||||||
|
`-h` `md5` | `sha1` | `sha2` | `sha256` | `sha384` | `sha512`
|
||||||
|
: Select the digest algorithm. The default is `sha256`. `sha2` and
|
||||||
|
`sha256` are equivalent.
|
||||||
|
|
||||||
|
`-n` *description*
|
||||||
|
: Description of the signed content.
|
||||||
|
|
||||||
|
`-i` *URL*
|
||||||
|
: Informational URL associated with the signed content.
|
||||||
|
|
||||||
|
`-comm`
|
||||||
|
: Use Microsoft Commercial Code Signing purpose instead of the default
|
||||||
|
individual purpose.
|
||||||
|
|
||||||
|
`-jp` `low`
|
||||||
|
: Add the Java CAB permission attribute. Only `low` is currently supported.
|
||||||
|
|
||||||
|
`-ph`
|
||||||
|
: Generate page hashes for executable files.
|
||||||
|
|
||||||
|
`-add-msi-dse`
|
||||||
|
: For MSI files, enable the `MsiDigitalSignatureEx` signing mode. In this
|
||||||
|
mode, the signature covers MSI metadata as well as file content. The
|
||||||
|
metadata portion includes stream names, sizes, and selected timestamps in
|
||||||
|
the MSI structure. This option changes the MSI signature format and should
|
||||||
|
be used consistently in any detached-signing workflow involving
|
||||||
|
`extract-data`, `sign`, `attach-signature`, or `add`.
|
||||||
|
|
||||||
|
For a newly signed MSI, this mode is generally preferred because it extends
|
||||||
|
signing coverage beyond file content alone. For an already signed MSI,
|
||||||
|
however, the chosen mode must match the file's existing signature
|
||||||
|
structure. Switching between basic MSI signing and `MsiDigitalSignatureEx`
|
||||||
|
during re-signing or nested-signature operations can invalidate the
|
||||||
|
existing signature.
|
||||||
|
|
||||||
|
`-pem`
|
||||||
|
: Write PKCS#7 output in PEM format instead of DER.
|
||||||
|
|
||||||
|
## Timestamping and network options
|
||||||
|
|
||||||
|
The following timestamping modes are **mutually exclusive** within a single
|
||||||
|
`sign` or `add` invocation:
|
||||||
|
|
||||||
|
- Authenticode timestamping with `-t`
|
||||||
|
- RFC 3161 timestamping with `-ts`
|
||||||
|
- built-in RFC 3161 timestamp generation with `-TSA-certs` and `-TSA-key`
|
||||||
|
|
||||||
|
`-t` *URL*
|
||||||
|
: Add an Authenticode timestamp from the specified URL. May be repeated.
|
||||||
|
|
||||||
|
`-ts` *URL*
|
||||||
|
: Add an RFC 3161 timestamp from the specified URL. May be repeated.
|
||||||
|
|
||||||
|
`-p` *proxy*
|
||||||
|
: Proxy used for timestamp or CRL retrieval.
|
||||||
|
|
||||||
|
`-noverifypeer`
|
||||||
|
: Do not verify the TLS certificate of the remote timestamp service.
|
||||||
|
|
||||||
|
`-HTTPS-CAfile` *file*
|
||||||
|
: PEM bundle used to verify HTTPS peers contacted by `osslsigncode`.
|
||||||
|
|
||||||
|
`-HTTPS-CRLfile` *file*
|
||||||
|
: PEM CRL file used while verifying HTTPS peers.
|
||||||
|
|
||||||
|
`-TSA-certs` *file*
|
||||||
|
: PEM certificate chain for locally generated RFC 3161 timestamps.
|
||||||
|
|
||||||
|
`-TSA-key` *file-or-URI*
|
||||||
|
: Private key for locally generated RFC 3161 timestamps.
|
||||||
|
|
||||||
|
`-TSA-time` *unix-time*
|
||||||
|
: Timestamp time for locally generated RFC 3161 responses.
|
||||||
|
|
||||||
|
## Nested signatures and indexed operations
|
||||||
|
|
||||||
|
`-nest`
|
||||||
|
: Add a nested signature instead of replacing the primary signature.
|
||||||
|
|
||||||
|
`-index` *n*
|
||||||
|
: Select a signature by index for `add` or `verify`. Index 0 is the primary
|
||||||
|
signature.
|
||||||
|
|
||||||
|
## Unauthenticated blob options
|
||||||
|
|
||||||
|
`-addUnauthenticatedBlob`
|
||||||
|
: Add an unauthenticated blob to the signature.
|
||||||
|
|
||||||
|
`-blobFile` *file*
|
||||||
|
: Read blob contents from *file*. If omitted, a placeholder blob is created.
|
||||||
|
|
||||||
|
## Verification options
|
||||||
|
|
||||||
|
`-c`, `-catalog` *file*
|
||||||
|
: Verify the input file against the specified catalog file.
|
||||||
|
|
||||||
|
`-CAfile` *file*
|
||||||
|
: PEM bundle of trusted CA certificates for signer validation.
|
||||||
|
|
||||||
|
`-CRLfile` *file*
|
||||||
|
: PEM file containing CRLs for signer validation.
|
||||||
|
|
||||||
|
`-TSA-CAfile`, `-untrusted` *file*
|
||||||
|
: PEM bundle of trusted CA certificates for timestamp validation.
|
||||||
|
|
||||||
|
`-TSA-CRLfile`, `-CRLuntrusted` *file*
|
||||||
|
: PEM file containing CRLs for timestamp validation.
|
||||||
|
|
||||||
|
`-time`, `-st` *unix-time*
|
||||||
|
: Verification time. If a valid timestamp is present and used, chain
|
||||||
|
validation is normally performed at the timestamp time.
|
||||||
|
|
||||||
|
`-ignore-timestamp`
|
||||||
|
: Skip verification of the timestamp signature.
|
||||||
|
|
||||||
|
`-ignore-cdp`
|
||||||
|
: Do not fetch CRLs from CRL Distribution Points.
|
||||||
|
|
||||||
|
`-ignore-crl`
|
||||||
|
: Disable CRL retrieval and CRL validation.
|
||||||
|
|
||||||
|
`-require-leaf-hash` *alg*:*hex*
|
||||||
|
: Require the signer's leaf certificate to hash to the specified value.
|
||||||
|
The hash is computed over the DER encoding of the leaf certificate.
|
||||||
|
|
||||||
|
# EXIT STATUS
|
||||||
|
|
||||||
|
`0`
|
||||||
|
: Success.
|
||||||
|
|
||||||
|
non-zero
|
||||||
|
: Failure.
|
||||||
|
|
||||||
|
# DIAGNOSTICS
|
||||||
|
|
||||||
|
Common causes of failure include:
|
||||||
|
|
||||||
|
missing CA trust bundle
|
||||||
|
: On Unix-like systems, `verify` expects a readable CA bundle, either from
|
||||||
|
`-CAfile` or from a detected system default.
|
||||||
|
|
||||||
|
detached-signing mismatch
|
||||||
|
: `extract-data`, `sign`, and `attach-signature` must use compatible
|
||||||
|
digest-affecting options such as `-h`, and where relevant `-ph` and
|
||||||
|
`-add-msi-dse`.
|
||||||
|
|
||||||
|
unsupported format feature
|
||||||
|
: Some file formats do not support every subcommand or every signature mode.
|
||||||
|
|
||||||
|
missing TSA trust chain
|
||||||
|
: Timestamp verification may fail unless the appropriate TSA trust anchors
|
||||||
|
are supplied with `-TSA-CAfile`, and where needed `-TSA-CRLfile`.
|
||||||
|
|
||||||
|
conflicting timestamp modes
|
||||||
|
: `-t`, `-ts`, and built-in TSA signing cannot be combined in one command.
|
||||||
|
|
||||||
|
MSI signature mode mismatch
|
||||||
|
: Re-signing or nesting an MSI signature must be consistent with whether the
|
||||||
|
file already uses `MsiDigitalSignatureEx`. Mixing modes may invalidate the
|
||||||
|
existing signature.
|
||||||
|
|
||||||
|
# ENVIRONMENT
|
||||||
|
|
||||||
|
`HTTP_PROXY`, `http_proxy`
|
||||||
|
: Default proxy for HTTP access if `-p` is not given.
|
||||||
|
|
||||||
|
`HTTPS_PROXY`, `https_proxy`
|
||||||
|
: Default proxy for HTTPS access if `-p` is not given.
|
||||||
|
|
||||||
|
`OPENSSL_ENGINES`
|
||||||
|
: May help OpenSSL find engine modules.
|
||||||
|
|
||||||
|
# FILES
|
||||||
|
|
||||||
|
On Unix-like systems, `osslsigncode` tries common CA bundle locations for
|
||||||
|
its default `-CAfile`, including:
|
||||||
|
|
||||||
|
- `/etc/ssl/certs/ca-certificates.crt`
|
||||||
|
- `/etc/pki/tls/certs/ca-bundle.crt`
|
||||||
|
- `/usr/share/ssl/certs/ca-bundle.crt`
|
||||||
|
- `/usr/local/share/certs/ca-root-nss.crt`
|
||||||
|
- `/etc/ssl/cert.pem`
|
||||||
|
|
||||||
|
If no readable CA bundle is available, `verify` may require an explicit
|
||||||
|
`-CAfile`.
|
||||||
|
|
||||||
|
# NOTES
|
||||||
|
|
||||||
|
Use `extract-data` when you need to create a new detached signature object.
|
||||||
|
Use `extract-signature` when you need to copy an existing embedded PKCS#7
|
||||||
|
signature out of a file.
|
||||||
|
|
||||||
|
For safer secret handling, prefer `-readpass` or `-askpass` over `-pass`.
|
||||||
|
|
||||||
|
Data added with `-addUnauthenticatedBlob` is not protected by the signature
|
||||||
|
and must not be treated as trusted.
|
||||||
|
|
||||||
|
For new MSI signatures, `-add-msi-dse` is generally preferred because it
|
||||||
|
extends signing coverage to MSI metadata as well as file content. However,
|
||||||
|
it is format-affecting rather than cosmetic, so existing signed MSI files
|
||||||
|
should be re-signed only in a mode consistent with their current signature
|
||||||
|
structure.
|
||||||
|
|
||||||
|
Output files are not overwritten.
|
||||||
|
|
||||||
|
# EXAMPLES
|
||||||
|
|
||||||
|
## Sign and verify a file
|
||||||
|
|
||||||
|
```sh
|
||||||
|
osslsigncode sign \
|
||||||
|
-pkcs12 signer.p12 \
|
||||||
|
-readpass p12-pass.txt \
|
||||||
|
-n "Example Application" \
|
||||||
|
-i "https://example.com/" \
|
||||||
|
-ts "https://tsa.example.net/" \
|
||||||
|
-in app.exe \
|
||||||
|
-out app-signed.exe
|
||||||
|
|
||||||
|
osslsigncode verify \
|
||||||
|
-CAfile ca-bundle.pem \
|
||||||
|
-TSA-CAfile tsa-ca-bundle.pem \
|
||||||
|
-in app-signed.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
## Detached signing workflow
|
||||||
|
|
||||||
|
```sh
|
||||||
|
osslsigncode extract-data \
|
||||||
|
-h sha384 \
|
||||||
|
-ph \
|
||||||
|
-in app.exe \
|
||||||
|
-out app-data.der
|
||||||
|
|
||||||
|
osslsigncode sign \
|
||||||
|
-pkcs12 signer.p12 \
|
||||||
|
-readpass p12-pass.txt \
|
||||||
|
-h sha384 \
|
||||||
|
-in app-data.der \
|
||||||
|
-out app-sig.der
|
||||||
|
|
||||||
|
osslsigncode attach-signature \
|
||||||
|
-h sha384 \
|
||||||
|
-sigin app-sig.der \
|
||||||
|
-in app.exe \
|
||||||
|
-out app-signed.exe
|
||||||
|
|
||||||
|
osslsigncode verify \
|
||||||
|
-CAfile ca-bundle.pem \
|
||||||
|
-in app-signed.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sign a new MSI with extended MSI metadata coverage
|
||||||
|
|
||||||
|
```sh
|
||||||
|
osslsigncode sign \
|
||||||
|
-pkcs12 signer.p12 \
|
||||||
|
-readpass p12-pass.txt \
|
||||||
|
-add-msi-dse \
|
||||||
|
-in installer.msi \
|
||||||
|
-out installer-signed.msi
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use a PKCS#11 provider
|
||||||
|
|
||||||
|
```sh
|
||||||
|
osslsigncode sign \
|
||||||
|
-provider /path/to/pkcs11prov.so \
|
||||||
|
-pkcs11module /path/to/opensc-pkcs11.so \
|
||||||
|
-pkcs11cert 'pkcs11:token=my-token;object=cert' \
|
||||||
|
-key 'pkcs11:token=my-token;object=key' \
|
||||||
|
-readpass pin.txt \
|
||||||
|
-in app.exe \
|
||||||
|
-out app-signed.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
## Add a timestamp to an already signed file
|
||||||
|
|
||||||
|
```sh
|
||||||
|
osslsigncode add \
|
||||||
|
-ts "https://tsa.example.net/" \
|
||||||
|
-in app-signed.exe \
|
||||||
|
-out app-signed-ts.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verify that a file is covered by a catalog
|
||||||
|
|
||||||
|
```sh
|
||||||
|
osslsigncode verify \
|
||||||
|
-catalog drivers.cat \
|
||||||
|
-CAfile ca-bundle.pem \
|
||||||
|
-CRLfile ca-crl.pem \
|
||||||
|
-in driver.sys
|
||||||
|
```
|
||||||
|
|
||||||
|
# REPORTING BUGS
|
||||||
|
|
||||||
|
Report bugs and suspected issues via the project issue tracker:
|
||||||
|
|
||||||
|
<https://github.com/mtrojnar/osslsigncode/issues>
|
||||||
|
|
||||||
|
# AUTHORS
|
||||||
|
|
||||||
|
Originally written by Per Allansson.
|
||||||
|
|
||||||
|
Maintained and extended by Michał Trojnara.
|
||||||
|
|
||||||
|
Major contributions by Małgorzata Olszówka.
|
||||||
|
|
||||||
|
Additional contributions by other project contributors.
|
||||||
|
|
||||||
|
# SEE ALSO
|
||||||
|
|
||||||
|
**OpenSSL** Library
|
||||||
|
|
||||||
|
<https://openssl-library.org/>
|
||||||
|
|
||||||
@@ -87,6 +87,7 @@ static uint32_t pe_calc_checksum(BIO *bio, uint32_t header_size);
|
|||||||
static uint32_t pe_calc_realchecksum(FILE_FORMAT_CTX *ctx);
|
static uint32_t pe_calc_realchecksum(FILE_FORMAT_CTX *ctx);
|
||||||
static int pe_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
|
static int pe_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
|
||||||
static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md);
|
static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md);
|
||||||
|
static int pkcs7_get_page_hash(PKCS7 *p7, u_char **ph, int *phlen, int *phtype);
|
||||||
static int pe_page_hash_get(u_char **ph, int *phlen, int *phtype, SpcAttributeTypeAndOptionalValue *obj);
|
static int pe_page_hash_get(u_char **ph, int *phlen, int *phtype, SpcAttributeTypeAndOptionalValue *obj);
|
||||||
static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype);
|
static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype);
|
||||||
static int pe_verify_page_hash(FILE_FORMAT_CTX *ctx, u_char *ph, int phlen, int phtype);
|
static int pe_verify_page_hash(FILE_FORMAT_CTX *ctx, u_char *ph, int phlen, int phtype);
|
||||||
@@ -163,8 +164,10 @@ static ASN1_OBJECT *pe_spc_image_data_get(u_char **p, int *plen, FILE_FORMAT_CTX
|
|||||||
if (EVP_MD_size(ctx->options->md) > EVP_MD_size(EVP_sha1()))
|
if (EVP_MD_size(ctx->options->md) > EVP_MD_size(EVP_sha1()))
|
||||||
phtype = NID_sha256;
|
phtype = NID_sha256;
|
||||||
link = pe_page_hash_link_get(ctx, phtype);
|
link = pe_page_hash_link_get(ctx, phtype);
|
||||||
if (!link)
|
if (!link) {
|
||||||
|
SpcPeImageData_free(pid);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
pid->file = link;
|
pid->file = link;
|
||||||
} else {
|
} else {
|
||||||
pid->file = spc_link_obsolete_get();
|
pid->file = spc_link_obsolete_get();
|
||||||
@@ -245,49 +248,34 @@ static int pe_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
|||||||
u_char *cmdbuf = NULL;
|
u_char *cmdbuf = NULL;
|
||||||
u_char *ph = NULL;
|
u_char *ph = NULL;
|
||||||
|
|
||||||
if (is_content_type(p7, SPC_INDIRECT_DATA_OBJID)) {
|
if (!pkcs7_get_content_digest(p7, mdbuf, &mdtype)) {
|
||||||
ASN1_STRING *content_val = p7->d.sign->contents->d.other->value.sequence;
|
fprintf(stderr, "Failed to extract current message digest\n\n");
|
||||||
const u_char *p = content_val->data;
|
|
||||||
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, content_val->length);
|
|
||||||
if (idc) {
|
|
||||||
if (!pe_page_hash_get(&ph, &phlen, &phtype, idc->data)) {
|
|
||||||
printf("Failed to extract a page hash\n\n");
|
|
||||||
SpcIndirectDataContent_free(idc);
|
|
||||||
return 0; /* FAILED */
|
|
||||||
}
|
|
||||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
|
||||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
|
||||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
|
||||||
}
|
|
||||||
SpcIndirectDataContent_free(idc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mdtype == -1) {
|
|
||||||
printf("Failed to extract current message digest\n\n");
|
|
||||||
OPENSSL_free(ph);
|
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
md = EVP_get_digestbynid(mdtype);
|
md = EVP_get_digestbynid(mdtype);
|
||||||
cmdbuf = pe_digest_calc(ctx, md);
|
cmdbuf = pe_digest_calc(ctx, md);
|
||||||
if (!cmdbuf) {
|
if (!cmdbuf) {
|
||||||
printf("Failed to calculate message digest\n\n");
|
fprintf(stderr, "Failed to calculate message digest\n\n");
|
||||||
OPENSSL_free(ph);
|
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
|
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
|
||||||
printf("Signature verification: failed\n\n");
|
fprintf(stderr, "Signature verification: failed\n\n");
|
||||||
OPENSSL_free(ph);
|
|
||||||
OPENSSL_free(cmdbuf);
|
OPENSSL_free(cmdbuf);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
|
OPENSSL_free(cmdbuf);
|
||||||
|
|
||||||
|
if (!pkcs7_get_page_hash(p7, &ph, &phlen, &phtype)) {
|
||||||
|
fprintf(stderr, "Failed to extract page hash\n\n");
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
if (!pe_verify_page_hash(ctx, ph, phlen, phtype)) {
|
if (!pe_verify_page_hash(ctx, ph, phlen, phtype)) {
|
||||||
printf("Signature verification: failed\n\n");
|
fprintf(stderr, "Signature verification: failed\n\n");
|
||||||
OPENSSL_free(ph);
|
OPENSSL_free(ph);
|
||||||
OPENSSL_free(cmdbuf);
|
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
OPENSSL_free(ph);
|
OPENSSL_free(ph);
|
||||||
OPENSSL_free(cmdbuf);
|
|
||||||
return 1; /* OK */
|
return 1; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,11 +291,11 @@ static int pe_verify_indirect_data(FILE_FORMAT_CTX *ctx, SpcAttributeTypeAndOpti
|
|||||||
u_char *ph = NULL;
|
u_char *ph = NULL;
|
||||||
|
|
||||||
if (!pe_page_hash_get(&ph, &phlen, &phtype, obj)) {
|
if (!pe_page_hash_get(&ph, &phlen, &phtype, obj)) {
|
||||||
printf("Failed to extract a page hash\n\n");
|
fprintf(stderr, "Failed to extract a page hash\n\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
if (!pe_verify_page_hash(ctx, ph, phlen, phtype)) {
|
if (!pe_verify_page_hash(ctx, ph, phlen, phtype)) {
|
||||||
printf("Page hash verification: failed\n\n");
|
fprintf(stderr, "Page hash verification: failed\n\n");
|
||||||
OPENSSL_free(ph);
|
OPENSSL_free(ph);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
@@ -353,7 +341,7 @@ static int pe_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
/* Strip current signature */
|
/* Strip current signature */
|
||||||
ctx->pe_ctx->fileend = ctx->pe_ctx->sigpos;
|
ctx->pe_ctx->fileend = ctx->pe_ctx->sigpos;
|
||||||
if (!pe_modify_header(ctx, hash, outdata)) {
|
if (!pe_modify_header(ctx, hash, outdata)) {
|
||||||
printf("Unable to modify file header\n");
|
fprintf(stderr, "Unable to modify file header\n");
|
||||||
return 1; /* FAILED */
|
return 1; /* FAILED */
|
||||||
}
|
}
|
||||||
return 0; /* OK */
|
return 0; /* OK */
|
||||||
@@ -373,10 +361,10 @@ static int pe_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
ctx->pe_ctx->fileend = ctx->pe_ctx->sigpos;
|
ctx->pe_ctx->fileend = ctx->pe_ctx->sigpos;
|
||||||
}
|
}
|
||||||
if (!pe_modify_header(ctx, hash, outdata)) {
|
if (!pe_modify_header(ctx, hash, outdata)) {
|
||||||
printf("Unable to modify file header\n");
|
fprintf(stderr, "Unable to modify file header\n");
|
||||||
return 1; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
return 0; /* OK */
|
return 1; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -391,21 +379,22 @@ static PKCS7 *pe_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
|
|||||||
PKCS7 *p7 = pkcs7_create(ctx);
|
PKCS7 *p7 = pkcs7_create(ctx);
|
||||||
|
|
||||||
if (!p7) {
|
if (!p7) {
|
||||||
printf("Creating a new signature failed\n");
|
fprintf(stderr, "Creating a new signature failed\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (!add_indirect_data_object(p7)) {
|
if (!add_indirect_data_object(p7)) {
|
||||||
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n");
|
fprintf(stderr, "Adding SPC_INDIRECT_DATA_OBJID failed\n");
|
||||||
PKCS7_free(p7);
|
PKCS7_free(p7);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
content = spc_indirect_data_content_get(hash, ctx);
|
content = spc_indirect_data_content_get(hash, ctx);
|
||||||
if (!content) {
|
if (!content) {
|
||||||
printf("Failed to get spcIndirectDataContent\n");
|
fprintf(stderr, "Failed to get spcIndirectDataContent\n");
|
||||||
|
PKCS7_free(p7);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (!sign_spc_indirect_data_content(p7, content)) {
|
if (!sign_spc_indirect_data_content(p7, content)) {
|
||||||
printf("Failed to set signed content\n");
|
fprintf(stderr, "Failed to set signed content\n");
|
||||||
PKCS7_free(p7);
|
PKCS7_free(p7);
|
||||||
ASN1_OCTET_STRING_free(content);
|
ASN1_OCTET_STRING_free(content);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
@@ -435,7 +424,7 @@ static int pe_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
|||||||
|
|
||||||
if (((len = i2d_PKCS7(p7, NULL)) <= 0)
|
if (((len = i2d_PKCS7(p7, NULL)) <= 0)
|
||||||
|| (p = OPENSSL_malloc((size_t)len)) == NULL) {
|
|| (p = OPENSSL_malloc((size_t)len)) == NULL) {
|
||||||
printf("i2d_PKCS memory allocation failed: %d\n", len);
|
fprintf(stderr, "i2d_PKCS memory allocation failed: %d\n", len);
|
||||||
return 1; /* FAILED */
|
return 1; /* FAILED */
|
||||||
}
|
}
|
||||||
i2d_PKCS7(p7, &p);
|
i2d_PKCS7(p7, &p);
|
||||||
@@ -540,7 +529,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
|
|||||||
uint16_t magic;
|
uint16_t magic;
|
||||||
|
|
||||||
if (filesize < 64) {
|
if (filesize < 64) {
|
||||||
printf("Corrupt DOS file - too short\n");
|
fprintf(stderr, "Corrupt DOS file - too short\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
/* SizeOfHeaders field specifies the combined size of an MS-DOS stub, PE header,
|
/* SizeOfHeaders field specifies the combined size of an MS-DOS stub, PE header,
|
||||||
@@ -549,15 +538,15 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
|
|||||||
* because of a bug when checking section names for compatibility purposes */
|
* because of a bug when checking section names for compatibility purposes */
|
||||||
header_size = GET_UINT32_LE(indata + 60);
|
header_size = GET_UINT32_LE(indata + 60);
|
||||||
if (header_size < 44 || header_size > filesize) {
|
if (header_size < 44 || header_size > filesize) {
|
||||||
printf("Unexpected SizeOfHeaders field: 0x%08X\n", header_size);
|
fprintf(stderr, "Unexpected SizeOfHeaders field: 0x%08X\n", header_size);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (filesize < header_size + 176) {
|
if (filesize < header_size + 176) {
|
||||||
printf("Corrupt PE file - too short\n");
|
fprintf(stderr, "Corrupt PE file - too short\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (memcmp(indata + header_size, "PE\0\0", 4)) {
|
if (memcmp(indata + header_size, "PE\0\0", 4)) {
|
||||||
printf("Unrecognized DOS file type\n");
|
fprintf(stderr, "Unrecognized DOS file type\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
/* Magic field identifies the state of the image file. The most common number is
|
/* Magic field identifies the state of the image file. The most common number is
|
||||||
@@ -570,7 +559,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
|
|||||||
} else if (magic == 0x10b) {
|
} else if (magic == 0x10b) {
|
||||||
pe32plus = 0;
|
pe32plus = 0;
|
||||||
} else {
|
} else {
|
||||||
printf("Corrupt PE file - found unknown magic %04X\n", magic);
|
fprintf(stderr, "Corrupt PE file - found unknown magic %04X\n", magic);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
/* The image file checksum */
|
/* The image file checksum */
|
||||||
@@ -579,7 +568,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
|
|||||||
* in the remainder of the optional header. Each describes a location and size. */
|
* in the remainder of the optional header. Each describes a location and size. */
|
||||||
nrvas = GET_UINT32_LE(indata + header_size + 116 + pe32plus * 16);
|
nrvas = GET_UINT32_LE(indata + header_size + 116 + pe32plus * 16);
|
||||||
if (nrvas < 5) {
|
if (nrvas < 5) {
|
||||||
printf("Can not handle PE files without certificate table resource\n");
|
fprintf(stderr, "Can not handle PE files without certificate table resource\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
/* Certificate Table field specifies the attribute certificate table address (4 bytes) and size (4 bytes) */
|
/* Certificate Table field specifies the attribute certificate table address (4 bytes) and size (4 bytes) */
|
||||||
@@ -589,7 +578,7 @@ static PE_CTX *pe_ctx_get(char *indata, uint32_t filesize)
|
|||||||
that signature should be last part of file */
|
that signature should be last part of file */
|
||||||
if ((sigpos != 0 || siglen != 0) &&
|
if ((sigpos != 0 || siglen != 0) &&
|
||||||
(sigpos == 0 || siglen == 0 || sigpos >= filesize || sigpos + siglen != filesize)) {
|
(sigpos == 0 || siglen == 0 || sigpos >= filesize || sigpos + siglen != filesize)) {
|
||||||
printf("Ignoring PE signature not at the end of the file\n");
|
printf("Warning: Ignoring PE signature not at the end of the file\n");
|
||||||
sigpos = 0;
|
sigpos = 0;
|
||||||
siglen = 0;
|
siglen = 0;
|
||||||
}
|
}
|
||||||
@@ -617,7 +606,7 @@ static PKCS7 *pe_pkcs7_get_file(char *indata, PE_CTX *pe_ctx)
|
|||||||
uint32_t pos = 0;
|
uint32_t pos = 0;
|
||||||
|
|
||||||
if (pe_ctx->siglen == 0 || pe_ctx->siglen > pe_ctx->fileend) {
|
if (pe_ctx->siglen == 0 || pe_ctx->siglen > pe_ctx->fileend) {
|
||||||
printf("Corrupted signature length: 0x%08X\n", pe_ctx->siglen);
|
fprintf(stderr, "Corrupted signature length: 0x%08X\n", pe_ctx->siglen);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
while (pos < pe_ctx->siglen) {
|
while (pos < pe_ctx->siglen) {
|
||||||
@@ -779,11 +768,18 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
|
|||||||
uint32_t idx = 0, fileend;
|
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)) {
|
||||||
printf("Unable to set the message digest of BIO\n");
|
fprintf(stderr, "Unable to set the message digest of BIO\n");
|
||||||
BIO_free_all(bhash);
|
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;
|
||||||
@@ -805,7 +801,7 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
|
|||||||
}
|
}
|
||||||
idx += (uint32_t)written + 8;
|
idx += (uint32_t)written + 8;
|
||||||
if (!bio_hash_data(bhash, ctx->options->indata, idx, fileend)) {
|
if (!bio_hash_data(bhash, ctx->options->indata, idx, fileend)) {
|
||||||
printf("Unable to calculate digest\n");
|
fprintf(stderr, "Unable to calculate digest\n");
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
@@ -827,6 +823,36 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
|
|||||||
* Page hash support
|
* Page hash support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve a page hash from PKCS7 SPC_INDIRECT_DATA structure.
|
||||||
|
* [in] p7: PKCS7 signature
|
||||||
|
* [out] ph: page hash
|
||||||
|
* [out] phlen: page hash length
|
||||||
|
* [out] phtype: NID_sha1 or NID_sha256
|
||||||
|
* [returns] 0 on error or 1 on success
|
||||||
|
*/
|
||||||
|
static int pkcs7_get_page_hash(PKCS7 *p7, u_char **ph, int *phlen, int *phtype)
|
||||||
|
{
|
||||||
|
SpcIndirectDataContent *idc = pkcs7_get_indirect_data_content(p7);
|
||||||
|
|
||||||
|
if (!idc) {
|
||||||
|
fprintf(stderr, "Failed to decode SpcIndirectDataContent\n\n");
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
if (!idc->data) {
|
||||||
|
fprintf(stderr, "Missing SpcIndirectDataContent data\n\n");
|
||||||
|
SpcIndirectDataContent_free(idc);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
if (!pe_page_hash_get(ph, phlen, phtype, idc->data)) {
|
||||||
|
fprintf(stderr, "Failed to extract a page hash\n\n");
|
||||||
|
SpcIndirectDataContent_free(idc);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
SpcIndirectDataContent_free(idc);
|
||||||
|
return 1; /* OK */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve a page hash from SPC_INDIRECT_DATA structure.
|
* Retrieve a page hash from SPC_INDIRECT_DATA structure.
|
||||||
* [out] ph: page hash
|
* [out] ph: page hash
|
||||||
@@ -835,43 +861,71 @@ static BIO *pe_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
|
|||||||
* [in] obj: SPC_INDIRECT_DATA OID: 1.3.6.1.4.1.311.2.1.4 containing page hash
|
* [in] obj: SPC_INDIRECT_DATA OID: 1.3.6.1.4.1.311.2.1.4 containing page hash
|
||||||
* [returns] 0 on error or 1 on success
|
* [returns] 0 on error or 1 on success
|
||||||
*/
|
*/
|
||||||
static int pe_page_hash_get(u_char **ph, int *phlen, int *phtype, SpcAttributeTypeAndOptionalValue *obj)
|
static int pe_page_hash_get(u_char **ph, int *phlen, int *phtype,
|
||||||
|
SpcAttributeTypeAndOptionalValue *obj)
|
||||||
{
|
{
|
||||||
const u_char *blob;
|
const unsigned char *blob;
|
||||||
|
const unsigned char *sequence_data;
|
||||||
|
const unsigned char *classid_data;
|
||||||
|
const unsigned char *serialized_data;
|
||||||
SpcPeImageData *id;
|
SpcPeImageData *id;
|
||||||
SpcSerializedObject *so;
|
SpcSerializedObject *so;
|
||||||
int l, l2;
|
int sequence_len, classid_len, serialized_len, l, l2;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
|
/* Validate input object */
|
||||||
if (!obj || !obj->value)
|
if (!obj || !obj->value)
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
blob = obj->value->value.sequence->data;
|
|
||||||
id = d2i_SpcPeImageData(NULL, &blob, obj->value->value.sequence->length);
|
/* Decode SpcPeImageData from ASN.1 sequence */
|
||||||
if (!id) {
|
sequence_data = ASN1_STRING_get0_data(obj->value->value.sequence);
|
||||||
|
sequence_len = ASN1_STRING_length(obj->value->value.sequence);
|
||||||
|
|
||||||
|
/* d2i_* modifies the input pointer, so use a temporary variable */
|
||||||
|
blob = sequence_data;
|
||||||
|
id = d2i_SpcPeImageData(NULL, &blob, sequence_len);
|
||||||
|
if (!id)
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
|
||||||
|
/* Validate SpcPeImageData contents */
|
||||||
if (!id->file) {
|
if (!id->file) {
|
||||||
SpcPeImageData_free(id);
|
SpcPeImageData_free(id);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Type 1 means SpcSerializedObject */
|
||||||
if (id->file->type != 1) {
|
if (id->file->type != 1) {
|
||||||
SpcPeImageData_free(id);
|
SpcPeImageData_free(id);
|
||||||
return 1; /* OK - This is not SpcSerializedObject structure that contains page hashes */
|
return 1; /* OK - no page hashes present */
|
||||||
}
|
}
|
||||||
|
|
||||||
so = id->file->value.moniker;
|
so = id->file->value.moniker;
|
||||||
if (so->classId->length != sizeof classid_page_hash ||
|
|
||||||
memcmp(so->classId->data, classid_page_hash, sizeof classid_page_hash)) {
|
/* Validate serialized object class ID */
|
||||||
|
classid_data = ASN1_STRING_get0_data((ASN1_STRING *)so->classId);
|
||||||
|
classid_len = ASN1_STRING_length((ASN1_STRING *)so->classId);
|
||||||
|
|
||||||
|
if (classid_len != sizeof classid_page_hash ||
|
||||||
|
memcmp(classid_data, classid_page_hash, sizeof classid_page_hash)) {
|
||||||
SpcPeImageData_free(id);
|
SpcPeImageData_free(id);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
/* skip ASN.1 SET hdr */
|
|
||||||
l = asn1_simple_hdr_len(so->serializedData->data, so->serializedData->length);
|
/*Get serialized ASN.1 blob */
|
||||||
blob = so->serializedData->data + l;
|
serialized_data = ASN1_STRING_get0_data((ASN1_STRING *)so->serializedData);
|
||||||
obj = d2i_SpcAttributeTypeAndOptionalValue(NULL, &blob, so->serializedData->length - l);
|
serialized_len = ASN1_STRING_length((ASN1_STRING *)so->serializedData);
|
||||||
|
|
||||||
|
/* Skip ASN.1 SET header */
|
||||||
|
l = asn1_simple_hdr_len(serialized_data, serialized_len);
|
||||||
|
blob = serialized_data + l;
|
||||||
|
|
||||||
|
/* Decode nested SpcAttributeTypeAndOptionalValue */
|
||||||
|
obj = d2i_SpcAttributeTypeAndOptionalValue(NULL, &blob, serialized_len - l);
|
||||||
SpcPeImageData_free(id);
|
SpcPeImageData_free(id);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
|
|
||||||
|
/* Determine page hash algorithm */
|
||||||
*phtype = 0;
|
*phtype = 0;
|
||||||
buf[0] = 0x00;
|
buf[0] = 0x00;
|
||||||
OBJ_obj2txt(buf, sizeof buf, obj->type, 1);
|
OBJ_obj2txt(buf, sizeof buf, obj->type, 1);
|
||||||
@@ -883,15 +937,30 @@ static int pe_page_hash_get(u_char **ph, int *phlen, int *phtype, SpcAttributeTy
|
|||||||
SpcAttributeTypeAndOptionalValue_free(obj);
|
SpcAttributeTypeAndOptionalValue_free(obj);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
/* Skip ASN.1 SET hdr */
|
|
||||||
l2 = asn1_simple_hdr_len(obj->value->value.sequence->data, obj->value->value.sequence->length);
|
/* IMPORTANT:
|
||||||
/* Skip ASN.1 OCTET STRING hdr */
|
* obj now points to the newly decoded structure,
|
||||||
l = asn1_simple_hdr_len(obj->value->value.sequence->data + l2, obj->value->value.sequence->length - l2);
|
* so refresh sequence_data/sequence_len */
|
||||||
|
sequence_data = ASN1_STRING_get0_data(obj->value->value.sequence);
|
||||||
|
sequence_len = ASN1_STRING_length(obj->value->value.sequence);
|
||||||
|
|
||||||
|
/* Skip ASN.1 SET header */
|
||||||
|
l2 = asn1_simple_hdr_len(sequence_data, sequence_len);
|
||||||
|
|
||||||
|
/* Skip ASN.1 OCTET STRING header */
|
||||||
|
l = asn1_simple_hdr_len(sequence_data + l2, sequence_len - l2);
|
||||||
l += l2;
|
l += l2;
|
||||||
*phlen = obj->value->value.sequence->length - l;
|
|
||||||
|
/* Extract raw page hash blob */
|
||||||
|
*phlen = sequence_len - l;
|
||||||
*ph = OPENSSL_malloc((size_t)*phlen);
|
*ph = OPENSSL_malloc((size_t)*phlen);
|
||||||
memcpy(*ph, obj->value->value.sequence->data + l, (size_t)*phlen);
|
if (!*ph) {
|
||||||
|
SpcAttributeTypeAndOptionalValue_free(obj);
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
memcpy(*ph, sequence_data + l, (size_t)*phlen);
|
||||||
SpcAttributeTypeAndOptionalValue_free(obj);
|
SpcAttributeTypeAndOptionalValue_free(obj);
|
||||||
|
|
||||||
return 1; /* OK */
|
return 1; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -907,18 +976,31 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
|
|||||||
uint16_t nsections, opthdr_size;
|
uint16_t nsections, opthdr_size;
|
||||||
uint32_t alignment, pagesize, hdrsize;
|
uint32_t alignment, pagesize, hdrsize;
|
||||||
uint32_t rs, ro, l, lastpos = 0;
|
uint32_t rs, ro, l, lastpos = 0;
|
||||||
int pphlen, phlen, i, pi = 1;
|
int mdlen, pphlen, phlen, i, pi = 1;
|
||||||
size_t written;
|
size_t written, off, sect_off, sect_tbl, need;
|
||||||
u_char *res, *zeroes;
|
u_char *res = NULL, *zeroes = NULL;
|
||||||
char *sections;
|
char *sections;
|
||||||
const EVP_MD *md = EVP_get_digestbynid(phtype);
|
const EVP_MD *md = EVP_get_digestbynid(phtype);
|
||||||
BIO *bhash;
|
BIO *bhash = NULL;
|
||||||
|
uint32_t filebound;
|
||||||
|
size_t pphlen_sz, sections_factor;
|
||||||
|
|
||||||
|
if (rphlen == NULL || ctx == NULL || ctx->options == NULL || ctx->pe_ctx == NULL
|
||||||
|
|| ctx->options->indata == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (md == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
mdlen = EVP_MD_size(md);
|
||||||
|
if (mdlen <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* NumberOfSections indicates the size of the section table,
|
/* NumberOfSections indicates the size of the section table,
|
||||||
* which immediately follows the headers, can be up to 65535 under Vista and later */
|
* which immediately follows the headers, can be up to 65535 under Vista and later */
|
||||||
nsections = GET_UINT16_LE(ctx->options->indata + ctx->pe_ctx->header_size + 6);
|
nsections = GET_UINT16_LE(ctx->options->indata + ctx->pe_ctx->header_size + 6);
|
||||||
if (nsections == 0) {
|
if (nsections == 0) {
|
||||||
printf("Corrupted number of sections: 0x%08X\n", nsections);
|
fprintf(stderr, "Corrupted number of sections: 0x%08X\n", nsections);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
/* FileAlignment is the alignment factor (in bytes) that is used to align
|
/* FileAlignment is the alignment factor (in bytes) that is used to align
|
||||||
@@ -926,7 +1008,7 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
|
|||||||
* of 2 between 512 and 64 K, inclusive. The default is 512. */
|
* of 2 between 512 and 64 K, inclusive. The default is 512. */
|
||||||
alignment = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 60);
|
alignment = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 60);
|
||||||
if (alignment < 512 || alignment > UINT16_MAX) {
|
if (alignment < 512 || alignment > UINT16_MAX) {
|
||||||
printf("Corrupted file alignment factor: 0x%08X\n", alignment);
|
fprintf(stderr, "Corrupted file alignment factor: 0x%08X\n", alignment);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
/* SectionAlignment is the alignment (in bytes) of sections when they are
|
/* SectionAlignment is the alignment (in bytes) of sections when they are
|
||||||
@@ -936,14 +1018,14 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
|
|||||||
* https://devblogs.microsoft.com/oldnewthing/20210510-00/?p=105200 */
|
* https://devblogs.microsoft.com/oldnewthing/20210510-00/?p=105200 */
|
||||||
pagesize = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 56);
|
pagesize = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 56);
|
||||||
if (pagesize == 0 || pagesize < alignment || pagesize > 4194304) {
|
if (pagesize == 0 || pagesize < alignment || pagesize > 4194304) {
|
||||||
printf("Corrupted page size: 0x%08X\n", pagesize);
|
fprintf(stderr, "Corrupted page size: 0x%08X\n", pagesize);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
/* SizeOfHeaders is the combined size of an MS-DOS stub, PE header,
|
/* SizeOfHeaders is the combined size of an MS-DOS stub, PE header,
|
||||||
* and section headers rounded up to a multiple of FileAlignment. */
|
* and section headers rounded up to a multiple of FileAlignment. */
|
||||||
hdrsize = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 84);
|
hdrsize = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->header_size + 84);
|
||||||
if (hdrsize < ctx->pe_ctx->header_size || hdrsize > UINT32_MAX) {
|
if (hdrsize < ctx->pe_ctx->header_size || hdrsize > UINT32_MAX) {
|
||||||
printf("Corrupted headers size: 0x%08X\n", hdrsize);
|
fprintf(stderr, "Corrupted headers size: 0x%08X\n", hdrsize);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
/* SizeOfOptionalHeader is the size of the optional header, which is
|
/* SizeOfOptionalHeader is the size of the optional header, which is
|
||||||
@@ -951,19 +1033,65 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
|
|||||||
* and can't be bigger than the file */
|
* and can't be bigger than the file */
|
||||||
opthdr_size = GET_UINT16_LE(ctx->options->indata + ctx->pe_ctx->header_size + 20);
|
opthdr_size = GET_UINT16_LE(ctx->options->indata + ctx->pe_ctx->header_size + 20);
|
||||||
if (opthdr_size == 0 || opthdr_size > ctx->pe_ctx->fileend) {
|
if (opthdr_size == 0 || opthdr_size > ctx->pe_ctx->fileend) {
|
||||||
printf("Corrupted optional header size: 0x%08X\n", opthdr_size);
|
fprintf(stderr, "Corrupted optional header size: 0x%08X\n", opthdr_size);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
pphlen = 4 + EVP_MD_size(md);
|
/* Validate that pagesize >= hdrsize to prevent integer underflow */
|
||||||
phlen = pphlen * (3 + (int)nsections + (int)(ctx->pe_ctx->fileend / pagesize));
|
if (pagesize < hdrsize) {
|
||||||
|
fprintf(stderr, "Page size (0x%08X) is smaller than header size (0x%08X)\n",
|
||||||
|
pagesize, hdrsize);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
|
pphlen = 4 + mdlen;
|
||||||
|
|
||||||
|
/* Compute an upper bound for result size and guard overflow */
|
||||||
|
pphlen_sz = (size_t)pphlen;
|
||||||
|
sections_factor = 3 + (size_t)nsections + ((size_t)ctx->pe_ctx->fileend / pagesize);
|
||||||
|
if (sections_factor > SIZE_MAX / pphlen_sz) {
|
||||||
|
fprintf(stderr, "Page hash allocation size would overflow\n");
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
|
phlen = (int)(pphlen_sz * sections_factor);
|
||||||
|
/* Sanity limit - page hash shouldn't exceed reasonable size (16 MB) */
|
||||||
|
if (phlen < 0 || (size_t)phlen > SIZE_16M) {
|
||||||
|
fprintf(stderr, "Page hash size exceeds limit: %d\n", phlen);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the file boundary for section data validation */
|
||||||
|
filebound = ctx->pe_ctx->sigpos ? ctx->pe_ctx->sigpos : ctx->pe_ctx->fileend;
|
||||||
|
|
||||||
|
/* Validate section table bounds before reading section headers */
|
||||||
|
sect_off = (size_t)ctx->pe_ctx->header_size + 24u + (size_t)opthdr_size;
|
||||||
|
sect_tbl = (size_t)nsections * 40u;
|
||||||
|
|
||||||
|
if (sect_off > (size_t)filebound || sect_tbl > (size_t)filebound - sect_off) {
|
||||||
|
fprintf(stderr, "Section table out of bounds: off=%zu size=%zu filebound=%u\n",
|
||||||
|
sect_off, sect_tbl, filebound);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
|
sections = (char *)ctx->options->indata + sect_off;
|
||||||
|
|
||||||
bhash = BIO_new(BIO_f_md());
|
bhash = BIO_new(BIO_f_md());
|
||||||
|
if (bhash == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
|
#endif
|
||||||
if (!BIO_set_md(bhash, md)) {
|
if (!BIO_set_md(bhash, md)) {
|
||||||
printf("Unable to set the message digest of BIO\n");
|
fprintf(stderr, "Unable to set the message digest of BIO\n");
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
BIO_push(bhash, BIO_new(BIO_s_null()));
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
if (BIO_push(bhash, BIO_new(BIO_s_null())) == NULL) {
|
||||||
|
BIO_free_all(bhash);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (!BIO_write_ex(bhash, ctx->options->indata, ctx->pe_ctx->header_size + 88, &written)
|
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) {
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
@@ -975,54 +1103,115 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
|
|||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (!BIO_write_ex(bhash,
|
off = ctx->pe_ctx->header_size + 160 + (size_t)ctx->pe_ctx->pe32plus * 16;
|
||||||
ctx->options->indata + ctx->pe_ctx->header_size + 160 + ctx->pe_ctx->pe32plus*16,
|
if (hdrsize < off || hdrsize > filebound) {
|
||||||
hdrsize - (ctx->pe_ctx->header_size + 160 + ctx->pe_ctx->pe32plus*16), &written)
|
BIO_free_all(bhash);
|
||||||
|| written != hdrsize - (ctx->pe_ctx->header_size + 160 + ctx->pe_ctx->pe32plus*16)) {
|
return NULL; /* FAILED: header too small */
|
||||||
|
}
|
||||||
|
if (!BIO_write_ex(bhash, ctx->options->indata + off, (size_t)hdrsize - off, &written)
|
||||||
|
|| written != hdrsize - off) {
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
|
if (pagesize < hdrsize) {
|
||||||
|
BIO_free_all(bhash);
|
||||||
|
return NULL; /* FAILED: header larger than page */
|
||||||
|
}
|
||||||
zeroes = OPENSSL_zalloc((size_t)pagesize);
|
zeroes = OPENSSL_zalloc((size_t)pagesize);
|
||||||
if (!BIO_write_ex(bhash, zeroes, pagesize - hdrsize, &written)
|
if (zeroes == NULL) {
|
||||||
|| written != pagesize - hdrsize) {
|
BIO_free_all(bhash);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
|
if (!BIO_write_ex(bhash, zeroes, (size_t)pagesize - (size_t)hdrsize, &written)
|
||||||
|
|| written != (size_t)pagesize - (size_t)hdrsize) {
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
OPENSSL_free(zeroes);
|
OPENSSL_free(zeroes);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
res = OPENSSL_malloc((size_t)phlen);
|
res = OPENSSL_malloc((size_t)phlen);
|
||||||
|
if (res == NULL) {
|
||||||
|
BIO_free_all(bhash);
|
||||||
|
OPENSSL_free(zeroes);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
memset(res, 0, 4);
|
memset(res, 0, 4);
|
||||||
BIO_gets(bhash, (char*)res + 4, EVP_MD_size(md));
|
if (BIO_gets(bhash, (char *)res + 4, mdlen) != mdlen) {
|
||||||
|
BIO_free_all(bhash);
|
||||||
|
OPENSSL_free(zeroes);
|
||||||
|
OPENSSL_free(res);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
sections = ctx->options->indata + ctx->pe_ctx->header_size + 24 + opthdr_size;
|
|
||||||
for (i=0; i<nsections; i++) {
|
for (i = 0; i < (int)nsections; i++) {
|
||||||
/* Resource Table address and size */
|
/* SizeOfRawData and PointerToRawData from section header */
|
||||||
rs = GET_UINT32_LE(sections + 16);
|
rs = GET_UINT32_LE(sections + 16);
|
||||||
ro = GET_UINT32_LE(sections + 20);
|
ro = GET_UINT32_LE(sections + 20);
|
||||||
if (rs == 0 || rs >= UINT32_MAX) {
|
if (rs == 0) {
|
||||||
sections += 40;
|
sections += 40;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (l=0; l<rs; l+=pagesize, pi++) {
|
/* Validate section bounds against file size to prevent OOB read */
|
||||||
PUT_UINT32_LE(ro + l, res + pi*pphlen);
|
if (ro >= filebound || rs > filebound - ro) {
|
||||||
|
fprintf(stderr, "Section %d has invalid bounds: offset=0x%08X, size=0x%08X, fileend=0x%08X\n",
|
||||||
|
i, ro, rs, filebound);
|
||||||
|
OPENSSL_free(zeroes);
|
||||||
|
OPENSSL_free(res);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
|
for (l = 0; l < rs; l += pagesize, pi++) {
|
||||||
|
need = (size_t)(pi + 1) * (size_t)pphlen;
|
||||||
|
|
||||||
|
/* Prevent OOB write into res if pi grows beyond allocated factor */
|
||||||
|
if (need > (size_t)phlen) {
|
||||||
|
fprintf(stderr, "Page hash buffer overflow prevented: pi=%d need=%zu phlen=%d\n",
|
||||||
|
pi, need, phlen);
|
||||||
|
OPENSSL_free(zeroes);
|
||||||
|
OPENSSL_free(res);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
|
|
||||||
|
PUT_UINT32_LE(ro + l, res + (size_t)pi * (size_t)pphlen);
|
||||||
|
|
||||||
bhash = BIO_new(BIO_f_md());
|
bhash = BIO_new(BIO_f_md());
|
||||||
|
if (bhash == NULL) {
|
||||||
|
OPENSSL_free(zeroes);
|
||||||
|
OPENSSL_free(res);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
|
#endif
|
||||||
if (!BIO_set_md(bhash, md)) {
|
if (!BIO_set_md(bhash, md)) {
|
||||||
printf("Unable to set the message digest of BIO\n");
|
fprintf(stderr, "Unable to set the message digest of BIO\n");
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
OPENSSL_free(zeroes);
|
OPENSSL_free(zeroes);
|
||||||
OPENSSL_free(res);
|
OPENSSL_free(res);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
BIO_push(bhash, BIO_new(BIO_s_null()));
|
#if defined(__GNUC__)
|
||||||
if (rs - l < pagesize) {
|
#pragma GCC diagnostic pop
|
||||||
if (!BIO_write_ex(bhash, ctx->options->indata + ro + l, rs - l, &written)
|
#endif
|
||||||
|| written != rs - l) {
|
if (BIO_push(bhash, BIO_new(BIO_s_null())) == NULL) {
|
||||||
|
BIO_free_all(bhash);
|
||||||
|
OPENSSL_free(zeroes);
|
||||||
|
OPENSSL_free(res);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (l < rs && rs - l < pagesize) {
|
||||||
|
size_t tail = (size_t)(rs - l);
|
||||||
|
|
||||||
|
if (!BIO_write_ex(bhash, ctx->options->indata + ro + l, tail, &written)
|
||||||
|
|| written != tail) {
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
OPENSSL_free(zeroes);
|
OPENSSL_free(zeroes);
|
||||||
OPENSSL_free(res);
|
OPENSSL_free(res);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (!BIO_write_ex(bhash, zeroes, pagesize - (rs - l), &written)
|
if (!BIO_write_ex(bhash, zeroes, pagesize - tail, &written)
|
||||||
|| written != pagesize - (rs - l)) {
|
|| written != pagesize - tail) {
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
OPENSSL_free(zeroes);
|
OPENSSL_free(zeroes);
|
||||||
OPENSSL_free(res);
|
OPENSSL_free(res);
|
||||||
@@ -1037,17 +1226,34 @@ static u_char *pe_page_hash_calc(int *rphlen, FILE_FORMAT_CTX *ctx, int phtype)
|
|||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BIO_gets(bhash, (char*)res + pi*pphlen + 4, EVP_MD_size(md));
|
if (BIO_gets(bhash, (char *)res + (size_t)pi * (size_t)pphlen + 4, mdlen) != mdlen) {
|
||||||
|
BIO_free_all(bhash);
|
||||||
|
OPENSSL_free(zeroes);
|
||||||
|
OPENSSL_free(res);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
}
|
}
|
||||||
lastpos = ro + rs;
|
lastpos = ro + rs;
|
||||||
sections += 40;
|
sections += 40;
|
||||||
}
|
}
|
||||||
PUT_UINT32_LE(lastpos, res + pi*pphlen);
|
/* Final entry */
|
||||||
memset(res + pi*pphlen + 4, 0, (size_t)EVP_MD_size(md));
|
need = (size_t)(pi + 1) * (size_t)pphlen;
|
||||||
|
|
||||||
|
if (need > (size_t)phlen) {
|
||||||
|
fprintf(stderr, "Page hash buffer overflow prevented at final entry: pi=%d need=%zu phlen=%d\n",
|
||||||
|
pi, need, phlen);
|
||||||
|
OPENSSL_free(zeroes);
|
||||||
|
OPENSSL_free(res);
|
||||||
|
return NULL; /* FAILED */
|
||||||
|
}
|
||||||
|
|
||||||
|
PUT_UINT32_LE(lastpos, res + (size_t)pi * (size_t)pphlen);
|
||||||
|
memset(res + (size_t)pi * (size_t)pphlen + 4, 0, (size_t)mdlen);
|
||||||
pi++;
|
pi++;
|
||||||
|
|
||||||
OPENSSL_free(zeroes);
|
OPENSSL_free(zeroes);
|
||||||
*rphlen = pi*pphlen;
|
*rphlen = pi * pphlen;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1067,6 +1273,10 @@ static int pe_verify_page_hash(FILE_FORMAT_CTX *ctx, u_char *ph, int phlen, int
|
|||||||
if (!ph)
|
if (!ph)
|
||||||
return 1; /* OK */
|
return 1; /* OK */
|
||||||
cph = pe_page_hash_calc(&cphlen, ctx, phtype);
|
cph = pe_page_hash_calc(&cphlen, ctx, phtype);
|
||||||
|
if (!cph) {
|
||||||
|
fprintf(stderr, "Page hash verification failed: could not calculate page hash\n");
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
mdok = (phlen == cphlen) && !memcmp(ph, cph, (size_t)phlen);
|
mdok = (phlen == cphlen) && !memcmp(ph, cph, (size_t)phlen);
|
||||||
printf("Page hash algorithm : %s\n", OBJ_nid2sn(phtype));
|
printf("Page hash algorithm : %s\n", OBJ_nid2sn(phtype));
|
||||||
if (ctx->options->verbose) {
|
if (ctx->options->verbose) {
|
||||||
@@ -1099,7 +1309,7 @@ static SpcLink *pe_page_hash_link_get(FILE_FORMAT_CTX *ctx, int phtype)
|
|||||||
|
|
||||||
ph = pe_page_hash_calc(&phlen, ctx, phtype);
|
ph = pe_page_hash_calc(&phlen, ctx, phtype);
|
||||||
if (!ph) {
|
if (!ph) {
|
||||||
printf("Failed to calculate page hash\n");
|
fprintf(stderr, "Failed to calculate page hash\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (ctx->options->verbose)
|
if (ctx->options->verbose)
|
||||||
@@ -1169,43 +1379,71 @@ static int pe_check_file(FILE_FORMAT_CTX *ctx)
|
|||||||
{
|
{
|
||||||
uint32_t real_pe_checksum, sum = 0;
|
uint32_t real_pe_checksum, sum = 0;
|
||||||
|
|
||||||
if (!ctx) {
|
if (ctx == NULL || ctx->pe_ctx == NULL || ctx->options == NULL
|
||||||
printf("Init error\n\n");
|
|| ctx->options->indata == NULL) {
|
||||||
|
fprintf(stderr, "Init error\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
real_pe_checksum = pe_calc_realchecksum(ctx);
|
real_pe_checksum = pe_calc_realchecksum(ctx);
|
||||||
if (ctx->pe_ctx->pe_checksum == real_pe_checksum) {
|
if (ctx->pe_ctx->pe_checksum == real_pe_checksum) {
|
||||||
printf("PE checksum : %08X\n\n", real_pe_checksum);
|
printf("PE checksum : %08X\n", real_pe_checksum);
|
||||||
} else {
|
} else {
|
||||||
printf("Current PE checksum : %08X\n", ctx->pe_ctx->pe_checksum);
|
printf("Current PE checksum : %08X\n", ctx->pe_ctx->pe_checksum);
|
||||||
printf("Calculated PE checksum: %08X\n", real_pe_checksum);
|
printf("Calculated PE checksum: %08X\n", real_pe_checksum);
|
||||||
printf("Warning: invalid PE checksum\n\n");
|
printf("Warning: invalid PE checksum\n");
|
||||||
}
|
}
|
||||||
|
/* Signature directory bounds */
|
||||||
if (ctx->pe_ctx->sigpos == 0 || ctx->pe_ctx->siglen == 0
|
if (ctx->pe_ctx->sigpos == 0 || ctx->pe_ctx->siglen == 0
|
||||||
|| ctx->pe_ctx->sigpos > ctx->pe_ctx->fileend) {
|
|| ctx->pe_ctx->sigpos > ctx->pe_ctx->fileend
|
||||||
printf("No signature found\n\n");
|
|| ctx->pe_ctx->siglen > ctx->pe_ctx->fileend - ctx->pe_ctx->sigpos) {
|
||||||
|
fprintf(stderr, "No signature found\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
* Validate WIN_CERTIFICATE chain.
|
||||||
* If the sum of the rounded dwLength values does not equal the Size value,
|
* If the sum of the rounded dwLength values does not equal the Size value,
|
||||||
* then either the attribute certificate table or the Size field is corrupted.
|
* then either the attribute certificate table or the Size field is corrupted.
|
||||||
*/
|
*/
|
||||||
while (sum < ctx->pe_ctx->siglen) {
|
while (sum < ctx->pe_ctx->siglen) {
|
||||||
uint32_t len = GET_UINT32_LE(ctx->options->indata + ctx->pe_ctx->sigpos + sum);
|
uint32_t len, off;
|
||||||
if (ctx->pe_ctx->siglen - len > 8) {
|
|
||||||
printf("Corrupted attribute certificate table\n");
|
/* Prevent overflow in sigpos + sum */
|
||||||
printf("Attribute certificate table size : %08X\n", ctx->pe_ctx->siglen);
|
if (sum > UINT32_MAX - ctx->pe_ctx->sigpos) {
|
||||||
printf("Attribute certificate entry length: %08X\n\n", len);
|
fprintf(stderr, "Corrupted attribute certificate table\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
/* quadword align data */
|
off = ctx->pe_ctx->sigpos + sum;
|
||||||
len += len % 8 ? 8 - len % 8 : 0;
|
|
||||||
|
/* Need at least 4 bytes to read dwLength */
|
||||||
|
if (off > ctx->pe_ctx->fileend || ctx->pe_ctx->fileend - off < 4) {
|
||||||
|
fprintf(stderr, "Corrupted attribute certificate table\n");
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
len = GET_UINT32_LE(ctx->options->indata + off);
|
||||||
|
|
||||||
|
/* dwLength must include the 8-byte WIN_CERTIFICATE header */
|
||||||
|
if (len < 8 || len > ctx->pe_ctx->siglen - sum || len > ctx->pe_ctx->fileend - off) {
|
||||||
|
fprintf(stderr, "Corrupted attribute certificate table\n");
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Quadword align data */
|
||||||
|
if (len % 8) {
|
||||||
|
uint32_t pad = 8 - (len % 8);
|
||||||
|
|
||||||
|
/* Ensure quadword alignment does not overflow or exceed remaining table size */
|
||||||
|
if (pad > ctx->pe_ctx->siglen - sum - len) {
|
||||||
|
fprintf(stderr, "Corrupted attribute certificate table\n");
|
||||||
|
return 0; /* FAILED */
|
||||||
|
}
|
||||||
|
len += pad;
|
||||||
|
}
|
||||||
sum += len;
|
sum += len;
|
||||||
}
|
}
|
||||||
if (sum != ctx->pe_ctx->siglen) {
|
if (sum != ctx->pe_ctx->siglen) {
|
||||||
printf("Corrupted attribute certificate table\n");
|
fprintf(stderr, "Corrupted attribute certificate table\n");
|
||||||
printf("Attribute certificate table size : %08X\n", ctx->pe_ctx->siglen);
|
fprintf(stderr, "Attribute certificate table size : %08X\n", ctx->pe_ctx->siglen);
|
||||||
printf("Sum of the rounded dwLength values: %08X\n\n", sum);
|
fprintf(stderr, "Sum of the rounded dwLength values: %08X\n\n", sum);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
return 1; /* OK */
|
return 1; /* OK */
|
||||||
|
|||||||
@@ -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)) {
|
||||||
printf("Unable to set the message digest of BIO\n");
|
fprintf(stderr, "Unable to set the message digest of BIO\n");
|
||||||
BIO_free_all(hash);
|
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);
|
||||||
@@ -272,21 +288,8 @@ static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
|||||||
const EVP_MD *md;
|
const EVP_MD *md;
|
||||||
BIO *bhash;
|
BIO *bhash;
|
||||||
|
|
||||||
/* FIXME: this shared code most likely belongs in osslsigncode.c */
|
if (!pkcs7_get_content_digest(p7, mdbuf, &mdtype)) {
|
||||||
if (is_content_type(p7, SPC_INDIRECT_DATA_OBJID)) {
|
fprintf(stderr, "Failed to extract current message digest\n\n");
|
||||||
ASN1_STRING *content_val = p7->d.sign->contents->d.other->value.sequence;
|
|
||||||
const u_char *p = content_val->data;
|
|
||||||
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, content_val->length);
|
|
||||||
if (idc) {
|
|
||||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
|
||||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
|
||||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
|
||||||
}
|
|
||||||
SpcIndirectDataContent_free(idc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mdtype == -1) {
|
|
||||||
printf("Failed to extract current message digest\n\n");
|
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
md = EVP_get_digestbynid(mdtype);
|
md = EVP_get_digestbynid(mdtype);
|
||||||
@@ -299,7 +302,7 @@ static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
|||||||
BIO_free_all(bhash);
|
BIO_free_all(bhash);
|
||||||
|
|
||||||
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
|
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
|
||||||
printf("Signature verification: failed\n\n");
|
fprintf(stderr, "Signature verification: failed\n\n");
|
||||||
OPENSSL_free(cmdbuf);
|
OPENSSL_free(cmdbuf);
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
@@ -316,20 +319,18 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
|
|||||||
{
|
{
|
||||||
const char *signature_data = ctx->options->indata + ctx->script_ctx->sigpos;
|
const char *signature_data = ctx->options->indata + ctx->script_ctx->sigpos;
|
||||||
size_t signature_len = ctx->script_ctx->fileend - ctx->script_ctx->sigpos;
|
size_t signature_len = ctx->script_ctx->fileend - ctx->script_ctx->sigpos;
|
||||||
size_t base64_len, der_max_length, der_length;
|
size_t base64_len;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
BIO *bio_mem, *bio_b64 = NULL;
|
BIO *bio_mem, *bio_b64 = NULL;
|
||||||
char *base64_data = NULL;
|
char *base64_data = NULL;
|
||||||
char *der_data = NULL;
|
|
||||||
const char *der_tmp;
|
|
||||||
char *clean_base64 = NULL;
|
char *clean_base64 = NULL;
|
||||||
int clean_base64_len = 0;
|
int clean_base64_len = 0;
|
||||||
const char *open_tag = ctx->script_ctx->comment_text->open;
|
const char *open_tag = ctx->script_ctx->comment_text->open;
|
||||||
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)) {
|
||||||
@@ -339,6 +340,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,
|
||||||
@@ -348,7 +351,7 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
|
|||||||
/* allocate memory for cleaned Base64 */
|
/* allocate memory for cleaned Base64 */
|
||||||
clean_base64 = OPENSSL_malloc(base64_len);
|
clean_base64 = OPENSSL_malloc(base64_len);
|
||||||
if (!clean_base64) {
|
if (!clean_base64) {
|
||||||
printf("Malloc failed\n");
|
fprintf(stderr, "Malloc failed\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +360,7 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
|
|||||||
/* find the opening tag */
|
/* find the opening tag */
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (ptr + open_tag_len >= base64_data + base64_len) {
|
if (ptr + open_tag_len >= base64_data + base64_len) {
|
||||||
printf("Signature line too long\n");
|
fprintf(stderr, "Signature line too long\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (!memcmp(ptr, open_tag, (size_t)open_tag_len)) {
|
if (!memcmp(ptr, open_tag, (size_t)open_tag_len)) {
|
||||||
@@ -366,18 +369,18 @@ 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 */
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (ptr + close_tag_len >= base64_data + base64_len) {
|
if (ptr + close_tag_len >= base64_data + base64_len) {
|
||||||
printf("Signature line too long\n");
|
fprintf(stderr, "Signature line too long\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (close_tag_len) {
|
if (close_tag_len) {
|
||||||
@@ -403,26 +406,12 @@ static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
|
|||||||
BIO_push(bio_b64, bio_mem);
|
BIO_push(bio_b64, bio_mem);
|
||||||
BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
|
BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
|
||||||
|
|
||||||
/* allocate memory for DER output */
|
|
||||||
der_max_length = BIO_ctrl_pending(bio_b64);
|
|
||||||
der_data = OPENSSL_malloc(der_max_length);
|
|
||||||
if (!der_data)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
/* decode Base64 to DER */
|
|
||||||
if (!BIO_read_ex(bio_b64, der_data, der_max_length, &der_length))
|
|
||||||
goto cleanup;
|
|
||||||
if (der_length <= 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
/* decode DER */
|
/* decode DER */
|
||||||
der_tmp = der_data;
|
retval = d2i_PKCS7_bio(bio_b64, NULL);
|
||||||
retval = d2i_PKCS7(NULL, (const unsigned char **)&der_tmp, (int)der_length);
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
OPENSSL_free(base64_data);
|
OPENSSL_free(base64_data);
|
||||||
OPENSSL_free(clean_base64);
|
OPENSSL_free(clean_base64);
|
||||||
OPENSSL_free(der_data);
|
|
||||||
BIO_free_all(bio_b64);
|
BIO_free_all(bio_b64);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -471,10 +460,10 @@ static int script_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
|||||||
ctx->script_ctx->fileend = ctx->script_ctx->sigpos;
|
ctx->script_ctx->fileend = ctx->script_ctx->sigpos;
|
||||||
}
|
}
|
||||||
if (!script_write_bio(outdata, ctx->options->indata, ctx->script_ctx->fileend))
|
if (!script_write_bio(outdata, ctx->options->indata, ctx->script_ctx->fileend))
|
||||||
return 1; /* FAILED */
|
return 0; /* FAILED */
|
||||||
if (!script_digest_convert(hash, ctx, ctx->script_ctx->fileend))
|
if (!script_digest_convert(hash, ctx, ctx->script_ctx->fileend))
|
||||||
return 1; /* FAILED */
|
return 0; /* FAILED */
|
||||||
return 0; /* OK */
|
return 1; /* OK */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -489,21 +478,21 @@ static PKCS7 *script_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
|
|||||||
PKCS7 *p7 = pkcs7_create(ctx);
|
PKCS7 *p7 = pkcs7_create(ctx);
|
||||||
|
|
||||||
if (!p7) {
|
if (!p7) {
|
||||||
printf("Creating a new signature failed\n");
|
fprintf(stderr, "Creating a new signature failed\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (!add_indirect_data_object(p7)) {
|
if (!add_indirect_data_object(p7)) {
|
||||||
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n");
|
fprintf(stderr, "Adding SPC_INDIRECT_DATA_OBJID failed\n");
|
||||||
PKCS7_free(p7);
|
PKCS7_free(p7);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
content = spc_indirect_data_content_get(hash, ctx);
|
content = spc_indirect_data_content_get(hash, ctx);
|
||||||
if (!content) {
|
if (!content) {
|
||||||
printf("Failed to get spcIndirectDataContent\n");
|
fprintf(stderr, "Failed to get spcIndirectDataContent\n");
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
if (!sign_spc_indirect_data_content(p7, content)) {
|
if (!sign_spc_indirect_data_content(p7, content)) {
|
||||||
printf("Failed to set signed content\n");
|
fprintf(stderr, "Failed to set signed content\n");
|
||||||
PKCS7_free(p7);
|
PKCS7_free(p7);
|
||||||
ASN1_OCTET_STRING_free(content);
|
ASN1_OCTET_STRING_free(content);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
@@ -547,7 +536,9 @@ static int script_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
|||||||
(void)BIO_set_close(bio, BIO_NOCLOSE);
|
(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,
|
||||||
@@ -555,7 +546,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 */
|
||||||
@@ -621,7 +614,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);
|
||||||
@@ -687,6 +680,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);
|
||||||
@@ -798,15 +793,21 @@ 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)) {
|
||||||
printf("Unable to set the message digest of BIO\n");
|
fprintf(stderr, "Unable to set the message digest of BIO\n");
|
||||||
BIO_free_all(hash);
|
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)) {
|
||||||
printf("Unable calc a message digest value\n");
|
fprintf(stderr, "Unable calc a message digest value\n");
|
||||||
BIO_free_all(hash);
|
BIO_free_all(hash);
|
||||||
return NULL; /* FAILED */
|
return NULL; /* FAILED */
|
||||||
}
|
}
|
||||||
@@ -868,12 +869,12 @@ static int script_write_bio(BIO *bio, char *indata, size_t len)
|
|||||||
static int script_check_file(FILE_FORMAT_CTX *ctx)
|
static int script_check_file(FILE_FORMAT_CTX *ctx)
|
||||||
{
|
{
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
printf("Init error\n\n");
|
fprintf(stderr, "Init error\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
if (ctx->script_ctx->sigpos == 0
|
if (ctx->script_ctx->sigpos == 0
|
||||||
|| ctx->script_ctx->sigpos > ctx->script_ctx->fileend) {
|
|| ctx->script_ctx->sigpos > ctx->script_ctx->fileend) {
|
||||||
printf("No signature found\n\n");
|
fprintf(stderr, "No signature found\n");
|
||||||
return 0; /* FAILED */
|
return 0; /* FAILED */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
__pycache__
|
||||||
|
.pylintrc
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDoTCCAomgAwIBAgIUVD6Q+gnrOmJWbEnmfydpUg2JNmswDQYJKoZIhvcNAQEL
|
|
||||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
|
||||||
MTcwMTAxMDAwMDAwWhcNMzYxMjI3MDAwMDAwWjBYMQswCQYDVQQGEwJQTDEVMBMG
|
|
||||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
|
||||||
cml0eTEQMA4GA1UEAwwHUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
|
||||||
AQoCggEBAMUvCAWI9LrgtVw9RARZLFb/qB1868H86eyr8oITzXl6u9FSQwvGH1MG
|
|
||||||
szRhuD9TJAjy1uIiVPJ7ez2VjKXm2G9lUZMPJQRt50XTGbsGGDi4ITU1W3P+HI5u
|
|
||||||
45I0IL14Qv/R8X26lndBzlY4ImoCTAN4KzdfvoGLaMpNvbC1P7a4mlukrumi3WKT
|
|
||||||
RAq46Mj5DAqr63NOolWimtTB+h0ZWv+xxngR7cfo+EimvhPB7y3xhY9OJ/27l6mJ
|
|
||||||
uQJohz5PmzhZByluMhicTsd2cJEKQb7jnih492okCj6vH/FJmKg+DzXKTyue5Ki4
|
|
||||||
2jhzM9v1npyIkd7s/gnZVEsHH6oQIt8CAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB
|
|
||||||
/zAdBgNVHQ4EFgQUGjxG/vql0oJgItr7HsLaW+koiMgwHwYDVR0jBBgwFoAUGjxG
|
|
||||||
/vql0oJgItr7HsLaW+koiMgwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUA
|
|
||||||
A4IBAQAy7AKbO8B8Njseqjy2LAj2sKHCLc1jsQa7izOAtr852NYFAfpBvkqQfxne
|
|
||||||
8k5iPKmcJE+Sm4wv3V/lzx2AHEXAPa7BgiAo7yeo9UbrDgRRGw4MirQ/djp44ekv
|
|
||||||
KCc54bSE/paUZyEWKr8NbdBy7SZfZ/Dd+XUY2lbm3Mue3AzWl4xp4StoT6oaw6VI
|
|
||||||
H6bIhZupond/RWp4jmHHEfvl4T6YLzl5FC+Ec2xBbpk5vAVZgyfrlv+W6V/il/X9
|
|
||||||
KTZl5ax4FJAm7vPn6fsgdAM5y24zJUAkeakKFsBYtoVoGg1iiFuMEGwFRn7EZYl1
|
|
||||||
8D16qEH+YPLCzujH1PhzjmmAfKl2
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
Binary file not shown.
@@ -1,13 +0,0 @@
|
|||||||
-----BEGIN X509 CRL-----
|
|
||||||
MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJQTDEVMBMGA1UE
|
|
||||||
CgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
|
|
||||||
eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBFw0xOTAxMDEwMDAwMDBaFw00MzAx
|
|
||||||
MDEwMDAwMDBaMCcwJQIUazbrVgbYb+IN803UmJJa0DPHQsAXDTI0MDIyNzE1MzAx
|
|
||||||
NFqgMDAuMB8GA1UdIwQYMBaAFGQQ8as5N9zB/bsdyD9BWHdiJ+8pMAsGA1UdFAQE
|
|
||||||
AgIQATANBgkqhkiG9w0BAQsFAAOCAQEAV+Ce8WaNN/PXbVT9rOy/TS2EDrM/oFPG
|
|
||||||
vwZr2IQDcBtgFV5DpNZRKJo2m4mjPPt1eCjE404U2r6081bvq3PtwSPwezV+uCzF
|
|
||||||
dDUafeR0eZhmzxD8M2Jmi5hGp3fQevDrA4+RR33DneYSNfzGx35VN8v/L7/TuA5X
|
|
||||||
0PG8b5hL9f3vsVXvFRj6hMkRy5m+gxFfWW/Uw3fXIt9sDLJ+eAKURdqn1c3CEwD6
|
|
||||||
bzh0s6dSXT4wp5/l96x8fKAv5hMqDC7KufvwjhhSXdYXDOHDQcv0g5aLo8Ug8dHg
|
|
||||||
NJHqbTAAViyGfvsS9/pYb8kHpAWvaADK84tzaMzj7uCDXlCZEjIr7w==
|
|
||||||
-----END X509 CRL-----
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
-----BEGIN X509 CRL-----
|
|
||||||
MIICMzCCARsCAQEwDQYJKoZIhvcNAQELBQAwZzELMAkGA1UEBhMCUEwxFTATBgNV
|
|
||||||
BAoMDG9zc2xzaWduY29kZTEgMB4GA1UECwwXQ2VydGlmaWNhdGlvbiBBdXRob3Jp
|
|
||||||
dHkxHzAdBgNVBAMMFkludGVybWVkaWF0ZSBDQSBDUkwgRFAXDTE5MDEwMTAwMDAw
|
|
||||||
MFoXDTQzMDEwMTAwMDAwMFowTjAlAhQcZvYIe2b1FreAKfoi/uGkSGJCthcNMjQw
|
|
||||||
MjI3MTUzMDE0WjAlAhRrNutWBthv4g3zTdSYklrQM8dCwBcNMjQwMjI3MTUzMDE0
|
|
||||||
WqAwMC4wHwYDVR0jBBgwFoAUFDxiqeJxiJbmZ4erKH0pBIhq7SMwCwYDVR0UBAQC
|
|
||||||
AhACMA0GCSqGSIb3DQEBCwUAA4IBAQBZzGXEP4XdKuJ8ANIBGPu1Z+7T+4ln+nu3
|
|
||||||
MEPC9BexVAA02YPZx6i4c3cHC87aOL7zsr/K9OeF5MAYzi2QJwsenF4b9QL2rzQV
|
|
||||||
sCAb3sY5ImAxN38GTJ+oI+uTeOefNE0wS7pP4phRmYNZwyDhxA2iT76+luoygyth
|
|
||||||
NesiGalMFDrJvUM1DADTZGQrz9cQVgFq9WTcta9rdTYqSNctxkbpQaY0hgssH1Sh
|
|
||||||
hWlSiFttciA2XVD7Ju/Qv9zN4nCQC0LskgKhqsefsOukpo6jqJ92OmNrrNaERfqs
|
|
||||||
Yavzuj6DlcnE46ZxA0y2Du1apz0WDlbcAnsEqfNSDDCid09v+V9a
|
|
||||||
-----END X509 CRL-----
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDqTCCApGgAwIBAgIUKFKqG3FwQAmy4HgYyO4mGEiQ8QAwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD1RydXN0ZWQgUm9v
|
|
||||||
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0zNzEyMjcwMDAwMDBaMFgxCzAJBgNVBAYT
|
|
||||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxIDAeBgNVBAsMF0NlcnRpZmljYXRp
|
|
||||||
b24gQXV0aG9yaXR5MRAwDgYDVQQDDAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEF
|
|
||||||
AAOCAQ8AMIIBCgKCAQEAxS8IBYj0uuC1XD1EBFksVv+oHXzrwfzp7KvyghPNeXq7
|
|
||||||
0VJDC8YfUwazNGG4P1MkCPLW4iJU8nt7PZWMpebYb2VRkw8lBG3nRdMZuwYYOLgh
|
|
||||||
NTVbc/4cjm7jkjQgvXhC/9HxfbqWd0HOVjgiagJMA3grN1++gYtoyk29sLU/tria
|
|
||||||
W6Su6aLdYpNECrjoyPkMCqvrc06iVaKa1MH6HRla/7HGeBHtx+j4SKa+E8HvLfGF
|
|
||||||
j04n/buXqYm5AmiHPk+bOFkHKW4yGJxOx3ZwkQpBvuOeKHj3aiQKPq8f8UmYqD4P
|
|
||||||
NcpPK57kqLjaOHMz2/WenIiR3uz+CdlUSwcfqhAi3wIDAQABo2MwYTAPBgNVHRMB
|
|
||||||
Af8EBTADAQH/MB0GA1UdDgQWBBQaPEb++qXSgmAi2vsewtpb6SiIyDAfBgNVHSME
|
|
||||||
GDAWgBSzLyt07qrH3+rgkQCvS/YZ3jR+fzAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZI
|
|
||||||
hvcNAQELBQADggEBADCY4hadNyzoz0CpdpBcFjyglxOkgcitIAgvoc2N5zwHrkg7
|
|
||||||
BgJM1BJmCyki0AhXRKwl7sYbzNHgAhP1pBNjZqO13+cRcqPKvrxpYnsv11HaPS2E
|
|
||||||
Ee/8EwHB3JlWlmWd6PHaJV0usRjDOuJnV/I/9mdFfIUcY0aoA36o2CCRJRKcvvVp
|
|
||||||
Ztomnvw8IqFTn3GCNK3TRmVf2RYMhsDNQoEEidJENwCCRlcojmk1Ld95T89QsGOR
|
|
||||||
cWJAHzyfbMQxRD7kQPZ4B2M8MvU3uD6nsamzvVM7H0UkSNuYLVkpU/wTUR8eQ2LI
|
|
||||||
wFyi9JhKP4hF/RBuSzIHpXWO46GvzAO5dXZPLm0=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDsTCCApmgAwIBAgIUQQOniemvgowXmc2hZSZoIWEF8DUwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD1RydXN0ZWQgUm9v
|
|
||||||
dCBDQTAeFw0xNzAxMDEwMDAwMDBaFw0zNjEyMjcwMDAwMDBaMGAxCzAJBgNVBAYT
|
|
||||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxIDAeBgNVBAsMF0NlcnRpZmljYXRp
|
|
||||||
b24gQXV0aG9yaXR5MRgwFgYDVQQDDA9UcnVzdGVkIFJvb3QgQ0EwggEiMA0GCSqG
|
|
||||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCL2tfObRQcJ4fo/jarNfQVmeqjulYkLLNG
|
|
||||||
UtYmFSAxkcYbmpfHpsSxnW9sbDZV8Cp6tFa97V7XATCNL/r671lpZjkYEj0NkjBE
|
|
||||||
84OI0pkAEwWC5m3+dl3wehu977OcV7cMxNTmAHJwEadXR3jmZV625/lja1QqgkqK
|
|
||||||
MqOty2pJNmsRUEogjFoh00eulnapW5u72ovq9IDgjjhdvAClwkTY5jsLTeDwgvfS
|
|
||||||
MRjAmef2qExI/l760Bl0xe4XDdROgN90npS/zuKcCkThtvmffiUZsyeel1kto1pF
|
|
||||||
zkYGJroWSJl0Jt+dpJHcpSXOXP5M+LnuLV4nl5vqwksdPzswQvuZAgMBAAGjYzBh
|
|
||||||
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLMvK3Tuqsff6uCRAK9L9hneNH5/
|
|
||||||
MB8GA1UdIwQYMBaAFLMvK3Tuqsff6uCRAK9L9hneNH5/MA4GA1UdDwEB/wQEAwIB
|
|
||||||
hjANBgkqhkiG9w0BAQsFAAOCAQEAesmiOEl8OA+T4DDOgjfhY6+pUZDDKpsx//mj
|
|
||||||
/1bxr+akfwL3dN5IBq8g8tJJHOLqrl7Lard7onDRnz8GZmpkPvFa87QD2PU2addo
|
|
||||||
DAQWdYsDrNMWkAE37Wk7FZ0RyFHiBopRUMspKmx/XwvJf+rhkidjJYxCo317i/Z8
|
|
||||||
fWi//wGsI6ogezOsMCxNEcIn2PltGfDiVFklmwsXhyfvGYfctqepu661a/7hFUaP
|
|
||||||
uN0iEboTDcQuiWwwEEwMe55L1rjDlpRkGUBah5FteGmVwk0AoT4b+1FVrj9Q6sEa
|
|
||||||
Ge6gsrhu2syUF9CErTW/CiV+jONe2ygw4welOBo598QW71w7Vw==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCplbeNvGrZmTDz
|
|
||||||
p48TyvpOX36bGPMfyTVc8ZfAoh0SG86EFc1LHBV2K52dshHYqniQ6lE14jhsRPps
|
|
||||||
YRBUFXO7I84Jd5CVcrvBWGuL8wXxjMwIW5buzY4x5oKowlyQGIasNiC8Mgx8TncJ
|
|
||||||
kVWE6ekgoP4i1f4PVsFyG8zVNpI5VzHArAemYhvDjuA5jgTisfP8ph2pxUKTzYAI
|
|
||||||
SaKm2YkBFvyhhTxtqnXHt8S0NnfDSCedKSzl1caN1TAKSbWoeChb+Tq8rycjPXh/
|
|
||||||
/7TkYgxmlSHiQhRcyEaZs54Ud8Q0nsnfRMhEtewr2IACmuKrFnoS+GtY5glPilR5
|
|
||||||
ScZ+7A9TAgMBAAECggEABOI/XIzFYMzeg2Rg8DAquQlyc92NE5zPtW0/WxhhizdT
|
|
||||||
bPF3EISXh9DdMimCBeH8XxIzWFfSeFaoNFHp1GCf9ckYRuptk8ppz3OKVhOIbxqr
|
|
||||||
YNY9UVVCrEFmjJ0Vxj7Be5M9TTEU4mxLVX4FtmDVClubeOxyX/oqcr4uwme0Az6A
|
|
||||||
tjBVzl+YEYvZrbhao5d09LVQ3zj1T1EQ+XU5iTTV5Two86FQ6NQ9txe7jxcB8x8S
|
|
||||||
BbD/PakmZj+oIdVBp4xnrhCJ3mYdzXy3qHWxq/BtHgS5fY3/tq3xtVSNxw7QJG7j
|
|
||||||
CT2Cps3/99Lq2CPi8OkQKgjJwWqCZ0jOwHahEMlWIQKBgQDneq4LH0zfPJIW2zsi
|
|
||||||
C7U813hV4NuQXd5EW2bmNe4KKnlrcbt3ZtJv8v3Ff5lMm1i8jDCeaeGhZOi/Ag/z
|
|
||||||
aTtM1STFFEQg3QktcSAvS7hXufvAeufSrPOZdpBO51wqZl5wLMp2lsq885R3wnRl
|
|
||||||
FtIErdmsLigVMC8RZ++gFNIjMQKBgQC7jJE93wV3j36QA7NAgxNH0AW5p5foWuA8
|
|
||||||
gR8MA9cpFI7X7q6hW9HYXw30kD3IzN6UW4U5LT4Pandxx484G1KENcyW2TzeGtpC
|
|
||||||
MWBWHF4Mbxb/2pEkQoPk1dZmUxF5hvaGGHQYJn/pnJFavGUoNBlNjaIfgStzd1IO
|
|
||||||
68ceo5URwwKBgGjHJjrQmzo9L5968sRRamM04Tp2QsyRQMfOW8B+ztX5LebNn17H
|
|
||||||
wx97bRVV0a1UcBFAn81E/iXRCG1VYKT8kCQSIse2ibQaeUoBd+EQtEu5WtRgjcjW
|
|
||||||
Epn3ihC9NwHWPo8mJysQzIpE84JWGducPcpyayI97lTQ761AT741Tn0xAoGARtG2
|
|
||||||
ioFrhBEoPmNXTZXxMt3HO6qgPvoJ0G8FdTkCBx4fLkSPppiQbb6++0l4Oxm5NpY0
|
|
||||||
gTmnRJT0U3+CgjI2/3t9LL0NMeU742DXusxtaw6LxcMXqXSAb2mb0vmtEJG5Bzu2
|
|
||||||
ouPuyxz2+idHn13E7Db+MB1Ldgdpcf7wKo6knJcCgYBwbcjW0MwCah3w4N4VLXBX
|
|
||||||
Q5wPSw7cRcytHqrrWkT/nTI3fxwd7UW6ZdM0IwGIAwYgBYD5B78KH0aP6BlUmYWu
|
|
||||||
8vut6S/MsNyCzHQVbcR9BUK3drByzhysVE3TUQKjCA33v6M/tTixhpyPf+ZZtjlK
|
|
||||||
b1+6D1aGpwt+11f9ubd+Nw==
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIEMzCCAxugAwIBAgIUAQ9lOMiuXUZuKaxzEpwQmCzU7aowDQYJKoZIhvcNAQEL
|
|
||||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
|
|
||||||
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
|
|
||||||
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0zODAxMDEwMDAwMDBaMFUxCzAJBgNVBAYT
|
|
||||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxHDAaBgNVBAsME1RpbWVzdGFtcCBB
|
|
||||||
dXRob3JpdHkxETAPBgNVBAMMCFRlc3QgVFNBMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
|
||||||
AQ8AMIIBCgKCAQEAqZW3jbxq2Zkw86ePE8r6Tl9+mxjzH8k1XPGXwKIdEhvOhBXN
|
|
||||||
SxwVdiudnbIR2Kp4kOpRNeI4bET6bGEQVBVzuyPOCXeQlXK7wVhri/MF8YzMCFuW
|
|
||||||
7s2OMeaCqMJckBiGrDYgvDIMfE53CZFVhOnpIKD+ItX+D1bBchvM1TaSOVcxwKwH
|
|
||||||
pmIbw47gOY4E4rHz/KYdqcVCk82ACEmiptmJARb8oYU8bap1x7fEtDZ3w0gnnSks
|
|
||||||
5dXGjdUwCkm1qHgoW/k6vK8nIz14f/+05GIMZpUh4kIUXMhGmbOeFHfENJ7J30TI
|
|
||||||
RLXsK9iAApriqxZ6EvhrWOYJT4pUeUnGfuwPUwIDAQABo4HvMIHsMAwGA1UdEwEB
|
|
||||||
/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwHQYDVR0OBBYEFKryJiH4Y0KO
|
|
||||||
x2nCc4cOvih1VzjmMB8GA1UdIwQYMBaAFD8ujz0I9Y7079ZMe9X7cO3/rSj5MC0G
|
|
||||||
A1UdHwQmMCQwIqAgoB6GHGh0dHA6Ly8xMjcuMC4wLjE6MTkyNTQvVFNBQ0EwVQYD
|
|
||||||
VR0eBE4wTKAYMAqCCHRlc3QuY29tMAqCCHRlc3Qub3JnoTAwCocIAAAAAAAAAAAw
|
|
||||||
IocgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwDQYJKoZIhvcNAQEL
|
|
||||||
BQADggEBAAhzijhC1kvBV75rxRqj27gtYRG8dNkHc5umzwXyNNMn2tI/kO2Rf+ES
|
|
||||||
9RamQE9sfvOgg3UqfXIfRPsC4cBHnjT+ELdqbt4byk3LPtstJGFuLy0iNRNY9f1j
|
|
||||||
lBJrldLZNNsIpNMQa0u5h/z4m0CAA8j6ayUvcoR11y2zYHkHlSScTq/s7gSQzXlK
|
|
||||||
z4DRiiYif2OEdKVeRCqlDV8AOlhm1+9am74dkfO71aT0G2hko2u19NWZvjc/DqI1
|
|
||||||
V+e2g5TDE7V65d9vvf9tA26i0At/VazvnhsgdpgUkwS6mjUvx+gW3i5YJhtXjdAX
|
|
||||||
hpE0ajpKT0x/dNa/qCwl/9zc8XxGnPk=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDkDCCAnigAwIBAgIULFuB5HWsyba6VHu2Ygv2vt4R4/swDQYJKoZIhvcNAQEL
|
|
||||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
|
|
||||||
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
|
|
||||||
dCBDQTAeFw0xNzAxMDEwMDAwMDBaFw0zNjEyMjcwMDAwMDBaMGAxCzAJBgNVBAYT
|
|
||||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxJDAiBgNVBAsMG1RpbWVzdGFtcCBB
|
|
||||||
dXRob3JpdHkgUm9vdCBDQTEUMBIGA1UEAwwLVFNBIFJvb3QgQ0EwggEiMA0GCSqG
|
|
||||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBo8JJDwVm6UTZvA2g/tOZ3xIbKYXI92Rn
|
|
||||||
T/FCCUycsB5tmoSWcmy1AB6UDv7bFMGy4mdbxnErtdytGj+hEIO3O2EBbpBLAmlJ
|
|
||||||
CEVNRrz/YbxGoJmeAii9s3jignUpTr/qLMSKkLowuqABZl2XtCp7Q83YlZPkVhFL
|
|
||||||
kCAny89cG/QGAUxViN7HB4jWzhcBTTfD4PFvSU1HZNhPM0Y6BCpv2qrof3/tPnQr
|
|
||||||
xM2zVZoIonQpf6paga61O9fM4wc1GqxGGwARz6Bxq6w2OxRDsV/biqP9gVUj0XmF
|
|
||||||
6o/draf3MkDswOUZyKpujOUIf12ezXJFPWaCRN1Rl0vwV2CyVxkvAgMBAAGjQjBA
|
|
||||||
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFD8ujz0I9Y7079ZMe9X7cO3/rSj5
|
|
||||||
MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAtHmPfVgu6Y7uWcpq
|
|
||||||
AdawOTZ/2ICOvAMmQ0LcXKmSpgsneHiyAL1Wwe2/XxTwmrpHylOapIIuV3irHCXU
|
|
||||||
CxaTMUyZGfXoUWsxnR8bcb5ac/aFKkC3ynE2/IfFyJOQ724cK5FRK1+piVleP4Rx
|
|
||||||
C04KQiuxuVLedyvGh5OPU/94ZW2JuuBjImVAO/lUbYhAUSpwueX2lYKSSPLkPfDx
|
|
||||||
AsIp55x70iQ+EsgARvseVY2JRzvRnuh66V4P15wn3dIzjtWQ1/t007wMk5Lji5dQ
|
|
||||||
iSvdyqULBytBqDtLPLzRuma1KJEPRIamF1j6Or6HaHSVUorRhqI3XuxEUGdO4LxZ
|
|
||||||
QepMyA==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
Binary file not shown.
@@ -1,15 +0,0 @@
|
|||||||
-----BEGIN X509 CRL-----
|
|
||||||
MIICUzCCATsCAQEwDQYJKoZIhvcNAQELBQAwYDELMAkGA1UEBhMCUEwxFTATBgNV
|
|
||||||
BAoMDG9zc2xzaWduY29kZTEkMCIGA1UECwwbVGltZXN0YW1wIEF1dGhvcml0eSBS
|
|
||||||
b290IENBMRQwEgYDVQQDDAtUU0EgUm9vdCBDQRcNMTkwMTAxMDAwMDAwWhcNNDMw
|
|
||||||
MTAxMDAwMDAwWjB1MCUCFA5lCWy+o133yMUTfqtWmkigL1MeFw0yNDAyMjcxNTMw
|
|
||||||
MTVaMCUCFBxm9gh7ZvUWt4Ap+iL+4aRIYkK2Fw0yNDAyMjcxNTMwMTRaMCUCFGs2
|
|
||||||
61YG2G/iDfNN1JiSWtAzx0LAFw0yNDAyMjcxNTMwMTRaoDAwLjAfBgNVHSMEGDAW
|
|
||||||
gBQ/Lo89CPWO9O/WTHvV+3Dt/60o+TALBgNVHRQEBAICEAMwDQYJKoZIhvcNAQEL
|
|
||||||
BQADggEBAJ1HK2LepVJyOfqbODFxD6GJo5jr1HEnoaZ1h/iJTZZyDYfRf8d8Y/VG
|
|
||||||
Iva00gj2KVy8tOlO0FrUR1Tqk42IjaPld0lXqKl4hkmCUWLpLgual5JcQPHhDUnT
|
|
||||||
hiIDvbI5UHGCWeN+unXFRuT9CvtAM+3FOhuL9bBnXwdlOxZPWL8wnYT0jB/HzdKP
|
|
||||||
KOWfN7eEXo6tTL8XxRJ5LxjwbrK1eZCdQqL2Rt2W8JTMweeqv9PkNqzYeDAvKc0s
|
|
||||||
UCkKj+aNxQlNPy+Tw/MckJK1NE921b8LwuV0uzBrOg0Gr62RnnPGa6Z5YLArczWo
|
|
||||||
aZlLVsJuQrOxxyXe/kygCu9lqjaf4CI=
|
|
||||||
-----END X509 CRL-----
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDxU8lwCceWEesm
|
|
||||||
HIQu9M8mIznHFWmxFF55E16DseWr1K2FbOKnNv1ddNhUHFhBQChcGPn/CvwfOMR7
|
|
||||||
DbCETrty9HUtoK3fCVZQuYIjZwRLZZB2ryLgO4PK+j07Z61yABi7NKBKv8oHISLU
|
|
||||||
QcNg7rBAZhmAurKpNu2Gpz/jFpFXwd6O+8xnsYFLT0zyjrq0rEvLmWQd5FBQaVt7
|
|
||||||
P+U9GH3GCg0kmdhIXAfdfSnqzj0OMnnzVdnEYrd1mYx+ZA7m0CmVJw330QXWiyax
|
|
||||||
wimNHUvlpIiZA8ol17tAybinhPL5nSM/LRZ2PN90EgyX1bv3x/cKCEiOYPSZ7xXV
|
|
||||||
mrRGjCtjAgMBAAECggEAHj01fIh9LdzI7lmcZpXebxTy5HNWbw3yWJGIwk/ES6e2
|
|
||||||
poViUTmevdsqUD/M/0AezouCp+akePUQCatJdwq2ikz/cdw0bUIqQqs8F1uNOjVb
|
|
||||||
yMNhR1+tv/1jNtJi9Wn1r1+ExlkJ46LPTnF/HeJKy4b/oxXB1VpAoSLL6pSlWa1+
|
|
||||||
+iEWM+s6xlxyFkeWPq3L3u1QGkuW58KqQae86mR8Mgc0kOVuTCqWpHgNjfxt7tnt
|
|
||||||
L/oBE9zEJmS3iZcGh1X5VR4CUQmtrCp7ldNdhSNk5WcNCNSsuIX+B13s658a0sRB
|
|
||||||
AnPIX08moB5VHZ/danblny5Zo6SrobWBBcTabwjnYQKBgQD/BHktS70tQj3yBqVL
|
|
||||||
xXmaO5ozqMLqF9A2o4EiJ/pF07ecHXmbiGaP9Nf/FJemuU5OHjw8akuxKn2M+DTu
|
|
||||||
gHYOHwByA9/SOeAiD8bp/dJNE+2BO2zygoG/adhEV5tLK8IYdz241t8oVZbQLwql
|
|
||||||
ZCs1uFab6E/cZEJgSQ0QuC8vtwKBgQDyQc+MX56UFFCP1QpWLIwFVdoPbOj/3cVZ
|
|
||||||
FIjQO9rNYNIscS36nISIBh0voubI2xFvO7/s+WS1pD1bOmn6qwsndewFGdmMtjnN
|
|
||||||
YguakmHAUmcF33f+gXVzwR91QvGPTjI2Fzd59OwOrZofO1+hajQiBKIP2B9VHJNP
|
|
||||||
khspe44JtQKBgFqTTyrMZNOnXHMS8zC3Ydpq4vkILrqQXK6bYiksg9K7QNKdEW0x
|
|
||||||
hCQLNZBu0vIvjOVoDcLzihDR46fnHH29eLDJSBI22A9F6RqP+flv4nrn4gptfeOg
|
|
||||||
gM7onByh9RE86IJiD7UP9FDSHW+x1Zkqu8Inx/M2Du9bWMv0BkTy9id/AoGBAOEy
|
|
||||||
oDcDZCyPPdyW1AcLXhZPmmegfG/tvlhyqEO6gElO6dF6XJ2NBf5UgKkZq6OnUWuv
|
|
||||||
hVhK9X2M8aRuhroIalQCYKbVQtB1TQJJVDQaQ1g+wZpKBAfIXGCAdDfTRS5MKIzz
|
|
||||||
xBRQw2dZpd3Gmb05NsEwwV4tL+M0rxPW4/0J6B3JAoGAB1vlzPsfKVvV9jwVpfdO
|
|
||||||
W2MWAqPF4iI716zLt2F30WNe/42MudQGvMYUEPTYQMu3hhpQk/6UFY2Mfux6+OKk
|
|
||||||
zG1khRdlq9BkCczfSVjkUvf4wTUUY5b66i4EpeJ//8OArZEx67LhmW715h/LExzG
|
|
||||||
jkdwUMLiaSrpf8KSTL3NxM0=
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIEIjCCAwqgAwIBAgIUDmUJbL6jXffIxRN+q1aaSKAvUx4wDQYJKoZIhvcNAQEL
|
|
||||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
|
|
||||||
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
|
|
||||||
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0zODAxMDEwMDAwMDBaMEQxCzAJBgNVBAYT
|
|
||||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNVBAsMA1RTQTEQMA4GA1UE
|
|
||||||
AwwHUmV2b2tlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPFTyXAJ
|
|
||||||
x5YR6yYchC70zyYjOccVabEUXnkTXoOx5avUrYVs4qc2/V102FQcWEFAKFwY+f8K
|
|
||||||
/B84xHsNsIROu3L0dS2grd8JVlC5giNnBEtlkHavIuA7g8r6PTtnrXIAGLs0oEq/
|
|
||||||
ygchItRBw2DusEBmGYC6sqk27YanP+MWkVfB3o77zGexgUtPTPKOurSsS8uZZB3k
|
|
||||||
UFBpW3s/5T0YfcYKDSSZ2EhcB919KerOPQ4yefNV2cRit3WZjH5kDubQKZUnDffR
|
|
||||||
BdaLJrHCKY0dS+WkiJkDyiXXu0DJuKeE8vmdIz8tFnY833QSDJfVu/fH9woISI5g
|
|
||||||
9JnvFdWatEaMK2MCAwEAAaOB7zCB7DAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQM
|
|
||||||
MAoGCCsGAQUFBwMIMB0GA1UdDgQWBBTTuQ7LmtwtVydASwFBXd4xUIEh3jAfBgNV
|
|
||||||
HSMEGDAWgBQ/Lo89CPWO9O/WTHvV+3Dt/60o+TAtBgNVHR8EJjAkMCKgIKAehhxo
|
|
||||||
dHRwOi8vMTI3LjAuMC4xOjE5MjU0L1RTQUNBMFUGA1UdHgROMEygGDAKggh0ZXN0
|
|
||||||
LmNvbTAKggh0ZXN0Lm9yZ6EwMAqHCAAAAAAAAAAAMCKHIAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAAAAAAAAMA0GCSqGSIb3DQEBCwUAA4IBAQBMiBltqGRRLmK9
|
|
||||||
0RymCJ4oxmX2jwZ4SM7fem39Ozei7NIQIw5nlkPJ7ZWyfQQNFMIujfwJJGzDguax
|
|
||||||
mMJHWngzbKjkbdSHnQswxT79RRwenlIKkExck6p2OUT82nGu/6TBIYutMJlITwKF
|
|
||||||
5OEmu+WneCvTkvEs0wussIug7E7dV6jJO9/TbwWyrtqU/t9GNRbu/4FIdQ9p9pK9
|
|
||||||
BcqaPmjn7IqnLs94THFfMFH0HVkqpLOfa9Wa8uc/C7WyIMTkchXb4U7/8B/hsDj7
|
|
||||||
BfKwN/F+IMNw4Rfqytk2JSWuV4pr7MiBweLKBwGgt4DhvfZj32Y/WFNANxtYkE9e
|
|
||||||
55mIPqG5
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,46 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIID7jCCAtagAwIBAgIUKiF/FG2pQjlbId3ox+nQHL/tJ4UwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD0ludGVybWVkaWF0
|
|
||||||
ZSBDQTAeFw0xODAxMDEwMDAwMDBaFw0zNDEyMzEwMDAwMDBaMIGdMQswCQYDVQQG
|
|
||||||
EwJQTDEZMBcGA1UECAwQTWF6b3ZpYSBQcm92aW5jZTEPMA0GA1UEBwwGV2Fyc2F3
|
|
||||||
MRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNVBAsMA0NTUDEUMBIGA1UEAwwL
|
|
||||||
Q2VydGlmaWNhdGUxJzAlBgkqhkiG9w0BCQEWGG9zc2xzaWduY29kZUBleGFtcGxl
|
|
||||||
LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdBCaytt9xsrUx0
|
|
||||||
2Fekq+IrsR2cC1pL9NANN3TbBv8RKt1IefMh8TjA1uPaOYZvz3o2ml9qKGmJ+uxH
|
|
||||||
kzLojKbg98bcmxBrkWemLQwmRv1hZIO8D4xiYRd0O0KZizrvwWwlNADzXXWw7iz+
|
|
||||||
MPPWkXj2nT5MpOTi3S851SwOc/c9SYCazCP8rMGItKHLO7iCjK3sFwBDI9eaTd2N
|
|
||||||
EjqEHadIymHRizeTOaYv34FokQiRgR/zk4flT6+b6DQHxnlbIivV61OP4bBlFtXX
|
|
||||||
jC4iGdHLIahhVMlw6ixGqR6910psIp0ST0KM8ly+N+1rPhoNkNSLqkzGUudKo7mV
|
|
||||||
t+Cp4EMCAwEAAaNiMGAwCQYDVR0TBAIwADAdBgNVHQ4EFgQU6a4Ta3t0UCTG04bC
|
|
||||||
WMCotMPLyWUwHwYDVR0jBBgwFoAUZBDxqzk33MH9ux3IP0FYd2In7ykwEwYDVR0l
|
|
||||||
BAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAN2Sad4rLRSKWmaRRUCn
|
|
||||||
syRO45y7zzvCRApHVSoeBUmtHP+n/OZ3rJTixfluqiGFAqbaXgTN8IantyfqoTjV
|
|
||||||
XgCP1qzSM3staLCkeAiZ0/OLW+hyHopP8aXX2ez/hMojB/J1b457+vkuudnNiLx8
|
|
||||||
by44nonUnJb3zyxmCSxcBklNP1wlxYjbbq5hFJ/et2/Y5Ct6igYAEMsYZUEUq3e7
|
|
||||||
g2GWbqNN/i2tnJyGjDPrNRdOuODuclfIDnYSPn83a40XHn+Hgl9SmoXuSdDutAXC
|
|
||||||
b017GsOa7OV3ZPildcIa3d/yk4S3L56SdoY+Py4NIIDmxcjji1e91qCrrFfGYwmg
|
|
||||||
TkQ=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
|
||||||
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
|
||||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
|
||||||
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
|
|
||||||
AAOCAQ8AMIIBCgKCAQEA5yrw3i+fvxBSODvCoQb+9ibWRozmphJBp57tKv9ZraQ5
|
|
||||||
THK+PkCdjNiJuxZn8F1QLsjJo6JqrrXufYln7wixK0Seu4uV6I2TRzcRyJx29D89
|
|
||||||
0G9GrTXKn7v8z32QAqCgtwSZ17uWYTFmRAYPllWXcWDONsVyw3UF2nClndL7GMqM
|
|
||||||
gDizlwsfg8HmRpZegn82I7Y2DXccm9a7pFHuBHpwenKqfBnMsXo3Jj4Xlr1cLTrh
|
|
||||||
+6ksS5YogOsOd9b5Dfz6FaGmmwrlUWHwdi+EzdnSpOnXzmgflF23sZQ0ynsVvmpl
|
|
||||||
iD4rXBWnxnQ6Ken3wVPNrA/0ZYGbgSKrcv+/olkh5QIDAQABo2YwZDASBgNVHRMB
|
|
||||||
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRkEPGrOTfcwf27Hcg/QVh3YifvKTAfBgNV
|
|
||||||
HSMEGDAWgBQaPEb++qXSgmAi2vsewtpb6SiIyDAOBgNVHQ8BAf8EBAMCAYYwDQYJ
|
|
||||||
KoZIhvcNAQELBQADggEBAL22kK3SDGnr3lhRE7ipptlKalrQKfpght0XEKm5hxCL
|
|
||||||
tougN2wtaTEWMwr2YfGJohcKBaGKQ+Bv6WY+EV+hJE4qEUFh6BGqRMtuZdiAbkG+
|
|
||||||
EveEMhZWQzgf9rUID+Y9Eg+NfCxlpkdQPjUxUV9OkGIshlxkUP8Y+C0h0xIcwq5v
|
|
||||||
hAfNiJAdcw4fUvtLkpEOFoOjThB8zxOu+Cl3xLCcNOMPLdSxd3YXjy6CMuuOk4RB
|
|
||||||
gOc8YCyyEvwb9KmARZpMOcQJmucMhs+aC3DF+n71g+agFhDl3Z0QkyyyRjAcD04+
|
|
||||||
sAR9C8PbqSCQAdydHbAFViEX6x3oGJ7L6zEDcIS10wg=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
Binary file not shown.
@@ -1,47 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIEPTCCAyWgAwIBAgIUe8Im9GuMCHMi3/FDfLgzoE8vTKgwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwZzELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNVBAMMFkludGVybWVkaWF0
|
|
||||||
ZSBDQSBDUkwgRFAwHhcNMTgwMTAxMDAwMDAwWhcNMzQxMjMxMDAwMDAwWjCBqzEL
|
|
||||||
MAkGA1UEBhMCUEwxGTAXBgNVBAgMEE1hem92aWEgUHJvdmluY2UxDzANBgNVBAcM
|
|
||||||
BldhcnNhdzEVMBMGA1UECgwMb3NzbHNpZ25jb2RlMQwwCgYDVQQLDANDU1AxIjAg
|
|
||||||
BgNVBAMMGUNlcnRpZmljYXRlIFg1MDl2MyBDUkwgRFAxJzAlBgkqhkiG9w0BCQEW
|
|
||||||
GG9zc2xzaWduY29kZUBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
|
||||||
ADCCAQoCggEBAMdBCaytt9xsrUx02Fekq+IrsR2cC1pL9NANN3TbBv8RKt1IefMh
|
|
||||||
8TjA1uPaOYZvz3o2ml9qKGmJ+uxHkzLojKbg98bcmxBrkWemLQwmRv1hZIO8D4xi
|
|
||||||
YRd0O0KZizrvwWwlNADzXXWw7iz+MPPWkXj2nT5MpOTi3S851SwOc/c9SYCazCP8
|
|
||||||
rMGItKHLO7iCjK3sFwBDI9eaTd2NEjqEHadIymHRizeTOaYv34FokQiRgR/zk4fl
|
|
||||||
T6+b6DQHxnlbIivV61OP4bBlFtXXjC4iGdHLIahhVMlw6ixGqR6910psIp0ST0KM
|
|
||||||
8ly+N+1rPhoNkNSLqkzGUudKo7mVt+Cp4EMCAwEAAaOBmzCBmDAJBgNVHRMEAjAA
|
|
||||||
MB0GA1UdDgQWBBTprhNre3RQJMbThsJYwKi0w8vJZTAfBgNVHSMEGDAWgBQUPGKp
|
|
||||||
4nGIluZnh6sofSkEiGrtIzATBgNVHSUEDDAKBggrBgEFBQcDAzA2BgNVHR8ELzAt
|
|
||||||
MCugKaAnhiVodHRwOi8vMTI3LjAuMC4xOjE5MjU0L2ludGVybWVkaWF0ZUNBMA0G
|
|
||||||
CSqGSIb3DQEBCwUAA4IBAQBlJrcOaJQQ3TuYaVtmH8VbCdF3GQE+255g0Kq4sWoO
|
|
||||||
ZgZm6LmRkchuoOXqeZ7aAV6HnGGpZf64ShPSZ3KPt4/UVYkRyS0UihN2ACsGrS4o
|
|
||||||
ZjOaaoM2xDxttngKV3lAF4xbx18RvAsx9QIzQhzowaSUBQNuu5W4tne/6h7htuwA
|
|
||||||
KNc0go4fqpCqQjNRVeB1IN50BzUrlHu3zQzfH0LDyUTt2gnObLHMl566Ft0azAG9
|
|
||||||
emHRM+BOUjKY3ZTjM+JEzpwWgse6e4r+J2fYVYIEtkSfm4ZZnAs5WFWI5o8tqr4b
|
|
||||||
ruBN7l6oP6R3ugOtPk7tW4x7OO0QoDnfa418MkBlXeqL
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDszCCApugAwIBAgIUN3RBnJCUJ8HmbeNjJZ/6jsXJLGEwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
|
||||||
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBnMQswCQYDVQQGEwJQTDEVMBMG
|
|
||||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
|
||||||
cml0eTEfMB0GA1UEAwwWSW50ZXJtZWRpYXRlIENBIENSTCBEUDCCASIwDQYJKoZI
|
|
||||||
hvcNAQEBBQADggEPADCCAQoCggEBAME32IBpxW4FhVuZe1PTarEskVHP233QjZtx
|
|
||||||
poC67/lUK44gtFmsxYsMrDYmmny5pfoM/Byxl5/rorEddLqtDe1kd1SpXUvEYxox
|
|
||||||
s5rizRd5sZPgkwNoJkSVyNZFwj7gKZHeg6IQHSxNgmTybZ+eZqiNvEveksj3lGpM
|
|
||||||
Xrbiew7cXUyIP636GPtYxLyIbwDVP0jScqcA/dmSAqofFVUi0SW3OS1hpyXAmmx8
|
|
||||||
hQHJRKPjPgitZVgjwf5X8/eMTa+ca9dRlRFLk7AcbkF6NcbLm+cRo816nO0EBFV4
|
|
||||||
Sn2dW9uYqJIfZcpRQ7wbv4fUCghwrk9h3gXrb7AweyK8nyYlmosCAwEAAaNmMGQw
|
|
||||||
EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUFDxiqeJxiJbmZ4erKH0pBIhq
|
|
||||||
7SMwHwYDVR0jBBgwFoAUGjxG/vql0oJgItr7HsLaW+koiMgwDgYDVR0PAQH/BAQD
|
|
||||||
AgGGMA0GCSqGSIb3DQEBCwUAA4IBAQAlI/1XnGc9WzL53rRascZc1EgWAnej9YFS
|
|
||||||
Dax5+nozYTihC8BRxGfSh1FGRVsmFWhZ0z0XogJJC2bZrQ/36+vwoILItcsWHrQr
|
|
||||||
rFoZa6s1Uo7ZCd9SfmXjbhMLQgydocCh9YIF66CAkQLwRXc1QIpF7nuZ+rxk0ru1
|
|
||||||
uGjjBrFRfdSdzlFnyK6wfFzi6LtYDVgVEHC7zzL9E/cyuGo7qQ++SoOg99HjTVY1
|
|
||||||
PS3ea522bRO2bJpYwZJvvbg020DAfm686VXwAadODdBkI2h6U5SwTxp4SkSmq9SI
|
|
||||||
mjtERFtnAKD0R2YrX4RzuIckezvwsqLDkQjMnI9XQmv5HWUZimcC
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIID6jCCAtKgAwIBAgIUcgUgRT1Lx8XLdgp7xcWxVl9YBjYwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD0ludGVybWVkaWF0
|
|
||||||
ZSBDQTAeFw0xODAxMDEwMDAwMDBaFw0xOTAxMDEwMDAwMDBaMIGZMQswCQYDVQQG
|
|
||||||
EwJQTDEZMBcGA1UECAwQTWF6b3ZpYSBQcm92aW5jZTEPMA0GA1UEBwwGV2Fyc2F3
|
|
||||||
MRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNVBAsMA0NTUDEQMA4GA1UEAwwH
|
|
||||||
RXhwaXJlZDEnMCUGCSqGSIb3DQEJARYYb3NzbHNpZ25jb2RlQGV4YW1wbGUuY29t
|
|
||||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx0EJrK233GytTHTYV6Sr
|
|
||||||
4iuxHZwLWkv00A03dNsG/xEq3Uh58yHxOMDW49o5hm/PejaaX2ooaYn67EeTMuiM
|
|
||||||
puD3xtybEGuRZ6YtDCZG/WFkg7wPjGJhF3Q7QpmLOu/BbCU0APNddbDuLP4w89aR
|
|
||||||
ePadPkyk5OLdLznVLA5z9z1JgJrMI/yswYi0ocs7uIKMrewXAEMj15pN3Y0SOoQd
|
|
||||||
p0jKYdGLN5M5pi/fgWiRCJGBH/OTh+VPr5voNAfGeVsiK9XrU4/hsGUW1deMLiIZ
|
|
||||||
0cshqGFUyXDqLEapHr3XSmwinRJPQozyXL437Ws+Gg2Q1IuqTMZS50qjuZW34Kng
|
|
||||||
QwIDAQABo2IwYDAJBgNVHRMEAjAAMB0GA1UdDgQWBBTprhNre3RQJMbThsJYwKi0
|
|
||||||
w8vJZTAfBgNVHSMEGDAWgBRkEPGrOTfcwf27Hcg/QVh3YifvKTATBgNVHSUEDDAK
|
|
||||||
BggrBgEFBQcDAzANBgkqhkiG9w0BAQsFAAOCAQEA0AxgPkboWfIOMYFOP6kQ4nxY
|
|
||||||
jQ+kAH842ALjm/5z20fYPS0k3LiCNS0FfBPzygeWQLwDGcH2QX6Lfec62CeIe9R9
|
|
||||||
IAdsX+nNxn9FeIZssfMK3EPgksGUybUNub78mXPrnhCNjYf/GmDY/Cf7jhBtNphK
|
|
||||||
6zCPOC0WDrupnLW7r4FyrB1j2CEgaHhiSmlQ+19rqbvcNfaCOMfe7IfiwkvVIzE6
|
|
||||||
tQhnudB/HnW3+pWT83n/KQk0F8lu00fahkak/0bPidTe4zOvepabiWYQXKJ9ZXhm
|
|
||||||
UW7FHHSM5Vbn2A6zyEht7rcK/gkpHbkckoIi6bDMFMp+K9o3qV7PzZPkaau7fg==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
|
||||||
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
|
||||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
|
||||||
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
|
|
||||||
AAOCAQ8AMIIBCgKCAQEA5yrw3i+fvxBSODvCoQb+9ibWRozmphJBp57tKv9ZraQ5
|
|
||||||
THK+PkCdjNiJuxZn8F1QLsjJo6JqrrXufYln7wixK0Seu4uV6I2TRzcRyJx29D89
|
|
||||||
0G9GrTXKn7v8z32QAqCgtwSZ17uWYTFmRAYPllWXcWDONsVyw3UF2nClndL7GMqM
|
|
||||||
gDizlwsfg8HmRpZegn82I7Y2DXccm9a7pFHuBHpwenKqfBnMsXo3Jj4Xlr1cLTrh
|
|
||||||
+6ksS5YogOsOd9b5Dfz6FaGmmwrlUWHwdi+EzdnSpOnXzmgflF23sZQ0ynsVvmpl
|
|
||||||
iD4rXBWnxnQ6Ken3wVPNrA/0ZYGbgSKrcv+/olkh5QIDAQABo2YwZDASBgNVHRMB
|
|
||||||
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRkEPGrOTfcwf27Hcg/QVh3YifvKTAfBgNV
|
|
||||||
HSMEGDAWgBQaPEb++qXSgmAi2vsewtpb6SiIyDAOBgNVHQ8BAf8EBAMCAYYwDQYJ
|
|
||||||
KoZIhvcNAQELBQADggEBAL22kK3SDGnr3lhRE7ipptlKalrQKfpght0XEKm5hxCL
|
|
||||||
tougN2wtaTEWMwr2YfGJohcKBaGKQ+Bv6WY+EV+hJE4qEUFh6BGqRMtuZdiAbkG+
|
|
||||||
EveEMhZWQzgf9rUID+Y9Eg+NfCxlpkdQPjUxUV9OkGIshlxkUP8Y+C0h0xIcwq5v
|
|
||||||
hAfNiJAdcw4fUvtLkpEOFoOjThB8zxOu+Cl3xLCcNOMPLdSxd3YXjy6CMuuOk4RB
|
|
||||||
gOc8YCyyEvwb9KmARZpMOcQJmucMhs+aC3DF+n71g+agFhDl3Z0QkyyyRjAcD04+
|
|
||||||
sAR9C8PbqSCQAdydHbAFViEX6x3oGJ7L6zEDcIS10wg=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
|
||||||
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
|
||||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
|
||||||
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
|
|
||||||
AAOCAQ8AMIIBCgKCAQEA5yrw3i+fvxBSODvCoQb+9ibWRozmphJBp57tKv9ZraQ5
|
|
||||||
THK+PkCdjNiJuxZn8F1QLsjJo6JqrrXufYln7wixK0Seu4uV6I2TRzcRyJx29D89
|
|
||||||
0G9GrTXKn7v8z32QAqCgtwSZ17uWYTFmRAYPllWXcWDONsVyw3UF2nClndL7GMqM
|
|
||||||
gDizlwsfg8HmRpZegn82I7Y2DXccm9a7pFHuBHpwenKqfBnMsXo3Jj4Xlr1cLTrh
|
|
||||||
+6ksS5YogOsOd9b5Dfz6FaGmmwrlUWHwdi+EzdnSpOnXzmgflF23sZQ0ynsVvmpl
|
|
||||||
iD4rXBWnxnQ6Ken3wVPNrA/0ZYGbgSKrcv+/olkh5QIDAQABo2YwZDASBgNVHRMB
|
|
||||||
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRkEPGrOTfcwf27Hcg/QVh3YifvKTAfBgNV
|
|
||||||
HSMEGDAWgBQaPEb++qXSgmAi2vsewtpb6SiIyDAOBgNVHQ8BAf8EBAMCAYYwDQYJ
|
|
||||||
KoZIhvcNAQELBQADggEBAL22kK3SDGnr3lhRE7ipptlKalrQKfpght0XEKm5hxCL
|
|
||||||
tougN2wtaTEWMwr2YfGJohcKBaGKQ+Bv6WY+EV+hJE4qEUFh6BGqRMtuZdiAbkG+
|
|
||||||
EveEMhZWQzgf9rUID+Y9Eg+NfCxlpkdQPjUxUV9OkGIshlxkUP8Y+C0h0xIcwq5v
|
|
||||||
hAfNiJAdcw4fUvtLkpEOFoOjThB8zxOu+Cl3xLCcNOMPLdSxd3YXjy6CMuuOk4RB
|
|
||||||
gOc8YCyyEvwb9KmARZpMOcQJmucMhs+aC3DF+n71g+agFhDl3Z0QkyyyRjAcD04+
|
|
||||||
sAR9C8PbqSCQAdydHbAFViEX6x3oGJ7L6zEDcIS10wg=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDszCCApugAwIBAgIUN3RBnJCUJ8HmbeNjJZ/6jsXJLGEwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
|
||||||
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBnMQswCQYDVQQGEwJQTDEVMBMG
|
|
||||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
|
||||||
cml0eTEfMB0GA1UEAwwWSW50ZXJtZWRpYXRlIENBIENSTCBEUDCCASIwDQYJKoZI
|
|
||||||
hvcNAQEBBQADggEPADCCAQoCggEBAME32IBpxW4FhVuZe1PTarEskVHP233QjZtx
|
|
||||||
poC67/lUK44gtFmsxYsMrDYmmny5pfoM/Byxl5/rorEddLqtDe1kd1SpXUvEYxox
|
|
||||||
s5rizRd5sZPgkwNoJkSVyNZFwj7gKZHeg6IQHSxNgmTybZ+eZqiNvEveksj3lGpM
|
|
||||||
Xrbiew7cXUyIP636GPtYxLyIbwDVP0jScqcA/dmSAqofFVUi0SW3OS1hpyXAmmx8
|
|
||||||
hQHJRKPjPgitZVgjwf5X8/eMTa+ca9dRlRFLk7AcbkF6NcbLm+cRo816nO0EBFV4
|
|
||||||
Sn2dW9uYqJIfZcpRQ7wbv4fUCghwrk9h3gXrb7AweyK8nyYlmosCAwEAAaNmMGQw
|
|
||||||
EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUFDxiqeJxiJbmZ4erKH0pBIhq
|
|
||||||
7SMwHwYDVR0jBBgwFoAUGjxG/vql0oJgItr7HsLaW+koiMgwDgYDVR0PAQH/BAQD
|
|
||||||
AgGGMA0GCSqGSIb3DQEBCwUAA4IBAQAlI/1XnGc9WzL53rRascZc1EgWAnej9YFS
|
|
||||||
Dax5+nozYTihC8BRxGfSh1FGRVsmFWhZ0z0XogJJC2bZrQ/36+vwoILItcsWHrQr
|
|
||||||
rFoZa6s1Uo7ZCd9SfmXjbhMLQgydocCh9YIF66CAkQLwRXc1QIpF7nuZ+rxk0ru1
|
|
||||||
uGjjBrFRfdSdzlFnyK6wfFzi6LtYDVgVEHC7zzL9E/cyuGo7qQ++SoOg99HjTVY1
|
|
||||||
PS3ea522bRO2bJpYwZJvvbg020DAfm686VXwAadODdBkI2h6U5SwTxp4SkSmq9SI
|
|
||||||
mjtERFtnAKD0R2YrX4RzuIckezvwsqLDkQjMnI9XQmv5HWUZimcC
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
Binary file not shown.
@@ -1,28 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHQQmsrbfcbK1M
|
|
||||||
dNhXpKviK7EdnAtaS/TQDTd02wb/ESrdSHnzIfE4wNbj2jmGb896Nppfaihpifrs
|
|
||||||
R5My6Iym4PfG3JsQa5Fnpi0MJkb9YWSDvA+MYmEXdDtCmYs678FsJTQA8111sO4s
|
|
||||||
/jDz1pF49p0+TKTk4t0vOdUsDnP3PUmAmswj/KzBiLShyzu4goyt7BcAQyPXmk3d
|
|
||||||
jRI6hB2nSMph0Ys3kzmmL9+BaJEIkYEf85OH5U+vm+g0B8Z5WyIr1etTj+GwZRbV
|
|
||||||
14wuIhnRyyGoYVTJcOosRqkevddKbCKdEk9CjPJcvjftaz4aDZDUi6pMxlLnSqO5
|
|
||||||
lbfgqeBDAgMBAAECggEABtHIBfvwFgA2Mi6xlNZS96utJSlJDi8ZUuGQ61Pvul0Z
|
|
||||||
DXfEjLi1q86VzDiUzXAYNsOVpvxYI7yQNPQCKrTg03lRoaG9QOOdl2GNmyPYPCXQ
|
|
||||||
Ld4K3jAjyIy21oGwzTSVdyES1ZF+ul9y12FfxYirc+tk2FQBNMA697nP/PEFsQl9
|
|
||||||
cMxBB5CIGH7jSI6UIbp99Kd90ScbnE2mLACM3d0s0sRq783P9yJGpM9a71XE/K2p
|
|
||||||
CxoRxwqmNRGvI5LrGs1zIF2BSZZgNT71cdfMnAIJBeaoNY7QTKDQlg9xQojE+0if
|
|
||||||
is16mMhrHQbIFBSxHDRR4uVdiY4iKDB6Lg2pMGcjUQKBgQDzWI2O8bh+YvaEM9QN
|
|
||||||
uUC1LI6oGzj7+wxkIhjXhCX680EFeJk6AQqNfu5VoBN/nrCXxqjNGKhjqDmtzxjD
|
|
||||||
y9LYTCJ8rM9eCkrgcdCFkTQNcdNT/zqkHeOIxsoXgsFLhYozWcbiW+8oe9MTrXX/
|
|
||||||
m9u9kTHkSjKziof7wxGXu3pAmQKBgQDRnYd+urSG0bulBccqT06pJpQMjYIi6CqQ
|
|
||||||
LYEkLlELxOT+EPeEH1ZdgYkDzzgKoO5L/Jp0Ic6kKEQv+o4l+g1gJp6V5wwX81nv
|
|
||||||
FJApcg51Yma6WQb6PEJ8HiZ531JQpGZZPmJvRIvEdqw+Dz/dferTApvOlD9s4PfM
|
|
||||||
xG4R/EoFOwKBgQCEQdW2IhQWxOycj5qp1syfa1chcKI4+YoThiCgSZdm2/yz34bP
|
|
||||||
6q70lk8sxHK0gugRpYwq5ELo3w5yM8OO7uFqY36+6iFOSCPH9rPRVEjJIdsspOQX
|
|
||||||
PJNkzD4cJxmtVSf2ns2kSzkhdKMU58rhILF+R0Kpg9YolJsxrySJpgBcyQKBgQCC
|
|
||||||
KCTYRiqOhHDVuU7AMNqRIclQOhYSgsLbH8ZOpwvgGPRv5i0rNyIzkZl4ahVMVD1j
|
|
||||||
pYhqkAt11yLv/86AOlJP3+sc/Yh+3rZ7Q/N4KMBdlypej6VLgFtwInCVwFumg06i
|
|
||||||
H6CToqZ+6YluR53KdMN5HueMUHVJsC9uUJJgTJ3RvQKBgFPi8mgG4zcdoKBhqyq2
|
|
||||||
x3VQEe0VYnzBsIz42E/NFpuB4ZwC7j0Uez+QFUj76UKMsoE6fX9/lGNdg/zitRBc
|
|
||||||
M21R9HeWuQHSM6nJ/ScK7C0vqQVsGOr/DKGEydvSjkPsyIbCw8qEdOq8idAULEKj
|
|
||||||
GlIpzzm+MYzra4yB4VpRw5ES
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
Binary file not shown.
@@ -1,30 +0,0 @@
|
|||||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
|
||||||
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIY7PpABd5xsYCAggA
|
|
||||||
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECC8FH8kZE5H/BIIEyK9LnEmc3VYK
|
|
||||||
kqwBBX15exPIRrsmeGkoSSrnHUeLzV0E2CN9bEL1XwJtX6d4YGYHnH7MopV9LPgl
|
|
||||||
Fdu2CvWXt5XLOMb3FJ38zZGtNnbYWZLbVlgQANZaTRCZaoWHS57KulgbtbJnn3PQ
|
|
||||||
DdYHaCiRh95pgPrdklEs0PhvBe98kR4xGJPoiGn+gJ75Ik4kwW/vJTcQeKbcU4oQ
|
|
||||||
MGIVXV66NU+Pc1d3CTYm9hwIys70+J9QtT1aSoENeYr1e+sHgzN7ykDalfAir/dZ
|
|
||||||
/E91Zg4RFV4clvvVmoAyXmZFpMxj5pLYGvdjBxTURh+8mdulfJMpKHjJldx7N9+I
|
|
||||||
cusGwKVXQcIXI76lxvKo08oENq0C6112+++s6bYtwzuk/Auk+dQ2mn2/gLgs6fsy
|
|
||||||
pi1ZKUoO8pdm8N4QzqPsFc2/ny5oSy6A6EKDC/tKoP59r6qJtoYselfypFsWemIo
|
|
||||||
F/W0HmZzC5OJMEqUxbKIuH7Xhx0ufs4TytzYMEnUVH0ChLan67VvFIcq4sLoMaW0
|
|
||||||
d2jyDdIe4WcmVckJtjudbIhcRsXtoSVB8PYjdHOmI9YZVksPreeKk7stf06V3PBU
|
|
||||||
/hsBpzlWu8xO6+cMGrlvoqOov3WAmD1/LW/ITggjLb28r7LnUrYTbj95xZ8Zd8s9
|
|
||||||
hx60MZpTJKni/Kfd5yVZw7xZWLHxNWdBbZxlCkvvFN5Ik0FjULLblfIfYa38zwp1
|
|
||||||
P6Dbw0wBSNhpsdsGcnkB+YWlzyIJzC99EZqgC3cGmb+9UGuj2bmvzx0hlIY4APCf
|
|
||||||
lfiFNXUHxxRZCV/Cp3TXqh3h7t99KvVoIzEIV8iUDMLG7dsnf2Y1z7AQ3cfL8tmC
|
|
||||||
qTlKH8QdMn87ntjcU1fynE3X/bL4+Fy8ZWeCWHHPLU2TP6Z7xBkXVB77gm0rK2cU
|
|
||||||
lJVZKB3kVemSvu9OennBAiE7yjusqCLyTJo9GlI3H7xM+jHf0CZM149n2yV7w98Z
|
|
||||||
Nag2b4iYnbVa1CRcL+4Y5zfA6AwCXvkqKcqyUqK4ZEvd1VnN9L+pTWrxaAxukC5f
|
|
||||||
KyKXKd+HdiS2b8fFVYKmpq+lK02zxuIJpLh7JlcztNinm67irwg+7VZczpX46Za1
|
|
||||||
waPuAnJ6zA6pVdRKxpXx5AnAh9vlCtlyakREx6NajG7f2nCe6IrznyVQ45jlkmwp
|
|
||||||
od0kAjsd/xp0NyvWI5A9ICU+pJ5xqhUGkXPvIxj1IqTFa7k4lYKiKgqeKoyLnzYA
|
|
||||||
+R1iQikwewxEahamhjiBH2xPYmZ77EjIF3EtLbpI02fxHR8LjyIBJ/HNnarKqJp0
|
|
||||||
HYhLJQ8z7uyAESfXY997UnTtgLQHEX5/6DKYqlNWdzRiIEGfleujHmaAb9kf9Xrr
|
|
||||||
r2EVc0E4q2/wvgMHn8GRSv6K7pQC//vNmBuNGCAMBl8t6y1QxDrX+UBn97HGk96Z
|
|
||||||
LqRoVM2mz1cS/tiP4+MSB0zqzGbHsk9xoEY0QeRPvjJfGc1skRWwdo8LA8Hf1pi1
|
|
||||||
/exyJzHNdxVdxM4CKMnXbTNCxKlhhZhUaWzELNjI5bQ5oQfechEypsFYAQETU5NS
|
|
||||||
182MgLMhkxqqcxLHcHIGE1ApZKXhY5siO0k4TTb2Kqxgn2fBUyLQLMVaVrHhZwxg
|
|
||||||
XwiQ2Rt3JBHrzPy9wXL8hw==
|
|
||||||
-----END ENCRYPTED PRIVATE KEY-----
|
|
||||||
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
passme
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDvTCCAqWgAwIBAgIUazbrVgbYb+IN803UmJJa0DPHQsAwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD0ludGVybWVkaWF0
|
|
||||||
ZSBDQTAeFw0xODAxMDEwMDAwMDBaFw0zNDEyMzEwMDAwMDBaMG0xCzAJBgNVBAYT
|
|
||||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNVBAsMA0NTUDEQMA4GA1UE
|
|
||||||
AwwHUmV2b2tlZDEnMCUGCSqGSIb3DQEJARYYb3NzbHNpZ25jb2RlQGV4YW1wbGUu
|
|
||||||
Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx0EJrK233GytTHTY
|
|
||||||
V6Sr4iuxHZwLWkv00A03dNsG/xEq3Uh58yHxOMDW49o5hm/PejaaX2ooaYn67EeT
|
|
||||||
MuiMpuD3xtybEGuRZ6YtDCZG/WFkg7wPjGJhF3Q7QpmLOu/BbCU0APNddbDuLP4w
|
|
||||||
89aRePadPkyk5OLdLznVLA5z9z1JgJrMI/yswYi0ocs7uIKMrewXAEMj15pN3Y0S
|
|
||||||
OoQdp0jKYdGLN5M5pi/fgWiRCJGBH/OTh+VPr5voNAfGeVsiK9XrU4/hsGUW1deM
|
|
||||||
LiIZ0cshqGFUyXDqLEapHr3XSmwinRJPQozyXL437Ws+Gg2Q1IuqTMZS50qjuZW3
|
|
||||||
4KngQwIDAQABo2IwYDAJBgNVHRMEAjAAMB0GA1UdDgQWBBTprhNre3RQJMbThsJY
|
|
||||||
wKi0w8vJZTAfBgNVHSMEGDAWgBRkEPGrOTfcwf27Hcg/QVh3YifvKTATBgNVHSUE
|
|
||||||
DDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQsFAAOCAQEAFJjwxpYA2jzrmF1mdKx/
|
|
||||||
up8gl6iISsHDc7oLAv63oUYXpFwzpNfvi1TGqYVhntAH2t/1XdA1HKdBp2LDsEnt
|
|
||||||
Av66c6HxyNPka26ZGD70+w5q8uHrIOO6MZw0eaLwu9bJI4cLbRXlKwxkGSzXHGYs
|
|
||||||
1hGR2YwAiMrqtVMPetlpd62y6qUZc0lEOhjJ6DsIfqSgO8AsdyI7Ao+cDqEZ1I/Q
|
|
||||||
Oi1Agn8kz8TtfWKxkX06EoL4DrZCDb1/w0CGQJATq77pKst+zw+B+2EKqlpuG3s/
|
|
||||||
FE7RkCjG7bEFIDEK2909BXQNyQJzp7ih9X8QeEx5fnPr9lDfe/75YjRqoHkfmcTC
|
|
||||||
Hw==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
|
||||||
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
|
||||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
|
||||||
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
|
|
||||||
AAOCAQ8AMIIBCgKCAQEA5yrw3i+fvxBSODvCoQb+9ibWRozmphJBp57tKv9ZraQ5
|
|
||||||
THK+PkCdjNiJuxZn8F1QLsjJo6JqrrXufYln7wixK0Seu4uV6I2TRzcRyJx29D89
|
|
||||||
0G9GrTXKn7v8z32QAqCgtwSZ17uWYTFmRAYPllWXcWDONsVyw3UF2nClndL7GMqM
|
|
||||||
gDizlwsfg8HmRpZegn82I7Y2DXccm9a7pFHuBHpwenKqfBnMsXo3Jj4Xlr1cLTrh
|
|
||||||
+6ksS5YogOsOd9b5Dfz6FaGmmwrlUWHwdi+EzdnSpOnXzmgflF23sZQ0ynsVvmpl
|
|
||||||
iD4rXBWnxnQ6Ken3wVPNrA/0ZYGbgSKrcv+/olkh5QIDAQABo2YwZDASBgNVHRMB
|
|
||||||
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRkEPGrOTfcwf27Hcg/QVh3YifvKTAfBgNV
|
|
||||||
HSMEGDAWgBQaPEb++qXSgmAi2vsewtpb6SiIyDAOBgNVHQ8BAf8EBAMCAYYwDQYJ
|
|
||||||
KoZIhvcNAQELBQADggEBAL22kK3SDGnr3lhRE7ipptlKalrQKfpght0XEKm5hxCL
|
|
||||||
tougN2wtaTEWMwr2YfGJohcKBaGKQ+Bv6WY+EV+hJE4qEUFh6BGqRMtuZdiAbkG+
|
|
||||||
EveEMhZWQzgf9rUID+Y9Eg+NfCxlpkdQPjUxUV9OkGIshlxkUP8Y+C0h0xIcwq5v
|
|
||||||
hAfNiJAdcw4fUvtLkpEOFoOjThB8zxOu+Cl3xLCcNOMPLdSxd3YXjy6CMuuOk4RB
|
|
||||||
gOc8YCyyEvwb9KmARZpMOcQJmucMhs+aC3DF+n71g+agFhDl3Z0QkyyyRjAcD04+
|
|
||||||
sAR9C8PbqSCQAdydHbAFViEX6x3oGJ7L6zEDcIS10wg=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIEDDCCAvSgAwIBAgIUHGb2CHtm9Ra3gCn6Iv7hpEhiQrYwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwZzELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNVBAMMFkludGVybWVkaWF0
|
|
||||||
ZSBDQSBDUkwgRFAwHhcNMTgwMTAxMDAwMDAwWhcNMzQxMjMxMDAwMDAwWjB7MQsw
|
|
||||||
CQYDVQQGEwJQTDEVMBMGA1UECgwMb3NzbHNpZ25jb2RlMQwwCgYDVQQLDANDU1Ax
|
|
||||||
HjAcBgNVBAMMFVJldm9rZWQgWDUwOXYzIENSTCBEUDEnMCUGCSqGSIb3DQEJARYY
|
|
||||||
b3NzbHNpZ25jb2RlQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
|
||||||
MIIBCgKCAQEAx0EJrK233GytTHTYV6Sr4iuxHZwLWkv00A03dNsG/xEq3Uh58yHx
|
|
||||||
OMDW49o5hm/PejaaX2ooaYn67EeTMuiMpuD3xtybEGuRZ6YtDCZG/WFkg7wPjGJh
|
|
||||||
F3Q7QpmLOu/BbCU0APNddbDuLP4w89aRePadPkyk5OLdLznVLA5z9z1JgJrMI/ys
|
|
||||||
wYi0ocs7uIKMrewXAEMj15pN3Y0SOoQdp0jKYdGLN5M5pi/fgWiRCJGBH/OTh+VP
|
|
||||||
r5voNAfGeVsiK9XrU4/hsGUW1deMLiIZ0cshqGFUyXDqLEapHr3XSmwinRJPQozy
|
|
||||||
XL437Ws+Gg2Q1IuqTMZS50qjuZW34KngQwIDAQABo4GbMIGYMAkGA1UdEwQCMAAw
|
|
||||||
HQYDVR0OBBYEFOmuE2t7dFAkxtOGwljAqLTDy8llMB8GA1UdIwQYMBaAFBQ8Yqni
|
|
||||||
cYiW5meHqyh9KQSIau0jMBMGA1UdJQQMMAoGCCsGAQUFBwMDMDYGA1UdHwQvMC0w
|
|
||||||
K6ApoCeGJWh0dHA6Ly8xMjcuMC4wLjE6MTkyNTQvaW50ZXJtZWRpYXRlQ0EwDQYJ
|
|
||||||
KoZIhvcNAQELBQADggEBAJ5WxnDiAiRPr7EvTRD7iaxixAY/2wgASXWekQLpvJ8Y
|
|
||||||
/ehaVdZWE8ft76y73F4NC62JfjWgAZHE+we3LSO+eB5kznM+Ctzrf/brR1MorSOu
|
|
||||||
iq78uz2pjwmQBpby6uDMii9r1txR62GYiLrZJizE+13AOVKBo5EW0PuwX3wKjk+s
|
|
||||||
Z5Mp9y7+GVzCSXwJC4wNMw/ZJZgr+o5D8msMh3UPgxUfT1rZ7THW3IwXao3ZtTXw
|
|
||||||
EA6uJoLVNb8FLfAVA1CFL0MlPgyiM2iNs+jIuhF7hPmMc8Je2qAr97ADdLCHWnRv
|
|
||||||
Majsbns7OCCFROF2qSQiyzVO5Hn1kiPSP7qmLMak610=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDszCCApugAwIBAgIUN3RBnJCUJ8HmbeNjJZ/6jsXJLGEwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
|
||||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
|
||||||
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBnMQswCQYDVQQGEwJQTDEVMBMG
|
|
||||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
|
||||||
cml0eTEfMB0GA1UEAwwWSW50ZXJtZWRpYXRlIENBIENSTCBEUDCCASIwDQYJKoZI
|
|
||||||
hvcNAQEBBQADggEPADCCAQoCggEBAME32IBpxW4FhVuZe1PTarEskVHP233QjZtx
|
|
||||||
poC67/lUK44gtFmsxYsMrDYmmny5pfoM/Byxl5/rorEddLqtDe1kd1SpXUvEYxox
|
|
||||||
s5rizRd5sZPgkwNoJkSVyNZFwj7gKZHeg6IQHSxNgmTybZ+eZqiNvEveksj3lGpM
|
|
||||||
Xrbiew7cXUyIP636GPtYxLyIbwDVP0jScqcA/dmSAqofFVUi0SW3OS1hpyXAmmx8
|
|
||||||
hQHJRKPjPgitZVgjwf5X8/eMTa+ca9dRlRFLk7AcbkF6NcbLm+cRo816nO0EBFV4
|
|
||||||
Sn2dW9uYqJIfZcpRQ7wbv4fUCghwrk9h3gXrb7AweyK8nyYlmosCAwEAAaNmMGQw
|
|
||||||
EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUFDxiqeJxiJbmZ4erKH0pBIhq
|
|
||||||
7SMwHwYDVR0jBBgwFoAUGjxG/vql0oJgItr7HsLaW+koiMgwDgYDVR0PAQH/BAQD
|
|
||||||
AgGGMA0GCSqGSIb3DQEBCwUAA4IBAQAlI/1XnGc9WzL53rRascZc1EgWAnej9YFS
|
|
||||||
Dax5+nozYTihC8BRxGfSh1FGRVsmFWhZ0z0XogJJC2bZrQ/36+vwoILItcsWHrQr
|
|
||||||
rFoZa6s1Uo7ZCd9SfmXjbhMLQgydocCh9YIF66CAkQLwRXc1QIpF7nuZ+rxk0ru1
|
|
||||||
uGjjBrFRfdSdzlFnyK6wfFzi6LtYDVgVEHC7zzL9E/cyuGo7qQ++SoOg99HjTVY1
|
|
||||||
PS3ea522bRO2bJpYwZJvvbg020DAfm686VXwAadODdBkI2h6U5SwTxp4SkSmq9SI
|
|
||||||
mjtERFtnAKD0R2YrX4RzuIckezvwsqLDkQjMnI9XQmv5HWUZimcC
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIEMzCCAxugAwIBAgIUAQ9lOMiuXUZuKaxzEpwQmCzU7aowDQYJKoZIhvcNAQEL
|
|
||||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
|
|
||||||
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
|
|
||||||
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0zODAxMDEwMDAwMDBaMFUxCzAJBgNVBAYT
|
|
||||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxHDAaBgNVBAsME1RpbWVzdGFtcCBB
|
|
||||||
dXRob3JpdHkxETAPBgNVBAMMCFRlc3QgVFNBMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
|
||||||
AQ8AMIIBCgKCAQEAqZW3jbxq2Zkw86ePE8r6Tl9+mxjzH8k1XPGXwKIdEhvOhBXN
|
|
||||||
SxwVdiudnbIR2Kp4kOpRNeI4bET6bGEQVBVzuyPOCXeQlXK7wVhri/MF8YzMCFuW
|
|
||||||
7s2OMeaCqMJckBiGrDYgvDIMfE53CZFVhOnpIKD+ItX+D1bBchvM1TaSOVcxwKwH
|
|
||||||
pmIbw47gOY4E4rHz/KYdqcVCk82ACEmiptmJARb8oYU8bap1x7fEtDZ3w0gnnSks
|
|
||||||
5dXGjdUwCkm1qHgoW/k6vK8nIz14f/+05GIMZpUh4kIUXMhGmbOeFHfENJ7J30TI
|
|
||||||
RLXsK9iAApriqxZ6EvhrWOYJT4pUeUnGfuwPUwIDAQABo4HvMIHsMAwGA1UdEwEB
|
|
||||||
/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwHQYDVR0OBBYEFKryJiH4Y0KO
|
|
||||||
x2nCc4cOvih1VzjmMB8GA1UdIwQYMBaAFD8ujz0I9Y7079ZMe9X7cO3/rSj5MC0G
|
|
||||||
A1UdHwQmMCQwIqAgoB6GHGh0dHA6Ly8xMjcuMC4wLjE6MTkyNTQvVFNBQ0EwVQYD
|
|
||||||
VR0eBE4wTKAYMAqCCHRlc3QuY29tMAqCCHRlc3Qub3JnoTAwCocIAAAAAAAAAAAw
|
|
||||||
IocgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwDQYJKoZIhvcNAQEL
|
|
||||||
BQADggEBAAhzijhC1kvBV75rxRqj27gtYRG8dNkHc5umzwXyNNMn2tI/kO2Rf+ES
|
|
||||||
9RamQE9sfvOgg3UqfXIfRPsC4cBHnjT+ELdqbt4byk3LPtstJGFuLy0iNRNY9f1j
|
|
||||||
lBJrldLZNNsIpNMQa0u5h/z4m0CAA8j6ayUvcoR11y2zYHkHlSScTq/s7gSQzXlK
|
|
||||||
z4DRiiYif2OEdKVeRCqlDV8AOlhm1+9am74dkfO71aT0G2hko2u19NWZvjc/DqI1
|
|
||||||
V+e2g5TDE7V65d9vvf9tA26i0At/VazvnhsgdpgUkwS6mjUvx+gW3i5YJhtXjdAX
|
|
||||||
hpE0ajpKT0x/dNa/qCwl/9zc8XxGnPk=
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDkDCCAnigAwIBAgIULFuB5HWsyba6VHu2Ygv2vt4R4/swDQYJKoZIhvcNAQEL
|
|
||||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
|
|
||||||
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
|
|
||||||
dCBDQTAeFw0xNzAxMDEwMDAwMDBaFw0zNjEyMjcwMDAwMDBaMGAxCzAJBgNVBAYT
|
|
||||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxJDAiBgNVBAsMG1RpbWVzdGFtcCBB
|
|
||||||
dXRob3JpdHkgUm9vdCBDQTEUMBIGA1UEAwwLVFNBIFJvb3QgQ0EwggEiMA0GCSqG
|
|
||||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBo8JJDwVm6UTZvA2g/tOZ3xIbKYXI92Rn
|
|
||||||
T/FCCUycsB5tmoSWcmy1AB6UDv7bFMGy4mdbxnErtdytGj+hEIO3O2EBbpBLAmlJ
|
|
||||||
CEVNRrz/YbxGoJmeAii9s3jignUpTr/qLMSKkLowuqABZl2XtCp7Q83YlZPkVhFL
|
|
||||||
kCAny89cG/QGAUxViN7HB4jWzhcBTTfD4PFvSU1HZNhPM0Y6BCpv2qrof3/tPnQr
|
|
||||||
xM2zVZoIonQpf6paga61O9fM4wc1GqxGGwARz6Bxq6w2OxRDsV/biqP9gVUj0XmF
|
|
||||||
6o/draf3MkDswOUZyKpujOUIf12ezXJFPWaCRN1Rl0vwV2CyVxkvAgMBAAGjQjBA
|
|
||||||
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFD8ujz0I9Y7079ZMe9X7cO3/rSj5
|
|
||||||
MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAtHmPfVgu6Y7uWcpq
|
|
||||||
AdawOTZ/2ICOvAMmQ0LcXKmSpgsneHiyAL1Wwe2/XxTwmrpHylOapIIuV3irHCXU
|
|
||||||
CxaTMUyZGfXoUWsxnR8bcb5ac/aFKkC3ynE2/IfFyJOQ724cK5FRK1+piVleP4Rx
|
|
||||||
C04KQiuxuVLedyvGh5OPU/94ZW2JuuBjImVAO/lUbYhAUSpwueX2lYKSSPLkPfDx
|
|
||||||
AsIp55x70iQ+EsgARvseVY2JRzvRnuh66V4P15wn3dIzjtWQ1/t007wMk5Lji5dQ
|
|
||||||
iSvdyqULBytBqDtLPLzRuma1KJEPRIamF1j6Or6HaHSVUorRhqI3XuxEUGdO4LxZ
|
|
||||||
QepMyA==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
bb7fd13ddf056e0a3e621d3537b25478
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""Check cryptography module."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
try:
|
||||||
|
import cryptography
|
||||||
|
print(cryptography.__version__, end="")
|
||||||
|
except ModuleNotFoundError as ierr:
|
||||||
|
print("Module not installed: {}".format(ierr))
|
||||||
|
sys.exit(1)
|
||||||
|
except ImportError as ierr:
|
||||||
|
print("Module not found: {}".format(ierr))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
class UnsupportedVersion(Exception):
|
||||||
|
"""Unsupported version"""
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
"""Check python3-cryptography version"""
|
||||||
|
try:
|
||||||
|
version = tuple(int(num) for num in cryptography.__version__.split('.'))
|
||||||
|
if version < (37, 0, 2):
|
||||||
|
raise UnsupportedVersion("unsupported python3-cryptography version")
|
||||||
|
except UnsupportedVersion as err:
|
||||||
|
print(" {}".format(err), end="")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
|
# pylint: disable=pointless-string-statement
|
||||||
|
"""Local Variables:
|
||||||
|
c-basic-offset: 4
|
||||||
|
tab-width: 4
|
||||||
|
indent-tabs-mode: nil
|
||||||
|
End:
|
||||||
|
vim: set ts=4 expandtab:
|
||||||
|
"""
|
||||||
@@ -1,21 +1,22 @@
|
|||||||
"""Implementation of a HTTP client"""
|
#!/usr/bin/python3
|
||||||
|
"""Implementation of an HTTP client"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import http.client
|
import http.client
|
||||||
|
|
||||||
RESULT_PATH = os.getcwd()
|
RESULT_PATH = os.getcwd()
|
||||||
LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/")
|
|
||||||
PORT_LOG = os.path.join(LOGS_PATH, "./port.log")
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
"""Creating a POST Request"""
|
"""Creating a POST Request"""
|
||||||
ret = 0
|
ret = 0
|
||||||
try:
|
try:
|
||||||
with open(PORT_LOG, 'r') as file:
|
file_path = os.path.join(RESULT_PATH, "./Testing/logs/url.log")
|
||||||
port = file.readline()
|
with open(file_path, mode="r", encoding="utf-8") as file:
|
||||||
conn = http.client.HTTPConnection('127.0.0.1', port)
|
url = file.readline()
|
||||||
|
host, port = url.split(":")
|
||||||
|
conn = http.client.HTTPConnection(host, port)
|
||||||
conn.request('POST', '/kill_server')
|
conn.request('POST', '/kill_server')
|
||||||
response = conn.getresponse()
|
response = conn.getresponse()
|
||||||
print("HTTP status code:", response.getcode(), end=', ')
|
print("HTTP status code:", response.getcode(), end=', ')
|
||||||
|
|||||||
@@ -1,448 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
result=0
|
|
||||||
|
|
||||||
test_result() {
|
|
||||||
if test "$1" -eq 0
|
|
||||||
then
|
|
||||||
printf "Succeeded\n" >> "makecerts.log"
|
|
||||||
else
|
|
||||||
printf "Failed\n" >> "makecerts.log"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
make_certs() {
|
|
||||||
password=passme
|
|
||||||
result_path=$(pwd)
|
|
||||||
cd $(dirname "$0")
|
|
||||||
script_path=$(pwd)
|
|
||||||
cd "${result_path}"
|
|
||||||
mkdir "tmp/"
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# OpenSSL settings
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
if test -n "$1"
|
|
||||||
then
|
|
||||||
OPENSSL="$1/bin/openssl"
|
|
||||||
export LD_LIBRARY_PATH="$1/lib:$1/lib64"
|
|
||||||
else
|
|
||||||
OPENSSL=openssl
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir "CA/" 2>> "makecerts.log" 1>&2
|
|
||||||
touch "CA/index.txt"
|
|
||||||
echo -n "unique_subject = no" > "CA/index.txt.attr"
|
|
||||||
$OPENSSL rand -hex 16 > "CA/serial"
|
|
||||||
$OPENSSL rand -hex 16 > "tmp/tsa-serial"
|
|
||||||
echo 1001 > "CA/crlnumber"
|
|
||||||
date > "makecerts.log"
|
|
||||||
"$OPENSSL" version 2>> "makecerts.log" 1>&2
|
|
||||||
echo -n "$password" > tmp/password.txt
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Root CA certificates
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
printf "\nGenerate trusted root CA certificate\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" genrsa -out CA/CAroot.key \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_root.cnf"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -x509 -days 7300 -key CA/CAroot.key -out tmp/CAroot.pem \
|
|
||||||
-subj "/C=PL/O=osslsigncode/OU=Certification Authority/CN=Trusted Root CA" \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nPrepare the Certificate Signing Request (CSR)\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" genrsa -out CA/CA.key \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_root.cnf"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -key CA/CA.key -out CA/CACert.csr \
|
|
||||||
-subj "/C=PL/O=osslsigncode/OU=Certification Authority/CN=Root CA" \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate Self-signed root CA certificate\n" >> "makecerts.log"
|
|
||||||
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_root.cnf"
|
|
||||||
"$OPENSSL" x509 -req -days 7300 -extfile "$CONF" -extensions ca_extensions \
|
|
||||||
-signkey CA/CA.key \
|
|
||||||
-in CA/CACert.csr -out tmp/CACert.pem \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate Cross-signed root CA certificate\n" >> "makecerts.log"
|
|
||||||
TZ=GMT faketime -f '@2018-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_root.cnf"
|
|
||||||
"$OPENSSL" x509 -req -days 7300 -extfile "$CONF" -extensions ca_extensions \
|
|
||||||
-CA tmp/CAroot.pem -CAkey CA/CAroot.key -CAserial CA/CAroot.srl \
|
|
||||||
-CAcreateserial -in CA/CACert.csr -out tmp/CAcross.pem \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Private RSA keys
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
printf "\nGenerate private RSA encrypted key\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" genrsa -des3 -out CA/private.key -passout pass:"$password" \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
cat CA/private.key >> tmp/keyp.pem 2>> "makecerts.log"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate private RSA decrypted key\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" rsa -in CA/private.key -passin pass:"$password" -out tmp/key.pem \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nConvert the key to DER format\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" rsa -in tmp/key.pem -outform DER -out tmp/key.der -passout pass:"$password" \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nConvert the key to PVK format\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" rsa -in tmp/key.pem -outform PVK -out tmp/key.pvk -pvk-none \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Intermediate CA certificates
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
CONF="${script_path}/openssl_intermediate.cnf"
|
|
||||||
|
|
||||||
printf "\nGenerate intermediate CA certificate\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" genrsa -out CA/intermediateCA.key \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_intermediate.cnf"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -key CA/intermediateCA.key -out CA/intermediateCA.csr \
|
|
||||||
-subj "/C=PL/O=osslsigncode/OU=Certification Authority/CN=Intermediate CA" \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_root.cnf"
|
|
||||||
"$OPENSSL" ca -config "$CONF" -batch -in CA/intermediateCA.csr -out CA/intermediateCA.cer \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" x509 -in CA/intermediateCA.cer -out tmp/intermediateCA.pem \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate a certificate to revoke\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -key CA/private.key -passin pass:"$password" -out CA/revoked.csr \
|
|
||||||
-subj "/C=PL/O=osslsigncode/OU=CSP/CN=Revoked/emailAddress=osslsigncode@example.com" \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" ca -config "$CONF" -batch -in CA/revoked.csr -out CA/revoked.cer \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" x509 -in CA/revoked.cer -out tmp/revoked.pem \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nRevoke above certificate\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" ca -config "$CONF" -revoke CA/revoked.cer \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nAttach intermediate certificate to revoked certificate\n" >> "makecerts.log"
|
|
||||||
cat tmp/intermediateCA.pem >> tmp/revoked.pem 2>> "makecerts.log"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate CRL file\n" >> "makecerts.log"
|
|
||||||
TZ=GMT faketime -f '@2019-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_intermediate.cnf"
|
|
||||||
"$OPENSSL" ca -config "$CONF" -gencrl -crldays 8766 -out tmp/CACertCRL.pem \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate code signing certificate\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -key CA/private.key -passin pass:"$password" -out CA/cert.csr \
|
|
||||||
-subj "/C=PL/ST=Mazovia Province/L=Warsaw/O=osslsigncode/OU=CSP/CN=Certificate/emailAddress=osslsigncode@example.com" \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" ca -config "$CONF" -batch -in CA/cert.csr -out CA/cert.cer \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" x509 -in CA/cert.cer -out tmp/cert.pem \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nConvert the certificate to DER format\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" x509 -in tmp/cert.pem -outform DER -out tmp/cert.der \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nAttach intermediate certificate to code signing certificate\n" >> "makecerts.log"
|
|
||||||
cat tmp/intermediateCA.pem >> tmp/cert.pem 2>> "makecerts.log"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nConvert the certificate to SPC format\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" crl2pkcs7 -nocrl -certfile tmp/cert.pem -outform DER -out tmp/cert.spc \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
ssl_version=$("$OPENSSL" version)
|
|
||||||
if test "${ssl_version:8:1}" -eq 3
|
|
||||||
then
|
|
||||||
printf "\nConvert the certificate and the key into legacy PKCS#12 container with\
|
|
||||||
RC2-40-CBC private key and certificate encryption algorithm\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" pkcs12 -export -in tmp/cert.pem -inkey tmp/key.pem -out tmp/legacy.p12 -passout pass:"$password" \
|
|
||||||
-keypbe rc2-40-cbc -certpbe rc2-40-cbc -legacy \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
else
|
|
||||||
printf "\nConvert the certificate and the key into legacy PKCS#12 container with\
|
|
||||||
RC2-40-CBC private key and certificate encryption algorithm\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" pkcs12 -export -in tmp/cert.pem -inkey tmp/key.pem -out tmp/legacy.p12 -passout pass:"$password" \
|
|
||||||
-keypbe rc2-40-cbc -certpbe rc2-40-cbc \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
fi
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nConvert the certificate and the key into a PKCS#12 container with\
|
|
||||||
AES-256-CBC private key and certificate encryption algorithm\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" pkcs12 -export -in tmp/cert.pem -inkey tmp/key.pem -out tmp/cert.p12 -passout pass:"$password" \
|
|
||||||
-keypbe aes-256-cbc -certpbe aes-256-cbc \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate expired certificate\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -key CA/private.key -passin pass:"$password" -out CA/expired.csr \
|
|
||||||
-subj "/C=PL/ST=Mazovia Province/L=Warsaw/O=osslsigncode/OU=CSP/CN=Expired/emailAddress=osslsigncode@example.com" \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" ca -config "$CONF" -enddate "190101000000Z" -batch -in CA/expired.csr -out CA/expired.cer \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" x509 -in CA/expired.cer -out tmp/expired.pem \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nAttach intermediate certificate to expired certificate\n" >> "makecerts.log"
|
|
||||||
cat tmp/intermediateCA.pem >> tmp/expired.pem 2>> "makecerts.log"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Intermediate CA certificates with CRL distribution point
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
CONF="${script_path}/openssl_intermediate_crldp.cnf"
|
|
||||||
|
|
||||||
printf "\nGenerate intermediate CA certificate with CRL distribution point\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" genrsa -out CA/intermediateCA_crldp.key \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_intermediate_crldp.cnf"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -key CA/intermediateCA_crldp.key -out CA/intermediateCA_crldp.csr \
|
|
||||||
-subj "/C=PL/O=osslsigncode/OU=Certification Authority/CN=Intermediate CA CRL DP" \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_root.cnf"
|
|
||||||
"$OPENSSL" ca -config "$CONF" -batch -in CA/intermediateCA_crldp.csr -out CA/intermediateCA_crldp.cer \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" x509 -in CA/intermediateCA_crldp.cer -out tmp/intermediateCA_crldp.pem \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate a certificate with X509v3 CRL Distribution Points extension to revoke\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -key CA/private.key -passin pass:"$password" -out CA/revoked_crldp.csr \
|
|
||||||
-subj "/C=PL/O=osslsigncode/OU=CSP/CN=Revoked X509v3 CRL DP/emailAddress=osslsigncode@example.com" \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" ca -config "$CONF" -batch -in CA/revoked_crldp.csr -out CA/revoked_crldp.cer \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" x509 -in CA/revoked_crldp.cer -out tmp/revoked_crldp.pem \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nRevoke above certificate\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" ca -config "$CONF" -revoke CA/revoked_crldp.cer \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nAttach intermediate certificate to revoked certificate\n" >> "makecerts.log"
|
|
||||||
cat tmp/intermediateCA_crldp.pem >> tmp/revoked_crldp.pem 2>> "makecerts.log"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate CRL file\n" >> "makecerts.log"
|
|
||||||
TZ=GMT faketime -f '@2019-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_intermediate_crldp.cnf"
|
|
||||||
"$OPENSSL" ca -config "$CONF" -gencrl -crldays 8766 -out tmp/CACertCRL_crldp.pem \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nConvert CRL file from PEM to DER (for CRL Distribution Points server to use) \n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" crl -in tmp/CACertCRL_crldp.pem -inform PEM -out tmp/CACertCRL.der -outform DER \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate code signing certificate with X509v3 CRL Distribution Points extension\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -key CA/private.key -passin pass:"$password" -out CA/cert_crldp.csr \
|
|
||||||
-subj "/C=PL/ST=Mazovia Province/L=Warsaw/O=osslsigncode/OU=CSP/CN=Certificate X509v3 CRL DP/emailAddress=osslsigncode@example.com" \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" ca -config "$CONF" -batch -in CA/cert_crldp.csr -out CA/cert_crldp.cer \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" x509 -in CA/cert_crldp.cer -out tmp/cert_crldp.pem \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nAttach intermediate certificate to code signing certificate\n" >> "makecerts.log"
|
|
||||||
cat tmp/intermediateCA_crldp.pem >> tmp/cert_crldp.pem 2>> "makecerts.log"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Time Stamp Authority certificates
|
|
||||||
################################################################################
|
|
||||||
printf "\nGenerate Root CA TSA certificate\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" genrsa -out CA/TSACA.key \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
TZ=GMT faketime -f '@2017-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_tsa_root.cnf"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -x509 -days 7300 -key CA/TSACA.key -out tmp/TSACA.pem \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate TSA certificate to revoke\n" >> "makecerts.log"
|
|
||||||
CONF="${script_path}/openssl_tsa_root.cnf"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -nodes -keyout tmp/TSA_revoked.key -out CA/TSA_revoked.csr \
|
|
||||||
-subj "/C=PL/O=osslsigncode/OU=TSA/CN=Revoked/emailAddress=osslsigncode@example.com" \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
CONF="${script_path}/openssl_tsa_root.cnf"
|
|
||||||
"$OPENSSL" ca -config "$CONF" -batch -in CA/TSA_revoked.csr -out CA/TSA_revoked.cer \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" x509 -in CA/TSA_revoked.cer -out tmp/TSA_revoked.pem \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nRevoke above certificate\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" ca -config "$CONF" -revoke CA/TSA_revoked.cer \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate TSA CRL file\n" >> "makecerts.log"
|
|
||||||
TZ=GMT faketime -f '@2019-01-01 00:00:00' /bin/bash -c '
|
|
||||||
script_path=$(pwd)
|
|
||||||
OPENSSL="$0"
|
|
||||||
export LD_LIBRARY_PATH="$1"
|
|
||||||
CONF="${script_path}/openssl_tsa_root.cnf"
|
|
||||||
"$OPENSSL" ca -config "$CONF" -gencrl -crldays 8766 -out tmp/TSACertCRL.pem \
|
|
||||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nConvert TSA CRL file from PEM to DER (for CRL Distribution Points server to use)\n" >> "makecerts.log"
|
|
||||||
"$OPENSSL" crl -in tmp/TSACertCRL.pem -inform PEM -out tmp/TSACertCRL.der -outform DER \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nGenerate TSA certificate\n" >> "makecerts.log"
|
|
||||||
CONF="${script_path}/openssl_tsa.cnf"
|
|
||||||
"$OPENSSL" req -config "$CONF" -new -nodes -keyout tmp/TSA.key -out CA/TSA.csr \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
CONF="${script_path}/openssl_tsa_root.cnf"
|
|
||||||
"$OPENSSL" ca -config "$CONF" -batch -in CA/TSA.csr -out CA/TSA.cer \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
"$OPENSSL" x509 -in CA/TSA.cer -out tmp/TSA.pem \
|
|
||||||
2>> "makecerts.log" 1>&2
|
|
||||||
test_result $?
|
|
||||||
|
|
||||||
printf "\nSave the chain to be included in the TSA response\n" >> "makecerts.log"
|
|
||||||
cat tmp/TSA.pem tmp/TSACA.pem > tmp/tsa-chain.pem 2>> "makecerts.log"
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Copy new files
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
if test -s tmp/CACert.pem -a -s tmp/CAcross.pem -a -s tmp/CAroot.pem \
|
|
||||||
-a -s tmp/intermediateCA.pem -a -s tmp/intermediateCA_crldp.pem \
|
|
||||||
-a -s tmp/CACertCRL.pem -a -s tmp/CACertCRL.der \
|
|
||||||
-a -s tmp/TSACertCRL.pem -a -s tmp/TSACertCRL.der \
|
|
||||||
-a -s tmp/key.pem -a -s tmp/keyp.pem -a -s tmp/key.der -a -s tmp/key.pvk \
|
|
||||||
-a -s tmp/cert.pem -a -s tmp/cert.der -a -s tmp/cert.spc \
|
|
||||||
-a -s tmp/cert.p12 -a -s tmp/legacy.p12 -a -s tmp/cert_crldp.pem\
|
|
||||||
-a -s tmp/expired.pem \
|
|
||||||
-a -s tmp/revoked.pem -a -s tmp/revoked_crldp.pem \
|
|
||||||
-a -s tmp/TSA_revoked.pem \
|
|
||||||
-a -s tmp/TSA.pem -a -s tmp/TSA.key -a -s tmp/tsa-chain.pem
|
|
||||||
then
|
|
||||||
mkdir -p "../certs"
|
|
||||||
cp tmp/* ../certs
|
|
||||||
printf "%s" "Keys & certificates successfully generated"
|
|
||||||
else
|
|
||||||
printf "%s" "Error logs ${result_path}/makecerts.log"
|
|
||||||
result=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Remove the working directory
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
rm -rf "CA/"
|
|
||||||
rm -rf "tmp/"
|
|
||||||
|
|
||||||
exit "$result"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Tests requirement and make certs
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
if test -n "$(command -v faketime)"
|
|
||||||
then
|
|
||||||
make_certs "$1"
|
|
||||||
result=$?
|
|
||||||
else
|
|
||||||
printf "%s" "faketime not found in \$PATH, please install faketime package"
|
|
||||||
result=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit "$result"
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
# OpenSSL intermediate CA configuration file
|
|
||||||
|
|
||||||
[ default ]
|
|
||||||
name = intermediateCA
|
|
||||||
default_ca = CA_default
|
|
||||||
|
|
||||||
[ CA_default ]
|
|
||||||
# Directory and file locations
|
|
||||||
dir = .
|
|
||||||
certs = $dir/CA
|
|
||||||
crl_dir = $dir/CA
|
|
||||||
new_certs_dir = $dir/CA
|
|
||||||
database = $dir/CA/index.txt
|
|
||||||
serial = $dir/CA/serial
|
|
||||||
rand_serial = yes
|
|
||||||
private_key = $dir/CA/$name.key
|
|
||||||
certificate = $dir/tmp/$name.pem
|
|
||||||
crlnumber = $dir/CA/crlnumber
|
|
||||||
crl_extensions = crl_ext
|
|
||||||
default_md = sha256
|
|
||||||
preserve = no
|
|
||||||
policy = policy_loose
|
|
||||||
default_startdate = 20180101000000Z
|
|
||||||
default_enddate = 20341231000000Z
|
|
||||||
x509_extensions = v3_req
|
|
||||||
email_in_dn = yes
|
|
||||||
default_days = 2200
|
|
||||||
|
|
||||||
[ req ]
|
|
||||||
# Options for the `req` tool
|
|
||||||
encrypt_key = no
|
|
||||||
default_bits = 2048
|
|
||||||
default_md = sha256
|
|
||||||
string_mask = utf8only
|
|
||||||
distinguished_name = req_distinguished_name
|
|
||||||
x509_extensions = usr_extensions
|
|
||||||
|
|
||||||
[ crl_ext ]
|
|
||||||
# Extension for CRLs
|
|
||||||
authorityKeyIdentifier = keyid:always
|
|
||||||
|
|
||||||
[ usr_extensions ]
|
|
||||||
# Extension to add when the -x509 option is used
|
|
||||||
basicConstraints = CA:FALSE
|
|
||||||
subjectKeyIdentifier = hash
|
|
||||||
authorityKeyIdentifier = keyid, issuer
|
|
||||||
extendedKeyUsage = codeSigning
|
|
||||||
|
|
||||||
[ v3_req ]
|
|
||||||
basicConstraints = CA:FALSE
|
|
||||||
subjectKeyIdentifier = hash
|
|
||||||
authorityKeyIdentifier = keyid, issuer
|
|
||||||
extendedKeyUsage = codeSigning
|
|
||||||
|
|
||||||
[ policy_loose ]
|
|
||||||
# Allow the intermediate CA to sign a more diverse range of certificates.
|
|
||||||
# See the POLICY FORMAT section of the `ca` man page.
|
|
||||||
countryName = optional
|
|
||||||
stateOrProvinceName = optional
|
|
||||||
localityName = optional
|
|
||||||
organizationName = optional
|
|
||||||
organizationalUnitName = optional
|
|
||||||
commonName = supplied
|
|
||||||
emailAddress = optional
|
|
||||||
|
|
||||||
[ req_distinguished_name ]
|
|
||||||
countryName = Country Name (2 letter code)
|
|
||||||
stateOrProvinceName = State or Province Name
|
|
||||||
localityName = Locality Name
|
|
||||||
0.organizationName = Organization Name
|
|
||||||
organizationalUnitName = Organizational Unit Name
|
|
||||||
commonName = Common Name
|
|
||||||
emailAddress = Email Address
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
# OpenSSL intermediate CA configuration file
|
|
||||||
|
|
||||||
[ default ]
|
|
||||||
name = intermediateCA
|
|
||||||
default_ca = CA_default
|
|
||||||
crl_url = http://127.0.0.1:19254/$name
|
|
||||||
|
|
||||||
[ CA_default ]
|
|
||||||
# Directory and file locations
|
|
||||||
dir = .
|
|
||||||
certs = $dir/CA
|
|
||||||
crl_dir = $dir/CA
|
|
||||||
new_certs_dir = $dir/CA
|
|
||||||
database = $dir/CA/index.txt
|
|
||||||
serial = $dir/CA/serial
|
|
||||||
rand_serial = yes
|
|
||||||
private_key = $dir/CA/$name\_crldp.key
|
|
||||||
certificate = $dir/tmp/$name\_crldp.pem
|
|
||||||
crlnumber = $dir/CA/crlnumber
|
|
||||||
crl_extensions = crl_ext
|
|
||||||
default_md = sha256
|
|
||||||
preserve = no
|
|
||||||
policy = policy_loose
|
|
||||||
default_startdate = 20180101000000Z
|
|
||||||
default_enddate = 20341231000000Z
|
|
||||||
x509_extensions = v3_req
|
|
||||||
email_in_dn = yes
|
|
||||||
default_days = 2200
|
|
||||||
|
|
||||||
[ req ]
|
|
||||||
# Options for the `req` tool
|
|
||||||
encrypt_key = no
|
|
||||||
default_bits = 2048
|
|
||||||
default_md = sha256
|
|
||||||
string_mask = utf8only
|
|
||||||
distinguished_name = req_distinguished_name
|
|
||||||
x509_extensions = usr_extensions
|
|
||||||
|
|
||||||
[ crl_ext ]
|
|
||||||
# Extension for CRLs
|
|
||||||
authorityKeyIdentifier = keyid:always
|
|
||||||
|
|
||||||
[ usr_extensions ]
|
|
||||||
# Extension to add when the -x509 option is used
|
|
||||||
basicConstraints = CA:FALSE
|
|
||||||
subjectKeyIdentifier = hash
|
|
||||||
authorityKeyIdentifier = keyid, issuer
|
|
||||||
extendedKeyUsage = codeSigning
|
|
||||||
|
|
||||||
[ v3_req ]
|
|
||||||
basicConstraints = CA:FALSE
|
|
||||||
subjectKeyIdentifier = hash
|
|
||||||
authorityKeyIdentifier = keyid, issuer
|
|
||||||
extendedKeyUsage = codeSigning
|
|
||||||
crlDistributionPoints = @crl_info
|
|
||||||
|
|
||||||
[ crl_info ]
|
|
||||||
# X509v3 CRL Distribution Points extension
|
|
||||||
URI.0 = $crl_url
|
|
||||||
|
|
||||||
[ policy_loose ]
|
|
||||||
# Allow the intermediate CA to sign a more diverse range of certificates.
|
|
||||||
# See the POLICY FORMAT section of the `ca` man page.
|
|
||||||
countryName = optional
|
|
||||||
stateOrProvinceName = optional
|
|
||||||
localityName = optional
|
|
||||||
organizationName = optional
|
|
||||||
organizationalUnitName = optional
|
|
||||||
commonName = supplied
|
|
||||||
emailAddress = optional
|
|
||||||
|
|
||||||
[ req_distinguished_name ]
|
|
||||||
countryName = Country Name (2 letter code)
|
|
||||||
stateOrProvinceName = State or Province Name
|
|
||||||
localityName = Locality Name
|
|
||||||
0.organizationName = Organization Name
|
|
||||||
organizationalUnitName = Organizational Unit Name
|
|
||||||
commonName = Common Name
|
|
||||||
emailAddress = Email Address
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
# OpenSSL root CA configuration file
|
|
||||||
|
|
||||||
[ ca ]
|
|
||||||
default_ca = CA_default
|
|
||||||
|
|
||||||
[ CA_default ]
|
|
||||||
# Directory and file locations.
|
|
||||||
dir = .
|
|
||||||
certs = $dir/CA
|
|
||||||
crl_dir = $dir/CA
|
|
||||||
new_certs_dir = $dir/CA
|
|
||||||
database = $dir/CA/index.txt
|
|
||||||
serial = $dir/CA/serial
|
|
||||||
rand_serial = yes
|
|
||||||
private_key = $dir/CA/CA.key
|
|
||||||
certificate = $dir/tmp/CACert.pem
|
|
||||||
crl_extensions = crl_ext
|
|
||||||
default_md = sha256
|
|
||||||
preserve = no
|
|
||||||
policy = policy_match
|
|
||||||
default_startdate = 20180101000000Z
|
|
||||||
default_enddate = 20360101000000Z
|
|
||||||
x509_extensions = v3_intermediate_ca
|
|
||||||
email_in_dn = yes
|
|
||||||
default_days = 3000
|
|
||||||
unique_subject = no
|
|
||||||
|
|
||||||
[ req ]
|
|
||||||
# Options for the `req` tool
|
|
||||||
encrypt_key = no
|
|
||||||
default_bits = 2048
|
|
||||||
default_md = sha256
|
|
||||||
string_mask = utf8only
|
|
||||||
x509_extensions = ca_extensions
|
|
||||||
distinguished_name = req_distinguished_name
|
|
||||||
|
|
||||||
[ ca_extensions ]
|
|
||||||
# Extension to add when the -x509 option is used
|
|
||||||
basicConstraints = critical, CA:true
|
|
||||||
subjectKeyIdentifier = hash
|
|
||||||
authorityKeyIdentifier = keyid:always,issuer
|
|
||||||
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
|
|
||||||
|
|
||||||
[ v3_intermediate_ca ]
|
|
||||||
# Extensions for a typical intermediate CA (`man x509v3_config`)
|
|
||||||
basicConstraints = critical, CA:true, pathlen:0
|
|
||||||
subjectKeyIdentifier = hash
|
|
||||||
authorityKeyIdentifier = keyid:always,issuer
|
|
||||||
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
|
|
||||||
|
|
||||||
[ policy_match ]
|
|
||||||
countryName = match
|
|
||||||
organizationName = match
|
|
||||||
organizationalUnitName = optional
|
|
||||||
commonName = supplied
|
|
||||||
emailAddress = optional
|
|
||||||
|
|
||||||
[ req_distinguished_name ]
|
|
||||||
countryName = Country Name (2 letter code)
|
|
||||||
stateOrProvinceName = State or Province Name
|
|
||||||
localityName = Locality Name
|
|
||||||
0.organizationName = Organization Name
|
|
||||||
organizationalUnitName = Organizational Unit Name
|
|
||||||
commonName = Common Name
|
|
||||||
emailAddress = Email Address
|
|
||||||
@@ -44,3 +44,4 @@ ordering = yes
|
|||||||
tsa_name = yes
|
tsa_name = yes
|
||||||
ess_cert_id_chain = yes
|
ess_cert_id_chain = yes
|
||||||
ess_cert_id_alg = sha256
|
ess_cert_id_alg = sha256
|
||||||
|
crypto_device = builtin
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
# OpenSSL Root Timestamp Authority configuration file
|
|
||||||
|
|
||||||
[ default ]
|
|
||||||
name = TSACA
|
|
||||||
domain_suffix = timestampauthority
|
|
||||||
crl_url = http://127.0.0.1:19254/$name
|
|
||||||
name_opt = utf8, esc_ctrl, multiline, lname, align
|
|
||||||
default_ca = CA_default
|
|
||||||
|
|
||||||
[ CA_default ]
|
|
||||||
dir = .
|
|
||||||
certs = $dir/CA
|
|
||||||
crl_dir = $dir/CA
|
|
||||||
new_certs_dir = $dir/CA
|
|
||||||
database = $dir/CA/index.txt
|
|
||||||
serial = $dir/CA/serial
|
|
||||||
crlnumber = $dir/CA/crlnumber
|
|
||||||
crl_extensions = crl_ext
|
|
||||||
rand_serial = yes
|
|
||||||
private_key = $dir/CA/$name.key
|
|
||||||
certificate = $dir/tmp/$name.pem
|
|
||||||
default_md = sha256
|
|
||||||
default_days = 3650
|
|
||||||
default_crl_days = 365
|
|
||||||
policy = policy_match
|
|
||||||
default_startdate = 20180101000000Z
|
|
||||||
default_enddate = 20380101000000Z
|
|
||||||
unique_subject = no
|
|
||||||
email_in_dn = no
|
|
||||||
x509_extensions = tsa_extensions
|
|
||||||
|
|
||||||
[ policy_match ]
|
|
||||||
countryName = match
|
|
||||||
stateOrProvinceName = optional
|
|
||||||
organizationName = match
|
|
||||||
organizationalUnitName = optional
|
|
||||||
commonName = supplied
|
|
||||||
emailAddress = optional
|
|
||||||
|
|
||||||
[ tsa_extensions ]
|
|
||||||
basicConstraints = critical, CA:false
|
|
||||||
extendedKeyUsage = critical, timeStamping
|
|
||||||
subjectKeyIdentifier = hash
|
|
||||||
authorityKeyIdentifier = keyid:always
|
|
||||||
crlDistributionPoints = @crl_info
|
|
||||||
nameConstraints = @name_constraints
|
|
||||||
|
|
||||||
[ crl_info ]
|
|
||||||
# X509v3 CRL Distribution Points extension
|
|
||||||
URI.0 = $crl_url
|
|
||||||
|
|
||||||
[ crl_ext ]
|
|
||||||
# Extension for CRLs
|
|
||||||
authorityKeyIdentifier = keyid:always
|
|
||||||
|
|
||||||
[ name_constraints ]
|
|
||||||
permitted;DNS.0=test.com
|
|
||||||
permitted;DNS.1=test.org
|
|
||||||
excluded;IP.0=0.0.0.0/0.0.0.0
|
|
||||||
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0
|
|
||||||
|
|
||||||
[ req ]
|
|
||||||
# Options for the `req` tool
|
|
||||||
default_bits = 2048
|
|
||||||
encrypt_key = yes
|
|
||||||
default_md = sha256
|
|
||||||
utf8 = yes
|
|
||||||
string_mask = utf8only
|
|
||||||
prompt = no
|
|
||||||
distinguished_name = ca_distinguished_name
|
|
||||||
x509_extensions = ca_extensions
|
|
||||||
|
|
||||||
[ ca_distinguished_name ]
|
|
||||||
countryName = "PL"
|
|
||||||
organizationName = "osslsigncode"
|
|
||||||
organizationalUnitName = "Timestamp Authority Root CA"
|
|
||||||
commonName = "TSA Root CA"
|
|
||||||
|
|
||||||
[ ca_extensions ]
|
|
||||||
# Extension to add when the -x509 option is used
|
|
||||||
basicConstraints = critical, CA:true
|
|
||||||
subjectKeyIdentifier = hash
|
|
||||||
keyUsage = critical, keyCertSign, cRLSign
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""Implementation of a single ctest script."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
|
|
||||||
|
def parse(value):
|
||||||
|
"""Read parameter from file."""
|
||||||
|
prefix = 'FILE '
|
||||||
|
if value.startswith(prefix):
|
||||||
|
with open(value[len(prefix):], mode="r", encoding="utf-8") as file:
|
||||||
|
return file.read().strip()
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
"""Run osslsigncode with its options."""
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
try:
|
||||||
|
params = map(parse, sys.argv[1:])
|
||||||
|
proc = Popen(params, stdout=PIPE, stderr=PIPE, text=True)
|
||||||
|
stdout, stderr = proc.communicate()
|
||||||
|
print(stdout, file=sys.stderr)
|
||||||
|
if stderr:
|
||||||
|
print("Error:\n" + "-" * 58 + "\n" + stderr, file=sys.stderr)
|
||||||
|
sys.exit(proc.returncode)
|
||||||
|
except Exception as err: # pylint: disable=broad-except
|
||||||
|
# all exceptions are critical
|
||||||
|
print(err, file=sys.stderr)
|
||||||
|
else:
|
||||||
|
print("Usage:\n\t{} COMMAND [ARG]...".format(sys.argv[0]), file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=pointless-string-statement
|
||||||
|
"""Local Variables:
|
||||||
|
c-basic-offset: 4
|
||||||
|
tab-width: 4
|
||||||
|
indent-tabs-mode: nil
|
||||||
|
End:
|
||||||
|
vim: set ts=4 expandtab:
|
||||||
|
"""
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
console.log("Hello, world!");
|
||||||
@@ -0,0 +1,593 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""Make test certificates"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import datetime
|
||||||
|
import cryptography
|
||||||
|
|
||||||
|
# Explicit imports of cryptography submodules
|
||||||
|
import cryptography.x509
|
||||||
|
import cryptography.x509.oid
|
||||||
|
import cryptography.hazmat.primitives.hashes
|
||||||
|
import cryptography.hazmat.primitives.asymmetric.rsa
|
||||||
|
import cryptography.hazmat.primitives.serialization
|
||||||
|
import cryptography.hazmat.primitives.serialization.pkcs12
|
||||||
|
|
||||||
|
# Import classes and functions from the cryptography module
|
||||||
|
from cryptography.x509 import (
|
||||||
|
AuthorityKeyIdentifier,
|
||||||
|
BasicConstraints,
|
||||||
|
Certificate,
|
||||||
|
CertificateBuilder,
|
||||||
|
CertificateRevocationListBuilder,
|
||||||
|
CRLDistributionPoints,
|
||||||
|
CRLNumber,
|
||||||
|
CRLReason,
|
||||||
|
DistributionPoint,
|
||||||
|
DNSName,
|
||||||
|
ExtendedKeyUsage,
|
||||||
|
KeyUsage,
|
||||||
|
Name,
|
||||||
|
NameAttribute,
|
||||||
|
NameConstraints,
|
||||||
|
random_serial_number,
|
||||||
|
RevokedCertificateBuilder,
|
||||||
|
ReasonFlags,
|
||||||
|
SubjectKeyIdentifier,
|
||||||
|
UniformResourceIdentifier
|
||||||
|
)
|
||||||
|
from cryptography.x509.oid import (
|
||||||
|
ExtendedKeyUsageOID,
|
||||||
|
NameOID
|
||||||
|
)
|
||||||
|
from cryptography.hazmat.primitives.hashes import SHA256
|
||||||
|
from cryptography.hazmat.primitives.asymmetric.rsa import (
|
||||||
|
generate_private_key,
|
||||||
|
RSAPrivateKey
|
||||||
|
)
|
||||||
|
from cryptography.hazmat.primitives.serialization import (
|
||||||
|
BestAvailableEncryption,
|
||||||
|
Encoding,
|
||||||
|
NoEncryption,
|
||||||
|
PrivateFormat
|
||||||
|
)
|
||||||
|
from cryptography.hazmat.primitives.serialization.pkcs12 import serialize_key_and_certificates
|
||||||
|
|
||||||
|
try:
|
||||||
|
if cryptography.__version__ >= '38.0.0':
|
||||||
|
from cryptography.hazmat.primitives.serialization.pkcs12 import PBES
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
RESULT_PATH = os.getcwd()
|
||||||
|
CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
|
||||||
|
|
||||||
|
date_20170101 = datetime.datetime(2017, 1, 1)
|
||||||
|
date_20180101 = datetime.datetime(2018, 1, 1)
|
||||||
|
date_20190101 = datetime.datetime(2019, 1, 1)
|
||||||
|
|
||||||
|
PASSWORD='passme'
|
||||||
|
|
||||||
|
|
||||||
|
class X509Extensions():
|
||||||
|
"""Base class for X509 Extensions"""
|
||||||
|
|
||||||
|
def __init__(self, unit_name, cdp_port, cdp_name):
|
||||||
|
self.unit_name = unit_name
|
||||||
|
self.port = cdp_port
|
||||||
|
self.name = cdp_name
|
||||||
|
|
||||||
|
def create_x509_name(self, common_name) -> Name:
|
||||||
|
"""Return x509.Name"""
|
||||||
|
return Name(
|
||||||
|
[
|
||||||
|
NameAttribute(NameOID.COUNTRY_NAME, "PL"),
|
||||||
|
NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Mazovia Province"),
|
||||||
|
NameAttribute(NameOID.LOCALITY_NAME, "Warsaw"),
|
||||||
|
NameAttribute(NameOID.ORGANIZATION_NAME, "osslsigncode"),
|
||||||
|
NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, self.unit_name),
|
||||||
|
NameAttribute(NameOID.COMMON_NAME, common_name)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_x509_crldp(self) -> CRLDistributionPoints:
|
||||||
|
"""Return x509.CRLDistributionPoints"""
|
||||||
|
return CRLDistributionPoints(
|
||||||
|
[
|
||||||
|
DistributionPoint(
|
||||||
|
full_name=[UniformResourceIdentifier(
|
||||||
|
"http://127.0.0.1:" + str(self.port) + "/" + str(self.name))
|
||||||
|
],
|
||||||
|
relative_name=None,
|
||||||
|
reasons=None,
|
||||||
|
crl_issuer=None
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_x509_name_constraints(self) -> NameConstraints:
|
||||||
|
"""Return x509.NameConstraints"""
|
||||||
|
return NameConstraints(
|
||||||
|
permitted_subtrees = [DNSName('test.com'), DNSName('test.org')],
|
||||||
|
excluded_subtrees = None
|
||||||
|
)
|
||||||
|
|
||||||
|
class IntermediateCACertificate(X509Extensions):
|
||||||
|
"""Base class for Intermediate CA certificate"""
|
||||||
|
|
||||||
|
def __init__(self, issuer_cert, issuer_key):
|
||||||
|
self.issuer_cert = issuer_cert
|
||||||
|
self.issuer_key = issuer_key
|
||||||
|
super().__init__("Certification Authority", 0, None)
|
||||||
|
|
||||||
|
def make_cert(self) -> (Certificate, RSAPrivateKey):
|
||||||
|
"""Generate intermediate CA certificate"""
|
||||||
|
key = generate_private_key(public_exponent=65537, key_size=2048)
|
||||||
|
key_public = key.public_key()
|
||||||
|
authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
|
||||||
|
self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
|
||||||
|
)
|
||||||
|
key_usage = KeyUsage(
|
||||||
|
digital_signature=True,
|
||||||
|
content_commitment=False,
|
||||||
|
key_encipherment=False,
|
||||||
|
data_encipherment=False,
|
||||||
|
key_agreement=False,
|
||||||
|
key_cert_sign=True,
|
||||||
|
crl_sign=True,
|
||||||
|
encipher_only=False,
|
||||||
|
decipher_only=False
|
||||||
|
)
|
||||||
|
cert = (
|
||||||
|
CertificateBuilder()
|
||||||
|
.subject_name(self.create_x509_name("Intermediate CA"))
|
||||||
|
.issuer_name(self.issuer_cert.subject)
|
||||||
|
.public_key(key_public)
|
||||||
|
.serial_number(random_serial_number())
|
||||||
|
.not_valid_before(date_20180101)
|
||||||
|
.not_valid_after(date_20180101 + datetime.timedelta(days=7300))
|
||||||
|
.add_extension(BasicConstraints(ca=True, path_length=0), critical=True)
|
||||||
|
.add_extension(SubjectKeyIdentifier.from_public_key(key_public), critical=False)
|
||||||
|
.add_extension(authority_key, critical=False)
|
||||||
|
.add_extension(key_usage, critical=True)
|
||||||
|
.sign(self.issuer_key, SHA256())
|
||||||
|
)
|
||||||
|
file_path=os.path.join(CERTS_PATH, "intermediateCA.pem")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(cert.public_bytes(encoding=Encoding.PEM))
|
||||||
|
|
||||||
|
return cert, key
|
||||||
|
|
||||||
|
|
||||||
|
class RootCACertificate(X509Extensions):
|
||||||
|
"""Base class for Root CA certificate"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.key_usage = KeyUsage(
|
||||||
|
digital_signature=True,
|
||||||
|
content_commitment=False,
|
||||||
|
key_encipherment=False,
|
||||||
|
data_encipherment=False,
|
||||||
|
key_agreement=False,
|
||||||
|
key_cert_sign=True,
|
||||||
|
crl_sign=True,
|
||||||
|
encipher_only=False,
|
||||||
|
decipher_only=False
|
||||||
|
)
|
||||||
|
super().__init__("Certification Authority", 0, None)
|
||||||
|
|
||||||
|
def make_cert(self) -> (Certificate, RSAPrivateKey):
|
||||||
|
"""Generate CA certificates"""
|
||||||
|
ca_root, root_key = self.make_ca_cert("Trusted Root CA", "CAroot.pem")
|
||||||
|
ca_cert, ca_key = self.make_ca_cert("Root CA", "CACert.pem")
|
||||||
|
self.make_cross_cert(ca_root, root_key, ca_cert, ca_key)
|
||||||
|
return ca_cert, ca_key
|
||||||
|
|
||||||
|
def make_ca_cert(self, common_name, file_name) -> None:
|
||||||
|
"""Generate self-signed root CA certificate"""
|
||||||
|
ca_key = generate_private_key(public_exponent=65537, key_size=2048)
|
||||||
|
ca_public = ca_key.public_key()
|
||||||
|
authority_key = AuthorityKeyIdentifier.from_issuer_public_key(ca_public)
|
||||||
|
name = self.create_x509_name(common_name)
|
||||||
|
ca_cert = (
|
||||||
|
CertificateBuilder()
|
||||||
|
.subject_name(name)
|
||||||
|
.issuer_name(name)
|
||||||
|
.public_key(ca_public)
|
||||||
|
.serial_number(random_serial_number())
|
||||||
|
.not_valid_before(date_20170101)
|
||||||
|
.not_valid_after(date_20170101 + datetime.timedelta(days=7300))
|
||||||
|
.add_extension(BasicConstraints(ca=True, path_length=None), critical=True)
|
||||||
|
.add_extension(SubjectKeyIdentifier.from_public_key(ca_public), critical=False)
|
||||||
|
.add_extension(authority_key, critical=False)
|
||||||
|
.add_extension(self.key_usage, critical=True)
|
||||||
|
.sign(ca_key, SHA256())
|
||||||
|
)
|
||||||
|
file_path=os.path.join(CERTS_PATH, file_name)
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(ca_cert.public_bytes(encoding=Encoding.PEM))
|
||||||
|
return ca_cert, ca_key
|
||||||
|
|
||||||
|
def make_cross_cert(self, ca_root, root_key, ca_cert, ca_key) -> None:
|
||||||
|
"""Generate cross-signed root CA certificate"""
|
||||||
|
ca_public = ca_key.public_key()
|
||||||
|
authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
|
||||||
|
ca_root.extensions.get_extension_for_class(SubjectKeyIdentifier).value
|
||||||
|
)
|
||||||
|
ca_cross = (
|
||||||
|
CertificateBuilder()
|
||||||
|
.subject_name(ca_cert.subject)
|
||||||
|
.issuer_name(ca_root.subject)
|
||||||
|
.public_key(ca_public)
|
||||||
|
.serial_number(ca_cert.serial_number)
|
||||||
|
.not_valid_before(date_20180101)
|
||||||
|
.not_valid_after(date_20180101 + datetime.timedelta(days=7300))
|
||||||
|
.add_extension(BasicConstraints(ca=True, path_length=None), critical=True)
|
||||||
|
.add_extension(SubjectKeyIdentifier.from_public_key(ca_public), critical=False)
|
||||||
|
.add_extension(authority_key, critical=False)
|
||||||
|
.add_extension(self.key_usage, critical=True)
|
||||||
|
.sign(root_key, SHA256())
|
||||||
|
)
|
||||||
|
file_path=os.path.join(CERTS_PATH, "CAcross.pem")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(ca_cross.public_bytes(encoding=Encoding.PEM))
|
||||||
|
|
||||||
|
def write_key(self, key, file_name) -> None:
|
||||||
|
"""Write a private RSA key"""
|
||||||
|
# Write password
|
||||||
|
file_path = os.path.join(CERTS_PATH, "password.txt")
|
||||||
|
with open(file_path, mode="w", encoding="utf-8") as file:
|
||||||
|
file.write("{}".format(PASSWORD))
|
||||||
|
|
||||||
|
# Write encrypted key in PEM format
|
||||||
|
file_path = os.path.join(CERTS_PATH, file_name + "p.pem")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(key.private_bytes(
|
||||||
|
encoding=Encoding.PEM,
|
||||||
|
format=PrivateFormat.PKCS8,
|
||||||
|
encryption_algorithm=BestAvailableEncryption(PASSWORD.encode())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# Write decrypted key in PEM format
|
||||||
|
file_path = os.path.join(CERTS_PATH, file_name + ".pem")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(key.private_bytes(
|
||||||
|
encoding=Encoding.PEM,
|
||||||
|
format=PrivateFormat.PKCS8,
|
||||||
|
encryption_algorithm=NoEncryption()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# Write the key in DER format
|
||||||
|
file_path = os.path.join(CERTS_PATH, file_name + ".der")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(key.private_bytes(
|
||||||
|
encoding=Encoding.DER,
|
||||||
|
format=PrivateFormat.PKCS8,
|
||||||
|
encryption_algorithm=NoEncryption()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TSARootCACertificate(X509Extensions):
|
||||||
|
"""Base class for TSA certificates"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Timestamp Authority Root CA", 0, None)
|
||||||
|
|
||||||
|
def make_cert(self) -> (Certificate, RSAPrivateKey):
|
||||||
|
"""Generate a Time Stamp Authority certificate"""
|
||||||
|
ca_key = generate_private_key(public_exponent=65537, key_size=2048)
|
||||||
|
ca_public = ca_key.public_key()
|
||||||
|
authority_key = AuthorityKeyIdentifier.from_issuer_public_key(ca_public)
|
||||||
|
name = self.create_x509_name("TSA Root CA")
|
||||||
|
key_usage = KeyUsage(
|
||||||
|
digital_signature=False,
|
||||||
|
content_commitment=False,
|
||||||
|
key_encipherment=False,
|
||||||
|
data_encipherment=False,
|
||||||
|
key_agreement=False,
|
||||||
|
key_cert_sign=True,
|
||||||
|
crl_sign=True,
|
||||||
|
encipher_only=False,
|
||||||
|
decipher_only=False
|
||||||
|
)
|
||||||
|
ca_cert = (
|
||||||
|
CertificateBuilder()
|
||||||
|
.subject_name(name)
|
||||||
|
.issuer_name(name)
|
||||||
|
.public_key(ca_public)
|
||||||
|
.serial_number(random_serial_number())
|
||||||
|
.not_valid_before(date_20170101)
|
||||||
|
.not_valid_after(date_20170101 + datetime.timedelta(days=7300))
|
||||||
|
.add_extension(BasicConstraints(ca=True, path_length=None), critical=True)
|
||||||
|
.add_extension(SubjectKeyIdentifier.from_public_key(ca_public), critical=False)
|
||||||
|
.add_extension(authority_key, critical=False)
|
||||||
|
.add_extension(key_usage, critical=True)
|
||||||
|
.sign(ca_key, SHA256())
|
||||||
|
)
|
||||||
|
file_path=os.path.join(CERTS_PATH, "TSACA.pem")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(ca_cert.public_bytes(encoding=Encoding.PEM))
|
||||||
|
|
||||||
|
return ca_cert, ca_key
|
||||||
|
|
||||||
|
def write_key(self, key, file_name) -> None:
|
||||||
|
"""Write decrypted private RSA key into PEM format"""
|
||||||
|
file_path = os.path.join(CERTS_PATH, file_name + ".key")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(key.private_bytes(
|
||||||
|
encoding=Encoding.PEM,
|
||||||
|
format=PrivateFormat.PKCS8,
|
||||||
|
encryption_algorithm=NoEncryption()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class LeafCertificate(X509Extensions):
|
||||||
|
"""Base class for a leaf certificate"""
|
||||||
|
|
||||||
|
def __init__(self, issuer_cert, issuer_key, unit_name, common_name, cdp_port, cdp_name):
|
||||||
|
#pylint: disable=too-many-arguments
|
||||||
|
self.issuer_cert = issuer_cert
|
||||||
|
self.issuer_key = issuer_key
|
||||||
|
self.common_name = common_name
|
||||||
|
super().__init__(unit_name, cdp_port, cdp_name)
|
||||||
|
|
||||||
|
def make_cert(self, public_key, not_before, days) -> Certificate:
|
||||||
|
"""Generate a leaf certificate"""
|
||||||
|
authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
|
||||||
|
self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
|
||||||
|
)
|
||||||
|
key_usage = KeyUsage(
|
||||||
|
digital_signature=True,
|
||||||
|
content_commitment=False,
|
||||||
|
key_encipherment=False,
|
||||||
|
data_encipherment=False,
|
||||||
|
key_agreement=False,
|
||||||
|
key_cert_sign=False,
|
||||||
|
crl_sign=False,
|
||||||
|
encipher_only=False,
|
||||||
|
decipher_only=False
|
||||||
|
)
|
||||||
|
extended_key_usage = ExtendedKeyUsage(
|
||||||
|
[ExtendedKeyUsageOID.CODE_SIGNING]
|
||||||
|
)
|
||||||
|
cert = (
|
||||||
|
CertificateBuilder()
|
||||||
|
.subject_name(self.create_x509_name(self.common_name))
|
||||||
|
.issuer_name(self.issuer_cert.subject)
|
||||||
|
.public_key(public_key)
|
||||||
|
.serial_number(random_serial_number())
|
||||||
|
.not_valid_before(not_before)
|
||||||
|
.not_valid_after(not_before + datetime.timedelta(days=days))
|
||||||
|
.add_extension(BasicConstraints(ca=False, path_length=None), critical=False)
|
||||||
|
.add_extension(SubjectKeyIdentifier.from_public_key(public_key), critical=False)
|
||||||
|
.add_extension(authority_key, critical=False)
|
||||||
|
.add_extension(key_usage, critical=False)
|
||||||
|
.add_extension(extended_key_usage, critical=False)
|
||||||
|
.add_extension(self.create_x509_crldp(), critical=False)
|
||||||
|
.sign(self.issuer_key, SHA256())
|
||||||
|
)
|
||||||
|
# Write PEM file and attach intermediate certificate
|
||||||
|
file_path = os.path.join(CERTS_PATH, self.common_name + ".pem")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(cert.public_bytes(encoding=Encoding.PEM))
|
||||||
|
file.write(self.issuer_cert.public_bytes(encoding=Encoding.PEM))
|
||||||
|
|
||||||
|
return cert
|
||||||
|
|
||||||
|
def revoke_cert(self, serial_number, file_name) -> None:
|
||||||
|
"""Revoke a certificate"""
|
||||||
|
revoked = (
|
||||||
|
RevokedCertificateBuilder()
|
||||||
|
.serial_number(serial_number)
|
||||||
|
.revocation_date(date_20190101)
|
||||||
|
.add_extension(CRLReason(ReasonFlags.superseded), critical=False)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
# Generate CRL
|
||||||
|
authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
|
||||||
|
self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
|
||||||
|
)
|
||||||
|
crl = (
|
||||||
|
CertificateRevocationListBuilder()
|
||||||
|
.issuer_name(self.issuer_cert.subject)
|
||||||
|
.last_update(date_20190101)
|
||||||
|
.next_update(date_20190101 + datetime.timedelta(days=7300))
|
||||||
|
.add_extension(authority_key, critical=False)
|
||||||
|
.add_extension(CRLNumber(4097), critical=False)
|
||||||
|
.add_revoked_certificate(revoked)
|
||||||
|
.sign(self.issuer_key, SHA256())
|
||||||
|
)
|
||||||
|
# Write CRL file
|
||||||
|
file_path = os.path.join(CERTS_PATH, file_name + ".pem")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(crl.public_bytes(encoding=Encoding.PEM))
|
||||||
|
|
||||||
|
file_path = os.path.join(CERTS_PATH, file_name + ".der")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(crl.public_bytes(encoding=Encoding.DER))
|
||||||
|
|
||||||
|
|
||||||
|
class LeafCACertificate(LeafCertificate):
|
||||||
|
"""Base class for a leaf certificate"""
|
||||||
|
|
||||||
|
def __init__(self, issuer_cert, issuer_key, common, cdp_port):
|
||||||
|
super().__init__(issuer_cert, issuer_key, "CSP", common, cdp_port, "intermediateCA")
|
||||||
|
|
||||||
|
|
||||||
|
class LeafTSACertificate(LeafCertificate):
|
||||||
|
"""Base class for a TSA leaf certificate"""
|
||||||
|
|
||||||
|
def __init__(self, issuer_cert, issuer_key, common, cdp_port):
|
||||||
|
self.issuer_cert = issuer_cert
|
||||||
|
self.issuer_key = issuer_key
|
||||||
|
self.common_name = common
|
||||||
|
super().__init__(issuer_cert, issuer_key, "Timestamp Root CA", common, cdp_port, "TSACA")
|
||||||
|
|
||||||
|
def make_cert(self, public_key, not_before, days) -> Certificate:
|
||||||
|
"""Generate a TSA leaf certificate"""
|
||||||
|
|
||||||
|
authority_key = AuthorityKeyIdentifier.from_issuer_subject_key_identifier(
|
||||||
|
self.issuer_cert.extensions.get_extension_for_class(SubjectKeyIdentifier).value
|
||||||
|
)
|
||||||
|
|
||||||
|
# The TSA signing certificate must have exactly one extended key usage
|
||||||
|
# assigned to it: timeStamping. The extended key usage must also be critical,
|
||||||
|
# otherwise the certificate is going to be refused.
|
||||||
|
extended_key_usage = ExtendedKeyUsage(
|
||||||
|
[ExtendedKeyUsageOID.TIME_STAMPING]
|
||||||
|
)
|
||||||
|
cert = (
|
||||||
|
CertificateBuilder()
|
||||||
|
.subject_name(self.create_x509_name(self.common_name))
|
||||||
|
.issuer_name(self.issuer_cert.subject)
|
||||||
|
.public_key(public_key)
|
||||||
|
.serial_number(random_serial_number())
|
||||||
|
.not_valid_before(not_before)
|
||||||
|
.not_valid_after(not_before + datetime.timedelta(days=days))
|
||||||
|
.add_extension(BasicConstraints(ca=False, path_length=None), critical=True)
|
||||||
|
.add_extension(SubjectKeyIdentifier.from_public_key(public_key), critical=False)
|
||||||
|
.add_extension(authority_key, critical=False)
|
||||||
|
.add_extension(extended_key_usage, critical=True)
|
||||||
|
.add_extension(self.create_x509_crldp(), critical=False)
|
||||||
|
.add_extension(self.create_x509_name_constraints(), critical=False)
|
||||||
|
.sign(self.issuer_key, SHA256())
|
||||||
|
)
|
||||||
|
# Write PEM file and attach intermediate certificate
|
||||||
|
file_path = os.path.join(CERTS_PATH, self.common_name + ".pem")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(cert.public_bytes(encoding=Encoding.PEM))
|
||||||
|
file.write(self.issuer_cert.public_bytes(encoding=Encoding.PEM))
|
||||||
|
|
||||||
|
return cert
|
||||||
|
|
||||||
|
|
||||||
|
class CertificateMaker():
|
||||||
|
"""Base class for test certificates"""
|
||||||
|
|
||||||
|
def __init__(self, cdp_port, logs):
|
||||||
|
self.cdp_port = cdp_port
|
||||||
|
self.logs = logs
|
||||||
|
|
||||||
|
def make_certs(self) -> None:
|
||||||
|
"""Make test certificates"""
|
||||||
|
try:
|
||||||
|
self.make_ca_certs()
|
||||||
|
self.make_tsa_certs()
|
||||||
|
logs = os.path.join(CERTS_PATH, "./cert.log")
|
||||||
|
with open(logs, mode="w", encoding="utf-8") as file:
|
||||||
|
file.write("Test certificates generation succeeded")
|
||||||
|
except Exception as err: # pylint: disable=broad-except
|
||||||
|
with open(self.logs, mode="a", encoding="utf-8") as file:
|
||||||
|
file.write("Error: {}".format(err))
|
||||||
|
|
||||||
|
def make_ca_certs(self):
|
||||||
|
"""Make test certificates"""
|
||||||
|
|
||||||
|
# Generate root CA certificate
|
||||||
|
root = RootCACertificate()
|
||||||
|
ca_cert, ca_key = root.make_cert()
|
||||||
|
|
||||||
|
# Generate intermediate root CA certificate
|
||||||
|
intermediate = IntermediateCACertificate(ca_cert, ca_key)
|
||||||
|
issuer_cert, issuer_key = intermediate.make_cert()
|
||||||
|
|
||||||
|
# Generate private RSA key
|
||||||
|
private_key = generate_private_key(public_exponent=65537, key_size=2048)
|
||||||
|
public_key = private_key.public_key()
|
||||||
|
root.write_key(key=private_key, file_name="key")
|
||||||
|
|
||||||
|
# Generate expired certificate
|
||||||
|
expired = LeafCACertificate(issuer_cert, issuer_key, "expired", self.cdp_port)
|
||||||
|
expired.make_cert(public_key, date_20180101, 365)
|
||||||
|
|
||||||
|
# Generate revoked certificate
|
||||||
|
revoked = LeafCACertificate(issuer_cert, issuer_key, "revoked", self.cdp_port)
|
||||||
|
cert = revoked.make_cert(public_key, date_20180101, 5840)
|
||||||
|
revoked.revoke_cert(cert.serial_number, "CACertCRL")
|
||||||
|
|
||||||
|
# Generate code signing certificate
|
||||||
|
signer = LeafCACertificate(issuer_cert, issuer_key, "cert", self.cdp_port)
|
||||||
|
cert = signer.make_cert(public_key, date_20180101, 5840)
|
||||||
|
|
||||||
|
# Write a certificate and a key into PKCS#12 container
|
||||||
|
self.write_pkcs12_container(
|
||||||
|
cert=cert,
|
||||||
|
key=private_key,
|
||||||
|
issuer=issuer_cert
|
||||||
|
)
|
||||||
|
|
||||||
|
# Write DER file and attach intermediate certificate
|
||||||
|
file_path = os.path.join(CERTS_PATH, "cert.der")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(cert.public_bytes(encoding=Encoding.DER))
|
||||||
|
|
||||||
|
def make_tsa_certs(self):
|
||||||
|
"""Make test TSA certificates"""
|
||||||
|
|
||||||
|
# Time Stamp Authority certificate
|
||||||
|
root = TSARootCACertificate()
|
||||||
|
issuer_cert, issuer_key = root.make_cert()
|
||||||
|
|
||||||
|
# Generate private RSA key
|
||||||
|
private_key = generate_private_key(public_exponent=65537, key_size=2048)
|
||||||
|
public_key = private_key.public_key()
|
||||||
|
root.write_key(key=private_key, file_name="TSA")
|
||||||
|
|
||||||
|
# Generate revoked TSA certificate
|
||||||
|
revoked = LeafTSACertificate(issuer_cert, issuer_key, "TSA_revoked", self.cdp_port)
|
||||||
|
cert = revoked.make_cert(public_key, date_20180101, 7300)
|
||||||
|
revoked.revoke_cert(cert.serial_number, "TSACertCRL")
|
||||||
|
|
||||||
|
# Generate TSA certificate
|
||||||
|
signer = LeafTSACertificate(issuer_cert, issuer_key, "TSA", self.cdp_port)
|
||||||
|
cert = signer.make_cert(public_key, date_20180101, 7300)
|
||||||
|
|
||||||
|
# Save the chain to be included in the TSA response
|
||||||
|
file_path = os.path.join(CERTS_PATH, "tsa-chain.pem")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(cert.public_bytes(encoding=Encoding.PEM))
|
||||||
|
file.write(issuer_cert.public_bytes(encoding=Encoding.PEM))
|
||||||
|
|
||||||
|
|
||||||
|
def write_pkcs12_container(self, cert, key, issuer) -> None:
|
||||||
|
"""Write a certificate and a key into a PKCS#12 container"""
|
||||||
|
|
||||||
|
# Set an encryption algorithm
|
||||||
|
if cryptography.__version__ >= "38.0.0":
|
||||||
|
# For OpenSSL legacy mode use the default algorithm for certificate
|
||||||
|
# and private key encryption: DES-EDE3-CBC (vel 3DES_CBC)
|
||||||
|
# pylint: disable=no-member
|
||||||
|
encryption = (
|
||||||
|
PrivateFormat.PKCS12.encryption_builder()
|
||||||
|
.key_cert_algorithm(PBES.PBESv1SHA1And3KeyTripleDESCBC)
|
||||||
|
.kdf_rounds(5000)
|
||||||
|
.build(PASSWORD.encode())
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
encryption = BestAvailableEncryption(PASSWORD.encode())
|
||||||
|
|
||||||
|
# Generate PKCS#12 struct
|
||||||
|
pkcs12 = serialize_key_and_certificates(
|
||||||
|
name=b'certificate',
|
||||||
|
key=key,
|
||||||
|
cert=cert,
|
||||||
|
cas=(issuer,),
|
||||||
|
encryption_algorithm=encryption
|
||||||
|
)
|
||||||
|
|
||||||
|
# Write into a PKCS#12 container
|
||||||
|
file_path = os.path.join(CERTS_PATH, "cert.p12")
|
||||||
|
with open(file_path, mode="wb") as file:
|
||||||
|
file.write(pkcs12)
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=pointless-string-statement
|
||||||
|
"""Local Variables:
|
||||||
|
c-basic-offset: 4
|
||||||
|
tab-width: 4
|
||||||
|
indent-tabs-mode: nil
|
||||||
|
End:
|
||||||
|
vim: set ts=4 expandtab:
|
||||||
|
"""
|
||||||
+32
-18
@@ -1,4 +1,5 @@
|
|||||||
"""Implementation of a HTTP server"""
|
#!/usr/bin/python3
|
||||||
|
"""Implementation of an HTTP server"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
@@ -8,6 +9,7 @@ import threading
|
|||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from http.server import SimpleHTTPRequestHandler, HTTPServer
|
from http.server import SimpleHTTPRequestHandler, HTTPServer
|
||||||
from socketserver import ThreadingMixIn
|
from socketserver import ThreadingMixIn
|
||||||
|
from make_certificates import CertificateMaker
|
||||||
|
|
||||||
RESULT_PATH = os.getcwd()
|
RESULT_PATH = os.getcwd()
|
||||||
FILES_PATH = os.path.join(RESULT_PATH, "./Testing/files/")
|
FILES_PATH = os.path.join(RESULT_PATH, "./Testing/files/")
|
||||||
@@ -15,22 +17,23 @@ CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
|
|||||||
CONF_PATH = os.path.join(RESULT_PATH, "./Testing/conf/")
|
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")
|
||||||
CACRL = os.path.join(CERTS_PATH, "./CACertCRL.der")
|
|
||||||
TSACRL = os.path.join(CERTS_PATH, "./TSACertCRL.der")
|
|
||||||
OPENSSL_CONF = os.path.join(CONF_PATH, "./openssl_tsa.cnf")
|
OPENSSL_CONF = os.path.join(CONF_PATH, "./openssl_tsa.cnf")
|
||||||
PORT_LOG = os.path.join(LOGS_PATH, "./port.log")
|
SERVER_LOG = os.path.join(LOGS_PATH, "./server.log")
|
||||||
|
URL_LOG = os.path.join(LOGS_PATH, "./url.log")
|
||||||
|
|
||||||
OPENSSL_TS = ["openssl", "ts",
|
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):
|
||||||
|
"""This variant of HTTPServer creates a new thread for every connection"""
|
||||||
daemon_threads = True
|
daemon_threads = True
|
||||||
|
|
||||||
|
|
||||||
class RequestHandler(SimpleHTTPRequestHandler):
|
class RequestHandler(SimpleHTTPRequestHandler):
|
||||||
"""Handle the HTTP POST request that arrive at the server"""
|
"""Handle the HTTP POST request that arrive at the server"""
|
||||||
|
|
||||||
@@ -44,15 +47,17 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||||||
try:
|
try:
|
||||||
url = urlparse(self.path)
|
url = urlparse(self.path)
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header("Content-type", "application/crl")
|
self.send_header("Content-type", "application/pkix-crl")
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
resp_data = b''
|
resp_data = b''
|
||||||
# Read the file and send the contents
|
# Read the file and send the contents
|
||||||
if url.path == "/intermediateCA":
|
if url.path == "/intermediateCA":
|
||||||
with open(CACRL, 'rb') as file:
|
file_path = os.path.join(CERTS_PATH, "./CACertCRL.der")
|
||||||
|
with open(file_path, 'rb') as file:
|
||||||
resp_data = file.read()
|
resp_data = file.read()
|
||||||
if url.path == "/TSACA":
|
if url.path == "/TSACA":
|
||||||
with open(TSACRL, 'rb') as file:
|
file_path = os.path.join(CERTS_PATH, "./TSACertCRL.der")
|
||||||
|
with open(file_path, 'rb') as file:
|
||||||
resp_data = file.read()
|
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
|
||||||
@@ -65,8 +70,8 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||||||
url = urlparse(self.path)
|
url = urlparse(self.path)
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
if url.path == "/kill_server":
|
if url.path == "/kill_server":
|
||||||
self.log_message(f"Deleting file: {PORT_LOG}")
|
self.log_message(f"Deleting file: {URL_LOG}")
|
||||||
os.remove(f"{PORT_LOG}")
|
os.remove(f"{URL_LOG}")
|
||||||
self.send_header('Content-type', 'text/plain')
|
self.send_header('Content-type', 'text/plain')
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(bytes('Shutting down HTTP server', 'utf-8'))
|
self.wfile.write(bytes('Shutting down HTTP server', 'utf-8'))
|
||||||
@@ -76,15 +81,15 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||||||
post_data = self.rfile.read(content_length)
|
post_data = self.rfile.read(content_length)
|
||||||
with open(REQUEST, mode="wb") as file:
|
with open(REQUEST, mode="wb") as file:
|
||||||
file.write(post_data)
|
file.write(post_data)
|
||||||
openssl = subprocess.run(OPENSSL_TS,
|
openssl = subprocess.run(OPENSSL_TS, check=True, universal_newlines=True)
|
||||||
check=True, universal_newlines=True)
|
|
||||||
openssl.check_returncode()
|
openssl.check_returncode()
|
||||||
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
|
||||||
print("HTTP POST request error: {}".format(err))
|
print("HTTP POST request error: {}".format(err))
|
||||||
|
|
||||||
@@ -108,7 +113,8 @@ class HttpServerThread():
|
|||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
"""Start HTTP server"""
|
"""Start HTTP server, make test certificates."""
|
||||||
|
|
||||||
ret = 0
|
ret = 0
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@@ -121,11 +127,16 @@ def main() -> None:
|
|||||||
try:
|
try:
|
||||||
server = HttpServerThread()
|
server = HttpServerThread()
|
||||||
port = server.start_server(args.port)
|
port = server.start_server(args.port)
|
||||||
with open(PORT_LOG, mode="w") as file:
|
with open(URL_LOG, mode="w", encoding="utf-8") as file:
|
||||||
file.write("{}".format(port))
|
file.write("127.0.0.1:{}".format(port))
|
||||||
|
tests = CertificateMaker(port, SERVER_LOG)
|
||||||
|
tests.make_certs()
|
||||||
except OSError as err:
|
except OSError as err:
|
||||||
print("OSError: {}".format(err))
|
print("OSError: {}".format(err))
|
||||||
ret = err.errno
|
ret = err.errno
|
||||||
|
except Exception as err: # pylint: disable=broad-except
|
||||||
|
print("Error: {}".format(err))
|
||||||
|
ret = 1
|
||||||
finally:
|
finally:
|
||||||
sys.exit(ret)
|
sys.exit(ret)
|
||||||
|
|
||||||
@@ -135,6 +146,9 @@ if __name__ == '__main__':
|
|||||||
fpid = os.fork()
|
fpid = os.fork()
|
||||||
if fpid > 0:
|
if fpid > 0:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
with open(SERVER_LOG, mode='w', encoding='utf-8') as log:
|
||||||
|
os.dup2(log.fileno(), sys.stdout.fileno())
|
||||||
|
os.dup2(log.fileno(), sys.stderr.fileno())
|
||||||
except OSError as ferr:
|
except OSError as ferr:
|
||||||
print("Fork #1 failed: {} {}".format(ferr.errno, ferr.strerror))
|
print("Fork #1 failed: {} {}".format(ferr.errno, ferr.strerror))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|||||||
+31
-17
@@ -1,11 +1,14 @@
|
|||||||
"""Windows: Implementation of a HTTP server"""
|
#!/usr/bin/python3
|
||||||
|
"""Windows: Implementation of an HTTP server"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
|
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
|
||||||
|
from make_certificates import CertificateMaker
|
||||||
|
|
||||||
RESULT_PATH = os.getcwd()
|
RESULT_PATH = os.getcwd()
|
||||||
FILES_PATH = os.path.join(RESULT_PATH, "./Testing/files/")
|
FILES_PATH = os.path.join(RESULT_PATH, "./Testing/files/")
|
||||||
@@ -13,19 +16,17 @@ CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
|
|||||||
CONF_PATH = os.path.join(RESULT_PATH, "./Testing/conf/")
|
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")
|
||||||
CACRL = os.path.join(CERTS_PATH, "./CACertCRL.der")
|
|
||||||
TSACRL = os.path.join(CERTS_PATH, "./TSACertCRL.der")
|
|
||||||
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")
|
||||||
PORT_LOG = os.path.join(LOGS_PATH, "./port.log")
|
URL_LOG = os.path.join(LOGS_PATH, "./url.log")
|
||||||
|
|
||||||
|
|
||||||
OPENSSL_TS = ["openssl", "ts",
|
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):
|
||||||
@@ -41,15 +42,17 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||||||
try:
|
try:
|
||||||
url = urlparse(self.path)
|
url = urlparse(self.path)
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header("Content-type", "application/crl")
|
self.send_header("Content-type", "application/pkix-crl")
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
resp_data = b''
|
resp_data = b''
|
||||||
# Read the file and send the contents
|
# Read the file and send the contents
|
||||||
if url.path == "/intermediateCA":
|
if url.path == "/intermediateCA":
|
||||||
with open(CACRL, 'rb') as file:
|
file_path = os.path.join(CERTS_PATH, "./CACertCRL.der")
|
||||||
|
with open(file_path, 'rb') as file:
|
||||||
resp_data = file.read()
|
resp_data = file.read()
|
||||||
if url.path == "/TSACA":
|
if url.path == "/TSACA":
|
||||||
with open(TSACRL, 'rb') as file:
|
file_path = os.path.join(CERTS_PATH, "./TSACertCRL.der")
|
||||||
|
with open(file_path, 'rb') as file:
|
||||||
resp_data = file.read()
|
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
|
||||||
@@ -62,8 +65,8 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||||||
url = urlparse(self.path)
|
url = urlparse(self.path)
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
if url.path == "/kill_server":
|
if url.path == "/kill_server":
|
||||||
self.log_message(f"Deleting file: {PORT_LOG}")
|
self.log_message(f"Deleting file: {URL_LOG}")
|
||||||
os.remove(f"{PORT_LOG}")
|
os.remove(f"{URL_LOG}")
|
||||||
self.send_header('Content-type', 'text/plain')
|
self.send_header('Content-type', 'text/plain')
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(bytes('Shutting down HTTP server', 'utf-8'))
|
self.wfile.write(bytes('Shutting down HTTP server', 'utf-8'))
|
||||||
@@ -79,7 +82,7 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
|||||||
self.send_header("Content-type", "application/timestamp-reply")
|
self.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
|
||||||
@@ -94,9 +97,9 @@ class HttpServerThread():
|
|||||||
self.server = None
|
self.server = None
|
||||||
self.server_thread = None
|
self.server_thread = None
|
||||||
|
|
||||||
def start_server(self) -> (int):
|
def start_server(self, port) -> (int):
|
||||||
"""Starting HTTP server on 127.0.0.1 and a random available port for binding"""
|
"""Starting HTTP server on 127.0.0.1 and a random available port for binding"""
|
||||||
self.server = ThreadingHTTPServer(('127.0.0.1', 19254), RequestHandler)
|
self.server = ThreadingHTTPServer(('127.0.0.1', port), RequestHandler)
|
||||||
self.server_thread = threading.Thread(target=self.server.serve_forever)
|
self.server_thread = threading.Thread(target=self.server.serve_forever)
|
||||||
self.server_thread.start()
|
self.server_thread.start()
|
||||||
hostname, port = self.server.server_address[:2]
|
hostname, port = self.server.server_address[:2]
|
||||||
@@ -106,14 +109,25 @@ class HttpServerThread():
|
|||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
"""Start HTTP server"""
|
"""Start HTTP server"""
|
||||||
|
|
||||||
ret = 0
|
ret = 0
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument(
|
||||||
|
"--port",
|
||||||
|
type=int,
|
||||||
|
default=0,
|
||||||
|
help="port number"
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
try:
|
try:
|
||||||
sys.stdout = open(SERVER_LOG, "w")
|
sys.stdout = open(SERVER_LOG, "w")
|
||||||
sys.stderr = open(SERVER_LOG, "a")
|
sys.stderr = open(SERVER_LOG, "a")
|
||||||
server = HttpServerThread()
|
server = HttpServerThread()
|
||||||
port = server.start_server()
|
port = server.start_server(args.port)
|
||||||
with open(PORT_LOG, mode="w") as file:
|
with open(URL_LOG, mode="w") as file:
|
||||||
file.write("{}".format(port))
|
file.write("127.0.0.1:{}".format(port))
|
||||||
|
tests = CertificateMaker(port, SERVER_LOG)
|
||||||
|
tests.make_certs()
|
||||||
except OSError as err:
|
except OSError as err:
|
||||||
print("OSError: {}".format(err))
|
print("OSError: {}".format(err))
|
||||||
ret = err.errno
|
ret = err.errno
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""Wait for all tests certificate, compute leafhash"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import binascii
|
||||||
|
import hashlib
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
import platform
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
RESULT_PATH = os.getcwd()
|
||||||
|
CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
|
||||||
|
LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/")
|
||||||
|
SERVER_LOG = os.path.join(LOGS_PATH, "./server.log")
|
||||||
|
if platform.system() == 'Windows':
|
||||||
|
DEFAULT_PYTHON = "C:/Program Files/Python/Python311/pythonw.exe"
|
||||||
|
DEFAULT_PROG = os.path.join(RESULT_PATH, "./Testing/server_http.pyw")
|
||||||
|
else:
|
||||||
|
DEFAULT_PYTHON = "/usr/bin/python3"
|
||||||
|
DEFAULT_PROG = os.path.join(RESULT_PATH, "./Testing/server_http.py")
|
||||||
|
|
||||||
|
|
||||||
|
def compute_sha256(file_name) -> str:
|
||||||
|
"""Compute a SHA256 hash of the leaf certificate (in DER form)"""
|
||||||
|
|
||||||
|
sha256_hash = hashlib.sha256()
|
||||||
|
file_path = os.path.join(CERTS_PATH, file_name)
|
||||||
|
with open(file_path, mode="rb") as file:
|
||||||
|
for bajt in iter(lambda: file.read(4096),b""):
|
||||||
|
sha256_hash.update(bajt)
|
||||||
|
return sha256_hash.hexdigest()
|
||||||
|
|
||||||
|
def clear_catalog(certs_path) -> None:
|
||||||
|
""""Clear a test certificates catalog."""
|
||||||
|
|
||||||
|
if os.path.exists(certs_path):
|
||||||
|
#Remove old test certificates
|
||||||
|
for root, _, files in os.walk(certs_path):
|
||||||
|
for file in files:
|
||||||
|
os.remove(os.path.join(root, file))
|
||||||
|
else:
|
||||||
|
os.mkdir(certs_path)
|
||||||
|
|
||||||
|
# Generate 16 random bytes and convert to hex
|
||||||
|
random_hex = binascii.b2a_hex(os.urandom(16)).decode()
|
||||||
|
serial = os.path.join(certs_path, "./tsa-serial")
|
||||||
|
with open(serial, mode="w", encoding="utf-8") as file:
|
||||||
|
file.write(random_hex)
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
"""Wait for all test certificates and compute leaf hash"""
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument(
|
||||||
|
"--exe",
|
||||||
|
type=pathlib.Path,
|
||||||
|
default=DEFAULT_PYTHON,
|
||||||
|
help=f"the path to the python3 executable to use"
|
||||||
|
f"(default: {DEFAULT_PYTHON})",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--script",
|
||||||
|
type=pathlib.Path,
|
||||||
|
default=DEFAULT_PROG,
|
||||||
|
help=f"the path to the python script to run"
|
||||||
|
f"(default: {DEFAULT_PROG})",
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
try:
|
||||||
|
clear_catalog(CERTS_PATH)
|
||||||
|
#pylint: disable=consider-using-with
|
||||||
|
subprocess.Popen([str(args.exe), str(args.script)])
|
||||||
|
|
||||||
|
cert_log = os.path.join(CERTS_PATH, "./cert.log")
|
||||||
|
while not (os.path.exists(cert_log) and os.path.getsize(cert_log) > 0):
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
leafhash = compute_sha256("cert.der")
|
||||||
|
file_path = os.path.join(CERTS_PATH, "./leafhash.txt")
|
||||||
|
with open(file_path, mode="w", encoding="utf-8") as file:
|
||||||
|
file.write("SHA256:{}".format(leafhash))
|
||||||
|
|
||||||
|
except OSError as err:
|
||||||
|
with open(SERVER_LOG, mode="w", encoding="utf-8") as file:
|
||||||
|
file.write("OSError: {}".format(err))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
except Exception as err: # pylint: disable=broad-except
|
||||||
|
with open(SERVER_LOG, mode="w", encoding="utf-8") as file:
|
||||||
|
file.write("Error: {}".format(err))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=pointless-string-statement
|
||||||
|
"""Local Variables:
|
||||||
|
c-basic-offset: 4
|
||||||
|
tab-width: 4
|
||||||
|
indent-tabs-mode: nil
|
||||||
|
End:
|
||||||
|
vim: set ts=4 expandtab:
|
||||||
|
"""
|
||||||
+1
-5
@@ -3,11 +3,7 @@
|
|||||||
"version-string": "2.4",
|
"version-string": "2.4",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"openssl",
|
"openssl",
|
||||||
"curl",
|
"zlib"
|
||||||
{
|
|
||||||
"name": "python3",
|
|
||||||
"platform": "!(windows & static) & !osx"
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"builtin-baseline": "9edb1b8e590cc086563301d735cae4b6e732d2d2"
|
"builtin-baseline": "9edb1b8e590cc086563301d735cae4b6e732d2d2"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user