├── .gitattributes ├── .github └── workflows │ ├── linux.yml │ ├── macos.yml │ └── windows.yml ├── .gitignore ├── CHANGELOG ├── LICENSE.md ├── NOTICE.md ├── README.md ├── build ├── linux │ ├── Makefile │ ├── build.sh │ └── pkcs11-logger.version ├── macos │ ├── Makefile │ ├── build.sh │ └── pkcs11-logger.symbols └── windows │ ├── build.bat │ ├── pkcs11-logger.sln │ ├── pkcs11-logger │ ├── pkcs11-logger.vcxproj │ └── pkcs11-logger.vcxproj.filters │ └── sign.bat ├── src ├── cryptoki │ ├── pkcs11.h │ ├── pkcs11f.h │ └── pkcs11t.h ├── dl.c ├── init.c ├── lock.c ├── log.c ├── pkcs11-logger.c ├── pkcs11-logger.h ├── translate.c └── utils.c └── test ├── Pkcs11LoggerTests.sln └── Pkcs11LoggerTests ├── BasicPkcs11LoggerTests.cs ├── EnvVarUtils.cs ├── Pkcs11LoggerTests.csproj ├── Settings.cs └── pkcs11-mock ├── README.txt ├── linux ├── pkcs11-mock-x64.so └── pkcs11-mock-x86.so ├── macos └── pkcs11-mock.dylib └── windows ├── pkcs11-mock-x64.dll └── pkcs11-mock-x86.dll /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behaviour, in case users don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files we want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.c text 7 | *.cs text 8 | *.config text 9 | *.h text 10 | *.txt text 11 | 12 | # Declare files that will always have CRLF line endings on checkout. 13 | *.sln text eol=crlf 14 | *.vcxproj text eol=crlf 15 | *.vcxproj.filters text eol=crlf 16 | *.csproj text eol=crlf 17 | 18 | # Denote all files that are truly binary and should not be modified. 19 | *.pdf binary 20 | *.dll binary 21 | -------------------------------------------------------------------------------- /.github/workflows/linux.yml: -------------------------------------------------------------------------------- 1 | name: Linux 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Setup OS 15 | run: | 16 | sudo apt-get update 17 | sudo apt-get install -y build-essential gcc-multilib 18 | 19 | - name: Checkout source 20 | uses: actions/checkout@v4 21 | 22 | - name: Build source 23 | run: | 24 | cd build/linux/ 25 | sh build.sh 26 | 27 | - name: Run tests 28 | run: | 29 | dotnet build ./test/Pkcs11LoggerTests.sln 30 | dotnet test ./test/Pkcs11LoggerTests.sln 31 | 32 | - name: Upload artifacts 33 | uses: actions/upload-artifact@v4 34 | with: 35 | name: pkcs11-logger-linux 36 | path: build/linux/pkcs11-logger-*.so 37 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: macOS 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | build: 11 | runs-on: macos-latest 12 | 13 | steps: 14 | - name: Checkout source 15 | uses: actions/checkout@v4 16 | 17 | - name: Build source 18 | run: | 19 | cd build/macos/ 20 | sh build.sh 21 | 22 | - name: Run tests 23 | run: | 24 | dotnet build ./test/Pkcs11LoggerTests.sln 25 | dotnet test ./test/Pkcs11LoggerTests.sln 26 | 27 | - name: Upload artifacts 28 | uses: actions/upload-artifact@v4 29 | with: 30 | name: pkcs11-logger-macos 31 | path: build/macos/pkcs11-logger.dylib 32 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | build: 11 | runs-on: windows-latest 12 | 13 | steps: 14 | - name: Checkout source 15 | uses: actions/checkout@v4 16 | 17 | - name: Build source 18 | shell: cmd 19 | run: | 20 | cd build/windows/ 21 | build.bat 22 | 23 | - name: Run tests 24 | shell: cmd 25 | run: | 26 | dotnet build .\test\Pkcs11LoggerTests.sln 27 | dotnet test .\test\Pkcs11LoggerTests.sln 28 | 29 | - name: Upload artifacts 30 | uses: actions/upload-artifact@v4 31 | with: 32 | name: pkcs11-logger-windows 33 | path: build/windows/pkcs11-logger-*.dll 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | [Bb]in/ 2 | [Oo]bj/ 3 | *.userprefs 4 | test-results/ 5 | TestResults/ 6 | *.sdf 7 | *.suo 8 | *.user 9 | Debug/ 10 | Release/ 11 | ipch/ 12 | .vs/ 13 | /build/windows/pkcs11-logger-x86.dll 14 | /build/windows/pkcs11-logger-x64.dll 15 | /build/linux/pkcs11-logger-x86.so 16 | /build/linux/pkcs11-logger-x64.so 17 | /build/macos/pkcs11-logger-x64.dylib 18 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | PKCS11-LOGGER 2.3.0 (2025-02-12) 2 | - #4 - Added break missing in the function translating CK_RV 3 | Based on code provided by @viperomega 4 | - #5 - Skip logging the value of PKCS#11 attributes that cannot be read 5 | - #8 - Fixed multiple compilation warnings on macOS 6 | Based on code provided by @LudovicRousseau 7 | - #8 - Use pthread_threadid_np instead of pthread_self on macOS 8 | Based on code provided by @LudovicRousseau 9 | - #8 - Print thread_id with the correct 64-bit size 10 | Based on code provided by @LudovicRousseau 11 | - #16 - Uses PKCS#11 v3.1 headers but still supports only PKCS#11 v2.20 12 | - #17 - Target current platforms 13 | - #22 - Enabled GitHub Actions 14 | - #24 - Use LoadLibraryEx instead of LoadLibrary 15 | - #25 - Add microseconds to timestamps 16 | Based on code provided by @lImbus 17 | - #26 - Log performance related data 18 | 19 | PKCS11-LOGGER 2.2.0 (2016-04-03) 20 | - License changed to the Apache License, Version 2.0 21 | 22 | PKCS11-LOGGER 2.1.0 (2015-11-25) 23 | - Increased performance when logging into the file 24 | - Fixed reading of environment variables on Windows 25 | 26 | PKCS11-LOGGER 2.0.0 (2014-02-14) 27 | - Introduced PKCS11_LOGGER_FLAGS environment variable 28 | - Added support for Visual Studio builds 29 | - Added support for Mac OS X 30 | - Added support for 64-bit platforms 31 | 32 | PKCS11-LOGGER 1.0 (2013-01-13) 33 | - Initial stable release -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Apache License 2 | **Version 2.0, January 2004** 3 | http://www.apache.org/licenses/ 4 | 5 | ## TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | ### 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 10 | 11 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 12 | 13 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 14 | 15 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 16 | 17 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 18 | 19 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 20 | 21 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 22 | 23 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 24 | 25 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." 26 | 27 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 28 | 29 | ### 2. Grant of Copyright License. 30 | 31 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 32 | 33 | ### 3. Grant of Patent License. 34 | 35 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 36 | 37 | ### 4. Redistribution. 38 | 39 | You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 40 | 41 | * (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and 42 | 43 | * (b) You must cause any modified files to carry prominent notices stating that You changed the files; and 44 | 45 | * (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 46 | 47 | * (d) If the Work includes a "[NOTICE](NOTICE.md)" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 48 | 49 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 50 | 51 | ### 5. Submission of Contributions. 52 | 53 | Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 54 | 55 | ### 6. Trademarks. 56 | 57 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 58 | 59 | ### 7. Disclaimer of Warranty. 60 | 61 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 62 | 63 | ### 8. Limitation of Liability. 64 | 65 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 66 | 67 | ### 9. Accepting Warranty or Additional Liability. 68 | 69 | While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 70 | 71 | ## END OF TERMS AND CONDITIONS 72 | 73 | ## APPENDIX: How to apply the Apache License to your work. 74 | 75 | To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. 76 | 77 | ``` 78 | Copyright [yyyy] [name of copyright owner] 79 | 80 | Licensed under the Apache License, Version 2.0 (the "License"); 81 | you may not use this file except in compliance with the License. 82 | You may obtain a copy of the License at 83 | 84 | http://www.apache.org/licenses/LICENSE-2.0 85 | 86 | Unless required by applicable law or agreed to in writing, software 87 | distributed under the License is distributed on an "AS IS" BASIS, 88 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 89 | See the License for the specific language governing permissions and 90 | limitations under the License. 91 | ``` 92 | -------------------------------------------------------------------------------- /NOTICE.md: -------------------------------------------------------------------------------- 1 | This product includes software developed at 2 | The Pkcs11Interop Project (http://www.pkcs11interop.net). 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PKCS11-LOGGER 2 | ============= 3 | **PKCS#11 logging proxy module** 4 | 5 | [![Windows](https://github.com/Pkcs11Interop/pkcs11-logger/actions/workflows/windows.yml/badge.svg?branch=master)](https://github.com/Pkcs11Interop/pkcs11-logger/actions/workflows/windows.yml) 6 | [![Linux](https://github.com/Pkcs11Interop/pkcs11-logger/actions/workflows/linux.yml/badge.svg?branch=master)](https://github.com/Pkcs11Interop/pkcs11-logger/actions/workflows/linux.yml) 7 | [![macOS](https://github.com/Pkcs11Interop/pkcs11-logger/actions/workflows/macos.yml/badge.svg?branch=master)](https://github.com/Pkcs11Interop/pkcs11-logger/actions/workflows/macos.yml) 8 | 9 | ## Table of Contents 10 | 11 | * [Overview](#overview) 12 | * [Output example](#output-example) 13 | * [Configuration](#configuration) 14 | * [Download](#download) 15 | * [Building the source](#building-the-source) 16 | * [Windows](#windows) 17 | * [Linux](#linux) 18 | * [macOS](#macos) 19 | * [License](#license) 20 | * [About](#about) 21 | 22 | ## Overview 23 | 24 | PKCS11-LOGGER (hereafter referred to as logger) is a minimalistic C library that implements the [PKCS#11 v2.20](https://github.com/Pkcs11Interop/PKCS11-SPECS/tree/master/v2.20) API. 25 | 26 | PKCS#11 is a cryptographic standard that defines an ANSI C API for accessing smart cards and other types of cryptographic hardware. 27 | 28 | Library implementing the PKCS#11 interface is typically used in the following scenario: 29 | 30 | ```mermaid 31 | flowchart TB 32 | A[Application] --> B[PKCS#11 library] --> C[Device] 33 | ``` 34 | 35 | Due to the complexity of the PKCS#11 API, users often need to troubleshoot communication issues between the application and the PKCS#11 library. This is where the logger becomes useful. 36 | 37 | The logger acts as an intermediary between the application and the original PKCS#11 library: 38 | 39 | ```mermaid 40 | flowchart TB 41 | A[Application] --> B[PKCS11-LOGGER library] --> C[PKCS#11 library] --> D[Device] 42 | ``` 43 | 44 | When an application calls PKCS#11 function provided by the logger, the logger forwards the call to the original PKCS#11 library while logging the interaction. It then returns the result to the application. 45 | 46 | ## Output example 47 | 48 | By default, each logged line starts with two hexadecimal numbers separated by a colon. The first number represents the process ID, and the second represents the thread ID. The following example shows a call to the `C_OpenSession` function: 49 | 50 | ``` 51 | 0x0000956c : 0x0000000000006838 : 2025-02-12 06:28:22.171000 - Entered C_OpenSession 52 | 0x0000956c : 0x0000000000006838 : Input 53 | 0x0000956c : 0x0000000000006838 : slotID: 1 54 | 0x0000956c : 0x0000000000006838 : flags: 6 55 | 0x0000956c : 0x0000000000006838 : CKF_RW_SESSION: TRUE 56 | 0x0000956c : 0x0000000000006838 : CKF_SERIAL_SESSION: TRUE 57 | 0x0000956c : 0x0000000000006838 : pApplication: 0000000000000000 58 | 0x0000956c : 0x0000000000006838 : Notify: 0000000000000000 59 | 0x0000956c : 0x0000000000006838 : phSession: 000000782AFFF110 60 | 0x0000956c : 0x0000000000006838 : *phSession: 721416464 61 | 0x0000956c : 0x0000000000006838 : 2025-02-12 06:28:22.171000 - Calling C_OpenSession 62 | 0x0000956c : 0x0000000000006838 : 2025-02-12 06:28:22.171000 - Received response from C_OpenSession 63 | 0x0000956c : 0x0000000000006838 : Output 64 | 0x0000956c : 0x0000000000006838 : phSession: 000000782AFFF110 65 | 0x0000956c : 0x0000000000006838 : *phSession: 1 66 | 0x0000956c : 0x0000000000006838 : 2025-02-12 06:28:22.171000 - Returning 0 (CKR_OK) 67 | ``` 68 | 69 | ## Configuration 70 | 71 | The logger's behavior can be controlled using the following [environment variables](https://en.wikipedia.org/wiki/Environment_variable): 72 | 73 | * **`PKCS11_LOGGER_LIBRARY_PATH`** 74 | 75 | Specifies the path to the original PKCS#11 library. The value must be provided without enclosing quotes. If this variable is not defined, all logger functions return `CKR_GENERAL_ERROR` and print an error message to `STDERR`. 76 | 77 | * **`PKCS11_LOGGER_LOG_FILE_PATH`** 78 | 79 | Specifies the path to the log file. The value must be provided without enclosing quotes. 80 | 81 | * **`PKCS11_LOGGER_FLAGS`** 82 | 83 | Specifies a [bitmask](https://en.wikipedia.org/wiki/Mask_(computing)) that controls multiple logger features. The meaning of individual bits is as follows: 84 | 85 | * `0x01` hex or `1` dec disables logging to the log file 86 | * `0x02` hex or `2` dec disables logging of the process ID 87 | * `0x04` hex or `4` dec disables logging of the thread ID 88 | * `0x08` hex or `8` dec enables logging of PINs 89 | * `0x10` hex or `16` dec enables logging to `STDOUT` 90 | * `0x20` hex or `32` dec enables logging to `STDERR` 91 | * `0x40` hex or `64` dec enables reopening of the log file (reduces performance but allows log file deletion) 92 | 93 | The value must be provided as a decimal number representing the sum of the desired features. For example, a value of `6` disables logging of both the process ID and thread ID. The default value is `0`. 94 | 95 | ## Download 96 | 97 | Signed precompiled binaries as well as source code releases can be downloaded from [releases page](https://github.com/Pkcs11Interop/pkcs11-logger/releases). 98 | Archives with source code are signed with [GnuPG key of Jaroslav Imrich](https://www.jimrich.sk/crypto/). 99 | Windows libraries are signed with [code-signing certificate of Jaroslav Imrich](https://www.jimrich.sk/crypto/). 100 | 101 | ## Building the source 102 | 103 | ### Windows 104 | 105 | Execute the build script on a 64-bit Windows machine with [Visual Studio 2022](https://visualstudio.microsoft.com/vs/) (or newer) installed: 106 | 107 | ``` 108 | cd build/windows/ 109 | build.bat 110 | ``` 111 | 112 | The script should use Visual Studio to build both 32-bit (`pkcs11-logger-x86.dll`) and 64-bit (`pkcs11-logger-x64.dll`) versions of the library. 113 | 114 | ### Linux 115 | 116 | Execute the build script on a 64-bit Linux machine with GCC, GNU Make and GCC multilib support installed (available in [build-essential](https://packages.ubuntu.com/noble/build-essential) and [gcc-multilib](https://packages.ubuntu.com/noble/gcc-multilib) packages on Ubuntu 24.04 LTS): 117 | 118 | ``` 119 | cd build/linux/ 120 | sh build.sh 121 | ``` 122 | 123 | The script should use GCC to build both 32-bit (`pkcs11-logger-x86.so`) and 64-bit (`pkcs11-logger-x64.so`) versions of the library. 124 | 125 | ### macOS 126 | 127 | Execute the build script on a 64-bit macOS machine with [Xcode](https://developer.apple.com/xcode/) and its "Command Line Tools" extension installed: 128 | 129 | ``` 130 | cd build/macos/ 131 | sh build.sh 132 | ``` 133 | 134 | The script should use Clang to build Mach-O universal binary (`pkcs11-logger.dylib`) usable on both Apple silicon and Intel-based Mac computers. 135 | 136 | ## License 137 | 138 | PKCS11-LOGGER is available under the terms of the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). 139 | [Human friendly license summary](https://www.tldrlegal.com/license/apache-license-2-0-apache-2-0) is available at tldrlegal.com but the [full license text](LICENSE.md) always prevails. 140 | 141 | ## About 142 | 143 | PKCS11-LOGGER has been written for the [Pkcs11Interop](https://www.pkcs11interop.net/) project by [Jaroslav Imrich](https://www.jimrich.sk/). 144 | Please visit project website - [pkcs11interop.net](https://www.pkcs11interop.net) - for more information. 145 | -------------------------------------------------------------------------------- /build/linux/Makefile: -------------------------------------------------------------------------------- 1 | # Display exported symbols: 2 | # nm -D pkcs11-logger.so | grep ' T ' 3 | 4 | SRC_DIR=../../src 5 | 6 | CC= gcc 7 | ARCH_FLAGS= -m32 8 | CFLAGS= $(ARCH_FLAGS) -Wall -Wextra -Werror -O2 -I$(SRC_DIR) 9 | LIBNAME=pkcs11-logger-x86.so 10 | 11 | all: dl.o init.o lock.o log.o pkcs11-logger.o translate.o utils.o 12 | $(CC) $(ARCH_FLAGS) -shared -o $(LIBNAME) \ 13 | -Wl,-soname,$(LIBNAME) \ 14 | -Wl,--version-script,pkcs11-logger.version \ 15 | dl.o init.o lock.o log.o pkcs11-logger.o translate.o utils.o \ 16 | -lc -ldl -lpthread 17 | strip --strip-all $(LIBNAME) 18 | 19 | dl.o: $(SRC_DIR)/dl.c $(SRC_DIR)/*.h 20 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/dl.c 21 | 22 | init.o: $(SRC_DIR)/init.c $(SRC_DIR)/*.h 23 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/init.c 24 | 25 | lock.o: $(SRC_DIR)/lock.c $(SRC_DIR)/*.h 26 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/lock.c 27 | 28 | log.o: $(SRC_DIR)/log.c $(SRC_DIR)/*.h 29 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/log.c 30 | 31 | pkcs11-logger.o: $(SRC_DIR)/pkcs11-logger.c $(SRC_DIR)/*.h 32 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/pkcs11-logger.c 33 | 34 | translate.o: $(SRC_DIR)/translate.c $(SRC_DIR)/*.h 35 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/translate.c 36 | 37 | utils.o: $(SRC_DIR)/utils.c $(SRC_DIR)/*.h 38 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/utils.c 39 | 40 | clean: 41 | -rm -f *.o 42 | 43 | distclean: clean 44 | -rm -f *.so 45 | -------------------------------------------------------------------------------- /build/linux/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | make distclean 6 | 7 | cat Makefile | sed 's/^ARCH_FLAGS=.*/ARCH_FLAGS= -m32/' | sed 's/^LIBNAME=.*/LIBNAME=pkcs11-logger-x86.so/' > Makefile.x86 8 | make -f Makefile.x86 9 | rm Makefile.x86 10 | make clean 11 | 12 | cat Makefile | sed 's/^ARCH_FLAGS=.*/ARCH_FLAGS= -m64/' | sed 's/^LIBNAME=.*/LIBNAME=pkcs11-logger-x64.so/' > Makefile.x64 13 | make -f Makefile.x64 14 | rm Makefile.x64 15 | make clean 16 | 17 | -------------------------------------------------------------------------------- /build/linux/pkcs11-logger.version: -------------------------------------------------------------------------------- 1 | PKCS11LOGGER { 2 | global: 3 | C_*; 4 | local: 5 | *; 6 | }; 7 | 8 | -------------------------------------------------------------------------------- /build/macos/Makefile: -------------------------------------------------------------------------------- 1 | # Display exported symbols: 2 | # nm pkcs11-logger.dylib | grep ' T ' 3 | 4 | SRC_DIR=../../src 5 | 6 | CC= clang 7 | ARCH_FLAGS= -target arm64-apple-macos11 8 | CFLAGS= $(ARCH_FLAGS) -Wall -Wextra -Werror -O2 -I$(SRC_DIR) 9 | LIBNAME=pkcs11-logger-arm64.dylib 10 | 11 | all: dl.o init.o lock.o log.o pkcs11-logger.o translate.o utils.o 12 | $(CC) $(ARCH_FLAGS) -dynamiclib -o $(LIBNAME) \ 13 | -Wl,-exported_symbols_list,pkcs11-logger.symbols \ 14 | dl.o init.o lock.o log.o pkcs11-logger.o translate.o utils.o \ 15 | -lc -ldl -lpthread 16 | strip -x $(LIBNAME) 17 | 18 | dl.o: $(SRC_DIR)/dl.c $(SRC_DIR)/*.h 19 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/dl.c 20 | 21 | init.o: $(SRC_DIR)/init.c $(SRC_DIR)/*.h 22 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/init.c 23 | 24 | lock.o: $(SRC_DIR)/lock.c $(SRC_DIR)/*.h 25 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/lock.c 26 | 27 | log.o: $(SRC_DIR)/log.c $(SRC_DIR)/*.h 28 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/log.c 29 | 30 | pkcs11-logger.o: $(SRC_DIR)/pkcs11-logger.c $(SRC_DIR)/*.h 31 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/pkcs11-logger.c 32 | 33 | translate.o: $(SRC_DIR)/translate.c $(SRC_DIR)/*.h 34 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/translate.c 35 | 36 | utils.o: $(SRC_DIR)/utils.c $(SRC_DIR)/*.h 37 | $(CC) $(CFLAGS) -fPIC -c $(SRC_DIR)/utils.c 38 | 39 | clean: 40 | -rm -f *.o 41 | 42 | distclean: clean 43 | -rm -f *.dylib 44 | -------------------------------------------------------------------------------- /build/macos/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | make distclean 6 | 7 | cat Makefile | sed 's/^ARCH_FLAGS=.*/ARCH_FLAGS= -target arm64-apple-macos11/' | sed 's/^LIBNAME=.*/LIBNAME=pkcs11-logger-arm64.dylib/' > Makefile.arm64 8 | make -f Makefile.arm64 9 | rm Makefile.arm64 10 | make clean 11 | 12 | cat Makefile | sed 's/^ARCH_FLAGS=.*/ARCH_FLAGS= -target x86_64-apple-macos10.12/' | sed 's/^LIBNAME=.*/LIBNAME=pkcs11-logger-x86_64.dylib/' > Makefile.x86_64 13 | make -f Makefile.x86_64 14 | rm Makefile.x86_64 15 | make clean 16 | 17 | lipo -create -output pkcs11-logger.dylib pkcs11-logger-arm64.dylib pkcs11-logger-x86_64.dylib 18 | rm pkcs11-logger-arm64.dylib pkcs11-logger-x86_64.dylib 19 | -------------------------------------------------------------------------------- /build/macos/pkcs11-logger.symbols: -------------------------------------------------------------------------------- 1 | _C_* 2 | -------------------------------------------------------------------------------- /build/windows/build.bat: -------------------------------------------------------------------------------- 1 | @rem Initialize build environment of Visual Studio 2022 Community/Professional/Enterprise 2 | @set tools= 3 | @set tmptools="c:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" 4 | @if exist %tmptools% set tools=%tmptools% 5 | @set tmptools="c:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\Build\vcvarsall.bat" 6 | @if exist %tmptools% set tools=%tmptools% 7 | @set tmptools="c:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" 8 | @if exist %tmptools% set tools=%tmptools% 9 | @if not defined tools goto :error 10 | 11 | @rem Build for x86 platform 12 | @setlocal 13 | @echo on 14 | call %tools% x86 15 | @echo on 16 | msbuild pkcs11-logger.sln /p:Configuration=Release /p:Platform=Win32 /target:Clean || goto :error 17 | msbuild pkcs11-logger.sln /p:Configuration=Release /p:Platform=Win32 /target:Build || goto :error 18 | copy .\Win32\Release\pkcs11-logger-x86.dll . || goto :error 19 | @endlocal 20 | 21 | @rem Build for x64 platform 22 | @setlocal 23 | @echo on 24 | call %tools% x64 25 | @echo on 26 | msbuild pkcs11-logger.sln /p:Configuration=Release /p:Platform=x64 /target:Clean || goto :error 27 | msbuild pkcs11-logger.sln /p:Configuration=Release /p:Platform=x64 /target:Build || goto :error 28 | copy .\x64\Release\pkcs11-logger-x64.dll . || goto :error 29 | @endlocal 30 | 31 | @echo *** BUILD SUCCESSFUL *** 32 | @exit /b %errorlevel% 33 | 34 | :error 35 | @echo *** BUILD FAILED *** 36 | @endlocal 37 | @exit /b %errorlevel% 38 | -------------------------------------------------------------------------------- /build/windows/pkcs11-logger.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pkcs11-logger", "pkcs11-logger\pkcs11-logger.vcxproj", "{078A7AAC-5D04-4270-868C-3585816EC8AD}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Debug|x64 = Debug|x64 12 | Release|Win32 = Release|Win32 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {078A7AAC-5D04-4270-868C-3585816EC8AD}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {078A7AAC-5D04-4270-868C-3585816EC8AD}.Debug|Win32.Build.0 = Debug|Win32 18 | {078A7AAC-5D04-4270-868C-3585816EC8AD}.Debug|x64.ActiveCfg = Debug|x64 19 | {078A7AAC-5D04-4270-868C-3585816EC8AD}.Debug|x64.Build.0 = Debug|x64 20 | {078A7AAC-5D04-4270-868C-3585816EC8AD}.Release|Win32.ActiveCfg = Release|Win32 21 | {078A7AAC-5D04-4270-868C-3585816EC8AD}.Release|Win32.Build.0 = Release|Win32 22 | {078A7AAC-5D04-4270-868C-3585816EC8AD}.Release|x64.ActiveCfg = Release|x64 23 | {078A7AAC-5D04-4270-868C-3585816EC8AD}.Release|x64.Build.0 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /build/windows/pkcs11-logger/pkcs11-logger.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | {078A7AAC-5D04-4270-868C-3585816EC8AD} 35 | Win32Proj 36 | pkcs11logger 37 | 38 | 39 | 40 | DynamicLibrary 41 | true 42 | v143 43 | Unicode 44 | 45 | 46 | DynamicLibrary 47 | true 48 | v143 49 | Unicode 50 | 51 | 52 | DynamicLibrary 53 | false 54 | v143 55 | true 56 | Unicode 57 | 58 | 59 | DynamicLibrary 60 | false 61 | v143 62 | true 63 | Unicode 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | true 83 | $(ProjectName)-x86 84 | $(SolutionDir)$(Platform)\$(Configuration)\ 85 | $(Platform)\$(Configuration)\ 86 | 87 | 88 | true 89 | $(ProjectName)-x64 90 | 91 | 92 | false 93 | $(ProjectName)-x86 94 | $(SolutionDir)$(Platform)\$(Configuration)\ 95 | $(Platform)\$(Configuration)\ 96 | 97 | 98 | false 99 | $(ProjectName)-x64 100 | 101 | 102 | 103 | NotUsing 104 | Level4 105 | Disabled 106 | WIN32;_DEBUG;_WINDOWS;_USRDLL;CRYPTOKI_EXPORTS;%(PreprocessorDefinitions) 107 | ..\..\..\src 108 | 109 | 110 | Windows 111 | true 112 | 113 | 114 | 115 | 116 | 117 | 118 | NotUsing 119 | Level4 120 | Disabled 121 | WIN32;_DEBUG;_WINDOWS;_USRDLL;CRYPTOKI_EXPORTS;%(PreprocessorDefinitions) 122 | ..\..\..\src 123 | 124 | 125 | Windows 126 | true 127 | 128 | 129 | 130 | 131 | 132 | 133 | Level4 134 | NotUsing 135 | MaxSpeed 136 | true 137 | true 138 | WIN32;NDEBUG;_WINDOWS;_USRDLL;CRYPTOKI_EXPORTS;%(PreprocessorDefinitions) 139 | ..\..\..\src 140 | 141 | 142 | Windows 143 | true 144 | true 145 | true 146 | 147 | 148 | 149 | 150 | 151 | 152 | Level4 153 | NotUsing 154 | MaxSpeed 155 | true 156 | true 157 | WIN32;NDEBUG;_WINDOWS;_USRDLL;CRYPTOKI_EXPORTS;%(PreprocessorDefinitions) 158 | ..\..\..\src 159 | 160 | 161 | Windows 162 | true 163 | true 164 | true 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /build/windows/pkcs11-logger/pkcs11-logger.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | 41 | 42 | Header Files 43 | 44 | 45 | -------------------------------------------------------------------------------- /build/windows/sign.bat: -------------------------------------------------------------------------------- 1 | @setlocal 2 | 3 | @rem Define paths to necessary tools 4 | set SIGNTOOL="C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" 5 | 6 | @rem Define signing options 7 | set CERTHASH=7e26cd682dc453927843a514f2110977a0e4709f 8 | set TSAURL=http://time.certum.pl/ 9 | set LIBNAME=PKCS11-LOGGER 10 | set LIBURL=https://www.pkcs11interop.net/ 11 | 12 | @rem Sign all assemblies using SHA256withRSA algorithm 13 | %SIGNTOOL% sign /sha1 %CERTHASH% /fd sha256 /tr %TSAURL% /td sha256 /d %LIBNAME% /du %LIBURL% ^ 14 | pkcs11-logger-x86.dll ^ 15 | pkcs11-logger-x64.dll || goto :error 16 | 17 | @echo *** SIGN SUCCESSFUL *** 18 | @endlocal 19 | @exit /b 0 20 | 21 | :error 22 | @echo *** SIGN FAILED *** 23 | @endlocal 24 | @exit /b 1 25 | -------------------------------------------------------------------------------- /src/cryptoki/pkcs11.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PKCS #11 Specification Version 3.1 3 | * OASIS Standard 4 | * 23 July 2023 5 | * Copyright (c) OASIS Open 2023. All Rights Reserved. 6 | * Source: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/os/include/pkcs11-v3.1/ 7 | * Latest stage of narrative specification: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/pkcs11-spec-v3.1.html 8 | * TC IPR Statement: https://www.oasis-open.org/committees/pkcs11/ipr.php 9 | */ 10 | 11 | #ifndef _PKCS11_H_ 12 | #define _PKCS11_H_ 1 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /* Before including this file (pkcs11.h) (or pkcs11t.h by 19 | * itself), 5 platform-specific macros must be defined. These 20 | * macros are described below, and typical definitions for them 21 | * are also given. Be advised that these definitions can depend 22 | * on both the platform and the compiler used (and possibly also 23 | * on whether a Cryptoki library is linked statically or 24 | * dynamically). 25 | * 26 | * In addition to defining these 5 macros, the packing convention 27 | * for Cryptoki structures should be set. The Cryptoki 28 | * convention on packing is that structures should be 1-byte 29 | * aligned. 30 | * 31 | * If you're using Windows this might be done by using the following 32 | * preprocessor directive before including pkcs11.h or pkcs11t.h: 33 | * 34 | * #pragma pack(push, cryptoki, 1) 35 | * 36 | * and using the following preprocessor directive after including 37 | * pkcs11.h or pkcs11t.h: 38 | * 39 | * #pragma pack(pop, cryptoki) 40 | * 41 | * In a UNIX environment, you're on your own for this. You might 42 | * not need to do (or be able to do!) anything. 43 | * 44 | * 45 | * Now for the macros: 46 | * 47 | * 48 | * 1. CK_PTR: The indirection string for making a pointer to an 49 | * object. It can be used like this: 50 | * 51 | * typedef CK_BYTE CK_PTR CK_BYTE_PTR; 52 | * 53 | * If you're using Windows, it might be defined by: 54 | * 55 | * #define CK_PTR * 56 | * 57 | * In a typical UNIX environment, it might be defined by: 58 | * 59 | * #define CK_PTR * 60 | * 61 | * 62 | * 2. CK_DECLARE_FUNCTION(returnType, name): A macro which makes 63 | * an importable Cryptoki library function declaration out of a 64 | * return type and a function name. It should be used in the 65 | * following fashion: 66 | * 67 | * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)( 68 | * CK_VOID_PTR pReserved 69 | * ); 70 | * 71 | * If you're using Windows to declare a function in a Win32 Cryptoki .dll, 72 | * it might be defined by: 73 | * 74 | * #define CK_DECLARE_FUNCTION(returnType, name) \ 75 | * returnType __declspec(dllimport) name 76 | * 77 | * In a UNIX environment, it might be defined by: 78 | * 79 | * #define CK_DECLARE_FUNCTION(returnType, name) \ 80 | * returnType name 81 | * 82 | * 83 | * 3. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro 84 | * which makes a Cryptoki API function pointer declaration or 85 | * function pointer type declaration out of a return type and a 86 | * function name. It should be used in the following fashion: 87 | * 88 | * // Define funcPtr to be a pointer to a Cryptoki API function 89 | * // taking arguments args and returning CK_RV. 90 | * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args); 91 | * 92 | * or 93 | * 94 | * // Define funcPtrType to be the type of a pointer to a 95 | * // Cryptoki API function taking arguments args and returning 96 | * // CK_RV, and then define funcPtr to be a variable of type 97 | * // funcPtrType. 98 | * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args); 99 | * funcPtrType funcPtr; 100 | * 101 | * If you're using Windows to access 102 | * functions in a Win32 Cryptoki .dll, in might be defined by: 103 | * 104 | * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ 105 | * returnType __declspec(dllimport) (* name) 106 | * 107 | * In a UNIX environment, it might be defined by: 108 | * 109 | * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ 110 | * returnType (* name) 111 | * 112 | * 113 | * 4. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes 114 | * a function pointer type for an application callback out of 115 | * a return type for the callback and a name for the callback. 116 | * It should be used in the following fashion: 117 | * 118 | * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args); 119 | * 120 | * to declare a function pointer, myCallback, to a callback 121 | * which takes arguments args and returns a CK_RV. It can also 122 | * be used like this: 123 | * 124 | * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args); 125 | * myCallbackType myCallback; 126 | * 127 | * If you're using Windows, it might be defined by: 128 | * 129 | * #define CK_CALLBACK_FUNCTION(returnType, name) \ 130 | * returnType (* name) 131 | * 132 | * In a UNIX environment, it might be defined by: 133 | * 134 | * #define CK_CALLBACK_FUNCTION(returnType, name) \ 135 | * returnType (* name) 136 | * 137 | * 138 | * 5. NULL_PTR: This macro is the value of a NULL pointer. 139 | * 140 | * In any ANSI/ISO C environment (and in many others as well), 141 | * this should best be defined by 142 | * 143 | * #ifndef NULL_PTR 144 | * #define NULL_PTR 0 145 | * #endif 146 | */ 147 | 148 | 149 | /* All the various Cryptoki types and #define'd values are in the 150 | * file pkcs11t.h. 151 | */ 152 | #include "pkcs11t.h" 153 | 154 | #define __PASTE(x,y) x##y 155 | 156 | 157 | /* ============================================================== 158 | * Define the "extern" form of all the entry points. 159 | * ============================================================== 160 | */ 161 | 162 | #define CK_NEED_ARG_LIST 1 163 | #define CK_PKCS11_FUNCTION_INFO(name) \ 164 | extern CK_DECLARE_FUNCTION(CK_RV, name) 165 | 166 | /* pkcs11f.h has all the information about the Cryptoki 167 | * function prototypes. 168 | */ 169 | #include "pkcs11f.h" 170 | 171 | #undef CK_NEED_ARG_LIST 172 | #undef CK_PKCS11_FUNCTION_INFO 173 | 174 | 175 | /* ============================================================== 176 | * Define the typedef form of all the entry points. That is, for 177 | * each Cryptoki function C_XXX, define a type CK_C_XXX which is 178 | * a pointer to that kind of function. 179 | * ============================================================== 180 | */ 181 | 182 | #define CK_NEED_ARG_LIST 1 183 | #define CK_PKCS11_FUNCTION_INFO(name) \ 184 | typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name)) 185 | 186 | /* pkcs11f.h has all the information about the Cryptoki 187 | * function prototypes. 188 | */ 189 | #include "pkcs11f.h" 190 | 191 | #undef CK_NEED_ARG_LIST 192 | #undef CK_PKCS11_FUNCTION_INFO 193 | 194 | 195 | /* ============================================================== 196 | * Define structed vector of entry points. A CK_FUNCTION_LIST 197 | * contains a CK_VERSION indicating a library's Cryptoki version 198 | * and then a whole slew of function pointers to the routines in 199 | * the library. This type was declared, but not defined, in 200 | * pkcs11t.h. 201 | * ============================================================== 202 | */ 203 | 204 | #define CK_PKCS11_FUNCTION_INFO(name) \ 205 | __PASTE(CK_,name) name; 206 | 207 | /* Create the 3.0 Function list */ 208 | struct CK_FUNCTION_LIST_3_0 { 209 | 210 | CK_VERSION version; /* Cryptoki version */ 211 | 212 | /* Pile all the function pointers into the CK_FUNCTION_LIST. */ 213 | /* pkcs11f.h has all the information about the Cryptoki 214 | * function prototypes. 215 | */ 216 | #include "pkcs11f.h" 217 | 218 | }; 219 | 220 | #define CK_PKCS11_2_0_ONLY 1 221 | 222 | /* Continue to define the old CK_FUNCTION_LIST */ 223 | struct CK_FUNCTION_LIST { 224 | 225 | CK_VERSION version; /* Cryptoki version */ 226 | 227 | /* Pile all the function pointers into the CK_FUNCTION_LIST. */ 228 | /* pkcs11f.h has all the information about the Cryptoki 229 | * function prototypes. 230 | */ 231 | #include "pkcs11f.h" 232 | 233 | }; 234 | 235 | #undef CK_PKCS11_FUNCTION_INFO 236 | #undef CK_PKCS11_2_0_ONLY 237 | 238 | 239 | #undef __PASTE 240 | 241 | #ifdef __cplusplus 242 | } 243 | #endif 244 | 245 | #endif /* _PKCS11_H_ */ 246 | 247 | -------------------------------------------------------------------------------- /src/cryptoki/pkcs11f.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PKCS #11 Specification Version 3.1 3 | * OASIS Standard 4 | * 23 July 2023 5 | * Copyright (c) OASIS Open 2023. All Rights Reserved. 6 | * Source: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/os/include/pkcs11-v3.1/ 7 | * Latest stage of narrative specification: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/pkcs11-spec-v3.1.html 8 | * TC IPR Statement: https://www.oasis-open.org/committees/pkcs11/ipr.php 9 | */ 10 | 11 | /* This header file contains pretty much everything about all the 12 | * Cryptoki function prototypes. Because this information is 13 | * used for more than just declaring function prototypes, the 14 | * order of the functions appearing herein is important, and 15 | * should not be altered. 16 | */ 17 | 18 | /* General-purpose */ 19 | 20 | /* C_Initialize initializes the Cryptoki library. */ 21 | CK_PKCS11_FUNCTION_INFO(C_Initialize) 22 | #ifdef CK_NEED_ARG_LIST 23 | ( 24 | CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets 25 | * cast to CK_C_INITIALIZE_ARGS_PTR 26 | * and dereferenced 27 | */ 28 | ); 29 | #endif 30 | 31 | 32 | /* C_Finalize indicates that an application is done with the 33 | * Cryptoki library. 34 | */ 35 | CK_PKCS11_FUNCTION_INFO(C_Finalize) 36 | #ifdef CK_NEED_ARG_LIST 37 | ( 38 | CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ 39 | ); 40 | #endif 41 | 42 | 43 | /* C_GetInfo returns general information about Cryptoki. */ 44 | CK_PKCS11_FUNCTION_INFO(C_GetInfo) 45 | #ifdef CK_NEED_ARG_LIST 46 | ( 47 | CK_INFO_PTR pInfo /* location that receives information */ 48 | ); 49 | #endif 50 | 51 | 52 | /* C_GetFunctionList returns the function list. */ 53 | CK_PKCS11_FUNCTION_INFO(C_GetFunctionList) 54 | #ifdef CK_NEED_ARG_LIST 55 | ( 56 | CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to 57 | * function list 58 | */ 59 | ); 60 | #endif 61 | 62 | 63 | 64 | /* Slot and token management */ 65 | 66 | /* C_GetSlotList obtains a list of slots in the system. */ 67 | CK_PKCS11_FUNCTION_INFO(C_GetSlotList) 68 | #ifdef CK_NEED_ARG_LIST 69 | ( 70 | CK_BBOOL tokenPresent, /* only slots with tokens */ 71 | CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */ 72 | CK_ULONG_PTR pulCount /* receives number of slots */ 73 | ); 74 | #endif 75 | 76 | 77 | /* C_GetSlotInfo obtains information about a particular slot in 78 | * the system. 79 | */ 80 | CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo) 81 | #ifdef CK_NEED_ARG_LIST 82 | ( 83 | CK_SLOT_ID slotID, /* the ID of the slot */ 84 | CK_SLOT_INFO_PTR pInfo /* receives the slot information */ 85 | ); 86 | #endif 87 | 88 | 89 | /* C_GetTokenInfo obtains information about a particular token 90 | * in the system. 91 | */ 92 | CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo) 93 | #ifdef CK_NEED_ARG_LIST 94 | ( 95 | CK_SLOT_ID slotID, /* ID of the token's slot */ 96 | CK_TOKEN_INFO_PTR pInfo /* receives the token information */ 97 | ); 98 | #endif 99 | 100 | 101 | /* C_GetMechanismList obtains a list of mechanism types 102 | * supported by a token. 103 | */ 104 | CK_PKCS11_FUNCTION_INFO(C_GetMechanismList) 105 | #ifdef CK_NEED_ARG_LIST 106 | ( 107 | CK_SLOT_ID slotID, /* ID of token's slot */ 108 | CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */ 109 | CK_ULONG_PTR pulCount /* gets # of mechs. */ 110 | ); 111 | #endif 112 | 113 | 114 | /* C_GetMechanismInfo obtains information about a particular 115 | * mechanism possibly supported by a token. 116 | */ 117 | CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo) 118 | #ifdef CK_NEED_ARG_LIST 119 | ( 120 | CK_SLOT_ID slotID, /* ID of the token's slot */ 121 | CK_MECHANISM_TYPE type, /* type of mechanism */ 122 | CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */ 123 | ); 124 | #endif 125 | 126 | 127 | /* C_InitToken initializes a token. */ 128 | CK_PKCS11_FUNCTION_INFO(C_InitToken) 129 | #ifdef CK_NEED_ARG_LIST 130 | ( 131 | CK_SLOT_ID slotID, /* ID of the token's slot */ 132 | CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */ 133 | CK_ULONG ulPinLen, /* length in bytes of the PIN */ 134 | CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */ 135 | ); 136 | #endif 137 | 138 | 139 | /* C_InitPIN initializes the normal user's PIN. */ 140 | CK_PKCS11_FUNCTION_INFO(C_InitPIN) 141 | #ifdef CK_NEED_ARG_LIST 142 | ( 143 | CK_SESSION_HANDLE hSession, /* the session's handle */ 144 | CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */ 145 | CK_ULONG ulPinLen /* length in bytes of the PIN */ 146 | ); 147 | #endif 148 | 149 | 150 | /* C_SetPIN modifies the PIN of the user who is logged in. */ 151 | CK_PKCS11_FUNCTION_INFO(C_SetPIN) 152 | #ifdef CK_NEED_ARG_LIST 153 | ( 154 | CK_SESSION_HANDLE hSession, /* the session's handle */ 155 | CK_UTF8CHAR_PTR pOldPin, /* the old PIN */ 156 | CK_ULONG ulOldLen, /* length of the old PIN */ 157 | CK_UTF8CHAR_PTR pNewPin, /* the new PIN */ 158 | CK_ULONG ulNewLen /* length of the new PIN */ 159 | ); 160 | #endif 161 | 162 | 163 | 164 | /* Session management */ 165 | 166 | /* C_OpenSession opens a session between an application and a 167 | * token. 168 | */ 169 | CK_PKCS11_FUNCTION_INFO(C_OpenSession) 170 | #ifdef CK_NEED_ARG_LIST 171 | ( 172 | CK_SLOT_ID slotID, /* the slot's ID */ 173 | CK_FLAGS flags, /* from CK_SESSION_INFO */ 174 | CK_VOID_PTR pApplication, /* passed to callback */ 175 | CK_NOTIFY Notify, /* callback function */ 176 | CK_SESSION_HANDLE_PTR phSession /* gets session handle */ 177 | ); 178 | #endif 179 | 180 | 181 | /* C_CloseSession closes a session between an application and a 182 | * token. 183 | */ 184 | CK_PKCS11_FUNCTION_INFO(C_CloseSession) 185 | #ifdef CK_NEED_ARG_LIST 186 | ( 187 | CK_SESSION_HANDLE hSession /* the session's handle */ 188 | ); 189 | #endif 190 | 191 | 192 | /* C_CloseAllSessions closes all sessions with a token. */ 193 | CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions) 194 | #ifdef CK_NEED_ARG_LIST 195 | ( 196 | CK_SLOT_ID slotID /* the token's slot */ 197 | ); 198 | #endif 199 | 200 | 201 | /* C_GetSessionInfo obtains information about the session. */ 202 | CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo) 203 | #ifdef CK_NEED_ARG_LIST 204 | ( 205 | CK_SESSION_HANDLE hSession, /* the session's handle */ 206 | CK_SESSION_INFO_PTR pInfo /* receives session info */ 207 | ); 208 | #endif 209 | 210 | 211 | /* C_GetOperationState obtains the state of the cryptographic operation 212 | * in a session. 213 | */ 214 | CK_PKCS11_FUNCTION_INFO(C_GetOperationState) 215 | #ifdef CK_NEED_ARG_LIST 216 | ( 217 | CK_SESSION_HANDLE hSession, /* session's handle */ 218 | CK_BYTE_PTR pOperationState, /* gets state */ 219 | CK_ULONG_PTR pulOperationStateLen /* gets state length */ 220 | ); 221 | #endif 222 | 223 | 224 | /* C_SetOperationState restores the state of the cryptographic 225 | * operation in a session. 226 | */ 227 | CK_PKCS11_FUNCTION_INFO(C_SetOperationState) 228 | #ifdef CK_NEED_ARG_LIST 229 | ( 230 | CK_SESSION_HANDLE hSession, /* session's handle */ 231 | CK_BYTE_PTR pOperationState, /* holds state */ 232 | CK_ULONG ulOperationStateLen, /* holds state length */ 233 | CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */ 234 | CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */ 235 | ); 236 | #endif 237 | 238 | 239 | /* C_Login logs a user into a token. */ 240 | CK_PKCS11_FUNCTION_INFO(C_Login) 241 | #ifdef CK_NEED_ARG_LIST 242 | ( 243 | CK_SESSION_HANDLE hSession, /* the session's handle */ 244 | CK_USER_TYPE userType, /* the user type */ 245 | CK_UTF8CHAR_PTR pPin, /* the user's PIN */ 246 | CK_ULONG ulPinLen /* the length of the PIN */ 247 | ); 248 | #endif 249 | 250 | 251 | /* C_Logout logs a user out from a token. */ 252 | CK_PKCS11_FUNCTION_INFO(C_Logout) 253 | #ifdef CK_NEED_ARG_LIST 254 | ( 255 | CK_SESSION_HANDLE hSession /* the session's handle */ 256 | ); 257 | #endif 258 | 259 | 260 | 261 | /* Object management */ 262 | 263 | /* C_CreateObject creates a new object. */ 264 | CK_PKCS11_FUNCTION_INFO(C_CreateObject) 265 | #ifdef CK_NEED_ARG_LIST 266 | ( 267 | CK_SESSION_HANDLE hSession, /* the session's handle */ 268 | CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ 269 | CK_ULONG ulCount, /* attributes in template */ 270 | CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ 271 | ); 272 | #endif 273 | 274 | 275 | /* C_CopyObject copies an object, creating a new object for the 276 | * copy. 277 | */ 278 | CK_PKCS11_FUNCTION_INFO(C_CopyObject) 279 | #ifdef CK_NEED_ARG_LIST 280 | ( 281 | CK_SESSION_HANDLE hSession, /* the session's handle */ 282 | CK_OBJECT_HANDLE hObject, /* the object's handle */ 283 | CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ 284 | CK_ULONG ulCount, /* attributes in template */ 285 | CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ 286 | ); 287 | #endif 288 | 289 | 290 | /* C_DestroyObject destroys an object. */ 291 | CK_PKCS11_FUNCTION_INFO(C_DestroyObject) 292 | #ifdef CK_NEED_ARG_LIST 293 | ( 294 | CK_SESSION_HANDLE hSession, /* the session's handle */ 295 | CK_OBJECT_HANDLE hObject /* the object's handle */ 296 | ); 297 | #endif 298 | 299 | 300 | /* C_GetObjectSize gets the size of an object in bytes. */ 301 | CK_PKCS11_FUNCTION_INFO(C_GetObjectSize) 302 | #ifdef CK_NEED_ARG_LIST 303 | ( 304 | CK_SESSION_HANDLE hSession, /* the session's handle */ 305 | CK_OBJECT_HANDLE hObject, /* the object's handle */ 306 | CK_ULONG_PTR pulSize /* receives size of object */ 307 | ); 308 | #endif 309 | 310 | 311 | /* C_GetAttributeValue obtains the value of one or more object 312 | * attributes. 313 | */ 314 | CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue) 315 | #ifdef CK_NEED_ARG_LIST 316 | ( 317 | CK_SESSION_HANDLE hSession, /* the session's handle */ 318 | CK_OBJECT_HANDLE hObject, /* the object's handle */ 319 | CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */ 320 | CK_ULONG ulCount /* attributes in template */ 321 | ); 322 | #endif 323 | 324 | 325 | /* C_SetAttributeValue modifies the value of one or more object 326 | * attributes. 327 | */ 328 | CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue) 329 | #ifdef CK_NEED_ARG_LIST 330 | ( 331 | CK_SESSION_HANDLE hSession, /* the session's handle */ 332 | CK_OBJECT_HANDLE hObject, /* the object's handle */ 333 | CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */ 334 | CK_ULONG ulCount /* attributes in template */ 335 | ); 336 | #endif 337 | 338 | 339 | /* C_FindObjectsInit initializes a search for token and session 340 | * objects that match a template. 341 | */ 342 | CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit) 343 | #ifdef CK_NEED_ARG_LIST 344 | ( 345 | CK_SESSION_HANDLE hSession, /* the session's handle */ 346 | CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ 347 | CK_ULONG ulCount /* attrs in search template */ 348 | ); 349 | #endif 350 | 351 | 352 | /* C_FindObjects continues a search for token and session 353 | * objects that match a template, obtaining additional object 354 | * handles. 355 | */ 356 | CK_PKCS11_FUNCTION_INFO(C_FindObjects) 357 | #ifdef CK_NEED_ARG_LIST 358 | ( 359 | CK_SESSION_HANDLE hSession, /* session's handle */ 360 | CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */ 361 | CK_ULONG ulMaxObjectCount, /* max handles to get */ 362 | CK_ULONG_PTR pulObjectCount /* actual # returned */ 363 | ); 364 | #endif 365 | 366 | 367 | /* C_FindObjectsFinal finishes a search for token and session 368 | * objects. 369 | */ 370 | CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal) 371 | #ifdef CK_NEED_ARG_LIST 372 | ( 373 | CK_SESSION_HANDLE hSession /* the session's handle */ 374 | ); 375 | #endif 376 | 377 | 378 | 379 | /* Encryption and decryption */ 380 | 381 | /* C_EncryptInit initializes an encryption operation. */ 382 | CK_PKCS11_FUNCTION_INFO(C_EncryptInit) 383 | #ifdef CK_NEED_ARG_LIST 384 | ( 385 | CK_SESSION_HANDLE hSession, /* the session's handle */ 386 | CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ 387 | CK_OBJECT_HANDLE hKey /* handle of encryption key */ 388 | ); 389 | #endif 390 | 391 | 392 | /* C_Encrypt encrypts single-part data. */ 393 | CK_PKCS11_FUNCTION_INFO(C_Encrypt) 394 | #ifdef CK_NEED_ARG_LIST 395 | ( 396 | CK_SESSION_HANDLE hSession, /* session's handle */ 397 | CK_BYTE_PTR pData, /* the plaintext data */ 398 | CK_ULONG ulDataLen, /* bytes of plaintext */ 399 | CK_BYTE_PTR pEncryptedData, /* gets ciphertext */ 400 | CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */ 401 | ); 402 | #endif 403 | 404 | 405 | /* C_EncryptUpdate continues a multiple-part encryption 406 | * operation. 407 | */ 408 | CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate) 409 | #ifdef CK_NEED_ARG_LIST 410 | ( 411 | CK_SESSION_HANDLE hSession, /* session's handle */ 412 | CK_BYTE_PTR pPart, /* the plaintext data */ 413 | CK_ULONG ulPartLen, /* plaintext data len */ 414 | CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ 415 | CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */ 416 | ); 417 | #endif 418 | 419 | 420 | /* C_EncryptFinal finishes a multiple-part encryption 421 | * operation. 422 | */ 423 | CK_PKCS11_FUNCTION_INFO(C_EncryptFinal) 424 | #ifdef CK_NEED_ARG_LIST 425 | ( 426 | CK_SESSION_HANDLE hSession, /* session handle */ 427 | CK_BYTE_PTR pLastEncryptedPart, /* last c-text */ 428 | CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */ 429 | ); 430 | #endif 431 | 432 | 433 | /* C_DecryptInit initializes a decryption operation. */ 434 | CK_PKCS11_FUNCTION_INFO(C_DecryptInit) 435 | #ifdef CK_NEED_ARG_LIST 436 | ( 437 | CK_SESSION_HANDLE hSession, /* the session's handle */ 438 | CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ 439 | CK_OBJECT_HANDLE hKey /* handle of decryption key */ 440 | ); 441 | #endif 442 | 443 | 444 | /* C_Decrypt decrypts encrypted data in a single part. */ 445 | CK_PKCS11_FUNCTION_INFO(C_Decrypt) 446 | #ifdef CK_NEED_ARG_LIST 447 | ( 448 | CK_SESSION_HANDLE hSession, /* session's handle */ 449 | CK_BYTE_PTR pEncryptedData, /* ciphertext */ 450 | CK_ULONG ulEncryptedDataLen, /* ciphertext length */ 451 | CK_BYTE_PTR pData, /* gets plaintext */ 452 | CK_ULONG_PTR pulDataLen /* gets p-text size */ 453 | ); 454 | #endif 455 | 456 | 457 | /* C_DecryptUpdate continues a multiple-part decryption 458 | * operation. 459 | */ 460 | CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate) 461 | #ifdef CK_NEED_ARG_LIST 462 | ( 463 | CK_SESSION_HANDLE hSession, /* session's handle */ 464 | CK_BYTE_PTR pEncryptedPart, /* encrypted data */ 465 | CK_ULONG ulEncryptedPartLen, /* input length */ 466 | CK_BYTE_PTR pPart, /* gets plaintext */ 467 | CK_ULONG_PTR pulPartLen /* p-text size */ 468 | ); 469 | #endif 470 | 471 | 472 | /* C_DecryptFinal finishes a multiple-part decryption 473 | * operation. 474 | */ 475 | CK_PKCS11_FUNCTION_INFO(C_DecryptFinal) 476 | #ifdef CK_NEED_ARG_LIST 477 | ( 478 | CK_SESSION_HANDLE hSession, /* the session's handle */ 479 | CK_BYTE_PTR pLastPart, /* gets plaintext */ 480 | CK_ULONG_PTR pulLastPartLen /* p-text size */ 481 | ); 482 | #endif 483 | 484 | 485 | 486 | /* Message digesting */ 487 | 488 | /* C_DigestInit initializes a message-digesting operation. */ 489 | CK_PKCS11_FUNCTION_INFO(C_DigestInit) 490 | #ifdef CK_NEED_ARG_LIST 491 | ( 492 | CK_SESSION_HANDLE hSession, /* the session's handle */ 493 | CK_MECHANISM_PTR pMechanism /* the digesting mechanism */ 494 | ); 495 | #endif 496 | 497 | 498 | /* C_Digest digests data in a single part. */ 499 | CK_PKCS11_FUNCTION_INFO(C_Digest) 500 | #ifdef CK_NEED_ARG_LIST 501 | ( 502 | CK_SESSION_HANDLE hSession, /* the session's handle */ 503 | CK_BYTE_PTR pData, /* data to be digested */ 504 | CK_ULONG ulDataLen, /* bytes of data to digest */ 505 | CK_BYTE_PTR pDigest, /* gets the message digest */ 506 | CK_ULONG_PTR pulDigestLen /* gets digest length */ 507 | ); 508 | #endif 509 | 510 | 511 | /* C_DigestUpdate continues a multiple-part message-digesting 512 | * operation. 513 | */ 514 | CK_PKCS11_FUNCTION_INFO(C_DigestUpdate) 515 | #ifdef CK_NEED_ARG_LIST 516 | ( 517 | CK_SESSION_HANDLE hSession, /* the session's handle */ 518 | CK_BYTE_PTR pPart, /* data to be digested */ 519 | CK_ULONG ulPartLen /* bytes of data to be digested */ 520 | ); 521 | #endif 522 | 523 | 524 | /* C_DigestKey continues a multi-part message-digesting 525 | * operation, by digesting the value of a secret key as part of 526 | * the data already digested. 527 | */ 528 | CK_PKCS11_FUNCTION_INFO(C_DigestKey) 529 | #ifdef CK_NEED_ARG_LIST 530 | ( 531 | CK_SESSION_HANDLE hSession, /* the session's handle */ 532 | CK_OBJECT_HANDLE hKey /* secret key to digest */ 533 | ); 534 | #endif 535 | 536 | 537 | /* C_DigestFinal finishes a multiple-part message-digesting 538 | * operation. 539 | */ 540 | CK_PKCS11_FUNCTION_INFO(C_DigestFinal) 541 | #ifdef CK_NEED_ARG_LIST 542 | ( 543 | CK_SESSION_HANDLE hSession, /* the session's handle */ 544 | CK_BYTE_PTR pDigest, /* gets the message digest */ 545 | CK_ULONG_PTR pulDigestLen /* gets byte count of digest */ 546 | ); 547 | #endif 548 | 549 | 550 | 551 | /* Signing and MACing */ 552 | 553 | /* C_SignInit initializes a signature (private key encryption) 554 | * operation, where the signature is (will be) an appendix to 555 | * the data, and plaintext cannot be recovered from the 556 | * signature. 557 | */ 558 | CK_PKCS11_FUNCTION_INFO(C_SignInit) 559 | #ifdef CK_NEED_ARG_LIST 560 | ( 561 | CK_SESSION_HANDLE hSession, /* the session's handle */ 562 | CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ 563 | CK_OBJECT_HANDLE hKey /* handle of signature key */ 564 | ); 565 | #endif 566 | 567 | 568 | /* C_Sign signs (encrypts with private key) data in a single 569 | * part, where the signature is (will be) an appendix to the 570 | * data, and plaintext cannot be recovered from the signature. 571 | */ 572 | CK_PKCS11_FUNCTION_INFO(C_Sign) 573 | #ifdef CK_NEED_ARG_LIST 574 | ( 575 | CK_SESSION_HANDLE hSession, /* the session's handle */ 576 | CK_BYTE_PTR pData, /* the data to sign */ 577 | CK_ULONG ulDataLen, /* count of bytes to sign */ 578 | CK_BYTE_PTR pSignature, /* gets the signature */ 579 | CK_ULONG_PTR pulSignatureLen /* gets signature length */ 580 | ); 581 | #endif 582 | 583 | 584 | /* C_SignUpdate continues a multiple-part signature operation, 585 | * where the signature is (will be) an appendix to the data, 586 | * and plaintext cannot be recovered from the signature. 587 | */ 588 | CK_PKCS11_FUNCTION_INFO(C_SignUpdate) 589 | #ifdef CK_NEED_ARG_LIST 590 | ( 591 | CK_SESSION_HANDLE hSession, /* the session's handle */ 592 | CK_BYTE_PTR pPart, /* the data to sign */ 593 | CK_ULONG ulPartLen /* count of bytes to sign */ 594 | ); 595 | #endif 596 | 597 | 598 | /* C_SignFinal finishes a multiple-part signature operation, 599 | * returning the signature. 600 | */ 601 | CK_PKCS11_FUNCTION_INFO(C_SignFinal) 602 | #ifdef CK_NEED_ARG_LIST 603 | ( 604 | CK_SESSION_HANDLE hSession, /* the session's handle */ 605 | CK_BYTE_PTR pSignature, /* gets the signature */ 606 | CK_ULONG_PTR pulSignatureLen /* gets signature length */ 607 | ); 608 | #endif 609 | 610 | 611 | /* C_SignRecoverInit initializes a signature operation, where 612 | * the data can be recovered from the signature. 613 | */ 614 | CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit) 615 | #ifdef CK_NEED_ARG_LIST 616 | ( 617 | CK_SESSION_HANDLE hSession, /* the session's handle */ 618 | CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ 619 | CK_OBJECT_HANDLE hKey /* handle of the signature key */ 620 | ); 621 | #endif 622 | 623 | 624 | /* C_SignRecover signs data in a single operation, where the 625 | * data can be recovered from the signature. 626 | */ 627 | CK_PKCS11_FUNCTION_INFO(C_SignRecover) 628 | #ifdef CK_NEED_ARG_LIST 629 | ( 630 | CK_SESSION_HANDLE hSession, /* the session's handle */ 631 | CK_BYTE_PTR pData, /* the data to sign */ 632 | CK_ULONG ulDataLen, /* count of bytes to sign */ 633 | CK_BYTE_PTR pSignature, /* gets the signature */ 634 | CK_ULONG_PTR pulSignatureLen /* gets signature length */ 635 | ); 636 | #endif 637 | 638 | 639 | 640 | /* Verifying signatures and MACs */ 641 | 642 | /* C_VerifyInit initializes a verification operation, where the 643 | * signature is an appendix to the data, and plaintext cannot 644 | * cannot be recovered from the signature (e.g. DSA). 645 | */ 646 | CK_PKCS11_FUNCTION_INFO(C_VerifyInit) 647 | #ifdef CK_NEED_ARG_LIST 648 | ( 649 | CK_SESSION_HANDLE hSession, /* the session's handle */ 650 | CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ 651 | CK_OBJECT_HANDLE hKey /* verification key */ 652 | ); 653 | #endif 654 | 655 | 656 | /* C_Verify verifies a signature in a single-part operation, 657 | * where the signature is an appendix to the data, and plaintext 658 | * cannot be recovered from the signature. 659 | */ 660 | CK_PKCS11_FUNCTION_INFO(C_Verify) 661 | #ifdef CK_NEED_ARG_LIST 662 | ( 663 | CK_SESSION_HANDLE hSession, /* the session's handle */ 664 | CK_BYTE_PTR pData, /* signed data */ 665 | CK_ULONG ulDataLen, /* length of signed data */ 666 | CK_BYTE_PTR pSignature, /* signature */ 667 | CK_ULONG ulSignatureLen /* signature length*/ 668 | ); 669 | #endif 670 | 671 | 672 | /* C_VerifyUpdate continues a multiple-part verification 673 | * operation, where the signature is an appendix to the data, 674 | * and plaintext cannot be recovered from the signature. 675 | */ 676 | CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate) 677 | #ifdef CK_NEED_ARG_LIST 678 | ( 679 | CK_SESSION_HANDLE hSession, /* the session's handle */ 680 | CK_BYTE_PTR pPart, /* signed data */ 681 | CK_ULONG ulPartLen /* length of signed data */ 682 | ); 683 | #endif 684 | 685 | 686 | /* C_VerifyFinal finishes a multiple-part verification 687 | * operation, checking the signature. 688 | */ 689 | CK_PKCS11_FUNCTION_INFO(C_VerifyFinal) 690 | #ifdef CK_NEED_ARG_LIST 691 | ( 692 | CK_SESSION_HANDLE hSession, /* the session's handle */ 693 | CK_BYTE_PTR pSignature, /* signature to verify */ 694 | CK_ULONG ulSignatureLen /* signature length */ 695 | ); 696 | #endif 697 | 698 | 699 | /* C_VerifyRecoverInit initializes a signature verification 700 | * operation, where the data is recovered from the signature. 701 | */ 702 | CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit) 703 | #ifdef CK_NEED_ARG_LIST 704 | ( 705 | CK_SESSION_HANDLE hSession, /* the session's handle */ 706 | CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ 707 | CK_OBJECT_HANDLE hKey /* verification key */ 708 | ); 709 | #endif 710 | 711 | 712 | /* C_VerifyRecover verifies a signature in a single-part 713 | * operation, where the data is recovered from the signature. 714 | */ 715 | CK_PKCS11_FUNCTION_INFO(C_VerifyRecover) 716 | #ifdef CK_NEED_ARG_LIST 717 | ( 718 | CK_SESSION_HANDLE hSession, /* the session's handle */ 719 | CK_BYTE_PTR pSignature, /* signature to verify */ 720 | CK_ULONG ulSignatureLen, /* signature length */ 721 | CK_BYTE_PTR pData, /* gets signed data */ 722 | CK_ULONG_PTR pulDataLen /* gets signed data len */ 723 | ); 724 | #endif 725 | 726 | 727 | 728 | /* Dual-function cryptographic operations */ 729 | 730 | /* C_DigestEncryptUpdate continues a multiple-part digesting 731 | * and encryption operation. 732 | */ 733 | CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate) 734 | #ifdef CK_NEED_ARG_LIST 735 | ( 736 | CK_SESSION_HANDLE hSession, /* session's handle */ 737 | CK_BYTE_PTR pPart, /* the plaintext data */ 738 | CK_ULONG ulPartLen, /* plaintext length */ 739 | CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ 740 | CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ 741 | ); 742 | #endif 743 | 744 | 745 | /* C_DecryptDigestUpdate continues a multiple-part decryption and 746 | * digesting operation. 747 | */ 748 | CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate) 749 | #ifdef CK_NEED_ARG_LIST 750 | ( 751 | CK_SESSION_HANDLE hSession, /* session's handle */ 752 | CK_BYTE_PTR pEncryptedPart, /* ciphertext */ 753 | CK_ULONG ulEncryptedPartLen, /* ciphertext length */ 754 | CK_BYTE_PTR pPart, /* gets plaintext */ 755 | CK_ULONG_PTR pulPartLen /* gets plaintext len */ 756 | ); 757 | #endif 758 | 759 | 760 | /* C_SignEncryptUpdate continues a multiple-part signing and 761 | * encryption operation. 762 | */ 763 | CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate) 764 | #ifdef CK_NEED_ARG_LIST 765 | ( 766 | CK_SESSION_HANDLE hSession, /* session's handle */ 767 | CK_BYTE_PTR pPart, /* the plaintext data */ 768 | CK_ULONG ulPartLen, /* plaintext length */ 769 | CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ 770 | CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ 771 | ); 772 | #endif 773 | 774 | 775 | /* C_DecryptVerifyUpdate continues a multiple-part decryption and 776 | * verify operation. 777 | */ 778 | CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate) 779 | #ifdef CK_NEED_ARG_LIST 780 | ( 781 | CK_SESSION_HANDLE hSession, /* session's handle */ 782 | CK_BYTE_PTR pEncryptedPart, /* ciphertext */ 783 | CK_ULONG ulEncryptedPartLen, /* ciphertext length */ 784 | CK_BYTE_PTR pPart, /* gets plaintext */ 785 | CK_ULONG_PTR pulPartLen /* gets p-text length */ 786 | ); 787 | #endif 788 | 789 | 790 | 791 | /* Key management */ 792 | 793 | /* C_GenerateKey generates a secret key, creating a new key 794 | * object. 795 | */ 796 | CK_PKCS11_FUNCTION_INFO(C_GenerateKey) 797 | #ifdef CK_NEED_ARG_LIST 798 | ( 799 | CK_SESSION_HANDLE hSession, /* the session's handle */ 800 | CK_MECHANISM_PTR pMechanism, /* key generation mech. */ 801 | CK_ATTRIBUTE_PTR pTemplate, /* template for new key */ 802 | CK_ULONG ulCount, /* # of attrs in template */ 803 | CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */ 804 | ); 805 | #endif 806 | 807 | 808 | /* C_GenerateKeyPair generates a public-key/private-key pair, 809 | * creating new key objects. 810 | */ 811 | CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair) 812 | #ifdef CK_NEED_ARG_LIST 813 | ( 814 | CK_SESSION_HANDLE hSession, /* session handle */ 815 | CK_MECHANISM_PTR pMechanism, /* key-gen mech. */ 816 | CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template for pub. key */ 817 | CK_ULONG ulPublicKeyAttributeCount, /* # pub. attrs. */ 818 | CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template for priv. key */ 819 | CK_ULONG ulPrivateKeyAttributeCount, /* # priv. attrs. */ 820 | CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */ 821 | CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key handle */ 822 | ); 823 | #endif 824 | 825 | 826 | /* C_WrapKey wraps (i.e., encrypts) a key. */ 827 | CK_PKCS11_FUNCTION_INFO(C_WrapKey) 828 | #ifdef CK_NEED_ARG_LIST 829 | ( 830 | CK_SESSION_HANDLE hSession, /* the session's handle */ 831 | CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */ 832 | CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */ 833 | CK_OBJECT_HANDLE hKey, /* key to be wrapped */ 834 | CK_BYTE_PTR pWrappedKey, /* gets wrapped key */ 835 | CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */ 836 | ); 837 | #endif 838 | 839 | 840 | /* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new 841 | * key object. 842 | */ 843 | CK_PKCS11_FUNCTION_INFO(C_UnwrapKey) 844 | #ifdef CK_NEED_ARG_LIST 845 | ( 846 | CK_SESSION_HANDLE hSession, /* session's handle */ 847 | CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */ 848 | CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */ 849 | CK_BYTE_PTR pWrappedKey, /* the wrapped key */ 850 | CK_ULONG ulWrappedKeyLen, /* wrapped key len */ 851 | CK_ATTRIBUTE_PTR pTemplate, /* new key template */ 852 | CK_ULONG ulAttributeCount, /* template length */ 853 | CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ 854 | ); 855 | #endif 856 | 857 | 858 | /* C_DeriveKey derives a key from a base key, creating a new key 859 | * object. 860 | */ 861 | CK_PKCS11_FUNCTION_INFO(C_DeriveKey) 862 | #ifdef CK_NEED_ARG_LIST 863 | ( 864 | CK_SESSION_HANDLE hSession, /* session's handle */ 865 | CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */ 866 | CK_OBJECT_HANDLE hBaseKey, /* base key */ 867 | CK_ATTRIBUTE_PTR pTemplate, /* new key template */ 868 | CK_ULONG ulAttributeCount, /* template length */ 869 | CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ 870 | ); 871 | #endif 872 | 873 | 874 | 875 | /* Random number generation */ 876 | 877 | /* C_SeedRandom mixes additional seed material into the token's 878 | * random number generator. 879 | */ 880 | CK_PKCS11_FUNCTION_INFO(C_SeedRandom) 881 | #ifdef CK_NEED_ARG_LIST 882 | ( 883 | CK_SESSION_HANDLE hSession, /* the session's handle */ 884 | CK_BYTE_PTR pSeed, /* the seed material */ 885 | CK_ULONG ulSeedLen /* length of seed material */ 886 | ); 887 | #endif 888 | 889 | 890 | /* C_GenerateRandom generates random data. */ 891 | CK_PKCS11_FUNCTION_INFO(C_GenerateRandom) 892 | #ifdef CK_NEED_ARG_LIST 893 | ( 894 | CK_SESSION_HANDLE hSession, /* the session's handle */ 895 | CK_BYTE_PTR RandomData, /* receives the random data */ 896 | CK_ULONG ulRandomLen /* # of bytes to generate */ 897 | ); 898 | #endif 899 | 900 | 901 | 902 | /* Parallel function management */ 903 | 904 | /* C_GetFunctionStatus is a legacy function; it obtains an 905 | * updated status of a function running in parallel with an 906 | * application. 907 | */ 908 | CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus) 909 | #ifdef CK_NEED_ARG_LIST 910 | ( 911 | CK_SESSION_HANDLE hSession /* the session's handle */ 912 | ); 913 | #endif 914 | 915 | 916 | /* C_CancelFunction is a legacy function; it cancels a function 917 | * running in parallel. 918 | */ 919 | CK_PKCS11_FUNCTION_INFO(C_CancelFunction) 920 | #ifdef CK_NEED_ARG_LIST 921 | ( 922 | CK_SESSION_HANDLE hSession /* the session's handle */ 923 | ); 924 | #endif 925 | 926 | 927 | /* C_WaitForSlotEvent waits for a slot event (token insertion, 928 | * removal, etc.) to occur. 929 | */ 930 | CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent) 931 | #ifdef CK_NEED_ARG_LIST 932 | ( 933 | CK_FLAGS flags, /* blocking/nonblocking flag */ 934 | CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */ 935 | CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */ 936 | ); 937 | #endif 938 | 939 | #ifndef CK_PKCS11_2_0_ONLY 940 | /* C_GetInterfaceList returns all the interfaces supported by the module*/ 941 | CK_PKCS11_FUNCTION_INFO(C_GetInterfaceList) 942 | #ifdef CK_NEED_ARG_LIST 943 | ( 944 | CK_INTERFACE_PTR pInterfacesList, /* returned interfaces */ 945 | CK_ULONG_PTR pulCount /* number of interfaces returned */ 946 | ); 947 | #endif 948 | 949 | /* C_GetInterface returns a specific interface from the module. */ 950 | CK_PKCS11_FUNCTION_INFO(C_GetInterface) 951 | #ifdef CK_NEED_ARG_LIST 952 | ( 953 | CK_UTF8CHAR_PTR pInterfaceName, /* name of the interface */ 954 | CK_VERSION_PTR pVersion, /* version of the interface */ 955 | CK_INTERFACE_PTR_PTR ppInterface, /* returned interface */ 956 | CK_FLAGS flags /* flags controlling the semantics 957 | * of the interface */ 958 | ); 959 | #endif 960 | 961 | CK_PKCS11_FUNCTION_INFO(C_LoginUser) 962 | #ifdef CK_NEED_ARG_LIST 963 | ( 964 | CK_SESSION_HANDLE hSession, /* the session's handle */ 965 | CK_USER_TYPE userType, /* the user type */ 966 | CK_UTF8CHAR_PTR pPin, /* the user's PIN */ 967 | CK_ULONG ulPinLen, /* the length of the PIN */ 968 | CK_UTF8CHAR_PTR pUsername, /* the user's name */ 969 | CK_ULONG ulUsernameLen /*the length of the user's name */ 970 | ); 971 | #endif 972 | 973 | CK_PKCS11_FUNCTION_INFO(C_SessionCancel) 974 | #ifdef CK_NEED_ARG_LIST 975 | ( 976 | CK_SESSION_HANDLE hSession, /* the session's handle */ 977 | CK_FLAGS flags /* flags control which sessions are cancelled */ 978 | ); 979 | #endif 980 | 981 | CK_PKCS11_FUNCTION_INFO(C_MessageEncryptInit) 982 | #ifdef CK_NEED_ARG_LIST 983 | ( 984 | CK_SESSION_HANDLE hSession, /* the session's handle */ 985 | CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ 986 | CK_OBJECT_HANDLE hKey /* handle of encryption key */ 987 | ); 988 | #endif 989 | 990 | CK_PKCS11_FUNCTION_INFO(C_EncryptMessage) 991 | #ifdef CK_NEED_ARG_LIST 992 | ( 993 | CK_SESSION_HANDLE hSession, /* the session's handle */ 994 | CK_VOID_PTR pParameter, /* message specific parameter */ 995 | CK_ULONG ulParameterLen, /* length of message specific parameter */ 996 | CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ 997 | CK_ULONG ulAssociatedDataLen, /* AEAD Associated data length */ 998 | CK_BYTE_PTR pPlaintext, /* plain text */ 999 | CK_ULONG ulPlaintextLen, /* plain text length */ 1000 | CK_BYTE_PTR pCiphertext, /* gets cipher text */ 1001 | CK_ULONG_PTR pulCiphertextLen /* gets cipher text length */ 1002 | ); 1003 | #endif 1004 | 1005 | CK_PKCS11_FUNCTION_INFO(C_EncryptMessageBegin) 1006 | #ifdef CK_NEED_ARG_LIST 1007 | ( 1008 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1009 | CK_VOID_PTR pParameter, /* message specific parameter */ 1010 | CK_ULONG ulParameterLen, /* length of message specific parameter */ 1011 | CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ 1012 | CK_ULONG ulAssociatedDataLen /* AEAD Associated data length */ 1013 | ); 1014 | #endif 1015 | 1016 | CK_PKCS11_FUNCTION_INFO(C_EncryptMessageNext) 1017 | #ifdef CK_NEED_ARG_LIST 1018 | ( 1019 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1020 | CK_VOID_PTR pParameter, /* message specific parameter */ 1021 | CK_ULONG ulParameterLen, /* length of message specific parameter */ 1022 | CK_BYTE_PTR pPlaintextPart, /* plain text */ 1023 | CK_ULONG ulPlaintextPartLen, /* plain text length */ 1024 | CK_BYTE_PTR pCiphertextPart, /* gets cipher text */ 1025 | CK_ULONG_PTR pulCiphertextPartLen, /* gets cipher text length */ 1026 | CK_FLAGS flags /* multi mode flag */ 1027 | ); 1028 | #endif 1029 | 1030 | CK_PKCS11_FUNCTION_INFO(C_MessageEncryptFinal) 1031 | #ifdef CK_NEED_ARG_LIST 1032 | ( 1033 | CK_SESSION_HANDLE hSession /* the session's handle */ 1034 | ); 1035 | #endif 1036 | 1037 | CK_PKCS11_FUNCTION_INFO(C_MessageDecryptInit) 1038 | #ifdef CK_NEED_ARG_LIST 1039 | ( 1040 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1041 | CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ 1042 | CK_OBJECT_HANDLE hKey /* handle of decryption key */ 1043 | ); 1044 | #endif 1045 | 1046 | CK_PKCS11_FUNCTION_INFO(C_DecryptMessage) 1047 | #ifdef CK_NEED_ARG_LIST 1048 | ( 1049 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1050 | CK_VOID_PTR pParameter, /* message specific parameter */ 1051 | CK_ULONG ulParameterLen, /* length of message specific parameter */ 1052 | CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ 1053 | CK_ULONG ulAssociatedDataLen, /* AEAD Associated data length */ 1054 | CK_BYTE_PTR pCiphertext, /* cipher text */ 1055 | CK_ULONG ulCiphertextLen, /* cipher text length */ 1056 | CK_BYTE_PTR pPlaintext, /* gets plain text */ 1057 | CK_ULONG_PTR pulPlaintextLen /* gets plain text length */ 1058 | ); 1059 | #endif 1060 | 1061 | CK_PKCS11_FUNCTION_INFO(C_DecryptMessageBegin) 1062 | #ifdef CK_NEED_ARG_LIST 1063 | ( 1064 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1065 | CK_VOID_PTR pParameter, /* message specific parameter */ 1066 | CK_ULONG ulParameterLen, /* length of message specific parameter */ 1067 | CK_BYTE_PTR pAssociatedData, /* AEAD Associated data */ 1068 | CK_ULONG ulAssociatedDataLen /* AEAD Associated data length */ 1069 | ); 1070 | #endif 1071 | 1072 | CK_PKCS11_FUNCTION_INFO(C_DecryptMessageNext) 1073 | #ifdef CK_NEED_ARG_LIST 1074 | ( 1075 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1076 | CK_VOID_PTR pParameter, /* message specific parameter */ 1077 | CK_ULONG ulParameterLen, /* length of message specific parameter */ 1078 | CK_BYTE_PTR pCiphertextPart, /* cipher text */ 1079 | CK_ULONG ulCiphertextPartLen, /* cipher text length */ 1080 | CK_BYTE_PTR pPlaintextPart, /* gets plain text */ 1081 | CK_ULONG_PTR pulPlaintextPartLen, /* gets plain text length */ 1082 | CK_FLAGS flags /* multi mode flag */ 1083 | ); 1084 | #endif 1085 | 1086 | CK_PKCS11_FUNCTION_INFO(C_MessageDecryptFinal) 1087 | #ifdef CK_NEED_ARG_LIST 1088 | ( 1089 | CK_SESSION_HANDLE hSession /* the session's handle */ 1090 | ); 1091 | #endif 1092 | 1093 | CK_PKCS11_FUNCTION_INFO(C_MessageSignInit) 1094 | #ifdef CK_NEED_ARG_LIST 1095 | ( 1096 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1097 | CK_MECHANISM_PTR pMechanism, /* the signing mechanism */ 1098 | CK_OBJECT_HANDLE hKey /* handle of signing key */ 1099 | ); 1100 | #endif 1101 | 1102 | CK_PKCS11_FUNCTION_INFO(C_SignMessage) 1103 | #ifdef CK_NEED_ARG_LIST 1104 | ( 1105 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1106 | CK_VOID_PTR pParameter, /* message specific parameter */ 1107 | CK_ULONG ulParameterLen, /* length of message specific parameter */ 1108 | CK_BYTE_PTR pData, /* data to sign */ 1109 | CK_ULONG ulDataLen, /* data to sign length */ 1110 | CK_BYTE_PTR pSignature, /* gets signature */ 1111 | CK_ULONG_PTR pulSignatureLen /* gets signature length */ 1112 | ); 1113 | #endif 1114 | 1115 | CK_PKCS11_FUNCTION_INFO(C_SignMessageBegin) 1116 | #ifdef CK_NEED_ARG_LIST 1117 | ( 1118 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1119 | CK_VOID_PTR pParameter, /* message specific parameter */ 1120 | CK_ULONG ulParameterLen /* length of message specific parameter */ 1121 | ); 1122 | #endif 1123 | 1124 | CK_PKCS11_FUNCTION_INFO(C_SignMessageNext) 1125 | #ifdef CK_NEED_ARG_LIST 1126 | ( 1127 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1128 | CK_VOID_PTR pParameter, /* message specific parameter */ 1129 | CK_ULONG ulParameterLen, /* length of message specific parameter */ 1130 | CK_BYTE_PTR pData, /* data to sign */ 1131 | CK_ULONG ulDataLen, /* data to sign length */ 1132 | CK_BYTE_PTR pSignature, /* gets signature */ 1133 | CK_ULONG_PTR pulSignatureLen /* gets signature length */ 1134 | ); 1135 | #endif 1136 | 1137 | CK_PKCS11_FUNCTION_INFO(C_MessageSignFinal) 1138 | #ifdef CK_NEED_ARG_LIST 1139 | ( 1140 | CK_SESSION_HANDLE hSession /* the session's handle */ 1141 | ); 1142 | #endif 1143 | 1144 | CK_PKCS11_FUNCTION_INFO(C_MessageVerifyInit) 1145 | #ifdef CK_NEED_ARG_LIST 1146 | ( 1147 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1148 | CK_MECHANISM_PTR pMechanism, /* the signing mechanism */ 1149 | CK_OBJECT_HANDLE hKey /* handle of signing key */ 1150 | ); 1151 | #endif 1152 | 1153 | CK_PKCS11_FUNCTION_INFO(C_VerifyMessage) 1154 | #ifdef CK_NEED_ARG_LIST 1155 | ( 1156 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1157 | CK_VOID_PTR pParameter, /* message specific parameter */ 1158 | CK_ULONG ulParameterLen, /* length of message specific parameter */ 1159 | CK_BYTE_PTR pData, /* data to sign */ 1160 | CK_ULONG ulDataLen, /* data to sign length */ 1161 | CK_BYTE_PTR pSignature, /* signature */ 1162 | CK_ULONG ulSignatureLen /* signature length */ 1163 | ); 1164 | #endif 1165 | 1166 | CK_PKCS11_FUNCTION_INFO(C_VerifyMessageBegin) 1167 | #ifdef CK_NEED_ARG_LIST 1168 | ( 1169 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1170 | CK_VOID_PTR pParameter, /* message specific parameter */ 1171 | CK_ULONG ulParameterLen /* length of message specific parameter */ 1172 | ); 1173 | #endif 1174 | 1175 | CK_PKCS11_FUNCTION_INFO(C_VerifyMessageNext) 1176 | #ifdef CK_NEED_ARG_LIST 1177 | ( 1178 | CK_SESSION_HANDLE hSession, /* the session's handle */ 1179 | CK_VOID_PTR pParameter, /* message specific parameter */ 1180 | CK_ULONG ulParameterLen, /* length of message specific parameter */ 1181 | CK_BYTE_PTR pData, /* data to sign */ 1182 | CK_ULONG ulDataLen, /* data to sign length */ 1183 | CK_BYTE_PTR pSignature, /* signature */ 1184 | CK_ULONG ulSignatureLen /* signature length */ 1185 | ); 1186 | #endif 1187 | 1188 | CK_PKCS11_FUNCTION_INFO(C_MessageVerifyFinal) 1189 | #ifdef CK_NEED_ARG_LIST 1190 | ( 1191 | CK_SESSION_HANDLE hSession /* the session's handle */ 1192 | ); 1193 | #endif 1194 | 1195 | #endif /* CK_PKCS11_2_0_ONLY */ 1196 | -------------------------------------------------------------------------------- /src/dl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2025 The Pkcs11Interop Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Written for the Pkcs11Interop project by: 19 | * Jaroslav IMRICH 20 | */ 21 | 22 | 23 | #include "pkcs11-logger.h" 24 | 25 | 26 | // Platform dependend function that loads dynamic library 27 | DLHANDLE pkcs11_logger_dl_open(const char* library) 28 | { 29 | DLHANDLE handle = NULL; 30 | 31 | pkcs11_logger_log_with_timestamp("Loading library \"%s\"", library); 32 | 33 | #ifdef _WIN32 34 | 35 | DWORD flags = 0; 36 | DWORD error = 0; 37 | 38 | if (CK_TRUE == pkcs11_logger_utils_path_is_absolute(library)) 39 | flags = LOAD_WITH_ALTERED_SEARCH_PATH; 40 | 41 | handle = LoadLibraryExA(library, NULL, flags); 42 | if (NULL == handle) 43 | { 44 | error = GetLastError(); 45 | pkcs11_logger_log_with_timestamp("Unable to load library. Error: %0#10x", error); 46 | } 47 | else 48 | { 49 | pkcs11_logger_log_with_timestamp("Successfully loaded library"); 50 | } 51 | 52 | #else 53 | 54 | char* error = NULL; 55 | 56 | handle = dlopen(library, RTLD_NOW | RTLD_LOCAL); 57 | if (NULL == handle) 58 | { 59 | error = dlerror(); 60 | if (NULL != error) 61 | { 62 | pkcs11_logger_log_with_timestamp("Unable to load library. Error: %s", error); 63 | } 64 | else 65 | { 66 | pkcs11_logger_log_with_timestamp("Unable to load library"); 67 | } 68 | } 69 | else 70 | { 71 | pkcs11_logger_log_with_timestamp("Successfully loaded library"); 72 | } 73 | 74 | #endif 75 | 76 | return handle; 77 | } 78 | 79 | 80 | // Platform dependend function that gets function pointer from dynamic library 81 | void *pkcs11_logger_dl_sym(DLHANDLE library, const char *function) 82 | { 83 | void *address = NULL; 84 | 85 | pkcs11_logger_log_with_timestamp("Retrieving function pointer for %s", function); 86 | 87 | #ifdef _WIN32 88 | 89 | DWORD error = 0; 90 | 91 | address = (void*) GetProcAddress(library, function); 92 | if (NULL == address) 93 | { 94 | error = GetLastError(); 95 | pkcs11_logger_log_with_timestamp("Unable to retrieve function pointer. Error: %0#10x", error); 96 | } 97 | else 98 | { 99 | pkcs11_logger_log_with_timestamp("Successfully retrieved function pointer"); 100 | } 101 | 102 | #else 103 | 104 | char* error = NULL; 105 | 106 | address = dlsym(library, function); 107 | if (NULL == address) 108 | { 109 | error = dlerror(); 110 | if (NULL != error) 111 | { 112 | pkcs11_logger_log_with_timestamp("Unable to retrieve function pointer. Error: %s", error); 113 | } 114 | else 115 | { 116 | pkcs11_logger_log_with_timestamp("Unable to retrieve function pointer"); 117 | } 118 | } 119 | else 120 | { 121 | pkcs11_logger_log_with_timestamp("Successfully retrieved function pointer"); 122 | } 123 | 124 | #endif 125 | 126 | return address; 127 | } 128 | 129 | 130 | // Platform dependend function that unloads dynamic library 131 | int pkcs11_logger_dl_close(DLHANDLE library) 132 | { 133 | int rv = 0; 134 | 135 | pkcs11_logger_log_with_timestamp("Unloading library"); 136 | 137 | #ifdef _WIN32 138 | 139 | DWORD error = 0; 140 | 141 | rv = FreeLibrary(library); 142 | if (0 == rv) 143 | { 144 | error = GetLastError(); 145 | pkcs11_logger_log_with_timestamp("Unable to unload library. Error: %0#10x", error); 146 | } 147 | else 148 | { 149 | pkcs11_logger_log_with_timestamp("Successfully unloaded library"); 150 | } 151 | 152 | #else 153 | 154 | char* error = NULL; 155 | 156 | rv = dlclose(library); 157 | if (0 == rv) 158 | { 159 | error = dlerror(); 160 | if (NULL != error) 161 | { 162 | pkcs11_logger_log_with_timestamp("Unable to unload library. Error: %s", error); 163 | } 164 | else 165 | { 166 | pkcs11_logger_log_with_timestamp("Unable to unload library"); 167 | } 168 | } 169 | else 170 | { 171 | pkcs11_logger_log_with_timestamp("Successfully unloaded library"); 172 | } 173 | 174 | #endif 175 | 176 | return rv; 177 | } 178 | -------------------------------------------------------------------------------- /src/init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2025 The Pkcs11Interop Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Written for the Pkcs11Interop project by: 19 | * Jaroslav IMRICH 20 | */ 21 | 22 | 23 | #include "pkcs11-logger.h" 24 | 25 | 26 | extern PKCS11_LOGGER_GLOBALS pkcs11_logger_globals; 27 | 28 | 29 | #ifdef _WIN32 30 | 31 | // Entry and exit point for the shared library on windows platforms 32 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 33 | { 34 | IGNORE_ARG(hModule); 35 | IGNORE_ARG(lpReserved); 36 | 37 | if ((DLL_PROCESS_ATTACH == ul_reason_for_call) || (DLL_PROCESS_DETACH == ul_reason_for_call)) 38 | pkcs11_logger_init_globals(); 39 | 40 | return TRUE; 41 | } 42 | 43 | #else 44 | 45 | // Entry point for the shared library on unix platforms 46 | __attribute__((constructor)) void pkcs11_logger_init_entry_point(void) 47 | { 48 | pkcs11_logger_init_globals(); 49 | } 50 | 51 | // Exit point for the shared library on unix platforms 52 | __attribute__((destructor)) void pkcs11_logger_init_exit_point(void) 53 | { 54 | pkcs11_logger_init_globals(); 55 | } 56 | 57 | #endif 58 | 59 | 60 | // Initializes/frees global variables 61 | void pkcs11_logger_init_globals(void) 62 | { 63 | // Note: Calling LoadLibrary() or FreeLibrary() in DllMain() can cause a deadlock or a crash. 64 | // See "Dynamic-Link Library Best Practices" article on MSDN for more details. 65 | pkcs11_logger_globals.orig_lib_handle = NULL; 66 | pkcs11_logger_globals.orig_lib_functions = NULL; 67 | // Note: There is no need to modify pkcs11_logger_globals.logger_functions 68 | pkcs11_logger_globals.env_vars_read = CK_FALSE; 69 | CALL_N_CLEAR(free, pkcs11_logger_globals.env_var_library_path); 70 | CALL_N_CLEAR(free, pkcs11_logger_globals.env_var_log_file_path); 71 | CALL_N_CLEAR(free, pkcs11_logger_globals.env_var_flags); 72 | pkcs11_logger_globals.flags = 0; 73 | CALL_N_CLEAR(fclose, pkcs11_logger_globals.log_file_handle); 74 | } 75 | 76 | 77 | // Loads original PKCS#11 library 78 | int pkcs11_logger_init_orig_lib(void) 79 | { 80 | CK_C_GetFunctionList GetFunctionListPointer = NULL; 81 | CK_RV rv = CKR_OK; 82 | 83 | if (NULL != pkcs11_logger_globals.orig_lib_handle) 84 | return PKCS11_LOGGER_RV_SUCCESS; 85 | 86 | // Initialize global variables 87 | pkcs11_logger_init_globals(); 88 | 89 | // Create lock for synchronization of log file access 90 | if (PKCS11_LOGGER_RV_SUCCESS != pkcs11_logger_lock_create()) 91 | return PKCS11_LOGGER_RV_ERROR; 92 | 93 | // Read environment variables 94 | if (PKCS11_LOGGER_RV_SUCCESS != pkcs11_logger_init_parse_env_vars()) 95 | return PKCS11_LOGGER_RV_ERROR; 96 | 97 | pkcs11_logger_globals.env_vars_read = CK_TRUE; 98 | 99 | // Log informational header 100 | pkcs11_logger_log_separator(); 101 | pkcs11_logger_log("%s %s", PKCS11_LOGGER_NAME, PKCS11_LOGGER_VERSION); 102 | pkcs11_logger_log("%s", PKCS11_LOGGER_DESCRIPTION); 103 | pkcs11_logger_log("Developed as a part of the Pkcs11Interop project"); 104 | pkcs11_logger_log("Please visit www.pkcs11interop.net for more information"); 105 | pkcs11_logger_log_separator(); 106 | 107 | // Load PKCS#11 library 108 | pkcs11_logger_globals.orig_lib_handle = pkcs11_logger_dl_open((const char *)pkcs11_logger_globals.env_var_library_path); 109 | if (NULL == pkcs11_logger_globals.orig_lib_handle) 110 | { 111 | return PKCS11_LOGGER_RV_ERROR; 112 | } 113 | 114 | // Get pointer to C_GetFunctionList() 115 | GetFunctionListPointer = (CK_C_GetFunctionList) pkcs11_logger_dl_sym(pkcs11_logger_globals.orig_lib_handle, "C_GetFunctionList"); 116 | if (NULL == GetFunctionListPointer) 117 | { 118 | CALL_N_CLEAR(pkcs11_logger_dl_close, pkcs11_logger_globals.orig_lib_handle); 119 | return PKCS11_LOGGER_RV_ERROR; 120 | } 121 | 122 | // Get pointers to all PKCS#11 functions 123 | pkcs11_logger_log_with_timestamp("Calling C_GetFunctionList function"); 124 | rv = GetFunctionListPointer(&(pkcs11_logger_globals.orig_lib_functions)); 125 | pkcs11_logger_log_with_timestamp("Received response from C_GetFunctionList function"); 126 | if (CKR_OK != rv) 127 | { 128 | pkcs11_logger_log("C_GetFunctionList returned %lu (%s)", rv, pkcs11_logger_translate_ck_rv(rv)); 129 | CALL_N_CLEAR(pkcs11_logger_dl_close, pkcs11_logger_globals.orig_lib_handle); 130 | return PKCS11_LOGGER_RV_ERROR; 131 | } 132 | 133 | // Lets present version of orig library as ours - that's what proxies do :) 134 | pkcs11_logger_globals.logger_functions.version.major = pkcs11_logger_globals.orig_lib_functions->version.major; 135 | pkcs11_logger_globals.logger_functions.version.minor = pkcs11_logger_globals.orig_lib_functions->version.minor; 136 | 137 | // Everything is set up 138 | pkcs11_logger_log_separator(); 139 | pkcs11_logger_log("NOTE: Memory contents will be logged without the endianness conversion"); 140 | 141 | return PKCS11_LOGGER_RV_SUCCESS; 142 | } 143 | 144 | 145 | // Parses environment variables 146 | int pkcs11_logger_init_parse_env_vars(void) 147 | { 148 | int rv = PKCS11_LOGGER_RV_ERROR; 149 | 150 | // Read PKCS11_LOGGER_LIBRARY_PATH environment variable 151 | pkcs11_logger_globals.env_var_library_path = pkcs11_logger_init_read_env_var(PKCS11_LOGGER_LIBRARY_PATH); 152 | if (NULL == pkcs11_logger_globals.env_var_library_path) 153 | { 154 | pkcs11_logger_log("Environment variable %s is not defined", PKCS11_LOGGER_LIBRARY_PATH); 155 | goto err; 156 | } 157 | 158 | if (('"' == pkcs11_logger_globals.env_var_library_path[0]) || ('\'' == pkcs11_logger_globals.env_var_library_path[0])) 159 | { 160 | pkcs11_logger_log("Value of %s environment variable needs to be provided without enclosing quotes", PKCS11_LOGGER_LIBRARY_PATH); 161 | goto err; 162 | } 163 | 164 | // Read PKCS11_LOGGER_LOG_FILE_PATH environment variable 165 | pkcs11_logger_globals.env_var_log_file_path = pkcs11_logger_init_read_env_var(PKCS11_LOGGER_LOG_FILE_PATH); 166 | if (NULL != pkcs11_logger_globals.env_var_log_file_path) 167 | { 168 | if (('"' == pkcs11_logger_globals.env_var_log_file_path[0]) || ('\'' == pkcs11_logger_globals.env_var_log_file_path[0])) 169 | { 170 | pkcs11_logger_log("Value of %s environment variable needs to be provided without enclosing quotes", PKCS11_LOGGER_LOG_FILE_PATH); 171 | goto err; 172 | } 173 | } 174 | 175 | // Read PKCS11_LOGGER_FLAGS environment variable 176 | pkcs11_logger_globals.env_var_flags = pkcs11_logger_init_read_env_var(PKCS11_LOGGER_FLAGS); 177 | if (NULL != pkcs11_logger_globals.env_var_flags) 178 | { 179 | if (PKCS11_LOGGER_RV_SUCCESS != pkcs11_logger_utils_str_to_long((const char *)pkcs11_logger_globals.env_var_flags, &(pkcs11_logger_globals.flags))) 180 | { 181 | pkcs11_logger_log("Unable to read the value of %s environment variable as a number", PKCS11_LOGGER_FLAGS); 182 | goto err; 183 | } 184 | } 185 | 186 | rv = PKCS11_LOGGER_RV_SUCCESS; 187 | 188 | err: 189 | 190 | if (rv == PKCS11_LOGGER_RV_ERROR) 191 | { 192 | CALL_N_CLEAR(free, pkcs11_logger_globals.env_var_library_path); 193 | CALL_N_CLEAR(free, pkcs11_logger_globals.env_var_log_file_path); 194 | CALL_N_CLEAR(free, pkcs11_logger_globals.env_var_flags); 195 | } 196 | 197 | return rv; 198 | } 199 | 200 | 201 | // Reads environment variable 202 | CK_CHAR_PTR pkcs11_logger_init_read_env_var(const char *env_var_name) 203 | { 204 | #ifdef _WIN32 205 | 206 | CK_CHAR_PTR output_value = NULL; 207 | LPSTR env_var_value = NULL; 208 | DWORD env_var_value_size = 0; 209 | 210 | env_var_value_size = GetEnvironmentVariableA(env_var_name, env_var_value, env_var_value_size); 211 | if (0 == env_var_value_size) 212 | { 213 | // Note: Environment variable is not defined 214 | goto err; 215 | } 216 | 217 | env_var_value = (LPSTR) malloc(env_var_value_size); 218 | if (NULL == env_var_value) 219 | { 220 | pkcs11_logger_log("Unable to allocate memory for the value of %s environment variable", env_var_name); 221 | goto err; 222 | } 223 | 224 | if ((env_var_value_size - 1) != GetEnvironmentVariableA(env_var_name, env_var_value, env_var_value_size)) 225 | { 226 | pkcs11_logger_log("Unable to read the value of %s environment variable", env_var_name); 227 | goto err; 228 | } 229 | 230 | output_value = (CK_CHAR_PTR) env_var_value; 231 | env_var_value = NULL; 232 | 233 | err: 234 | 235 | CALL_N_CLEAR(free, env_var_value); 236 | 237 | return output_value; 238 | 239 | #else 240 | 241 | CK_CHAR_PTR output_value = NULL; 242 | char *env_var_value = NULL; 243 | 244 | env_var_value = getenv(env_var_name); 245 | if (NULL == env_var_value) 246 | { 247 | // Note: Environment variable is not defined 248 | goto err; 249 | } 250 | 251 | output_value = (CK_CHAR_PTR) strdup(env_var_value); 252 | if (NULL == output_value) 253 | { 254 | pkcs11_logger_log("Unable to copy the value of %s environment variable", env_var_name); 255 | goto err; 256 | } 257 | 258 | err: 259 | 260 | return output_value; 261 | 262 | #endif 263 | } 264 | 265 | -------------------------------------------------------------------------------- /src/lock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2025 The Pkcs11Interop Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Written for the Pkcs11Interop project by: 19 | * Jaroslav IMRICH 20 | */ 21 | 22 | 23 | #include "pkcs11-logger.h" 24 | 25 | 26 | // Lock for log file access synchronization 27 | #ifdef _WIN32 28 | static HANDLE pkcs11_logger_lock = NULL; 29 | #else 30 | static pthread_mutex_t pkcs11_logger_lock; 31 | #endif 32 | 33 | 34 | // Creates lock for log file access synchronization 35 | int pkcs11_logger_lock_create(void) 36 | { 37 | int rv = PKCS11_LOGGER_RV_ERROR; 38 | 39 | #ifdef _WIN32 40 | 41 | if (NULL != pkcs11_logger_lock) 42 | { 43 | pkcs11_logger_log("Lock already exists"); 44 | goto end; 45 | } 46 | 47 | pkcs11_logger_lock = CreateMutex(NULL, FALSE, NULL); 48 | if (NULL == pkcs11_logger_lock) 49 | { 50 | pkcs11_logger_log("Unable to create lock"); 51 | goto end; 52 | } 53 | 54 | #else 55 | 56 | if (0 != pthread_mutex_init(&pkcs11_logger_lock, NULL)) 57 | { 58 | pkcs11_logger_log("Unable to create lock"); 59 | goto end; 60 | } 61 | 62 | #endif 63 | 64 | rv = PKCS11_LOGGER_RV_SUCCESS; 65 | 66 | end: 67 | 68 | return rv; 69 | } 70 | 71 | 72 | // Acquires lock for log file access synchronization 73 | void pkcs11_logger_lock_acquire(void) 74 | { 75 | #ifdef _WIN32 76 | 77 | if (NULL == pkcs11_logger_lock) 78 | return; 79 | 80 | if (WAIT_OBJECT_0 != WaitForSingleObject(pkcs11_logger_lock, INFINITE)) 81 | pkcs11_logger_log("Unable to get lock ownership"); 82 | 83 | #else 84 | 85 | if (0 != pthread_mutex_lock(&pkcs11_logger_lock)) 86 | pkcs11_logger_log("Unable to get lock ownership"); 87 | 88 | #endif 89 | } 90 | 91 | 92 | // Releases lock for log file access synchronization 93 | void pkcs11_logger_lock_release(void) 94 | { 95 | #ifdef _WIN32 96 | 97 | if (NULL == pkcs11_logger_lock) 98 | return; 99 | 100 | if (!ReleaseMutex(pkcs11_logger_lock)) 101 | pkcs11_logger_log("Unable to release lock ownership"); 102 | 103 | #else 104 | 105 | if (0 != pthread_mutex_unlock(&pkcs11_logger_lock)) 106 | pkcs11_logger_log("Unable to release lock ownership"); 107 | 108 | #endif 109 | } 110 | 111 | 112 | // Destroys lock for log file access synchronization 113 | void pkcs11_logger_lock_destroy(void) 114 | { 115 | #ifdef _WIN32 116 | 117 | CALL_N_CLEAR(CloseHandle, pkcs11_logger_lock); 118 | 119 | #else 120 | 121 | pthread_mutex_destroy(&pkcs11_logger_lock); 122 | 123 | #endif 124 | } 125 | -------------------------------------------------------------------------------- /src/log.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2025 The Pkcs11Interop Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Written for the Pkcs11Interop project by: 19 | * Jaroslav IMRICH 20 | */ 21 | 22 | 23 | #include "pkcs11-logger.h" 24 | 25 | 26 | extern PKCS11_LOGGER_GLOBALS pkcs11_logger_globals; 27 | 28 | 29 | // Logs message 30 | void pkcs11_logger_log(const char* message, ...) 31 | { 32 | va_list ap; 33 | 34 | unsigned long disable_log_file = ((pkcs11_logger_globals.flags & PKCS11_LOGGER_FLAG_DISABLE_LOG_FILE) == PKCS11_LOGGER_FLAG_DISABLE_LOG_FILE); 35 | unsigned long disable_process_id = ((pkcs11_logger_globals.flags & PKCS11_LOGGER_FLAG_DISABLE_PROCESS_ID) == PKCS11_LOGGER_FLAG_DISABLE_PROCESS_ID); 36 | unsigned long disable_thread_id = ((pkcs11_logger_globals.flags & PKCS11_LOGGER_FLAG_DISABLE_THREAD_ID) == PKCS11_LOGGER_FLAG_DISABLE_THREAD_ID); 37 | unsigned long enable_stdout = ((pkcs11_logger_globals.flags & PKCS11_LOGGER_FLAG_ENABLE_STDOUT) == PKCS11_LOGGER_FLAG_ENABLE_STDOUT); 38 | unsigned long enable_stderr = ((pkcs11_logger_globals.flags & PKCS11_LOGGER_FLAG_ENABLE_STDERR) == PKCS11_LOGGER_FLAG_ENABLE_STDERR); 39 | unsigned long enable_fclose = ((pkcs11_logger_globals.flags & PKCS11_LOGGER_FLAG_ENABLE_FCLOSE) == PKCS11_LOGGER_FLAG_ENABLE_FCLOSE); 40 | 41 | // Acquire exclusive access to the file 42 | pkcs11_logger_lock_acquire(); 43 | 44 | #ifdef _WIN32 45 | #pragma warning(push) 46 | #pragma warning(disable: 4996) 47 | #endif 48 | 49 | // Open log file 50 | if ((!disable_log_file) && (NULL != pkcs11_logger_globals.env_var_log_file_path) && (NULL == pkcs11_logger_globals.log_file_handle)) 51 | { 52 | pkcs11_logger_globals.log_file_handle = fopen((const char *)pkcs11_logger_globals.env_var_log_file_path, "a"); 53 | } 54 | 55 | #ifdef _WIN32 56 | #pragma warning(pop) 57 | #endif 58 | 59 | // Log to file 60 | if ((!disable_log_file) && (NULL != pkcs11_logger_globals.log_file_handle)) 61 | { 62 | va_start(ap, message); 63 | 64 | if (!disable_process_id) 65 | fprintf(pkcs11_logger_globals.log_file_handle, "%0#10x : ", pkcs11_logger_utils_get_process_id()); 66 | if (!disable_thread_id) 67 | fprintf(pkcs11_logger_globals.log_file_handle, "%0#18lx : ", pkcs11_logger_utils_get_thread_id()); 68 | vfprintf(pkcs11_logger_globals.log_file_handle, message, ap); 69 | fprintf(pkcs11_logger_globals.log_file_handle, "\n"); 70 | 71 | va_end(ap); 72 | } 73 | 74 | // Log to stdout 75 | if (enable_stdout) 76 | { 77 | va_start(ap, message); 78 | 79 | if (!disable_process_id) 80 | fprintf(stdout, "%0#10x : ", pkcs11_logger_utils_get_process_id()); 81 | if (!disable_thread_id) 82 | fprintf(stdout, "%0#18lx : ", pkcs11_logger_utils_get_thread_id()); 83 | vfprintf(stdout, message, ap); 84 | fprintf(stdout, "\n"); 85 | 86 | va_end(ap); 87 | } 88 | 89 | // Log to stderr 90 | if (enable_stderr || CK_FALSE == pkcs11_logger_globals.env_vars_read) 91 | { 92 | va_start(ap, message); 93 | 94 | if (!disable_process_id) 95 | fprintf(stderr, "%0#10x : ", pkcs11_logger_utils_get_process_id()); 96 | if (!disable_thread_id) 97 | fprintf(stderr, "%0#18lx : ", pkcs11_logger_utils_get_thread_id()); 98 | vfprintf(stderr, message, ap); 99 | fprintf(stderr, "\n"); 100 | 101 | va_end(ap); 102 | } 103 | 104 | // Cleanup 105 | if (enable_fclose) 106 | { 107 | CALL_N_CLEAR(fclose, pkcs11_logger_globals.log_file_handle); 108 | } 109 | else 110 | { 111 | if (NULL != pkcs11_logger_globals.log_file_handle) 112 | fflush(pkcs11_logger_globals.log_file_handle); 113 | } 114 | 115 | // Release exclusive access to the file 116 | pkcs11_logger_lock_release(); 117 | } 118 | 119 | 120 | // Logs message with prepended timestamp 121 | void pkcs11_logger_log_with_timestamp(const char* message, ...) 122 | { 123 | char* message_string = NULL; 124 | int message_string_len = 0; 125 | 126 | va_list ap; 127 | va_start(ap, message); 128 | message_string_len = vsnprintf(NULL, 0, message, ap); 129 | va_end(ap); 130 | 131 | message_string = (char*) malloc(message_string_len + 1); 132 | if (NULL == message_string) 133 | return; 134 | 135 | memset(message_string, 0, message_string_len + 1); 136 | 137 | va_start(ap, message); 138 | vsnprintf(message_string, message_string_len + 1, message, ap); 139 | va_end(ap); 140 | 141 | char time_string[27]; 142 | pkcs11_logger_utils_get_current_time_str(time_string, sizeof(time_string)); 143 | 144 | pkcs11_logger_log("%s - %s", time_string, message_string); 145 | 146 | CALL_N_CLEAR(free, message_string); 147 | } 148 | 149 | 150 | // Logs separator line 151 | void pkcs11_logger_log_separator(void) 152 | { 153 | pkcs11_logger_log("******************************************************************************************************************************"); 154 | } 155 | 156 | 157 | // Logs entry into logger function 158 | void pkcs11_logger_log_function_enter(const char *function) 159 | { 160 | pkcs11_logger_log_separator(); 161 | pkcs11_logger_log_with_timestamp("Entered %s", function); 162 | } 163 | 164 | 165 | // Logs exit from logger function 166 | void pkcs11_logger_log_function_exit(CK_RV rv) 167 | { 168 | pkcs11_logger_log_with_timestamp("Returning %lu (%s)", rv, pkcs11_logger_translate_ck_rv(rv)); 169 | } 170 | 171 | 172 | // Logs input params notice 173 | void pkcs11_logger_log_input_params(void) 174 | { 175 | pkcs11_logger_log("Input"); 176 | } 177 | 178 | 179 | // Logs entry into original function 180 | void pkcs11_logger_log_orig_function_enter(const char* function) 181 | { 182 | pkcs11_logger_log_with_timestamp("Calling %s", function); 183 | } 184 | 185 | 186 | // Logs exit from original function 187 | void pkcs11_logger_log_orig_function_exit(const char* function) 188 | { 189 | pkcs11_logger_log_with_timestamp("Received response from %s", function); 190 | } 191 | 192 | 193 | // Logs output params notice 194 | void pkcs11_logger_log_output_params(void) 195 | { 196 | pkcs11_logger_log("Output"); 197 | } 198 | 199 | 200 | // Logs flag 201 | void pkcs11_logger_log_flag(CK_ULONG flags, CK_ULONG flag_value, const char *flag_name) 202 | { 203 | if (flags & flag_value) 204 | pkcs11_logger_log("%s: TRUE", flag_name); 205 | else 206 | pkcs11_logger_log("%s: FALSE", flag_name); 207 | } 208 | 209 | 210 | // Logs string that is not zero terminated 211 | void pkcs11_logger_log_nonzero_string(const char *name, const CK_UTF8CHAR_PTR nonzero_string, CK_ULONG nonzero_string_len) 212 | { 213 | if (NULL != nonzero_string) 214 | { 215 | unsigned char *zero_string = NULL; 216 | zero_string = (unsigned char*) malloc(nonzero_string_len + 1); 217 | if (NULL != zero_string) 218 | { 219 | memset(zero_string, 0, nonzero_string_len + 1); 220 | memcpy(zero_string, nonzero_string, nonzero_string_len); 221 | pkcs11_logger_log("%s: %s", name, zero_string); 222 | CALL_N_CLEAR(free, zero_string); 223 | } 224 | else 225 | { 226 | pkcs11_logger_log("%s: *** cannot be displayed ***", name); 227 | } 228 | } 229 | } 230 | 231 | 232 | // Logs byte array 233 | void pkcs11_logger_log_byte_array(const char *name, CK_BYTE_PTR byte_array, CK_ULONG byte_array_len) 234 | { 235 | if (NULL != byte_array) 236 | { 237 | char *array = NULL; 238 | array = pkcs11_logger_translate_ck_byte_ptr(byte_array, byte_array_len); 239 | if (NULL != array) 240 | { 241 | pkcs11_logger_log("%s: HEX(%s)", name, array); 242 | CALL_N_CLEAR(free, array); 243 | } 244 | else 245 | { 246 | pkcs11_logger_log("%s: *** cannot be displayed ***", name); 247 | } 248 | } 249 | } 250 | 251 | 252 | // Logs array of cryptoki attributes 253 | void pkcs11_logger_log_attribute_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) 254 | { 255 | CK_ULONG i = 0; 256 | 257 | if ((NULL == pTemplate) || (ulCount < 1)) 258 | return; 259 | 260 | pkcs11_logger_log(" *** Begin attribute template ***"); 261 | 262 | for (i = 0; i < ulCount; i++) 263 | { 264 | pkcs11_logger_log(" Attribute %d", i); 265 | pkcs11_logger_log(" Attribute: %lu (%s)", pTemplate[i].type, pkcs11_logger_translate_ck_attribute(pTemplate[i].type)); 266 | pkcs11_logger_log(" pValue: %p", pTemplate[i].pValue); 267 | pkcs11_logger_log(" ulValueLen: %lu", pTemplate[i].ulValueLen); 268 | 269 | if ((-1 != (CK_LONG) pTemplate[i].ulValueLen) && (NULL != pTemplate[i].pValue)) 270 | { 271 | char *value = NULL; 272 | 273 | if ((pTemplate[i].type & CKF_ARRAY_ATTRIBUTE) == CKF_ARRAY_ATTRIBUTE) 274 | { 275 | if (0 == (pTemplate[i].ulValueLen % sizeof(CK_ATTRIBUTE))) 276 | { 277 | pkcs11_logger_log_attribute_template(pTemplate[i].pValue, pTemplate[i].ulValueLen / sizeof(CK_ATTRIBUTE)); 278 | continue; 279 | } 280 | } 281 | 282 | value = pkcs11_logger_translate_ck_byte_ptr(pTemplate[i].pValue, pTemplate[i].ulValueLen); 283 | if (NULL != value) 284 | { 285 | pkcs11_logger_log(" *pValue: HEX(%s)", value); 286 | CALL_N_CLEAR(free, value); 287 | } 288 | else 289 | { 290 | pkcs11_logger_log(" *pValue: *** cannot be displayed ***"); 291 | } 292 | } 293 | } 294 | 295 | pkcs11_logger_log(" *** End attribute template ***"); 296 | } 297 | -------------------------------------------------------------------------------- /src/pkcs11-logger.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2025 The Pkcs11Interop Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Written for the Pkcs11Interop project by: 19 | * Jaroslav IMRICH 20 | */ 21 | 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | 30 | #ifdef _WIN32 31 | 32 | 33 | #include 34 | #include 35 | 36 | // PKCS#11 related stuff 37 | #pragma pack(push, cryptoki, 1) 38 | 39 | #define CK_IMPORT_SPEC __declspec(dllimport) 40 | 41 | #ifdef CRYPTOKI_EXPORTS 42 | #define CK_EXPORT_SPEC __declspec(dllexport) 43 | #else 44 | #define CK_EXPORT_SPEC CK_IMPORT_SPEC 45 | #endif 46 | 47 | #define CK_CALL_SPEC __cdecl 48 | 49 | #define CK_PTR * 50 | #define CK_DEFINE_FUNCTION(returnType, name) returnType CK_EXPORT_SPEC CK_CALL_SPEC name 51 | #define CK_DECLARE_FUNCTION(returnType, name) returnType CK_EXPORT_SPEC CK_CALL_SPEC name 52 | #define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name) 53 | #define CK_CALLBACK_FUNCTION(returnType, name) returnType (CK_CALL_SPEC CK_PTR name) 54 | 55 | #ifndef NULL_PTR 56 | #define NULL_PTR 0 57 | #endif 58 | 59 | #include 60 | 61 | #pragma pack(pop, cryptoki) 62 | 63 | // Platform dependend type for dynamically loaded library handle 64 | typedef HMODULE DLHANDLE; 65 | 66 | 67 | #else // #ifdef _WIN32 68 | 69 | 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include 76 | 77 | // PKCS#11 related stuff 78 | #define CK_PTR * 79 | #define CK_DEFINE_FUNCTION(returnType, name) returnType name 80 | #define CK_DECLARE_FUNCTION(returnType, name) returnType name 81 | #define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name) 82 | #define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name) 83 | 84 | #ifndef NULL_PTR 85 | #define NULL_PTR 0 86 | #endif 87 | 88 | #include 89 | 90 | // Platform dependend type for dynamically loaded library handle 91 | typedef void* DLHANDLE; 92 | 93 | 94 | #endif // #ifdef _WIN32 95 | 96 | 97 | // Structure that holds global variables 98 | typedef struct 99 | { 100 | // Handle to original PKCS#11 library 101 | DLHANDLE orig_lib_handle; 102 | // Pointers to all cryptoki functions in original PKCS#11 library 103 | CK_FUNCTION_LIST_PTR orig_lib_functions; 104 | // Pointers to all cryptoki functions in PKCS11-LOGGER library 105 | CK_FUNCTION_LIST logger_functions; 106 | // Flag indicating whether environment variables has been successfully read 107 | CK_BBOOL env_vars_read; 108 | // Value of PKCS11_LOGGER_LIBRARY_PATH environment variable 109 | CK_CHAR_PTR env_var_library_path; 110 | // Value of PKCS11_LOGGER_LOG_FILE_PATH environment variable 111 | CK_CHAR_PTR env_var_log_file_path; 112 | // Value of PKCS11_LOGGER_FLAGS environment variable 113 | CK_CHAR_PTR env_var_flags; 114 | // Value of PKCS11_LOGGER_FLAGS environment variable 115 | CK_ULONG flags; 116 | // Handle to log file 117 | FILE *log_file_handle; 118 | } 119 | PKCS11_LOGGER_GLOBALS; 120 | 121 | 122 | // Environment variable that specifies path to the original PKCS#11 library 123 | #define PKCS11_LOGGER_LIBRARY_PATH "PKCS11_LOGGER_LIBRARY_PATH" 124 | // Environment variable that specifies path to the log file 125 | #define PKCS11_LOGGER_LOG_FILE_PATH "PKCS11_LOGGER_LOG_FILE_PATH" 126 | // Environment variable that specifies pkcs11-logger flags 127 | #define PKCS11_LOGGER_FLAGS "PKCS11_LOGGER_FLAGS" 128 | 129 | // Flag that disables logging into the log file 130 | #define PKCS11_LOGGER_FLAG_DISABLE_LOG_FILE 0x00000001 131 | // Flag that disables logging of process ID 132 | #define PKCS11_LOGGER_FLAG_DISABLE_PROCESS_ID 0x00000002 133 | // Flag that disables logging of thread ID 134 | #define PKCS11_LOGGER_FLAG_DISABLE_THREAD_ID 0x00000004 135 | // Flag that enables logging of PINs 136 | #define PKCS11_LOGGER_FLAG_ENABLE_PIN 0x00000008 137 | // Flag that enables logging to the stdout 138 | #define PKCS11_LOGGER_FLAG_ENABLE_STDOUT 0x00000010 139 | // Flag that enables logging to the stderr 140 | #define PKCS11_LOGGER_FLAG_ENABLE_STDERR 0x00000020 141 | // Flag that enables reopening of log file 142 | #define PKCS11_LOGGER_FLAG_ENABLE_FCLOSE 0x00000040 143 | 144 | // Library name 145 | #define PKCS11_LOGGER_NAME "PKCS11-LOGGER" 146 | // Library version 147 | #define PKCS11_LOGGER_VERSION "2.3.0" 148 | // Library description 149 | #define PKCS11_LOGGER_DESCRIPTION "PKCS#11 logging proxy module" 150 | 151 | // Return value indicating success 152 | #define PKCS11_LOGGER_RV_SUCCESS 1 153 | // Return value indicating error 154 | #define PKCS11_LOGGER_RV_ERROR -1 155 | 156 | // Macro for safe resource clearing 157 | #define CALL_N_CLEAR(function, pointer) if (NULL != pointer) { function(pointer); pointer = NULL; } 158 | // Macro for safe initialization of original PKCS#11 library 159 | #define SAFELY_INIT_ORIG_LIB_OR_FAIL() if (pkcs11_logger_init_orig_lib() != PKCS11_LOGGER_RV_SUCCESS) return CKR_GENERAL_ERROR; 160 | // Macro that removes unused argument warning 161 | #define IGNORE_ARG(P) (void)(P) 162 | 163 | // dl.c - declaration of functions 164 | DLHANDLE pkcs11_logger_dl_open(const char* library); 165 | void* pkcs11_logger_dl_sym(DLHANDLE library, const char* function); 166 | int pkcs11_logger_dl_close(DLHANDLE library); 167 | 168 | // init.c - declaration of functions 169 | #ifdef _WIN32 170 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved); 171 | #else 172 | __attribute__((constructor)) void pkcs11_logger_init_entry_point(void); 173 | __attribute__((destructor)) void pkcs11_logger_init_exit_point(void); 174 | #endif 175 | void pkcs11_logger_init_globals(void); 176 | int pkcs11_logger_init_orig_lib(void); 177 | int pkcs11_logger_init_parse_env_vars(void); 178 | CK_CHAR_PTR pkcs11_logger_init_read_env_var(const char *env_var_name); 179 | 180 | // lock.c - declaration of functions 181 | int pkcs11_logger_lock_create(void); 182 | void pkcs11_logger_lock_acquire(void); 183 | void pkcs11_logger_lock_release(void); 184 | void pkcs11_logger_lock_destroy(void); 185 | 186 | // log.c - declaration of functions 187 | void pkcs11_logger_log(const char* message, ...); 188 | void pkcs11_logger_log_with_timestamp(const char* message, ...); 189 | void pkcs11_logger_log_separator(void); 190 | void pkcs11_logger_log_function_enter(const char *function); 191 | void pkcs11_logger_log_function_exit(CK_RV rv); 192 | void pkcs11_logger_log_input_params(void); 193 | void pkcs11_logger_log_orig_function_enter(const char* function); 194 | void pkcs11_logger_log_orig_function_exit(const char* function); 195 | void pkcs11_logger_log_output_params(void); 196 | void pkcs11_logger_log_flag(CK_ULONG flags, CK_ULONG flag_value, const char *flag_name); 197 | void pkcs11_logger_log_nonzero_string(const char *name, const CK_UTF8CHAR_PTR nonzero_string, CK_ULONG nonzero_string_len); 198 | void pkcs11_logger_log_byte_array(const char *name, CK_BYTE_PTR byte_array, CK_ULONG byte_array_len); 199 | void pkcs11_logger_log_attribute_template(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); 200 | 201 | // translate.c - declaration of functions 202 | const char* pkcs11_logger_translate_ck_rv(CK_RV rv); 203 | const char* pkcs11_logger_translate_ck_mechanism_type(CK_MECHANISM_TYPE type); 204 | const char* pkcs11_logger_translate_ck_user_type(CK_USER_TYPE type); 205 | const char* pkcs11_logger_translate_ck_state(CK_STATE state); 206 | char* pkcs11_logger_translate_ck_byte_ptr(CK_BYTE_PTR bytes, CK_ULONG length); 207 | const char* pkcs11_logger_translate_ck_attribute(CK_ATTRIBUTE_TYPE type); 208 | 209 | // utils.c - declaration of functions 210 | int pkcs11_logger_utils_str_to_long(const char *str, unsigned long *val); 211 | void pkcs11_logger_utils_get_current_time_str(char* buff, int buff_len); 212 | unsigned long pkcs11_logger_utils_get_thread_id(void); 213 | int pkcs11_logger_utils_get_process_id(void); 214 | CK_BBOOL pkcs11_logger_utils_path_is_absolute(const char* path); 215 | -------------------------------------------------------------------------------- /src/utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2025 The Pkcs11Interop Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Written for the Pkcs11Interop project by: 19 | * Jaroslav IMRICH 20 | */ 21 | 22 | 23 | #include "pkcs11-logger.h" 24 | 25 | 26 | // Converts string to long 27 | int pkcs11_logger_utils_str_to_long(const char *str, unsigned long *val) 28 | { 29 | unsigned long output = 0; 30 | char *endptr = NULL; 31 | 32 | if ((NULL == str) || (NULL == val)) 33 | return PKCS11_LOGGER_RV_ERROR; 34 | 35 | errno = 0; 36 | output = strtoul(str, &endptr, 10); 37 | if ((0 != errno) || ('\0' != *endptr)) 38 | return PKCS11_LOGGER_RV_ERROR; 39 | 40 | *val = output; 41 | 42 | return PKCS11_LOGGER_RV_SUCCESS; 43 | } 44 | 45 | 46 | // Gets current system time as string 47 | void pkcs11_logger_utils_get_current_time_str(char* buff, int buff_len) 48 | { 49 | if (buff_len < 27) 50 | return; 51 | 52 | #ifdef _WIN32 53 | 54 | SYSTEMTIME systemtime; 55 | memset(&systemtime, 0, sizeof(SYSTEMTIME)); 56 | 57 | memset(buff, 0, buff_len * sizeof(char)); 58 | 59 | GetLocalTime(&systemtime); 60 | GetDateFormatA(LOCALE_SYSTEM_DEFAULT, 0, &systemtime, "yyyy-MM-dd ", buff, buff_len); 61 | GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &systemtime, "HH:mm:ss", buff + 11, buff_len - 11); 62 | 63 | size_t len = strlen(buff); 64 | snprintf(buff + len, buff_len - len, ".%03d000", systemtime.wMilliseconds); 65 | 66 | #else 67 | 68 | struct timeval tv; 69 | struct tm tm; 70 | 71 | memset(buff, 0, buff_len * sizeof(char)); 72 | 73 | if (gettimeofday(&tv, NULL) == 0) 74 | { 75 | if (localtime_r(&tv.tv_sec, &tm) != NULL) 76 | { 77 | strftime(buff, buff_len, "%Y-%m-%d %H:%M:%S", &tm); 78 | 79 | #ifdef __APPLE__ 80 | size_t len = strlen(buff); 81 | snprintf(buff + len, buff_len - len, ".%06d", tv.tv_usec); 82 | #else 83 | size_t len = strlen(buff); 84 | snprintf(buff + len, buff_len - len, ".%06ld", tv.tv_usec); 85 | #endif 86 | } 87 | } 88 | 89 | #endif 90 | } 91 | 92 | 93 | // Gets ID of current thread 94 | unsigned long pkcs11_logger_utils_get_thread_id(void) 95 | { 96 | #ifdef _WIN32 97 | return GetCurrentThreadId(); 98 | #else 99 | #ifdef __APPLE__ 100 | uint64_t tid = 0; 101 | pthread_threadid_np(NULL, &tid); 102 | return tid; 103 | #else 104 | return pthread_self(); 105 | #endif 106 | #endif 107 | } 108 | 109 | 110 | // Gets ID of current process 111 | int pkcs11_logger_utils_get_process_id(void) 112 | { 113 | #ifdef _WIN32 114 | return _getpid(); 115 | #else 116 | return getpid(); 117 | #endif 118 | } 119 | 120 | 121 | // Determines whether the path is absolute 122 | CK_BBOOL pkcs11_logger_utils_path_is_absolute(const char* path) 123 | { 124 | #ifdef _WIN32 125 | if ((NULL == path) || (strlen(path) < 3)) 126 | return CK_FALSE; 127 | 128 | char char1 = path[0]; 129 | char char2 = path[1]; 130 | char char3 = path[2]; 131 | 132 | // First character must be valid drive character 133 | if ((char1 < 'A' || char1 > 'Z') && (char1 < 'a' || char1 > 'z')) 134 | return CK_FALSE; 135 | 136 | // Second character must be valid volume separator character 137 | if (char2 != ':') 138 | return CK_FALSE; 139 | 140 | // Third character must be valid directory separator character 141 | if (char3 != '\\' && char3 != '/') 142 | return CK_FALSE; 143 | 144 | return CK_TRUE; 145 | #else 146 | if ((NULL == path) || (strlen(path) < 1)) 147 | return CK_FALSE; 148 | 149 | return (path[0] == '/') ? CK_TRUE : CK_FALSE; 150 | #endif 151 | } 152 | -------------------------------------------------------------------------------- /test/Pkcs11LoggerTests.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.32126.317 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pkcs11LoggerTests", "Pkcs11LoggerTests\Pkcs11LoggerTests.csproj", "{1474EB46-C623-4E08-9BA1-E7016CC988F8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {1474EB46-C623-4E08-9BA1-E7016CC988F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {1474EB46-C623-4E08-9BA1-E7016CC988F8}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {1474EB46-C623-4E08-9BA1-E7016CC988F8}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {1474EB46-C623-4E08-9BA1-E7016CC988F8}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {E7CB3F7C-43CC-4B42-B25C-279C1BCF6FFD} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /test/Pkcs11LoggerTests/BasicPkcs11LoggerTests.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2025 The Pkcs11Interop Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Written for the Pkcs11Interop project by: 19 | * Jaroslav IMRICH 20 | */ 21 | 22 | using System; 23 | using System.IO; 24 | using Net.Pkcs11Interop.Common; 25 | using Net.Pkcs11Interop.HighLevelAPI; 26 | using NUnit.Framework; 27 | using NUnit.Framework.Legacy; 28 | 29 | namespace Pkcs11Logger.Tests 30 | { 31 | /// 32 | /// Basic tests for PKCS11-LOGGER library 33 | /// 34 | [TestFixture()] 35 | public class BasicPkcs11LoggerTests 36 | { 37 | #region Imports from PKCS11-LOGGER 38 | 39 | /// 40 | /// Environment variable that specifies path to the original PKCS#11 library 41 | /// 42 | public const string PKCS11_LOGGER_LIBRARY_PATH = "PKCS11_LOGGER_LIBRARY_PATH"; 43 | 44 | /// 45 | /// Environment variable that specifies path to the log file 46 | /// 47 | public const string PKCS11_LOGGER_LOG_FILE_PATH = "PKCS11_LOGGER_LOG_FILE_PATH"; 48 | 49 | /// 50 | /// Environment variable that specifies pkcs11-logger flags 51 | /// 52 | public const string PKCS11_LOGGER_FLAGS = "PKCS11_LOGGER_FLAGS"; 53 | 54 | /// 55 | /// Flag that disables logging into the log file 56 | /// 57 | public const uint PKCS11_LOGGER_FLAG_DISABLE_LOG_FILE = 0x00000001; 58 | 59 | /// 60 | /// Flag that disables logging of process ID 61 | /// 62 | public const uint PKCS11_LOGGER_FLAG_DISABLE_PROCESS_ID = 0x00000002; 63 | 64 | /// 65 | /// Flag that disables logging of thread ID 66 | /// 67 | public const uint PKCS11_LOGGER_FLAG_DISABLE_THREAD_ID = 0x00000004; 68 | 69 | /// 70 | /// Flag that enables logging of PINs 71 | /// 72 | public const uint PKCS11_LOGGER_FLAG_ENABLE_PIN = 0x00000008; 73 | 74 | /// 75 | /// Flag that enables logging to the stdout 76 | /// 77 | public const uint PKCS11_LOGGER_FLAG_ENABLE_STDOUT = 0x00000010; 78 | 79 | /// 80 | /// Flag that enables logging to the stderr 81 | /// 82 | public const uint PKCS11_LOGGER_FLAG_ENABLE_STDERR = 0x00000020; 83 | 84 | /// 85 | /// Flag that enables reopening of log file 86 | /// 87 | public const uint PKCS11_LOGGER_FLAG_ENABLE_FCLOSE = 0x00000040; 88 | 89 | #endregion 90 | 91 | /// 92 | /// Deletes environment variables used by PKCS11-LOGGER library 93 | /// 94 | private void DeleteEnvironmentVariables() 95 | { 96 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, null); 97 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, null); 98 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, null); 99 | } 100 | 101 | /// 102 | /// Test environment variable processing 103 | /// 104 | [Test()] 105 | public void EnvironmentVariableProcessingTest() 106 | { 107 | DeleteEnvironmentVariables(); 108 | 109 | // PKCS11_LOGGER_LIBRARY_PATH is required 110 | try 111 | { 112 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, null); 113 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, null); 114 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, null); 115 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 116 | pkcs11Library.GetInfo(); 117 | 118 | Assert.Fail("Exception expected but not thrown"); 119 | } 120 | catch (Exception ex) 121 | { 122 | ClassicAssert.IsTrue(ex is Pkcs11Exception); 123 | ClassicAssert.IsTrue(((Pkcs11Exception)ex).RV == CKR.CKR_GENERAL_ERROR); 124 | } 125 | 126 | // PKCS11_LOGGER_LOG_FILE_PATH and PKCS11_LOGGER_FLAGS are optional 127 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 128 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, null); 129 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, null); 130 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 131 | pkcs11Library.GetInfo(); 132 | 133 | // PKCS11_LOGGER_LIBRARY_PATH has to be provided without enclosing quotes 134 | try 135 | { 136 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, "\"" + Settings.Pkcs11LibraryPath + "\""); 137 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, null); 138 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, null); 139 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 140 | pkcs11Library.GetInfo(); 141 | 142 | Assert.Fail("Exception expected but not thrown"); 143 | } 144 | catch (Exception ex) 145 | { 146 | ClassicAssert.IsTrue(ex is Pkcs11Exception); 147 | ClassicAssert.IsTrue(((Pkcs11Exception)ex).RV == CKR.CKR_GENERAL_ERROR); 148 | } 149 | 150 | // PKCS11_LOGGER_LOG_FILE_PATH has to be provided without enclosing quotes 151 | try 152 | { 153 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 154 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, "\"" + Settings.Pkcs11LoggerLogPath1 + "\""); 155 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, null); 156 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 157 | pkcs11Library.GetInfo(); 158 | 159 | Assert.Fail("Exception expected but not thrown"); 160 | } 161 | catch (Exception ex) 162 | { 163 | ClassicAssert.IsTrue(ex is Pkcs11Exception); 164 | ClassicAssert.IsTrue(((Pkcs11Exception)ex).RV == CKR.CKR_GENERAL_ERROR); 165 | } 166 | 167 | // PKCS11_LOGGER_FLAGS must contain a number 168 | try 169 | { 170 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 171 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 172 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, "InvalidValue"); 173 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 174 | pkcs11Library.GetInfo(); 175 | 176 | Assert.Fail("Exception expected but not thrown"); 177 | } 178 | catch (Exception ex) 179 | { 180 | ClassicAssert.IsTrue(ex is Pkcs11Exception); 181 | ClassicAssert.IsTrue(((Pkcs11Exception)ex).RV == CKR.CKR_GENERAL_ERROR); 182 | } 183 | } 184 | 185 | /// 186 | /// Test PKCS11_LOGGER_LIBRARY_PATH environment variable 187 | /// 188 | [Test()] 189 | public void LibraryPathTest() 190 | { 191 | DeleteEnvironmentVariables(); 192 | 193 | // Delete log file 194 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 195 | File.Delete(Settings.Pkcs11LoggerLogPath1); 196 | 197 | // Existing PKCS#11 library path should work 198 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 199 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 200 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 201 | pkcs11Library.GetInfo(); 202 | 203 | // Check whether Pkcs11LoggerLogPath1 exists 204 | if (!File.Exists(Settings.Pkcs11LoggerLogPath1)) 205 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath1 + " does not exist"); 206 | 207 | // Non-existing PKCS#11 library path should not work 208 | try 209 | { 210 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, @"NonExistingLibrary.dll"); 211 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 212 | pkcs11Library.GetInfo(); 213 | 214 | Assert.Fail("Exception expected but not thrown"); 215 | } 216 | catch (Exception ex) 217 | { 218 | ClassicAssert.IsTrue(ex is Pkcs11Exception); 219 | ClassicAssert.IsTrue(((Pkcs11Exception)ex).RV == CKR.CKR_GENERAL_ERROR); 220 | } 221 | 222 | // Unspecified PKCS#11 library should not work 223 | try 224 | { 225 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, null); 226 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 227 | pkcs11Library.GetInfo(); 228 | 229 | Assert.Fail("Exception expected but not thrown"); 230 | } 231 | catch (Exception ex) 232 | { 233 | ClassicAssert.IsTrue(ex is Pkcs11Exception); 234 | ClassicAssert.IsTrue(((Pkcs11Exception)ex).RV == CKR.CKR_GENERAL_ERROR); 235 | } 236 | } 237 | 238 | /// 239 | /// Test PKCS11_LOGGER_LOG_FILE_PATH environment variable 240 | /// 241 | [Test()] 242 | public void LogFilePathTest() 243 | { 244 | DeleteEnvironmentVariables(); 245 | 246 | // Delete log files 247 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 248 | File.Delete(Settings.Pkcs11LoggerLogPath1); 249 | if (File.Exists(Settings.Pkcs11LoggerLogPath2)) 250 | File.Delete(Settings.Pkcs11LoggerLogPath2); 251 | 252 | // Log to Pkcs11LoggerLogPath1 253 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 254 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 255 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 256 | pkcs11Library.GetInfo(); 257 | 258 | // Check whether Pkcs11LoggerLogPath1 exists 259 | if (!File.Exists(Settings.Pkcs11LoggerLogPath1)) 260 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath1 + " does not exist"); 261 | if (File.Exists(Settings.Pkcs11LoggerLogPath2)) 262 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath2 + " exists"); 263 | 264 | // Delete log files 265 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 266 | File.Delete(Settings.Pkcs11LoggerLogPath1); 267 | if (File.Exists(Settings.Pkcs11LoggerLogPath2)) 268 | File.Delete(Settings.Pkcs11LoggerLogPath2); 269 | 270 | // Log to Pkcs11LoggerLogPath2 271 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath2); 272 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 273 | pkcs11Library.GetInfo(); 274 | 275 | // Check whether Pkcs11LoggerLogPath2 exists 276 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 277 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath1 + " exists"); 278 | if (!File.Exists(Settings.Pkcs11LoggerLogPath2)) 279 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath2 + " does not exist"); 280 | 281 | // Delete log files 282 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 283 | File.Delete(Settings.Pkcs11LoggerLogPath1); 284 | if (File.Exists(Settings.Pkcs11LoggerLogPath2)) 285 | File.Delete(Settings.Pkcs11LoggerLogPath2); 286 | 287 | // Settings.LogFilePath may also be null 288 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, null); 289 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 290 | pkcs11Library.GetInfo(); 291 | 292 | // Check whether Pkcs11LoggerLogPath1 exists 293 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 294 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath1 + " exists"); 295 | if (File.Exists(Settings.Pkcs11LoggerLogPath2)) 296 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath2 + " exists"); 297 | } 298 | 299 | /// 300 | /// Test PKCS11_LOGGER_FLAG_DISABLE_LOG_FILE flag 301 | /// 302 | [Test()] 303 | public void DisableLogFileTest() 304 | { 305 | DeleteEnvironmentVariables(); 306 | 307 | uint flags = 0; 308 | 309 | // Delete log file 310 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 311 | File.Delete(Settings.Pkcs11LoggerLogPath1); 312 | 313 | // Log to Pkcs11LoggerLogPath1 with disabled log file 314 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 315 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 316 | flags = flags | PKCS11_LOGGER_FLAG_DISABLE_LOG_FILE; 317 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 318 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 319 | pkcs11Library.GetInfo(); 320 | 321 | // Check whether Pkcs11LoggerLogPath1 exists 322 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 323 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath1 + " exists"); 324 | 325 | // Log to Pkcs11LoggerLogPath1 with enabled log file 326 | flags = flags & ~PKCS11_LOGGER_FLAG_DISABLE_LOG_FILE; 327 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 328 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 329 | pkcs11Library.GetInfo(); 330 | 331 | // Check whether Pkcs11LoggerLogPath1 exists 332 | if (!File.Exists(Settings.Pkcs11LoggerLogPath1)) 333 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath1 + " does not exist"); 334 | } 335 | 336 | /// 337 | /// Test PKCS11_LOGGER_FLAG_DISABLE_PROCESS_ID and PKCS11_LOGGER_FLAG_DISABLE_THREAD_ID flags 338 | /// 339 | [Test()] 340 | public void DisableProcessIdAndThreadIdTest() 341 | { 342 | DeleteEnvironmentVariables(); 343 | 344 | uint flags = 0; 345 | 346 | // Delete log file 347 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 348 | File.Delete(Settings.Pkcs11LoggerLogPath1); 349 | 350 | // Log to Pkcs11LoggerLogPath1 with both IDs enabled 351 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 352 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 353 | flags = flags & ~PKCS11_LOGGER_FLAG_DISABLE_PROCESS_ID; 354 | flags = flags & ~PKCS11_LOGGER_FLAG_DISABLE_THREAD_ID; 355 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 356 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 357 | pkcs11Library.GetInfo(); 358 | 359 | // Read first line from the log file 360 | string line = null; 361 | using (StreamReader reader = new StreamReader(Settings.Pkcs11LoggerLogPath1)) 362 | line = reader.ReadLine(); 363 | 364 | // Get ProcessID and ThreadID 365 | string[] parts = line.Split(new string[] { " : " }, StringSplitOptions.RemoveEmptyEntries); 366 | ClassicAssert.IsTrue(parts != null && parts.Length == 3); 367 | string processId = parts[0]; 368 | string threadId = parts[1]; 369 | ClassicAssert.IsTrue(processId.StartsWith("0x") && threadId.StartsWith("0x")); 370 | 371 | // Delete log file 372 | File.Delete(Settings.Pkcs11LoggerLogPath1); 373 | 374 | // Log to Pkcs11LoggerLogPath1 with ProcessID disabled 375 | flags = flags | PKCS11_LOGGER_FLAG_DISABLE_PROCESS_ID; 376 | flags = flags & ~PKCS11_LOGGER_FLAG_DISABLE_THREAD_ID; 377 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 378 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 379 | pkcs11Library.GetInfo(); 380 | 381 | // Check if the first line starts with ThreadID 382 | using (StreamReader reader = new StreamReader(Settings.Pkcs11LoggerLogPath1)) 383 | line = reader.ReadLine(); 384 | ClassicAssert.IsTrue(line.StartsWith(threadId)); 385 | 386 | // Delete log file 387 | File.Delete(Settings.Pkcs11LoggerLogPath1); 388 | 389 | // Log to Pkcs11LoggerLogPath1 with both IDs disabled 390 | flags = flags | PKCS11_LOGGER_FLAG_DISABLE_PROCESS_ID; 391 | flags = flags | PKCS11_LOGGER_FLAG_DISABLE_THREAD_ID; 392 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 393 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 394 | pkcs11Library.GetInfo(); 395 | 396 | // Check if both IDs are missing 397 | using (StreamReader reader = new StreamReader(Settings.Pkcs11LoggerLogPath1)) 398 | line = reader.ReadLine(); 399 | ClassicAssert.IsTrue(!line.StartsWith(processId) && !line.StartsWith(threadId)); 400 | } 401 | 402 | /// 403 | /// Test PKCS11_LOGGER_FLAG_ENABLE_PIN flag 404 | /// 405 | [Test()] 406 | public void EnablePinTest() 407 | { 408 | DeleteEnvironmentVariables(); 409 | 410 | uint flags = 0; 411 | 412 | // Delete log file 413 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 414 | File.Delete(Settings.Pkcs11LoggerLogPath1); 415 | 416 | // Log to Pkcs11LoggerLogPath1 with PIN logging disabled 417 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 418 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 419 | flags = flags & ~PKCS11_LOGGER_FLAG_ENABLE_PIN; 420 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 421 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 422 | using (ISession session = pkcs11Library.GetSlotList(SlotsType.WithTokenPresent)[0].OpenSession(SessionType.ReadOnly)) 423 | session.Login(CKU.CKU_USER, Settings.NormalUserPin); 424 | 425 | ClassicAssert.IsTrue(File.ReadAllText(Settings.Pkcs11LoggerLogPath1).Contains(" *pPin: *** Intentionally hidden ***")); 426 | 427 | // Delete log file 428 | File.Delete(Settings.Pkcs11LoggerLogPath1); 429 | 430 | // Log to Pkcs11LoggerLogPath1 with PIN logging enabled 431 | flags = flags | PKCS11_LOGGER_FLAG_ENABLE_PIN; 432 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 433 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 434 | using (ISession session = pkcs11Library.GetSlotList(SlotsType.WithTokenPresent)[0].OpenSession(SessionType.ReadOnly)) 435 | session.Login(CKU.CKU_USER, Settings.NormalUserPin); 436 | 437 | ClassicAssert.IsTrue(File.ReadAllText(Settings.Pkcs11LoggerLogPath1).Contains(" *pPin: " + Settings.NormalUserPin)); 438 | } 439 | 440 | /// 441 | /// Test PKCS11_LOGGER_FLAG_ENABLE_STDOUT flag 442 | /// 443 | [Test()] 444 | public void EnableStdOutTest() 445 | { 446 | DeleteEnvironmentVariables(); 447 | 448 | uint flags = 0; 449 | 450 | // Test result needs to be verified visually in NUnit console: 451 | // nunit3-console.exe Pkcs11LoggerTests.dll --test=Pkcs11Logger.Tests.BasicPkcs11LoggerTests.EnableStdOutTest 452 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 453 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 454 | flags = flags | PKCS11_LOGGER_FLAG_ENABLE_STDOUT; 455 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 456 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 457 | pkcs11Library.GetInfo(); 458 | } 459 | 460 | /// 461 | /// Test PKCS11_LOGGER_FLAG_ENABLE_STDERR flag 462 | /// 463 | [Test()] 464 | public void EnableStdErrTest() 465 | { 466 | DeleteEnvironmentVariables(); 467 | 468 | uint flags = 0; 469 | 470 | // Test result needs to be verified visually in NUnit console: 471 | // nunit3-console.exe Pkcs11LoggerTests.dll --test=Pkcs11Logger.Tests.BasicPkcs11LoggerTests.EnableStdErrTest 472 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 473 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 474 | flags = flags | PKCS11_LOGGER_FLAG_ENABLE_STDERR; 475 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 476 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 477 | pkcs11Library.GetInfo(); 478 | } 479 | 480 | /// 481 | /// Test PKCS11_LOGGER_FLAG_ENABLE_FCLOSE flag 482 | /// 483 | [Test()] 484 | public void EnableFcloseTest() 485 | { 486 | DeleteEnvironmentVariables(); 487 | 488 | // Tested file locking behavior is valid only on Windows platform 489 | if (!Platform.IsWindows) 490 | Assert.Inconclusive("Test cannot be executed on this platform"); 491 | 492 | uint flags = 0; 493 | 494 | // Delete log file 495 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 496 | File.Delete(Settings.Pkcs11LoggerLogPath1); 497 | 498 | // Log to Pkcs11LoggerLogPath1 with fclose disabled 499 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 500 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 501 | flags = flags & ~PKCS11_LOGGER_FLAG_ENABLE_FCLOSE; 502 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 503 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 504 | { 505 | pkcs11Library.GetInfo(); 506 | 507 | // Check whether log file exists 508 | if (!File.Exists(Settings.Pkcs11LoggerLogPath1)) 509 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath1 + " does not exist"); 510 | 511 | try 512 | { 513 | // It should not be possible to delete log file 514 | File.Delete(Settings.Pkcs11LoggerLogPath1); 515 | Assert.Fail("Exception expected but not thrown"); 516 | } 517 | catch (Exception ex) 518 | { 519 | ClassicAssert.IsTrue(ex is IOException); 520 | } 521 | 522 | // Check whether log file was not deleted 523 | if (!File.Exists(Settings.Pkcs11LoggerLogPath1)) 524 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath1 + " does not exist"); 525 | } 526 | 527 | // Delete log file 528 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 529 | File.Delete(Settings.Pkcs11LoggerLogPath1); 530 | 531 | // Log to Pkcs11LoggerLogPath1 with fclose enabled 532 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 533 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 534 | flags = flags | PKCS11_LOGGER_FLAG_ENABLE_FCLOSE; 535 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 536 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 537 | { 538 | pkcs11Library.GetInfo(); 539 | 540 | // Check whether log file exists 541 | if (!File.Exists(Settings.Pkcs11LoggerLogPath1)) 542 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath1 + " does not exist"); 543 | 544 | // It should be possible to delete log file 545 | File.Delete(Settings.Pkcs11LoggerLogPath1); 546 | 547 | // Check whether log file was deleted 548 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 549 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath1 + " exists"); 550 | 551 | pkcs11Library.GetInfo(); 552 | 553 | // Check whether log file exists 554 | if (!File.Exists(Settings.Pkcs11LoggerLogPath1)) 555 | Assert.Fail("File " + Settings.Pkcs11LoggerLogPath1 + " does not exist"); 556 | } 557 | 558 | // Delete log file 559 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 560 | File.Delete(Settings.Pkcs11LoggerLogPath1); 561 | } 562 | 563 | /// 564 | /// Test performance with PKCS11_LOGGER_FLAG_ENABLE_FCLOSE flag 565 | /// 566 | [Test()] 567 | public void EnableFclosePerformanceTest() 568 | { 569 | DeleteEnvironmentVariables(); 570 | 571 | uint flags = 0; 572 | int fcloseDisabledTicks = 0; 573 | int fcloseEnabledTicks = 0; 574 | 575 | // Delete log file 576 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 577 | File.Delete(Settings.Pkcs11LoggerLogPath1); 578 | 579 | // Log to Pkcs11LoggerLogPath1 with fclose disabled 580 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 581 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 582 | flags = flags & ~PKCS11_LOGGER_FLAG_ENABLE_FCLOSE; 583 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 584 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 585 | { 586 | int tickCountStart = Environment.TickCount; 587 | 588 | for (int i = 0; i < 10; i++) 589 | { 590 | pkcs11Library.GetInfo(); 591 | foreach (ISlot slot in pkcs11Library.GetSlotList(SlotsType.WithTokenPresent)) 592 | { 593 | slot.GetTokenInfo(); 594 | foreach (CKM mechanism in slot.GetMechanismList()) 595 | { 596 | slot.GetMechanismInfo(mechanism); 597 | } 598 | } 599 | } 600 | 601 | int tickCountStop = Environment.TickCount; 602 | fcloseDisabledTicks = tickCountStop - tickCountStart; 603 | } 604 | 605 | // Delete log file 606 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 607 | File.Delete(Settings.Pkcs11LoggerLogPath1); 608 | 609 | // Log to Pkcs11LoggerLogPath1 with fclose enabled 610 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LIBRARY_PATH, Settings.Pkcs11LibraryPath); 611 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_LOG_FILE_PATH, Settings.Pkcs11LoggerLogPath1); 612 | flags = flags | PKCS11_LOGGER_FLAG_ENABLE_FCLOSE; 613 | EnvVarUtils.SetEnvVar(PKCS11_LOGGER_FLAGS, Convert.ToString(flags)); 614 | using (IPkcs11Library pkcs11Library = Settings.Pkcs11InteropFactories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Pkcs11InteropFactories, Settings.Pkcs11LoggerLibraryPath, AppType.MultiThreaded)) 615 | { 616 | int tickCountStart = Environment.TickCount; 617 | 618 | for (int i = 0; i < 10; i++) 619 | { 620 | pkcs11Library.GetInfo(); 621 | foreach (ISlot slot in pkcs11Library.GetSlotList(SlotsType.WithTokenPresent)) 622 | { 623 | slot.GetTokenInfo(); 624 | foreach (CKM mechanism in slot.GetMechanismList()) 625 | { 626 | slot.GetMechanismInfo(mechanism); 627 | } 628 | } 629 | } 630 | 631 | int tickCountStop = Environment.TickCount; 632 | fcloseEnabledTicks = tickCountStop - tickCountStart; 633 | } 634 | 635 | // Delete log file 636 | if (File.Exists(Settings.Pkcs11LoggerLogPath1)) 637 | File.Delete(Settings.Pkcs11LoggerLogPath1); 638 | 639 | // PKCS11_LOGGER_FLAG_ENABLE_FCLOSE decreases performance 640 | ClassicAssert.IsTrue(fcloseEnabledTicks > fcloseDisabledTicks); 641 | } 642 | } 643 | } 644 | -------------------------------------------------------------------------------- /test/Pkcs11LoggerTests/EnvVarUtils.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2025 The Pkcs11Interop Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Written for the Pkcs11Interop project by: 19 | * Jaroslav IMRICH 20 | */ 21 | 22 | using System; 23 | using System.Runtime.InteropServices; 24 | using Net.Pkcs11Interop.Common; 25 | 26 | namespace Pkcs11Logger.Tests 27 | { 28 | /// 29 | /// Utility class for environment variables 30 | /// 31 | public class EnvVarUtils 32 | { 33 | /// 34 | /// Creates, modifies, or deletes an environment variable 35 | /// 36 | /// The name of an environment variable 37 | /// A value to assign to variable 38 | public static void SetEnvVar(string name, string value) 39 | { 40 | if (Platform.IsLinux || Platform.IsMacOsX) 41 | { 42 | if (value == null) 43 | { 44 | if (0 != NativeMethods.unsetenv(name)) 45 | throw new Exception("Unmanaged function unsetenv failed"); 46 | } 47 | else 48 | { 49 | if (0 != NativeMethods.setenv(name, value, 1)) 50 | throw new Exception("Unmanaged function setenv failed"); 51 | } 52 | } 53 | else 54 | { 55 | System.Environment.SetEnvironmentVariable(name, value); 56 | } 57 | } 58 | 59 | /// 60 | /// Definition of unmanaged functions 61 | /// 62 | private static class NativeMethods 63 | { 64 | /// 65 | /// Creates or modifies an environment variable 66 | /// 67 | /// The name of an environment variable 68 | /// A value to assign to variable 69 | /// Indicates whether value of existing variable should be overwritten (nonzero) or not (zero) 70 | /// Zero on success, or -1 on error, with errno set to indicate the cause of the error 71 | [DllImport("libc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)] 72 | internal static extern int setenv(string name, string value, int overwrite); 73 | 74 | /// 75 | /// Deletes an environment variable 76 | /// 77 | /// The name of an environment variable 78 | /// Zero on success, or -1 on error, with errno set to indicate the cause of the error 79 | [DllImport("libc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)] 80 | internal static extern int unsetenv(string name); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /test/Pkcs11LoggerTests/Pkcs11LoggerTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net80 5 | 6 | 7 | 8 | Pkcs11Logger.Tests 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | Always 21 | 22 | 23 | Always 24 | 25 | 26 | Always 27 | 28 | 29 | Always 30 | 31 | 32 | Always 33 | 34 | 35 | Always 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /test/Pkcs11LoggerTests/Settings.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2025 The Pkcs11Interop Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /* 18 | * Written for the Pkcs11Interop project by: 19 | * Jaroslav IMRICH 20 | */ 21 | 22 | using System; 23 | using System.IO; 24 | using System.Reflection; 25 | using System.Runtime.InteropServices; 26 | using Net.Pkcs11Interop.Common; 27 | using Net.Pkcs11Interop.HighLevelAPI; 28 | 29 | namespace Pkcs11Logger.Tests 30 | { 31 | /// 32 | /// Test settings 33 | /// 34 | public static class Settings 35 | { 36 | /// 37 | /// Factories to be used by Pkcs11Interop library 38 | /// 39 | public static Pkcs11InteropFactories Pkcs11InteropFactories = new Pkcs11InteropFactories(); 40 | 41 | /// 42 | /// The PKCS#11 unmanaged library path 43 | /// 44 | public static string Pkcs11LibraryPath = null; 45 | 46 | /// 47 | /// The normal user pin 48 | /// 49 | public static string NormalUserPin = @"11111111"; 50 | 51 | /// 52 | /// The PKCS11-LOGGER unmanaged library path 53 | /// 54 | public static string Pkcs11LoggerLibraryPath = null; 55 | 56 | /// 57 | /// Primary log file path 58 | /// 59 | public static string Pkcs11LoggerLogPath1 = null; 60 | 61 | /// 62 | /// Alternative log file path 63 | /// 64 | public static string Pkcs11LoggerLogPath2 = null; 65 | 66 | /// 67 | /// Class constructor 68 | /// 69 | static Settings() 70 | { 71 | string testBasePath = Path.GetDirectoryName(typeof(Settings).Assembly.Location); 72 | string repoBasePath = testBasePath.Replace(Path.Combine("test", "Pkcs11LoggerTests", "bin", "Debug", "net80"), string.Empty); 73 | string platform = Platform.Uses32BitRuntime ? "x86" : "x64"; 74 | 75 | if (Platform.IsWindows) 76 | { 77 | Pkcs11LibraryPath = Path.Combine(testBasePath, "pkcs11-mock", "windows", $"pkcs11-mock-{platform}.dll"); 78 | Pkcs11LoggerLibraryPath = Path.Combine(repoBasePath, "build", "windows", $"pkcs11-logger-{platform}.dll"); 79 | Pkcs11LoggerLogPath1 = Path.Combine(testBasePath, $"pkcs11-logger-{platform}-1.txt"); 80 | Pkcs11LoggerLogPath2 = Path.Combine(testBasePath, $"pkcs11-logger-{platform}-2.txt"); 81 | } 82 | else if (Platform.IsLinux) 83 | { 84 | // Set callback for resolving native library imports from Pkcs11Interop 85 | NativeLibrary.SetDllImportResolver(typeof(Pkcs11InteropFactories).Assembly, LinuxDllImportResolver); 86 | 87 | Pkcs11LibraryPath = Path.Combine(testBasePath, "pkcs11-mock", "linux", $"pkcs11-mock-{platform}.so"); 88 | Pkcs11LoggerLibraryPath = Path.Combine(repoBasePath, "build", "linux", $"pkcs11-logger-{platform}.so"); 89 | Pkcs11LoggerLogPath1 = Path.Combine(testBasePath, $"pkcs11-logger-{platform}-1.txt"); 90 | Pkcs11LoggerLogPath2 = Path.Combine(testBasePath, $"pkcs11-logger-{platform}-2.txt"); 91 | } 92 | else if (Platform.IsMacOsX) 93 | { 94 | Pkcs11LibraryPath = Path.Combine(testBasePath, "pkcs11-mock", "macos", $"pkcs11-mock.dylib"); 95 | Pkcs11LoggerLibraryPath = Path.Combine(repoBasePath, "build", "macos", $"pkcs11-logger.dylib"); 96 | Pkcs11LoggerLogPath1 = Path.Combine(testBasePath, $"pkcs11-logger-1.txt"); 97 | Pkcs11LoggerLogPath2 = Path.Combine(testBasePath, $"pkcs11-logger-2.txt"); 98 | } 99 | } 100 | 101 | /// 102 | /// Callback for resolving native library imports 103 | /// 104 | /// Name of the native library that needs to be resolved 105 | /// The assembly loading the native library 106 | /// The search path for native library 107 | /// The OS handle for the loaded native library library 108 | static IntPtr LinuxDllImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? dllImportSearchPath) 109 | { 110 | // Note: Pkcs11Interop tries to load "libdl" but Ubuntu 22.04 provides "libdl.so.2" 111 | string mappedLibraryName = (libraryName == "libdl") ? "libdl.so.2" : libraryName; 112 | return NativeLibrary.Load(mappedLibraryName, assembly, dllImportSearchPath); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /test/Pkcs11LoggerTests/pkcs11-mock/README.txt: -------------------------------------------------------------------------------- 1 | PKCS11-MOCK is minimalistic C library that implements PKCS#11 v3.1 API. 2 | It is not a real cryptographic module but just a dummy mock object designed 3 | specifically for unit testing of Pkcs11Interop library. 4 | 5 | The Wikipedia article on mock objects states: 6 | 7 | In object-oriented programming, mock objects are simulated objects 8 | that mimic the behavior of real objects in controlled ways. A programmer 9 | typically creates a mock object to test the behavior of some other object, 10 | in much the same way that a car designer uses a crash test dummy 11 | to simulate the dynamic behavior of a human in vehicle impacts. 12 | 13 | Following these simple principles PKCS11-MOCK does not depend on any hardware 14 | nor configuration and can be easily modified to return any response or data. 15 | 16 | For more info visit https://github.com/Pkcs11Interop/pkcs11-mock -------------------------------------------------------------------------------- /test/Pkcs11LoggerTests/pkcs11-mock/linux/pkcs11-mock-x64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pkcs11Interop/pkcs11-logger/f48d0120243b986d6990a7916c5918cee1bf2036/test/Pkcs11LoggerTests/pkcs11-mock/linux/pkcs11-mock-x64.so -------------------------------------------------------------------------------- /test/Pkcs11LoggerTests/pkcs11-mock/linux/pkcs11-mock-x86.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pkcs11Interop/pkcs11-logger/f48d0120243b986d6990a7916c5918cee1bf2036/test/Pkcs11LoggerTests/pkcs11-mock/linux/pkcs11-mock-x86.so -------------------------------------------------------------------------------- /test/Pkcs11LoggerTests/pkcs11-mock/macos/pkcs11-mock.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pkcs11Interop/pkcs11-logger/f48d0120243b986d6990a7916c5918cee1bf2036/test/Pkcs11LoggerTests/pkcs11-mock/macos/pkcs11-mock.dylib -------------------------------------------------------------------------------- /test/Pkcs11LoggerTests/pkcs11-mock/windows/pkcs11-mock-x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pkcs11Interop/pkcs11-logger/f48d0120243b986d6990a7916c5918cee1bf2036/test/Pkcs11LoggerTests/pkcs11-mock/windows/pkcs11-mock-x64.dll -------------------------------------------------------------------------------- /test/Pkcs11LoggerTests/pkcs11-mock/windows/pkcs11-mock-x86.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pkcs11Interop/pkcs11-logger/f48d0120243b986d6990a7916c5918cee1bf2036/test/Pkcs11LoggerTests/pkcs11-mock/windows/pkcs11-mock-x86.dll --------------------------------------------------------------------------------