mirror of
https://github.com/mtrojnar/osslsigncode.git
synced 2025-07-02 19:22:47 -05:00
Compare commits
188 Commits
Author | SHA1 | Date | |
---|---|---|---|
699bc85d0a | |||
192e7a732b | |||
656051676f | |||
3998bcabb2 | |||
fa40c57f80 | |||
0b93a94ffa | |||
105fd3af4a | |||
86a594b087 | |||
1dea73b038 | |||
b661ed08ed | |||
ead0584611 | |||
bd7751147e | |||
1bc7fc36b8 | |||
42e9733916 | |||
b2024cee9d | |||
9d152b8477 | |||
7a02d51a83 | |||
dac68a3a4d | |||
bd1ab77f44 | |||
5ee859db2c | |||
ee3c51f6d5 | |||
cedb8b5798 | |||
dcf58a00e7 | |||
4576895718 | |||
1bdcad619e | |||
31b046cf98 | |||
f3ac2c0c6f | |||
f22c83514c | |||
44ca1f38e6 | |||
0985c47990 | |||
aa158e40ec | |||
5da62de5ef | |||
4d08fbb2c1 | |||
98b004edda | |||
34bf3bc525 | |||
64e1bba96b | |||
46bcaa9d88 | |||
867e0d446d | |||
7285778cb0 | |||
c909ba82d7 | |||
7b60d6447d | |||
588a1a0b5f | |||
8a9b275494 | |||
0db17be606 | |||
f9ad19d4a2 | |||
b9ca24d423 | |||
8d2b562244 | |||
6f4e9ab597 | |||
6d6270094e | |||
57563716d1 | |||
8ab8a133f7 | |||
ef5047038e | |||
e290e03341 | |||
900ffed596 | |||
33253afb5e | |||
3aba55e5e0 | |||
898a53b2a7 | |||
75ce1dadf5 | |||
4166476030 | |||
a5690f2d19 | |||
cdb75578e9 | |||
e2ab4a152d | |||
b8e690f3bd | |||
c89d6b43aa | |||
9faed39931 | |||
ecb17709fc | |||
9ebd79ad18 | |||
1700455533 | |||
a6f767f5a3 | |||
4c5b329bc4 | |||
5626482e82 | |||
2d21a2121c | |||
5d2bf2c80f | |||
5b8376ce32 | |||
1fc2c937f2 | |||
2ed54490a6 | |||
a096aa8a33 | |||
aa08566a63 | |||
c04b229ce2 | |||
adcfd9a33f | |||
f2f3a8891c | |||
29eedf9059 | |||
d6f94d71f7 | |||
a509a66c65 | |||
7bf4c92d83 | |||
0a0fdfe96a | |||
199f2b4586 | |||
a92c4a5522 | |||
dc44ed5f5b | |||
c6990878c2 | |||
abbbfabdc7 | |||
2a4b75842a | |||
56e7a72e8a | |||
b61bcaac2e | |||
924af9e783 | |||
cb80c7d188 | |||
76bb06bf7e | |||
4b6027a4f7 | |||
de6a65cc67 | |||
c90166ba8d | |||
b00ceee310 | |||
54e61cb76a | |||
fb731f2b5e | |||
eec5a0755d | |||
41d98c3917 | |||
7fa0b21ddd | |||
e0eb331baf | |||
7bb21c3539 | |||
edcb18d63f | |||
3d7b8d2a21 | |||
7bfe3b5db9 | |||
dd365d68c4 | |||
09555e8c05 | |||
e4aa06f0c0 | |||
46e9ee447f | |||
3e7247d9dc | |||
d2f1b9c035 | |||
4199310cdf | |||
0204d04a25 | |||
246f0abbfc | |||
0f51a06b8f | |||
44a6768089 | |||
93f5f800d6 | |||
4db6ed0cad | |||
32b65659be | |||
8e74a05b40 | |||
83e47e0252 | |||
41e6042c26 | |||
33c1fdaa85 | |||
11eb76d4f3 | |||
b0391244a6 | |||
83f6ceeaea | |||
b96a7a2232 | |||
ff8034af2e | |||
bde67ec1e2 | |||
c5ad70d31a | |||
27a2a2bfa3 | |||
827f167f8b | |||
4098a5efc7 | |||
e88bc1ca14 | |||
dd2aaf0804 | |||
08113a08cb | |||
29843ccf40 | |||
5fef4faf47 | |||
5981c740c9 | |||
f3af509973 | |||
c29e14e697 | |||
4da5526c05 | |||
4ec23dbaa5 | |||
d9979c4bc6 | |||
695892b8bf | |||
192ff59916 | |||
506daf84ac | |||
bb6322e378 | |||
b0eaa96d45 | |||
fade782e58 | |||
199a852c12 | |||
95a8a9d9c1 | |||
c197d7727c | |||
efbe570f27 | |||
fef65536f6 | |||
1155a9c338 | |||
f67ca8aac5 | |||
d59601f2b9 | |||
7f87f930f7 | |||
dadca2516d | |||
a862378280 | |||
c4ec6debe5 | |||
08c205a02f | |||
acfece2c26 | |||
61cf89f26f | |||
07a927f34a | |||
257cb1fb08 | |||
c48a6cdef0 | |||
8bba4496c0 | |||
dfc13c9bf8 | |||
f57b469c29 | |||
c718882ffb | |||
3109bdf0ab | |||
7aca21b481 | |||
8c113b3a86 | |||
f3a5ecce9c | |||
1c678bf926 | |||
454e15326d | |||
db556d0a2d | |||
8bdd22c183 | |||
cc4e5a5076 | |||
b8cb44fa47 |
59
.github/workflows/ci.yml
vendored
59
.github/workflows/ci.yml
vendored
@ -7,7 +7,7 @@ on:
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: Release
|
||||
version: osslsigncode-2.5
|
||||
version: osslsigncode-2.8
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@ -27,12 +27,6 @@ jobs:
|
||||
os: ubuntu-20.04
|
||||
generator: Unix Makefiles
|
||||
vcpkg_root:
|
||||
- id: ubuntu-18.04
|
||||
triplet: x64-linux
|
||||
compiler: gcc
|
||||
os: ubuntu-18.04
|
||||
generator: Unix Makefiles
|
||||
vcpkg_root:
|
||||
- id: macOS
|
||||
triplet: x64-osx
|
||||
compiler: clang
|
||||
@ -96,9 +90,33 @@ jobs:
|
||||
with:
|
||||
arch: ${{matrix.arch}}
|
||||
|
||||
- name: Install MSYS2
|
||||
if: matrix.compiler == 'mingw'
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
update: true
|
||||
install: mingw-w64-x86_64-ninja
|
||||
|
||||
- name: Put MSYS2_MinGW64 on PATH
|
||||
if: matrix.compiler == 'mingw'
|
||||
run: echo "D:/a/_temp/msys64/mingw64/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
|
||||
- name: Install apt dependencies (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: sudo apt-get install -y libssl-dev libcurl4-openssl-dev faketime
|
||||
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'
|
||||
run: |
|
||||
brew install python@3.8
|
||||
|
||||
- name: Install Xcode (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: latest-stable
|
||||
|
||||
- name: Setup the oldest supported version of cmake (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
@ -123,6 +141,25 @@ jobs:
|
||||
--build ${{github.workspace}}/build
|
||||
--config ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Start HTTP server (macOS)
|
||||
working-directory: ${{github.workspace}}/build
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
python3.8 --version
|
||||
python3.8 ./Testing/server_http.py --port 19254
|
||||
while test ! -s ./Testing/logs/port.log; do sleep 1; done
|
||||
|
||||
- name: Start HTTP server (Windows)
|
||||
working-directory: ${{github.workspace}}\build
|
||||
if: runner.os == 'Windows'
|
||||
run: |
|
||||
python.exe --version
|
||||
$Args = '.\Testing\server_http.pyw --port 19254'
|
||||
$File = '.\Testing\logs\port.log'
|
||||
Start-Process -FilePath pythonw.exe -ArgumentList $Args
|
||||
while(-not(Test-Path -Path $File -PathType Leaf) -or [String]::IsNullOrWhiteSpace((Get-Content $File))) {Start-Sleep -Seconds 1}
|
||||
Get-Content '.\Testing\logs\server.log'
|
||||
|
||||
- name: List files (Linux/macOS)
|
||||
if: runner.os != 'Windows'
|
||||
run: find .. -ls
|
||||
@ -140,7 +177,11 @@ jobs:
|
||||
if: failure()
|
||||
with:
|
||||
name: errors-${{matrix.id}}
|
||||
path: ${{github.workspace}}/build/Testing/Temporary/LastTest.log
|
||||
path: |
|
||||
${{github.workspace}}/build/Testing/Temporary/LastTest.log
|
||||
${{github.workspace}}/build/Testing/conf/makecerts.log
|
||||
${{github.workspace}}/build/Testing/logs/server.log
|
||||
${{github.workspace}}/build/Testing/logs/port.log
|
||||
|
||||
- name: Install
|
||||
run: cmake --install ${{github.workspace}}/build
|
||||
|
3
.github/workflows/coverity.yml
vendored
3
.github/workflows/coverity.yml
vendored
@ -2,7 +2,7 @@ name: Coverity Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
coverity:
|
||||
@ -15,6 +15,7 @@ jobs:
|
||||
- name: Get ready for scanning
|
||||
if: env.token
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libssl-dev libcurl4-openssl-dev
|
||||
cmake -S ${{github.workspace}} -B ${{github.workspace}}/build
|
||||
- uses: vapier/coverity-scan-action@v1
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,7 +12,6 @@ CPackSourceConfig.cmake
|
||||
CTestTestfile.cmake
|
||||
install_manifest.txt
|
||||
Makefile
|
||||
missing
|
||||
osslsigncode
|
||||
osslsigncode.exe
|
||||
stamp-h1
|
||||
|
@ -4,16 +4,16 @@ cmake_minimum_required(VERSION 3.17)
|
||||
# autodetect vcpkg CMAKE_TOOLCHAIN_FILE if VCPKG_ROOT is defined
|
||||
# this needs to be configured before the project() directive
|
||||
if(DEFINED ENV{VCPKG_ROOT} AND NOT $ENV{VCPKG_ROOT} STREQUAL "" AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
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)
|
||||
set(BUILTIN_SOCKET ON CACHE BOOL "") # for static Python
|
||||
|
||||
# configure basic project information
|
||||
project(osslsigncode
|
||||
VERSION 2.5
|
||||
DESCRIPTION "OpenSSL based Authenticode signing for PE, CAB, CAT and MSI files"
|
||||
HOMEPAGE_URL "https://github.com/mtrojnar/osslsigncode"
|
||||
LANGUAGES C)
|
||||
VERSION 2.8
|
||||
DESCRIPTION "OpenSSL based Authenticode signing for PE, CAB, CAT and MSI files"
|
||||
HOMEPAGE_URL "https://github.com/mtrojnar/osslsigncode"
|
||||
LANGUAGES C)
|
||||
|
||||
# force nonstandard version format for development packages
|
||||
set(DEV "")
|
||||
@ -30,6 +30,7 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
# load CMake library modules
|
||||
include(FindOpenSSL)
|
||||
include(FindCURL)
|
||||
include(FindZLIB)
|
||||
|
||||
# load CMake project modules
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake")
|
||||
@ -47,9 +48,9 @@ configure_file(Config.h.in config.h)
|
||||
target_compile_definitions(osslsigncode PRIVATE HAVE_CONFIG_H=1)
|
||||
|
||||
# set sources
|
||||
target_sources(osslsigncode PRIVATE osslsigncode.c msi.c)
|
||||
target_sources(osslsigncode PRIVATE osslsigncode.c helpers.c utf.c msi.c pe.c cab.c cat.c appx.c script.c)
|
||||
if(NOT UNIX)
|
||||
target_sources(osslsigncode PRIVATE applink.c)
|
||||
target_sources(osslsigncode PRIVATE applink.c)
|
||||
endif(NOT UNIX)
|
||||
|
||||
# set include directories
|
||||
@ -57,21 +58,27 @@ target_include_directories(osslsigncode PRIVATE "${PROJECT_BINARY_DIR}")
|
||||
|
||||
# set OpenSSL includes/libraries
|
||||
if(NOT OPENSSL_FOUND)
|
||||
message(FATAL_ERROR "OpenSSL library not found")
|
||||
message(FATAL_ERROR "OpenSSL library not found")
|
||||
endif(NOT OPENSSL_FOUND)
|
||||
target_include_directories(osslsigncode PRIVATE ${OPENSSL_INCLUDE_DIR})
|
||||
target_link_libraries(osslsigncode PRIVATE ${OPENSSL_LIBRARIES})
|
||||
|
||||
# set cURL includes/libraries
|
||||
if(CURL_FOUND)
|
||||
target_compile_definitions(osslsigncode PRIVATE ENABLE_CURL=1)
|
||||
target_include_directories(osslsigncode PRIVATE ${CURL_INCLUDE_DIRS})
|
||||
target_link_libraries(osslsigncode PRIVATE ${CURL_LIBRARIES})
|
||||
message(STATUS "cURL support enabled")
|
||||
target_compile_definitions(osslsigncode PRIVATE ENABLE_CURL=1)
|
||||
target_include_directories(osslsigncode PRIVATE ${CURL_INCLUDE_DIRS})
|
||||
target_link_libraries(osslsigncode PRIVATE ${CURL_LIBRARIES})
|
||||
message(STATUS "cURL support enabled")
|
||||
else(CURL_FOUND)
|
||||
message(STATUS "cURL support disabled (library not found)")
|
||||
message(STATUS "cURL support disabled (library not found)")
|
||||
endif(CURL_FOUND)
|
||||
|
||||
if(NOT ZLIB_FOUND)
|
||||
message(FATAL_ERROR "Zlib library not found")
|
||||
endif(NOT ZLIB_FOUND)
|
||||
target_include_directories(osslsigncode PRIVATE ${ZLIB_INCLUDE_DIR})
|
||||
target_link_libraries(osslsigncode PRIVATE ${ZLIB_LIBRARIES})
|
||||
|
||||
# add paths to linker search and installed rpath
|
||||
set_target_properties(osslsigncode PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
@ -82,14 +89,22 @@ include(CMakeTest)
|
||||
set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin")
|
||||
install(TARGETS osslsigncode RUNTIME DESTINATION ${BINDIR})
|
||||
if(UNIX)
|
||||
include(CMakeDist)
|
||||
include(CMakeDist)
|
||||
else(UNIX)
|
||||
install(
|
||||
DIRECTORY ${PROJECT_BINARY_DIR}/ DESTINATION ${BINDIR}
|
||||
FILES_MATCHING
|
||||
PATTERN "*.dll"
|
||||
PATTERN "vcpkg_installed" EXCLUDE
|
||||
PATTERN "CMakeFiles" EXCLUDE
|
||||
PATTERN "Testing" EXCLUDE
|
||||
)
|
||||
install(
|
||||
DIRECTORY ${PROJECT_BINARY_DIR}/ DESTINATION ${BINDIR}
|
||||
FILES_MATCHING
|
||||
PATTERN "*.dll"
|
||||
PATTERN "vcpkg_installed" EXCLUDE
|
||||
PATTERN "CMakeFiles" EXCLUDE
|
||||
PATTERN "Testing" EXCLUDE)
|
||||
endif(UNIX)
|
||||
|
||||
#[[
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
]]
|
||||
|
32
Dockerfile
Normal file
32
Dockerfile
Normal file
@ -0,0 +1,32 @@
|
||||
# Stage 1: Build osslsigncode on Alpine
|
||||
FROM alpine:latest AS builder
|
||||
|
||||
# Install build dependencies
|
||||
RUN apk add --no-cache build-base cmake openssl-dev curl-dev
|
||||
|
||||
# Copy osslsigncode source code into the image
|
||||
COPY . /source
|
||||
|
||||
# Build osslsigncode
|
||||
RUN cd /source && \
|
||||
mkdir -p build && \
|
||||
cd build && \
|
||||
rm -f CMakeCache.txt && \
|
||||
cmake -S .. && \
|
||||
cmake --build . && \
|
||||
cmake --install .
|
||||
|
||||
# Stage 2: Create final image without build environment
|
||||
FROM alpine:latest
|
||||
|
||||
# Copy compiled binary from builder stage
|
||||
COPY --from=builder /usr/local/bin/osslsigncode /usr/local/bin/osslsigncode
|
||||
|
||||
# Install necessary runtime libraries (latest version)
|
||||
RUN apk add --no-cache libcrypto3 libcurl
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /workdir
|
||||
|
||||
# Declare volume to mount files
|
||||
VOLUME [ "/workdir" ]
|
@ -12,7 +12,7 @@
|
||||
2) Run "MSYS2 MinGW 64-bit" and build 64-bit Windows executables.
|
||||
```
|
||||
cd osslsigncode-folder
|
||||
x86_64-w64-mingw32-gcc osslsigncode.c msi.c -o osslsigncode.exe \
|
||||
x86_64-w64-mingw32-gcc *.c -o osslsigncode.exe \
|
||||
-lcrypto -lssl -lcurl \
|
||||
-D 'PACKAGE_STRING="osslsigncode x.y"' \
|
||||
-D 'PACKAGE_BUGREPORT="Your.Email@example.com"' \
|
||||
@ -71,7 +71,7 @@
|
||||
3) Build 64-bit Windows executables.
|
||||
```
|
||||
cd osslsigncode-folder
|
||||
x86_64-w64-mingw32-gcc osslsigncode.c msi.c -o osslsigncode.exe \
|
||||
x86_64-w64-mingw32-gcc *.c -o osslsigncode.exe \
|
||||
-L 'C:/OpenSSL/lib/' -lcrypto -lssl \
|
||||
-I 'C:/OpenSSL/include/' \
|
||||
-L 'C:/curl/lib' -lcurl \
|
||||
|
39
NEWS.md
39
NEWS.md
@ -1,5 +1,44 @@
|
||||
# osslsigncode change log
|
||||
|
||||
### 2.8 (2024.03.03)
|
||||
|
||||
- Microsoft PowerShell signing sponsored by Cisco Systems, Inc.
|
||||
- fixed setting unauthenticated attributes (Countersignature, Unauthenticated
|
||||
Data Blob) in a nested signature
|
||||
- added the "-index" option to verify a specific signature or modify its
|
||||
unauthenticated attributes
|
||||
- added CAT file verification
|
||||
- added listing the contents of a CAT file with the "-verbose" option
|
||||
- added the new "extract-data" command to extract a PKCS#7 data content to be
|
||||
signed with "sign" and attached with "attach-signature"
|
||||
- added PKCS9_SEQUENCE_NUMBER authenticated attribute support
|
||||
- added the "-ignore-cdp" option to disable CRL Distribution Points (CDP)
|
||||
online verification
|
||||
- unsuccessful CRL retrieval and verification changed into a critical error
|
||||
- the "-p" option modified to also use to configured proxy to connect CRL
|
||||
Distribution Points
|
||||
- added implicit allowlisting of the Microsoft Root Authority serial number
|
||||
00C1008B3C3C8811D13EF663ECDF40
|
||||
- added listing of certificate chain retrieved from the signature in case of
|
||||
verification failure
|
||||
|
||||
### 2.7 (2023.09.19)
|
||||
|
||||
- fixed signing CAB files (by Michael Brown)
|
||||
- fixed handling of unsupported commands (by Maxim Bagryantsev)
|
||||
- fixed writing DIFAT sectors
|
||||
- added APPX support (by Maciej Panek and Małgorzata Olszówka)
|
||||
- added a built-in TSA response generation (-TSA-certs, -TSA-key
|
||||
and -TSA-time options)
|
||||
|
||||
### 2.6 (2023.05.29)
|
||||
|
||||
- modular architecture implemented to simplify adding file formats
|
||||
- added verification of CRLs specified in the signing certificate
|
||||
- added MSI DIFAT sectors support (by Max Bagryantsev)
|
||||
- added legacy provider support for OpenSSL 3.0.0 and later
|
||||
- fixed numerous bugs
|
||||
|
||||
### 2.5 (2022.08.12)
|
||||
|
||||
- fixed the Unix executable install path
|
||||
|
11
README.md
11
README.md
@ -39,14 +39,14 @@ We highly recommend downloading a [release tarball](https://github.com/mtrojnar/
|
||||
|
||||
* Install prerequisites on a Debian-based distributions, such as Ubuntu:
|
||||
```
|
||||
sudo apt update && sudo apt install cmake libssl-dev libcurl4-openssl-dev
|
||||
sudo apt update && sudo apt install cmake libssl-dev libcurl4-openssl-dev zlib1g-dev python3
|
||||
```
|
||||
* Install prerequisites on macOS with Homebrew:
|
||||
```
|
||||
brew install cmake pkg-config openssl@1.1
|
||||
export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"
|
||||
```
|
||||
**NOTE:** osslsigncode requires CMake 3.6 or newer.
|
||||
**NOTE:** osslsigncode requires CMake 3.17 or newer.
|
||||
|
||||
You may need to use `cmake3` instead of `cmake` to complete the following steps on your system.
|
||||
* Navigate to the build directory and run CMake to configure the osslsigncode project
|
||||
@ -54,12 +54,13 @@ You may need to use `cmake3` instead of `cmake` to complete the following steps
|
||||
```
|
||||
mkdir build && cd build && cmake -S ..
|
||||
```
|
||||
with specific compile options:
|
||||
optional CMake parameters:
|
||||
```
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DCMAKE_C_COMPILER=clang
|
||||
-DCMAKE_PREFIX_PATH=[openssl directory];[curl directory]
|
||||
-DCMAKE_INSTALL_PREFIX=[installation directory]
|
||||
-DBASH_COMPLETION_USER_DIR=[bash completion installation directory]
|
||||
|
||||
```
|
||||
* Then call that build system to actually compile/link the osslsigncode project (alias `make`):
|
||||
@ -180,9 +181,7 @@ in the unauthenticated blob, as an attacker could modify this. Do NOT, under
|
||||
any circumstances, put a URL here that you will use to download an additional
|
||||
file. If you do do that, you would need to check the newly downloaded file is
|
||||
code signed AND that it has been signed with your cert AND that it is the
|
||||
version you expect. You should consider using asymmetrical encryption for the
|
||||
data you put in the blob, such that the executable contains the public key to
|
||||
decrypt the data. Basically, be VERY careful.
|
||||
version you expect.
|
||||
|
||||
## BUGS, QUESTIONS etc.
|
||||
|
||||
|
977
cab.c
Normal file
977
cab.c
Normal file
@ -0,0 +1,977 @@
|
||||
/*
|
||||
* CAB file support library
|
||||
*
|
||||
* Copyright (C) 2021-2023 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
* Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
|
||||
*
|
||||
* Reference specifications:
|
||||
* https://www.file-recovery.com/cab-signature-format.htm
|
||||
* https://learn.microsoft.com/en-us/previous-versions/ms974336(v=msdn.10)
|
||||
*/
|
||||
|
||||
#include "osslsigncode.h"
|
||||
#include "helpers.h"
|
||||
|
||||
/*
|
||||
* FLAG_PREV_CABINET is set if the cabinet file is not the first in a set
|
||||
* of cabinet files. When this bit is set, the szCabinetPrev and szDiskPrev
|
||||
* fields are present in this CFHEADER.
|
||||
*/
|
||||
#define FLAG_PREV_CABINET 0x0001
|
||||
/*
|
||||
* FLAG_NEXT_CABINET is set if the cabinet file is not the last in a set of
|
||||
* cabinet files. When this bit is set, the szCabinetNext and szDiskNext
|
||||
* fields are present in this CFHEADER.
|
||||
*/
|
||||
#define FLAG_NEXT_CABINET 0x0002
|
||||
/*
|
||||
* FLAG_RESERVE_PRESENT is set if the cabinet file contains any reserved
|
||||
* fields. When this bit is set, the cbCFHeader, cbCFFolder, and cbCFData
|
||||
* fields are present in this CFHEADER.
|
||||
*/
|
||||
#define FLAG_RESERVE_PRESENT 0x0004
|
||||
|
||||
|
||||
struct cab_ctx_st {
|
||||
uint32_t header_size;
|
||||
uint32_t sigpos;
|
||||
uint32_t siglen;
|
||||
uint32_t fileend;
|
||||
uint16_t flags;
|
||||
};
|
||||
|
||||
/* FILE_FORMAT method prototypes */
|
||||
static FILE_FORMAT_CTX *cab_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *outdata);
|
||||
static ASN1_OBJECT *cab_obsolete_link_get(u_char **p, int *plen, FILE_FORMAT_CTX *ctx);
|
||||
static PKCS7 *cab_pkcs7_contents_get(FILE_FORMAT_CTX *ctx, BIO *hash, const EVP_MD *md);
|
||||
static int cab_hash_length_get(FILE_FORMAT_CTX *ctx);
|
||||
static u_char *cab_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md);
|
||||
static int cab_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7);
|
||||
static PKCS7 *cab_pkcs7_extract(FILE_FORMAT_CTX *ctx);
|
||||
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_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
|
||||
static PKCS7 *cab_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash);
|
||||
static int cab_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7);
|
||||
static void cab_update_data_size(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7);
|
||||
static void cab_bio_free(BIO *hash, BIO *outdata);
|
||||
static void cab_ctx_cleanup(FILE_FORMAT_CTX *ctx);
|
||||
static int cab_is_detaching_supported(void);
|
||||
|
||||
FILE_FORMAT file_format_cab = {
|
||||
.ctx_new = cab_ctx_new,
|
||||
.data_blob_get = cab_obsolete_link_get,
|
||||
.pkcs7_contents_get = cab_pkcs7_contents_get,
|
||||
.hash_length_get = cab_hash_length_get,
|
||||
.digest_calc = cab_digest_calc,
|
||||
.verify_digests = cab_verify_digests,
|
||||
.pkcs7_extract = cab_pkcs7_extract,
|
||||
.pkcs7_extract_to_nest = cab_pkcs7_extract_to_nest,
|
||||
.remove_pkcs7 = cab_remove_pkcs7,
|
||||
.process_data = cab_process_data,
|
||||
.pkcs7_signature_new = cab_pkcs7_signature_new,
|
||||
.append_pkcs7 = cab_append_pkcs7,
|
||||
.update_data_size = cab_update_data_size,
|
||||
.bio_free = cab_bio_free,
|
||||
.ctx_cleanup = cab_ctx_cleanup,
|
||||
.is_detaching_supported = cab_is_detaching_supported
|
||||
};
|
||||
|
||||
/* Prototypes */
|
||||
static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize);
|
||||
static int cab_add_jp_attribute(PKCS7 *p7, int jp);
|
||||
static size_t cab_write_optional_names(BIO *outdata, char *indata, size_t len, uint16_t flags);
|
||||
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_check_file(FILE_FORMAT_CTX *ctx);
|
||||
|
||||
/*
|
||||
* FILE_FORMAT method definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Allocate and return a CAB file format context.
|
||||
* [in, out] options: structure holds the input data
|
||||
* [out] hash: message digest BIO
|
||||
* [in] outdata: outdata file BIO
|
||||
* [returns] pointer to CAB file format context
|
||||
*/
|
||||
static FILE_FORMAT_CTX *cab_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *outdata)
|
||||
{
|
||||
FILE_FORMAT_CTX *ctx;
|
||||
CAB_CTX *cab_ctx;
|
||||
uint32_t filesize;
|
||||
|
||||
filesize = get_file_size(options->infile);
|
||||
if (filesize == 0)
|
||||
return NULL; /* FAILED */
|
||||
|
||||
options->indata = map_file(options->infile, filesize);
|
||||
if (!options->indata) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (memcmp(options->indata, "MSCF", 4)) {
|
||||
unmap_file(options->indata, filesize);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
cab_ctx = cab_ctx_get(options->indata, filesize);
|
||||
if (!cab_ctx) {
|
||||
unmap_file(options->indata, filesize);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
ctx = OPENSSL_malloc(sizeof(FILE_FORMAT_CTX));
|
||||
ctx->format = &file_format_cab;
|
||||
ctx->options = options;
|
||||
ctx->cab_ctx = cab_ctx;
|
||||
|
||||
/* Push hash on outdata, if hash is NULL the function does nothing */
|
||||
BIO_push(hash, outdata);
|
||||
|
||||
if (options->pagehash == 1)
|
||||
printf("Warning: -ph option is only valid for PE files\n");
|
||||
if (options->add_msi_dse == 1)
|
||||
printf("Warning: -add-msi-dse option is only valid for MSI files\n");
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and return SpcLink object.
|
||||
* [out] p: SpcLink data
|
||||
* [out] plen: SpcLink data length
|
||||
* [in] ctx: structure holds input and output data (unused)
|
||||
* [returns] pointer to ASN1_OBJECT structure corresponding to SPC_CAB_DATA_OBJID
|
||||
*/
|
||||
static ASN1_OBJECT *cab_obsolete_link_get(u_char **p, int *plen, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
ASN1_OBJECT *dtype;
|
||||
SpcLink *link = spc_link_obsolete_get();
|
||||
|
||||
/* squash the unused parameter warning */
|
||||
(void)ctx;
|
||||
|
||||
*plen = i2d_SpcLink(link, NULL);
|
||||
*p = OPENSSL_malloc((size_t)*plen);
|
||||
i2d_SpcLink(link, p);
|
||||
*p -= *plen;
|
||||
dtype = OBJ_txt2obj(SPC_CAB_DATA_OBJID, 1);
|
||||
SpcLink_free(link);
|
||||
return dtype; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and return a data content to be signed.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] hash: message digest BIO
|
||||
* [in] md: message digest algorithm
|
||||
* [returns] data content
|
||||
*/
|
||||
static PKCS7 *cab_pkcs7_contents_get(FILE_FORMAT_CTX *ctx, BIO *hash, const EVP_MD *md)
|
||||
{
|
||||
ASN1_OCTET_STRING *content;
|
||||
|
||||
/* squash the unused parameter warning, use initialized message digest BIO */
|
||||
(void)md;
|
||||
|
||||
/* Strip current signature and modify header */
|
||||
if (ctx->cab_ctx->header_size == 20) {
|
||||
if (!cab_modify_header(ctx, hash, NULL))
|
||||
return NULL; /* FAILED */
|
||||
} else {
|
||||
if (!cab_add_header(ctx, hash, NULL))
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
content = spc_indirect_data_content_get(hash, ctx);
|
||||
return pkcs7_set_content(content);
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] the size of the message digest when passed an EVP_MD structure (the size of the hash)
|
||||
*/
|
||||
static int cab_hash_length_get(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
return EVP_MD_size(ctx->options->md);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute a message digest value of the signed or unsigned CAB file.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] md: message digest algorithm
|
||||
* [returns] pointer to calculated message digest
|
||||
*/
|
||||
static u_char *cab_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
|
||||
{
|
||||
uint32_t idx, fileend, coffFiles;
|
||||
u_char *mdbuf = NULL;
|
||||
BIO *bhash = BIO_new(BIO_f_md());
|
||||
|
||||
if (!BIO_set_md(bhash, md)) {
|
||||
printf("Unable to set the message digest of BIO\n");
|
||||
BIO_free_all(bhash);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
BIO_push(bhash, BIO_new(BIO_s_null()));
|
||||
|
||||
/* u1 signature[4] 4643534D MSCF: 0-3 */
|
||||
BIO_write(bhash, ctx->options->indata, 4);
|
||||
/* u4 reserved1 00000000: 4-7 skipped */
|
||||
if (ctx->cab_ctx->sigpos) {
|
||||
uint16_t nfolders, flags;
|
||||
|
||||
/*
|
||||
* u4 cbCabinet - size of this cabinet file in bytes: 8-11
|
||||
* u4 reserved2 00000000: 12-15
|
||||
*/
|
||||
BIO_write(bhash, ctx->options->indata + 8, 8);
|
||||
/* u4 coffFiles - offset of the first CFFILE entry: 16-19 */
|
||||
coffFiles = GET_UINT32_LE(ctx->options->indata + 16);
|
||||
BIO_write(bhash, ctx->options->indata + 16, 4);
|
||||
/*
|
||||
* u4 reserved3 00000000: 20-23
|
||||
* u1 versionMinor 03: 24
|
||||
* u1 versionMajor 01: 25
|
||||
*/
|
||||
BIO_write(bhash, ctx->options->indata + 20, 6);
|
||||
/* u2 cFolders - number of CFFOLDER entries in this cabinet: 26-27 */
|
||||
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
|
||||
BIO_write(bhash, ctx->options->indata + 26, 2);
|
||||
/* u2 cFiles - number of CFFILE entries in this cabinet: 28-29 */
|
||||
BIO_write(bhash, ctx->options->indata + 28, 2);
|
||||
/* u2 flags: 30-31 */
|
||||
flags = GET_UINT16_LE(ctx->options->indata + 30);
|
||||
BIO_write(bhash, ctx->options->indata + 30, 2);
|
||||
/* u2 setID must be the same for all cabinets in a set: 32-33 */
|
||||
BIO_write(bhash, ctx->options->indata + 32, 2);
|
||||
/*
|
||||
* u2 iCabinet - number of this cabinet file in a set: 34-35 skipped
|
||||
* u2 cbCFHeader: 36-37 skipped
|
||||
* u1 cbCFFolder: 38 skipped
|
||||
* u1 cbCFData: 39 skipped
|
||||
* u22 abReserve: 40-55 skipped
|
||||
* - Additional data offset: 44-47 skipped
|
||||
* - Additional data size: 48-51 skipped
|
||||
*/
|
||||
/* u22 abReserve: 56-59 */
|
||||
BIO_write(bhash, ctx->options->indata + 56, 4);
|
||||
idx = 60;
|
||||
fileend = ctx->cab_ctx->sigpos;
|
||||
/* TODO */
|
||||
if (flags & FLAG_PREV_CABINET) {
|
||||
uint8_t byte;
|
||||
/* szCabinetPrev */
|
||||
do {
|
||||
byte = GET_UINT8_LE(ctx->options->indata + idx);
|
||||
BIO_write(bhash, ctx->options->indata + idx, 1);
|
||||
idx++;
|
||||
} while (byte && idx < fileend);
|
||||
/* szDiskPrev */
|
||||
do {
|
||||
byte = GET_UINT8_LE(ctx->options->indata + idx);
|
||||
BIO_write(bhash, ctx->options->indata + idx, 1);
|
||||
idx++;
|
||||
} while (byte && idx < fileend);
|
||||
}
|
||||
if (flags & FLAG_NEXT_CABINET) {
|
||||
uint8_t byte;
|
||||
/* szCabinetNext */
|
||||
do {
|
||||
byte = GET_UINT8_LE(ctx->options->indata + idx);
|
||||
BIO_write(bhash, ctx->options->indata + idx, 1);
|
||||
idx++;
|
||||
} while (byte && idx < fileend);
|
||||
/* szDiskNext */
|
||||
do {
|
||||
byte = GET_UINT8_LE(ctx->options->indata + idx);
|
||||
BIO_write(bhash, ctx->options->indata + idx, 1);
|
||||
idx++;
|
||||
} while (byte && idx < fileend);
|
||||
}
|
||||
/*
|
||||
* (u8 * cFolders) CFFOLDER - structure contains information about
|
||||
* one of the folders or partial folders stored in this cabinet file
|
||||
*/
|
||||
while (nfolders && idx < fileend) {
|
||||
BIO_write(bhash, ctx->options->indata + idx, 8);
|
||||
idx += 8;
|
||||
nfolders--;
|
||||
}
|
||||
if (idx != coffFiles) {
|
||||
printf("Corrupt coffFiles value: 0x%08X\n", coffFiles);
|
||||
BIO_free_all(bhash);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
} else {
|
||||
/* read what's left of the unsigned CAB file */
|
||||
idx = 8;
|
||||
fileend = ctx->cab_ctx->fileend;
|
||||
}
|
||||
/* (variable) ab - the compressed data bytes */
|
||||
if (!bio_hash_data(bhash, ctx->options->indata, idx, fileend)) {
|
||||
printf("Unable to calculate digest\n");
|
||||
BIO_free_all(bhash);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
mdbuf = OPENSSL_malloc((size_t)EVP_MD_size(md));
|
||||
BIO_gets(bhash, (char*)mdbuf, EVP_MD_size(md));
|
||||
BIO_free_all(bhash);
|
||||
return mdbuf; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate message digest and compare to value retrieved from PKCS#7 signedData.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cab_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
||||
{
|
||||
int mdtype = -1;
|
||||
const EVP_MD *md;
|
||||
u_char mdbuf[EVP_MAX_MD_SIZE];
|
||||
u_char *cmdbuf;
|
||||
|
||||
if (is_content_type(p7, SPC_INDIRECT_DATA_OBJID)) {
|
||||
ASN1_STRING *content_val = p7->d.sign->contents->d.other->value.sequence;
|
||||
const u_char *p = content_val->data;
|
||||
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, content_val->length);
|
||||
if (idc) {
|
||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
||||
}
|
||||
SpcIndirectDataContent_free(idc);
|
||||
}
|
||||
}
|
||||
if (mdtype == -1) {
|
||||
printf("Failed to extract current message digest\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
md = EVP_get_digestbynid(mdtype);
|
||||
cmdbuf = cab_digest_calc(ctx, md);
|
||||
if (!cmdbuf) {
|
||||
printf("Failed to calculate message digest\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
|
||||
printf("Signature verification: failed\n\n");
|
||||
OPENSSL_free(cmdbuf);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
OPENSSL_free(cmdbuf);
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract existing signature in DER format.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *cab_pkcs7_extract(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
const u_char *blob;
|
||||
|
||||
if (!cab_check_file(ctx)) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
blob = (u_char *)ctx->options->indata + ctx->cab_ctx->sigpos;
|
||||
return d2i_PKCS7(NULL, &blob, ctx->cab_ctx->siglen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract existing signature in DER format.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *cab_pkcs7_extract_to_nest(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
return cab_pkcs7_extract(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove existing signature.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO (unused)
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int cab_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
||||
{
|
||||
size_t i, written, len;
|
||||
uint32_t tmp;
|
||||
uint16_t nfolders, flags;
|
||||
char *buf;
|
||||
|
||||
/* squash the unused parameter warning */
|
||||
(void)hash;
|
||||
|
||||
if (!cab_check_file(ctx)) {
|
||||
return 1; /* FAILED, no signature */
|
||||
}
|
||||
buf = OPENSSL_malloc(SIZE_64K);
|
||||
/*
|
||||
* u1 signature[4] 4643534D MSCF: 0-3
|
||||
* u4 reserved1 00000000: 4-7
|
||||
*/
|
||||
BIO_write(outdata, ctx->options->indata, 8);
|
||||
/* u4 cbCabinet - size of this cabinet file in bytes: 8-11 */
|
||||
tmp = GET_UINT32_LE(ctx->options->indata + 8) - 24;
|
||||
PUT_UINT32_LE(tmp, buf);
|
||||
BIO_write(outdata, buf, 4);
|
||||
/* u4 reserved2 00000000: 12-15 */
|
||||
BIO_write(outdata, ctx->options->indata + 12, 4);
|
||||
/* u4 coffFiles - offset of the first CFFILE entry: 16-19 */
|
||||
tmp = GET_UINT32_LE(ctx->options->indata + 16) - 24;
|
||||
PUT_UINT32_LE(tmp, buf);
|
||||
BIO_write(outdata, buf, 4);
|
||||
/*
|
||||
* u4 reserved3 00000000: 20-23
|
||||
* u1 versionMinor 03: 24
|
||||
* u1 versionMajor 01: 25
|
||||
* u2 cFolders - number of CFFOLDER entries in this cabinet: 26-27
|
||||
* u2 cFiles - number of CFFILE entries in this cabinet: 28-29
|
||||
*/
|
||||
BIO_write(outdata, ctx->options->indata + 20, 10);
|
||||
/* u2 flags: 30-31 */
|
||||
flags = GET_UINT16_LE(ctx->options->indata + 30);
|
||||
/* coverity[result_independent_of_operands] only least significant byte is affected */
|
||||
PUT_UINT16_LE(flags & (FLAG_PREV_CABINET | FLAG_NEXT_CABINET), buf);
|
||||
BIO_write(outdata, buf, 2);
|
||||
/*
|
||||
* u2 setID must be the same for all cabinets in a set: 32-33
|
||||
* u2 iCabinet - number of this cabinet file in a set: 34-35
|
||||
*/
|
||||
BIO_write(outdata, ctx->options->indata + 32, 4);
|
||||
i = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
|
||||
/*
|
||||
* (u8 * cFolders) CFFOLDER - structure contains information about
|
||||
* one of the folders or partial folders stored in this cabinet file
|
||||
*/
|
||||
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
|
||||
while (nfolders) {
|
||||
tmp = GET_UINT32_LE(ctx->options->indata + i);
|
||||
tmp -= 24;
|
||||
PUT_UINT32_LE(tmp, buf);
|
||||
BIO_write(outdata, buf, 4);
|
||||
BIO_write(outdata, ctx->options->indata + i + 4, 4);
|
||||
i+=8;
|
||||
nfolders--;
|
||||
}
|
||||
OPENSSL_free(buf);
|
||||
/* Write what's left - the compressed data bytes */
|
||||
len = ctx->cab_ctx->fileend - ctx->cab_ctx->siglen - i;
|
||||
while (len > 0) {
|
||||
if (!BIO_write_ex(outdata, ctx->options->indata + i, len, &written))
|
||||
return 1; /* FAILED */
|
||||
len -= written;
|
||||
i += written;
|
||||
}
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Modify specific type data and calculate a hash (message digest) of data.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int cab_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
||||
{
|
||||
/* Strip current signature and modify header */
|
||||
if (ctx->cab_ctx->header_size == 20) {
|
||||
if (!cab_modify_header(ctx, hash, outdata))
|
||||
return 1; /* FAILED */
|
||||
} else {
|
||||
if (!cab_add_header(ctx, hash, outdata))
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new PKCS#7 signature.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *cab_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
|
||||
{
|
||||
ASN1_OCTET_STRING *content;
|
||||
PKCS7 *p7 = pkcs7_create(ctx);
|
||||
|
||||
if (!p7) {
|
||||
printf("Creating a new signature failed\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (ctx->options->jp >= 0 && !cab_add_jp_attribute(p7, ctx->options->jp)) {
|
||||
printf("Adding jp attribute failed\n");
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!add_indirect_data_object(p7)) {
|
||||
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n");
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
content = spc_indirect_data_content_get(hash, ctx);
|
||||
if (!content) {
|
||||
printf("Failed to get spcIndirectDataContent\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!sign_spc_indirect_data_content(p7, content)) {
|
||||
printf("Failed to set signed content\n");
|
||||
PKCS7_free(p7);
|
||||
ASN1_OCTET_STRING_free(content);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
ASN1_OCTET_STRING_free(content);
|
||||
return p7;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append signature to the outfile.
|
||||
* [in, out] ctx: structure holds input and output data (unused)
|
||||
* [out] outdata: outdata file BIO
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int cab_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
||||
{
|
||||
u_char *p = NULL;
|
||||
int len; /* signature length */
|
||||
int padlen; /* signature padding length */
|
||||
|
||||
/* squash the unused parameter warning */
|
||||
(void)ctx;
|
||||
|
||||
if (((len = i2d_PKCS7(p7, NULL)) <= 0)
|
||||
|| (p = OPENSSL_malloc((size_t)len)) == NULL) {
|
||||
printf("i2d_PKCS memory allocation failed: %d\n", len);
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
i2d_PKCS7(p7, &p);
|
||||
p -= len;
|
||||
padlen = len % 8 ? 8 - len % 8 : 0;
|
||||
BIO_write(outdata, p, len);
|
||||
/* pad (with 0's) asn1 blob to 8 byte boundary */
|
||||
if (padlen > 0) {
|
||||
memset(p, 0, (size_t)padlen);
|
||||
BIO_write(outdata, p, padlen);
|
||||
}
|
||||
OPENSSL_free(p);
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Update additional data size.
|
||||
* Additional data size is located at offset 0x30 (from file beginning)
|
||||
* and consist of 4 bytes (little-endian order).
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] outdata: outdata file BIO
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [returns] none
|
||||
*/
|
||||
static void cab_update_data_size(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
||||
{
|
||||
int len, padlen;
|
||||
u_char buf[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* squash the unused parameter warning */
|
||||
(void)ctx;
|
||||
|
||||
if (!p7) {
|
||||
/* CMD_REMOVE
|
||||
* additional header does not exist so additional data size is unused */
|
||||
return;
|
||||
}
|
||||
(void)BIO_seek(outdata, 0x30);
|
||||
len = i2d_PKCS7(p7, NULL);
|
||||
padlen = len % 8 ? 8 - len % 8 : 0;
|
||||
PUT_UINT32_LE(len + padlen, buf);
|
||||
BIO_write(outdata, buf, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up an entire message digest BIO chain.
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO (unused)
|
||||
* [returns] none
|
||||
*/
|
||||
static void cab_bio_free(BIO *hash, BIO *outdata)
|
||||
{
|
||||
/* squash the unused parameter warning */
|
||||
(void)outdata;
|
||||
BIO_free_all(hash);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocate a FILE_FORMAT_CTX structure and CAB format specific structure,
|
||||
* unmap indata file.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [in] outdata: outdata file BIO
|
||||
* [returns] none
|
||||
*/
|
||||
static void cab_ctx_cleanup(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
unmap_file(ctx->options->indata, ctx->cab_ctx->fileend);
|
||||
OPENSSL_free(ctx->cab_ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
static int cab_is_detaching_supported(void)
|
||||
{
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* CAB helper functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Verify mapped CAB file and create CAB format specific structure.
|
||||
* [in] indata: mapped CAB file
|
||||
* [in] filesize: size of CAB file
|
||||
* [returns] pointer to CAB format specific structure
|
||||
*/
|
||||
static CAB_CTX *cab_ctx_get(char *indata, uint32_t filesize)
|
||||
{
|
||||
CAB_CTX *cab_ctx;
|
||||
uint32_t reserved, header_size = 0, sigpos = 0, siglen = 0;
|
||||
uint16_t flags;
|
||||
|
||||
if (filesize < 44) {
|
||||
printf("CAB file is too short\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
reserved = GET_UINT32_LE(indata + 4);
|
||||
if (reserved) {
|
||||
printf("Reserved1: 0x%08X\n", reserved);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
/* flags specify bit-mapped values that indicate the presence of optional data */
|
||||
flags = GET_UINT16_LE(indata + 30);
|
||||
if (flags & FLAG_PREV_CABINET) {
|
||||
/* FLAG_NEXT_CABINET works */
|
||||
printf("Multivolume cabinet file is unsupported: flags 0x%04X\n", flags);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (flags & FLAG_RESERVE_PRESENT) {
|
||||
/*
|
||||
* Additional headers is located at offset 36 (cbCFHeader, cbCFFolder, cbCFData);
|
||||
* size of header (4 bytes, little-endian order) must be 20 (checkpoint).
|
||||
*/
|
||||
header_size = GET_UINT32_LE(indata + 36);
|
||||
if (header_size != 20) {
|
||||
printf("Additional header size: 0x%08X\n", header_size);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
reserved = GET_UINT32_LE(indata + 40);
|
||||
if (reserved != 0x00100000) {
|
||||
printf("abReserved: 0x%08X\n", reserved);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
/*
|
||||
* File size is defined at offset 8, however if additional header exists, this size is not valid.
|
||||
* sigpos - additional data offset is located at offset 44 (from file beginning)
|
||||
* and consist of 4 bytes (little-endian order)
|
||||
* siglen - additional data size is located at offset 48 (from file beginning)
|
||||
* and consist of 4 bytes (little-endian order)
|
||||
* If there are additional headers, size of the CAB archive file is calcualted
|
||||
* as additional data offset plus additional data size.
|
||||
*/
|
||||
sigpos = GET_UINT32_LE(indata + 44);
|
||||
siglen = GET_UINT32_LE(indata + 48);
|
||||
if ((sigpos < filesize && sigpos + siglen != filesize) || (sigpos >= filesize)) {
|
||||
printf("Additional data offset:\t%u bytes\nAdditional data size:\t%u bytes\n",
|
||||
sigpos, siglen);
|
||||
printf("File size:\t\t%u bytes\n", filesize);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if ((sigpos > 0 && siglen == 0) || (sigpos == 0 && siglen > 0)) {
|
||||
printf("Corrupt signature\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
}
|
||||
cab_ctx = OPENSSL_zalloc(sizeof(CAB_CTX));
|
||||
cab_ctx->header_size = header_size;
|
||||
cab_ctx->sigpos = sigpos;
|
||||
cab_ctx->siglen = siglen;
|
||||
cab_ctx->fileend = filesize;
|
||||
cab_ctx->flags = flags;
|
||||
return cab_ctx; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Add level of permissions in Microsoft Internet Explorer 4.x for CAB files,
|
||||
* only low level is supported.
|
||||
* [in, out] p7: PKCS#7 signature
|
||||
* [in] jp: low (0) level
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cab_add_jp_attribute(PKCS7 *p7, int jp)
|
||||
{
|
||||
STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
|
||||
PKCS7_SIGNER_INFO *si;
|
||||
ASN1_STRING *astr;
|
||||
const u_char *attrs = NULL;
|
||||
const u_char java_attrs_low[] = {
|
||||
0x30, 0x06, 0x03, 0x02, 0x00, 0x01, 0x30, 0x00
|
||||
};
|
||||
|
||||
signer_info = PKCS7_get_signer_info(p7);
|
||||
if (!signer_info)
|
||||
return 0; /* FAILED */
|
||||
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
|
||||
if (!si)
|
||||
return 0; /* FAILED */
|
||||
switch (jp) {
|
||||
case 0:
|
||||
attrs = java_attrs_low;
|
||||
break;
|
||||
case 1:
|
||||
/* XXX */
|
||||
case 2:
|
||||
/* XXX */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (attrs) {
|
||||
astr = ASN1_STRING_new();
|
||||
ASN1_STRING_set(astr, attrs, sizeof java_attrs_low);
|
||||
return PKCS7_add_signed_attribute(si, OBJ_txt2nid(MS_JAVA_SOMETHING),
|
||||
V_ASN1_SEQUENCE, astr);
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Write name of previous and next cabinet file.
|
||||
* Multivolume cabinet file is unsupported TODO.
|
||||
* [out] outdata: outdata file BIO
|
||||
* [in] indata: mapped CAB file
|
||||
* [in] len: offset
|
||||
* [in] flags: FLAG_PREV_CABINET, FLAG_NEXT_CABINET
|
||||
* [returns] offset
|
||||
*/
|
||||
static size_t cab_write_optional_names(BIO *outdata, char *indata, size_t i, uint16_t flags)
|
||||
{
|
||||
if (flags & FLAG_PREV_CABINET) {
|
||||
/* szCabinetPrev */
|
||||
while (GET_UINT8_LE(indata + i)) {
|
||||
BIO_write(outdata, indata + i, 1);
|
||||
i++;
|
||||
}
|
||||
BIO_write(outdata, indata + i, 1);
|
||||
i++;
|
||||
/* szDiskPrev */
|
||||
while (GET_UINT8_LE(indata + i)) {
|
||||
BIO_write(outdata, indata + i, 1);
|
||||
i++;
|
||||
}
|
||||
BIO_write(outdata, indata + i, 1);
|
||||
i++;
|
||||
}
|
||||
if (flags & FLAG_NEXT_CABINET) {
|
||||
/* szCabinetNext */
|
||||
while (GET_UINT8_LE(indata + i)) {
|
||||
BIO_write(outdata, indata + i, 1);
|
||||
i++;
|
||||
}
|
||||
BIO_write(outdata, indata + i, 1);
|
||||
i++;
|
||||
/* szDiskNext */
|
||||
while (GET_UINT8_LE(indata + i)) {
|
||||
BIO_write(outdata, indata + i, 1);
|
||||
i++;
|
||||
}
|
||||
BIO_write(outdata, indata + i, 1);
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modify CAB header.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cab_modify_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
||||
{
|
||||
size_t i, written, len;
|
||||
uint16_t nfolders, flags;
|
||||
u_char buf[] = {0x00, 0x00};
|
||||
|
||||
/* u1 signature[4] 4643534D MSCF: 0-3 */
|
||||
BIO_write(hash, ctx->options->indata, 4);
|
||||
/* u4 reserved1 00000000: 4-7 */
|
||||
BIO_write(outdata, ctx->options->indata + 4, 4);
|
||||
/*
|
||||
* u4 cbCabinet - size of this cabinet file in bytes: 8-11
|
||||
* u4 reserved2 00000000: 12-15
|
||||
* u4 coffFiles - offset of the first CFFILE entry: 16-19
|
||||
* u4 reserved3 00000000: 20-23
|
||||
* u1 versionMinor 03: 24
|
||||
* u1 versionMajor 01: 25
|
||||
* u2 cFolders - number of CFFOLDER entries in this cabinet: 26-27
|
||||
* u2 cFiles - number of CFFILE entries in this cabinet: 28-29
|
||||
*/
|
||||
BIO_write(hash, ctx->options->indata + 8, 22);
|
||||
/* u2 flags: 30-31 */
|
||||
flags = GET_UINT16_LE(ctx->options->indata + 30);
|
||||
PUT_UINT16_LE(flags, buf);
|
||||
BIO_write(hash, buf, 2);
|
||||
/* u2 setID must be the same for all cabinets in a set: 32-33 */
|
||||
BIO_write(hash, ctx->options->indata + 32, 2);
|
||||
/*
|
||||
* u2 iCabinet - number of this cabinet file in a set: 34-35
|
||||
* u2 cbCFHeader: 36-37
|
||||
* u1 cbCFFolder: 38
|
||||
* u1 cbCFData: 39
|
||||
* u16 abReserve: 40-55
|
||||
* - Additional data offset: 44-47
|
||||
* - Additional data size: 48-51
|
||||
*/
|
||||
BIO_write(outdata, ctx->options->indata + 34, 22);
|
||||
/* u4 abReserve: 56-59 */
|
||||
BIO_write(hash, ctx->options->indata + 56, 4);
|
||||
|
||||
i = cab_write_optional_names(outdata, ctx->options->indata, 60, flags);
|
||||
/*
|
||||
* (u8 * cFolders) CFFOLDER - structure contains information about
|
||||
* one of the folders or partial folders stored in this cabinet file
|
||||
*/
|
||||
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
|
||||
while (nfolders) {
|
||||
BIO_write(hash, ctx->options->indata + i, 8);
|
||||
i += 8;
|
||||
nfolders--;
|
||||
}
|
||||
/* Write what's left - the compressed data bytes */
|
||||
len = ctx->cab_ctx->sigpos - i;
|
||||
while (len > 0) {
|
||||
if (!BIO_write_ex(hash, ctx->options->indata + i, len, &written))
|
||||
return 0; /* FAILED */
|
||||
len -= written;
|
||||
i += written;
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Add signed CAB header.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cab_add_header(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
||||
{
|
||||
size_t i, written, len;
|
||||
uint32_t tmp;
|
||||
uint16_t nfolders, flags;
|
||||
u_char cabsigned[] = {
|
||||
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
|
||||
0xde, 0xad, 0xbe, 0xef, /* size of cab file */
|
||||
0xde, 0xad, 0xbe, 0xef, /* size of asn1 blob */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
char *buf = OPENSSL_malloc(SIZE_64K);
|
||||
memset(buf, 0, SIZE_64K);
|
||||
|
||||
/* u1 signature[4] 4643534D MSCF: 0-3 */
|
||||
BIO_write(hash, ctx->options->indata, 4);
|
||||
/* u4 reserved1 00000000: 4-7 */
|
||||
BIO_write(outdata, ctx->options->indata + 4, 4);
|
||||
/* u4 cbCabinet - size of this cabinet file in bytes: 8-11 */
|
||||
tmp = GET_UINT32_LE(ctx->options->indata + 8) + 24;
|
||||
PUT_UINT32_LE(tmp, buf);
|
||||
BIO_write(hash, buf, 4);
|
||||
/* u4 reserved2 00000000: 12-15 */
|
||||
BIO_write(hash, ctx->options->indata + 12, 4);
|
||||
/* u4 coffFiles - offset of the first CFFILE entry: 16-19 */
|
||||
tmp = GET_UINT32_LE(ctx->options->indata + 16) + 24;
|
||||
PUT_UINT32_LE(tmp, buf + 4);
|
||||
BIO_write(hash, buf + 4, 4);
|
||||
/*
|
||||
* u4 reserved3 00000000: 20-23
|
||||
* u1 versionMinor 03: 24
|
||||
* u1 versionMajor 01: 25
|
||||
* u2 cFolders - number of CFFOLDER entries in this cabinet: 26-27
|
||||
* u2 cFiles - number of CFFILE entries in this cabinet: 28-29
|
||||
*/
|
||||
memcpy(buf + 4, ctx->options->indata + 20, 10);
|
||||
flags = GET_UINT16_LE(ctx->options->indata + 30);
|
||||
buf[4+10] = (char)flags | FLAG_RESERVE_PRESENT;
|
||||
/* u2 setID must be the same for all cabinets in a set: 32-33 */
|
||||
memcpy(buf + 16, ctx->options->indata + 32, 2);
|
||||
BIO_write(hash, buf + 4, 14);
|
||||
/* u2 iCabinet - number of this cabinet file in a set: 34-35 */
|
||||
BIO_write(outdata, ctx->options->indata + 34, 2);
|
||||
memcpy(cabsigned + 8, buf, 4);
|
||||
BIO_write(outdata, cabsigned, 20);
|
||||
BIO_write(hash, cabsigned+20, 4);
|
||||
|
||||
i = cab_write_optional_names(outdata, ctx->options->indata, 36, flags);
|
||||
/*
|
||||
* (u8 * cFolders) CFFOLDER - structure contains information about
|
||||
* one of the folders or partial folders stored in this cabinet file
|
||||
*/
|
||||
nfolders = GET_UINT16_LE(ctx->options->indata + 26);
|
||||
while (nfolders) {
|
||||
tmp = GET_UINT32_LE(ctx->options->indata + i);
|
||||
tmp += 24;
|
||||
PUT_UINT32_LE(tmp, buf);
|
||||
BIO_write(hash, buf, 4);
|
||||
BIO_write(hash, ctx->options->indata + i + 4, 4);
|
||||
i += 8;
|
||||
nfolders--;
|
||||
}
|
||||
OPENSSL_free(buf);
|
||||
/* Write what's left - the compressed data bytes */
|
||||
len = ctx->cab_ctx->fileend - i;
|
||||
while (len > 0) {
|
||||
if (!BIO_write_ex(hash, ctx->options->indata + i, len, &written))
|
||||
return 0; /* FAILED */
|
||||
len -= written;
|
||||
i += written;
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the signature exists.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cab_check_file(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
if (!ctx) {
|
||||
printf("Init error\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (ctx->cab_ctx->header_size != 20) {
|
||||
printf("No signature found\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (ctx->cab_ctx->sigpos == 0 || ctx->cab_ctx->siglen == 0
|
||||
|| ctx->cab_ctx->sigpos > ctx->cab_ctx->fileend) {
|
||||
printf("No signature found\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
vim: set ts=4 expandtab:
|
||||
*/
|
480
cat.c
Normal file
480
cat.c
Normal file
@ -0,0 +1,480 @@
|
||||
/*
|
||||
* CAT file support library
|
||||
*
|
||||
* Copyright (C) 2021-2023 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
* Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
|
||||
*
|
||||
* Catalog files are a bit odd, in that they are only a PKCS7 blob.
|
||||
* CAT files do not support nesting (multiple signature)
|
||||
*/
|
||||
|
||||
#include "osslsigncode.h"
|
||||
#include "helpers.h"
|
||||
|
||||
typedef struct {
|
||||
ASN1_BMPSTRING *tag;
|
||||
ASN1_INTEGER *flags;
|
||||
ASN1_OCTET_STRING *value;
|
||||
} CatNameValueContent;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(CatNameValueContent)
|
||||
|
||||
ASN1_SEQUENCE(CatNameValueContent) = {
|
||||
ASN1_SIMPLE(CatNameValueContent, tag, ASN1_BMPSTRING),
|
||||
ASN1_SIMPLE(CatNameValueContent, flags, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(CatNameValueContent, value, ASN1_OCTET_STRING)
|
||||
} ASN1_SEQUENCE_END(CatNameValueContent)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(CatNameValueContent)
|
||||
|
||||
struct cat_ctx_st {
|
||||
uint32_t sigpos;
|
||||
uint32_t siglen;
|
||||
uint32_t fileend;
|
||||
PKCS7 *p7;
|
||||
};
|
||||
|
||||
/* FILE_FORMAT method prototypes */
|
||||
static FILE_FORMAT_CTX *cat_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *outdata);
|
||||
static int cat_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7);
|
||||
static PKCS7 *cat_pkcs7_extract(FILE_FORMAT_CTX *ctx);
|
||||
static PKCS7 *cat_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash);
|
||||
static int cat_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7);
|
||||
static void cat_bio_free(BIO *hash, BIO *outdata);
|
||||
static void cat_ctx_cleanup(FILE_FORMAT_CTX *ctx);
|
||||
|
||||
FILE_FORMAT file_format_cat = {
|
||||
.ctx_new = cat_ctx_new,
|
||||
.verify_digests = cat_verify_digests,
|
||||
.pkcs7_extract = cat_pkcs7_extract,
|
||||
.pkcs7_signature_new = cat_pkcs7_signature_new,
|
||||
.append_pkcs7 = cat_append_pkcs7,
|
||||
.bio_free = cat_bio_free,
|
||||
.ctx_cleanup = cat_ctx_cleanup,
|
||||
};
|
||||
|
||||
/* Prototypes */
|
||||
static CAT_CTX *cat_ctx_get(char *indata, uint32_t filesize);
|
||||
static int cat_add_ms_ctl_object(PKCS7 *p7);
|
||||
static int cat_sign_ms_ctl_content(PKCS7 *p7, PKCS7 *contents);
|
||||
static int cat_list_content(PKCS7 *p7);
|
||||
static int cat_print_content_member_digest(ASN1_TYPE *content);
|
||||
static int cat_print_content_member_name(ASN1_TYPE *content);
|
||||
static void cat_print_base64(ASN1_OCTET_STRING *value);
|
||||
static void cat_print_utf16_as_ascii(ASN1_OCTET_STRING *value);
|
||||
static int cat_check_file(FILE_FORMAT_CTX *ctx);
|
||||
|
||||
/*
|
||||
* FILE_FORMAT method definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Allocate and return a CAT file format context.
|
||||
* [in, out] options: structure holds the input data
|
||||
* [out] hash: message digest BIO (unused)
|
||||
* [in] outdata: outdata file BIO (unused)
|
||||
* [returns] pointer to CAT file format context
|
||||
*/
|
||||
static FILE_FORMAT_CTX *cat_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *outdata)
|
||||
{
|
||||
FILE_FORMAT_CTX *ctx;
|
||||
CAT_CTX *cat_ctx;
|
||||
uint32_t filesize;
|
||||
|
||||
if (options->cmd == CMD_REMOVE || options->cmd==CMD_ATTACH || options->cmd == CMD_EXTRACT_DATA) {
|
||||
printf("Unsupported command\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
filesize = get_file_size(options->infile);
|
||||
if (filesize == 0)
|
||||
return NULL; /* FAILED */
|
||||
|
||||
options->indata = map_file(options->infile, filesize);
|
||||
if (!options->indata) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
cat_ctx = cat_ctx_get(options->indata, filesize);
|
||||
if (!cat_ctx) {
|
||||
unmap_file(options->indata, filesize);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
ctx = OPENSSL_malloc(sizeof(FILE_FORMAT_CTX));
|
||||
ctx->format = &file_format_cat;
|
||||
ctx->options = options;
|
||||
ctx->cat_ctx = cat_ctx;
|
||||
|
||||
/* Push hash on outdata, if hash is NULL the function does nothing */
|
||||
BIO_push(hash, outdata);
|
||||
|
||||
if (options->cmd == CMD_VERIFY)
|
||||
printf("Warning: Use -catalog option to verify that a file, listed in catalog file, is signed\n");
|
||||
if (options->jp >= 0)
|
||||
printf("Warning: -jp option is only valid for CAB files\n");
|
||||
if (options->pagehash == 1)
|
||||
printf("Warning: -ph option is only valid for PE files\n");
|
||||
if (options->add_msi_dse == 1)
|
||||
printf("Warning: -add-msi-dse option is only valid for MSI files\n");
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/*
|
||||
* ContentInfo value is the inner content of pkcs7-signedData.
|
||||
* An extra verification is not necessary when a content type data
|
||||
* is the inner content of the signed-data type.
|
||||
*/
|
||||
static int cat_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
||||
{
|
||||
/* squash unused parameter warnings */
|
||||
(void)ctx;
|
||||
(void)p7;
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract existing signature in DER format.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *cat_pkcs7_extract(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
if (!cat_check_file(ctx)) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
return PKCS7_dup(ctx->cat_ctx->p7);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new PKCS#7 signature.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO (unused)
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *cat_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
|
||||
{
|
||||
PKCS7 *p7 = NULL;
|
||||
|
||||
/* squash unused parameter warnings */
|
||||
(void)hash;
|
||||
|
||||
p7 = pkcs7_create(ctx);
|
||||
if (!p7) {
|
||||
printf("Creating a new signature failed\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!cat_add_ms_ctl_object(p7)) {
|
||||
printf("Adding MS_CTL_OBJID failed\n");
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!cat_sign_ms_ctl_content(p7, ctx->cat_ctx->p7->d.sign->contents)) {
|
||||
printf("Failed to set signed content\n");
|
||||
PKCS7_free(p7);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
return p7; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Append signature to the outfile.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] outdata: outdata file BIO
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int cat_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
||||
{
|
||||
return data_write_pkcs7(ctx, outdata, p7);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up an entire message digest BIO chain.
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO (unused)
|
||||
* [returns] none
|
||||
*/
|
||||
static void cat_bio_free(BIO *hash, BIO *outdata)
|
||||
{
|
||||
/* squash the unused parameter warning */
|
||||
(void)outdata;
|
||||
BIO_free_all(hash);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocate a FILE_FORMAT_CTX structure and CAT format specific structure,
|
||||
* unmap indata file.
|
||||
* [in, out] ctx: structure holds all input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [in] outdata: outdata file BIO
|
||||
* [returns] none
|
||||
*/
|
||||
static void cat_ctx_cleanup(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
unmap_file(ctx->options->indata, ctx->cat_ctx->fileend);
|
||||
PKCS7_free(ctx->cat_ctx->p7);
|
||||
OPENSSL_free(ctx->cat_ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* CAT helper functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Verify mapped PKCS#7 (CAT) file and create CAT format specific structure.
|
||||
* [in] indata: mapped file
|
||||
* [in] filesize: size of file
|
||||
* [returns] pointer to CAT format specific structure
|
||||
*/
|
||||
static CAT_CTX *cat_ctx_get(char *indata, uint32_t filesize)
|
||||
{
|
||||
CAT_CTX *cat_ctx;
|
||||
PKCS7 *p7;
|
||||
|
||||
p7 = pkcs7_read_data(indata, filesize);
|
||||
if (!p7)
|
||||
return NULL; /* FAILED */
|
||||
if (!PKCS7_type_is_signed(p7)) {
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
cat_ctx = OPENSSL_zalloc(sizeof(CAT_CTX));
|
||||
cat_ctx->p7 = p7;
|
||||
cat_ctx->sigpos = 0;
|
||||
cat_ctx->siglen = filesize;
|
||||
cat_ctx->fileend = filesize;
|
||||
return cat_ctx; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Add "1.3.6.1.4.1.311.10.1" MS_CTL_OBJID signed attribute
|
||||
* [in, out] p7: new PKCS#7 signature
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cat_add_ms_ctl_object(PKCS7 *p7)
|
||||
{
|
||||
STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
|
||||
PKCS7_SIGNER_INFO *si;
|
||||
|
||||
signer_info = PKCS7_get_signer_info(p7);
|
||||
if (!signer_info)
|
||||
return 0; /* FAILED */
|
||||
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
|
||||
if (!si)
|
||||
return 0; /* FAILED */
|
||||
if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
|
||||
V_ASN1_OBJECT, OBJ_txt2obj(MS_CTL_OBJID, 1)))
|
||||
return 0; /* FAILED */
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Sign the MS CTL blob.
|
||||
* Certificate Trust List (CTL) is a list of file names or thumbprints.
|
||||
* All the items in this list are authenticated (approved) by the signing entity.
|
||||
* [in, out] p7: new PKCS#7 signature
|
||||
* [in] contents: Certificate Trust List (CTL)
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cat_sign_ms_ctl_content(PKCS7 *p7, PKCS7 *contents)
|
||||
{
|
||||
u_char *content;
|
||||
int seqhdrlen, content_length;
|
||||
|
||||
seqhdrlen = asn1_simple_hdr_len(contents->d.other->value.sequence->data,
|
||||
contents->d.other->value.sequence->length);
|
||||
content = contents->d.other->value.sequence->data + seqhdrlen;
|
||||
content_length = contents->d.other->value.sequence->length - seqhdrlen;
|
||||
|
||||
if (!pkcs7_sign_content(p7, content, content_length)) {
|
||||
printf("Failed to sign content\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (!PKCS7_set_content(p7, PKCS7_dup(contents))) {
|
||||
printf("PKCS7_set_content failed\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Print each member of the CAT file by using the "-verbose" option.
|
||||
* [in, out] p7: catalog file to verify
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int cat_list_content(PKCS7 *p7)
|
||||
{
|
||||
MsCtlContent *ctlc;
|
||||
int i;
|
||||
|
||||
ctlc = ms_ctl_content_get(p7);
|
||||
if (!ctlc) {
|
||||
printf("Failed to extract MS_CTL_OBJID data\n");
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
printf("\nCatalog members:\n");
|
||||
for (i = 0; i < sk_CatalogInfo_num(ctlc->header_attributes); i++) {
|
||||
int j, found = 0;
|
||||
CatalogInfo *header_attr = sk_CatalogInfo_value(ctlc->header_attributes, i);
|
||||
if (header_attr == NULL)
|
||||
continue;
|
||||
for (j = 0; j < sk_CatalogAuthAttr_num(header_attr->attributes); j++) {
|
||||
char object_txt[128];
|
||||
CatalogAuthAttr *attribute;
|
||||
ASN1_TYPE *content;
|
||||
|
||||
attribute = sk_CatalogAuthAttr_value(header_attr->attributes, j);
|
||||
if (!attribute)
|
||||
continue;
|
||||
content = catalog_content_get(attribute);
|
||||
if (!content)
|
||||
continue;
|
||||
object_txt[0] = 0x00;
|
||||
OBJ_obj2txt(object_txt, sizeof object_txt, attribute->type, 1);
|
||||
if (!strcmp(object_txt, CAT_NAMEVALUE_OBJID)) {
|
||||
/* CAT_NAMEVALUE_OBJID OID: 1.3.6.1.4.1.311.12.2.1 */
|
||||
found |= cat_print_content_member_name(content);
|
||||
} else if (!strcmp(object_txt, SPC_INDIRECT_DATA_OBJID)) {
|
||||
/* SPC_INDIRECT_DATA_OBJID OID: 1.3.6.1.4.1.311.2.1.4 */
|
||||
found |= cat_print_content_member_digest(content);
|
||||
}
|
||||
ASN1_TYPE_free(content);
|
||||
}
|
||||
if (found)
|
||||
printf("\n");
|
||||
}
|
||||
MsCtlContent_free(ctlc);
|
||||
ERR_print_errors_fp(stdout);
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a hash algorithm and a message digest from the SPC_INDIRECT_DATA_OBJID attribute.
|
||||
* [in] content: catalog file content
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cat_print_content_member_digest(ASN1_TYPE *content)
|
||||
{
|
||||
SpcIndirectDataContent *idc;
|
||||
u_char mdbuf[EVP_MAX_MD_SIZE];
|
||||
const u_char *data ;
|
||||
int mdtype = -1;
|
||||
ASN1_STRING *value;
|
||||
|
||||
value = content->value.sequence;
|
||||
data = ASN1_STRING_get0_data(value);
|
||||
idc = d2i_SpcIndirectDataContent(NULL, &data, ASN1_STRING_length(value));
|
||||
if (!idc)
|
||||
return 0; /* FAILED */
|
||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
||||
/* get a digest algorithm a message digest of the file from the content */
|
||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
||||
}
|
||||
SpcIndirectDataContent_free(idc);
|
||||
if (mdtype == -1) {
|
||||
printf("Failed to extract current message digest\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
printf("\tHash algorithm: %s\n", OBJ_nid2sn(mdtype));
|
||||
print_hash("\tMessage digest", "", mdbuf, EVP_MD_size(EVP_get_digestbynid(mdtype)));
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a file name from the CAT_NAMEVALUE_OBJID attribute.
|
||||
* [in] content: catalog file content
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cat_print_content_member_name(ASN1_TYPE *content)
|
||||
{
|
||||
CatNameValueContent *nvc;
|
||||
const u_char *data = NULL;
|
||||
ASN1_STRING *value;
|
||||
|
||||
value = content->value.sequence;
|
||||
data = ASN1_STRING_get0_data(value);
|
||||
nvc = d2i_CatNameValueContent(NULL, &data, ASN1_STRING_length(value));
|
||||
if (!nvc) {
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
printf("\tFile name: ");
|
||||
if (ASN1_INTEGER_get(nvc->flags) & 0x00020000) {
|
||||
cat_print_base64(nvc->value);
|
||||
} else {
|
||||
cat_print_utf16_as_ascii(nvc->value);
|
||||
}
|
||||
printf("\n");
|
||||
CatNameValueContent_free(nvc);
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a CAT_NAMEVALUE_OBJID attribute represented in base-64 encoding.
|
||||
* [in] value: catalog member file name
|
||||
* [returns] none
|
||||
*/
|
||||
static void cat_print_base64(ASN1_OCTET_STRING *value)
|
||||
{
|
||||
BIO *stdbio, *b64;
|
||||
stdbio = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
b64 = BIO_new(BIO_f_base64());
|
||||
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
stdbio = BIO_push(b64, stdbio);
|
||||
ASN1_STRING_print_ex(stdbio, value, 0);
|
||||
BIO_free_all(stdbio);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a CAT_NAMEVALUE_OBJID attribute represented in plaintext.
|
||||
* [in] value: catalog member file name
|
||||
* [returns] none
|
||||
*/
|
||||
static void cat_print_utf16_as_ascii(ASN1_OCTET_STRING *value)
|
||||
{
|
||||
const u_char *data;
|
||||
int len, i;
|
||||
|
||||
data = ASN1_STRING_get0_data(value);
|
||||
len = ASN1_STRING_length(value);
|
||||
for (i = 0; i < len && (data[i] || data[i+1]); i+=2)
|
||||
putchar(isprint(data[i]) && !data[i+1] ? data[i] : '.');
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the signature exists.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int cat_check_file(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
|
||||
PKCS7_SIGNER_INFO *si;
|
||||
|
||||
if (!ctx) {
|
||||
printf("Init error\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
signer_info = PKCS7_get_signer_info(ctx->cat_ctx->p7);
|
||||
if (!signer_info) {
|
||||
printf("Failed catalog file\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
|
||||
if (!si) {
|
||||
printf("No signature found\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (ctx->options->verbose) {
|
||||
(void)cat_list_content(ctx->cat_ctx->p7);
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
vim: set ts=4 expandtab:
|
||||
*/
|
@ -25,3 +25,12 @@ list(APPEND CPACK_SOURCE_IGNORE_FILES "/build/")
|
||||
|
||||
include(CPack)
|
||||
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
|
||||
|
||||
#[[
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
]]
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,16 +2,25 @@ include(CheckIncludeFile)
|
||||
include(CheckFunctionExists)
|
||||
|
||||
if(UNIX)
|
||||
check_function_exists(getpass HAVE_GETPASS)
|
||||
check_include_file(termios.h HAVE_TERMIOS_H)
|
||||
check_include_file(sys/mman.h HAVE_SYS_MMAN_H)
|
||||
if(HAVE_SYS_MMAN_H)
|
||||
check_function_exists(mmap HAVE_MMAP)
|
||||
endif(HAVE_SYS_MMAN_H)
|
||||
check_function_exists(getpass HAVE_GETPASS)
|
||||
check_include_file(termios.h HAVE_TERMIOS_H)
|
||||
check_include_file(sys/mman.h HAVE_SYS_MMAN_H)
|
||||
if(HAVE_SYS_MMAN_H)
|
||||
check_function_exists(mmap HAVE_MMAP)
|
||||
endif(HAVE_SYS_MMAN_H)
|
||||
else(UNIX)
|
||||
check_include_file(windows.h HAVE_MAPVIEWOFFILE)
|
||||
check_include_file(windows.h HAVE_MAPVIEWOFFILE)
|
||||
endif(UNIX)
|
||||
|
||||
if(NOT (HAVE_MMAP OR HAVE_MAPVIEWOFFILE))
|
||||
message(FATAL_ERROR "Error: Need file mapping function to build.")
|
||||
message(FATAL_ERROR "Error: Need file mapping function to build.")
|
||||
endif(NOT (HAVE_MMAP OR HAVE_MAPVIEWOFFILE))
|
||||
|
||||
#[[
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
]]
|
||||
|
@ -1,13 +1,32 @@
|
||||
# This list describes the default variables included in the bash-completion package:
|
||||
# BASH_COMPLETION_VERSION "@VERSION@"
|
||||
# BASH_COMPLETION_PREFIX "@prefix@"
|
||||
# BASH_COMPLETION_COMPATDIR "@sysconfdir@/bash_completion.d"
|
||||
# BASH_COMPLETION_COMPLETIONSDIR "@datadir@/@PACKAGE@/completions"
|
||||
# BASH_COMPLETION_HELPERSDIR "@datadir@/@PACKAGE@/helpers"
|
||||
# BASH_COMPLETION_FOUND "TRUE"
|
||||
# https://github.com/scop/bash-completion/blob/master/bash-completion-config.cmake.in
|
||||
|
||||
if(NOT MSVC)
|
||||
find_package(bash-completion QUIET)
|
||||
if(NOT BASH_COMPLETION_COMPLETIONSDIR)
|
||||
if(BASH_COMPLETION_COMPATDIR)
|
||||
set(BASH_COMPLETION_COMPLETIONSDIR ${BASH_COMPLETION_COMPATDIR})
|
||||
else()
|
||||
set(SHAREDIR "${CMAKE_INSTALL_PREFIX}/share")
|
||||
set(BASH_COMPLETION_COMPLETIONSDIR "${SHAREDIR}/bash-completion/completions")
|
||||
endif()
|
||||
endif()
|
||||
message(STATUS "Using bash completions dir ${BASH_COMPLETION_COMPLETIONSDIR}")
|
||||
install(FILES "osslsigncode.bash" DESTINATION ${BASH_COMPLETION_COMPLETIONSDIR})
|
||||
endif()
|
||||
if(BASH_COMPLETION_USER_DIR)
|
||||
set(BASH_COMPLETION_COMPLETIONSDIR "${BASH_COMPLETION_USER_DIR}/bash-completion/completions")
|
||||
else(BASH_COMPLETION_USER_DIR)
|
||||
find_package(bash-completion QUIET)
|
||||
if(NOT BASH_COMPLETION_FOUND)
|
||||
set(SHAREDIR "${CMAKE_INSTALL_PREFIX}/share")
|
||||
set(BASH_COMPLETION_COMPLETIONSDIR "${SHAREDIR}/bash-completion/completions")
|
||||
endif(NOT BASH_COMPLETION_FOUND)
|
||||
endif(BASH_COMPLETION_USER_DIR)
|
||||
|
||||
message(STATUS "Using bash completions dir ${BASH_COMPLETION_COMPLETIONSDIR}")
|
||||
install(FILES "osslsigncode.bash" DESTINATION ${BASH_COMPLETION_COMPLETIONSDIR})
|
||||
endif(NOT MSVC)
|
||||
|
||||
#[[
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
]]
|
||||
|
@ -3,111 +3,121 @@ include(CheckCCompilerFlag)
|
||||
set(CMAKE_REQUIRED_QUIET ON)
|
||||
|
||||
function(add_debug_flag_if_supported flagname targets)
|
||||
check_c_compiler_flag("${flagname}" HAVE_FLAG_${flagname})
|
||||
if (HAVE_FLAG_${flagname})
|
||||
foreach(target ${targets})
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:DEBUG>:${flagname}>)
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
check_c_compiler_flag("${flagname}" HAVE_FLAG_${flagname})
|
||||
if (HAVE_FLAG_${flagname})
|
||||
foreach(target ${targets})
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:DEBUG>:${flagname}>)
|
||||
endforeach(target ${targets})
|
||||
endif(HAVE_FLAG_${flagname})
|
||||
endfunction(add_debug_flag_if_supported flagname targets)
|
||||
|
||||
function(add_compile_flag_to_targets targets)
|
||||
set(CHECKED_DEBUG_FLAGS
|
||||
"-ggdb"
|
||||
"-g"
|
||||
"-O2"
|
||||
"-pedantic"
|
||||
"-Wall"
|
||||
"-Wextra"
|
||||
"-Wno-long-long"
|
||||
"-Wconversion"
|
||||
"-D_FORTIFY_SOURCE=2"
|
||||
"-Wformat=2"
|
||||
"-Wredundant-decls"
|
||||
"-Wcast-qual"
|
||||
"-Wnull-dereference"
|
||||
"-Wno-deprecated-declarations"
|
||||
"-Wmissing-declarations"
|
||||
"-Wmissing-prototypes"
|
||||
"-Wmissing-noreturn"
|
||||
"-Wmissing-braces"
|
||||
"-Wparentheses"
|
||||
"-Wstrict-aliasing=3"
|
||||
"-Wstrict-overflow=2"
|
||||
"-Wlogical-op"
|
||||
"-Wwrite-strings"
|
||||
"-Wcast-align=strict"
|
||||
"-Wdisabled-optimization"
|
||||
"-Wshift-overflow=2"
|
||||
"-Wundef"
|
||||
"-Wshadow"
|
||||
"-Wmisleading-indentation"
|
||||
"-Wabsolute-value"
|
||||
"-Wunused-parameter"
|
||||
"-Wunused-function"
|
||||
)
|
||||
foreach(flag ${CHECKED_DEBUG_FLAGS})
|
||||
add_debug_flag_if_supported(${flag} ${targets})
|
||||
endforeach()
|
||||
endfunction()
|
||||
set(CHECKED_DEBUG_FLAGS
|
||||
"-ggdb"
|
||||
"-g"
|
||||
"-O2"
|
||||
"-pedantic"
|
||||
"-Wall"
|
||||
"-Wextra"
|
||||
"-Wno-long-long"
|
||||
"-Wconversion"
|
||||
"-D_FORTIFY_SOURCE=2"
|
||||
"-Wformat=2"
|
||||
"-Wredundant-decls"
|
||||
"-Wcast-qual"
|
||||
"-Wnull-dereference"
|
||||
"-Wno-deprecated-declarations"
|
||||
"-Wmissing-declarations"
|
||||
"-Wmissing-prototypes"
|
||||
"-Wmissing-noreturn"
|
||||
"-Wmissing-braces"
|
||||
"-Wparentheses"
|
||||
"-Wstrict-aliasing=3"
|
||||
"-Wstrict-overflow=2"
|
||||
"-Wlogical-op"
|
||||
"-Wwrite-strings"
|
||||
"-Wcast-align=strict"
|
||||
"-Wdisabled-optimization"
|
||||
"-Wshift-overflow=2"
|
||||
"-Wundef"
|
||||
"-Wshadow"
|
||||
"-Wmisleading-indentation"
|
||||
"-Wabsolute-value"
|
||||
"-Wunused-parameter"
|
||||
"-Wunused-function")
|
||||
foreach(flag ${CHECKED_DEBUG_FLAGS})
|
||||
add_debug_flag_if_supported(${flag} ${targets})
|
||||
endforeach(flag ${CHECKED_DEBUG_FLAGS})
|
||||
endfunction(add_compile_flag_to_targets targets)
|
||||
|
||||
function(add_compile_flags target)
|
||||
if(MSVC)
|
||||
# Enable parallel builds
|
||||
target_compile_options(${target} PRIVATE /MP)
|
||||
# Use address space layout randomization, generate PIE code for ASLR (default on)
|
||||
target_link_options(${target} PRIVATE /DYNAMICBASE)
|
||||
# Create terminal server aware application (default on)
|
||||
target_link_options(${target} PRIVATE /TSAWARE)
|
||||
# Mark the binary as compatible with Intel Control-flow Enforcement Technology (CET) Shadow Stack
|
||||
target_link_options(${target} PRIVATE /CETCOMPAT)
|
||||
# Enable compiler generation of Control Flow Guard security checks
|
||||
target_compile_options(${target} PRIVATE /guard:cf)
|
||||
target_link_options(${target} PRIVATE /guard:cf)
|
||||
# Buffer Security Check
|
||||
target_compile_options(${target} PRIVATE /GS)
|
||||
# Suppress startup banner
|
||||
target_link_options(${target} PRIVATE /NOLOGO)
|
||||
# Generate debug info
|
||||
target_link_options(${target} PRIVATE /DEBUG)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
# High entropy ASLR for 64 bits targets (default on)
|
||||
target_link_options(${target} PRIVATE /HIGHENTROPYVA)
|
||||
# Enable generation of EH Continuation (EHCONT) metadata by the compiler
|
||||
#target_compile_options(${target} PRIVATE /guard:ehcont)
|
||||
#target_link_options(${target} PRIVATE /guard:ehcont)
|
||||
else()
|
||||
# Can handle addresses larger than 2 gigabytes
|
||||
target_link_options(${target} PRIVATE /LARGEADDRESSAWARE)
|
||||
# Safe structured exception handlers (x86 only)
|
||||
target_link_options(${target} PRIVATE /SAFESEH)
|
||||
endif()
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:DEBUG>:/D_FORTIFY_SOURCE=2>)
|
||||
# Unrecognized compiler options are errors
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:DEBUG>:/options:strict>)
|
||||
else(MSVC)
|
||||
check_c_compiler_flag("-fstack-protector-all" HAVE_STACK_PROTECTOR_ALL)
|
||||
if(HAVE_STACK_PROTECTOR_ALL)
|
||||
target_link_options(${target} PRIVATE -fstack-protector-all)
|
||||
else()
|
||||
check_c_compiler_flag("-fstack-protector" HAVE_STACK_PROTECTOR)
|
||||
if(HAVE_STACK_PROTECTOR)
|
||||
target_link_options(${target} PRIVATE -fstack-protector)
|
||||
else()
|
||||
message(WARNING "No stack protection supported")
|
||||
endif()
|
||||
endif()
|
||||
# Support address space layout randomization (ASLR)
|
||||
if(NOT (MINGW OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang"))
|
||||
target_compile_options(${target} PRIVATE -fPIE)
|
||||
target_link_options(${target} PRIVATE -fPIE -pie)
|
||||
target_link_options(${target} PRIVATE -Wl,-z,relro)
|
||||
target_link_options(${target} PRIVATE -Wl,-z,now)
|
||||
target_link_options(${target} PRIVATE -Wl,-z,noexecstack)
|
||||
endif(NOT (MINGW OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang"))
|
||||
target_link_options(${target} PRIVATE -fstack-check)
|
||||
add_compile_flag_to_targets(${target})
|
||||
endif(MSVC)
|
||||
endfunction()
|
||||
if(MSVC)
|
||||
# Enable parallel builds
|
||||
target_compile_options(${target} PRIVATE /MP)
|
||||
# Use address space layout randomization, generate PIE code for ASLR (default on)
|
||||
target_link_options(${target} PRIVATE /DYNAMICBASE)
|
||||
# Create terminal server aware application (default on)
|
||||
target_link_options(${target} PRIVATE /TSAWARE)
|
||||
# Mark the binary as compatible with Intel Control-flow Enforcement Technology (CET) Shadow Stack
|
||||
target_link_options(${target} PRIVATE /CETCOMPAT)
|
||||
# Enable compiler generation of Control Flow Guard security checks
|
||||
target_compile_options(${target} PRIVATE /guard:cf)
|
||||
target_link_options(${target} PRIVATE /guard:cf)
|
||||
# Buffer Security Check
|
||||
target_compile_options(${target} PRIVATE /GS)
|
||||
# Suppress startup banner
|
||||
target_link_options(${target} PRIVATE /NOLOGO)
|
||||
# Generate debug info
|
||||
target_link_options(${target} PRIVATE /DEBUG)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
# High entropy ASLR for 64 bits targets (default on)
|
||||
target_link_options(${target} PRIVATE /HIGHENTROPYVA)
|
||||
# Enable generation of EH Continuation (EHCONT) metadata by the compiler
|
||||
#target_compile_options(${target} PRIVATE /guard:ehcont)
|
||||
#target_link_options(${target} PRIVATE /guard:ehcont)
|
||||
else("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
# Can handle addresses larger than 2 gigabytes
|
||||
target_link_options(${target} PRIVATE /LARGEADDRESSAWARE)
|
||||
# Safe structured exception handlers (x86 only)
|
||||
target_link_options(${target} PRIVATE /SAFESEH)
|
||||
endif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:DEBUG>:/D_FORTIFY_SOURCE=2>)
|
||||
# Unrecognized compiler options are errors
|
||||
target_compile_options(${target} PRIVATE $<$<CONFIG:DEBUG>:/options:strict>)
|
||||
else(MSVC)
|
||||
check_c_compiler_flag("-fstack-protector-all" HAVE_STACK_PROTECTOR_ALL)
|
||||
if(HAVE_STACK_PROTECTOR_ALL)
|
||||
target_link_options(${target} PRIVATE -fstack-protector-all)
|
||||
else(HAVE_STACK_PROTECTOR_ALL)
|
||||
check_c_compiler_flag("-fstack-protector" HAVE_STACK_PROTECTOR)
|
||||
if(HAVE_STACK_PROTECTOR)
|
||||
target_link_options(${target} PRIVATE -fstack-protector)
|
||||
else(HAVE_STACK_PROTECTOR)
|
||||
message(WARNING "No stack protection supported")
|
||||
endif(HAVE_STACK_PROTECTOR)
|
||||
endif(HAVE_STACK_PROTECTOR_ALL)
|
||||
# Support address space layout randomization (ASLR)
|
||||
if(NOT (MINGW OR CYGWIN OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
|
||||
OR ((CMAKE_SYSTEM_NAME MATCHES Darwin) AND (CMAKE_C_COMPILER_ID MATCHES Clang))))
|
||||
target_compile_options(${target} PRIVATE -fPIE)
|
||||
target_link_options(${target} PRIVATE -fPIE -pie)
|
||||
target_link_options(${target} PRIVATE -Wl,-z,relro)
|
||||
target_link_options(${target} PRIVATE -Wl,-z,now)
|
||||
target_link_options(${target} PRIVATE -Wl,-z,noexecstack)
|
||||
endif(NOT (MINGW OR CYGWIN OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
|
||||
OR ((CMAKE_SYSTEM_NAME MATCHES Darwin) AND (CMAKE_C_COMPILER_ID MATCHES Clang))))
|
||||
target_link_options(${target} PRIVATE -fstack-check)
|
||||
add_compile_flag_to_targets(${target})
|
||||
endif(MSVC)
|
||||
endfunction(add_compile_flags target)
|
||||
|
||||
add_compile_flags(osslsigncode)
|
||||
|
||||
#[[
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
]]
|
||||
|
806
helpers.c
Normal file
806
helpers.c
Normal file
@ -0,0 +1,806 @@
|
||||
/*
|
||||
* osslsigncode support library
|
||||
*
|
||||
* Copyright (C) 2021-2023 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
* Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
|
||||
*/
|
||||
|
||||
#include "osslsigncode.h"
|
||||
#include "helpers.h"
|
||||
|
||||
/* Prototypes */
|
||||
static SpcSpOpusInfo *spc_sp_opus_info_create(FILE_FORMAT_CTX *ctx);
|
||||
static int spc_indirect_data_content_create(u_char **blob, int *len, FILE_FORMAT_CTX *ctx);
|
||||
static int pkcs7_signer_info_add_spc_sp_opus_info(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||
static int pkcs7_signer_info_add_signing_time(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||
static int pkcs7_signer_info_add_purpose(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||
static int pkcs7_signer_info_add_sequence_number(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
|
||||
static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer);
|
||||
static int X509_compare(const X509 *const *a, const X509 *const *b);
|
||||
|
||||
/*
|
||||
* Common functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* [in] infile
|
||||
* [returns] file size
|
||||
*/
|
||||
uint32_t get_file_size(const char *infile)
|
||||
{
|
||||
int ret;
|
||||
#ifdef _WIN32
|
||||
struct _stat64 st;
|
||||
ret = _stat64(infile, &st);
|
||||
#else
|
||||
struct stat st;
|
||||
ret = stat(infile, &st);
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("Failed to open file: %s\n", infile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (st.st_size < 4) {
|
||||
printf("Unrecognized file type - file is too short: %s\n", infile);
|
||||
return 0;
|
||||
}
|
||||
if (st.st_size > UINT32_MAX) {
|
||||
printf("Unsupported file - too large: %s\n", infile);
|
||||
return 0;
|
||||
}
|
||||
return (uint32_t)st.st_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] infile: starting address for the new mapping
|
||||
* [returns] pointer to the mapped area
|
||||
*/
|
||||
char *map_file(const char *infile, const size_t size)
|
||||
{
|
||||
char *indata = NULL;
|
||||
#ifdef WIN32
|
||||
HANDLE fhandle, fmap;
|
||||
(void)size;
|
||||
fhandle = CreateFile(infile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (fhandle == INVALID_HANDLE_VALUE) {
|
||||
return NULL;
|
||||
}
|
||||
fmap = CreateFileMapping(fhandle, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
CloseHandle(fhandle);
|
||||
if (fmap == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
indata = (char *)MapViewOfFile(fmap, FILE_MAP_READ, 0, 0, 0);
|
||||
CloseHandle(fmap);
|
||||
#else
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
int fd = open(infile, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
indata = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (indata == MAP_FAILED) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
close(fd);
|
||||
#else
|
||||
printf("No file mapping function\n");
|
||||
return NULL;
|
||||
#endif /* HAVE_SYS_MMAN_H */
|
||||
#endif /* WIN32 */
|
||||
return indata;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] indata: starting address space
|
||||
* [in] size: mapped area length
|
||||
* [returns] none
|
||||
*/
|
||||
void unmap_file(char *indata, const size_t size)
|
||||
{
|
||||
if (!indata)
|
||||
return;
|
||||
#ifdef WIN32
|
||||
(void)size;
|
||||
UnmapViewOfFile(indata);
|
||||
#else
|
||||
munmap(indata, size);
|
||||
#endif /* WIN32 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve a decoded PKCS#7 structure
|
||||
* [in] data: encoded PEM or DER data
|
||||
* [in] size: data size
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
PKCS7 *pkcs7_read_data(char *data, uint32_t size)
|
||||
{
|
||||
PKCS7 *p7 = NULL;
|
||||
BIO *bio;
|
||||
const char pemhdr[] = "-----BEGIN PKCS7-----";
|
||||
|
||||
bio = BIO_new_mem_buf(data, (int)size);
|
||||
if (size >= sizeof pemhdr && !memcmp(data, pemhdr, sizeof pemhdr - 1)) {
|
||||
/* PEM format */
|
||||
p7 = PEM_read_bio_PKCS7(bio, NULL, NULL, NULL);
|
||||
} else { /* DER format */
|
||||
p7 = d2i_PKCS7_bio(bio, NULL);
|
||||
}
|
||||
BIO_free_all(bio);
|
||||
return p7;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] outdata: BIO outdata file
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
int data_write_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
||||
{
|
||||
int ret;
|
||||
|
||||
(void)BIO_reset(outdata);
|
||||
if (ctx->options->output_pkcs7) {
|
||||
/* PEM format */
|
||||
ret = !PEM_write_bio_PKCS7(outdata, p7);
|
||||
} else {
|
||||
/* default DER format */
|
||||
ret = !i2d_PKCS7_bio(outdata, p7);
|
||||
}
|
||||
if (ret) {
|
||||
printf("Unable to write pkcs7 object\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate, set type, add content and return a new PKCS#7 signature
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
int i, signer = -1;
|
||||
PKCS7 *p7;
|
||||
PKCS7_SIGNER_INFO *si = NULL;
|
||||
STACK_OF(X509) *chain = NULL;
|
||||
|
||||
p7 = PKCS7_new();
|
||||
PKCS7_set_type(p7, NID_pkcs7_signed);
|
||||
PKCS7_content_new(p7, NID_pkcs7_data);
|
||||
if (ctx->options->cert != NULL) {
|
||||
/*
|
||||
* the private key and corresponding certificate are parsed from the PKCS12
|
||||
* structure or loaded from the security token, so we may omit to check
|
||||
* the consistency of a private key with the public key in an X509 certificate
|
||||
*/
|
||||
si = PKCS7_add_signature(p7, ctx->options->cert, ctx->options->pkey,
|
||||
ctx->options->md);
|
||||
if (si == NULL)
|
||||
return NULL; /* FAILED */
|
||||
} else {
|
||||
/* find the signer's certificate located somewhere in the whole certificate chain */
|
||||
for (i=0; i<sk_X509_num(ctx->options->certs); i++) {
|
||||
X509 *signcert = sk_X509_value(ctx->options->certs, i);
|
||||
if (X509_check_private_key(signcert, ctx->options->pkey)) {
|
||||
si = PKCS7_add_signature(p7, signcert, ctx->options->pkey, ctx->options->md);
|
||||
signer = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (si == NULL) {
|
||||
printf("Failed to checking the consistency of a private key: %s\n",
|
||||
ctx->options->keyfile);
|
||||
printf(" with a public key in any X509 certificate: %s\n\n",
|
||||
ctx->options->certfile);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
}
|
||||
if (!pkcs7_signer_info_add_signing_time(si, ctx)) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!pkcs7_signer_info_add_purpose(si, ctx)) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if ((ctx->options->desc || ctx->options->url) &&
|
||||
!pkcs7_signer_info_add_spc_sp_opus_info(si, ctx)) {
|
||||
printf("Couldn't allocate memory for opus info\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if ((ctx->options->nested_number >= 0) &&
|
||||
!pkcs7_signer_info_add_sequence_number(si, ctx)) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
/* create X509 chain sorted in ascending order by their DER encoding */
|
||||
chain = X509_chain_get_sorted(ctx, signer);
|
||||
if (chain == NULL) {
|
||||
printf("Failed to create a sorted certificate chain\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
/* add sorted certificate chain */
|
||||
for (i=0; i<sk_X509_num(chain); i++) {
|
||||
PKCS7_add_certificate(p7, sk_X509_value(chain, i));
|
||||
}
|
||||
/* add crls */
|
||||
if (ctx->options->crls) {
|
||||
for (i=0; i<sk_X509_CRL_num(ctx->options->crls); i++)
|
||||
PKCS7_add_crl(p7, sk_X509_CRL_value(ctx->options->crls, i));
|
||||
}
|
||||
sk_X509_free(chain);
|
||||
return p7; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* PE, MSI, CAB and APPX file specific
|
||||
* Add "1.3.6.1.4.1.311.2.1.4" SPC_INDIRECT_DATA_OBJID signed attribute
|
||||
* [in, out] p7: new PKCS#7 signature
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
int add_indirect_data_object(PKCS7 *p7)
|
||||
{
|
||||
STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
|
||||
PKCS7_SIGNER_INFO *si;
|
||||
|
||||
signer_info = PKCS7_get_signer_info(p7);
|
||||
if (!signer_info)
|
||||
return 0; /* FAILED */
|
||||
si = sk_PKCS7_SIGNER_INFO_value(signer_info, 0);
|
||||
if (!si)
|
||||
return 0; /* FAILED */
|
||||
if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
|
||||
V_ASN1_OBJECT, OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1)))
|
||||
return 0; /* FAILED */
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* PE, MSI, CAB and APPX format specific
|
||||
* Sign the MS Authenticode spcIndirectDataContent blob.
|
||||
* The spcIndirectDataContent structure is used in Authenticode signatures
|
||||
* to store the digest and other attributes of the signed file.
|
||||
* [in, out] p7: new PKCS#7 signature
|
||||
* [in] content: spcIndirectDataContent
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content)
|
||||
{
|
||||
int len, inf, tag, class;
|
||||
long plen;
|
||||
const u_char *data, *p;
|
||||
PKCS7 *td7;
|
||||
|
||||
p = data = ASN1_STRING_get0_data(content);
|
||||
len = ASN1_STRING_length(content);
|
||||
inf = ASN1_get_object(&p, &plen, &tag, &class, len);
|
||||
if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE
|
||||
|| !pkcs7_sign_content(p7, p, (int)plen)) {
|
||||
printf("Failed to sign spcIndirectDataContent\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
td7 = PKCS7_new();
|
||||
if (!td7) {
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
td7->type = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1);
|
||||
td7->d.other = ASN1_TYPE_new();
|
||||
td7->d.other->type = V_ASN1_SEQUENCE;
|
||||
td7->d.other->value.sequence = ASN1_STRING_new();
|
||||
ASN1_STRING_set(td7->d.other->value.sequence, data, len);
|
||||
if (!PKCS7_set_content(p7, td7)) {
|
||||
printf("PKCS7_set_content failed\n");
|
||||
PKCS7_free(td7);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Add encapsulated content to signed PKCS7 structure.
|
||||
* [in] content: spcIndirectDataContent
|
||||
* [returns] new PKCS#7 signature with encapsulated content
|
||||
*/
|
||||
PKCS7 *pkcs7_set_content(ASN1_OCTET_STRING *content)
|
||||
{
|
||||
PKCS7 *p7, *td7;
|
||||
|
||||
p7 = PKCS7_new();
|
||||
if (!p7) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!PKCS7_set_type(p7, NID_pkcs7_signed)) {
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!PKCS7_content_new(p7, NID_pkcs7_data)) {
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
td7 = PKCS7_new();
|
||||
if (!td7) {
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
td7->type = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1);
|
||||
td7->d.other = ASN1_TYPE_new();
|
||||
td7->d.other->type = V_ASN1_SEQUENCE;
|
||||
td7->d.other->value.sequence = content;
|
||||
if (!PKCS7_set_content(p7, td7)) {
|
||||
PKCS7_free(td7);
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
return p7;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return spcIndirectDataContent.
|
||||
* [in] hash: message digest BIO
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] content
|
||||
*/
|
||||
ASN1_OCTET_STRING *spc_indirect_data_content_get(BIO *hash, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
ASN1_OCTET_STRING *content;
|
||||
u_char mdbuf[5 * EVP_MAX_MD_SIZE + 24];
|
||||
int mdlen, hashlen, len = 0;
|
||||
u_char *data, *p = NULL;
|
||||
|
||||
content = ASN1_OCTET_STRING_new();
|
||||
if (!content) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!spc_indirect_data_content_create(&p, &len, ctx)) {
|
||||
ASN1_OCTET_STRING_free(content);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
hashlen = ctx->format->hash_length_get(ctx);
|
||||
if (hashlen > EVP_MAX_MD_SIZE) {
|
||||
/* APPX format specific */
|
||||
mdlen = BIO_read(hash, (char*)mdbuf, hashlen);
|
||||
} else {
|
||||
mdlen = BIO_gets(hash, (char*)mdbuf, EVP_MAX_MD_SIZE);
|
||||
}
|
||||
data = OPENSSL_malloc((size_t)(len + mdlen));
|
||||
memcpy(data, p, (size_t)len);
|
||||
OPENSSL_free(p);
|
||||
memcpy(data + len, mdbuf, (size_t)mdlen);
|
||||
if (!ASN1_OCTET_STRING_set(content, data, len + mdlen)) {
|
||||
ASN1_OCTET_STRING_free(content);
|
||||
OPENSSL_free(data);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
OPENSSL_free(data);
|
||||
return content;
|
||||
}
|
||||
|
||||
/*
|
||||
* Signs the data and place the signature in p7
|
||||
* [in, out] p7: new PKCS#7 signature
|
||||
* [in] data: content data
|
||||
* [in] len: content length
|
||||
*/
|
||||
int pkcs7_sign_content(PKCS7 *p7, const u_char *data, int len)
|
||||
{
|
||||
BIO *p7bio;
|
||||
|
||||
if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
|
||||
printf("PKCS7_dataInit failed\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
BIO_write(p7bio, data, len);
|
||||
(void)BIO_flush(p7bio);
|
||||
if (!PKCS7_dataFinal(p7, p7bio)) {
|
||||
printf("PKCS7_dataFinal failed\n");
|
||||
BIO_free_all(p7bio);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
BIO_free_all(p7bio);
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/* Return the header length (tag and length octets) of the ASN.1 type
|
||||
* [in] p: ASN.1 data
|
||||
* [in] len: ASN.1 data length
|
||||
* [returns] header length
|
||||
*/
|
||||
int asn1_simple_hdr_len(const u_char *p, int len)
|
||||
{
|
||||
if (len <= 2 || p[0] > 0x31)
|
||||
return 0;
|
||||
return (p[1]&0x80) ? (2 + (p[1]&0x7f)) : 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in, out] hash: BIO with message digest method
|
||||
* [in] indata: starting address space
|
||||
* [in] idx: offset
|
||||
* [in] fileend: the length of the hashed area
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
int bio_hash_data(BIO *hash, char *indata, size_t idx, size_t fileend)
|
||||
{
|
||||
while (idx < fileend) {
|
||||
size_t want, written;
|
||||
want = fileend - idx;
|
||||
if (want > SIZE_64K)
|
||||
want = SIZE_64K;
|
||||
if (!BIO_write_ex(hash, indata + idx, want, &written))
|
||||
return 0; /* FAILED */
|
||||
idx += written;
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] descript1, descript2: descriptions
|
||||
* [in] mdbuf: message digest
|
||||
* [in] len: message digest length
|
||||
* [returns] none
|
||||
*/
|
||||
void print_hash(const char *descript1, const char *descript2, const u_char *mdbuf, int len)
|
||||
{
|
||||
char *hexbuf = NULL;
|
||||
int size, i, j = 0;
|
||||
|
||||
size = 2 * len + 1;
|
||||
hexbuf = OPENSSL_malloc((size_t)size);
|
||||
for (i = 0; i < len; i++) {
|
||||
#ifdef WIN32
|
||||
j += sprintf_s(hexbuf + j, size - j, "%02X", mdbuf[i]);
|
||||
#else
|
||||
j += sprintf(hexbuf + j, "%02X", mdbuf[i]);
|
||||
#endif /* WIN32 */
|
||||
}
|
||||
printf("%s: %s %s\n", descript1, hexbuf, descript2);
|
||||
OPENSSL_free(hexbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] p7: new PKCS#7 signature
|
||||
* [in] objid: Microsoft OID Authenticode
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
int is_content_type(PKCS7 *p7, const char *objid)
|
||||
{
|
||||
ASN1_OBJECT *indir_objid;
|
||||
int ret;
|
||||
|
||||
indir_objid = OBJ_txt2obj(objid, 1);
|
||||
ret = p7 && PKCS7_type_is_signed(p7) &&
|
||||
!OBJ_cmp(p7->d.sign->contents->type, indir_objid) &&
|
||||
(p7->d.sign->contents->d.other->type == V_ASN1_SEQUENCE ||
|
||||
p7->d.sign->contents->d.other->type == V_ASN1_OCTET_STRING);
|
||||
ASN1_OBJECT_free(indir_objid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] p7: new PKCS#7 signature
|
||||
* [returns] pointer to MsCtlContent structure
|
||||
*/
|
||||
MsCtlContent *ms_ctl_content_get(PKCS7 *p7)
|
||||
{
|
||||
ASN1_STRING *value;
|
||||
const u_char *data;
|
||||
|
||||
if (!is_content_type(p7, MS_CTL_OBJID)) {
|
||||
printf("Failed to find MS_CTL_OBJID\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
value = p7->d.sign->contents->d.other->value.sequence;
|
||||
data = ASN1_STRING_get0_data(value);
|
||||
return d2i_MsCtlContent(NULL, &data, ASN1_STRING_length(value));
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] attribute: catalog attribute
|
||||
* [returns] catalog content
|
||||
*/
|
||||
ASN1_TYPE *catalog_content_get(CatalogAuthAttr *attribute)
|
||||
{
|
||||
ASN1_STRING *value;
|
||||
STACK_OF(ASN1_TYPE) *contents;
|
||||
ASN1_TYPE *content;
|
||||
const u_char *contents_data;
|
||||
|
||||
value = attribute->contents->value.sequence;
|
||||
contents_data = ASN1_STRING_get0_data(value);
|
||||
contents = d2i_ASN1_SET_ANY(NULL, &contents_data, ASN1_STRING_length(value));
|
||||
if (!contents)
|
||||
return 0; /* FAILED */
|
||||
content = sk_ASN1_TYPE_value(contents, 0);
|
||||
sk_ASN1_TYPE_free(contents);
|
||||
return content;
|
||||
}
|
||||
|
||||
/*
|
||||
* PE and CAB format specific
|
||||
* [in] none
|
||||
* [returns] pointer to SpcLink
|
||||
*/
|
||||
SpcLink *spc_link_obsolete_get(void)
|
||||
{
|
||||
const u_char obsolete[] = {
|
||||
0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x4f,
|
||||
0x00, 0x62, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x6c,
|
||||
0x00, 0x65, 0x00, 0x74, 0x00, 0x65, 0x00, 0x3e,
|
||||
0x00, 0x3e, 0x00, 0x3e
|
||||
};
|
||||
SpcLink *link = SpcLink_new();
|
||||
link->type = 2;
|
||||
link->value.file = SpcString_new();
|
||||
link->value.file->type = 0;
|
||||
link->value.file->value.unicode = ASN1_BMPSTRING_new();
|
||||
ASN1_STRING_set(link->value.file->value.unicode, obsolete, sizeof obsolete);
|
||||
return link;
|
||||
}
|
||||
|
||||
/*
|
||||
* [in] mdbuf, cmdbuf: message digests
|
||||
* [in] mdtype: message digest algorithm type
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
int compare_digests(u_char *mdbuf, u_char *cmdbuf, int mdtype)
|
||||
{
|
||||
int mdlen = EVP_MD_size(EVP_get_digestbynid(mdtype));
|
||||
int mdok = !memcmp(mdbuf, cmdbuf, (size_t)mdlen);
|
||||
printf("Message digest algorithm : %s\n", OBJ_nid2sn(mdtype));
|
||||
print_hash("Current message digest ", "", mdbuf, mdlen);
|
||||
print_hash("Calculated message digest ", mdok ? "\n" : " MISMATCH!!!\n", cmdbuf, mdlen);
|
||||
return mdok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* [in] ctx: FILE_FORMAT_CTX structure
|
||||
* [returns] pointer to SpcSpOpusInfo structure
|
||||
*/
|
||||
static SpcSpOpusInfo *spc_sp_opus_info_create(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
SpcSpOpusInfo *info = SpcSpOpusInfo_new();
|
||||
|
||||
if (ctx->options->desc) {
|
||||
info->programName = SpcString_new();
|
||||
info->programName->type = 1;
|
||||
info->programName->value.ascii = ASN1_IA5STRING_new();
|
||||
ASN1_STRING_set((ASN1_STRING *)info->programName->value.ascii,
|
||||
ctx->options->desc, (int)strlen(ctx->options->desc));
|
||||
}
|
||||
if (ctx->options->url) {
|
||||
info->moreInfo = SpcLink_new();
|
||||
info->moreInfo->type = 0;
|
||||
info->moreInfo->value.url = ASN1_IA5STRING_new();
|
||||
ASN1_STRING_set((ASN1_STRING *)info->moreInfo->value.url,
|
||||
ctx->options->url, (int)strlen(ctx->options->url));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/*
|
||||
* [out] blob: SpcIndirectDataContent data
|
||||
* [out] len: SpcIndirectDataContent data length
|
||||
* [in] ctx: FILE_FORMAT_CTX structure
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int spc_indirect_data_content_create(u_char **blob, int *len, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
u_char *p = NULL;
|
||||
int mdtype, hashlen, l = 0;
|
||||
void *hash;
|
||||
SpcIndirectDataContent *idc = SpcIndirectDataContent_new();
|
||||
|
||||
if (!ctx->format->data_blob_get || !ctx->format->hash_length_get) {
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (ctx->format->md_get) {
|
||||
/* APPX file specific - use a hash algorithm specified in the AppxBlockMap.xml file */
|
||||
mdtype = EVP_MD_nid(ctx->format->md_get(ctx));
|
||||
} else {
|
||||
mdtype = EVP_MD_nid(ctx->options->md);
|
||||
}
|
||||
idc->data->value = ASN1_TYPE_new();
|
||||
idc->data->value->type = V_ASN1_SEQUENCE;
|
||||
idc->data->value->value.sequence = ASN1_STRING_new();
|
||||
idc->data->type = ctx->format->data_blob_get(&p, &l, ctx);
|
||||
idc->data->value->value.sequence->data = p;
|
||||
idc->data->value->value.sequence->length = l;
|
||||
idc->messageDigest->digestAlgorithm->algorithm = OBJ_nid2obj(mdtype);
|
||||
idc->messageDigest->digestAlgorithm->parameters = ASN1_TYPE_new();
|
||||
idc->messageDigest->digestAlgorithm->parameters->type = V_ASN1_NULL;
|
||||
|
||||
hashlen = ctx->format->hash_length_get(ctx);
|
||||
hash = OPENSSL_zalloc((size_t)hashlen);
|
||||
ASN1_OCTET_STRING_set(idc->messageDigest->digest, hash, hashlen);
|
||||
OPENSSL_free(hash);
|
||||
|
||||
*len = i2d_SpcIndirectDataContent(idc, NULL);
|
||||
*blob = OPENSSL_malloc((size_t)*len);
|
||||
p = *blob;
|
||||
i2d_SpcIndirectDataContent(idc, &p);
|
||||
SpcIndirectDataContent_free(idc);
|
||||
*len -= hashlen;
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* [in, out] si: PKCS7_SIGNER_INFO structure
|
||||
* [in] ctx: FILE_FORMAT_CTX structure
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int pkcs7_signer_info_add_spc_sp_opus_info(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
SpcSpOpusInfo *opus;
|
||||
ASN1_STRING *astr;
|
||||
int len;
|
||||
u_char *p = NULL;
|
||||
|
||||
opus = spc_sp_opus_info_create(ctx);
|
||||
if ((len = i2d_SpcSpOpusInfo(opus, NULL)) <= 0
|
||||
|| (p = OPENSSL_malloc((size_t)len)) == NULL) {
|
||||
SpcSpOpusInfo_free(opus);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
i2d_SpcSpOpusInfo(opus, &p);
|
||||
p -= len;
|
||||
astr = ASN1_STRING_new();
|
||||
ASN1_STRING_set(astr, p, len);
|
||||
OPENSSL_free(p);
|
||||
SpcSpOpusInfo_free(opus);
|
||||
return PKCS7_add_signed_attribute(si, OBJ_txt2nid(SPC_SP_OPUS_INFO_OBJID),
|
||||
V_ASN1_SEQUENCE, astr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a custom, non-trusted time to the PKCS7 structure to prevent OpenSSL
|
||||
* adding the _current_ time. This allows to create a deterministic signature
|
||||
* when no trusted timestamp server was specified, making osslsigncode
|
||||
* behaviour closer to signtool.exe (which doesn't include any non-trusted
|
||||
* time in this case.)
|
||||
* [in, out] si: PKCS7_SIGNER_INFO structure
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int pkcs7_signer_info_add_signing_time(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
if (ctx->options->time == INVALID_TIME) /* -time option was not specified */
|
||||
return 1; /* SUCCESS */
|
||||
return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, V_ASN1_UTCTIME,
|
||||
ASN1_TIME_adj(NULL, ctx->options->time, 0, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* [in, out] si: PKCS7_SIGNER_INFO structure
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int pkcs7_signer_info_add_purpose(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
static const u_char purpose_ind[] = {
|
||||
0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
|
||||
0x01, 0x82, 0x37, 0x02, 0x01, 0x15
|
||||
};
|
||||
static const u_char purpose_comm[] = {
|
||||
0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
|
||||
0x01, 0x82, 0x37, 0x02, 0x01, 0x16
|
||||
};
|
||||
ASN1_STRING *purpose = ASN1_STRING_new();
|
||||
|
||||
if (ctx->options->comm) {
|
||||
ASN1_STRING_set(purpose, purpose_comm, sizeof purpose_comm);
|
||||
} else {
|
||||
ASN1_STRING_set(purpose, purpose_ind, sizeof purpose_ind);
|
||||
}
|
||||
return PKCS7_add_signed_attribute(si, OBJ_txt2nid(SPC_STATEMENT_TYPE_OBJID),
|
||||
V_ASN1_SEQUENCE, purpose);
|
||||
}
|
||||
|
||||
/*
|
||||
* [in, out] si: PKCS7_SIGNER_INFO structure
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int pkcs7_signer_info_add_sequence_number(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
ASN1_INTEGER *number = ASN1_INTEGER_new();
|
||||
|
||||
if (!number)
|
||||
return 0; /* FAILED */
|
||||
if (!ASN1_INTEGER_set(number, ctx->options->nested_number + 1)) {
|
||||
ASN1_INTEGER_free(number);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
return PKCS7_add_signed_attribute(si, OBJ_txt2nid(PKCS9_SEQUENCE_NUMBER),
|
||||
V_ASN1_INTEGER, number);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create certificate chain sorted in ascending order by their DER encoding.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] signer: signer's certificate number in the certificate chain
|
||||
* [returns] sorted certificate chain
|
||||
*/
|
||||
static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer)
|
||||
{
|
||||
int i;
|
||||
STACK_OF(X509) *chain = sk_X509_new(X509_compare);
|
||||
|
||||
/* add the signer's certificate */
|
||||
if (ctx->options->cert != NULL && !sk_X509_push(chain, ctx->options->cert)) {
|
||||
sk_X509_free(chain);
|
||||
return NULL;
|
||||
}
|
||||
if (signer != -1 && !sk_X509_push(chain, sk_X509_value(ctx->options->certs, signer))) {
|
||||
sk_X509_free(chain);
|
||||
return NULL;
|
||||
}
|
||||
/* add the certificate chain */
|
||||
for (i=0; i<sk_X509_num(ctx->options->certs); i++) {
|
||||
if (i == signer)
|
||||
continue;
|
||||
if (!sk_X509_push(chain, sk_X509_value(ctx->options->certs, i))) {
|
||||
sk_X509_free(chain);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* add all cross certificates */
|
||||
if (ctx->options->xcerts) {
|
||||
for (i=0; i<sk_X509_num(ctx->options->xcerts); i++) {
|
||||
if (!sk_X509_push(chain, sk_X509_value(ctx->options->xcerts, i))) {
|
||||
sk_X509_free(chain);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* sort certificate chain using the supplied comparison function */
|
||||
sk_X509_sort(chain);
|
||||
return chain;
|
||||
}
|
||||
|
||||
/*
|
||||
* X.690-compliant certificate comparison function
|
||||
* Windows requires catalog files to use PKCS#7
|
||||
* content ordering specified in X.690 section 11.6
|
||||
* https://support.microsoft.com/en-us/topic/october-13-2020-kb4580358-security-only-update-d3f6eb3c-d7c4-a9cb-0de6-759386bf7113
|
||||
* This algorithm is different from X509_cmp()
|
||||
* [in] a_ptr, b_ptr: pointers to X509 certificates
|
||||
* [returns] certificates order
|
||||
*/
|
||||
static int X509_compare(const X509 *const *a, const X509 *const *b)
|
||||
{
|
||||
u_char *a_data, *b_data, *a_tmp, *b_tmp;
|
||||
size_t a_len, b_len;
|
||||
int ret;
|
||||
|
||||
a_len = (size_t)i2d_X509(*a, NULL);
|
||||
a_tmp = a_data = OPENSSL_malloc(a_len);
|
||||
i2d_X509(*a, &a_tmp);
|
||||
|
||||
b_len = (size_t)i2d_X509(*b, NULL);
|
||||
b_tmp = b_data = OPENSSL_malloc(b_len);
|
||||
i2d_X509(*b, &b_tmp);
|
||||
|
||||
ret = memcmp(a_data, b_data, MIN(a_len, b_len));
|
||||
OPENSSL_free(a_data);
|
||||
OPENSSL_free(b_data);
|
||||
|
||||
if (ret == 0 && a_len != b_len) /* identical up to the length of the shorter DER */
|
||||
ret = a_len < b_len ? -1 : 1; /* shorter is smaller */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
vim: set ts=4 expandtab:
|
||||
*/
|
37
helpers.h
Normal file
37
helpers.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* osslsigncode support library
|
||||
*
|
||||
* Copyright (C) 2021-2023 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
* Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
|
||||
*/
|
||||
|
||||
/* Common functions */
|
||||
uint32_t get_file_size(const char *infile);
|
||||
char *map_file(const char *infile, const size_t size);
|
||||
void unmap_file(char *indata, const size_t size);
|
||||
PKCS7 *pkcs7_read_data(char *indata, uint32_t size);
|
||||
int data_write_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7);
|
||||
PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx);
|
||||
int add_indirect_data_object(PKCS7 *p7);
|
||||
int sign_spc_indirect_data_content(PKCS7 *p7, ASN1_OCTET_STRING *content);
|
||||
PKCS7 *pkcs7_set_content(ASN1_OCTET_STRING *content);
|
||||
ASN1_OCTET_STRING *spc_indirect_data_content_get(BIO *hash, FILE_FORMAT_CTX *ctx);
|
||||
int pkcs7_sign_content(PKCS7 *p7, const u_char *data, int len);
|
||||
int asn1_simple_hdr_len(const u_char *p, int len);
|
||||
int bio_hash_data(BIO *hash, char *indata, size_t idx, size_t fileend);
|
||||
void print_hash(const char *descript1, const char *descript2, const u_char *hashbuf, int length);
|
||||
int is_content_type(PKCS7 *p7, const char *objid);
|
||||
MsCtlContent *ms_ctl_content_get(PKCS7 *p7);
|
||||
ASN1_TYPE *catalog_content_get(CatalogAuthAttr *attribute);
|
||||
SpcLink *spc_link_obsolete_get(void);
|
||||
int compare_digests(u_char *mdbuf, u_char *cmdbuf, int mdtype);
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
vim: set ts=4 expandtab:
|
||||
*/
|
238
msi.h
238
msi.h
@ -1,238 +0,0 @@
|
||||
/*
|
||||
* MSI file support library
|
||||
*
|
||||
* Copyright (C) 2021 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
* Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
|
||||
*
|
||||
* Reference specifications:
|
||||
* http://en.wikipedia.org/wiki/Compound_File_Binary_Format
|
||||
* https://msdn.microsoft.com/en-us/library/dd942138.aspx
|
||||
* https://github.com/microsoft/compoundfilereader
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <openssl/safestack.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#define MAXREGSECT 0xfffffffa /* maximum regular sector number */
|
||||
#define DIFSECT 0xfffffffc /* specifies a DIFAT sector in the FAT */
|
||||
#define FATSECT 0xfffffffd /* specifies a FAT sector in the FAT */
|
||||
#define ENDOFCHAIN 0xfffffffe /* end of a linked chain of sectors */
|
||||
#define NOSTREAM 0xffffffff /* terminator or empty pointer */
|
||||
#define FREESECT 0xffffffff /* empty unallocated free sectors */
|
||||
|
||||
#define DIR_UNKNOWN 0
|
||||
#define DIR_STORAGE 1
|
||||
#define DIR_STREAM 2
|
||||
#define DIR_ROOT 5
|
||||
|
||||
#define RED_COLOR 0
|
||||
#define BLACK_COLOR 1
|
||||
|
||||
#define DIFAT_IN_HEADER 109
|
||||
#define MINI_STREAM_CUTOFF_SIZE 0x00001000 /* 4096 bytes */
|
||||
#define HEADER_SIZE 0x200 /* 512 bytes, independent of sector size */
|
||||
#define MAX_SECTOR_SIZE 0x1000 /* 4096 bytes */
|
||||
|
||||
#define HEADER_SIGNATURE 0x00 /* 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 */
|
||||
#define HEADER_CLSID 0x08 /* reserved and unused */
|
||||
#define HEADER_MINOR_VER 0x18 /* SHOULD be set to 0x003E */
|
||||
#define HEADER_MAJOR_VER 0x1a /* MUST be set to either 0x0003 (version 3) or 0x0004 (version 4) */
|
||||
#define HEADER_BYTE_ORDER 0x1c /* 0xfe 0xff == Intel Little Endian */
|
||||
#define HEADER_SECTOR_SHIFT 0x1e /* MUST be set to 0x0009, or 0x000c */
|
||||
#define HEADER_MINI_SECTOR_SHIFT 0x20 /* MUST be set to 0x0006 */
|
||||
#define RESERVED 0x22 /* reserved and unused */
|
||||
#define HEADER_DIR_SECTORS_NUM 0x28
|
||||
#define HEADER_FAT_SECTORS_NUM 0x2c
|
||||
#define HEADER_DIR_SECTOR_LOC 0x30
|
||||
#define HEADER_TRANSACTION 0x34
|
||||
#define HEADER_MINI_STREAM_CUTOFF 0x38 /* 4096 bytes */
|
||||
#define HEADER_MINI_FAT_SECTOR_LOC 0x3c
|
||||
#define HEADER_MINI_FAT_SECTORS_NUM 0x40
|
||||
#define HEADER_DIFAT_SECTOR_LOC 0x44
|
||||
#define HEADER_DIFAT_SECTORS_NUM 0x48
|
||||
#define HEADER_DIFAT 0x4c
|
||||
|
||||
#define DIRENT_SIZE 0x80 /* 128 bytes */
|
||||
#define DIRENT_MAX_NAME_SIZE 0x40 /* 64 bytes */
|
||||
|
||||
#define DIRENT_NAME 0x00
|
||||
#define DIRENT_NAME_LEN 0x40 /* length in bytes incl 0 terminator */
|
||||
#define DIRENT_TYPE 0x42
|
||||
#define DIRENT_COLOUR 0x43
|
||||
#define DIRENT_LEFT_SIBLING_ID 0x44
|
||||
#define DIRENT_RIGHT_SIBLING_ID 0x48
|
||||
#define DIRENT_CHILD_ID 0x4c
|
||||
#define DIRENT_CLSID 0x50
|
||||
#define DIRENT_STATE_BITS 0x60
|
||||
#define DIRENT_CREATE_TIME 0x64
|
||||
#define DIRENT_MODIFY_TIME 0x6c
|
||||
#define DIRENT_START_SECTOR_LOC 0x74
|
||||
#define DIRENT_FILE_SIZE 0x78
|
||||
|
||||
#define GET_UINT8_LE(p) ((const u_char *)(p))[0]
|
||||
|
||||
#define GET_UINT16_LE(p) (uint16_t)(((const u_char *)(p))[0] | \
|
||||
(((const u_char *)(p))[1] << 8))
|
||||
|
||||
#define GET_UINT32_LE(p) (uint32_t)(((const u_char *)(p))[0] | \
|
||||
(((const u_char *)(p))[1] << 8) | \
|
||||
(((const u_char *)(p))[2] << 16) | \
|
||||
(((const u_char *)(p))[3] << 24))
|
||||
|
||||
#define PUT_UINT8_LE(i, p) ((u_char *)(p))[0] = (u_char)((i) & 0xff);
|
||||
|
||||
#define PUT_UINT16_LE(i,p) ((u_char *)(p))[0] = (u_char)((i) & 0xff); \
|
||||
((u_char *)(p))[1] = (u_char)(((i) >> 8) & 0xff)
|
||||
|
||||
#define PUT_UINT32_LE(i,p) ((u_char *)(p))[0] = (u_char)((i) & 0xff); \
|
||||
((u_char *)(p))[1] = (u_char)(((i) >> 8) & 0xff); \
|
||||
((u_char *)(p))[2] = (u_char)(((i) >> 16) & 0xff); \
|
||||
((u_char *)(p))[3] = (u_char)(((i) >> 24) & 0xff)
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#define SIZE_64K 65536 /* 2^16 */
|
||||
#define SIZE_16M 16777216 /* 2^24 */
|
||||
|
||||
typedef unsigned char u_char;
|
||||
|
||||
typedef struct {
|
||||
u_char signature[8]; /* 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 */
|
||||
u_char unused_clsid[16]; /* reserved and unused */
|
||||
uint16_t minorVersion;
|
||||
uint16_t majorVersion;
|
||||
uint16_t byteOrder;
|
||||
uint16_t sectorShift; /* power of 2 */
|
||||
uint16_t miniSectorShift; /* power of 2 */
|
||||
u_char reserved[6]; /* reserved and unused */
|
||||
uint32_t numDirectorySector;
|
||||
uint32_t numFATSector;
|
||||
uint32_t firstDirectorySectorLocation;
|
||||
uint32_t transactionSignatureNumber; /* reserved */
|
||||
uint32_t miniStreamCutoffSize;
|
||||
uint32_t firstMiniFATSectorLocation;
|
||||
uint32_t numMiniFATSector;
|
||||
uint32_t firstDIFATSectorLocation;
|
||||
uint32_t numDIFATSector;
|
||||
uint32_t headerDIFAT[DIFAT_IN_HEADER];
|
||||
} MSI_FILE_HDR;
|
||||
|
||||
typedef struct {
|
||||
u_char name[DIRENT_MAX_NAME_SIZE];
|
||||
uint16_t nameLen;
|
||||
uint8_t type;
|
||||
uint8_t colorFlag;
|
||||
uint32_t leftSiblingID;
|
||||
uint32_t rightSiblingID;
|
||||
uint32_t childID;
|
||||
u_char clsid[16];
|
||||
u_char stateBits[4];
|
||||
u_char creationTime[8];
|
||||
u_char modifiedTime[8];
|
||||
uint32_t startSectorLocation;
|
||||
u_char size[8];
|
||||
} MSI_ENTRY;
|
||||
|
||||
typedef struct msi_dirent_struct {
|
||||
u_char name[DIRENT_MAX_NAME_SIZE];
|
||||
uint16_t nameLen;
|
||||
uint8_t type;
|
||||
MSI_ENTRY *entry;
|
||||
STACK_OF(MSI_DIRENT) *children;
|
||||
struct msi_dirent_struct *next; /* for cycle detection */
|
||||
} MSI_DIRENT;
|
||||
|
||||
DEFINE_STACK_OF(MSI_DIRENT)
|
||||
|
||||
typedef struct {
|
||||
const u_char *m_buffer;
|
||||
uint32_t m_bufferLen;
|
||||
MSI_FILE_HDR *m_hdr;
|
||||
uint32_t m_sectorSize;
|
||||
uint32_t m_minisectorSize;
|
||||
uint32_t m_miniStreamStartSector;
|
||||
} MSI_FILE;
|
||||
|
||||
typedef struct {
|
||||
char *header;
|
||||
char *ministream;
|
||||
char *minifat;
|
||||
char *fat;
|
||||
uint32_t dirtreeLen;
|
||||
uint32_t miniStreamLen;
|
||||
uint32_t minifatLen;
|
||||
uint32_t fatLen;
|
||||
uint32_t ministreamsMemallocCount;
|
||||
uint32_t minifatMemallocCount;
|
||||
uint32_t fatMemallocCount;
|
||||
uint32_t dirtreeSectorsCount;
|
||||
uint32_t minifatSectorsCount;
|
||||
uint32_t fatSectorsCount;
|
||||
uint32_t miniSectorNum;
|
||||
uint32_t sectorNum;
|
||||
uint32_t sectorSize;
|
||||
} MSI_OUT;
|
||||
|
||||
static const u_char msi_magic[] = {
|
||||
0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1
|
||||
};
|
||||
|
||||
static const u_char digital_signature[] = {
|
||||
0x05, 0x00, 0x44, 0x00, 0x69, 0x00, 0x67, 0x00,
|
||||
0x69, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6C, 0x00,
|
||||
0x53, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6E, 0x00,
|
||||
0x61, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00,
|
||||
0x65, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const u_char digital_signature_ex[] = {
|
||||
0x05, 0x00, 0x4D, 0x00, 0x73, 0x00, 0x69, 0x00,
|
||||
0x44, 0x00, 0x69, 0x00, 0x67, 0x00, 0x69, 0x00,
|
||||
0x74, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x53, 0x00,
|
||||
0x69, 0x00, 0x67, 0x00, 0x6E, 0x00, 0x61, 0x00,
|
||||
0x74, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00,
|
||||
0x45, 0x00, 0x78, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const u_char msi_root_entry[] = {
|
||||
0x52, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x74, 0x00,
|
||||
0x20, 0x00, 0x45, 0x00, 0x6E, 0x00, 0x74, 0x00,
|
||||
0x72, 0x00, 0x79, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const u_char msi_zeroes[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
int msi_file_read(MSI_FILE *msi, MSI_ENTRY *entry, uint32_t offset, char *buffer, uint32_t len);
|
||||
MSI_FILE *msi_file_new(char *buffer, uint32_t len);
|
||||
void msi_file_free(MSI_FILE *msi);
|
||||
MSI_ENTRY *msi_root_entry_get(MSI_FILE *msi);
|
||||
int msi_dirent_new(MSI_FILE *msi, MSI_ENTRY *entry, MSI_DIRENT *parent, MSI_DIRENT **ret);
|
||||
MSI_ENTRY *msi_signatures_get(MSI_DIRENT *dirent, MSI_ENTRY **dse);
|
||||
void msi_dirent_free(MSI_DIRENT *dirent);
|
||||
int msi_prehash_dir(MSI_DIRENT *dirent, BIO *hash, int is_root);
|
||||
int msi_hash_dir(MSI_FILE *msi, MSI_DIRENT *dirent, BIO *hash, int is_root);
|
||||
int msi_calc_digest(char *indata, int mdtype, u_char *mdbuf, uint32_t fileend);
|
||||
int msi_dirent_delete(MSI_DIRENT *dirent, const u_char *name, uint16_t nameLen);
|
||||
int msi_file_write(MSI_FILE *msi, MSI_DIRENT *dirent, u_char *p, uint32_t len,
|
||||
u_char *p_msiex, uint32_t len_msiex, BIO *outdata);
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: t
|
||||
End:
|
||||
|
||||
vim: set ts=4 noexpandtab:
|
||||
*/
|
10103
osslsigncode.c
10103
osslsigncode.c
File diff suppressed because it is too large
Load Diff
539
osslsigncode.h
Normal file
539
osslsigncode.h
Normal file
@ -0,0 +1,539 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2023 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
* Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
|
||||
*/
|
||||
|
||||
#define OPENSSL_API_COMPAT 0x10100000L
|
||||
#define OPENSSL_NO_DEPRECATED
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#define HAVE_WINDOWS_H
|
||||
#endif /* _MSC_VER || __MINGW32__ */
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#define NOCRYPT
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif /* HAVE_WINDOWS_H */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif /* HAVE_SYS_MMAN_H */
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
#include <termios.h>
|
||||
#endif /* HAVE_TERMIOS_H */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/crypto.h>
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
#endif /* OPENSSL_NO_ENGINE */
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#if OPENSSL_VERSION_NUMBER>=0x30000000L
|
||||
#include <openssl/provider.h>
|
||||
#endif /* OPENSSL_VERSION_NUMBER>=0x30000000L */
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/safestack.h>
|
||||
#include <openssl/ts.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h> /* X509_PURPOSE */
|
||||
|
||||
#ifdef ENABLE_CURL
|
||||
#ifdef __CYGWIN__
|
||||
#ifndef SOCKET
|
||||
#define SOCKET UINT_PTR
|
||||
#endif /* SOCKET */
|
||||
#endif /* __CYGWIN__ */
|
||||
#include <curl/curl.h>
|
||||
#endif /* ENABLE_CURL */
|
||||
|
||||
#define MAX_TS_SERVERS 256
|
||||
|
||||
#if defined (HAVE_TERMIOS_H) || defined (HAVE_GETPASS)
|
||||
#define PROVIDE_ASKPASS 1
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* not WIN32, because strcasecmp exists in MinGW */
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define remove_file(filename) _unlink(filename)
|
||||
#else
|
||||
#define remove_file(filename) unlink(filename)
|
||||
#endif /* WIN32 */
|
||||
|
||||
#define GET_UINT8_LE(p) ((const u_char *)(p))[0]
|
||||
|
||||
#define GET_UINT16_LE(p) (uint16_t)(((const u_char *)(p))[0] | \
|
||||
(((const u_char *)(p))[1] << 8))
|
||||
|
||||
#define GET_UINT32_LE(p) (uint32_t)(((const u_char *)(p))[0] | \
|
||||
(((const u_char *)(p))[1] << 8) | \
|
||||
(((const u_char *)(p))[2] << 16) | \
|
||||
(((const u_char *)(p))[3] << 24))
|
||||
|
||||
#define PUT_UINT8_LE(i, p) ((u_char *)(p))[0] = (u_char)((i) & 0xff);
|
||||
|
||||
#define PUT_UINT16_LE(i,p) ((u_char *)(p))[0] = (u_char)((i) & 0xff); \
|
||||
((u_char *)(p))[1] = (u_char)(((i) >> 8) & 0xff)
|
||||
|
||||
#define PUT_UINT32_LE(i,p) ((u_char *)(p))[0] = (u_char)((i) & 0xff); \
|
||||
((u_char *)(p))[1] = (u_char)(((i) >> 8) & 0xff); \
|
||||
((u_char *)(p))[2] = (u_char)(((i) >> 16) & 0xff); \
|
||||
((u_char *)(p))[3] = (u_char)(((i) >> 24) & 0xff)
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#define SIZE_64K 65536 /* 2^16 */
|
||||
#define SIZE_16M 16777216 /* 2^24 */
|
||||
|
||||
/*
|
||||
* Macro names:
|
||||
* linux: __BYTE_ORDER == __LITTLE_ENDIAN | __BIG_ENDIAN
|
||||
* BYTE_ORDER == LITTLE_ENDIAN | BIG_ENDIAN
|
||||
* bsd: _BYTE_ORDER == _LITTLE_ENDIAN | _BIG_ENDIAN
|
||||
* BYTE_ORDER == LITTLE_ENDIAN | BIG_ENDIAN
|
||||
* solaris: _LITTLE_ENDIAN | _BIG_ENDIAN
|
||||
*/
|
||||
|
||||
#ifndef BYTE_ORDER
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#define BIG_ENDIAN 4321
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif /* BYTE_ORDER */
|
||||
|
||||
#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN)
|
||||
#error "Cannot determine the endian-ness of this platform"
|
||||
#endif
|
||||
|
||||
#ifndef LOWORD
|
||||
#define LOWORD(x) ((x) & 0xFFFF)
|
||||
#endif /* LOWORD */
|
||||
#ifndef HIWORD
|
||||
#define HIWORD(x) (((x) >> 16) & 0xFFFF)
|
||||
#endif /* HIWORD */
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define LE_UINT16(x) ((((x) >> 8) & 0x00FF) | \
|
||||
(((x) << 8) & 0xFF00))
|
||||
#define LE_UINT32(x) (((x) >> 24) | \
|
||||
(((x) & 0x00FF0000) >> 8) | \
|
||||
(((x) & 0x0000FF00) << 8) | \
|
||||
((x) << 24))
|
||||
#else
|
||||
#define LE_UINT16(x) (x)
|
||||
#define LE_UINT32(x) (x)
|
||||
#endif /* BYTE_ORDER == BIG_ENDIAN */
|
||||
|
||||
#define MIN(a,b) ((a) < (b) ? a : b)
|
||||
#define INVALID_TIME ((time_t)-1)
|
||||
|
||||
/* Microsoft OID Authenticode */
|
||||
#define SPC_INDIRECT_DATA_OBJID "1.3.6.1.4.1.311.2.1.4"
|
||||
#define SPC_STATEMENT_TYPE_OBJID "1.3.6.1.4.1.311.2.1.11"
|
||||
#define SPC_SP_OPUS_INFO_OBJID "1.3.6.1.4.1.311.2.1.12"
|
||||
#define SPC_PE_IMAGE_DATA_OBJID "1.3.6.1.4.1.311.2.1.15"
|
||||
#define SPC_CAB_DATA_OBJID "1.3.6.1.4.1.311.2.1.25"
|
||||
#define SPC_SIPINFO_OBJID "1.3.6.1.4.1.311.2.1.30"
|
||||
#define SPC_PE_IMAGE_PAGE_HASHES_V1 "1.3.6.1.4.1.311.2.3.1" /* SHA1 */
|
||||
#define SPC_PE_IMAGE_PAGE_HASHES_V2 "1.3.6.1.4.1.311.2.3.2" /* SHA256 */
|
||||
#define SPC_NESTED_SIGNATURE_OBJID "1.3.6.1.4.1.311.2.4.1"
|
||||
/* Microsoft OID Time Stamping */
|
||||
#define SPC_TIME_STAMP_REQUEST_OBJID "1.3.6.1.4.1.311.3.2.1"
|
||||
#define SPC_RFC3161_OBJID "1.3.6.1.4.1.311.3.3.1"
|
||||
/* Microsoft OID Crypto 2.0 */
|
||||
#define MS_CTL_OBJID "1.3.6.1.4.1.311.10.1"
|
||||
/* Microsoft OID Catalog */
|
||||
#define CAT_NAMEVALUE_OBJID "1.3.6.1.4.1.311.12.2.1"
|
||||
/* Microsoft OID Microsoft_Java */
|
||||
#define MS_JAVA_SOMETHING "1.3.6.1.4.1.311.15.1"
|
||||
|
||||
#define SPC_UNAUTHENTICATED_DATA_BLOB_OBJID "1.3.6.1.4.1.42921.1.2.1"
|
||||
|
||||
/* Public Key Cryptography Standards PKCS#9 */
|
||||
#define PKCS9_MESSAGE_DIGEST "1.2.840.113549.1.9.4"
|
||||
#define PKCS9_SIGNING_TIME "1.2.840.113549.1.9.5"
|
||||
#define PKCS9_COUNTER_SIGNATURE "1.2.840.113549.1.9.6"
|
||||
#define PKCS9_SEQUENCE_NUMBER "1.2.840.113549.1.9.25.4"
|
||||
|
||||
/* WIN_CERTIFICATE structure declared in Wintrust.h */
|
||||
#define WIN_CERT_REVISION_2_0 0x0200
|
||||
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
|
||||
|
||||
/*
|
||||
* FLAG_PREV_CABINET is set if the cabinet file is not the first in a set
|
||||
* of cabinet files. When this bit is set, the szCabinetPrev and szDiskPrev
|
||||
* fields are present in this CFHEADER.
|
||||
*/
|
||||
#define FLAG_PREV_CABINET 0x0001
|
||||
/*
|
||||
* FLAG_NEXT_CABINET is set if the cabinet file is not the last in a set of
|
||||
* cabinet files. When this bit is set, the szCabinetNext and szDiskNext
|
||||
* fields are present in this CFHEADER.
|
||||
*/
|
||||
#define FLAG_NEXT_CABINET 0x0002
|
||||
/*
|
||||
* FLAG_RESERVE_PRESENT is set if the cabinet file contains any reserved
|
||||
* fields. When this bit is set, the cbCFHeader, cbCFFolder, and cbCFData
|
||||
* fields are present in this CFHEADER.
|
||||
*/
|
||||
#define FLAG_RESERVE_PRESENT 0x0004
|
||||
|
||||
#define DO_EXIT_0(x) { printf(x); goto err_cleanup; }
|
||||
#define DO_EXIT_1(x, y) { printf(x, y); goto err_cleanup; }
|
||||
#define DO_EXIT_2(x, y, z) { printf(x, y, z); goto err_cleanup; }
|
||||
|
||||
/* Default policy if request did not specify it. */
|
||||
#define TSA_POLICY1 "1.2.3.4.1"
|
||||
|
||||
typedef enum {
|
||||
CMD_SIGN,
|
||||
CMD_EXTRACT,
|
||||
CMD_EXTRACT_DATA,
|
||||
CMD_REMOVE,
|
||||
CMD_VERIFY,
|
||||
CMD_ADD,
|
||||
CMD_ATTACH,
|
||||
CMD_HELP,
|
||||
CMD_DEFAULT
|
||||
} cmd_type_t;
|
||||
|
||||
typedef unsigned char u_char;
|
||||
|
||||
typedef struct {
|
||||
char *infile;
|
||||
char *outfile;
|
||||
char *sigfile;
|
||||
char *certfile;
|
||||
char *xcertfile;
|
||||
char *keyfile;
|
||||
char *pvkfile;
|
||||
char *pkcs12file;
|
||||
int output_pkcs7;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
char *p11engine;
|
||||
char *p11module;
|
||||
char *p11cert;
|
||||
#endif /* OPENSSL_NO_ENGINE */
|
||||
int askpass;
|
||||
char *readpass;
|
||||
char *pass;
|
||||
int comm;
|
||||
int pagehash;
|
||||
char *desc;
|
||||
const EVP_MD *md;
|
||||
char *url;
|
||||
time_t time;
|
||||
char *turl[MAX_TS_SERVERS];
|
||||
int nturl;
|
||||
char *tsurl[MAX_TS_SERVERS];
|
||||
int ntsurl;
|
||||
char *proxy;
|
||||
int noverifypeer;
|
||||
int addBlob;
|
||||
int nest;
|
||||
int index;
|
||||
int ignore_timestamp;
|
||||
int ignore_cdp;
|
||||
int verbose;
|
||||
int add_msi_dse;
|
||||
char *catalog;
|
||||
char *cafile;
|
||||
char *crlfile;
|
||||
char *tsa_cafile;
|
||||
char *tsa_crlfile;
|
||||
char *leafhash;
|
||||
int jp;
|
||||
#if OPENSSL_VERSION_NUMBER>=0x30000000L
|
||||
int legacy;
|
||||
#endif /* OPENSSL_VERSION_NUMBER>=0x30000000L */
|
||||
EVP_PKEY *pkey;
|
||||
X509 *cert;
|
||||
STACK_OF(X509) *certs;
|
||||
STACK_OF(X509) *xcerts;
|
||||
STACK_OF(X509_CRL) *crls;
|
||||
cmd_type_t cmd;
|
||||
char *indata;
|
||||
char *tsa_certfile;
|
||||
char *tsa_keyfile;
|
||||
time_t tsa_time;
|
||||
int nested_number;
|
||||
} GLOBAL_OPTIONS;
|
||||
|
||||
/*
|
||||
* ASN.1 definitions (more or less from official MS Authenticode docs)
|
||||
*/
|
||||
typedef struct {
|
||||
int type;
|
||||
union {
|
||||
ASN1_BMPSTRING *unicode;
|
||||
ASN1_IA5STRING *ascii;
|
||||
} value;
|
||||
} SpcString;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcString)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OCTET_STRING *classId;
|
||||
ASN1_OCTET_STRING *serializedData;
|
||||
} SpcSerializedObject;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcSerializedObject)
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
union {
|
||||
ASN1_IA5STRING *url;
|
||||
SpcSerializedObject *moniker;
|
||||
SpcString *file;
|
||||
} value;
|
||||
} SpcLink;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcLink)
|
||||
|
||||
typedef struct {
|
||||
SpcString *programName;
|
||||
SpcLink *moreInfo;
|
||||
} SpcSpOpusInfo;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcSpOpusInfo)
|
||||
|
||||
typedef struct {
|
||||
ASN1_INTEGER *a;
|
||||
ASN1_OCTET_STRING *string;
|
||||
ASN1_INTEGER *b;
|
||||
ASN1_INTEGER *c;
|
||||
ASN1_INTEGER *d;
|
||||
ASN1_INTEGER *e;
|
||||
ASN1_INTEGER *f;
|
||||
} SpcSipInfo;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcSipInfo)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OBJECT *type;
|
||||
ASN1_TYPE *value;
|
||||
} SpcAttributeTypeAndOptionalValue;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcAttributeTypeAndOptionalValue)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OBJECT *algorithm;
|
||||
ASN1_TYPE *parameters;
|
||||
} AlgorithmIdentifier;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(AlgorithmIdentifier)
|
||||
|
||||
typedef struct {
|
||||
AlgorithmIdentifier *digestAlgorithm;
|
||||
ASN1_OCTET_STRING *digest;
|
||||
} DigestInfo;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(DigestInfo)
|
||||
|
||||
typedef struct {
|
||||
SpcAttributeTypeAndOptionalValue *data;
|
||||
DigestInfo *messageDigest;
|
||||
} SpcIndirectDataContent;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(SpcIndirectDataContent)
|
||||
|
||||
typedef struct CatalogAuthAttr_st {
|
||||
ASN1_OBJECT *type;
|
||||
ASN1_TYPE *contents;
|
||||
} CatalogAuthAttr;
|
||||
|
||||
DEFINE_STACK_OF(CatalogAuthAttr)
|
||||
DECLARE_ASN1_FUNCTIONS(CatalogAuthAttr)
|
||||
|
||||
typedef struct {
|
||||
AlgorithmIdentifier *digestAlgorithm;
|
||||
ASN1_OCTET_STRING *digest;
|
||||
} MessageImprint;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(MessageImprint)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OBJECT *type;
|
||||
ASN1_OCTET_STRING *signature;
|
||||
} TimeStampRequestBlob;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampRequestBlob)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OBJECT *type;
|
||||
TimeStampRequestBlob *blob;
|
||||
} TimeStampRequest;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampRequest)
|
||||
|
||||
/* RFC3161 Time stamping */
|
||||
|
||||
typedef struct {
|
||||
ASN1_INTEGER *status;
|
||||
STACK_OF(ASN1_UTF8STRING) *statusString;
|
||||
ASN1_BIT_STRING *failInfo;
|
||||
} PKIStatusInfo;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(PKIStatusInfo)
|
||||
|
||||
typedef struct {
|
||||
PKIStatusInfo *status;
|
||||
PKCS7 *token;
|
||||
} TimeStampResp;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampResp)
|
||||
|
||||
typedef struct {
|
||||
ASN1_INTEGER *version;
|
||||
MessageImprint *messageImprint;
|
||||
ASN1_OBJECT *reqPolicy;
|
||||
ASN1_INTEGER *nonce;
|
||||
ASN1_BOOLEAN certReq;
|
||||
STACK_OF(X509_EXTENSION) *extensions;
|
||||
} TimeStampReq;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampReq)
|
||||
|
||||
typedef struct {
|
||||
ASN1_INTEGER *seconds;
|
||||
ASN1_INTEGER *millis;
|
||||
ASN1_INTEGER *micros;
|
||||
} TimeStampAccuracy;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampAccuracy)
|
||||
|
||||
typedef struct {
|
||||
ASN1_INTEGER *version;
|
||||
ASN1_OBJECT *policy_id;
|
||||
MessageImprint *messageImprint;
|
||||
ASN1_INTEGER *serial;
|
||||
ASN1_GENERALIZEDTIME *time;
|
||||
TimeStampAccuracy *accuracy;
|
||||
ASN1_BOOLEAN ordering;
|
||||
ASN1_INTEGER *nonce;
|
||||
GENERAL_NAME *tsa;
|
||||
STACK_OF(X509_EXTENSION) *extensions;
|
||||
} TimeStampToken;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(TimeStampToken)
|
||||
|
||||
typedef struct {
|
||||
ASN1_OCTET_STRING *digest;
|
||||
STACK_OF(CatalogAuthAttr) *attributes;
|
||||
} CatalogInfo;
|
||||
|
||||
DEFINE_STACK_OF(CatalogInfo)
|
||||
DECLARE_ASN1_FUNCTIONS(CatalogInfo)
|
||||
|
||||
typedef struct {
|
||||
/* 1.3.6.1.4.1.311.12.1.1 MS_CATALOG_LIST */
|
||||
SpcAttributeTypeAndOptionalValue *type;
|
||||
ASN1_OCTET_STRING *identifier;
|
||||
ASN1_UTCTIME *time;
|
||||
/* 1.3.6.1.4.1.311.12.1.2 CatalogVersion = 1
|
||||
* 1.3.6.1.4.1.311.12.1.3 CatalogVersion = 2 */
|
||||
SpcAttributeTypeAndOptionalValue *version;
|
||||
STACK_OF(CatalogInfo) *header_attributes;
|
||||
/* 1.3.6.1.4.1.311.12.2.1 CAT_NAMEVALUE_OBJID */
|
||||
ASN1_TYPE *filename;
|
||||
} MsCtlContent;
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(MsCtlContent)
|
||||
|
||||
typedef struct file_format_st FILE_FORMAT;
|
||||
|
||||
typedef struct script_ctx_st SCRIPT_CTX;
|
||||
typedef struct msi_ctx_st MSI_CTX;
|
||||
typedef struct pe_ctx_st PE_CTX;
|
||||
typedef struct cab_ctx_st CAB_CTX;
|
||||
typedef struct cat_ctx_st CAT_CTX;
|
||||
typedef struct appx_ctx_st APPX_CTX;
|
||||
|
||||
typedef struct {
|
||||
FILE_FORMAT *format;
|
||||
GLOBAL_OPTIONS *options;
|
||||
union {
|
||||
SCRIPT_CTX *script_ctx;
|
||||
MSI_CTX *msi_ctx;
|
||||
PE_CTX *pe_ctx;
|
||||
CAB_CTX *cab_ctx;
|
||||
CAT_CTX *cat_ctx;
|
||||
APPX_CTX *appx_ctx;
|
||||
};
|
||||
} FILE_FORMAT_CTX;
|
||||
|
||||
extern FILE_FORMAT file_format_script;
|
||||
extern FILE_FORMAT file_format_msi;
|
||||
extern FILE_FORMAT file_format_pe;
|
||||
extern FILE_FORMAT file_format_cab;
|
||||
extern FILE_FORMAT file_format_cat;
|
||||
extern FILE_FORMAT file_format_appx;
|
||||
|
||||
struct file_format_st {
|
||||
FILE_FORMAT_CTX *(*ctx_new) (GLOBAL_OPTIONS *option, BIO *hash, BIO *outdata);
|
||||
const EVP_MD *(*md_get) (FILE_FORMAT_CTX *ctx);
|
||||
ASN1_OBJECT *(*data_blob_get) (u_char **p, int *plen, FILE_FORMAT_CTX *ctx);
|
||||
PKCS7 *(*pkcs7_contents_get) (FILE_FORMAT_CTX *ctx, BIO *hash, const EVP_MD *md);
|
||||
int (*hash_length_get) (FILE_FORMAT_CTX *ctx);
|
||||
u_char *(*digest_calc) (FILE_FORMAT_CTX *ctx, const EVP_MD *md);
|
||||
int (*verify_digests) (FILE_FORMAT_CTX *ctx, PKCS7 *p7);
|
||||
int (*verify_indirect_data) (FILE_FORMAT_CTX *ctx, SpcAttributeTypeAndOptionalValue *obj);
|
||||
PKCS7 *(*pkcs7_extract) (FILE_FORMAT_CTX *ctx);
|
||||
PKCS7 *(*pkcs7_extract_to_nest) (FILE_FORMAT_CTX *ctx);
|
||||
int (*remove_pkcs7) (FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
|
||||
int (*process_data) (FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
|
||||
PKCS7 *(*pkcs7_signature_new) (FILE_FORMAT_CTX *ctx, BIO *hash);
|
||||
int (*append_pkcs7) (FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7);
|
||||
void (*update_data_size) (FILE_FORMAT_CTX *data, BIO *outdata, PKCS7 *p7);
|
||||
void (*bio_free) (BIO *hash, BIO *outdata);
|
||||
void (*ctx_cleanup) (FILE_FORMAT_CTX *ctx);
|
||||
int (*is_detaching_supported) (void);
|
||||
};
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
vim: set ts=4 expandtab:
|
||||
*/
|
891
script.c
Normal file
891
script.c
Normal file
@ -0,0 +1,891 @@
|
||||
/*
|
||||
* Script file support library
|
||||
*
|
||||
* Copyright (C) 2021-2024 Michał Trojnara <Michal.Trojnara@stunnel.org>
|
||||
*/
|
||||
|
||||
#include "osslsigncode.h"
|
||||
#include "helpers.h"
|
||||
#include "utf.h"
|
||||
|
||||
typedef enum {comment_hash, comment_xml, comment_c, comment_not_found} comment_style;
|
||||
|
||||
typedef struct {
|
||||
const char *extension;
|
||||
comment_style comment;
|
||||
} SCRIPT_FORMAT;
|
||||
|
||||
const SCRIPT_FORMAT supported_formats[] = {
|
||||
{".ps1", comment_hash},
|
||||
{".ps1xml", comment_xml},
|
||||
{".psc1", comment_xml},
|
||||
{".psd1", comment_hash},
|
||||
{".psm1", comment_hash},
|
||||
{".cdxml", comment_xml},
|
||||
{".mof", comment_c},
|
||||
{NULL, comment_not_found},
|
||||
};
|
||||
|
||||
const char *signature_header = "SIG # Begin signature block";
|
||||
const char *signature_footer = "SIG # End signature block";
|
||||
|
||||
typedef struct {
|
||||
const char *open;
|
||||
const char *close;
|
||||
} SCRIPT_COMMENT;
|
||||
|
||||
const SCRIPT_COMMENT comment_text[] = {
|
||||
[comment_hash] = {"# ", ""},
|
||||
[comment_xml] = {"<!-- ", " -->"},
|
||||
[comment_c] = {"/* ", " */"}
|
||||
};
|
||||
|
||||
struct script_ctx_st {
|
||||
const SCRIPT_COMMENT *comment_text;
|
||||
int utf;
|
||||
uint32_t sigpos;
|
||||
uint32_t fileend;
|
||||
};
|
||||
|
||||
#define LINE_MAX_LEN 100
|
||||
|
||||
/* FILE_FORMAT method prototypes */
|
||||
static FILE_FORMAT_CTX *script_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *outdata);
|
||||
static ASN1_OBJECT *script_spc_sip_info_get(u_char **p, int *plen, FILE_FORMAT_CTX *ctx);
|
||||
static PKCS7 *script_pkcs7_contents_get(FILE_FORMAT_CTX *ctx, BIO *hash, const EVP_MD *md);
|
||||
static int script_hash_length_get(FILE_FORMAT_CTX *ctx);
|
||||
static u_char *script_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md);
|
||||
static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7);
|
||||
static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx);
|
||||
static PKCS7 *script_pkcs7_extract_to_nest(FILE_FORMAT_CTX *ctx);
|
||||
static int script_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
|
||||
static int script_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata);
|
||||
static PKCS7 *script_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash);
|
||||
static int script_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7);
|
||||
static void script_bio_free(BIO *hash, BIO *outdata);
|
||||
static void script_ctx_cleanup(FILE_FORMAT_CTX *ctx);
|
||||
static int script_is_detaching_supported(void);
|
||||
|
||||
FILE_FORMAT file_format_script = {
|
||||
.ctx_new = script_ctx_new,
|
||||
.data_blob_get = script_spc_sip_info_get,
|
||||
.pkcs7_contents_get = script_pkcs7_contents_get,
|
||||
.hash_length_get = script_hash_length_get,
|
||||
.digest_calc = script_digest_calc,
|
||||
.verify_digests = script_verify_digests,
|
||||
.pkcs7_extract = script_pkcs7_extract,
|
||||
.pkcs7_extract_to_nest = script_pkcs7_extract_to_nest,
|
||||
.remove_pkcs7 = script_remove_pkcs7,
|
||||
.process_data = script_process_data,
|
||||
.pkcs7_signature_new = script_pkcs7_signature_new,
|
||||
.append_pkcs7 = script_append_pkcs7,
|
||||
.bio_free = script_bio_free,
|
||||
.ctx_cleanup = script_ctx_cleanup,
|
||||
.is_detaching_supported = script_is_detaching_supported
|
||||
};
|
||||
|
||||
/* helper functions */
|
||||
static SCRIPT_CTX *script_ctx_get(char *indata, uint32_t filesize, const SCRIPT_COMMENT *comment, int utf);
|
||||
static int write_commented(FILE_FORMAT_CTX *ctx, BIO *outdata, const char *data, size_t length);
|
||||
static int write_in_encoding(FILE_FORMAT_CTX *ctx, BIO *outdata, const char *line, size_t length);
|
||||
static size_t utf8_to_utf16(const char *data, size_t len, uint16_t **out_utf16);
|
||||
static size_t utf16_to_utf8(const uint16_t *data, size_t len, char **out_utf8);
|
||||
static BIO *script_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md);
|
||||
static int script_digest_convert(BIO *hash, FILE_FORMAT_CTX *ctx, size_t len);
|
||||
static int script_write_bio(BIO *data, char *indata, size_t len);
|
||||
static int script_check_file(FILE_FORMAT_CTX *ctx);
|
||||
|
||||
/*
|
||||
* Allocate and return a script file format context.
|
||||
* [in, out] options: structure holds the input data
|
||||
* [out] hash: message digest BIO
|
||||
* [in] outdata: outdata file BIO (unused)
|
||||
* [returns] pointer to script file format context
|
||||
*/
|
||||
static FILE_FORMAT_CTX *script_ctx_new(GLOBAL_OPTIONS *options, BIO *hash, BIO *outdata)
|
||||
{
|
||||
FILE_FORMAT_CTX *ctx;
|
||||
SCRIPT_CTX *script_ctx;
|
||||
const SCRIPT_FORMAT *fmt;
|
||||
uint32_t filesize;
|
||||
const uint8_t utf16_bom[] = {0xff, 0xfe};
|
||||
size_t name_len;
|
||||
int utf;
|
||||
|
||||
/* squash the unused parameter warning */
|
||||
(void)outdata;
|
||||
|
||||
/* find out whether our format is supported */
|
||||
name_len = strlen(options->infile);
|
||||
for (fmt = supported_formats; fmt->comment != comment_not_found; fmt++) {
|
||||
size_t ext_len = strlen(fmt->extension);
|
||||
if(name_len > ext_len && !strcasecmp(options->infile + name_len - ext_len, fmt->extension))
|
||||
break;
|
||||
}
|
||||
if (fmt->comment == comment_not_found)
|
||||
return NULL;
|
||||
printf("Script file format: %s\n", fmt->extension);
|
||||
|
||||
filesize = get_file_size(options->infile);
|
||||
if (filesize == 0)
|
||||
return NULL; /* FAILED */
|
||||
|
||||
options->indata = map_file(options->infile, filesize);
|
||||
if (!options->indata) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
utf = memcmp(options->indata, utf16_bom, sizeof utf16_bom) ? 8 : 16;
|
||||
|
||||
/* initialize script context */
|
||||
script_ctx = script_ctx_get(options->indata, filesize, comment_text + fmt->comment, utf);
|
||||
if (!script_ctx) {
|
||||
unmap_file(options->indata, filesize);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
|
||||
/* initialize file format context */
|
||||
ctx = OPENSSL_malloc(sizeof(FILE_FORMAT_CTX));
|
||||
memset(ctx, 0, sizeof(FILE_FORMAT_CTX));
|
||||
ctx->format = &file_format_script;
|
||||
ctx->options = options;
|
||||
ctx->script_ctx = script_ctx;
|
||||
|
||||
if (hash)
|
||||
BIO_push(hash, BIO_new(BIO_s_null()));
|
||||
|
||||
/* FIXME: user interface logic belongs to osslsigncode.c */
|
||||
if (options->pagehash == 1)
|
||||
printf("Warning: -ph option is only valid for PE files\n");
|
||||
if (options->jp >= 0)
|
||||
printf("Warning: -jp option is only valid for CAB files\n");
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and return SpcSipInfo object.
|
||||
* Subject Interface Package (SIP) is an internal Microsoft API for
|
||||
* transforming arbitrary files into a digestible stream.
|
||||
* These ClassIDs are found in the indirect data section and identify
|
||||
* the type of processor needed to validate the signature.
|
||||
* https://github.com/sassoftware/relic/blob/620d0b75ec67c0158a8a9120950abe04327d922f/lib/authenticode/structs.go#L154
|
||||
* [out] p: SpcSipInfo data
|
||||
* [out] plen: SpcSipInfo data length
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] pointer to ASN1_OBJECT structure corresponding to SPC_SIPINFO_OBJID
|
||||
*/
|
||||
static ASN1_OBJECT *script_spc_sip_info_get(u_char **p, int *plen, FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
const u_char SpcUUIDSipInfoPs[] = {
|
||||
0x1f, 0xcc, 0x3b, 0x60, 0x59, 0x4b, 0x08, 0x4e,
|
||||
0xb7, 0x24, 0xd2, 0xc6, 0x29, 0x7e, 0xf3, 0x51
|
||||
};
|
||||
ASN1_OBJECT *dtype;
|
||||
SpcSipInfo *si = SpcSipInfo_new();
|
||||
|
||||
/* squash the unused parameter warning */
|
||||
(void)ctx;
|
||||
|
||||
ASN1_INTEGER_set(si->a, 65536);
|
||||
ASN1_INTEGER_set(si->b, 0);
|
||||
ASN1_INTEGER_set(si->c, 0);
|
||||
ASN1_INTEGER_set(si->d, 0);
|
||||
ASN1_INTEGER_set(si->e, 0);
|
||||
ASN1_INTEGER_set(si->f, 0);
|
||||
ASN1_OCTET_STRING_set(si->string, SpcUUIDSipInfoPs, sizeof SpcUUIDSipInfoPs);
|
||||
*plen = i2d_SpcSipInfo(si, NULL);
|
||||
*p = OPENSSL_malloc((size_t)*plen);
|
||||
i2d_SpcSipInfo(si, p);
|
||||
*p -= *plen;
|
||||
dtype = OBJ_txt2obj(SPC_SIPINFO_OBJID, 1);
|
||||
SpcSipInfo_free(si);
|
||||
return dtype; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and return a data content to be signed.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] hash: message digest BIO
|
||||
* [in] md: message digest algorithm
|
||||
* [returns] data content
|
||||
*/
|
||||
static PKCS7 *script_pkcs7_contents_get(FILE_FORMAT_CTX *ctx, BIO *hash, const EVP_MD *md)
|
||||
{
|
||||
ASN1_OCTET_STRING *content;
|
||||
BIO *bhash;
|
||||
|
||||
/* squash the unused parameter warning */
|
||||
(void)hash;
|
||||
|
||||
bhash = script_digest_calc_bio(ctx, md);
|
||||
if (!bhash) {
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
content = spc_indirect_data_content_get(bhash, ctx);
|
||||
BIO_free_all(bhash);
|
||||
return pkcs7_set_content(content);
|
||||
}
|
||||
|
||||
static int script_hash_length_get(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
return EVP_MD_size(ctx->options->md);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute a simple sha1/sha256 message digest of the MSI file
|
||||
* for use with a catalog file.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] md: message digest algorithm
|
||||
* [returns] pointer to calculated message digest
|
||||
*/
|
||||
static u_char *script_digest_calc(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
|
||||
{
|
||||
u_char *mdbuf;
|
||||
BIO *hash = BIO_new(BIO_f_md());
|
||||
|
||||
if (!BIO_set_md(hash, md)) {
|
||||
printf("Unable to set the message digest of BIO\n");
|
||||
BIO_free_all(hash);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
BIO_push(hash, BIO_new(BIO_s_null()));
|
||||
if (!script_write_bio(hash, ctx->options->indata, ctx->script_ctx->fileend)) {
|
||||
BIO_free_all(hash);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
mdbuf = OPENSSL_malloc((size_t)EVP_MD_size(md));
|
||||
BIO_gets(hash, (char*)mdbuf, EVP_MD_size(md));
|
||||
BIO_free_all(hash);
|
||||
return mdbuf; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the hash and compare to PKCS#7 signedData.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int script_verify_digests(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
|
||||
{
|
||||
int mdtype = -1;
|
||||
u_char mdbuf[EVP_MAX_MD_SIZE];
|
||||
u_char *cmdbuf = NULL;
|
||||
const EVP_MD *md;
|
||||
BIO *bhash;
|
||||
|
||||
/* FIXME: this shared code most likely belongs in osslsigncode.c */
|
||||
if (is_content_type(p7, SPC_INDIRECT_DATA_OBJID)) {
|
||||
ASN1_STRING *content_val = p7->d.sign->contents->d.other->value.sequence;
|
||||
const u_char *p = content_val->data;
|
||||
SpcIndirectDataContent *idc = d2i_SpcIndirectDataContent(NULL, &p, content_val->length);
|
||||
if (idc) {
|
||||
if (idc->messageDigest && idc->messageDigest->digest && idc->messageDigest->digestAlgorithm) {
|
||||
mdtype = OBJ_obj2nid(idc->messageDigest->digestAlgorithm->algorithm);
|
||||
memcpy(mdbuf, idc->messageDigest->digest->data, (size_t)idc->messageDigest->digest->length);
|
||||
}
|
||||
SpcIndirectDataContent_free(idc);
|
||||
}
|
||||
}
|
||||
if (mdtype == -1) {
|
||||
printf("Failed to extract current message digest\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
md = EVP_get_digestbynid(mdtype);
|
||||
bhash = script_digest_calc_bio(ctx, md);
|
||||
if (!bhash)
|
||||
return 0; /* FAILED */
|
||||
|
||||
cmdbuf = OPENSSL_malloc((size_t)EVP_MD_size(md));
|
||||
BIO_gets(bhash, (char*)cmdbuf, EVP_MD_size(md));
|
||||
BIO_free_all(bhash);
|
||||
|
||||
if (!compare_digests(mdbuf, cmdbuf, mdtype)) {
|
||||
printf("Signature verification: failed\n\n");
|
||||
OPENSSL_free(cmdbuf);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
OPENSSL_free(cmdbuf);
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract existing signature in DER format.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *script_pkcs7_extract(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
const char *signature_data = ctx->options->indata + ctx->script_ctx->sigpos;
|
||||
size_t signature_len = ctx->script_ctx->fileend - ctx->script_ctx->sigpos;
|
||||
size_t base64_len, der_max_length, der_length;
|
||||
char *ptr;
|
||||
BIO *bio_mem, *bio_b64 = NULL;
|
||||
char *base64_data = NULL;
|
||||
char *der_data = NULL;
|
||||
const char *der_tmp;
|
||||
char *clean_base64 = NULL;
|
||||
int clean_base64_len = 0;
|
||||
const char *open_tag = ctx->script_ctx->comment_text->open;
|
||||
const char *close_tag = ctx->script_ctx->comment_text->close;
|
||||
size_t open_tag_len = strlen(open_tag);
|
||||
size_t close_tag_len = strlen(close_tag);
|
||||
size_t signature_header_len = strlen(signature_header);
|
||||
size_t signature_footer_len = strlen(signature_footer);
|
||||
PKCS7 *retval = NULL;
|
||||
|
||||
if (!script_check_file(ctx)) {
|
||||
return NULL; /* FAILED, no signature */
|
||||
}
|
||||
/* extract Base64 signature */
|
||||
if (ctx->script_ctx->utf == 8) {
|
||||
base64_len = signature_len;
|
||||
base64_data = OPENSSL_malloc(base64_len);
|
||||
memcpy(base64_data, signature_data, base64_len);
|
||||
} else {
|
||||
base64_len = utf16_to_utf8((const void *)signature_data,
|
||||
signature_len, &base64_data);
|
||||
}
|
||||
|
||||
/* allocate memory for cleaned Base64 */
|
||||
clean_base64 = OPENSSL_malloc(base64_len);
|
||||
if (!clean_base64) {
|
||||
printf("Malloc failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* copy clean Base64 data */
|
||||
for (ptr = base64_data;;) {
|
||||
/* find the opening tag */
|
||||
for(;;) {
|
||||
if (ptr + open_tag_len >= base64_data + base64_len) {
|
||||
printf("Signature line too long\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if (!memcmp(ptr, open_tag, (size_t)open_tag_len)) {
|
||||
ptr += open_tag_len;
|
||||
break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
/* process signature_header and signature_footer */
|
||||
if (ptr + signature_header_len < base64_data + base64_len &&
|
||||
!memcmp(ptr, signature_header, signature_header_len))
|
||||
ptr += signature_header_len;
|
||||
if (ptr + signature_footer_len <= base64_data + base64_len &&
|
||||
!memcmp(ptr, signature_footer, signature_footer_len))
|
||||
break; /* success */
|
||||
|
||||
/* copy until the closing tag */
|
||||
for(;;) {
|
||||
if (ptr + close_tag_len >= base64_data + base64_len) {
|
||||
printf("Signature line too long\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if (close_tag_len) {
|
||||
if (!memcmp(ptr, close_tag, (size_t)close_tag_len)) {
|
||||
ptr += close_tag_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*ptr == '\r') {
|
||||
ptr++;
|
||||
} else if (*ptr == '\n') {
|
||||
ptr++;
|
||||
break;
|
||||
} else {
|
||||
clean_base64[clean_base64_len++] = *ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* prepare for Base64 decoding */
|
||||
bio_mem = BIO_new_mem_buf(clean_base64, clean_base64_len);
|
||||
bio_b64 = BIO_new(BIO_f_base64());
|
||||
BIO_push(bio_b64, bio_mem);
|
||||
BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
|
||||
/* allocate memory for DER output */
|
||||
der_max_length = BIO_ctrl_pending(bio_b64);
|
||||
der_data = OPENSSL_malloc(der_max_length);
|
||||
if (!der_data)
|
||||
goto cleanup;
|
||||
|
||||
/* decode Base64 to DER */
|
||||
if (!BIO_read_ex(bio_b64, der_data, der_max_length, &der_length))
|
||||
goto cleanup;
|
||||
if (der_length <= 0)
|
||||
goto cleanup;
|
||||
|
||||
/* decode DER */
|
||||
der_tmp = der_data;
|
||||
retval = d2i_PKCS7(NULL, (const unsigned char **)&der_tmp, (int)der_length);
|
||||
|
||||
cleanup:
|
||||
OPENSSL_free(base64_data);
|
||||
OPENSSL_free(clean_base64);
|
||||
OPENSSL_free(der_data);
|
||||
BIO_free_all(bio_b64);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract existing signature in DER format.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *script_pkcs7_extract_to_nest(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
return script_pkcs7_extract(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove existing signature.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int script_remove_pkcs7(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
||||
{
|
||||
/* squash the unused parameter warning */
|
||||
(void)hash;
|
||||
if (!script_check_file(ctx)) {
|
||||
return 1; /* FAILED, no signature */
|
||||
}
|
||||
if (!script_write_bio(outdata, ctx->options->indata, ctx->script_ctx->sigpos)) {
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize outdata file and calculate a hash (message digest) of data.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int script_process_data(FILE_FORMAT_CTX *ctx, BIO *hash, BIO *outdata)
|
||||
{
|
||||
if (ctx->script_ctx->sigpos > 0) {
|
||||
/* Strip current signature */
|
||||
ctx->script_ctx->fileend = ctx->script_ctx->sigpos;
|
||||
}
|
||||
if (!script_write_bio(outdata, ctx->options->indata, ctx->script_ctx->fileend))
|
||||
return 1; /* FAILED */
|
||||
if (!script_digest_convert(hash, ctx, ctx->script_ctx->fileend))
|
||||
return 1; /* FAILED */
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new PKCS#7 signature.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [returns] pointer to PKCS#7 structure
|
||||
*/
|
||||
static PKCS7 *script_pkcs7_signature_new(FILE_FORMAT_CTX *ctx, BIO *hash)
|
||||
{
|
||||
ASN1_OCTET_STRING *content;
|
||||
PKCS7 *p7 = pkcs7_create(ctx);
|
||||
|
||||
if (!p7) {
|
||||
printf("Creating a new signature failed\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!add_indirect_data_object(p7)) {
|
||||
printf("Adding SPC_INDIRECT_DATA_OBJID failed\n");
|
||||
PKCS7_free(p7);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
content = spc_indirect_data_content_get(hash, ctx);
|
||||
if (!content) {
|
||||
printf("Failed to get spcIndirectDataContent\n");
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
if (!sign_spc_indirect_data_content(p7, content)) {
|
||||
printf("Failed to set signed content\n");
|
||||
PKCS7_free(p7);
|
||||
ASN1_OCTET_STRING_free(content);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
ASN1_OCTET_STRING_free(content);
|
||||
return p7;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append signature to the outfile.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] outdata: outdata file BIO
|
||||
* [in] p7: PKCS#7 signature
|
||||
* [returns] 1 on error or 0 on success
|
||||
*/
|
||||
static int script_append_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
|
||||
{
|
||||
BIO *bio, *b64;
|
||||
BUF_MEM *buffer;
|
||||
size_t i;
|
||||
static const char crlf[] = {0x0d, 0x0a};
|
||||
int ret = 1;
|
||||
|
||||
/* convert to BASE64 */
|
||||
b64 = BIO_new(BIO_f_base64()); /* BIO for base64 encoding */
|
||||
if (!b64)
|
||||
return 1; /* FAILED */
|
||||
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
bio = BIO_new(BIO_s_mem()); /* BIO to hold the base64 data */
|
||||
if (!bio) {
|
||||
BIO_free(b64);
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
bio = BIO_push(b64, bio); /* chain base64 BIO onto memory BIO */
|
||||
if (!i2d_PKCS7_bio(bio, p7)) {
|
||||
BIO_free_all(bio);
|
||||
return 1; /* FAILED */
|
||||
}
|
||||
(void)BIO_flush(bio);
|
||||
BIO_get_mem_ptr(bio, &buffer);
|
||||
(void)BIO_set_close(bio, BIO_NOCLOSE);
|
||||
|
||||
/* split to individual lines and write to outdata */
|
||||
if (!write_commented(ctx, outdata, signature_header, strlen(signature_header)))
|
||||
goto cleanup;
|
||||
for (i = 0; i < buffer->length; i += 64) {
|
||||
if (!write_commented(ctx, outdata, buffer->data + i,
|
||||
buffer->length - i < 64 ? buffer->length - i : 64)) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (!write_commented(ctx, outdata, signature_footer, strlen(signature_footer)))
|
||||
goto cleanup;
|
||||
|
||||
/* signtool expects CRLF terminator at the end of the text file */
|
||||
if (!write_in_encoding(ctx, outdata, crlf, sizeof crlf))
|
||||
goto cleanup;
|
||||
ret = 0; /* OK */
|
||||
|
||||
cleanup:
|
||||
BUF_MEM_free(buffer);
|
||||
BIO_free_all(bio);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up an entire outdata BIO chain.
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] none
|
||||
*/
|
||||
static void script_bio_free(BIO *hash, BIO *outdata)
|
||||
{
|
||||
BIO_free_all(hash);
|
||||
BIO_free_all(outdata);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deallocate a FILE_FORMAT_CTX structure and script format specific structures.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [out] hash: message digest BIO
|
||||
* [out] outdata: outdata file BIO
|
||||
* [returns] none
|
||||
*/
|
||||
static void script_ctx_cleanup(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
unmap_file(ctx->options->indata, ctx->script_ctx->fileend);
|
||||
OPENSSL_free(ctx->script_ctx);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
static int script_is_detaching_supported(void)
|
||||
{
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Script helper functions
|
||||
*/
|
||||
|
||||
static SCRIPT_CTX *script_ctx_get(char *indata, uint32_t filesize, const SCRIPT_COMMENT *comment, int utf)
|
||||
{
|
||||
SCRIPT_CTX *script_ctx;
|
||||
|
||||
const char *input_pos, *signature_pos, *ptr;
|
||||
uint32_t line[LINE_MAX_LEN], commented_header[40], cr, lf;
|
||||
size_t sig_pos = 0, line_pos = 0, commented_header_len = 0;
|
||||
size_t commented_header_size = sizeof commented_header / sizeof(uint32_t);
|
||||
|
||||
utf8DecodeRune("\r", 1, &cr);
|
||||
utf8DecodeRune("\n", 1, &lf);
|
||||
|
||||
/* compute runes for the commented signature header */
|
||||
for (ptr = comment->open;
|
||||
*ptr && commented_header_len < commented_header_size;
|
||||
commented_header_len++)
|
||||
ptr = utf8DecodeRune(ptr, 1, commented_header + commented_header_len);
|
||||
for (ptr = signature_header;
|
||||
*ptr && commented_header_len < commented_header_size;
|
||||
commented_header_len++)
|
||||
ptr = utf8DecodeRune(ptr, 1, commented_header + commented_header_len);
|
||||
for (ptr = comment->close;
|
||||
*ptr && commented_header_len < commented_header_size;
|
||||
commented_header_len++)
|
||||
ptr = utf8DecodeRune(ptr, 1, commented_header + commented_header_len);
|
||||
|
||||
/* find the signature header */
|
||||
for (signature_pos = input_pos = indata; input_pos < indata + filesize; ) {
|
||||
const char *input_prev = input_pos;
|
||||
|
||||
input_pos = utf == 8 ?
|
||||
utf8DecodeRune(input_pos,
|
||||
(size_t)(indata + filesize - input_pos),
|
||||
line + line_pos) :
|
||||
(const char *)utf16DecodeRune((const void *)input_pos,
|
||||
(size_t)(indata + filesize - input_pos)/2,
|
||||
line + line_pos);
|
||||
|
||||
if (!memcmp(line + line_pos, &lf, sizeof lf)) {
|
||||
if (line_pos >= commented_header_len &&
|
||||
!memcmp(line, commented_header, commented_header_len * sizeof(uint32_t))) {
|
||||
sig_pos = (size_t)(signature_pos - indata);
|
||||
if (!memcmp(line + line_pos - 1, &cr, sizeof cr))
|
||||
sig_pos -= (size_t)utf / 8;
|
||||
break; /* SUCCEEDED */
|
||||
}
|
||||
line_pos = 0;
|
||||
signature_pos = input_prev; /* previous line */
|
||||
} else if (line_pos < LINE_MAX_LEN - 1) {
|
||||
line_pos++; /* we can ignore lines longer than our buffer */
|
||||
}
|
||||
}
|
||||
printf("Signature position: %zu\n", sig_pos);
|
||||
|
||||
script_ctx = OPENSSL_malloc(sizeof(SCRIPT_CTX));
|
||||
script_ctx->comment_text = comment;
|
||||
script_ctx->utf = utf;
|
||||
script_ctx->fileend = filesize;
|
||||
script_ctx->sigpos = (uint32_t)sig_pos;
|
||||
return script_ctx; /* OK */
|
||||
}
|
||||
|
||||
/* write a commented line to the bio:
|
||||
* - prepend with CRLF ("\r\n")
|
||||
* - add opening/closing comment tags
|
||||
* - adjust encoding if needed
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int write_commented(FILE_FORMAT_CTX *ctx, BIO *outdata, const char *data, size_t length)
|
||||
{
|
||||
const char *open_tag = ctx->script_ctx->comment_text->open;
|
||||
const char *close_tag = ctx->script_ctx->comment_text->close;
|
||||
size_t open_tag_len = strlen(open_tag);
|
||||
size_t close_tag_len = strlen(close_tag);
|
||||
char *line;
|
||||
|
||||
/* the buffer needs to be long enough for:
|
||||
* - CRLF ("\r\n")
|
||||
* - opening tag
|
||||
* - up to 64 bytes of data
|
||||
* - closing tag
|
||||
* - trailing NUL ("\0") */
|
||||
line = OPENSSL_malloc(2 + open_tag_len + length + close_tag_len + 1);
|
||||
strcpy(line, "\r\n");
|
||||
strcat(line, open_tag);
|
||||
memcpy(line + 2 + open_tag_len, data, length);
|
||||
line[2 + open_tag_len + length] = '\0';
|
||||
strcat(line, close_tag);
|
||||
|
||||
/* adjust encoding */
|
||||
if (!write_in_encoding(ctx, outdata, line, strlen(line))) {
|
||||
OPENSSL_free(line);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
OPENSSL_free(line);
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/* adjust encoding if needed
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int write_in_encoding(FILE_FORMAT_CTX *ctx, BIO *outdata, const char *line, size_t length)
|
||||
{
|
||||
size_t written;
|
||||
if (ctx->script_ctx->utf == 8) {
|
||||
if (!BIO_write_ex(outdata, line, length, &written)
|
||||
|| written != length) {
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
} else {
|
||||
uint16_t *utf16_data = NULL;
|
||||
size_t utf16_len = utf8_to_utf16(line, length, &utf16_data);
|
||||
|
||||
if (!BIO_write_ex(outdata, utf16_data, utf16_len, &written)
|
||||
|| written != utf16_len) {
|
||||
OPENSSL_free(utf16_data);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
OPENSSL_free(utf16_data);
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/* convert len bytes of UTF-8 to UTF-16
|
||||
* return the number of output bytes
|
||||
*/
|
||||
static size_t utf8_to_utf16(const char *data, size_t len, uint16_t **out_utf16)
|
||||
{
|
||||
size_t utf16_len = utf8UTF16Count(data, len);
|
||||
*out_utf16 = OPENSSL_malloc(utf16_len * sizeof(uint16_t));
|
||||
if (!*out_utf16)
|
||||
return 0; /* memory allocation failed */
|
||||
|
||||
const char *s = data;
|
||||
uint16_t *d = *out_utf16;
|
||||
uint32_t rune;
|
||||
size_t remaining_len = len;
|
||||
|
||||
while (remaining_len > 0) {
|
||||
s = utf8DecodeRune(s, remaining_len, &rune);
|
||||
if (!s || s < data)
|
||||
break; /* invalid UTF-8 sequence */
|
||||
size_t consumed = (size_t)(s - data);
|
||||
|
||||
remaining_len -= consumed;
|
||||
data = s;
|
||||
d += utf16EncodeRune(rune, d);
|
||||
}
|
||||
return (size_t)(2 * (d - *out_utf16));
|
||||
}
|
||||
|
||||
/* convert len bytes of UTF-16 to UTF-8
|
||||
* return the number of output bytes
|
||||
*/
|
||||
static size_t utf16_to_utf8(const uint16_t *data, size_t len, char **out_utf8)
|
||||
{
|
||||
size_t utf8_len = utf16UTF8Count(data, len/2);
|
||||
*out_utf8 = OPENSSL_malloc(utf8_len);
|
||||
if (!*out_utf8)
|
||||
return 0; /* memory allocation failed */
|
||||
|
||||
const uint16_t *s = data;
|
||||
char *d = *out_utf8;
|
||||
uint32_t rune;
|
||||
size_t remaining_len = len/2;
|
||||
|
||||
while (remaining_len > 0) {
|
||||
s = utf16DecodeRune(s, remaining_len, &rune);
|
||||
if (!s || s < data)
|
||||
break; /* invalid UTF-16 sequence */
|
||||
size_t consumed = (size_t)(s - data);
|
||||
|
||||
remaining_len -= consumed;
|
||||
data = s;
|
||||
d += utf8EncodeRune(rune, d);
|
||||
}
|
||||
return (size_t)(d - *out_utf8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute a message digest value of a signed or unsigned script file.
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] md: message digest algorithm
|
||||
* [returns] calculated message digest BIO
|
||||
*/
|
||||
static BIO *script_digest_calc_bio(FILE_FORMAT_CTX *ctx, const EVP_MD *md)
|
||||
{
|
||||
size_t fileend;
|
||||
BIO *hash = BIO_new(BIO_f_md());
|
||||
|
||||
if (ctx->script_ctx->sigpos)
|
||||
fileend = ctx->script_ctx->sigpos;
|
||||
else
|
||||
fileend = ctx->script_ctx->fileend;
|
||||
|
||||
if (!BIO_set_md(hash, md)) {
|
||||
printf("Unable to set the message digest of BIO\n");
|
||||
BIO_free_all(hash);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
BIO_push(hash, BIO_new(BIO_s_null()));
|
||||
if (!script_digest_convert(hash, ctx, fileend)) {
|
||||
printf("Unable calc a message digest value\n");
|
||||
BIO_free_all(hash);
|
||||
return NULL; /* FAILED */
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute a message digest value
|
||||
* [in, out] hash: message digest BIO
|
||||
* [in] ctx: structure holds input and output data
|
||||
* [in] len: mapped file length
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int script_digest_convert(BIO *hash, FILE_FORMAT_CTX *ctx, size_t len)
|
||||
{
|
||||
if (ctx->script_ctx->utf == 8) { /* need to convert to UTF-16 */
|
||||
uint16_t *utf16_data = NULL;
|
||||
size_t utf16_len = utf8_to_utf16(ctx->options->indata,
|
||||
len, &utf16_data);
|
||||
|
||||
if (!script_write_bio(hash, (char *)utf16_data, utf16_len)) {
|
||||
OPENSSL_free(utf16_data);
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
OPENSSL_free(utf16_data);
|
||||
} else { /* already UTF-16 -> no need to convert */
|
||||
if (!script_write_bio(hash, ctx->options->indata, len)) {
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Write len bytes from data to BIO
|
||||
* [in, out] bio: message digest or outdata BIO
|
||||
* [in] indata: mapped file
|
||||
* [in] len: indata length
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int script_write_bio(BIO *bio, char *indata, size_t len)
|
||||
{
|
||||
size_t i = 0, written;
|
||||
|
||||
while (len > 0) {
|
||||
if (!BIO_write_ex(bio, indata + i, len, &written))
|
||||
return 0; /* FAILED */
|
||||
len -= written;
|
||||
i += written;
|
||||
}
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the signature exists.
|
||||
* [in, out] ctx: structure holds input and output data
|
||||
* [returns] 0 on error or 1 on success
|
||||
*/
|
||||
static int script_check_file(FILE_FORMAT_CTX *ctx)
|
||||
{
|
||||
if (!ctx) {
|
||||
printf("Init error\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
if (ctx->script_ctx->sigpos == 0
|
||||
|| ctx->script_ctx->sigpos > ctx->script_ctx->fileend) {
|
||||
printf("No signature found\n\n");
|
||||
return 0; /* FAILED */
|
||||
}
|
||||
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
vim: set ts=4 expandtab:
|
||||
*/
|
@ -1,22 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDoTCCAomgAwIBAgIUOK8lwJ8A1Oqw8jDAb3TF06ve+PcwDQYJKoZIhvcNAQEL
|
||||
MIIDoTCCAomgAwIBAgIUVD6Q+gnrOmJWbEnmfydpUg2JNmswDQYJKoZIhvcNAQEL
|
||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
||||
MTcwMTAxMDAwMDAwWhcNMjYxMTEwMDAwMDAwWjBYMQswCQYDVQQGEwJQTDEVMBMG
|
||||
MTcwMTAxMDAwMDAwWhcNMzYxMjI3MDAwMDAwWjBYMQswCQYDVQQGEwJQTDEVMBMG
|
||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
||||
cml0eTEQMA4GA1UEAwwHUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
||||
AQoCggEBAKzObJwYq4t9Y/OOQLqUNLU8RDXq284L8zQgRLkvApF87FNN7kozIgC9
|
||||
/HAgJSho/Lup5lzkCWa3fjkYm1EBrL+JihesSaCxxe7LOg6tRaY+WxikwMUnlkNE
|
||||
s3R+DogeGVsla4q0FEcICiz3FHTfSAUVmrN3Nj1ll7npJXrqmXxfCuO3slgjUkHq
|
||||
tdZ5t1rSWwbiUhGIQKLzo3/uw2XoOI28qpoOw+0/y8AyjWs8My3u8GrYFr+qh5fx
|
||||
Y0Zp0EhhAJo23Xd43XmeVKjuKIOaHu3JiM8sp9K1WFsTvFNAO27TBRn/X0mJCeDX
|
||||
T117dQxhWOCcQ/uRGuXICT4ign8MLtUCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB
|
||||
/zAdBgNVHQ4EFgQU6ewx3DIpbR8OptEmDFlYNELRqP4wHwYDVR0jBBgwFoAU6ewx
|
||||
3DIpbR8OptEmDFlYNELRqP4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUA
|
||||
A4IBAQAhRMun0IzPmHVFM+SOfSCPVAgogWpqR5XlBAFlS+Aen6v3ukQAQjEhfBbE
|
||||
dZG6ye9i0ebf9qXYTvSq5wfaqP7FGb2/Z96uPXNMXPi796KjLW2CG578DitORPb7
|
||||
x1eV3UGrQX2bMQ0JbGkBU+DIdIRBqDfad/kjLtm5eHyCbaodSWdaZO4LSUIy3MBx
|
||||
2UeBj2qD4RTA0Dt7hG7RA5QdTxHlZyLIk8HX3krZ+il5RmSbOnQs/XqK5DJp4J5p
|
||||
122sIO4Y9ki+Wewzx8f3/7mcVbcMo67GwRHo8bk3GjWE74pczyrzfP68vDQ4tn85
|
||||
NcLPeLClfSziJD09z+Iyp94EQeKX
|
||||
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-----
|
||||
|
BIN
tests/certs/CACertCRL.der
Normal file
BIN
tests/certs/CACertCRL.der
Normal file
Binary file not shown.
@ -1,13 +1,13 @@
|
||||
-----BEGIN X509 CRL-----
|
||||
MIIB9zCB4AIBATANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJQTDEVMBMGA1UE
|
||||
MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJQTDEVMBMGA1UE
|
||||
CgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
|
||||
eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBFw0xOTAxMDEwMDAwMDBaFw00MzAx
|
||||
MDEwMDAwMDBaMCcwJQIUOpY5wp7DtqsdxII7sxculedk0PYXDTIyMDcyNjEzMDk1
|
||||
NlqgIzAhMB8GA1UdIwQYMBaAFJ4FrAtb4UB/ag702URPiid97ziLMA0GCSqGSIb3
|
||||
DQEBCwUAA4IBAQA4Kw0vEJrtjjMam16iN/stOMxJDgkp1IQzA3narxr9fEjX5Ynk
|
||||
JztuEExtowPIDOLGWCySXNEMmxCzXNAMvlUq+UQvnWrwgHQ9R7TBYIcAY+VRmzKz
|
||||
T4PXvDSL2WMuJ1dLWoIcL2D0wEdti7YMvAnCrOC8HAPGgke5QcOgSfMSAYSAtpiw
|
||||
PZAFgcuo53AodlCw9J+CPcHPYw+C2QExOy8s8q6d8Xgjg+Ge7v3RxLWy74sNPl0u
|
||||
uZ79vcLNEeqEXxKaw5abqDqIDcUKIT3b62KsSxkak9IGNMLcTASw1V+YaKVLSYNW
|
||||
NTuc5WJblfZi/q7WUMKkmRERzvdg2rf0CSH1
|
||||
MDEwMDAwMDBaMCcwJQIUazbrVgbYb+IN803UmJJa0DPHQsAXDTI0MDIyNzE1MzAx
|
||||
NFqgMDAuMB8GA1UdIwQYMBaAFGQQ8as5N9zB/bsdyD9BWHdiJ+8pMAsGA1UdFAQE
|
||||
AgIQATANBgkqhkiG9w0BAQsFAAOCAQEAV+Ce8WaNN/PXbVT9rOy/TS2EDrM/oFPG
|
||||
vwZr2IQDcBtgFV5DpNZRKJo2m4mjPPt1eCjE404U2r6081bvq3PtwSPwezV+uCzF
|
||||
dDUafeR0eZhmzxD8M2Jmi5hGp3fQevDrA4+RR33DneYSNfzGx35VN8v/L7/TuA5X
|
||||
0PG8b5hL9f3vsVXvFRj6hMkRy5m+gxFfWW/Uw3fXIt9sDLJ+eAKURdqn1c3CEwD6
|
||||
bzh0s6dSXT4wp5/l96x8fKAv5hMqDC7KufvwjhhSXdYXDOHDQcv0g5aLo8Ug8dHg
|
||||
NJHqbTAAViyGfvsS9/pYb8kHpAWvaADK84tzaMzj7uCDXlCZEjIr7w==
|
||||
-----END X509 CRL-----
|
||||
|
14
tests/certs/CACertCRL_crldp.pem
Normal file
14
tests/certs/CACertCRL_crldp.pem
Normal file
@ -0,0 +1,14 @@
|
||||
-----BEGIN X509 CRL-----
|
||||
MIICMzCCARsCAQEwDQYJKoZIhvcNAQELBQAwZzELMAkGA1UEBhMCUEwxFTATBgNV
|
||||
BAoMDG9zc2xzaWduY29kZTEgMB4GA1UECwwXQ2VydGlmaWNhdGlvbiBBdXRob3Jp
|
||||
dHkxHzAdBgNVBAMMFkludGVybWVkaWF0ZSBDQSBDUkwgRFAXDTE5MDEwMTAwMDAw
|
||||
MFoXDTQzMDEwMTAwMDAwMFowTjAlAhQcZvYIe2b1FreAKfoi/uGkSGJCthcNMjQw
|
||||
MjI3MTUzMDE0WjAlAhRrNutWBthv4g3zTdSYklrQM8dCwBcNMjQwMjI3MTUzMDE0
|
||||
WqAwMC4wHwYDVR0jBBgwFoAUFDxiqeJxiJbmZ4erKH0pBIhq7SMwCwYDVR0UBAQC
|
||||
AhACMA0GCSqGSIb3DQEBCwUAA4IBAQBZzGXEP4XdKuJ8ANIBGPu1Z+7T+4ln+nu3
|
||||
MEPC9BexVAA02YPZx6i4c3cHC87aOL7zsr/K9OeF5MAYzi2QJwsenF4b9QL2rzQV
|
||||
sCAb3sY5ImAxN38GTJ+oI+uTeOefNE0wS7pP4phRmYNZwyDhxA2iT76+luoygyth
|
||||
NesiGalMFDrJvUM1DADTZGQrz9cQVgFq9WTcta9rdTYqSNctxkbpQaY0hgssH1Sh
|
||||
hWlSiFttciA2XVD7Ju/Qv9zN4nCQC0LskgKhqsefsOukpo6jqJ92OmNrrNaERfqs
|
||||
Yavzuj6DlcnE46ZxA0y2Du1apz0WDlbcAnsEqfNSDDCid09v+V9a
|
||||
-----END X509 CRL-----
|
22
tests/certs/CAcross.pem
Normal file
22
tests/certs/CAcross.pem
Normal file
@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDqTCCApGgAwIBAgIUKFKqG3FwQAmy4HgYyO4mGEiQ8QAwDQYJKoZIhvcNAQEL
|
||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD1RydXN0ZWQgUm9v
|
||||
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0zNzEyMjcwMDAwMDBaMFgxCzAJBgNVBAYT
|
||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxIDAeBgNVBAsMF0NlcnRpZmljYXRp
|
||||
b24gQXV0aG9yaXR5MRAwDgYDVQQDDAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAxS8IBYj0uuC1XD1EBFksVv+oHXzrwfzp7KvyghPNeXq7
|
||||
0VJDC8YfUwazNGG4P1MkCPLW4iJU8nt7PZWMpebYb2VRkw8lBG3nRdMZuwYYOLgh
|
||||
NTVbc/4cjm7jkjQgvXhC/9HxfbqWd0HOVjgiagJMA3grN1++gYtoyk29sLU/tria
|
||||
W6Su6aLdYpNECrjoyPkMCqvrc06iVaKa1MH6HRla/7HGeBHtx+j4SKa+E8HvLfGF
|
||||
j04n/buXqYm5AmiHPk+bOFkHKW4yGJxOx3ZwkQpBvuOeKHj3aiQKPq8f8UmYqD4P
|
||||
NcpPK57kqLjaOHMz2/WenIiR3uz+CdlUSwcfqhAi3wIDAQABo2MwYTAPBgNVHRMB
|
||||
Af8EBTADAQH/MB0GA1UdDgQWBBQaPEb++qXSgmAi2vsewtpb6SiIyDAfBgNVHSME
|
||||
GDAWgBSzLyt07qrH3+rgkQCvS/YZ3jR+fzAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZI
|
||||
hvcNAQELBQADggEBADCY4hadNyzoz0CpdpBcFjyglxOkgcitIAgvoc2N5zwHrkg7
|
||||
BgJM1BJmCyki0AhXRKwl7sYbzNHgAhP1pBNjZqO13+cRcqPKvrxpYnsv11HaPS2E
|
||||
Ee/8EwHB3JlWlmWd6PHaJV0usRjDOuJnV/I/9mdFfIUcY0aoA36o2CCRJRKcvvVp
|
||||
Ztomnvw8IqFTn3GCNK3TRmVf2RYMhsDNQoEEidJENwCCRlcojmk1Ld95T89QsGOR
|
||||
cWJAHzyfbMQxRD7kQPZ4B2M8MvU3uD6nsamzvVM7H0UkSNuYLVkpU/wTUR8eQ2LI
|
||||
wFyi9JhKP4hF/RBuSzIHpXWO46GvzAO5dXZPLm0=
|
||||
-----END CERTIFICATE-----
|
22
tests/certs/CAroot.pem
Normal file
22
tests/certs/CAroot.pem
Normal file
@ -0,0 +1,22 @@
|
||||
-----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 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCivbbTCnbOqPoV
|
||||
7VVP/KJzgslx8yfX9laGwTsvzqStQtG8j40ljR85WD/bgy3I5duebudg7JhOVH2f
|
||||
aSqbh8SCzP4YNDFcseDIuHdoXi54POgW3S/wbe8l8P7g3btcBgnlXh/izhUlEMib
|
||||
Q/8G8UZj0n/MgKMLzcXc4t2eQ4Pzw7xAPqoXBZ20Fg2rFBfUsDDLc5F7lpO5t1WQ
|
||||
dXTYmF0oAL/HLmd+HKe5Xgp9jJ6XacesjWLnhRdZ06uUP9cgo+Jem4QZxeFhOtMe
|
||||
KAf7JH3Juz2Gi0a+4dMSNzES4m8RAlf6pXh4kAh7EhMNb/Ir6ZpY8uKM7dtn38mh
|
||||
1f59EKc9AgMBAAECggEAK5zB0P695hYcpyGqOjxO4LvM9m+eXt7SQ1ynWuF6+j+s
|
||||
62ZhAg42rux6eH5IF82ZtHSuJyhgjKVR4RWS6IlS3WbINX5PODMnNUNSJLMQqwJP
|
||||
hEkUXs9nRni2JVbmrfukTUaTLvnhasR7rjhjsN2Z6ohv3UMf7rrfapmVoKMhSoLd
|
||||
jqvZ2ZoaT5mfTiK/5PDyWqrt/vmvE4VlipAsvudwozG5vQDEsCNDNUTg5OTGnPUU
|
||||
i0xeQTioqzCcweIlEaWhj/eMHx/eAeZ6V0Evid/YwTDlbTqVDWZGLJ/phOnKJs3V
|
||||
j+eOv7E2d1ga7149SPDIv5Y0YZ91v3M06ICk5o66gQKBgQDSM+YyR5YOJTSAuAcI
|
||||
uKTc33wwCbPiJF/F1zLJDdPp2IamZQbuNIX/8fOG3Gho+OnfNAykMcr3rFrug2vi
|
||||
9GhWDQqguYGh16xos+2zNan6P/s0/rQ4OfPIsTEGC8X3fJeMzZUNMvnyN/FXzzus
|
||||
020o29gu59esEfGHEsvAupC3IQKBgQDGMqGLgrU4oW/5mmm4BZlwwkZJNMmFH49u
|
||||
Qe4Ylj87SQduExJMmTfrmANqQXu7RXG0IxLcvhwMLVCCYAkvuBv1awsbg2yfP1Pn
|
||||
Wb/K+5CaHaxnpwSpRiGaN6fnAPDl8PnALMVXtQGru2MMcISxOIFQ9slHth0lmaMo
|
||||
odIPIL1YnQKBgAOSskUEhn5zD3NorWXujY7blabTY2VirOYWBFz6iTGeZpuJeBaw
|
||||
ed6h5DvUn0m5gXAz2EsqNYMEQP9w6HKRKPzdd+LHhHaVze5xsIatUNhaIhECi1mx
|
||||
Un2E1Yp+xLyyN3lDPVdeGHWPkeCmOyNy7JYXNpOFiVr5axuarC/4e+FBAoGAeuRR
|
||||
/mshaufOwnnYK15tcdlEM4gjnAOhr7/5ng0rT9tMXBg/NHeckNxE4dGQouHASu2k
|
||||
eHL4eSRv0ycxCwGhdF7XGEw5QdTGdaDUp0ussaLMj8ijv0HY/AKefUG8HRd6BIq+
|
||||
Ik/9pTofhEsQO8LJjCY5T9m/4NyOqlcMJI0sWpECgYBvPLnutbBXYONVAE3jL05K
|
||||
hWwenKpv5Aaa11ahqzhil2Tj+VOMtmvhsSc5loSG83qp5LtN4LxyR0Vn9AGN7Z+d
|
||||
Ut6LHeZ/DMW3/RPT+1MIKm6WLNxgk5YvuCxprdpfE5tTmV9/t+t3Uao7TRsLPl2o
|
||||
qAKz8Fvq0el5RW3EtAgd4A==
|
||||
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,28 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEzTCCA7WgAwIBAgIUfRjXKciCGA4XbhbhxbAwfpcLGmowDQYJKoZIhvcNAQEL
|
||||
MIIEMzCCAxugAwIBAgIUAQ9lOMiuXUZuKaxzEpwQmCzU7aowDQYJKoZIhvcNAQEL
|
||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
|
||||
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
|
||||
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0yODAxMDEwMDAwMDBaMFUxCzAJBgNVBAYT
|
||||
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0zODAxMDEwMDAwMDBaMFUxCzAJBgNVBAYT
|
||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxHDAaBgNVBAsME1RpbWVzdGFtcCBB
|
||||
dXRob3JpdHkxETAPBgNVBAMMCFRlc3QgVFNBMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEAor220wp2zqj6Fe1VT/yic4LJcfMn1/ZWhsE7L86krULRvI+N
|
||||
JY0fOVg/24MtyOXbnm7nYOyYTlR9n2kqm4fEgsz+GDQxXLHgyLh3aF4ueDzoFt0v
|
||||
8G3vJfD+4N27XAYJ5V4f4s4VJRDIm0P/BvFGY9J/zICjC83F3OLdnkOD88O8QD6q
|
||||
FwWdtBYNqxQX1LAwy3ORe5aTubdVkHV02JhdKAC/xy5nfhynuV4KfYyel2nHrI1i
|
||||
54UXWdOrlD/XIKPiXpuEGcXhYTrTHigH+yR9ybs9hotGvuHTEjcxEuJvEQJX+qV4
|
||||
eJAIexITDW/yK+maWPLijO3bZ9/JodX+fRCnPQIDAQABo4IBiDCCAYQwDAYDVR0T
|
||||
AQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAdBgNVHQ4EFgQUKWCqogni
|
||||
6SseJ/P6LXo0M2cK++QwHwYDVR0jBBgwFoAU/5nNuG4Tm4v2y9uKf428/4fVQesw
|
||||
gYQGCCsGAQUFBwEBBHgwdjA5BggrBgEFBQcwAoYtaHR0cDovL1RTQUNBLnRpbWVz
|
||||
dGFtcGF1dGhvcml0eS5jb20vVFNBQ0EuY3J0MDkGCCsGAQUFBzABhi1odHRwOi8v
|
||||
b2NzcC5UU0FDQS50aW1lc3RhbXBhdXRob3JpdHkuY29tOjkwODAwPgYDVR0fBDcw
|
||||
NTAzoDGgL4YtaHR0cDovL1RTQUNBLnRpbWVzdGFtcGF1dGhvcml0eS5jb20vVFNB
|
||||
Q0EuY3JsMFUGA1UdHgROMEygGDAKggh0ZXN0LmNvbTAKggh0ZXN0Lm9yZ6EwMAqH
|
||||
CAAAAAAAAAAAMCKHIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMA0G
|
||||
CSqGSIb3DQEBCwUAA4IBAQB4YXa5nVWUzWSsUDMfYFTEETOe8boUErwfrDNBuj6z
|
||||
B5en20FhI49i6PCYEfNq3vrAtPOEFJj+KPomN3C46VLxbUEvqWLdq6EyzWvVVmXK
|
||||
VLeC0qV0m6CFM8GplaWzZdfFTQaaLUhgY08ZU2gp4QsoS2YjAosxlZrNSm6pBbv3
|
||||
q+Og1KeSK8gKS0V89k+6e3LOEF6KaNWKSkoz5xDniQY//mTjiDcNmYUh0KhHfhdU
|
||||
eO92M82uJSaDqnRs5HsWPs6z6qdfpuvj++OtQ1VCM2p5SEH2sEomdeN3YYChuG4h
|
||||
yzn0mYAdbTyGJHlFm17AH+SQRbVqCKYdHDaqsMb+fWzi
|
||||
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 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDkDCCAnigAwIBAgIUJ0nfE+EVsIThltlY2LHVWMJVIq4wDQYJKoZIhvcNAQEL
|
||||
MIIDkDCCAnigAwIBAgIULFuB5HWsyba6VHu2Ygv2vt4R4/swDQYJKoZIhvcNAQEL
|
||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
|
||||
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
|
||||
dCBDQTAeFw0xNzAxMDEwMDAwMDBaFw0yNjExMTAwMDAwMDBaMGAxCzAJBgNVBAYT
|
||||
dCBDQTAeFw0xNzAxMDEwMDAwMDBaFw0zNjEyMjcwMDAwMDBaMGAxCzAJBgNVBAYT
|
||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxJDAiBgNVBAsMG1RpbWVzdGFtcCBB
|
||||
dXRob3JpdHkgUm9vdCBDQTEUMBIGA1UEAwwLVFNBIFJvb3QgQ0EwggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGOTX1f9dmtUiyzlsUInRIGfRMya338SVx
|
||||
vYGeOwdpTSSGlYUVwR9AuFewQF5+klelstCJe+SoUG0AdzS30mRWlQrhip4UdvdW
|
||||
T2gkNKbSn6DQzlWoQej9izqRLxAsbuszgkvnLOBEmPaLimDsCgu0bAN95Hp0Hls9
|
||||
O/fVmzh8VuV4iscxc7q13ZB7CylWgwd55CFEGd/jpJ6kMwSHbOLoBWp4GQ3KxR+c
|
||||
ASAo0FapU2WSZB2EYWszRiyq91X+AvIYN4ypTv7RccgfUvnZ2qFykJAkf/wgkynu
|
||||
Qg7rCUNfUEpDc7jlqtDWR7iLrtHBkA17C3IU8ymmKQYWfw3ZyBwvAgMBAAGjQjBA
|
||||
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP+ZzbhuE5uL9svbin+NvP+H1UHr
|
||||
MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAbj3aFwIUxvzwgywO
|
||||
gj01JM8GNbw1E4MGdkaNI8rgeY8ay15ZXhR9NpRWWb6Y7IXPq5XhuEktVte5Z4Kf
|
||||
XLBrr7Xe9VVqJL9zd1tMzOEM/zG77rZf/iXBTZLkCtQc/GOEY4TTWKNEl5hiWVE0
|
||||
po97GX5XHoeyHlWQ75sd9z6MxFxmvdp9/uyYD700e9sd5gcD8LGvHw2DNy8vntYV
|
||||
ia9h95N9i1umffxU460o8W5GoIcsD13B3YftvnWhGSXqovBRFgcPAQZ4eW9Qh/zA
|
||||
4zQBQrRvmREPihXVdgtWVpbRchP99oSZBrYr7Hh/P69rycklquqxJl1ol1wbT6dK
|
||||
S5Gmng==
|
||||
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-----
|
||||
|
BIN
tests/certs/TSACertCRL.der
Normal file
BIN
tests/certs/TSACertCRL.der
Normal file
Binary file not shown.
15
tests/certs/TSACertCRL.pem
Normal file
15
tests/certs/TSACertCRL.pem
Normal file
@ -0,0 +1,15 @@
|
||||
-----BEGIN X509 CRL-----
|
||||
MIICUzCCATsCAQEwDQYJKoZIhvcNAQELBQAwYDELMAkGA1UEBhMCUEwxFTATBgNV
|
||||
BAoMDG9zc2xzaWduY29kZTEkMCIGA1UECwwbVGltZXN0YW1wIEF1dGhvcml0eSBS
|
||||
b290IENBMRQwEgYDVQQDDAtUU0EgUm9vdCBDQRcNMTkwMTAxMDAwMDAwWhcNNDMw
|
||||
MTAxMDAwMDAwWjB1MCUCFA5lCWy+o133yMUTfqtWmkigL1MeFw0yNDAyMjcxNTMw
|
||||
MTVaMCUCFBxm9gh7ZvUWt4Ap+iL+4aRIYkK2Fw0yNDAyMjcxNTMwMTRaMCUCFGs2
|
||||
61YG2G/iDfNN1JiSWtAzx0LAFw0yNDAyMjcxNTMwMTRaoDAwLjAfBgNVHSMEGDAW
|
||||
gBQ/Lo89CPWO9O/WTHvV+3Dt/60o+TALBgNVHRQEBAICEAMwDQYJKoZIhvcNAQEL
|
||||
BQADggEBAJ1HK2LepVJyOfqbODFxD6GJo5jr1HEnoaZ1h/iJTZZyDYfRf8d8Y/VG
|
||||
Iva00gj2KVy8tOlO0FrUR1Tqk42IjaPld0lXqKl4hkmCUWLpLgual5JcQPHhDUnT
|
||||
hiIDvbI5UHGCWeN+unXFRuT9CvtAM+3FOhuL9bBnXwdlOxZPWL8wnYT0jB/HzdKP
|
||||
KOWfN7eEXo6tTL8XxRJ5LxjwbrK1eZCdQqL2Rt2W8JTMweeqv9PkNqzYeDAvKc0s
|
||||
UCkKj+aNxQlNPy+Tw/MckJK1NE921b8LwuV0uzBrOg0Gr62RnnPGa6Z5YLArczWo
|
||||
aZlLVsJuQrOxxyXe/kygCu9lqjaf4CI=
|
||||
-----END X509 CRL-----
|
28
tests/certs/TSA_revoked.key
Normal file
28
tests/certs/TSA_revoked.key
Normal file
@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDxU8lwCceWEesm
|
||||
HIQu9M8mIznHFWmxFF55E16DseWr1K2FbOKnNv1ddNhUHFhBQChcGPn/CvwfOMR7
|
||||
DbCETrty9HUtoK3fCVZQuYIjZwRLZZB2ryLgO4PK+j07Z61yABi7NKBKv8oHISLU
|
||||
QcNg7rBAZhmAurKpNu2Gpz/jFpFXwd6O+8xnsYFLT0zyjrq0rEvLmWQd5FBQaVt7
|
||||
P+U9GH3GCg0kmdhIXAfdfSnqzj0OMnnzVdnEYrd1mYx+ZA7m0CmVJw330QXWiyax
|
||||
wimNHUvlpIiZA8ol17tAybinhPL5nSM/LRZ2PN90EgyX1bv3x/cKCEiOYPSZ7xXV
|
||||
mrRGjCtjAgMBAAECggEAHj01fIh9LdzI7lmcZpXebxTy5HNWbw3yWJGIwk/ES6e2
|
||||
poViUTmevdsqUD/M/0AezouCp+akePUQCatJdwq2ikz/cdw0bUIqQqs8F1uNOjVb
|
||||
yMNhR1+tv/1jNtJi9Wn1r1+ExlkJ46LPTnF/HeJKy4b/oxXB1VpAoSLL6pSlWa1+
|
||||
+iEWM+s6xlxyFkeWPq3L3u1QGkuW58KqQae86mR8Mgc0kOVuTCqWpHgNjfxt7tnt
|
||||
L/oBE9zEJmS3iZcGh1X5VR4CUQmtrCp7ldNdhSNk5WcNCNSsuIX+B13s658a0sRB
|
||||
AnPIX08moB5VHZ/danblny5Zo6SrobWBBcTabwjnYQKBgQD/BHktS70tQj3yBqVL
|
||||
xXmaO5ozqMLqF9A2o4EiJ/pF07ecHXmbiGaP9Nf/FJemuU5OHjw8akuxKn2M+DTu
|
||||
gHYOHwByA9/SOeAiD8bp/dJNE+2BO2zygoG/adhEV5tLK8IYdz241t8oVZbQLwql
|
||||
ZCs1uFab6E/cZEJgSQ0QuC8vtwKBgQDyQc+MX56UFFCP1QpWLIwFVdoPbOj/3cVZ
|
||||
FIjQO9rNYNIscS36nISIBh0voubI2xFvO7/s+WS1pD1bOmn6qwsndewFGdmMtjnN
|
||||
YguakmHAUmcF33f+gXVzwR91QvGPTjI2Fzd59OwOrZofO1+hajQiBKIP2B9VHJNP
|
||||
khspe44JtQKBgFqTTyrMZNOnXHMS8zC3Ydpq4vkILrqQXK6bYiksg9K7QNKdEW0x
|
||||
hCQLNZBu0vIvjOVoDcLzihDR46fnHH29eLDJSBI22A9F6RqP+flv4nrn4gptfeOg
|
||||
gM7onByh9RE86IJiD7UP9FDSHW+x1Zkqu8Inx/M2Du9bWMv0BkTy9id/AoGBAOEy
|
||||
oDcDZCyPPdyW1AcLXhZPmmegfG/tvlhyqEO6gElO6dF6XJ2NBf5UgKkZq6OnUWuv
|
||||
hVhK9X2M8aRuhroIalQCYKbVQtB1TQJJVDQaQ1g+wZpKBAfIXGCAdDfTRS5MKIzz
|
||||
xBRQw2dZpd3Gmb05NsEwwV4tL+M0rxPW4/0J6B3JAoGAB1vlzPsfKVvV9jwVpfdO
|
||||
W2MWAqPF4iI716zLt2F30WNe/42MudQGvMYUEPTYQMu3hhpQk/6UFY2Mfux6+OKk
|
||||
zG1khRdlq9BkCczfSVjkUvf4wTUUY5b66i4EpeJ//8OArZEx67LhmW715h/LExzG
|
||||
jkdwUMLiaSrpf8KSTL3NxM0=
|
||||
-----END PRIVATE KEY-----
|
25
tests/certs/TSA_revoked.pem
Normal file
25
tests/certs/TSA_revoked.pem
Normal file
@ -0,0 +1,25 @@
|
||||
-----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 +1,46 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID7jCCAtagAwIBAgIUdLInHjkevRVCr7I78r5++6eSrZ0wDQYJKoZIhvcNAQEL
|
||||
MIID7jCCAtagAwIBAgIUKiF/FG2pQjlbId3ox+nQHL/tJ4UwDQYJKoZIhvcNAQEL
|
||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD0ludGVybWVkaWF0
|
||||
ZSBDQTAeFw0xODAxMDEwMDAwMDBaFw0yNDEyMzEwMDAwMDBaMIGdMQswCQYDVQQG
|
||||
ZSBDQTAeFw0xODAxMDEwMDAwMDBaFw0zNDEyMzEwMDAwMDBaMIGdMQswCQYDVQQG
|
||||
EwJQTDEZMBcGA1UECAwQTWF6b3ZpYSBQcm92aW5jZTEPMA0GA1UEBwwGV2Fyc2F3
|
||||
MRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNVBAsMA0NTUDEUMBIGA1UEAwwL
|
||||
Q2VydGlmaWNhdGUxJzAlBgkqhkiG9w0BCQEWGG9zc2xzaWduY29kZUBleGFtcGxl
|
||||
LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJLJ3Vty2lgJw+5
|
||||
ouAV4ZqkIwvfWPcE7zD1CfQIL2802jVuCSTkN9cfFVYMKFEPJxQWJAKoCzr/Ux8z
|
||||
Yt9BXO5o39+z7umLKmc6pfrZJ6kG4msrMjZv36LsCQyfjUc1O9H1aiOQEvRQY2pF
|
||||
2v5dfqRMrAqH1ESQHCggUBjElWj9oMFax8jyO7JxTzuttOb6mhDmqz4q2u4LwZGH
|
||||
lBofgOAB54Mlv41x7dDh85i/jayXuYYmsjRwCuBAn14+D2zImyPDx5UaUJJMzujo
|
||||
QriOZ4KU2dHRgy0+vd7ZbrL1kRY1axyNQ+jBk7UHnlZZ2CCkhBoZIM6ez3ljPwgr
|
||||
cpg0RtcCAwEAAaNiMGAwCQYDVR0TBAIwADAdBgNVHQ4EFgQUBxPEs09WXDxGqb+D
|
||||
WTFgcUQd0AEwHwYDVR0jBBgwFoAUngWsC1vhQH9qDvTZRE+KJ33vOIswEwYDVR0l
|
||||
BAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAKK2e1s1puUFbNjglopi
|
||||
mKZ4Pks2zb6LVUGG6Q4XQ1dWe25ovt68jWv56HFyCMI1N+L8q0+Ku2eOfLObS7Ej
|
||||
FFRUWEIXDgipryDTGzoWRM380fuYpL/j7Rt1/xmIHWTFibf/6gK/naRXsFH3dEbb
|
||||
7DDWQ5pAd2d60dB+ThUEIZQTQd/926Kuk5oESvP08fXMYTuiYARypG1gmiuvxQ9N
|
||||
mDJP6CHxyJR/LB4tb0RAqnLkVsXVBDnRYWdEvkuhoqTtbhVzVbL3mPeEmVYypxxd
|
||||
NdrHpU5zmxFSin2T3F0TneNcT+MDV+dQcWyTGNYs/fnmo85LsiakJixGv1qx8PTs
|
||||
8iE=
|
||||
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-----
|
||||
MIIDrDCCApSgAwIBAgIUUPCDF21g2spK7557HZUhqSxBltMwDQYJKoZIhvcNAQEL
|
||||
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
|
||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
||||
MTgwMTAxMDAwMDAwWhcNMjYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
||||
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
||||
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAyMs1XoC0NUT5YgydibOrE5SWBKk5C47B6tv6gA4t3zZJ
|
||||
wejaiPkj+aTIU3Ww5DO/Gpz0GuqCHNBczIw92Cfvv8kyWzUy46bRkpBJLFav0JXS
|
||||
B3xQaPlHWeXqMfVAGuM5ExT4CjjYKFsrgV1Q300thCHBhvr8TPekDIf+6J7NSz1P
|
||||
062pYgypfqsA8OwKaQbgOL9v4QRmHoolnEDc1dK/FS4f3p9dlifl7kcSVGQK0yit
|
||||
7Uncn250icCxMxS3MOE2NfuplUOSN6h6poWNGUsx00O7Dy9nUndUwJRpFfKXTV3v
|
||||
GtlmFLNoho+ss/usnxjxggWBcRtKhqd8nGSJUlzs0wIDAQABo2YwZDASBgNVHRMB
|
||||
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBSeBawLW+FAf2oO9NlET4onfe84izAfBgNV
|
||||
HSMEGDAWgBTp7DHcMiltHw6m0SYMWVg0QtGo/jAOBgNVHQ8BAf8EBAMCAYYwDQYJ
|
||||
KoZIhvcNAQELBQADggEBAD/FBa4stJGd/Acg2E2soI071B/l9B7FiqIRpCFuLVC4
|
||||
1m7TIcjioIpZrxXwE1Egf8A9/6D/kKZtWnOljcxtPBEb+1/gB61M381RIgoMQ/Pf
|
||||
7XX2yakk6mscUjbSTR//Mj1sYOs2r6ueZBp0whzF9nVvA43G6WMpf6XZqmhlg/oV
|
||||
ynytW1Iu1SPoru3y8dX/lsukvKCak7MAp1eBcuUJxS56DnKcV9xgC30m3g+CErI3
|
||||
qsOJ7lcfDP6fDjy7MfBsZBiY64MqwlDjjn7+Pleo69JedMwurHLhKnfm07DBPy8X
|
||||
+EnQk61xHEjQtTsddXyQGQV3yjqylOF2AgsAf256uuA=
|
||||
AAOCAQ8AMIIBCgKCAQEA5yrw3i+fvxBSODvCoQb+9ibWRozmphJBp57tKv9ZraQ5
|
||||
THK+PkCdjNiJuxZn8F1QLsjJo6JqrrXufYln7wixK0Seu4uV6I2TRzcRyJx29D89
|
||||
0G9GrTXKn7v8z32QAqCgtwSZ17uWYTFmRAYPllWXcWDONsVyw3UF2nClndL7GMqM
|
||||
gDizlwsfg8HmRpZegn82I7Y2DXccm9a7pFHuBHpwenKqfBnMsXo3Jj4Xlr1cLTrh
|
||||
+6ksS5YogOsOd9b5Dfz6FaGmmwrlUWHwdi+EzdnSpOnXzmgflF23sZQ0ynsVvmpl
|
||||
iD4rXBWnxnQ6Ken3wVPNrA/0ZYGbgSKrcv+/olkh5QIDAQABo2YwZDASBgNVHRMB
|
||||
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRkEPGrOTfcwf27Hcg/QVh3YifvKTAfBgNV
|
||||
HSMEGDAWgBQaPEb++qXSgmAi2vsewtpb6SiIyDAOBgNVHQ8BAf8EBAMCAYYwDQYJ
|
||||
KoZIhvcNAQELBQADggEBAL22kK3SDGnr3lhRE7ipptlKalrQKfpght0XEKm5hxCL
|
||||
tougN2wtaTEWMwr2YfGJohcKBaGKQ+Bv6WY+EV+hJE4qEUFh6BGqRMtuZdiAbkG+
|
||||
EveEMhZWQzgf9rUID+Y9Eg+NfCxlpkdQPjUxUV9OkGIshlxkUP8Y+C0h0xIcwq5v
|
||||
hAfNiJAdcw4fUvtLkpEOFoOjThB8zxOu+Cl3xLCcNOMPLdSxd3YXjy6CMuuOk4RB
|
||||
gOc8YCyyEvwb9KmARZpMOcQJmucMhs+aC3DF+n71g+agFhDl3Z0QkyyyRjAcD04+
|
||||
sAR9C8PbqSCQAdydHbAFViEX6x3oGJ7L6zEDcIS10wg=
|
||||
-----END CERTIFICATE-----
|
||||
|
Binary file not shown.
47
tests/certs/cert_crldp.pem
Normal file
47
tests/certs/cert_crldp.pem
Normal file
@ -0,0 +1,47 @@
|
||||
-----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,23 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDzjCCAragAwIBAgIUGjZdQYlcAtlqZOsQ7eWRimQ9PIcwDQYJKoZIhvcNAQEL
|
||||
BQAwbzELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEMMAoGA1UE
|
||||
CwwDQ1NQMRIwEAYDVQQDDAljcm9zc2NlcnQxJzAlBgkqhkiG9w0BCQEWGG9zc2xz
|
||||
aWduY29kZUBleGFtcGxlLmNvbTAeFw0xODAxMDEwMDAwMDBaFw0yMDA2MTkwMDAw
|
||||
MDBaMG8xCzAJBgNVBAYTAlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNV
|
||||
BAsMA0NTUDESMBAGA1UEAwwJY3Jvc3NjZXJ0MScwJQYJKoZIhvcNAQkBFhhvc3Ns
|
||||
c2lnbmNvZGVAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||
AoIBAQDJU6WNMOEoErLYb5Qc7jsvVgruPM7DJTZ4vUpJNYAyprSDHciaKSa4SiYS
|
||||
84Mxc6tzBoJvKOAwpxzzONOqPVWUd5J244urgvfHgSGWsbA8bakiIYlETopnecFk
|
||||
B3ZELR33CPqIbpYYMYujhPGFa1xxZxFykJ1iBhZ8Gh3W4wHi/2kW6hTQkihMtUPP
|
||||
Xxc2XWACj/tz22OSdgNZcIfhXiy2HOuPch+0UlDR4UmlJIR5aet1y832hHoeeevo
|
||||
qfhfGOm9rRf9nyxKDwTyaN7JVOb7A1k6KJEJoe1zfIwT56mgoA433iUWFMLB6hKU
|
||||
be3zV1vGjk77Kk7atcvEMTRq+rwHAgMBAAGjYjBgMAkGA1UdEwQCMAAwHQYDVR0O
|
||||
BBYEFEXgglEcDh+8oCCvjlxrN/Y7C4YwMB8GA1UdIwQYMBaAFEXgglEcDh+8oCCv
|
||||
jlxrN/Y7C4YwMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IB
|
||||
AQBo8UqUEjxGQCVU/IgphwKA8Rb/uAyBYm+AjqFDs82lA6ze0n08Bj+eciVkxscA
|
||||
0deivOC1sDD88QkLzSQ9CPk4e7+m7nx5SFUnUWY+o3ln+cTbGSM0jW9hme0LtHXX
|
||||
QxDSKDBhQonRQk7lQ+TwFR7ol+y5SdZy7YQ+v/25qO6MMQgSPykJIa4vF7lwrYhu
|
||||
qL+1MJx/ryTbCUExcKNNkWHZJRc9ZvtdWEHYpBSZl5xmJdKMLnHAu5uv8N2pezzp
|
||||
PfujldZky7bnERaTM+bf/LvKXS8RfQGrCLu9QjgPVa6ysZV6gXTsEtwYh64vucjS
|
||||
s7IhdLxfiT0xYkK4JWrRLc38
|
||||
-----END CERTIFICATE-----
|
@ -1,45 +1,45 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID6jCCAtKgAwIBAgIUdtBZJAw8/6JVNMiQpN3PEROI8rowDQYJKoZIhvcNAQEL
|
||||
MIID6jCCAtKgAwIBAgIUcgUgRT1Lx8XLdgp7xcWxVl9YBjYwDQYJKoZIhvcNAQEL
|
||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD0ludGVybWVkaWF0
|
||||
ZSBDQTAeFw0xODAxMDEwMDAwMDBaFw0xOTAxMDEwMDAwMDBaMIGZMQswCQYDVQQG
|
||||
EwJQTDEZMBcGA1UECAwQTWF6b3ZpYSBQcm92aW5jZTEPMA0GA1UEBwwGV2Fyc2F3
|
||||
MRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNVBAsMA0NTUDEQMA4GA1UEAwwH
|
||||
RXhwaXJlZDEnMCUGCSqGSIb3DQEJARYYb3NzbHNpZ25jb2RlQGV4YW1wbGUuY29t
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsksndW3LaWAnD7mi4BXh
|
||||
mqQjC99Y9wTvMPUJ9AgvbzTaNW4JJOQ31x8VVgwoUQ8nFBYkAqgLOv9THzNi30Fc
|
||||
7mjf37Pu6YsqZzql+tknqQbiaysyNm/fouwJDJ+NRzU70fVqI5AS9FBjakXa/l1+
|
||||
pEysCofURJAcKCBQGMSVaP2gwVrHyPI7snFPO6205vqaEOarPira7gvBkYeUGh+A
|
||||
4AHngyW/jXHt0OHzmL+NrJe5hiayNHAK4ECfXj4PbMibI8PHlRpQkkzO6OhCuI5n
|
||||
gpTZ0dGDLT693tlusvWRFjVrHI1D6MGTtQeeVlnYIKSEGhkgzp7PeWM/CCtymDRG
|
||||
1wIDAQABo2IwYDAJBgNVHRMEAjAAMB0GA1UdDgQWBBQHE8SzT1ZcPEapv4NZMWBx
|
||||
RB3QATAfBgNVHSMEGDAWgBSeBawLW+FAf2oO9NlET4onfe84izATBgNVHSUEDDAK
|
||||
BggrBgEFBQcDAzANBgkqhkiG9w0BAQsFAAOCAQEAX1Ar7jRAXdcA0Wu37yRi58QN
|
||||
hpa1VLXadqfB+i5Y4e3DzqnMbpkLWsFzreC1AG0RjLe52s4PRUE6boGlpUeAyfFC
|
||||
Qu2Gl/REVWwMCYV8bq3vQZkYQjklAXCQLWFk5TrzuDmBcV8+fY518nWw+xmcYwW5
|
||||
5oehLsvB4nxoBzlHgcdDwS5b2dmpCKCbZFLU9aA9DjAVvY/9B8emyj7Sh2sEK0Yf
|
||||
xwHlATTVq5O0/9tvVZQmYsbpS0iCRGBM+spTEhDT4WGsaRO6wP+Ucgp6Ym3ahMvz
|
||||
tHME3uUanKWVoDb69sguGZ6KlnZZZdIX1AJ3dlTXCrzEO9xsoAzqzsxVJGrraQ==
|
||||
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-----
|
||||
MIIDrDCCApSgAwIBAgIUUPCDF21g2spK7557HZUhqSxBltMwDQYJKoZIhvcNAQEL
|
||||
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
|
||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
||||
MTgwMTAxMDAwMDAwWhcNMjYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
||||
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
||||
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAyMs1XoC0NUT5YgydibOrE5SWBKk5C47B6tv6gA4t3zZJ
|
||||
wejaiPkj+aTIU3Ww5DO/Gpz0GuqCHNBczIw92Cfvv8kyWzUy46bRkpBJLFav0JXS
|
||||
B3xQaPlHWeXqMfVAGuM5ExT4CjjYKFsrgV1Q300thCHBhvr8TPekDIf+6J7NSz1P
|
||||
062pYgypfqsA8OwKaQbgOL9v4QRmHoolnEDc1dK/FS4f3p9dlifl7kcSVGQK0yit
|
||||
7Uncn250icCxMxS3MOE2NfuplUOSN6h6poWNGUsx00O7Dy9nUndUwJRpFfKXTV3v
|
||||
GtlmFLNoho+ss/usnxjxggWBcRtKhqd8nGSJUlzs0wIDAQABo2YwZDASBgNVHRMB
|
||||
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBSeBawLW+FAf2oO9NlET4onfe84izAfBgNV
|
||||
HSMEGDAWgBTp7DHcMiltHw6m0SYMWVg0QtGo/jAOBgNVHQ8BAf8EBAMCAYYwDQYJ
|
||||
KoZIhvcNAQELBQADggEBAD/FBa4stJGd/Acg2E2soI071B/l9B7FiqIRpCFuLVC4
|
||||
1m7TIcjioIpZrxXwE1Egf8A9/6D/kKZtWnOljcxtPBEb+1/gB61M381RIgoMQ/Pf
|
||||
7XX2yakk6mscUjbSTR//Mj1sYOs2r6ueZBp0whzF9nVvA43G6WMpf6XZqmhlg/oV
|
||||
ynytW1Iu1SPoru3y8dX/lsukvKCak7MAp1eBcuUJxS56DnKcV9xgC30m3g+CErI3
|
||||
qsOJ7lcfDP6fDjy7MfBsZBiY64MqwlDjjn7+Pleo69JedMwurHLhKnfm07DBPy8X
|
||||
+EnQk61xHEjQtTsddXyQGQV3yjqylOF2AgsAf256uuA=
|
||||
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-----
|
||||
MIIDrDCCApSgAwIBAgIUUPCDF21g2spK7557HZUhqSxBltMwDQYJKoZIhvcNAQEL
|
||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
||||
MTgwMTAxMDAwMDAwWhcNMjYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
||||
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAyMs1XoC0NUT5YgydibOrE5SWBKk5C47B6tv6gA4t3zZJ
|
||||
wejaiPkj+aTIU3Ww5DO/Gpz0GuqCHNBczIw92Cfvv8kyWzUy46bRkpBJLFav0JXS
|
||||
B3xQaPlHWeXqMfVAGuM5ExT4CjjYKFsrgV1Q300thCHBhvr8TPekDIf+6J7NSz1P
|
||||
062pYgypfqsA8OwKaQbgOL9v4QRmHoolnEDc1dK/FS4f3p9dlifl7kcSVGQK0yit
|
||||
7Uncn250icCxMxS3MOE2NfuplUOSN6h6poWNGUsx00O7Dy9nUndUwJRpFfKXTV3v
|
||||
GtlmFLNoho+ss/usnxjxggWBcRtKhqd8nGSJUlzs0wIDAQABo2YwZDASBgNVHRMB
|
||||
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBSeBawLW+FAf2oO9NlET4onfe84izAfBgNV
|
||||
HSMEGDAWgBTp7DHcMiltHw6m0SYMWVg0QtGo/jAOBgNVHQ8BAf8EBAMCAYYwDQYJ
|
||||
KoZIhvcNAQELBQADggEBAD/FBa4stJGd/Acg2E2soI071B/l9B7FiqIRpCFuLVC4
|
||||
1m7TIcjioIpZrxXwE1Egf8A9/6D/kKZtWnOljcxtPBEb+1/gB61M381RIgoMQ/Pf
|
||||
7XX2yakk6mscUjbSTR//Mj1sYOs2r6ueZBp0whzF9nVvA43G6WMpf6XZqmhlg/oV
|
||||
ynytW1Iu1SPoru3y8dX/lsukvKCak7MAp1eBcuUJxS56DnKcV9xgC30m3g+CErI3
|
||||
qsOJ7lcfDP6fDjy7MfBsZBiY64MqwlDjjn7+Pleo69JedMwurHLhKnfm07DBPy8X
|
||||
+EnQk61xHEjQtTsddXyQGQV3yjqylOF2AgsAf256uuA=
|
||||
-----END CERTIFICATE-----
|
22
tests/certs/intermediateCA.pem
Normal file
22
tests/certs/intermediateCA.pem
Normal file
@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
|
||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
||||
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
||||
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEA5yrw3i+fvxBSODvCoQb+9ibWRozmphJBp57tKv9ZraQ5
|
||||
THK+PkCdjNiJuxZn8F1QLsjJo6JqrrXufYln7wixK0Seu4uV6I2TRzcRyJx29D89
|
||||
0G9GrTXKn7v8z32QAqCgtwSZ17uWYTFmRAYPllWXcWDONsVyw3UF2nClndL7GMqM
|
||||
gDizlwsfg8HmRpZegn82I7Y2DXccm9a7pFHuBHpwenKqfBnMsXo3Jj4Xlr1cLTrh
|
||||
+6ksS5YogOsOd9b5Dfz6FaGmmwrlUWHwdi+EzdnSpOnXzmgflF23sZQ0ynsVvmpl
|
||||
iD4rXBWnxnQ6Ken3wVPNrA/0ZYGbgSKrcv+/olkh5QIDAQABo2YwZDASBgNVHRMB
|
||||
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBRkEPGrOTfcwf27Hcg/QVh3YifvKTAfBgNV
|
||||
HSMEGDAWgBQaPEb++qXSgmAi2vsewtpb6SiIyDAOBgNVHQ8BAf8EBAMCAYYwDQYJ
|
||||
KoZIhvcNAQELBQADggEBAL22kK3SDGnr3lhRE7ipptlKalrQKfpght0XEKm5hxCL
|
||||
tougN2wtaTEWMwr2YfGJohcKBaGKQ+Bv6WY+EV+hJE4qEUFh6BGqRMtuZdiAbkG+
|
||||
EveEMhZWQzgf9rUID+Y9Eg+NfCxlpkdQPjUxUV9OkGIshlxkUP8Y+C0h0xIcwq5v
|
||||
hAfNiJAdcw4fUvtLkpEOFoOjThB8zxOu+Cl3xLCcNOMPLdSxd3YXjy6CMuuOk4RB
|
||||
gOc8YCyyEvwb9KmARZpMOcQJmucMhs+aC3DF+n71g+agFhDl3Z0QkyyyRjAcD04+
|
||||
sAR9C8PbqSCQAdydHbAFViEX6x3oGJ7L6zEDcIS10wg=
|
||||
-----END CERTIFICATE-----
|
22
tests/certs/intermediateCA_crldp.pem
Normal file
22
tests/certs/intermediateCA_crldp.pem
Normal file
@ -0,0 +1,22 @@
|
||||
-----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,27 +1,28 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAsksndW3LaWAnD7mi4BXhmqQjC99Y9wTvMPUJ9AgvbzTaNW4J
|
||||
JOQ31x8VVgwoUQ8nFBYkAqgLOv9THzNi30Fc7mjf37Pu6YsqZzql+tknqQbiaysy
|
||||
Nm/fouwJDJ+NRzU70fVqI5AS9FBjakXa/l1+pEysCofURJAcKCBQGMSVaP2gwVrH
|
||||
yPI7snFPO6205vqaEOarPira7gvBkYeUGh+A4AHngyW/jXHt0OHzmL+NrJe5hiay
|
||||
NHAK4ECfXj4PbMibI8PHlRpQkkzO6OhCuI5ngpTZ0dGDLT693tlusvWRFjVrHI1D
|
||||
6MGTtQeeVlnYIKSEGhkgzp7PeWM/CCtymDRG1wIDAQABAoIBACR/jgxT9ZgUvupR
|
||||
Li6BTDXD9AiyKBwpPm3fO7JhGpTBVQorBGQw891t14hN5NLzLyTFg4mnrOTe770r
|
||||
X8okL0n+3hWFWBsnCf8n2mKHob7QUfluVlEehcFsYE3dO6agFybb/mZZUAgDjNZs
|
||||
hnAb45juuSlOtP10Is90DfGEDLH5IeY1xjzc7Qv/CFxCffIAC8QmQYUTihJ2m5aE
|
||||
7Hvs79oEcSvbRJDYbykzrJ0eeIaEvfOxkWJnnJHrhiONzb8qgj3DLiZdX1qeo1Ao
|
||||
ldNxEG9n3Axd6M0nhajz0qbDV11S8YiKfP10XRQh5xv7lZi7MjvrRxFTFYpSrXwi
|
||||
YYyFNoECgYEA6YnIYg1nIe3qaI3Me1RQQTGRl8M/dQc2d98Pz5mez9vN3TIW6nEs
|
||||
QYw/9OKG1ercbD+YnuaV+1izuAcA3mNlSDReTtzInAotJjTH1V3WYqvBTVUZSb6T
|
||||
5qSBfRDC3AULFvHeX5c5wqgfB3U9KLDfVBfaHnMerg6dAGsYZPhPMrkCgYEAw3Eg
|
||||
5BRTzbqG0WXF25rycTeHCcylMZRjI+TVcIa8AGqNSCK4HgAWp89XPIV3WceVqe2R
|
||||
Lyn1jtA2MgGGcMBDFlOWF+h9j2/j27Z+pyIbBF9LAraJuBOG6dezd50y5Ur6HK/f
|
||||
e5lnjvElIYdz+RX+rmw8NFcIUbSAfE7rGinDvg8CgYBDx86VzsgJC/FFySn4/X6R
|
||||
fV6BSpTHVYGUhvQiz7ZNI8F7GoeWIaSznY4OeBSkT5cL/+U+8TPEkHkQx0+UPArw
|
||||
Suq4PtImn7l85kK9hY+scacX18QQKDTq8wH2F4BGtVwDm81rtwt3mK3wzzEh9zvK
|
||||
P2X6AnV8FReyQGMDIyJxWQKBgD6nu9WitqMTkzj6GY4nhGXLWV1I4ASe/5F4QPzM
|
||||
FOVFQ3nGt6PWf2zYyay7VOHRXCeX451tJC3ejiFF3+WxnVBBB7Muc2JSiofbX4sR
|
||||
Ifwq2I9MGaaLjArXfc9w8+oSOVCNCWZEbbCjmjW/iOxnorgkNsDIzf/zj+VKH5DJ
|
||||
ptj9AoGAUpB6nPES3Nnj8DsbpHCnShYMl/rFxzxg2pJJosXzuS/ttuBT2DlT5eiY
|
||||
aZcL1DGSp2CD4QXbVuDHPkQMPzVfZzKAuCZlotEMR9byK46aYIkQueym45e0PGZP
|
||||
djKZm+cxF+W55jBkBBhV6wSOLNRWCUYiIIq3RmwWjkopNvSlwY4=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----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 +1,30 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,6DB255395263EDD5
|
||||
|
||||
A83CH4mv7u89RbT8Tpz4gxImKGBw69Zr3LstRXlliGYobby5YBx/YimkA9wFCZK/
|
||||
B1eitWwy0F6axDZQYHKi+yvUJDPB9arXtClvYknMhwrHV1GHLSYeqb9oZJeqNyDZ
|
||||
Qd3lxTbUtkMVJgJNrl2kOezm6/srnAw4uA7NyAvrs2vEzB48q4VlysrJq+f9mLXj
|
||||
vCmrfUwY999lSifRmoxqeWlqNUQ2tgHHXYMNagpvxYXsfe1UvEH9aa6+UsO9S0py
|
||||
7dyfSu95QpWyVNqkWi1VAtNbo2VpjJ6NJLAk+dy/rNqN3a4KnWeIzkYssWTsKB08
|
||||
VyHrRLePPx5qdarsczZtf+M2PxhHHnl/09+Nrp5BUcMV31j3v3VSM0K+CHEucAk7
|
||||
95rUtSUNywKUQeSgXrG1eLX7kXwRQ7PPCz3sPtvmJRIvQlGgLiTbKPsG52m3kAIw
|
||||
zgXPcH2lYb3855occznl72jMUucxXq8gq0bC4xbEg/yJV8p1IuUEFhLGI9s9T4JV
|
||||
cO9NKwmSjpHFo1ULhB7o6uMmV2rYDK+5GbQHxZgHj3ES+i53eFMWGubPEEOmqSh3
|
||||
9K7gtW9y971tNfhp9ba8RnYXT6xW2nMTM4koO9b4ptdwRo5bMKFvWY8eecXfsDAG
|
||||
OJ+aXkDr8jsn1Xauq1m4TM71wn2wUx95KaCpL55UNBEn7aH9qlNFfxdyzXMPYS36
|
||||
zgWK44BV3PTSIGgW61NVwHwzi3bFfymortVxGpelzy2dggWVvI3uzKocLFQ8f4oe
|
||||
Y0HWSmGVPF3uFHNCZtCB/Tpbz6YwP/YYStqAcryeS5Yo9Hdkh8pBVnYiKdTFEUW2
|
||||
RbClgeB2MV+zttsqvmodfkviS4BjWgoIV5szxWOePnO8kQAHA/Ml3CyDPOX6rqI5
|
||||
lDKiUojEMLgir/3YWWcmigEIgRsyF3CL1s+kTR3S8e9QRe8RiliRUKW5gXrLEa6j
|
||||
eUjs4kgCrvmQvwyZYJjWl+r7ycmk+yB/EZs8P39KRR/pfeZDUCZIOx8vkJBt57hC
|
||||
oTNJ5llFzRcmEraElXmDOAuvmj3Lx/4qzY545rtzll3mFHJEX4qITslIX1ksZz1p
|
||||
DncuqgIECzmZIeHPbnw7Nkv6EkoPzTOlccqnCH/SumFr2fhctv9x13gGcO4kSsqO
|
||||
63yZCFHjMz/mos3l51aIAizj5wQO3BOo+RyKoSQohvPzVtSgjhYMZsAPzXKxF0/H
|
||||
9VH0DekEb1WwPSbGZw8kpx9ePlglGqOBinTL6QW8YmFPbjy9RDd1di+fxh4Qe024
|
||||
8gERZpdSsMoZ+NP0nr/TSbDISFPqcLzzMpC+V8Fc/QkNvSkR1GLlNQrxLoyfK0VX
|
||||
0evysXDxqIWK9+TH7hIS1lf3i2gMkLMppMso1v2Cqf0zRj1oM3MI743QE9XTXKRz
|
||||
iAwaEDDPZWS/00T9fqNrHgtSPNpsbeYZQPYaC2lq1kTIEOlUfZZvMy5lxVPVZ8y2
|
||||
foit+0DewZsqLDJwbjZ3wYMERVEY7KagoInQa3A1ZC9SkFiCb4fNEbRF13gfjrSz
|
||||
muRbKAhEhkzJDFRocIaTKZPIWdvC73tAW66v1Zha74mxuckgnQPPqQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----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-----
|
||||
|
BIN
tests/certs/legacy.p12
Normal file
BIN
tests/certs/legacy.p12
Normal file
Binary file not shown.
@ -1,45 +1,45 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDvTCCAqWgAwIBAgIUOpY5wp7DtqsdxII7sxculedk0PYwDQYJKoZIhvcNAQEL
|
||||
MIIDvTCCAqWgAwIBAgIUazbrVgbYb+IN803UmJJa0DPHQsAwDQYJKoZIhvcNAQEL
|
||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGDAWBgNVBAMMD0ludGVybWVkaWF0
|
||||
ZSBDQTAeFw0xODAxMDEwMDAwMDBaFw0yNDEyMzEwMDAwMDBaMG0xCzAJBgNVBAYT
|
||||
ZSBDQTAeFw0xODAxMDEwMDAwMDBaFw0zNDEyMzEwMDAwMDBaMG0xCzAJBgNVBAYT
|
||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxDDAKBgNVBAsMA0NTUDEQMA4GA1UE
|
||||
AwwHUmV2b2tlZDEnMCUGCSqGSIb3DQEJARYYb3NzbHNpZ25jb2RlQGV4YW1wbGUu
|
||||
Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsksndW3LaWAnD7mi
|
||||
4BXhmqQjC99Y9wTvMPUJ9AgvbzTaNW4JJOQ31x8VVgwoUQ8nFBYkAqgLOv9THzNi
|
||||
30Fc7mjf37Pu6YsqZzql+tknqQbiaysyNm/fouwJDJ+NRzU70fVqI5AS9FBjakXa
|
||||
/l1+pEysCofURJAcKCBQGMSVaP2gwVrHyPI7snFPO6205vqaEOarPira7gvBkYeU
|
||||
Gh+A4AHngyW/jXHt0OHzmL+NrJe5hiayNHAK4ECfXj4PbMibI8PHlRpQkkzO6OhC
|
||||
uI5ngpTZ0dGDLT693tlusvWRFjVrHI1D6MGTtQeeVlnYIKSEGhkgzp7PeWM/CCty
|
||||
mDRG1wIDAQABo2IwYDAJBgNVHRMEAjAAMB0GA1UdDgQWBBQHE8SzT1ZcPEapv4NZ
|
||||
MWBxRB3QATAfBgNVHSMEGDAWgBSeBawLW+FAf2oO9NlET4onfe84izATBgNVHSUE
|
||||
DDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQsFAAOCAQEAYVJiPrkACW/tK487fYS/
|
||||
gYzU3fYVCTfHpAv3njarNzy8UBNqBYr0kDg0DLoOWqGV7ogTtlbQP4IIjAQI/kW6
|
||||
cEreW8yU5VxO+kxDo+7oG9VEbR85i6kQW2ubJsXV6yBtf5aAbXEqImYrtjh7UObb
|
||||
BbQiUI1ll2dXWqvZGxr3Fz1uz8nPMYlBpVjpCh6JF8otdWwABmxRnqUvoLO6BZbH
|
||||
/gdUkouXfio9BlWkWaJXJGXMW8B7ozpjuCHSHyfvGKDA3YIfa7++A1BIKxW72jIF
|
||||
jRJDw/rwnV59tiEcBWmp2T6vV+rD8yaS+LotRPYD/ck/jEj/mV+N077KLmuZpdJF
|
||||
ag==
|
||||
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-----
|
||||
MIIDrDCCApSgAwIBAgIUUPCDF21g2spK7557HZUhqSxBltMwDQYJKoZIhvcNAQEL
|
||||
MIIDrDCCApSgAwIBAgIUcRGFYn4pUMRoDtFZhU1EOAPdiWwwDQYJKoZIhvcNAQEL
|
||||
BQAwWDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEgMB4GA1UE
|
||||
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcN
|
||||
MTgwMTAxMDAwMDAwWhcNMjYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
||||
MTgwMTAxMDAwMDAwWhcNMzYwMTAxMDAwMDAwWjBgMQswCQYDVQQGEwJQTDEVMBMG
|
||||
A1UECgwMb3NzbHNpZ25jb2RlMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhv
|
||||
cml0eTEYMBYGA1UEAwwPSW50ZXJtZWRpYXRlIENBMIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAyMs1XoC0NUT5YgydibOrE5SWBKk5C47B6tv6gA4t3zZJ
|
||||
wejaiPkj+aTIU3Ww5DO/Gpz0GuqCHNBczIw92Cfvv8kyWzUy46bRkpBJLFav0JXS
|
||||
B3xQaPlHWeXqMfVAGuM5ExT4CjjYKFsrgV1Q300thCHBhvr8TPekDIf+6J7NSz1P
|
||||
062pYgypfqsA8OwKaQbgOL9v4QRmHoolnEDc1dK/FS4f3p9dlifl7kcSVGQK0yit
|
||||
7Uncn250icCxMxS3MOE2NfuplUOSN6h6poWNGUsx00O7Dy9nUndUwJRpFfKXTV3v
|
||||
GtlmFLNoho+ss/usnxjxggWBcRtKhqd8nGSJUlzs0wIDAQABo2YwZDASBgNVHRMB
|
||||
Af8ECDAGAQH/AgEAMB0GA1UdDgQWBBSeBawLW+FAf2oO9NlET4onfe84izAfBgNV
|
||||
HSMEGDAWgBTp7DHcMiltHw6m0SYMWVg0QtGo/jAOBgNVHQ8BAf8EBAMCAYYwDQYJ
|
||||
KoZIhvcNAQELBQADggEBAD/FBa4stJGd/Acg2E2soI071B/l9B7FiqIRpCFuLVC4
|
||||
1m7TIcjioIpZrxXwE1Egf8A9/6D/kKZtWnOljcxtPBEb+1/gB61M381RIgoMQ/Pf
|
||||
7XX2yakk6mscUjbSTR//Mj1sYOs2r6ueZBp0whzF9nVvA43G6WMpf6XZqmhlg/oV
|
||||
ynytW1Iu1SPoru3y8dX/lsukvKCak7MAp1eBcuUJxS56DnKcV9xgC30m3g+CErI3
|
||||
qsOJ7lcfDP6fDjy7MfBsZBiY64MqwlDjjn7+Pleo69JedMwurHLhKnfm07DBPy8X
|
||||
+EnQk61xHEjQtTsddXyQGQV3yjqylOF2AgsAf256uuA=
|
||||
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.
46
tests/certs/revoked_crldp.pem
Normal file
46
tests/certs/revoked_crldp.pem
Normal file
@ -0,0 +1,46 @@
|
||||
-----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,50 +1,47 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEzTCCA7WgAwIBAgIUfRjXKciCGA4XbhbhxbAwfpcLGmowDQYJKoZIhvcNAQEL
|
||||
MIIEMzCCAxugAwIBAgIUAQ9lOMiuXUZuKaxzEpwQmCzU7aowDQYJKoZIhvcNAQEL
|
||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
|
||||
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
|
||||
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0yODAxMDEwMDAwMDBaMFUxCzAJBgNVBAYT
|
||||
dCBDQTAeFw0xODAxMDEwMDAwMDBaFw0zODAxMDEwMDAwMDBaMFUxCzAJBgNVBAYT
|
||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxHDAaBgNVBAsME1RpbWVzdGFtcCBB
|
||||
dXRob3JpdHkxETAPBgNVBAMMCFRlc3QgVFNBMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEAor220wp2zqj6Fe1VT/yic4LJcfMn1/ZWhsE7L86krULRvI+N
|
||||
JY0fOVg/24MtyOXbnm7nYOyYTlR9n2kqm4fEgsz+GDQxXLHgyLh3aF4ueDzoFt0v
|
||||
8G3vJfD+4N27XAYJ5V4f4s4VJRDIm0P/BvFGY9J/zICjC83F3OLdnkOD88O8QD6q
|
||||
FwWdtBYNqxQX1LAwy3ORe5aTubdVkHV02JhdKAC/xy5nfhynuV4KfYyel2nHrI1i
|
||||
54UXWdOrlD/XIKPiXpuEGcXhYTrTHigH+yR9ybs9hotGvuHTEjcxEuJvEQJX+qV4
|
||||
eJAIexITDW/yK+maWPLijO3bZ9/JodX+fRCnPQIDAQABo4IBiDCCAYQwDAYDVR0T
|
||||
AQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAdBgNVHQ4EFgQUKWCqogni
|
||||
6SseJ/P6LXo0M2cK++QwHwYDVR0jBBgwFoAU/5nNuG4Tm4v2y9uKf428/4fVQesw
|
||||
gYQGCCsGAQUFBwEBBHgwdjA5BggrBgEFBQcwAoYtaHR0cDovL1RTQUNBLnRpbWVz
|
||||
dGFtcGF1dGhvcml0eS5jb20vVFNBQ0EuY3J0MDkGCCsGAQUFBzABhi1odHRwOi8v
|
||||
b2NzcC5UU0FDQS50aW1lc3RhbXBhdXRob3JpdHkuY29tOjkwODAwPgYDVR0fBDcw
|
||||
NTAzoDGgL4YtaHR0cDovL1RTQUNBLnRpbWVzdGFtcGF1dGhvcml0eS5jb20vVFNB
|
||||
Q0EuY3JsMFUGA1UdHgROMEygGDAKggh0ZXN0LmNvbTAKggh0ZXN0Lm9yZ6EwMAqH
|
||||
CAAAAAAAAAAAMCKHIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMA0G
|
||||
CSqGSIb3DQEBCwUAA4IBAQB4YXa5nVWUzWSsUDMfYFTEETOe8boUErwfrDNBuj6z
|
||||
B5en20FhI49i6PCYEfNq3vrAtPOEFJj+KPomN3C46VLxbUEvqWLdq6EyzWvVVmXK
|
||||
VLeC0qV0m6CFM8GplaWzZdfFTQaaLUhgY08ZU2gp4QsoS2YjAosxlZrNSm6pBbv3
|
||||
q+Og1KeSK8gKS0V89k+6e3LOEF6KaNWKSkoz5xDniQY//mTjiDcNmYUh0KhHfhdU
|
||||
eO92M82uJSaDqnRs5HsWPs6z6qdfpuvj++OtQ1VCM2p5SEH2sEomdeN3YYChuG4h
|
||||
yzn0mYAdbTyGJHlFm17AH+SQRbVqCKYdHDaqsMb+fWzi
|
||||
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-----
|
||||
MIIDkDCCAnigAwIBAgIUJ0nfE+EVsIThltlY2LHVWMJVIq4wDQYJKoZIhvcNAQEL
|
||||
MIIDkDCCAnigAwIBAgIULFuB5HWsyba6VHu2Ygv2vt4R4/swDQYJKoZIhvcNAQEL
|
||||
BQAwYDELMAkGA1UEBhMCUEwxFTATBgNVBAoMDG9zc2xzaWduY29kZTEkMCIGA1UE
|
||||
CwwbVGltZXN0YW1wIEF1dGhvcml0eSBSb290IENBMRQwEgYDVQQDDAtUU0EgUm9v
|
||||
dCBDQTAeFw0xNzAxMDEwMDAwMDBaFw0yNjExMTAwMDAwMDBaMGAxCzAJBgNVBAYT
|
||||
dCBDQTAeFw0xNzAxMDEwMDAwMDBaFw0zNjEyMjcwMDAwMDBaMGAxCzAJBgNVBAYT
|
||||
AlBMMRUwEwYDVQQKDAxvc3Nsc2lnbmNvZGUxJDAiBgNVBAsMG1RpbWVzdGFtcCBB
|
||||
dXRob3JpdHkgUm9vdCBDQTEUMBIGA1UEAwwLVFNBIFJvb3QgQ0EwggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGOTX1f9dmtUiyzlsUInRIGfRMya338SVx
|
||||
vYGeOwdpTSSGlYUVwR9AuFewQF5+klelstCJe+SoUG0AdzS30mRWlQrhip4UdvdW
|
||||
T2gkNKbSn6DQzlWoQej9izqRLxAsbuszgkvnLOBEmPaLimDsCgu0bAN95Hp0Hls9
|
||||
O/fVmzh8VuV4iscxc7q13ZB7CylWgwd55CFEGd/jpJ6kMwSHbOLoBWp4GQ3KxR+c
|
||||
ASAo0FapU2WSZB2EYWszRiyq91X+AvIYN4ypTv7RccgfUvnZ2qFykJAkf/wgkynu
|
||||
Qg7rCUNfUEpDc7jlqtDWR7iLrtHBkA17C3IU8ymmKQYWfw3ZyBwvAgMBAAGjQjBA
|
||||
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP+ZzbhuE5uL9svbin+NvP+H1UHr
|
||||
MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAbj3aFwIUxvzwgywO
|
||||
gj01JM8GNbw1E4MGdkaNI8rgeY8ay15ZXhR9NpRWWb6Y7IXPq5XhuEktVte5Z4Kf
|
||||
XLBrr7Xe9VVqJL9zd1tMzOEM/zG77rZf/iXBTZLkCtQc/GOEY4TTWKNEl5hiWVE0
|
||||
po97GX5XHoeyHlWQ75sd9z6MxFxmvdp9/uyYD700e9sd5gcD8LGvHw2DNy8vntYV
|
||||
ia9h95N9i1umffxU460o8W5GoIcsD13B3YftvnWhGSXqovBRFgcPAQZ4eW9Qh/zA
|
||||
4zQBQrRvmREPihXVdgtWVpbRchP99oSZBrYr7Hh/P69rycklquqxJl1ol1wbT6dK
|
||||
S5Gmng==
|
||||
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
tests/certs/tsa-serial
Normal file
1
tests/certs/tsa-serial
Normal file
@ -0,0 +1 @@
|
||||
bb7fd13ddf056e0a3e621d3537b25478
|
50
tests/client_http.py
Normal file
50
tests/client_http.py
Normal file
@ -0,0 +1,50 @@
|
||||
"""Implementation of a HTTP client"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import http.client
|
||||
|
||||
RESULT_PATH = os.getcwd()
|
||||
LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/")
|
||||
PORT_LOG = os.path.join(LOGS_PATH, "./port.log")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Creating a POST Request"""
|
||||
ret = 0
|
||||
try:
|
||||
with open(PORT_LOG, 'r') as file:
|
||||
port = file.readline()
|
||||
conn = http.client.HTTPConnection('127.0.0.1', port)
|
||||
conn.request('POST', '/kill_server')
|
||||
response = conn.getresponse()
|
||||
print("HTTP status code:", response.getcode(), end=', ')
|
||||
try:
|
||||
text = response.read()
|
||||
print(text.decode("UTF-8"), end='', flush=True)
|
||||
except OSError as err:
|
||||
print(f"Warning: {err}")
|
||||
conn.close()
|
||||
except OSError as err:
|
||||
print(f"OSError: {err}")
|
||||
ret = err.errno
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
print(f"HTTP client error: {err}")
|
||||
ret = err
|
||||
finally:
|
||||
sys.exit(ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
# pylint: disable=pointless-string-statement
|
||||
"""
|
||||
Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
"""
|
@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
result=0
|
||||
|
||||
@ -18,10 +18,11 @@ make_certs() {
|
||||
script_path=$(pwd)
|
||||
cd "${result_path}"
|
||||
mkdir "tmp/"
|
||||
rm -rf "../certs"
|
||||
|
||||
################################################################################
|
||||
# OpenSSL settings
|
||||
CONF="${script_path}/openssl_intermediate.cnf"
|
||||
################################################################################
|
||||
|
||||
if test -n "$1"
|
||||
then
|
||||
OPENSSL="$1/bin/openssl"
|
||||
@ -34,14 +35,18 @@ make_certs() {
|
||||
touch "CA/index.txt"
|
||||
echo -n "unique_subject = no" > "CA/index.txt.attr"
|
||||
$OPENSSL rand -hex 16 > "CA/serial"
|
||||
$OPENSSL rand -hex 16 > "tsa-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
|
||||
|
||||
printf "\nGenerate root CA certificate\n" >> "makecerts.log"
|
||||
"$OPENSSL" genrsa -out CA/CA.key \
|
||||
################################################################################
|
||||
# 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 '
|
||||
@ -49,35 +54,52 @@ make_certs() {
|
||||
OPENSSL="$0"
|
||||
export LD_LIBRARY_PATH="$1"
|
||||
CONF="${script_path}/openssl_root.cnf"
|
||||
"$OPENSSL" req -config "$CONF" -new -x509 -days 3600 -key CA/CA.key -out tmp/CACert.pem \
|
||||
"$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 intermediate CA certificate\n" >> "makecerts.log"
|
||||
"$OPENSSL" genrsa -out CA/intermediate.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/intermediate.key -out CA/intermediate.csr \
|
||||
-subj "/C=PL/O=osslsigncode/OU=Certification Authority/CN=Intermediate 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" ca -config "$CONF" -batch -in CA/intermediate.csr -out CA/intermediate.cer \
|
||||
"$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 $?
|
||||
"$OPENSSL" x509 -in CA/intermediate.cer -out tmp/intermediate.pem \
|
||||
2>> "makecerts.log" 1>&2
|
||||
|
||||
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
|
||||
@ -90,6 +112,46 @@ make_certs() {
|
||||
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" \
|
||||
@ -108,7 +170,7 @@ make_certs() {
|
||||
test_result $?
|
||||
|
||||
printf "\nAttach intermediate certificate to revoked certificate\n" >> "makecerts.log"
|
||||
cat tmp/intermediate.pem >> tmp/revoked.pem 2>> "makecerts.log"
|
||||
cat tmp/intermediateCA.pem >> tmp/revoked.pem 2>> "makecerts.log"
|
||||
test_result $?
|
||||
|
||||
printf "\nGenerate CRL file\n" >> "makecerts.log"
|
||||
@ -121,24 +183,6 @@ make_certs() {
|
||||
2>> "makecerts.log" 1>&2' "$OPENSSL" "$LD_LIBRARY_PATH"
|
||||
test_result $?
|
||||
|
||||
printf "\nConvert revoked certificate to SPC format\n" >> "makecerts.log"
|
||||
"$OPENSSL" crl2pkcs7 -in tmp/CACertCRL.pem -certfile tmp/revoked.pem -outform DER -out tmp/revoked.spc \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nGenerate CSP Cross-Certificate\n" >> "makecerts.log"
|
||||
"$OPENSSL" genrsa -out CA/cross.key \
|
||||
2>> "makecerts.log" 1>&2
|
||||
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_intermediate.cnf"
|
||||
"$OPENSSL" req -config "$CONF" -new -x509 -days 900 -key CA/cross.key -out tmp/crosscert.pem \
|
||||
-subj "/C=PL/O=osslsigncode/OU=CSP/CN=crosscert/emailAddress=osslsigncode@example.com" \
|
||||
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" \
|
||||
@ -151,23 +195,13 @@ make_certs() {
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nConvert the key to DER format\n" >> "makecerts.log"
|
||||
"$OPENSSL" rsa -in tmp/key.pem -outform DER -out tmp/key.der -passout pass:"$password" \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nConvert the key to PVK format\n" >> "makecerts.log"
|
||||
"$OPENSSL" rsa -in tmp/key.pem -outform PVK -out tmp/key.pvk -pvk-none \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nConvert the certificate to DER format\n" >> "makecerts.log"
|
||||
"$OPENSSL" x509 -in tmp/cert.pem -outform DER -out tmp/cert.der \
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nAttach intermediate certificate to code signing certificate\n" >> "makecerts.log"
|
||||
cat tmp/intermediate.pem >> tmp/cert.pem 2>> "makecerts.log"
|
||||
cat tmp/intermediateCA.pem >> tmp/cert.pem 2>> "makecerts.log"
|
||||
test_result $?
|
||||
|
||||
printf "\nConvert the certificate to SPC format\n" >> "makecerts.log"
|
||||
@ -175,7 +209,25 @@ make_certs() {
|
||||
2>> "makecerts.log" 1>&2
|
||||
test_result $?
|
||||
|
||||
printf "\nConvert the certificate and the key into a PKCS#12 container\n" >> "makecerts.log"
|
||||
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
|
||||
@ -194,9 +246,95 @@ make_certs() {
|
||||
test_result $?
|
||||
|
||||
printf "\nAttach intermediate certificate to expired certificate\n" >> "makecerts.log"
|
||||
cat tmp/intermediate.pem >> tmp/expired.pem 2>> "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
|
||||
@ -205,10 +343,44 @@ make_certs() {
|
||||
OPENSSL="$0"
|
||||
export LD_LIBRARY_PATH="$1"
|
||||
CONF="${script_path}/openssl_tsa_root.cnf"
|
||||
"$OPENSSL" req -config "$CONF" -new -x509 -days 3600 -key CA/TSACA.key -out tmp/TSACA.pem \
|
||||
"$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 \
|
||||
@ -225,29 +397,45 @@ make_certs() {
|
||||
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/intermediate.pem -a -s tmp/CACert.pem -a -s tmp/CACertCRL.pem \
|
||||
################################################################################
|
||||
# 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.p12 -a -s tmp/cert.der -a -s tmp/cert.spc \
|
||||
-a -s tmp/crosscert.pem -a -s tmp/expired.pem -a -s tmp/revoked.pem -a -s tmp/revoked.spc \
|
||||
-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 "../certs"
|
||||
mkdir -p "../certs"
|
||||
cp tmp/* ../certs
|
||||
printf "%s" "keys & certificates successfully generated"
|
||||
printf "%s" "Keys & certificates successfully generated"
|
||||
else
|
||||
printf "%s" "error logs ${result_path}/makecerts.log"
|
||||
printf "%s" "Error logs ${result_path}/makecerts.log"
|
||||
result=1
|
||||
fi
|
||||
|
||||
# remove the working directory
|
||||
################################################################################
|
||||
# Remove the working directory
|
||||
################################################################################
|
||||
|
||||
rm -rf "CA/"
|
||||
rm -rf "tmp/"
|
||||
|
||||
exit "$result"
|
||||
}
|
||||
|
||||
# Tests requirement
|
||||
|
||||
################################################################################
|
||||
# Tests requirement and make certs
|
||||
################################################################################
|
||||
|
||||
if test -n "$(command -v faketime)"
|
||||
then
|
||||
make_certs "$1"
|
||||
|
@ -1,7 +1,7 @@
|
||||
# OpenSSL intermediate CA configuration file
|
||||
|
||||
[ default ]
|
||||
name = intermediate
|
||||
name = intermediateCA
|
||||
default_ca = CA_default
|
||||
|
||||
[ CA_default ]
|
||||
@ -15,12 +15,13 @@ 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 = 180101000000Z
|
||||
default_enddate = 241231000000Z
|
||||
default_startdate = 20180101000000Z
|
||||
default_enddate = 20341231000000Z
|
||||
x509_extensions = v3_req
|
||||
email_in_dn = yes
|
||||
default_days = 2200
|
||||
|
79
tests/conf/openssl_intermediate_crldp.cnf
Normal file
79
tests/conf/openssl_intermediate_crldp.cnf
Normal file
@ -0,0 +1,79 @@
|
||||
# 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
|
@ -18,8 +18,8 @@ crl_extensions = crl_ext
|
||||
default_md = sha256
|
||||
preserve = no
|
||||
policy = policy_match
|
||||
default_startdate = 180101000000Z
|
||||
default_enddate = 260101000000Z
|
||||
default_startdate = 20180101000000Z
|
||||
default_enddate = 20360101000000Z
|
||||
x509_extensions = v3_intermediate_ca
|
||||
email_in_dn = yes
|
||||
default_days = 3000
|
||||
|
@ -2,10 +2,8 @@
|
||||
|
||||
[ default ]
|
||||
name = TSACA
|
||||
domain_suffix = timestampauthority.com
|
||||
aia_url = http://$name.$domain_suffix/$name.crt
|
||||
crl_url = http://$name.$domain_suffix/$name.crl
|
||||
ocsp_url = http://ocsp.$name.$domain_suffix:9080
|
||||
domain_suffix = timestampauthority
|
||||
crl_url = http://127.0.0.1:19254/$name
|
||||
name_opt = utf8, esc_ctrl, multiline, lname, align
|
||||
default_ca = CA_default
|
||||
|
||||
@ -17,6 +15,7 @@ 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
|
||||
@ -25,8 +24,9 @@ default_days = 3650
|
||||
default_crl_days = 365
|
||||
policy = policy_match
|
||||
default_startdate = 20180101000000Z
|
||||
default_enddate = 20280101000000Z
|
||||
default_enddate = 20380101000000Z
|
||||
unique_subject = no
|
||||
email_in_dn = no
|
||||
x509_extensions = tsa_extensions
|
||||
|
||||
[ policy_match ]
|
||||
@ -42,17 +42,17 @@ basicConstraints = critical, CA:false
|
||||
extendedKeyUsage = critical, timeStamping
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always
|
||||
authorityInfoAccess = @issuer_info
|
||||
crlDistributionPoints = @crl_info
|
||||
nameConstraints = @name_constraints
|
||||
|
||||
[ issuer_info ]
|
||||
caIssuers;URI.0 = $aia_url
|
||||
OCSP;URI.0 = $ocsp_url
|
||||
|
||||
[ 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
|
||||
|
BIN
tests/files/unsigned.256appx
Normal file
BIN
tests/files/unsigned.256appx
Normal file
Binary file not shown.
BIN
tests/files/unsigned.512appx
Normal file
BIN
tests/files/unsigned.512appx
Normal file
Binary file not shown.
BIN
tests/files/unsigned.cat
Executable file → Normal file
BIN
tests/files/unsigned.cat
Executable file → Normal file
Binary file not shown.
0
tests/files/unsigned.exe
Executable file → Normal file
0
tests/files/unsigned.exe
Executable file → Normal file
BIN
tests/files/unsigned.mof
Normal file
BIN
tests/files/unsigned.mof
Normal file
Binary file not shown.
2
tests/files/unsigned.ps1
Normal file
2
tests/files/unsigned.ps1
Normal file
@ -0,0 +1,2 @@
|
||||
cls
|
||||
Write-Host "żółć"
|
5
tests/files/unsigned.psc1
Normal file
5
tests/files/unsigned.psc1
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PSConsoleFile ConsoleSchemaVersion="1.0">
|
||||
<PSVersion>5.1.19041.3930</PSVersion>
|
||||
<PSSnapIns />
|
||||
</PSConsoleFile>
|
161
tests/server_http.py
Normal file
161
tests/server_http.py
Normal file
@ -0,0 +1,161 @@
|
||||
"""Implementation of a HTTP server"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
from urllib.parse import urlparse
|
||||
from http.server import SimpleHTTPRequestHandler, HTTPServer
|
||||
from socketserver import ThreadingMixIn
|
||||
|
||||
RESULT_PATH = os.getcwd()
|
||||
FILES_PATH = os.path.join(RESULT_PATH, "./Testing/files/")
|
||||
CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
|
||||
CONF_PATH = os.path.join(RESULT_PATH, "./Testing/conf/")
|
||||
LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/")
|
||||
REQUEST = os.path.join(FILES_PATH, "./jreq.tsq")
|
||||
RESPONS = os.path.join(FILES_PATH, "./jresp.tsr")
|
||||
CACRL = os.path.join(CERTS_PATH, "./CACertCRL.der")
|
||||
TSACRL = os.path.join(CERTS_PATH, "./TSACertCRL.der")
|
||||
OPENSSL_CONF = os.path.join(CONF_PATH, "./openssl_tsa.cnf")
|
||||
PORT_LOG = os.path.join(LOGS_PATH, "./port.log")
|
||||
|
||||
|
||||
OPENSSL_TS = ["openssl", "ts",
|
||||
"-reply", "-config", OPENSSL_CONF,
|
||||
"-passin", "pass:passme",
|
||||
"-queryfile", REQUEST,
|
||||
"-out", RESPONS]
|
||||
|
||||
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
|
||||
daemon_threads = True
|
||||
|
||||
class RequestHandler(SimpleHTTPRequestHandler):
|
||||
"""Handle the HTTP POST request that arrive at the server"""
|
||||
|
||||
def __init__(self, request, client_address, server):
|
||||
# Save the server handle
|
||||
self.server = server
|
||||
SimpleHTTPRequestHandler.__init__(self, request, client_address, server)
|
||||
|
||||
def do_GET(self): # pylint: disable=invalid-name
|
||||
""""Serves the GET request type"""
|
||||
try:
|
||||
url = urlparse(self.path)
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "application/crl")
|
||||
self.end_headers()
|
||||
resp_data = b''
|
||||
# Read the file and send the contents
|
||||
if url.path == "/intermediateCA":
|
||||
with open(CACRL, 'rb') as file:
|
||||
resp_data = file.read()
|
||||
if url.path == "/TSACA":
|
||||
with open(TSACRL, 'rb') as file:
|
||||
resp_data = file.read()
|
||||
self.wfile.write(resp_data)
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
print("HTTP GET request error: {}".format(err))
|
||||
|
||||
|
||||
def do_POST(self): # pylint: disable=invalid-name
|
||||
""""Serves the POST request type"""
|
||||
try:
|
||||
url = urlparse(self.path)
|
||||
self.send_response(200)
|
||||
if url.path == "/kill_server":
|
||||
self.log_message(f"Deleting file: {PORT_LOG}")
|
||||
os.remove(f"{PORT_LOG}")
|
||||
self.send_header('Content-type', 'text/plain')
|
||||
self.end_headers()
|
||||
self.wfile.write(bytes('Shutting down HTTP server', 'utf-8'))
|
||||
self.server.shutdown()
|
||||
else:
|
||||
content_length = int(self.headers['Content-Length'])
|
||||
post_data = self.rfile.read(content_length)
|
||||
with open(REQUEST, mode="wb") as file:
|
||||
file.write(post_data)
|
||||
openssl = subprocess.run(OPENSSL_TS,
|
||||
check=True, universal_newlines=True)
|
||||
openssl.check_returncode()
|
||||
self.send_header("Content-type", "application/timestamp-reply")
|
||||
self.end_headers()
|
||||
resp_data = b''
|
||||
with open(RESPONS, mode="rb") as file:
|
||||
resp_data = file.read()
|
||||
self.wfile.write(resp_data)
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
print("HTTP POST request error: {}".format(err))
|
||||
|
||||
|
||||
class HttpServerThread():
|
||||
"""TSA server thread handler"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
self.server = None
|
||||
self.server_thread = None
|
||||
|
||||
def start_server(self, port) -> (int):
|
||||
"""Starting HTTP server on 127.0.0.1 and a random available port for binding"""
|
||||
self.server = ThreadingHTTPServer(('127.0.0.1', port), RequestHandler)
|
||||
self.server_thread = threading.Thread(target=self.server.serve_forever)
|
||||
self.server_thread.start()
|
||||
hostname, port = self.server.server_address[:2]
|
||||
print("HTTP server started, URL http://{}:{}".format(hostname, port))
|
||||
return port
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Start HTTP server"""
|
||||
ret = 0
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--port",
|
||||
type=int,
|
||||
default=0,
|
||||
help="port number"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
server = HttpServerThread()
|
||||
port = server.start_server(args.port)
|
||||
with open(PORT_LOG, mode="w") as file:
|
||||
file.write("{}".format(port))
|
||||
except OSError as err:
|
||||
print("OSError: {}".format(err))
|
||||
ret = err.errno
|
||||
finally:
|
||||
sys.exit(ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
fpid = os.fork()
|
||||
if fpid > 0:
|
||||
sys.exit(0)
|
||||
except OSError as ferr:
|
||||
print("Fork #1 failed: {} {}".format(ferr.errno, ferr.strerror))
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
fpid = os.fork()
|
||||
if fpid > 0:
|
||||
sys.exit(0)
|
||||
except OSError as ferr:
|
||||
print("Fork #2 failed: {} {}".format(ferr.errno, ferr.strerror))
|
||||
sys.exit(1)
|
||||
|
||||
# Start the daemon main loop
|
||||
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:
|
||||
"""
|
135
tests/server_http.pyw
Normal file
135
tests/server_http.pyw
Normal file
@ -0,0 +1,135 @@
|
||||
"""Windows: Implementation of a HTTP server"""
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
from urllib.parse import urlparse
|
||||
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
|
||||
|
||||
RESULT_PATH = os.getcwd()
|
||||
FILES_PATH = os.path.join(RESULT_PATH, "./Testing/files/")
|
||||
CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
|
||||
CONF_PATH = os.path.join(RESULT_PATH, "./Testing/conf/")
|
||||
LOGS_PATH = os.path.join(RESULT_PATH, "./Testing/logs/")
|
||||
REQUEST = os.path.join(FILES_PATH, "./jreq.tsq")
|
||||
RESPONS = os.path.join(FILES_PATH, "./jresp.tsr")
|
||||
CACRL = os.path.join(CERTS_PATH, "./CACertCRL.der")
|
||||
TSACRL = os.path.join(CERTS_PATH, "./TSACertCRL.der")
|
||||
OPENSSL_CONF = os.path.join(CONF_PATH, "./openssl_tsa.cnf")
|
||||
SERVER_LOG = os.path.join(LOGS_PATH, "./server.log")
|
||||
PORT_LOG = os.path.join(LOGS_PATH, "./port.log")
|
||||
|
||||
|
||||
OPENSSL_TS = ["openssl", "ts",
|
||||
"-reply", "-config", OPENSSL_CONF,
|
||||
"-passin", "pass:passme",
|
||||
"-queryfile", REQUEST,
|
||||
"-out", RESPONS]
|
||||
|
||||
|
||||
class RequestHandler(SimpleHTTPRequestHandler):
|
||||
"""Handle the HTTP POST request that arrive at the server"""
|
||||
|
||||
def __init__(self, request, client_address, server):
|
||||
# Save the server handle
|
||||
self.server = server
|
||||
SimpleHTTPRequestHandler.__init__(self, request, client_address, server)
|
||||
|
||||
def do_GET(self): # pylint: disable=invalid-name
|
||||
""""Serves the GET request type"""
|
||||
try:
|
||||
url = urlparse(self.path)
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "application/crl")
|
||||
self.end_headers()
|
||||
resp_data = b''
|
||||
# Read the file and send the contents
|
||||
if url.path == "/intermediateCA":
|
||||
with open(CACRL, 'rb') as file:
|
||||
resp_data = file.read()
|
||||
if url.path == "/TSACA":
|
||||
with open(TSACRL, 'rb') as file:
|
||||
resp_data = file.read()
|
||||
self.wfile.write(resp_data)
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
print("HTTP GET request error: {}".format(err))
|
||||
|
||||
|
||||
def do_POST(self): # pylint: disable=invalid-name
|
||||
""""Serves the POST request type"""
|
||||
try:
|
||||
url = urlparse(self.path)
|
||||
self.send_response(200)
|
||||
if url.path == "/kill_server":
|
||||
self.log_message(f"Deleting file: {PORT_LOG}")
|
||||
os.remove(f"{PORT_LOG}")
|
||||
self.send_header('Content-type', 'text/plain')
|
||||
self.end_headers()
|
||||
self.wfile.write(bytes('Shutting down HTTP server', 'utf-8'))
|
||||
self.server.shutdown()
|
||||
else:
|
||||
content_length = int(self.headers['Content-Length'])
|
||||
post_data = self.rfile.read(content_length)
|
||||
with open(REQUEST, mode="wb") as file:
|
||||
file.write(post_data)
|
||||
openssl = subprocess.run(OPENSSL_TS,
|
||||
check=True, universal_newlines=True)
|
||||
openssl.check_returncode()
|
||||
self.send_header("Content-type", "application/timestamp-reply")
|
||||
self.end_headers()
|
||||
resp_data = b''
|
||||
with open(RESPONS, mode="rb") as file:
|
||||
resp_data = file.read()
|
||||
self.wfile.write(resp_data)
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
print("HTTP POST request error: {}".format(err))
|
||||
|
||||
|
||||
class HttpServerThread():
|
||||
"""TSA server thread handler"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
def __init__(self):
|
||||
self.server = None
|
||||
self.server_thread = None
|
||||
|
||||
def start_server(self) -> (int):
|
||||
"""Starting HTTP server on 127.0.0.1 and a random available port for binding"""
|
||||
self.server = ThreadingHTTPServer(('127.0.0.1', 19254), RequestHandler)
|
||||
self.server_thread = threading.Thread(target=self.server.serve_forever)
|
||||
self.server_thread.start()
|
||||
hostname, port = self.server.server_address[:2]
|
||||
print("HTTP server started, URL http://{}:{}".format(hostname, port))
|
||||
return port
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Start HTTP server"""
|
||||
ret = 0
|
||||
try:
|
||||
sys.stdout = open(SERVER_LOG, "w")
|
||||
sys.stderr = open(SERVER_LOG, "a")
|
||||
server = HttpServerThread()
|
||||
port = server.start_server()
|
||||
with open(PORT_LOG, mode="w") as file:
|
||||
file.write("{}".format(port))
|
||||
except OSError as err:
|
||||
print("OSError: {}".format(err))
|
||||
ret = err.errno
|
||||
finally:
|
||||
sys.exit(ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
# pylint: disable=pointless-string-statement
|
||||
"""Local Variables:
|
||||
c-basic-offset: 4
|
||||
tab-width: 4
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
vim: set ts=4 expandtab:
|
||||
"""
|
57
tests/sources/CatalogDefinitionFileName.cdf
Normal file
57
tests/sources/CatalogDefinitionFileName.cdf
Normal file
@ -0,0 +1,57 @@
|
||||
# https://learn.microsoft.com/en-us/windows/win32/seccrypto/makecat
|
||||
# makecat -v CatalogDefinitionFileName.cdf
|
||||
|
||||
# Define information about the entire catalog file.
|
||||
[CatalogHeader]
|
||||
|
||||
# Name of the catalog file, including its extension.
|
||||
Name=unsigned.cat
|
||||
|
||||
# Directory where the created unsigned.cat file will be placed.
|
||||
ResultDir=..\files
|
||||
|
||||
# This option is not supported. Default value 1 is used.
|
||||
PublicVersion=0x0000001
|
||||
|
||||
# Catalog version.
|
||||
# If the version is set to 2, the HashAlgorithms option must contain SHA256.
|
||||
CatalogVersion=2
|
||||
|
||||
# Name of the hashing algorithm used.
|
||||
HashAlgorithms=SHA256
|
||||
|
||||
# Specifies whether to hash the files listed in the <HASH> option in the [CatalogFiles] section
|
||||
PageHashes=true
|
||||
|
||||
# Type of message encoding used.
|
||||
# The default EncodingType is PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0x00010001
|
||||
EncodingType=0x00010001
|
||||
|
||||
# Specify an attribute of the catalog file.
|
||||
# Set 1.3.6.1.4.1.311.12.2.1 CAT_NAMEVALUE_OBJID
|
||||
# CATATTR1={type}:{oid}:{value} (optional)
|
||||
# The OSAttr attribute specifies the target Windows version
|
||||
CATATTR1=0x11010001:OSAttr:2:6.0
|
||||
|
||||
# Define each member of the catalog file.
|
||||
[CatalogFiles]
|
||||
|
||||
<HASH>PEfile=..\files\unsigned.exe
|
||||
# 0x00010000 Attribute is represented in plaintext. No conversion will be done.
|
||||
<HASH>PEfileATTR1=0x11010001:File:unsigned.exe
|
||||
|
||||
<HASH>MSIfile=..\files\unsigned.msi
|
||||
# 0x00020000 Attribute is represented in base-64 encoding.
|
||||
<HASH>MSIfileATTR1=0x11020001:File:dW5zaWduZWQubXNp
|
||||
|
||||
<HASH>CABfile=..\files\unsigned.ex_
|
||||
<HASH>CABfileATTR1=0x11010001:File:unsigned.ex_
|
||||
|
||||
<HASH>PS1file=..\files\unsigned.ps1
|
||||
<HASH>PS1fileATTR1=0x11010001:File:unsigned.ps1
|
||||
|
||||
<HASH>PSC1file=..\files\unsigned.psc1
|
||||
<HASH>PSC1fileATTR1=0x11010001:File:unsigned.psc1
|
||||
|
||||
<HASH>MOFfile=..\files\unsigned.mof
|
||||
<HASH>MOFfileATTR1=0x11010001:File:unsigned.mof
|
Binary file not shown.
@ -1,152 +0,0 @@
|
||||
"""Implementation of a Time Stamping Authority HTTP server"""
|
||||
|
||||
import argparse
|
||||
import contextlib
|
||||
import os
|
||||
import pathlib
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
|
||||
RESULT_PATH = os.getcwd()
|
||||
FILES_PATH = os.path.join(RESULT_PATH, "./Testing/files/")
|
||||
CERTS_PATH = os.path.join(RESULT_PATH, "./Testing/certs/")
|
||||
CONF_PATH = os.path.join(RESULT_PATH, "./Testing/conf/")
|
||||
DEFAULT_IN = os.path.join(FILES_PATH, "./unsigned.exe")
|
||||
DEFAULT_OUT = os.path.join(FILES_PATH, "./ts.exe")
|
||||
DEFAULT_CERT = os.path.join(CERTS_PATH, "./cert.pem")
|
||||
DEFAULT_KEY = os.path.join(CERTS_PATH, "./key.pem")
|
||||
DEFAULT_CROSSCERT = os.path.join(CERTS_PATH, "./crosscert.pem")
|
||||
OPENSSL_CONF = os.path.join(CONF_PATH, "./openssl_tsa.cnf")
|
||||
REQUEST = os.path.join(FILES_PATH, "./jreq.tsq")
|
||||
RESPONS = os.path.join(FILES_PATH, "./jresp.tsr")
|
||||
|
||||
if os.path.exists(os.path.join(RESULT_PATH, "./Release/")):
|
||||
OSSLSIGNCODE_FILE = os.path.join(RESULT_PATH, "./Release/osslsigncode")
|
||||
elif os.path.exists(os.path.join(RESULT_PATH, "./Debug/")):
|
||||
OSSLSIGNCODE_FILE = os.path.join(RESULT_PATH, "./Debug/osslsigncode")
|
||||
else:
|
||||
OSSLSIGNCODE_FILE = os.path.join(RESULT_PATH, "./osslsigncode")
|
||||
|
||||
DEFAULT_OPENSSL = ["openssl", "ts",
|
||||
"-reply", "-config", OPENSSL_CONF,
|
||||
"-passin", "pass:passme",
|
||||
"-queryfile", REQUEST,
|
||||
"-out", RESPONS]
|
||||
|
||||
|
||||
class RequestHandler(BaseHTTPRequestHandler):
|
||||
"""Handle the HTTP POST request that arrive at the server"""
|
||||
|
||||
def do_POST(self):
|
||||
""""Serves the POST request type"""
|
||||
try:
|
||||
content_length = int(self.headers['Content-Length'])
|
||||
post_data = self.rfile.read(content_length)
|
||||
with open(REQUEST, mode="wb") as file:
|
||||
file.write(post_data)
|
||||
openssl = subprocess.run(DEFAULT_OPENSSL,
|
||||
check=True, universal_newlines=True)
|
||||
openssl.check_returncode()
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "application/timestamp-reply")
|
||||
self.end_headers()
|
||||
resp_data = None
|
||||
with open(RESPONS, mode="rb") as file:
|
||||
resp_data = file.read()
|
||||
self.wfile.write(resp_data)
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
print(f"HTTP POST request error: {err}")
|
||||
|
||||
|
||||
class HttpServerThread():
|
||||
"""TSA server thread handler"""
|
||||
|
||||
def __init__(self):
|
||||
self.server = None
|
||||
self.server_thread = None
|
||||
|
||||
def start_server(self) -> (str, int):
|
||||
"""Starting TSA server on localhost and a first available port"""
|
||||
self.server = HTTPServer(("127.0.0.1", 0), RequestHandler)
|
||||
self.server_thread = threading.Thread(target=self.server.serve_forever)
|
||||
self.server_thread.start()
|
||||
hostname, port = self.server.server_address[:2]
|
||||
print(f"Timestamp server started, URL: http://{hostname}:{port}")
|
||||
return hostname, port
|
||||
|
||||
def shut_down(self):
|
||||
"""Shutting down the server"""
|
||||
if self.server:
|
||||
self.server.shutdown()
|
||||
self.server_thread.join()
|
||||
print("Server is down")
|
||||
|
||||
|
||||
def parse_args() -> str:
|
||||
"""Parse the command-line arguments."""
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--input",
|
||||
type=pathlib.Path,
|
||||
default=DEFAULT_IN,
|
||||
help="input file"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
type=pathlib.Path,
|
||||
default=DEFAULT_OUT,
|
||||
help="output file"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--certs",
|
||||
type=pathlib.Path,
|
||||
default=DEFAULT_CERT,
|
||||
help="signing certificate"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--key",
|
||||
type=pathlib.Path,
|
||||
default=DEFAULT_KEY,
|
||||
help="private key"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--crosscert",
|
||||
type=pathlib.Path,
|
||||
default=DEFAULT_CROSSCERT,
|
||||
help="additional certificates"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
program = [OSSLSIGNCODE_FILE, "sign", "-in", args.input, "-out", args.output,
|
||||
"-certs", args.certs, "-key", args.key,
|
||||
"-addUnauthenticatedBlob", "-add-msi-dse", "-comm", "-ph", "-jp", "low",
|
||||
"-h", "sha384", "-time", "1556668800", "-i", "https://www.osslsigncode.com/",
|
||||
"-n", "osslsigncode", "-ac", args.crosscert, "-ts"]
|
||||
return program
|
||||
|
||||
def main() -> None:
|
||||
"""Main program"""
|
||||
ret = 0
|
||||
program = parse_args()
|
||||
server = HttpServerThread()
|
||||
hostname, port = server.start_server()
|
||||
program.append(f"{hostname}:{port}")
|
||||
try:
|
||||
osslsigncode = subprocess.run(program, check=True, universal_newlines=True)
|
||||
osslsigncode.check_returncode()
|
||||
except subprocess.CalledProcessError as err:
|
||||
ret = err.returncode
|
||||
except OSError as err:
|
||||
print(f"OSError: {err}")
|
||||
ret = err.errno
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
print(f"osslsigncode error: {err}")
|
||||
ret = 1
|
||||
finally:
|
||||
server.shut_down()
|
||||
sys.exit(ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
347
utf.c
Normal file
347
utf.c
Normal file
@ -0,0 +1,347 @@
|
||||
// utf by pietro gagliardi (andlabs) — https://github.com/andlabs/utf/
|
||||
// 10 november 2016
|
||||
#include "utf.h"
|
||||
|
||||
// this code imitates Go's unicode/utf8 and unicode/utf16
|
||||
// the biggest difference is that a rune is unsigned instead of signed (because Go guarantees what a right shift on a signed number will do, whereas C does not)
|
||||
// it is also an imitation so we can license it under looser terms than the Go source
|
||||
#define badrune 0xFFFD
|
||||
|
||||
// encoded must be at most 4 bytes
|
||||
// TODO clean this code up somehow
|
||||
size_t utf8EncodeRune(uint32_t rune, char *encoded)
|
||||
{
|
||||
uint8_t b, c, d, e;
|
||||
size_t n;
|
||||
|
||||
// not in the valid range for Unicode
|
||||
if (rune > 0x10FFFF)
|
||||
rune = badrune;
|
||||
// surrogate runes cannot be encoded
|
||||
if (rune >= 0xD800 && rune < 0xE000)
|
||||
rune = badrune;
|
||||
|
||||
if (rune < 0x80) { // ASCII bytes represent themselves
|
||||
b = (uint8_t) (rune & 0xFF);
|
||||
n = 1;
|
||||
goto done;
|
||||
}
|
||||
if (rune < 0x800) { // two-byte encoding
|
||||
c = (uint8_t) (rune & 0x3F);
|
||||
c |= 0x80;
|
||||
rune >>= 6;
|
||||
b = (uint8_t) (rune & 0x1F);
|
||||
b |= 0xC0;
|
||||
n = 2;
|
||||
goto done;
|
||||
}
|
||||
if (rune < 0x10000) { // three-byte encoding
|
||||
d = (uint8_t) (rune & 0x3F);
|
||||
d |= 0x80;
|
||||
rune >>= 6;
|
||||
c = (uint8_t) (rune & 0x3F);
|
||||
c |= 0x80;
|
||||
rune >>= 6;
|
||||
b = (uint8_t) (rune & 0x0F);
|
||||
b |= 0xE0;
|
||||
n = 3;
|
||||
goto done;
|
||||
}
|
||||
// otherwise use a four-byte encoding
|
||||
e = (uint8_t) (rune & 0x3F);
|
||||
e |= 0x80;
|
||||
rune >>= 6;
|
||||
d = (uint8_t) (rune & 0x3F);
|
||||
d |= 0x80;
|
||||
rune >>= 6;
|
||||
c = (uint8_t) (rune & 0x3F);
|
||||
c |= 0x80;
|
||||
rune >>= 6;
|
||||
b = (uint8_t) (rune & 0x07);
|
||||
b |= 0xF0;
|
||||
n = 4;
|
||||
|
||||
done:
|
||||
encoded[0] = (char)b;
|
||||
if (n > 1)
|
||||
encoded[1] = (char)c;
|
||||
if (n > 2)
|
||||
encoded[2] = (char)d;
|
||||
if (n > 3)
|
||||
encoded[3] = (char)e;
|
||||
return n;
|
||||
}
|
||||
|
||||
const char *utf8DecodeRune(const char *s, size_t nElem, uint32_t *rune)
|
||||
{
|
||||
uint8_t b, c;
|
||||
uint8_t lowestAllowed, highestAllowed;
|
||||
size_t i, expected;
|
||||
int bad;
|
||||
|
||||
b = (uint8_t) (*s);
|
||||
if (b < 0x80) { // ASCII bytes represent themselves
|
||||
*rune = b;
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
// 0xC0 and 0xC1 cover 2-byte overlong equivalents
|
||||
// 0xF5 to 0xFD cover values > 0x10FFFF
|
||||
// 0xFE and 0xFF were never defined (always illegal)
|
||||
if (b < 0xC2 || b > 0xF4) { // invalid
|
||||
*rune = badrune;
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
// this determines the range of allowed first continuation bytes
|
||||
lowestAllowed = 0x80;
|
||||
highestAllowed = 0xBF;
|
||||
switch (b) {
|
||||
case 0xE0:
|
||||
// disallow 3-byte overlong equivalents
|
||||
lowestAllowed = 0xA0;
|
||||
break;
|
||||
case 0xED:
|
||||
// disallow surrogate characters
|
||||
highestAllowed = 0x9F;
|
||||
break;
|
||||
case 0xF0:
|
||||
// disallow 4-byte overlong equivalents
|
||||
lowestAllowed = 0x90;
|
||||
break;
|
||||
case 0xF4:
|
||||
// disallow values > 0x10FFFF
|
||||
highestAllowed = 0x8F;
|
||||
break;
|
||||
}
|
||||
|
||||
// and this determines how many continuation bytes are expected
|
||||
expected = 1;
|
||||
if (b >= 0xE0)
|
||||
expected++;
|
||||
if (b >= 0xF0)
|
||||
expected++;
|
||||
if (nElem != 0) { // are there enough bytes?
|
||||
nElem--;
|
||||
if (nElem < expected) { // nope
|
||||
*rune = badrune;
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
// ensure that everything is correct
|
||||
// if not, **only** consume the initial byte
|
||||
bad = 0;
|
||||
for (i = 0; i < expected; i++) {
|
||||
c = (uint8_t) (s[1 + i]);
|
||||
if (c < lowestAllowed || c > highestAllowed) {
|
||||
bad = 1;
|
||||
break;
|
||||
}
|
||||
// the old lowestAllowed and highestAllowed is only for the first continuation byte
|
||||
lowestAllowed = 0x80;
|
||||
highestAllowed = 0xBF;
|
||||
}
|
||||
if (bad) {
|
||||
*rune = badrune;
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
// now do the topmost bits
|
||||
if (b < 0xE0)
|
||||
*rune = b & 0x1F;
|
||||
else if (b < 0xF0)
|
||||
*rune = b & 0x0F;
|
||||
else
|
||||
*rune = b & 0x07;
|
||||
s++; // we can finally move on
|
||||
|
||||
// now do the continuation bytes
|
||||
for (; expected; expected--) {
|
||||
c = (uint8_t) (*s);
|
||||
s++;
|
||||
c &= 0x3F; // strip continuation bits
|
||||
*rune <<= 6;
|
||||
*rune |= c;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// encoded must have at most 2 elements
|
||||
size_t utf16EncodeRune(uint32_t rune, uint16_t *encoded)
|
||||
{
|
||||
uint16_t low, high;
|
||||
|
||||
// not in the valid range for Unicode
|
||||
if (rune > 0x10FFFF)
|
||||
rune = badrune;
|
||||
// surrogate runes cannot be encoded
|
||||
if (rune >= 0xD800 && rune < 0xE000)
|
||||
rune = badrune;
|
||||
|
||||
if (rune < 0x10000) {
|
||||
encoded[0] = (uint16_t) rune;
|
||||
return 1;
|
||||
}
|
||||
|
||||
rune -= 0x10000;
|
||||
low = (uint16_t) (rune & 0x3FF);
|
||||
rune >>= 10;
|
||||
high = (uint16_t) (rune & 0x3FF);
|
||||
encoded[0] = high | 0xD800;
|
||||
encoded[1] = low | 0xDC00;
|
||||
return 2;
|
||||
}
|
||||
|
||||
// TODO see if this can be cleaned up somehow
|
||||
const uint16_t *utf16DecodeRune(const uint16_t *s, size_t nElem, uint32_t *rune)
|
||||
{
|
||||
uint16_t high, low;
|
||||
|
||||
if (*s < 0xD800 || *s >= 0xE000) {
|
||||
// self-representing character
|
||||
*rune = *s;
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
if (*s >= 0xDC00) {
|
||||
// out-of-order surrogates
|
||||
*rune = badrune;
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
if (nElem == 1) { // not enough elements
|
||||
*rune = badrune;
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
high = *s;
|
||||
high &= 0x3FF;
|
||||
if (s[1] < 0xDC00 || s[1] >= 0xE000) {
|
||||
// bad surrogate pair
|
||||
*rune = badrune;
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
s++;
|
||||
low = *s;
|
||||
s++;
|
||||
low &= 0x3FF;
|
||||
*rune = high;
|
||||
*rune <<= 10;
|
||||
*rune |= low;
|
||||
*rune += 0x10000;
|
||||
return s;
|
||||
}
|
||||
|
||||
// TODO find a way to reduce the code in all of these somehow
|
||||
// TODO find a way to remove u as well
|
||||
size_t utf8RuneCount(const char *s, size_t nElem)
|
||||
{
|
||||
size_t len;
|
||||
uint32_t rune;
|
||||
|
||||
if (nElem != 0) {
|
||||
const char *t, *u;
|
||||
|
||||
len = 0;
|
||||
t = s;
|
||||
while (nElem != 0) {
|
||||
u = utf8DecodeRune(t, nElem, &rune);
|
||||
len++;
|
||||
nElem -= (size_t)(u - t);
|
||||
t = u;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
len = 0;
|
||||
while (*s) {
|
||||
s = utf8DecodeRune(s, nElem, &rune);
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t utf8UTF16Count(const char *s, size_t nElem)
|
||||
{
|
||||
size_t len;
|
||||
uint32_t rune;
|
||||
uint16_t encoded[2];
|
||||
|
||||
if (nElem != 0) {
|
||||
const char *t, *u;
|
||||
|
||||
len = 0;
|
||||
t = s;
|
||||
while (nElem != 0) {
|
||||
u = utf8DecodeRune(t, nElem, &rune);
|
||||
len += utf16EncodeRune(rune, encoded);
|
||||
nElem -= (size_t)(u - t);
|
||||
t = u;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
len = 0;
|
||||
while (*s) {
|
||||
s = utf8DecodeRune(s, nElem, &rune);
|
||||
len += utf16EncodeRune(rune, encoded);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t utf16RuneCount(const uint16_t *s, size_t nElem)
|
||||
{
|
||||
size_t len;
|
||||
uint32_t rune;
|
||||
|
||||
if (nElem != 0) {
|
||||
const uint16_t *t, *u;
|
||||
|
||||
len = 0;
|
||||
t = s;
|
||||
while (nElem != 0) {
|
||||
u = utf16DecodeRune(t, nElem, &rune);
|
||||
len++;
|
||||
nElem -= (size_t)(u - t);
|
||||
t = u;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
len = 0;
|
||||
while (*s) {
|
||||
s = utf16DecodeRune(s, nElem, &rune);
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t utf16UTF8Count(const uint16_t *s, size_t nElem)
|
||||
{
|
||||
size_t len;
|
||||
uint32_t rune;
|
||||
char encoded[4];
|
||||
|
||||
if (nElem != 0) {
|
||||
const uint16_t *t, *u;
|
||||
|
||||
len = 0;
|
||||
t = s;
|
||||
while (nElem != 0) {
|
||||
u = utf16DecodeRune(t, nElem, &rune);
|
||||
len += utf8EncodeRune(rune, encoded);
|
||||
nElem -= (size_t)(u - t);
|
||||
t = u;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
len = 0;
|
||||
while (*s) {
|
||||
s = utf16DecodeRune(s, nElem, &rune);
|
||||
len += utf8EncodeRune(rune, encoded);
|
||||
}
|
||||
return len;
|
||||
}
|
61
utf.h
Normal file
61
utf.h
Normal file
@ -0,0 +1,61 @@
|
||||
// utf by pietro gagliardi (andlabs) — https://github.com/andlabs/utf/
|
||||
// 10 november 2016
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// if nElem == 0, assume the buffer has no upper limit and is '\0' terminated
|
||||
// otherwise, assume buffer is NOT '\0' terminated but is bounded by nElem *elements*
|
||||
|
||||
extern size_t utf8EncodeRune(uint32_t rune, char *encoded);
|
||||
extern const char *utf8DecodeRune(const char *s, size_t nElem, uint32_t *rune);
|
||||
extern size_t utf16EncodeRune(uint32_t rune, uint16_t *encoded);
|
||||
extern const uint16_t *utf16DecodeRune(const uint16_t *s, size_t nElem, uint32_t *rune);
|
||||
|
||||
extern size_t utf8RuneCount(const char *s, size_t nElem);
|
||||
extern size_t utf8UTF16Count(const char *s, size_t nElem);
|
||||
extern size_t utf16RuneCount(const uint16_t *s, size_t nElem);
|
||||
extern size_t utf16UTF8Count(const uint16_t *s, size_t nElem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
// Provide overloads on Windows for using these functions with wchar_t and WCHAR when wchar_t is a keyword in C++ mode (the default).
|
||||
// Otherwise, you'd need to cast to pass a wchar_t pointer, WCHAR pointer, or equivalent to these functions.
|
||||
// We use __wchar_t to be independent of the setting; see https://blogs.msdn.microsoft.com/oldnewthing/20161201-00/?p=94836 (ironically posted one day after I initially wrote this code!).
|
||||
// TODO check this on MinGW-w64
|
||||
// TODO check this under /Wall
|
||||
// TODO C-style casts enough? or will that fail in /Wall?
|
||||
// TODO same for UniChar/unichar on Mac? if both are unsigned then we have nothing to worry about
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
inline size_t utf16EncodeRune(uint32_t rune, __wchar_t *encoded)
|
||||
{
|
||||
return utf16EncodeRune(rune, reinterpret_cast<uint16_t *>(encoded));
|
||||
}
|
||||
|
||||
inline const __wchar_t *utf16DecodeRune(const __wchar_t *s, size_t nElem, uint32_t *rune)
|
||||
{
|
||||
const uint16_t *ret;
|
||||
|
||||
ret = utf16DecodeRune(reinterpret_cast<const uint16_t *>(s), nElem, rune);
|
||||
return reinterpret_cast<const __wchar_t *>(ret);
|
||||
}
|
||||
|
||||
inline size_t utf16RuneCount(const __wchar_t *s, size_t nElem)
|
||||
{
|
||||
return utf16RuneCount(reinterpret_cast<const uint16_t *>(s), nElem);
|
||||
}
|
||||
|
||||
inline size_t utf16UTF8Count(const __wchar_t *s, size_t nElem)
|
||||
{
|
||||
return utf16UTF8Count(reinterpret_cast<const uint16_t *>(s), nElem);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -8,5 +8,6 @@
|
||||
"name": "python3",
|
||||
"platform": "!(windows & static) & !osx"
|
||||
}
|
||||
]
|
||||
],
|
||||
"builtin-baseline": "9edb1b8e590cc086563301d735cae4b6e732d2d2"
|
||||
}
|
||||
|
Reference in New Issue
Block a user