├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── config.sample ├── src ├── certificate.c ├── certificate.h ├── config.c ├── config.h ├── log.c ├── log.h ├── object.c ├── object.h ├── objects.c ├── objects.h ├── pk11.c ├── pk11.h ├── pkix.asn ├── pkix_asn1_tab.c ├── sessions.c ├── sessions.h ├── tpm.c ├── tpm.h ├── tpm20_compat.h ├── utils.c └── utils.h ├── test ├── bat │ ├── bats.bat │ └── test_util.bash └── travis_run_bat.sh └── tpm2-pk11.module.in /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | compiler: 3 | - gcc 4 | - clang-3.8 5 | 6 | env: 7 | - TSS_BRANCH=master TPM2_TOOLS_BRANCH=master TSS_CONFIGURATIONS=--disable-esapi TCTI=mssim 8 | 9 | matrix: 10 | include: 11 | env: TSS_BRANCH=1.x TPM2_TOOLS_BRANCH=3.0.X TSS_CONFIGURATIONS= TCTI=socket 12 | 13 | sudo: required 14 | dist: trusty 15 | 16 | addons: 17 | apt: 18 | packages: 19 | - cmake 20 | - libp11-kit-dev 21 | - liburiparser-dev 22 | - clang-3.8 23 | - libdbus-1-dev 24 | - libglib2.0-dev 25 | - pandoc 26 | - libcurl4-gnutls-dev 27 | 28 | install: 29 | # build tpm2 simulator - needed for testing 30 | - wget https://downloads.sourceforge.net/project/ibmswtpm2/ibmtpm1119.tar.gz 31 | - sha256sum ibmtpm1119.tar.gz | grep -q b9eef79904e276aeaed2a6b9e4021442ef4d7dfae4adde2473bef1a6a4cd10fb 32 | - mkdir ibmtpm1119 && pushd ibmtpm1119 && tar axf ../ibmtpm1119.tar.gz && pushd ./src && make 33 | - ./tpm_server & 34 | - popd && popd 35 | # build tpm2-tss 36 | - wget http://ftpmirror.gnu.org/autoconf-archive/autoconf-archive-2017.09.28.tar.xz 37 | - sha256sum autoconf-archive-2017.09.28.tar.xz | grep -q 5c9fb5845b38b28982a3ef12836f76b35f46799ef4a2e46b48e2bd3c6182fa01 38 | - tar xJf autoconf-archive-2017.09.28.tar.xz && pushd autoconf-archive-2017.09.28 39 | - ./configure --prefix=/usr && make -j$(nproc) && sudo make install 40 | - popd 41 | - git clone https://github.com/tpm2-software/tpm2-tss.git --branch $TSS_BRANCH 42 | - pushd tpm2-tss 43 | - ./bootstrap && ./configure ${TSS_CONFIGURATIONS} && make -j$(nproc) 44 | - sudo make install 45 | - popd 46 | - sudo ldconfig /usr/local/lib 47 | # build user space resource manager & attach to simulator 48 | - git clone https://github.com/tpm2-software/tpm2-abrmd.git --branch $TSS_BRANCH 49 | - pushd tpm2-abrmd 50 | - ./bootstrap && ./configure --disable-dlclose --with-dbuspolicydir=/etc/dbus-1/system.d && make -j$(nproc) && sudo make install && popd 51 | - sudo mkdir -p /var/lib/tpm 52 | - sudo groupadd tss && sudo useradd -M -d /var/lib/tpm -s /bin/false -g tss tss 53 | - sudo pkill -HUP dbus-daemon 54 | - sudo -u tss tpm2-abrmd --tcti=$TCTI & 55 | # openssl 1.0.2g - needed for tpm2-tools 56 | - wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.0.0_1.0.2g-1ubuntu4.13_amd64.deb 57 | - wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.0.2g-1ubuntu4.13_amd64.deb 58 | - sha256sum libssl1.0.0_*_amd64.deb | grep -q 22218427bf75a27e4e384d98bcb5286144ff824cc86bf21a82632304ac099195 59 | - sha256sum libssl-dev_*_amd64.deb | grep -q c6aadbb7b58700a108ef9d51edbdf9dd7534f70d02943a2e540f2021619602b5 60 | - sudo dpkg -i libssl1.0.0_*_amd64.deb 61 | - sudo dpkg -i libssl-dev_*_amd64.deb 62 | # build tpm2-tools - needed for testing 63 | - git clone https://github.com/tpm2-software/tpm2-tools.git --branch $TPM2_TOOLS_BRANCH 64 | - pushd tpm2-tools 65 | - ./bootstrap && TSS2_SYS_CFLAGS='-Wno-missing-field-initializers' ./configure --disable-dlclose && make -j$(nproc) && sudo make install 66 | - popd 67 | # setup travis environment for testing. 68 | - mkdir -p ~/.ssh 69 | - chmod 700 ~/.ssh 70 | - git clone https://github.com/sstephenson/bats.git 71 | - pushd bats 72 | - sudo ./install.sh /usr/local 73 | - popd 74 | - mkdir -p ~/.tpm2 75 | - pushd ~/.tpm2 76 | - echo "type tabrmd" >> config 77 | - echo "hostname localhost" >> config 78 | - echo "sign-using-encrypt true" >> config 79 | - popd 80 | 81 | script: 82 | - mkdir build 83 | - pushd build 84 | - cmake .. && make 85 | - popd 86 | - ./test/travis_run_bat.sh 87 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | project(TPM2_PK11 LANGUAGES C) 3 | include(${CMAKE_ROOT}/Modules/GNUInstallDirs.cmake) 4 | 5 | find_package(PkgConfig REQUIRED) 6 | function(pkg_check_variable _pkg _name) 7 | string(TOUPPER ${_pkg} _pkg_upper) 8 | string(TOUPPER ${_name} _name_upper) 9 | string(REPLACE "-" "_" _pkg_upper ${_pkg_upper}) 10 | string(REPLACE "-" "_" _name_upper ${_name_upper}) 11 | set(_output_name "${_pkg_upper}_${_name_upper}") 12 | 13 | execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=${_name} ${_pkg} OUTPUT_VARIABLE _pkg_result OUTPUT_STRIP_TRAILING_WHITESPACE) 14 | set("${_output_name}" "${_pkg_result}" CACHE STRING "pkg-config variable ${_name} of ${_pkg}") 15 | endfunction() 16 | 17 | pkg_check_modules(P11_KIT REQUIRED p11-kit-1) 18 | pkg_check_variable(p11-kit-1 p11_module_configs) 19 | pkg_check_variable(p11-kit-1 p11_module_path) 20 | pkg_search_module(SAPI REQUIRED sapi tss2-sys) 21 | pkg_check_modules(TCTI_SOCKET tcti-socket) 22 | pkg_check_modules(TCTI_MSSIM tss2-tcti-mssim) 23 | pkg_search_module(TCTI_DEVICE tcti-device tss2-tcti-device) 24 | pkg_search_module(TCTI_TABRMD tcti-tabrmd tss2-tcti-tabrmd) 25 | pkg_check_modules(LIBTASN1 REQUIRED libtasn1) 26 | 27 | if(NOT TCTI_SOCKET_FOUND AND NOT TCTI_MSSIM_FOUND AND NOT TCTI_DEVICE_FOUND AND NOT TCTI_TABRMD_FOUND) 28 | message(FATAL_ERROR "At least one connection type must be enabled") 29 | endif() 30 | 31 | find_library(SAPI_LIBRARIES 32 | NAMES sapi tss2-sys 33 | HINTS ${SAPI_LIBDIR} ${SAPI_LIBRARY_DIRS} 34 | ) 35 | 36 | if(TCTI_SOCKET_FOUND) 37 | find_library(TCTI_SOCKET_LIBRARIES 38 | NAMES tcti-socket 39 | HINTS ${TCTI_SOCKET_LIBDIR} ${TCTI_SOCKET_LIBRARY_DIRS} 40 | ) 41 | endif() 42 | 43 | if(TCTI_MSSIM_FOUND) 44 | find_library(TCTI_MSSIM_LIBRARIES 45 | NAMES tss2-tcti-mssim 46 | HINTS ${TCTI_MSSIM_LIBDIR} ${TCTI_MSSIM_LIBRARY_DIRS} 47 | ) 48 | endif() 49 | 50 | if(TCTI_DEVICE_FOUND) 51 | find_library(TCTI_DEVICE_LIBRARIES 52 | NAMES tcti-device tss2-tcti-device 53 | HINTS ${TCTI_DEVICE_LIBDIR} ${TCTI_DEVICE_LIBRARY_DIRS} 54 | ) 55 | endif() 56 | 57 | if(TCTI_TABRMD_FOUND) 58 | find_library(TCTI_TABRMD_LIBRARIES 59 | NAMES tcti-tabrmd tss2-tcti-tabrmd 60 | HINTS ${TCTI_TABRMD_LIBDIR} ${TCTI_TABRMD_LIBRARY_DIRS} 61 | ) 62 | endif() 63 | 64 | find_library(P11_KIT_LIBRARIES 65 | NAMES p11-kit 66 | HINTS ${P11_KIT_LIBDIR} ${P11_KIT_LIBRARY_DIRS} 67 | ) 68 | 69 | find_library(LIBTASN1_LIBRARIES 70 | NAMES tasn1 71 | HINTS ${LIBTASN1_LIBDIR} ${LIBTASN1_LIBRARY_DIRS} 72 | ) 73 | 74 | configure_file("tpm2-pk11.module.in" "tpm2-pk11.module") 75 | 76 | aux_source_directory(./src SRC_LIST) 77 | 78 | add_library(tpm2-pk11 SHARED ${SRC_LIST}) 79 | set_property(TARGET tpm2-pk11 PROPERTY C_STANDARD 11) 80 | target_include_directories(tpm2-pk11 PRIVATE ${P11_KIT_INCLUDE_DIRS} ${SAPI_INCLUDE_DIRS} ${TCTI_SOCKET_INCLUDE_DIRS} ${TCTI_MSSIM_INCLUDE_DIRS} ${TCTI_DEVICE_INCLUDE_DIRS} ${TCTI_TABRMD_INCLUDE_DIRS} ${LIBTASN1_INCLUSE_DIRS}) 81 | target_link_libraries(tpm2-pk11 ${P11_KIT_LIBRARIES} ${SAPI_LIBRARIES} ${TCTI_SOCKET_LIBRARIES} ${TCTI_MSSIM_LIBRARIES} ${TCTI_DEVICE_LIBRARIES} ${TCTI_TABRMD_LIBRARIES} ${LIBTASN1_LIBRARIES}) 82 | if(TCTI_SOCKET_FOUND) 83 | target_compile_definitions(tpm2-pk11 PUBLIC TCTI_SOCKET_ENABLED=1) 84 | endif() 85 | if(TCTI_MSSIM_FOUND) 86 | target_compile_definitions(tpm2-pk11 PUBLIC TCTI_MSSIM_ENABLED=1) 87 | endif() 88 | if(TCTI_DEVICE_FOUND) 89 | target_compile_definitions(tpm2-pk11 PUBLIC TCTI_DEVICE_ENABLED=1) 90 | endif() 91 | if(TCTI_TABRMD_FOUND) 92 | target_compile_definitions(tpm2-pk11 PUBLIC TCTI_TABRMD_ENABLED=1) 93 | endif() 94 | 95 | if (SAPI_VERSION VERSION_LESS "2.0") 96 | target_compile_definitions(tpm2-pk11 PUBLIC TSS_COMPAT=1) 97 | endif() 98 | 99 | install(TARGETS tpm2-pk11 DESTINATION ${P11_KIT_1_P11_MODULE_PATH}) 100 | install(FILES ${CMAKE_BINARY_DIR}/tpm2-pk11.module DESTINATION ${P11_KIT_1_P11_MODULE_CONFIGS}) 101 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions are met: 3 | 4 | 1. Redistributions of source code must retain the above copyright notice, 5 | this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, 8 | this list of conditions and the following disclaimer in the documentation 9 | and/or other materials provided with the distribution. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 12 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 13 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 14 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 15 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 16 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 17 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 18 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 19 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 20 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 21 | THE POSSIBILITY OF SUCH DAMAGE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Deprecation Notice 2 | 3 | This package is no longer maintained. Users are advised to switch to [tpm2-pkcs11](https://github.com/tpm2-software/tpm2-pkcs11) which is developed by the developers of the TPM2 Software Stack. 4 | 5 | TPM2-PK11 6 | ========== 7 | 8 | TPM2-PK11 provide a PKCS#11 backend for TPM 2.0 chips. 9 | This allows you to use your TPM keys in every application which support the PKCS #11 standard. 10 | For more information about howto setup keys, certificates and applications see the [wiki](https://github.com/irtimmer/tpm2-pk11/wiki). 11 | 12 | ## Features 13 | 14 | - Sign and decrypt using private RSA key stored in TPM 15 | - Provide on disk stored certificate in DER format to applications using PKCS #11 16 | 17 | ## Supported applications 18 | 19 | - OpenSSH Client (SSH key in TPM) 20 | - Firefox (Private key of Client certificate in TPM) 21 | - GnuPG using [gnupg-pkcs11-scd](https://github.com/alonbl/gnupg-pkcs11-scd) (PGP key in TPM) 22 | 23 | ## Contribute 24 | 25 | 1. Fork us 26 | 2. Write code 27 | 3. Send Pull Requests 28 | -------------------------------------------------------------------------------- /config.sample: -------------------------------------------------------------------------------- 1 | # Type can be device/socket/tabrmd 2 | type device 3 | # Hostname to connect when using socket 4 | hostname localhost 5 | # Port number of TPM socket to connect to 6 | port 2321 7 | # Device to use as TPM 8 | device /dev/tpm0 9 | # Sign using encrypt in case TPM doesn't support hash format 10 | # For example SSH use SHA512 which isn't supported by all TPM's 11 | # Enabling this option requires key's to be encryption keys instead of signing only keys 12 | sign-using-encrypt true 13 | # Set login_required in case keys are protected by a password 14 | # Notice currently only a single password for all keys is supported 15 | # Depending on the TPM settings, providing wrong passwords can lead to a lockout 16 | login-required false 17 | # Enable logging 18 | # None: 0 19 | # Error: 1 20 | # Warning: 2 21 | # Info: 3 22 | # Verbose: 4 23 | # Debug: 5 24 | log-level 2 25 | # Set log file location or use stdout/stderr 26 | log stderr 27 | -------------------------------------------------------------------------------- /src/certificate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #define _GNU_SOURCE 28 | 29 | #include "object.h" 30 | #include "objects.h" 31 | #include "pk11.h" 32 | #include "utils.h" 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | 40 | #define MAX_ID_BITS 512 41 | #define MAX_DER_LENGTH 256 42 | 43 | extern const asn1_static_node pkix_asn1_tab[]; 44 | 45 | typedef struct userdata_certificate_t { 46 | CK_BYTE id[MAX_ID_BITS / 4]; 47 | CK_UTF8CHAR label[MAX_ID_BITS / 2]; 48 | CK_BYTE subject[MAX_DER_LENGTH]; 49 | CK_BYTE issuer[MAX_DER_LENGTH]; 50 | CK_BYTE serial[MAX_DER_LENGTH]; 51 | PkcsObject object; 52 | PkcsX509 certificate; 53 | } UserdataCertificate, *pUserdataCertificate; 54 | 55 | 56 | 57 | pObject certificate_read(const char* pathname) { 58 | pObject object = malloc(sizeof(Object)); 59 | if (!object) 60 | return NULL; 61 | 62 | size_t size = sizeof(UserdataCertificate); 63 | pUserdataCertificate userdata = (pUserdataCertificate) read_file(pathname, &size); 64 | if (!userdata) { 65 | free(object); 66 | return NULL; 67 | } 68 | 69 | userdata->object.class = CKO_CERTIFICATE; 70 | userdata->object.token = CK_TRUE; 71 | userdata->object.id = userdata->id; 72 | userdata->object.id_size = 0; 73 | userdata->object.label = userdata->label; 74 | char* filename = basename(pathname); 75 | while (userdata->object.id_size < sizeof(userdata->id)) { 76 | if (sscanf(filename + (userdata->object.id_size * 2), "%2hhx", userdata->id + userdata->object.id_size) != 1) 77 | break; 78 | 79 | sprintf((char*) userdata->label + userdata->object.id_size * 2, "%02X", userdata->id[userdata->object.id_size]); 80 | userdata->object.id_size++; 81 | } 82 | 83 | userdata->object.label_size = userdata->object.id_size * 2; 84 | 85 | userdata->certificate.value_size = size; 86 | userdata->certificate.value = ((char*) userdata) + sizeof(UserdataCertificate); 87 | userdata->certificate.cert_type = CKC_X_509; 88 | userdata->certificate.subject = userdata->subject; 89 | userdata->certificate.subject_size = 0; 90 | userdata->certificate.issuer = userdata->issuer; 91 | userdata->certificate.issuer_size = 0; 92 | userdata->certificate.serial = userdata->serial; 93 | userdata->certificate.serial_size = 0; 94 | 95 | ASN1_TYPE definition = ASN1_TYPE_EMPTY; 96 | ASN1_TYPE element = ASN1_TYPE_EMPTY; 97 | char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; 98 | 99 | asn1_array2tree(pkix_asn1_tab, &definition, errorDescription); 100 | asn1_create_element(definition, "PKIX1.Certificate", &element); 101 | if (asn1_der_decoding(&element, userdata->certificate.value, userdata->certificate.value_size, errorDescription) != ASN1_SUCCESS) { 102 | free(object); 103 | free(userdata); 104 | return NULL; 105 | } 106 | 107 | int length = MAX_DER_LENGTH; 108 | if (asn1_der_coding(element, "tbsCertificate.subject", userdata->subject, &length, errorDescription) == ASN1_SUCCESS) 109 | userdata->certificate.subject_size = length; 110 | 111 | length = MAX_DER_LENGTH; 112 | if (asn1_der_coding(element, "tbsCertificate.issuer", userdata->issuer, &length, errorDescription) == ASN1_SUCCESS) 113 | userdata->certificate.issuer_size = length; 114 | 115 | length = MAX_DER_LENGTH; 116 | if (asn1_der_coding(element, "tbsCertificate.serialNumber", userdata->serial, &length, errorDescription) == ASN1_SUCCESS) 117 | userdata->certificate.serial_size = length; 118 | 119 | asn1_delete_structure(&definition); 120 | asn1_delete_structure(&element); 121 | 122 | object->userdata = userdata; 123 | object->num_entries = 2; 124 | object->entries = calloc(object->num_entries, sizeof(AttrIndexEntry)); 125 | object->entries[0] = (AttrIndexEntry) attr_index_entry(&userdata->object, OBJECT_INDEX); 126 | object->entries[1] = (AttrIndexEntry) attr_index_entry(&userdata->certificate, CERTIFICATE_INDEX); 127 | 128 | return object; 129 | } 130 | -------------------------------------------------------------------------------- /src/certificate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #pragma once 28 | 29 | #include "object.h" 30 | 31 | pObject certificate_read(const char* pathname); 32 | -------------------------------------------------------------------------------- /src/config.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include "config.h" 28 | #include "log.h" 29 | 30 | #define _POSIX_C_SOURCE 200809L 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | int config_load(char* filename, struct config *config) { 43 | FILE* file = fopen(filename, "r"); 44 | 45 | if (file == NULL) 46 | return -ENOENT; 47 | 48 | char *line = NULL; 49 | size_t len = 0; 50 | 51 | while (getline(&line, &len, file) != -1) { 52 | char *key = NULL, *value = NULL; 53 | if (sscanf(line, "%ms %m[^\n]", &key, &value) == 2) { 54 | if (strcmp(key, "hostname") == 0) { 55 | config->hostname = value; 56 | value = NULL; 57 | } else if (strcmp(key, "device") == 0) { 58 | config->device = value; 59 | value = NULL; 60 | } else if (strcmp(key, "certificates") == 0) { 61 | config->certificates = value; 62 | value = NULL; 63 | } else if (strcmp(key, "port") == 0) 64 | config->port = atoi(value); 65 | else if (strcmp(key, "sign-using-encrypt") == 0) 66 | config->sign_using_encrypt = strcasecmp(value, "true") == 0; 67 | else if (strcmp(key, "login-required") == 0) 68 | config->login_required = strcasecmp(value, "true") == 0; 69 | else if (strcmp(key, "log-level") == 0) 70 | config->log_level = atoi(value); 71 | else if (strcmp(key, "log") == 0) { 72 | config->log_file = value; 73 | value = NULL; 74 | } else if (strcmp(key, "type") == 0) { 75 | if (strcmp(value, "socket") == 0) 76 | config->type = TPM_TYPE_SOCKET; 77 | else if (strcmp(value, "device") == 0) 78 | config->type = TPM_TYPE_DEVICE; 79 | else if (strcmp(value, "tabrmd") == 0) 80 | config->type = TPM_TYPE_TABRMD; 81 | } 82 | } 83 | if (key != NULL) 84 | free(key); 85 | 86 | if (value != NULL) 87 | free(value); 88 | } 89 | if (line != NULL) 90 | free(line); 91 | 92 | fclose(file); 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #pragma once 28 | 29 | #include 30 | 31 | #define TPM_TYPE_DEVICE 0 32 | #define TPM_TYPE_SOCKET 1 33 | #define TPM_TYPE_TABRMD 2 34 | 35 | struct config { 36 | int type; 37 | char* device; 38 | char* hostname; 39 | char* certificates; 40 | char* log_file; 41 | int log_level; 42 | unsigned int port; 43 | bool sign_using_encrypt; 44 | bool login_required; 45 | }; 46 | 47 | int config_load(char* filename, struct config *config); 48 | -------------------------------------------------------------------------------- /src/log.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include "log.h" 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | static int log_level = NONE; 36 | static FILE* log_stream = NULL; 37 | 38 | void log_init(char* filename, int level) { 39 | log_level = level; 40 | if (filename != NULL) { 41 | if (strcmp(filename, "stdout") == 0) 42 | log_stream = stdout; 43 | else if (strcmp(filename, "stderr") == 0) 44 | log_stream = stderr; 45 | else 46 | log_stream = fopen(filename, "a"); 47 | } 48 | } 49 | 50 | void print_log(int level, const char* format, ...) { 51 | if (log_stream != NULL && level <= log_level) { 52 | char buffer[20]; 53 | time_t now = time(0); 54 | struct tm* time_now = localtime(&now); 55 | 56 | va_list args; 57 | va_start(args, format); 58 | strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", time_now); 59 | fprintf(log_stream, "%s [tpm-pk11] ", buffer); 60 | vfprintf(log_stream, format, args); 61 | fprintf(log_stream, "\n"); 62 | va_end(args); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #define NONE 0 28 | #define ERROR 1 29 | #define WARNING 2 30 | #define INFO 3 31 | #define VERBOSE 4 32 | #define DEBUG 5 33 | 34 | void log_init(char* filename, int level); 35 | void print_log(int level, const char* format, ...); 36 | -------------------------------------------------------------------------------- /src/object.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include "object.h" 28 | 29 | AttrIndex OBJECT_INDEX[] = { 30 | attr_dynamic_index_of(CKA_ID, PkcsObject, id, id_size), 31 | attr_dynamic_index_of(CKA_LABEL, PkcsObject, label, label_size), 32 | attr_index_of(CKA_CLASS, PkcsObject, class), 33 | attr_index_of(CKA_TOKEN, PkcsObject, token) 34 | }; 35 | 36 | AttrIndex KEY_INDEX[] = { 37 | attr_index_of(CKA_SIGN, PkcsKey, sign), 38 | attr_index_of(CKA_DECRYPT, PkcsKey, decrypt), 39 | attr_index_of(CKA_KEY_TYPE, PkcsKey, key_type) 40 | }; 41 | 42 | AttrIndex PUBLIC_KEY_INDEX[] = { 43 | attr_index_of(CKA_PUBLIC_EXPONENT, PkcsPublicKey, exponent) 44 | }; 45 | 46 | AttrIndex MODULUS_INDEX[] = { 47 | attr_dynamic_index_of(CKA_MODULUS, PkcsModulus, modulus, modulus_size), 48 | attr_index_of(CKA_MODULUS_BITS, PkcsModulus, bits), 49 | }; 50 | 51 | AttrIndex CERTIFICATE_INDEX[] = { 52 | attr_dynamic_index_of(CKA_VALUE, PkcsX509, value, value_size), 53 | attr_dynamic_index_of(CKA_SUBJECT, PkcsX509, subject, subject_size), 54 | attr_dynamic_index_of(CKA_ISSUER, PkcsX509, issuer, issuer_size), 55 | attr_dynamic_index_of(CKA_SERIAL_NUMBER, PkcsX509, serial, serial_size), 56 | attr_index_of(CKA_CERTIFICATE_TYPE, PkcsX509, cert_type), 57 | }; 58 | 59 | void* attr_get(pObject object, CK_ATTRIBUTE_TYPE type, size_t *size) { 60 | for (int i = 0; i < object->num_entries; i++) { 61 | pAttrIndexEntry entries = &object->entries[i]; 62 | for (int j = 0; j < entries->num_attrs; j++) { 63 | if (type == entries->indexes[j].type) { 64 | pAttrIndex index = &entries->indexes[j]; 65 | if (index->size_offset == 0) { 66 | if (size) 67 | *size = index->size; 68 | 69 | return entries->object + index->offset; 70 | } else { 71 | if (size) 72 | *size = *((size_t*) (entries->object + index->size_offset)); 73 | 74 | return *((void**) (entries->object + index->offset)); 75 | } 76 | } 77 | } 78 | } 79 | 80 | return NULL; 81 | } 82 | -------------------------------------------------------------------------------- /src/object.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #pragma once 28 | 29 | #include "tpm20_compat.h" 30 | 31 | #include 32 | 33 | #include 34 | 35 | #define NELEMS(x) (sizeof(x) / sizeof((x)[0])) 36 | 37 | #define attr_index_of(type, struct, attribute) {type, offsetof(struct, attribute), sizeof(((struct*)0)->attribute), 0} 38 | #define attr_dynamic_index_of(type, struct, attribute, size_attribute) {type, offsetof(struct, attribute), 0, offsetof(struct, size_attribute)} 39 | #define attr_index_entry(object, index) {object, index, NELEMS(index)} 40 | 41 | typedef struct attr_index_t { 42 | CK_ATTRIBUTE_TYPE type; 43 | size_t offset; 44 | size_t size; 45 | size_t size_offset; 46 | } AttrIndex, *pAttrIndex; 47 | 48 | typedef struct attr_index_entry_t { 49 | void* object; 50 | pAttrIndex indexes; 51 | size_t num_attrs; 52 | } AttrIndexEntry, *pAttrIndexEntry; 53 | 54 | typedef struct attr_map_t { 55 | CK_ATTRIBUTE_TYPE type; 56 | unsigned int len; 57 | void* value; 58 | struct attr_map_t* next; 59 | } AttrMap, *pAttrMap; 60 | 61 | typedef struct object_t { 62 | int id; 63 | void* userdata; 64 | pAttrIndexEntry entries; 65 | size_t num_entries; 66 | TPMI_DH_OBJECT tpm_handle; 67 | struct object_t *opposite; 68 | } Object, *pObject; 69 | 70 | typedef struct pkcs_object_t { 71 | void* id; 72 | size_t id_size; 73 | char* label; 74 | size_t label_size; 75 | CK_OBJECT_CLASS class; 76 | CK_BBOOL token; 77 | } PkcsObject, *pPkcsObject; 78 | 79 | typedef struct pkcs_key_t { 80 | CK_BBOOL sign; 81 | CK_BBOOL decrypt; 82 | CK_KEY_TYPE key_type; 83 | } PkcsKey, *pPkcsKey; 84 | 85 | typedef struct pkcs_public_key_t { 86 | uint32_t exponent; 87 | } PkcsPublicKey, *pPkcsPublicKey; 88 | 89 | typedef struct pkcs_modulus_t { 90 | void* modulus; 91 | size_t modulus_size; 92 | CK_ULONG bits; 93 | } PkcsModulus, *pPkcsModulus; 94 | 95 | typedef struct pkcs_x509_t { 96 | char* value; 97 | size_t value_size; 98 | char* subject; 99 | size_t subject_size; 100 | char* issuer; 101 | size_t issuer_size; 102 | char* serial; 103 | size_t serial_size; 104 | CK_CERTIFICATE_TYPE cert_type; 105 | } PkcsX509, *pPkcsX509; 106 | 107 | extern AttrIndex OBJECT_INDEX[4]; 108 | extern AttrIndex KEY_INDEX[3]; 109 | extern AttrIndex PUBLIC_KEY_INDEX[1]; 110 | extern AttrIndex MODULUS_INDEX[2]; 111 | extern AttrIndex CERTIFICATE_INDEX[5]; 112 | 113 | void* attr_get(pObject object, CK_ATTRIBUTE_TYPE type, size_t *size); 114 | -------------------------------------------------------------------------------- /src/objects.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #define _GNU_SOURCE 28 | 29 | #include "objects.h" 30 | #include "certificate.h" 31 | #include "tpm.h" 32 | #include "pk11.h" 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #ifndef PATH_MAX 40 | #define PATH_MAX 4096 41 | #endif 42 | #include 43 | 44 | typedef struct userdata_tpm_t { 45 | TPM2B_PUBLIC tpm_key; 46 | TPM2B_NAME name; 47 | CK_UTF8CHAR label[256]; 48 | PkcsObject public_object, private_object; 49 | PkcsKey key; 50 | PkcsPublicKey public_key; 51 | PkcsModulus modulus; 52 | } UserdataTpm, *pUserdataTpm; 53 | 54 | pObject object_get(pObjectList list, int id) { 55 | while (list != NULL) { 56 | if (list->object != NULL && list->object->id == id) 57 | return list->object; 58 | list = list->next; 59 | } 60 | return NULL; 61 | } 62 | 63 | void object_add(pObjectList* list, pObject object) { 64 | pObjectList entry = malloc(sizeof(ObjectList)); 65 | if (!entry) { 66 | if (object->userdata != NULL) 67 | free(object->userdata); 68 | 69 | free(object->entries); 70 | free(object); 71 | 72 | return; 73 | } 74 | 75 | entry->object = object; 76 | entry->next = *list; 77 | *list = entry; 78 | } 79 | 80 | void object_free(pObjectList list) { 81 | while (list != NULL) { 82 | pObjectList next = list->next; 83 | if (list->object != NULL) { 84 | pObject object = list->object; 85 | if (object->userdata != NULL) 86 | free(object->userdata); 87 | 88 | free(object->entries); 89 | free(object); 90 | } 91 | free(list); 92 | list = next; 93 | } 94 | } 95 | 96 | pObjectList object_load(TSS2_SYS_CONTEXT *ctx, struct config *config) { 97 | pObjectList list = NULL; 98 | 99 | TPMS_CAPABILITY_DATA persistent; 100 | TPM2_RC rc = tpm_info(ctx, TPM2_HT_PERSISTENT, &persistent); 101 | if (rc != TPM2_RC_SUCCESS) 102 | goto error; 103 | 104 | for (int i = 0; i < persistent.data.handles.count; i++) { 105 | pUserdataTpm userdata = malloc(sizeof(UserdataTpm)); 106 | if (userdata == NULL) 107 | goto error; 108 | 109 | memset(userdata, 0, sizeof(UserdataTpm)); 110 | userdata->name.TSS_COMPAT_TMPB(size) = sizeof(TPMU_NAME); 111 | rc = tpm_readpublic(ctx, persistent.data.handles.handle[i], &userdata->tpm_key, &userdata->name); 112 | if (rc != TPM2_RC_SUCCESS) { 113 | free(userdata); 114 | goto error; 115 | } 116 | TPM2B_PUBLIC_KEY_RSA *rsa_key = &userdata->tpm_key.TSS_COMPAT_TMPB(publicArea).unique.rsa; 117 | TPMS_RSA_PARMS *rsa_key_parms = &userdata->tpm_key.TSS_COMPAT_TMPB(publicArea).parameters.rsaDetail; 118 | 119 | /* 120 | * fill the label with the same value as the name (they both have 121 | * different uses ; some application never display the id but only 122 | * the label). Since the label is an UTF8 string, we need to 123 | * transform the binary name into a hexadecimal string. 124 | */ 125 | size_t max_label_size = userdata->name.TSS_COMPAT_TMPB(size); 126 | if (max_label_size >= sizeof(userdata->label) / 2) 127 | max_label_size = sizeof(userdata->label) / 2; 128 | 129 | for (size_t n = 0; n < max_label_size; ++n) 130 | sprintf((char*) userdata->label + 2 * n, "%02X", userdata->name.TSS_COMPAT_TMPB(name[n])); 131 | 132 | userdata->public_object.id = userdata->name.TSS_COMPAT_TMPB(name); 133 | userdata->public_object.id_size = userdata->name.TSS_COMPAT_TMPB(size); 134 | userdata->public_object.label = userdata->label; 135 | userdata->public_object.label_size = max_label_size * 2; 136 | userdata->public_object.class = CKO_PUBLIC_KEY; 137 | userdata->public_object.token = CK_TRUE; 138 | userdata->private_object.id = userdata->name.TSS_COMPAT_TMPB(name); 139 | userdata->private_object.id_size = userdata->name.TSS_COMPAT_TMPB(size); 140 | userdata->private_object.label = userdata->label; 141 | userdata->private_object.label_size = max_label_size * 2; 142 | userdata->private_object.class = CKO_PRIVATE_KEY; 143 | userdata->private_object.token = CK_TRUE; 144 | userdata->key.sign = CK_TRUE; 145 | userdata->key.decrypt = CK_TRUE; 146 | userdata->key.key_type = CKK_RSA; 147 | userdata->modulus.modulus = rsa_key->TSS_COMPAT_TMPB(buffer); 148 | userdata->modulus.modulus_size = rsa_key_parms->keyBits / 8; 149 | userdata->modulus.bits = rsa_key_parms->keyBits; 150 | userdata->public_key.exponent = htobe32(rsa_key_parms->exponent == 0 ? 65537 : rsa_key_parms->exponent); 151 | 152 | pObject object = malloc(sizeof(Object)); 153 | if (object == NULL) { 154 | free(userdata); 155 | goto error; 156 | } 157 | 158 | object->tpm_handle = 0; 159 | object->userdata = userdata; 160 | object->num_entries = 4; 161 | object->entries = calloc(object->num_entries, sizeof(AttrIndexEntry)); 162 | object->entries[0] = (AttrIndexEntry) attr_index_entry(&userdata->public_object, OBJECT_INDEX); 163 | object->entries[1] = (AttrIndexEntry) attr_index_entry(&userdata->key, KEY_INDEX); 164 | object->entries[2] = (AttrIndexEntry) attr_index_entry(&userdata->public_key, PUBLIC_KEY_INDEX); 165 | object->entries[3] = (AttrIndexEntry) attr_index_entry(&userdata->modulus, MODULUS_INDEX); 166 | object_add(&list, object); 167 | pObject public_object = object; 168 | 169 | object = malloc(sizeof(Object)); 170 | if (object == NULL) 171 | goto error; 172 | 173 | object->tpm_handle = persistent.data.handles.handle[i]; 174 | object->userdata = NULL; 175 | object->num_entries = 3; 176 | object->entries = calloc(object->num_entries, sizeof(AttrIndexEntry)); 177 | object->entries[0] = (AttrIndexEntry) attr_index_entry(&userdata->private_object, OBJECT_INDEX); 178 | object->entries[1] = (AttrIndexEntry) attr_index_entry(&userdata->key, KEY_INDEX); 179 | object->entries[2] = (AttrIndexEntry) attr_index_entry(&userdata->modulus, MODULUS_INDEX); 180 | object_add(&list, object); 181 | 182 | public_object->opposite = object; 183 | object->opposite = public_object; 184 | } 185 | 186 | if (config->certificates) { 187 | glob_t results; 188 | char search_path[PATH_MAX]; 189 | snprintf(search_path, PATH_MAX, "%s/*.der", config->certificates); 190 | if (glob(search_path, GLOB_TILDE, NULL, &results) == 0) { 191 | for (int i = 0; i < results.gl_pathc; i++) { 192 | pObject object = certificate_read(results.gl_pathv[i]); 193 | if (object) 194 | object_add(&list, object); 195 | } 196 | globfree(&results); 197 | } 198 | } 199 | 200 | return list; 201 | 202 | error: 203 | object_free(list); 204 | return NULL; 205 | } 206 | -------------------------------------------------------------------------------- /src/objects.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #pragma once 28 | 29 | #include "config.h" 30 | #include "object.h" 31 | 32 | #include "tpm20_compat.h" 33 | 34 | typedef struct object_list_t { 35 | pObject object; 36 | struct object_list_t* next; 37 | } ObjectList, *pObjectList; 38 | 39 | pObject object_get(pObjectList list, int id); 40 | void object_add(pObjectList* list, pObject object); 41 | void object_free(pObjectList list); 42 | 43 | pObjectList object_load(TSS2_SYS_CONTEXT *ctx, struct config *config); 44 | -------------------------------------------------------------------------------- /src/pk11.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include "pk11.h" 28 | 29 | #include "config.h" 30 | #include "sessions.h" 31 | #include "utils.h" 32 | #include "tpm.h" 33 | #include "object.h" 34 | #include "log.h" 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #define SLOT_ID 0x1234 43 | 44 | #define get_session(x) ((struct session*) x) 45 | 46 | static const CK_MECHANISM_TYPE supported_mechanisms[] = { 47 | CKM_RSA_PKCS, 48 | }; 49 | 50 | static struct config pk11_config = {0}; 51 | static struct session main_session; 52 | 53 | CK_RV C_GetInfo(CK_INFO_PTR info) { 54 | print_log(VERBOSE, "C_GetInfo"); 55 | info->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR; 56 | info->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR; 57 | strncpy_pad(info->manufacturerID, sizeof(info->manufacturerID), TPM2_PK11_MANUFACTURER, sizeof(info->manufacturerID)); 58 | strncpy_pad(info->libraryDescription, sizeof(info->libraryDescription), TPM2_PK11_LIBRARY_DESCRIPTION, sizeof(info->libraryDescription)); 59 | info->flags = 0; 60 | 61 | return CKR_OK; 62 | } 63 | 64 | CK_RV C_GetSlotList(CK_BBOOL present, CK_SLOT_ID_PTR list, CK_ULONG_PTR count) { 65 | print_log(VERBOSE, "C_GetSlotList: present = %s", present ? "true" : "false"); 66 | if (*count && list) 67 | *list = SLOT_ID; 68 | 69 | *count = 1; 70 | 71 | return CKR_OK; 72 | } 73 | 74 | CK_RV C_OpenSession(CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR application, CK_NOTIFY notify, CK_SESSION_HANDLE_PTR session) { 75 | print_log(VERBOSE, "C_OpenSession: id = %d, flags = %x", id, flags); 76 | *session = (unsigned long) malloc(sizeof(struct session)); 77 | if ((void*) *session == NULL) 78 | return CKR_GENERAL_ERROR; 79 | 80 | int ret = session_init((struct session*) *session, &pk11_config); 81 | 82 | return ret != 0 ? CKR_GENERAL_ERROR : CKR_OK; 83 | } 84 | 85 | CK_RV C_CloseSession(CK_SESSION_HANDLE session_handle) { 86 | print_log(VERBOSE, "C_CloseSession: session = %x", session_handle); 87 | session_close(get_session(session_handle)); 88 | free(get_session(session_handle)); 89 | return CKR_OK; 90 | } 91 | 92 | CK_RV C_GetSessionInfo(CK_SESSION_HANDLE session_handle, CK_SESSION_INFO_PTR info) { 93 | print_log(VERBOSE, "C_GetSessionInfo: session = %x", session_handle); 94 | info->slotID = 0; 95 | info->state = CKS_RO_USER_FUNCTIONS; 96 | info->flags = CKF_SERIAL_SESSION; 97 | info->ulDeviceError = 0; 98 | return CKR_OK; 99 | } 100 | 101 | CK_RV C_GetSlotInfo(CK_SLOT_ID id, CK_SLOT_INFO_PTR info) { 102 | print_log(VERBOSE, "C_GetSlotInfo: id = %d", id); 103 | TPMS_CAPABILITY_DATA fixed; 104 | if (tpm_info(main_session.context, TPM2_PT_FIXED, &fixed) != TPM2_RC_SUCCESS) 105 | return CKR_DEVICE_ERROR; 106 | 107 | TPML_TAGGED_TPM_PROPERTY props = fixed.data.tpmProperties; 108 | TPMS_TAGGED_PROPERTY* manufacturer = tpm_info_get(props.tpmProperty, props.count, TPM2_PT_MANUFACTURER); 109 | UINT32 manufacturer_val = manufacturer ? htobe32(manufacturer->value) : 0; 110 | strncpy_pad(info->manufacturerID, sizeof(info->manufacturerID), manufacturer ? (char*) &manufacturer_val : TPM2_PK11_MANUFACTURER, manufacturer ? 4 : sizeof(info->manufacturerID)); 111 | strncpy_pad(info->slotDescription, sizeof(info->slotDescription), TPM2_PK11_SLOT_DESCRIPTION, sizeof(info->slotDescription)); 112 | 113 | info->flags = CKF_TOKEN_PRESENT | CKF_HW_SLOT; 114 | TPMS_TAGGED_PROPERTY* revision = tpm_info_get(props.tpmProperty, props.count, TPM2_PT_REVISION); 115 | info->hardwareVersion.major = revision ? revision->value / 100 : 0; 116 | info->hardwareVersion.minor = revision ? revision->value % 100 : 0; 117 | TPMS_TAGGED_PROPERTY* major = tpm_info_get(props.tpmProperty, props.count, TPM2_PT_FIRMWARE_VERSION_1); 118 | info->firmwareVersion.major = major ? major->value : 0; 119 | TPMS_TAGGED_PROPERTY* minor = tpm_info_get(props.tpmProperty, props.count, TPM2_PT_FIRMWARE_VERSION_2); 120 | info->firmwareVersion.minor = major ? major->value : 0; 121 | return CKR_OK; 122 | } 123 | 124 | CK_RV C_GetTokenInfo(CK_SLOT_ID id, CK_TOKEN_INFO_PTR info) { 125 | print_log(VERBOSE, "C_GetTokenInfo: id = %d", id); 126 | TPMS_CAPABILITY_DATA fixed; 127 | if (tpm_info(main_session.context, TPM2_PT_FIXED, &fixed) != TPM2_RC_SUCCESS) 128 | return CKR_DEVICE_ERROR; 129 | 130 | TPML_TAGGED_TPM_PROPERTY props = fixed.data.tpmProperties; 131 | strncpy_pad(info->label, sizeof(info->label), TPM2_PK11_EMPTY, sizeof(info->label)); 132 | TPMS_TAGGED_PROPERTY* manufacturer = tpm_info_get(props.tpmProperty, props.count, TPM2_PT_MANUFACTURER); 133 | UINT32 manufacturer_val = manufacturer ? htobe32(manufacturer->value) : 0; 134 | strncpy_pad(info->manufacturerID, sizeof(info->manufacturerID), manufacturer ? (char*) &manufacturer_val : TPM2_PK11_MANUFACTURER, manufacturer ? 4 : sizeof(info->manufacturerID)); 135 | strncpy_pad(info->model, sizeof(info->label), TPM2_PK11_MODEL, sizeof(info->label)); 136 | strncpy_pad(info->serialNumber, sizeof(info->serialNumber), TPM2_PK11_SERIAL, sizeof(info->serialNumber)); 137 | strncpy_pad(info->utcTime, sizeof(info->utcTime), "", sizeof(info->utcTime)); 138 | 139 | info->flags = CKF_TOKEN_INITIALIZED | CKF_WRITE_PROTECTED; 140 | if (pk11_config.login_required) 141 | info->flags |= CKF_LOGIN_REQUIRED; 142 | 143 | TPMS_TAGGED_PROPERTY* max_sessions = tpm_info_get(props.tpmProperty, props.count, TPM2_PT_ACTIVE_SESSIONS_MAX); 144 | info->ulMaxSessionCount = max_sessions ? max_sessions->value : CK_EFFECTIVELY_INFINITE; 145 | info->ulSessionCount = open_sessions; 146 | info->ulMaxRwSessionCount = max_sessions ? max_sessions->value : CK_EFFECTIVELY_INFINITE; 147 | info->ulRwSessionCount = 0; 148 | info->ulMaxPinLen = 64; 149 | info->ulMinPinLen = 0; 150 | info->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION; 151 | info->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION; 152 | info->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION; 153 | info->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION; 154 | TPMS_TAGGED_PROPERTY* revision = tpm_info_get(props.tpmProperty, props.count, TPM2_PT_REVISION); 155 | info->hardwareVersion.major = revision ? revision->value / 100 : 0; 156 | info->hardwareVersion.minor = revision ? revision->value % 100 : 0; 157 | TPMS_TAGGED_PROPERTY* major = tpm_info_get(props.tpmProperty, props.count, TPM2_PT_FIRMWARE_VERSION_1); 158 | info->firmwareVersion.major = major ? major->value : 0; 159 | TPMS_TAGGED_PROPERTY* minor = tpm_info_get(props.tpmProperty, props.count, TPM2_PT_FIRMWARE_VERSION_2); 160 | info->firmwareVersion.minor = major ? major->value : 0; 161 | 162 | return CKR_OK; 163 | } 164 | 165 | CK_RV C_Finalize(CK_VOID_PTR reserved) { 166 | print_log(VERBOSE, "C_Finalize"); 167 | session_close(&main_session); 168 | return CKR_OK; 169 | } 170 | 171 | CK_RV C_FindObjectsInit(CK_SESSION_HANDLE session_handle, CK_ATTRIBUTE_PTR filters, CK_ULONG count) { 172 | print_log(VERBOSE, "C_FindObjectsInit: session = %x, count = %d", session_handle, count); 173 | struct session *session = get_session(session_handle); 174 | session->find_cursor = session->objects; 175 | session->filters = filters; 176 | session->num_filters = count; 177 | return CKR_OK; 178 | } 179 | 180 | CK_RV C_FindObjects(CK_SESSION_HANDLE session_handle, CK_OBJECT_HANDLE_PTR object_handle, CK_ULONG max_objects, CK_ULONG_PTR found) { 181 | print_log(VERBOSE, "C_FindObjects: session = %x, max = %d", session_handle, max_objects); 182 | TPMS_CAPABILITY_DATA persistent; 183 | tpm_info(get_session(session_handle)->context, TPM2_HT_PERSISTENT, &persistent); 184 | struct session* session = get_session(session_handle); 185 | *found = 0; 186 | 187 | while (session->find_cursor != NULL && *found < max_objects) { 188 | pObject object = session->find_cursor->object; 189 | bool filtered = false; 190 | for (int j = 0; j < session->num_filters; j++) { 191 | size_t size = 0; 192 | void* value = attr_get(object, session->filters[j].type, &size); 193 | if (session->filters[j].ulValueLen != size || memcmp(session->filters[j].pValue, value, size) != 0) { 194 | filtered = true; 195 | break; 196 | } 197 | } 198 | if (!filtered) { 199 | object_handle[*found] = (CK_OBJECT_HANDLE) session->find_cursor->object; 200 | (*found)++; 201 | } 202 | session->find_cursor = session->find_cursor->next; 203 | } 204 | 205 | return CKR_OK; 206 | } 207 | 208 | CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE session_handle) { 209 | print_log(VERBOSE, "C_FindObjectsFinal: session = %x", session_handle); 210 | return CKR_OK; 211 | } 212 | 213 | CK_RV C_GetAttributeValue(CK_SESSION_HANDLE session_handle, CK_OBJECT_HANDLE object_handle, CK_ATTRIBUTE_PTR template, CK_ULONG count) { 214 | print_log(VERBOSE, "C_GetAttributeValue: session = %x, object = %x, count = %d", session_handle, object_handle, count); 215 | pObject object = (pObject) object_handle; 216 | 217 | for (int i = 0; i < count; i++) { 218 | void* entry_obj = NULL; 219 | pAttrIndex entry = NULL; 220 | for (int j = 0; j < object->num_entries; j++) { 221 | void *obj = object->entries[j].object; 222 | pAttrIndex index = object->entries[j].indexes; 223 | for (int k = 0; k < object->entries[j].num_attrs; k++) { 224 | if (template[i].type == index[k].type) { 225 | entry = &index[k]; 226 | entry_obj = obj; 227 | continue; 228 | } 229 | } 230 | if (entry) 231 | continue; 232 | } 233 | if (!entry) { 234 | print_log(DEBUG, " attribute not found: type = %x", template[i].type); 235 | template[i].ulValueLen = 0; 236 | } else if (entry->size_offset == 0) { 237 | print_log(DEBUG, " return attribute: type = %x, size = %d, buffer_size = %d", template[i].type, entry->size, template[i].ulValueLen); 238 | retmem(template[i].pValue, &template[i].ulValueLen, entry_obj + entry->offset, entry->size); 239 | } else { 240 | print_log(DEBUG, " return attribute: type = %x, size = %d, buffer_size = %d", template[i].type, *((size_t*) (entry_obj + entry->size_offset)), template[i].ulValueLen); 241 | retmem(template[i].pValue, &template[i].ulValueLen, *((void**) (entry_obj + entry->offset)), *((size_t*) (entry_obj + entry->size_offset))); 242 | } 243 | } 244 | 245 | return CKR_OK; 246 | } 247 | 248 | CK_RV C_SignInit(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { 249 | print_log(VERBOSE, "C_SignInit: session = %x, key = %x", session_handle, key); 250 | pObject object = (pObject) key; 251 | struct session* session = get_session(session_handle); 252 | session->key_handle = object->tpm_handle; 253 | session->current_object = object; 254 | return CKR_OK; 255 | } 256 | 257 | CK_RV C_Sign(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR data, CK_ULONG data_len, CK_BYTE_PTR signature, CK_ULONG_PTR signature_len) { 258 | print_log(VERBOSE, "C_Sign: session = %x, len = %d", session_handle, data_len); 259 | struct session* session = get_session(session_handle); 260 | TPM2_RC ret; 261 | 262 | if (pk11_config.sign_using_encrypt) { 263 | TPM2B_PUBLIC_KEY_RSA message = { .TSS_COMPAT_TMPB(size) = TPM2_MAX_RSA_KEY_BYTES }; 264 | pObject object = session->current_object->opposite; 265 | CK_ULONG_PTR key_size = (CK_ULONG_PTR) attr_get(object, CKA_MODULUS_BITS, NULL); 266 | ret = tpm_sign_encrypt(session->context, session->key_handle, *key_size / 8, data, data_len, &message, session->password); 267 | retmem(signature, signature_len, message.TSS_COMPAT_TMPB(buffer), message.TSS_COMPAT_TMPB(size)); 268 | } else { 269 | TPMT_SIGNATURE sign = {0}; 270 | ret = tpm_sign(session->context, session->key_handle, data, data_len, &sign, session->password); 271 | retmem(signature, signature_len, sign.signature.rsassa.sig.TSS_COMPAT_TMPB(buffer), sign.signature.rsassa.sig.TSS_COMPAT_TMPB(size)); 272 | } 273 | 274 | return ret == TPM2_RC_SUCCESS ? CKR_OK : CKR_GENERAL_ERROR; 275 | } 276 | 277 | CK_RV C_DecryptInit(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { 278 | print_log(VERBOSE, "C_DecryptInit: session = %x, key = %x", session_handle, key); 279 | pObject object = (pObject) key; 280 | get_session(session_handle)->key_handle = object->tpm_handle; 281 | return CKR_OK; 282 | } 283 | 284 | CK_RV C_Decrypt(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR enc_data, CK_ULONG enc_data_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len) { 285 | print_log(VERBOSE, "C_Decrypt: session = %x, len = %d", session_handle, enc_data_len); 286 | TPM2B_PUBLIC_KEY_RSA message = { .TSS_COMPAT_TMPB(size) = TPM2_MAX_RSA_KEY_BYTES }; 287 | struct session* session = get_session(session_handle); 288 | TPM2_RC ret = tpm_decrypt(session->context, session->key_handle, enc_data, enc_data_len, &message, session->password); 289 | retmem(data, data_len, message.TSS_COMPAT_TMPB(buffer), message.TSS_COMPAT_TMPB(size)); 290 | 291 | return ret == TPM2_RC_SUCCESS ? CKR_OK : CKR_GENERAL_ERROR; 292 | } 293 | 294 | CK_RV C_Initialize(CK_VOID_PTR pInitArgs) { 295 | print_log(VERBOSE, "C_Initialize"); 296 | char configfile_path[256]; 297 | snprintf(configfile_path, sizeof(configfile_path), "%s/" TPM2_PK11_CONFIG_DIR "/" TPM2_PK11_CONFIG_FILE, getenv("HOME")); 298 | if (config_load(configfile_path, &pk11_config) < 0) 299 | return CKR_GENERAL_ERROR; 300 | 301 | session_init(&main_session, &pk11_config); 302 | log_init(pk11_config.log_file, pk11_config.log_level); 303 | return CKR_OK; 304 | } 305 | 306 | /* Stubs for not yet supported functions*/ 307 | CK_RV C_GetMechanismList(CK_SLOT_ID id, CK_MECHANISM_TYPE_PTR list, CK_ULONG_PTR count) { 308 | print_log(VERBOSE, "C_GetMechanismList: slot = %d", id); 309 | 310 | if (count == NULL_PTR) 311 | return CKR_ARGUMENTS_BAD; 312 | 313 | int countSupported = sizeof(supported_mechanisms) / sizeof(CK_MECHANISM_TYPE); 314 | 315 | if (list != NULL_PTR && *count < countSupported) { 316 | *count = countSupported; 317 | return CKR_BUFFER_TOO_SMALL; 318 | } 319 | 320 | *count = countSupported; 321 | if (list != NULL_PTR) { 322 | for (CK_ULONG i = 0; i < countSupported; i++) { 323 | list[i] = supported_mechanisms[i]; 324 | } 325 | } 326 | 327 | return CKR_OK; 328 | } 329 | 330 | CK_RV C_GetMechanismInfo (CK_SLOT_ID id, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR info) { 331 | print_log(VERBOSE, "C_GetMechanismInfo: slot = %d", id); 332 | return CKR_FUNCTION_NOT_SUPPORTED; 333 | } 334 | 335 | CK_RV C_InitToken (CK_SLOT_ID id, CK_CHAR_PTR pin, CK_ULONG pin_len, CK_CHAR_PTR label) { 336 | print_log(VERBOSE, "C_InitToken: slot = %d", id); 337 | return CKR_FUNCTION_NOT_SUPPORTED; 338 | } 339 | 340 | CK_RV C_InitPIN (CK_SESSION_HANDLE session_handle, CK_CHAR_PTR pin, CK_ULONG pin_len) { 341 | print_log(VERBOSE, "C_InitPIN: session = %x", session_handle); 342 | return CKR_FUNCTION_NOT_SUPPORTED; 343 | } 344 | 345 | CK_RV C_SetPIN (CK_SESSION_HANDLE session_handle, CK_CHAR_PTR old_pin, CK_ULONG old_pin_len, CK_CHAR_PTR new_pin, CK_ULONG new_pin_len) { 346 | print_log(VERBOSE, "C_SetPIN: session = %x", session_handle); 347 | return CKR_FUNCTION_NOT_SUPPORTED; 348 | } 349 | 350 | 351 | CK_RV C_CloseAllSessions (CK_SLOT_ID id) { 352 | print_log(VERBOSE, "C_CloseAllSessions: slot = %d", id); 353 | return CKR_FUNCTION_NOT_SUPPORTED; 354 | } 355 | 356 | CK_RV C_GetOperationState(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR state, CK_ULONG_PTR state_len) { 357 | print_log(VERBOSE, "C_GetOperationState: session = %x, len = %d", session_handle, state_len); 358 | return CKR_FUNCTION_NOT_SUPPORTED; 359 | } 360 | 361 | CK_RV C_SetOperationState(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR state, CK_ULONG state_len, CK_OBJECT_HANDLE enc_key, CK_OBJECT_HANDLE auth_key) { 362 | print_log(VERBOSE, "C_SetOperationState: session = %x, len = %d, enc_key = %x, auth_key = %x", session_handle, state_len, enc_key, auth_key); 363 | return CKR_FUNCTION_NOT_SUPPORTED; 364 | } 365 | 366 | CK_RV C_Login(CK_SESSION_HANDLE session_handle, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len) { 367 | print_log(VERBOSE, "C_Login: session = %x", session_handle); 368 | 369 | if (userType != CKU_USER) 370 | return CKR_USER_TYPE_INVALID; 371 | 372 | struct session* session = get_session(session_handle); 373 | session->password = strndup(pin, pin_len); 374 | 375 | return CKR_OK; 376 | } 377 | 378 | CK_RV C_Logout(CK_SESSION_HANDLE session_handle) { 379 | print_log(VERBOSE, "C_Logout: session = %x", session_handle); 380 | 381 | struct session* session = get_session(session_handle); 382 | if (session->password) { 383 | free(session->password); 384 | session->password = NULL; 385 | } 386 | 387 | return CKR_OK; 388 | } 389 | 390 | CK_RV C_CreateObject(CK_SESSION_HANDLE session_handle, CK_ATTRIBUTE_PTR template, CK_ULONG count, CK_OBJECT_HANDLE_PTR object) { 391 | print_log(VERBOSE, "C_CreateObject: session = %x, count = %d", session_handle, count); 392 | return CKR_FUNCTION_NOT_SUPPORTED; 393 | } 394 | 395 | CK_RV C_CopyObject(CK_SESSION_HANDLE session_handle, CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR template, CK_ULONG count, CK_OBJECT_HANDLE_PTR new_object) { 396 | print_log(VERBOSE, "C_CopyObject: session = %x, object = %x, count = %d", session_handle, object, count); 397 | return CKR_FUNCTION_NOT_SUPPORTED; 398 | } 399 | 400 | CK_RV C_DestroyObject(CK_SESSION_HANDLE session_handle, CK_OBJECT_HANDLE object) { 401 | print_log(VERBOSE, "C_DestroyObject: session = %x, object = %x", session_handle, object); 402 | return CKR_FUNCTION_NOT_SUPPORTED; 403 | } 404 | 405 | CK_RV C_GetObjectSize(CK_SESSION_HANDLE session_handle, CK_OBJECT_HANDLE object, CK_ULONG_PTR size) { 406 | print_log(VERBOSE, "C_GetObjectSize: session = %x, object = %x", session_handle, object); 407 | return CKR_FUNCTION_NOT_SUPPORTED; 408 | } 409 | 410 | 411 | CK_RV C_SetAttributeValue(CK_SESSION_HANDLE session_handle, CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR template, CK_ULONG count) { 412 | print_log(VERBOSE, "C_SetAttributeValue: session = %x, object = %x, count = %d", session_handle, object, count); 413 | return CKR_FUNCTION_NOT_SUPPORTED; 414 | } 415 | 416 | CK_RV C_EncryptInit(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE object) { 417 | print_log(VERBOSE, "C_EncryptInit: session = %x, object = %x", session_handle, object); 418 | return CKR_FUNCTION_NOT_SUPPORTED; 419 | } 420 | 421 | CK_RV C_Encrypt(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR data, CK_ULONG data_len, CK_BYTE_PTR enc_data, CK_ULONG_PTR enc_data_len) { 422 | print_log(VERBOSE, "C_Encrypt: session = %x, len = %x", session_handle, data_len); 423 | return CKR_FUNCTION_NOT_SUPPORTED; 424 | } 425 | 426 | CK_RV C_EncryptUpdate(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR data, CK_ULONG data_len, CK_BYTE_PTR enc_data, CK_ULONG_PTR enc_data_len) { 427 | print_log(VERBOSE, "C_EncryptUpdate: session = %x, len = %x", session_handle, data_len); 428 | return CKR_FUNCTION_NOT_SUPPORTED; 429 | } 430 | 431 | CK_RV C_EncryptFinal(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR enc_data, CK_ULONG_PTR enc_data_len) { 432 | print_log(VERBOSE, "C_EncryptFinal: session = %x", session_handle); 433 | return CKR_FUNCTION_NOT_SUPPORTED; 434 | } 435 | 436 | CK_RV C_DecryptUpdate(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR enc_data, CK_ULONG enc_data_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len) { 437 | print_log(VERBOSE, "C_DecryptUpdate: session = %x, len = %x", session_handle, enc_data_len); 438 | return CKR_FUNCTION_NOT_SUPPORTED; 439 | } 440 | 441 | CK_RV C_DecryptFinal(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR data, CK_ULONG_PTR data_len) { 442 | print_log(VERBOSE, "C_DecryptFinal: session = %x", session_handle); 443 | return CKR_FUNCTION_NOT_SUPPORTED; 444 | } 445 | 446 | CK_RV C_DigestInit(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism) { 447 | print_log(VERBOSE, "C_DigestInit: session = %x", session_handle); 448 | return CKR_FUNCTION_NOT_SUPPORTED; 449 | } 450 | 451 | CK_RV C_Digest(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR data, CK_ULONG data_len, CK_BYTE_PTR digest, CK_ULONG_PTR digest_len) { 452 | print_log(VERBOSE, "C_Digest: session = %x, len = %x", session_handle, data_len); 453 | return CKR_FUNCTION_NOT_SUPPORTED; 454 | } 455 | 456 | CK_RV C_DigestUpdate(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR part, CK_ULONG part_len) { 457 | print_log(VERBOSE, "C_DigestUpdate: session = %x, len = %x", session_handle, part_len); 458 | return CKR_FUNCTION_NOT_SUPPORTED; 459 | } 460 | 461 | CK_RV C_DigestKey(CK_SESSION_HANDLE session_handle, CK_OBJECT_HANDLE object) { 462 | print_log(VERBOSE, "C_DigestKey: session = %x, object = %x", session_handle, object); 463 | return CKR_FUNCTION_NOT_SUPPORTED; 464 | } 465 | 466 | CK_RV C_DigestFinal(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR digest, CK_ULONG_PTR digest_len) { 467 | print_log(VERBOSE, "C_DigestFinal: session = %x", session_handle); 468 | return CKR_FUNCTION_NOT_SUPPORTED; 469 | } 470 | 471 | CK_RV C_SignUpdate(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR part, CK_ULONG part_len) { 472 | print_log(VERBOSE, "C_SignUpdate: session = %x, len = %x", session_handle, part_len); 473 | return CKR_FUNCTION_NOT_SUPPORTED; 474 | } 475 | 476 | CK_RV C_SignFinal(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR signature, CK_ULONG_PTR signature_len) { 477 | print_log(VERBOSE, "C_SignFinal: session = %x", session_handle); 478 | return CKR_FUNCTION_NOT_SUPPORTED; 479 | } 480 | 481 | CK_RV C_SignRecoverInit(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { 482 | print_log(VERBOSE, "C_SignRecoverInit: session = %x, key = %x", session_handle, key); 483 | return CKR_FUNCTION_NOT_SUPPORTED; 484 | } 485 | 486 | CK_RV C_SignRecover(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR data, CK_ULONG data_len, CK_BYTE_PTR signature, CK_ULONG_PTR signature_len) { 487 | print_log(VERBOSE, "C_SignRecover: session = %x, len = %d", session_handle, data_len); 488 | return CKR_FUNCTION_NOT_SUPPORTED; 489 | } 490 | 491 | CK_RV C_VerifyInit(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { 492 | print_log(VERBOSE, "C_VerifyInit: session = %x, key = %x", session_handle, key); 493 | return CKR_FUNCTION_NOT_SUPPORTED; 494 | } 495 | 496 | CK_RV C_Verify(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR data, CK_ULONG data_len, CK_BYTE_PTR signature, CK_ULONG signature_len) { 497 | print_log(VERBOSE, "C_Verify: session = %x, len = %d", session_handle, data_len); 498 | return CKR_FUNCTION_NOT_SUPPORTED; 499 | } 500 | 501 | CK_RV C_VerifyUpdate(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR part, CK_ULONG part_len) { 502 | print_log(VERBOSE, "C_VerifyUpdate: session = %x, len = %d", session_handle, part_len); 503 | return CKR_FUNCTION_NOT_SUPPORTED; 504 | } 505 | 506 | CK_RV C_VerifyFinal(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR signature, CK_ULONG signature_len) { 507 | print_log(VERBOSE, "C_VerifyFinal: session = %x", session_handle); 508 | return CKR_FUNCTION_NOT_SUPPORTED; 509 | } 510 | 511 | CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { 512 | print_log(VERBOSE, "C_VerifyRecoverInit: session = %x, key = %x", session_handle, key); 513 | return CKR_FUNCTION_NOT_SUPPORTED; 514 | } 515 | 516 | CK_RV C_VerifyRecover(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR signature, CK_ULONG signature_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len) { 517 | print_log(VERBOSE, "C_VerifyRecover: session = %x, len = %d", session_handle, signature_len); 518 | return CKR_FUNCTION_NOT_SUPPORTED; 519 | } 520 | 521 | CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR part, CK_ULONG part_len, CK_BYTE_PTR enc_part, CK_ULONG_PTR enc_part_len) { 522 | print_log(VERBOSE, "C_DigestEncryptUpdate: session = %x, len = %d", session_handle, part_len); 523 | return CKR_FUNCTION_NOT_SUPPORTED; 524 | } 525 | 526 | CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR part, CK_ULONG part_len, CK_BYTE_PTR dec_part, CK_ULONG_PTR dec_part_len) { 527 | print_log(VERBOSE, "C_DigestEncryptUpdate: session = %x, len = %d", session_handle, part_len); 528 | return CKR_FUNCTION_NOT_SUPPORTED; 529 | } 530 | 531 | CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR part, CK_ULONG part_len, CK_BYTE_PTR enc_part, CK_ULONG_PTR enc_part_len) { 532 | print_log(VERBOSE, "C_DigestEncryptUpdate: session = %x, len = %d", session_handle, part_len); 533 | return CKR_FUNCTION_NOT_SUPPORTED; 534 | } 535 | 536 | CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR enc_part, CK_ULONG enc_part_len, CK_BYTE_PTR part, CK_ULONG_PTR part_len) { 537 | print_log(VERBOSE, "C_DigestEncryptUpdate: session = %x, len = %d", session_handle, enc_part_len); 538 | return CKR_FUNCTION_NOT_SUPPORTED; 539 | } 540 | 541 | CK_RV C_GenerateKey(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism, CK_ATTRIBUTE_PTR template, CK_ULONG count, CK_OBJECT_HANDLE_PTR key) { 542 | print_log(VERBOSE, "C_GenerateKey: session = %x, count = %d", session_handle, count); 543 | return CKR_FUNCTION_NOT_SUPPORTED; 544 | } 545 | 546 | CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism, CK_ATTRIBUTE_PTR public_key_template, CK_ULONG public_key_attr_count, CK_ATTRIBUTE_PTR private_key_template, CK_ULONG private_key_attr_count, CK_OBJECT_HANDLE_PTR public_key, CK_OBJECT_HANDLE_PTR private_key) { 547 | print_log(VERBOSE, "C_GenerateKeyPair: session = %x, public_count = %d, private_count = %d", session_handle, public_key_attr_count, private_key_attr_count); 548 | return CKR_FUNCTION_NOT_SUPPORTED; 549 | } 550 | 551 | CK_RV C_WrapKey(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE wrapping_key, CK_OBJECT_HANDLE key, CK_BYTE_PTR wrapped_key, CK_ULONG_PTR wrapped_key_len) { 552 | print_log(VERBOSE, "C_WrapKey: session = %x, wrapping_key = %x, key = %x", session_handle, wrapping_key, key); 553 | return CKR_FUNCTION_NOT_SUPPORTED; 554 | } 555 | 556 | CK_RV C_UnwrapKey(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE unwrapping_key, CK_BYTE_PTR wrapped_key, CK_ULONG wrapped_key_len, CK_ATTRIBUTE_PTR template, CK_ULONG count, CK_OBJECT_HANDLE_PTR key) { 557 | print_log(VERBOSE, "C_UnwrapKey: session = %x, unwrapping_key = %x, key = %x, count = %d", session_handle, unwrapping_key, key, count); 558 | return CKR_FUNCTION_NOT_SUPPORTED; 559 | } 560 | 561 | CK_RV C_DeriveKey(CK_SESSION_HANDLE session_handle, CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE_PTR template, CK_ULONG count, CK_OBJECT_HANDLE_PTR key) { 562 | print_log(VERBOSE, "C_WrapKey: session = %x, base_key = %x, count = %d", session_handle, base_key, count); 563 | return CKR_FUNCTION_NOT_SUPPORTED; 564 | } 565 | 566 | CK_RV C_SeedRandom(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR seed, CK_ULONG seed_len) { 567 | print_log(VERBOSE, "C_SeedRandom: session = %x, len = %d", session_handle, seed_len); 568 | return CKR_FUNCTION_NOT_SUPPORTED; 569 | } 570 | 571 | CK_RV C_GenerateRandom(CK_SESSION_HANDLE session_handle, CK_BYTE_PTR random_data, CK_ULONG random_data_len) { 572 | print_log(VERBOSE, "C_GenerateRandom: session = %x, len = %d", session_handle, random_data_len); 573 | return CKR_FUNCTION_NOT_SUPPORTED; 574 | } 575 | 576 | CK_RV C_GetFunctionStatus(CK_SESSION_HANDLE session_handle) { 577 | print_log(VERBOSE, "C_GetFunctionStatus: session = %x", session_handle); 578 | return CKR_FUNCTION_NOT_SUPPORTED; 579 | } 580 | 581 | CK_RV C_CancelFunction(CK_SESSION_HANDLE session_handle) { 582 | print_log(VERBOSE, "C_CancelFunction: session = %x", session_handle); 583 | return CKR_FUNCTION_NOT_SUPPORTED; 584 | } 585 | 586 | CK_RV C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR slot, CK_VOID_PTR reserved) { 587 | print_log(VERBOSE, "C_WaitForSlotEvent: flags = %x", flags); 588 | return CKR_FUNCTION_NOT_SUPPORTED; 589 | } 590 | 591 | static CK_FUNCTION_LIST function_list = { 592 | { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, 593 | .C_Initialize = C_Initialize, 594 | .C_Finalize = C_Finalize, 595 | .C_GetInfo = C_GetInfo, 596 | .C_GetSlotList = C_GetSlotList, 597 | .C_GetSlotInfo = C_GetSlotInfo, 598 | .C_GetTokenInfo = C_GetTokenInfo, 599 | .C_GetMechanismList = C_GetMechanismList, 600 | .C_GetMechanismInfo = C_GetMechanismInfo, 601 | .C_InitToken = C_InitToken, 602 | .C_InitPIN = C_InitPIN, 603 | .C_SetPIN = C_SetPIN, 604 | .C_OpenSession = C_OpenSession, 605 | .C_CloseSession = C_CloseSession, 606 | .C_CloseAllSessions = C_CloseAllSessions, 607 | .C_GetSessionInfo = C_GetSessionInfo, 608 | .C_CloseAllSessions = C_CloseAllSessions, 609 | .C_GetOperationState = C_GetOperationState, 610 | .C_SetOperationState = C_SetOperationState, 611 | .C_Login = C_Login, 612 | .C_Logout = C_Logout, 613 | .C_CreateObject = C_CreateObject, 614 | .C_CopyObject = C_CopyObject, 615 | .C_DestroyObject = C_DestroyObject, 616 | .C_GetObjectSize = C_GetObjectSize, 617 | .C_GetAttributeValue = C_GetAttributeValue, 618 | .C_SetAttributeValue = C_SetAttributeValue, 619 | .C_FindObjectsInit = C_FindObjectsInit, 620 | .C_FindObjects = C_FindObjects, 621 | .C_FindObjectsFinal = C_FindObjectsFinal, 622 | .C_EncryptInit = C_EncryptInit, 623 | .C_Encrypt = C_Encrypt, 624 | .C_EncryptUpdate = C_EncryptUpdate, 625 | .C_EncryptFinal = C_EncryptFinal, 626 | .C_DecryptInit = C_DecryptInit, 627 | .C_Decrypt = C_Decrypt, 628 | .C_DecryptUpdate = C_DecryptUpdate, 629 | .C_DecryptFinal = C_DecryptFinal, 630 | .C_DigestInit = C_DigestInit, 631 | .C_Digest = C_Digest, 632 | .C_DigestUpdate = C_DigestUpdate, 633 | .C_DigestKey = C_DigestKey, 634 | .C_DigestFinal = C_DigestFinal, 635 | .C_SignInit = C_SignInit, 636 | .C_Sign = C_Sign, 637 | .C_SignUpdate = C_SignUpdate, 638 | .C_SignFinal = C_SignFinal, 639 | .C_SignRecoverInit = C_SignRecoverInit, 640 | .C_SignRecover = C_SignRecover, 641 | .C_VerifyInit = C_VerifyInit, 642 | .C_Verify = C_Verify, 643 | .C_VerifyUpdate = C_VerifyUpdate, 644 | .C_VerifyFinal = C_VerifyFinal, 645 | .C_VerifyRecoverInit = C_VerifyRecoverInit, 646 | .C_VerifyRecover = C_VerifyRecover, 647 | .C_DigestEncryptUpdate = C_DigestEncryptUpdate, 648 | .C_DecryptDigestUpdate = C_DecryptDigestUpdate, 649 | .C_SignEncryptUpdate = C_SignEncryptUpdate, 650 | .C_DecryptVerifyUpdate = C_DecryptVerifyUpdate, 651 | .C_GenerateKey = C_GenerateKey, 652 | .C_GenerateKeyPair = C_GenerateKeyPair, 653 | .C_WrapKey = C_WrapKey, 654 | .C_UnwrapKey = C_UnwrapKey, 655 | .C_DeriveKey = C_DeriveKey, 656 | .C_SeedRandom = C_SeedRandom, 657 | .C_GenerateRandom = C_GenerateRandom, 658 | .C_GetFunctionStatus = C_GetFunctionStatus, 659 | .C_CancelFunction = C_CancelFunction, 660 | .C_WaitForSlotEvent = C_WaitForSlotEvent, 661 | }; 662 | 663 | CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR list) { 664 | if (list == NULL_PTR) 665 | return CKR_ARGUMENTS_BAD; 666 | 667 | *list = &function_list; 668 | return CKR_OK; 669 | } 670 | -------------------------------------------------------------------------------- /src/pk11.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #pragma once 28 | 29 | #include 30 | 31 | #include 32 | 33 | #define TPM2_PK11_CONFIG_DIR ".tpm2" 34 | #define TPM2_PK11_CONFIG_FILE "config" 35 | 36 | #define TPM2_PK11_EMPTY "" 37 | #define TPM2_PK11_SLOT_DESCRIPTION "TPM2 PKCS11 slot" 38 | #define TPM2_PK11_MANUFACTURER "Iwan Timmer" 39 | #define TPM2_PK11_LIBRARY_DESCRIPTION "TPM2 PKCS11 Library" 40 | #define TPM2_PK11_MODEL "TPM2" 41 | #define TPM2_PK11_SERIAL "123456789" 42 | -------------------------------------------------------------------------------- /src/pkix.asn: -------------------------------------------------------------------------------- 1 | 2 | PKIX1 { } 3 | 4 | DEFINITIONS IMPLICIT TAGS ::= 5 | 6 | BEGIN 7 | 8 | -- This contains both PKIX1Implicit88 and RFC2630 ASN.1 modules. 9 | 10 | id-pkix OBJECT IDENTIFIER ::= 11 | { iso(1) identified-organization(3) dod(6) internet(1) 12 | security(5) mechanisms(5) pkix(7) } 13 | 14 | -- ISO arc for standard certificate and CRL extensions 15 | 16 | -- authority key identifier OID and syntax 17 | 18 | AuthorityKeyIdentifier ::= SEQUENCE { 19 | keyIdentifier [0] KeyIdentifier OPTIONAL, 20 | authorityCertIssuer [1] GeneralNames OPTIONAL, 21 | authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } 22 | -- authorityCertIssuer and authorityCertSerialNumber shall both 23 | -- be present or both be absgent 24 | 25 | KeyIdentifier ::= OCTET STRING 26 | 27 | -- subject key identifier OID and syntax 28 | 29 | SubjectKeyIdentifier ::= KeyIdentifier 30 | 31 | -- key usage extension OID and syntax 32 | 33 | KeyUsage ::= BIT STRING 34 | 35 | -- Directory string type -- 36 | 37 | DirectoryString ::= CHOICE { 38 | teletexString TeletexString (SIZE (1..MAX)), 39 | printableString PrintableString (SIZE (1..MAX)), 40 | universalString UniversalString (SIZE (1..MAX)), 41 | utf8String UTF8String (SIZE (1..MAX)), 42 | bmpString BMPString (SIZE(1..MAX)), 43 | -- IA5String is added here to handle old UID encoded as ia5String -- 44 | -- See tests/userid/ for more information. It shouldn't be here, -- 45 | -- so if it causes problems, considering dropping it. -- 46 | ia5String IA5String (SIZE(1..MAX)) } 47 | 48 | SubjectAltName ::= GeneralNames 49 | 50 | GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 51 | 52 | GeneralName ::= CHOICE { 53 | otherName [0] AnotherName, 54 | rfc822Name [1] IA5String, 55 | dNSName [2] IA5String, 56 | x400Address [3] ANY, 57 | -- Changed to work with the libtasn1 parser. 58 | directoryName [4] EXPLICIT RDNSequence, --Name, 59 | ediPartyName [5] ANY, --EDIPartyName replaced by ANY to save memory 60 | uniformResourceIdentifier [6] IA5String, 61 | iPAddress [7] OCTET STRING, 62 | registeredID [8] OBJECT IDENTIFIER } 63 | 64 | -- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as 65 | -- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax 66 | 67 | AnotherName ::= SEQUENCE { 68 | type-id OBJECT IDENTIFIER, 69 | value [0] EXPLICIT ANY DEFINED BY type-id } 70 | 71 | -- issuer alternative name extension OID and syntax 72 | 73 | IssuerAltName ::= GeneralNames 74 | 75 | -- basic constraints extension OID and syntax 76 | 77 | BasicConstraints ::= SEQUENCE { 78 | cA BOOLEAN DEFAULT FALSE, 79 | pathLenConstraint INTEGER (0..MAX) OPTIONAL } 80 | 81 | -- CRL distribution points extension OID and syntax 82 | 83 | CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint 84 | 85 | DistributionPoint ::= SEQUENCE { 86 | distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL, 87 | reasons [1] ReasonFlags OPTIONAL, 88 | cRLIssuer [2] GeneralNames OPTIONAL 89 | } 90 | 91 | DistributionPointName ::= CHOICE { 92 | fullName [0] GeneralNames, 93 | nameRelativeToCRLIssuer [1] RelativeDistinguishedName 94 | } 95 | 96 | ReasonFlags ::= BIT STRING 97 | 98 | -- extended key usage extension OID and syntax 99 | 100 | ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId 101 | 102 | KeyPurposeId ::= OBJECT IDENTIFIER 103 | 104 | -- CRL number extension OID and syntax 105 | 106 | CRLNumber ::= INTEGER (0..MAX) 107 | 108 | -- certificate issuer CRL entry extension OID and syntax 109 | 110 | CertificateIssuer ::= GeneralNames 111 | 112 | -- -------------------------------------- 113 | -- EXPLICIT 114 | -- -------------------------------------- 115 | 116 | -- UNIVERSAL Types defined in '93 and '98 ASN.1 117 | -- but required by this specification 118 | 119 | NumericString ::= [UNIVERSAL 18] IMPLICIT OCTET STRING 120 | 121 | IA5String ::= [UNIVERSAL 22] IMPLICIT OCTET STRING 122 | 123 | TeletexString ::= [UNIVERSAL 20] IMPLICIT OCTET STRING 124 | 125 | PrintableString ::= [UNIVERSAL 19] IMPLICIT OCTET STRING 126 | 127 | UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING 128 | -- UniversalString is defined in ASN.1:1993 129 | 130 | BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING 131 | -- BMPString is the subtype of UniversalString and models 132 | -- the Basic Multilingual Plane of ISO/IEC/ITU 10646-1 133 | 134 | UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING 135 | -- The content of this type conforms to RFC 2279. 136 | 137 | 138 | -- attribute data types -- 139 | 140 | Attribute ::= SEQUENCE { 141 | type AttributeType, 142 | values SET OF AttributeValue 143 | -- at least one value is required -- 144 | } 145 | 146 | AttributeType ::= OBJECT IDENTIFIER 147 | 148 | AttributeValue ::= ANY DEFINED BY type 149 | 150 | AttributeTypeAndValue ::= SEQUENCE { 151 | type AttributeType, 152 | value AttributeValue } 153 | 154 | -- suggested naming attributes: Definition of the following 155 | -- information object set may be augmented to meet local 156 | -- requirements. Note that deleting members of the set may 157 | -- prevent interoperability with conforming implementations. 158 | -- presented in pairs: the AttributeType followed by the 159 | -- type definition for the corresponding AttributeValue 160 | 161 | -- Arc for standard naming attributes 162 | id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} 163 | 164 | -- Attributes of type NameDirectoryString 165 | 166 | -- gnutls: Note that the Object ID (id-at*) is being set just before the 167 | -- actual definition. This is done in order for asn1_find_structure_from_oid 168 | -- to work (locate structure from OID). 169 | -- Maybe this is inefficient and memory consuming. Should we replace with 170 | -- a table that maps OIDs to structures? 171 | 172 | PostalAddress ::= SEQUENCE OF DirectoryString 173 | 174 | -- Legacy attributes 175 | 176 | emailAddress AttributeType ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 1 } 177 | 178 | Pkcs9email ::= IA5String (SIZE (1..ub-emailaddress-length)) 179 | 180 | -- naming data types -- 181 | 182 | Name ::= CHOICE { -- only one possibility for now -- 183 | rdnSequence RDNSequence } 184 | 185 | RDNSequence ::= SEQUENCE OF RelativeDistinguishedName 186 | 187 | DistinguishedName ::= RDNSequence 188 | 189 | RelativeDistinguishedName ::= 190 | SET SIZE (1 .. MAX) OF AttributeTypeAndValue 191 | 192 | 193 | 194 | -- -------------------------------------------------------- 195 | -- certificate and CRL specific structures begin here 196 | -- -------------------------------------------------------- 197 | 198 | Certificate ::= SEQUENCE { 199 | tbsCertificate TBSCertificate, 200 | signatureAlgorithm AlgorithmIdentifier, 201 | signature BIT STRING } 202 | 203 | TBSCertificate ::= SEQUENCE { 204 | version [0] EXPLICIT Version DEFAULT v1, 205 | serialNumber CertificateSerialNumber, 206 | signature AlgorithmIdentifier, 207 | issuer Name, 208 | validity Validity, 209 | subject Name, 210 | subjectPublicKeyInfo SubjectPublicKeyInfo, 211 | issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, 212 | -- If present, version shall be v2 or v3 213 | subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, 214 | -- If present, version shall be v2 or v3 215 | extensions [3] EXPLICIT Extensions OPTIONAL 216 | -- If present, version shall be v3 -- 217 | } 218 | 219 | Version ::= INTEGER { v1(0), v2(1), v3(2) } 220 | 221 | CertificateSerialNumber ::= INTEGER 222 | 223 | Validity ::= SEQUENCE { 224 | notBefore Time, 225 | notAfter Time } 226 | 227 | Time ::= CHOICE { 228 | utcTime UTCTime, 229 | generalTime GeneralizedTime } 230 | 231 | UniqueIdentifier ::= BIT STRING 232 | 233 | SubjectPublicKeyInfo ::= SEQUENCE { 234 | algorithm AlgorithmIdentifier, 235 | subjectPublicKey BIT STRING } 236 | 237 | Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 238 | 239 | Extension ::= SEQUENCE { 240 | extnID OBJECT IDENTIFIER, 241 | critical BOOLEAN DEFAULT FALSE, 242 | extnValue OCTET STRING } 243 | 244 | 245 | -- ------------------------------------------ 246 | -- CRL structures 247 | -- ------------------------------------------ 248 | 249 | CertificateList ::= SEQUENCE { 250 | tbsCertList TBSCertList, 251 | signatureAlgorithm AlgorithmIdentifier, 252 | signature BIT STRING } 253 | 254 | TBSCertList ::= SEQUENCE { 255 | version Version OPTIONAL, 256 | -- if present, shall be v2 257 | signature AlgorithmIdentifier, 258 | issuer Name, 259 | thisUpdate Time, 260 | nextUpdate Time OPTIONAL, 261 | revokedCertificates SEQUENCE OF SEQUENCE { 262 | userCertificate CertificateSerialNumber, 263 | revocationDate Time, 264 | crlEntryExtensions Extensions OPTIONAL 265 | -- if present, shall be v2 266 | } OPTIONAL, 267 | crlExtensions [0] EXPLICIT Extensions OPTIONAL 268 | -- if present, shall be v2 -- 269 | } 270 | 271 | -- Version, Time, CertificateSerialNumber, and Extensions were 272 | -- defined earlier for use in the certificate structure 273 | 274 | AlgorithmIdentifier ::= SEQUENCE { 275 | algorithm OBJECT IDENTIFIER, 276 | parameters ANY DEFINED BY algorithm OPTIONAL } 277 | -- contains a value of the type 278 | -- registered for use with the 279 | -- algorithm object identifier value 280 | 281 | -- Algorithm OIDs and parameter structures 282 | 283 | Dss-Sig-Value ::= SEQUENCE { 284 | r INTEGER, 285 | s INTEGER 286 | } 287 | 288 | DomainParameters ::= SEQUENCE { 289 | p INTEGER, -- odd prime, p=jq +1 290 | g INTEGER, -- generator, g 291 | q INTEGER, -- factor of p-1 292 | j INTEGER OPTIONAL, -- subgroup factor, j>= 2 293 | validationParms ValidationParms OPTIONAL } 294 | 295 | ValidationParms ::= SEQUENCE { 296 | seed BIT STRING, 297 | pgenCounter INTEGER } 298 | 299 | Dss-Parms ::= SEQUENCE { 300 | p INTEGER, 301 | q INTEGER, 302 | g INTEGER } 303 | 304 | -- x400 address syntax starts here 305 | -- OR Names 306 | 307 | CountryName ::= [APPLICATION 1] CHOICE { 308 | x121-dcc-code NumericString 309 | (SIZE (ub-country-name-numeric-length)), 310 | iso-3166-alpha2-code PrintableString 311 | (SIZE (ub-country-name-alpha-length)) } 312 | 313 | OrganizationName ::= PrintableString 314 | (SIZE (1..ub-organization-name-length)) 315 | -- see also teletex-organization-name 316 | 317 | NumericUserIdentifier ::= NumericString 318 | (SIZE (1..ub-numeric-user-id-length)) 319 | 320 | -- see also teletex-personal-name 321 | 322 | OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) 323 | OF OrganizationalUnitName 324 | -- see also teletex-organizational-unit-names 325 | 326 | OrganizationalUnitName ::= PrintableString (SIZE 327 | (1..ub-organizational-unit-name-length)) 328 | 329 | -- Extension types and attribute values 330 | -- 331 | 332 | CommonName ::= PrintableString 333 | 334 | -- END of PKIX1Implicit88 335 | 336 | 337 | -- BEGIN of RFC2630 338 | 339 | -- Cryptographic Message Syntax 340 | 341 | pkcs-7-ContentInfo ::= SEQUENCE { 342 | contentType pkcs-7-ContentType, 343 | content [0] EXPLICIT ANY DEFINED BY contentType } 344 | 345 | pkcs-7-DigestInfo ::= SEQUENCE { 346 | digestAlgorithm pkcs-7-DigestAlgorithmIdentifier, 347 | digest pkcs-7-Digest 348 | } 349 | 350 | pkcs-7-Digest ::= OCTET STRING 351 | 352 | pkcs-7-ContentType ::= OBJECT IDENTIFIER 353 | 354 | pkcs-7-SignedData ::= SEQUENCE { 355 | version pkcs-7-CMSVersion, 356 | digestAlgorithms pkcs-7-DigestAlgorithmIdentifiers, 357 | encapContentInfo pkcs-7-EncapsulatedContentInfo, 358 | certificates [0] IMPLICIT pkcs-7-CertificateSet OPTIONAL, 359 | crls [1] IMPLICIT pkcs-7-CertificateRevocationLists OPTIONAL, 360 | signerInfos pkcs-7-SignerInfos 361 | } 362 | 363 | pkcs-7-CMSVersion ::= INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4) } 364 | 365 | pkcs-7-DigestAlgorithmIdentifiers ::= SET OF pkcs-7-DigestAlgorithmIdentifier 366 | 367 | pkcs-7-DigestAlgorithmIdentifier ::= AlgorithmIdentifier 368 | 369 | pkcs-7-EncapsulatedContentInfo ::= SEQUENCE { 370 | eContentType pkcs-7-ContentType, 371 | eContent [0] EXPLICIT OCTET STRING OPTIONAL } 372 | 373 | -- We don't use CertificateList here since we only want 374 | -- to read the raw data. 375 | pkcs-7-CertificateRevocationLists ::= SET OF ANY 376 | 377 | pkcs-7-CertificateChoices ::= CHOICE { 378 | -- Although the paper uses Certificate type, we 379 | -- don't use it since, we don't need to parse it. 380 | -- We only need to read and store it. 381 | certificate ANY 382 | } 383 | 384 | pkcs-7-CertificateSet ::= SET OF pkcs-7-CertificateChoices 385 | 386 | pkcs-7-SignerInfos ::= SET OF ANY -- this is not correct but we don't use it 387 | -- anyway 388 | 389 | 390 | -- BEGIN of RFC2986 391 | 392 | -- Certificate requests 393 | pkcs-10-CertificationRequestInfo ::= SEQUENCE { 394 | version INTEGER { v1(0) }, 395 | subject Name, 396 | subjectPKInfo SubjectPublicKeyInfo, 397 | attributes [0] Attributes 398 | } 399 | 400 | Attributes ::= SET OF Attribute 401 | 402 | pkcs-10-CertificationRequest ::= SEQUENCE { 403 | certificationRequestInfo pkcs-10-CertificationRequestInfo, 404 | signatureAlgorithm AlgorithmIdentifier, 405 | signature BIT STRING 406 | } 407 | 408 | -- stuff from PKCS#9 409 | 410 | pkcs-9-at-challengePassword OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 7} 411 | 412 | pkcs-9-challengePassword ::= CHOICE { 413 | printableString PrintableString, 414 | utf8String UTF8String } 415 | 416 | pkcs-9-localKeyId ::= OCTET STRING 417 | 418 | -- PKCS #8 stuff 419 | 420 | -- Private-key information syntax 421 | 422 | pkcs-8-PrivateKeyInfo ::= SEQUENCE { 423 | version pkcs-8-Version, 424 | privateKeyAlgorithm AlgorithmIdentifier, 425 | privateKey pkcs-8-PrivateKey, 426 | attributes [0] Attributes OPTIONAL } 427 | 428 | pkcs-8-Version ::= INTEGER {v1(0)} 429 | 430 | pkcs-8-PrivateKey ::= OCTET STRING 431 | 432 | pkcs-8-Attributes ::= SET OF Attribute 433 | 434 | -- Encrypted private-key information syntax 435 | 436 | pkcs-8-EncryptedPrivateKeyInfo ::= SEQUENCE { 437 | encryptionAlgorithm AlgorithmIdentifier, 438 | encryptedData pkcs-8-EncryptedData 439 | } 440 | 441 | pkcs-8-EncryptedData ::= OCTET STRING 442 | 443 | -- PKCS #5 stuff 444 | 445 | pkcs-5-des-EDE3-CBC-params ::= OCTET STRING (SIZE(8)) 446 | pkcs-5-aes128-CBC-params ::= OCTET STRING (SIZE(16)) 447 | pkcs-5-aes192-CBC-params ::= OCTET STRING (SIZE(16)) 448 | pkcs-5-aes256-CBC-params ::= OCTET STRING (SIZE(16)) 449 | 450 | pkcs-5-PBES2-params ::= SEQUENCE { 451 | keyDerivationFunc AlgorithmIdentifier, 452 | encryptionScheme AlgorithmIdentifier } 453 | 454 | -- PBKDF2 455 | 456 | -- pkcs-5-algid-hmacWithSHA1 AlgorithmIdentifier ::= 457 | -- {algorithm pkcs-5-id-hmacWithSHA1, parameters NULL : NULL} 458 | 459 | pkcs-5-PBKDF2-params ::= SEQUENCE { 460 | salt CHOICE { 461 | specified OCTET STRING, 462 | otherSource AlgorithmIdentifier 463 | }, 464 | iterationCount INTEGER (1..MAX), 465 | keyLength INTEGER (1..MAX) OPTIONAL, 466 | prf AlgorithmIdentifier OPTIONAL -- DEFAULT pkcs-5-id-hmacWithSHA1 467 | } 468 | 469 | -- PKCS #12 stuff 470 | 471 | pkcs-12-PFX ::= SEQUENCE { 472 | version INTEGER {v3(3)}, 473 | authSafe pkcs-7-ContentInfo, 474 | macData pkcs-12-MacData OPTIONAL 475 | } 476 | 477 | pkcs-12-PbeParams ::= SEQUENCE { 478 | salt OCTET STRING, 479 | iterations INTEGER 480 | } 481 | 482 | pkcs-12-MacData ::= SEQUENCE { 483 | mac pkcs-7-DigestInfo, 484 | macSalt OCTET STRING, 485 | iterations INTEGER DEFAULT 1 486 | -- Note: The default is for historical reasons and its use is 487 | -- deprecated. A higher value, like 1024 is recommended. 488 | } 489 | 490 | pkcs-12-AuthenticatedSafe ::= SEQUENCE OF pkcs-7-ContentInfo 491 | -- Data if unencrypted 492 | -- EncryptedData if password-encrypted 493 | -- EnvelopedData if public key-encrypted 494 | 495 | pkcs-12-SafeContents ::= SEQUENCE OF pkcs-12-SafeBag 496 | 497 | pkcs-12-SafeBag ::= SEQUENCE { 498 | bagId OBJECT IDENTIFIER, 499 | bagValue [0] EXPLICIT ANY DEFINED BY badId, 500 | bagAttributes SET OF pkcs-12-PKCS12Attribute OPTIONAL 501 | } 502 | 503 | -- Bag types 504 | 505 | pkcs-12-KeyBag ::= pkcs-8-PrivateKeyInfo 506 | 507 | -- Shrouded KeyBag 508 | 509 | pkcs-12-PKCS8ShroudedKeyBag ::= pkcs-8-EncryptedPrivateKeyInfo 510 | 511 | -- CertBag 512 | 513 | pkcs-12-CertBag ::= SEQUENCE { 514 | certId OBJECT IDENTIFIER, 515 | certValue [0] EXPLICIT ANY DEFINED BY certId 516 | } 517 | 518 | -- x509Certificate BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {pkcs-9-certTypes 1}} 519 | -- DER-encoded X.509 certificate stored in OCTET STRING 520 | 521 | pkcs-12-CRLBag ::= SEQUENCE { 522 | crlId OBJECT IDENTIFIER, 523 | crlValue [0] EXPLICIT ANY DEFINED BY crlId 524 | } 525 | 526 | pkcs-12-SecretBag ::= SEQUENCE { 527 | secretTypeId OBJECT IDENTIFIER, 528 | secretValue [0] EXPLICIT ANY DEFINED BY secretTypeId 529 | } 530 | 531 | -- x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {pkcs-9-crlTypes 1}} 532 | -- DER-encoded X.509 CRL stored in OCTET STRING 533 | 534 | pkcs-12-PKCS12Attribute ::= Attribute 535 | 536 | -- PKCS #7 stuff (needed in PKCS 12) 537 | 538 | pkcs-7-Data ::= OCTET STRING 539 | 540 | pkcs-7-EncryptedData ::= SEQUENCE { 541 | version pkcs-7-CMSVersion, 542 | encryptedContentInfo pkcs-7-EncryptedContentInfo, 543 | unprotectedAttrs [1] IMPLICIT pkcs-7-UnprotectedAttributes OPTIONAL } 544 | 545 | pkcs-7-EncryptedContentInfo ::= SEQUENCE { 546 | contentType pkcs-7-ContentType, 547 | contentEncryptionAlgorithm pkcs-7-ContentEncryptionAlgorithmIdentifier, 548 | encryptedContent [0] IMPLICIT pkcs-7-EncryptedContent OPTIONAL } 549 | 550 | pkcs-7-ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier 551 | 552 | pkcs-7-EncryptedContent ::= OCTET STRING 553 | 554 | pkcs-7-UnprotectedAttributes ::= SET SIZE (1..MAX) OF Attribute 555 | 556 | -- rfc3820 557 | 558 | ProxyCertInfo ::= SEQUENCE { 559 | pCPathLenConstraint INTEGER (0..MAX) OPTIONAL, 560 | proxyPolicy ProxyPolicy } 561 | 562 | ProxyPolicy ::= SEQUENCE { 563 | policyLanguage OBJECT IDENTIFIER, 564 | policy OCTET STRING OPTIONAL } 565 | 566 | END 567 | -------------------------------------------------------------------------------- /src/pkix_asn1_tab.c: -------------------------------------------------------------------------------- 1 | #if HAVE_CONFIG_H 2 | # include "config.h" 3 | #endif 4 | 5 | #include 6 | 7 | const asn1_static_node pkix_asn1_tab[] = { 8 | { "PKIX1", 536875024, NULL }, 9 | { NULL, 1073741836, NULL }, 10 | { "id-pkix", 1879048204, NULL }, 11 | { "iso", 1073741825, "1"}, 12 | { "identified-organization", 1073741825, "3"}, 13 | { "dod", 1073741825, "6"}, 14 | { "internet", 1073741825, "1"}, 15 | { "security", 1073741825, "5"}, 16 | { "mechanisms", 1073741825, "5"}, 17 | { "pkix", 1, "7"}, 18 | { "AuthorityKeyIdentifier", 1610612741, NULL }, 19 | { "keyIdentifier", 1610637314, "KeyIdentifier"}, 20 | { NULL, 4104, "0"}, 21 | { "authorityCertIssuer", 1610637314, "GeneralNames"}, 22 | { NULL, 4104, "1"}, 23 | { "authorityCertSerialNumber", 536895490, "CertificateSerialNumber"}, 24 | { NULL, 4104, "2"}, 25 | { "KeyIdentifier", 1073741831, NULL }, 26 | { "SubjectKeyIdentifier", 1073741826, "KeyIdentifier"}, 27 | { "KeyUsage", 1073741830, NULL }, 28 | { "DirectoryString", 1610612754, NULL }, 29 | { "teletexString", 1612709918, NULL }, 30 | { "MAX", 524298, "1"}, 31 | { "printableString", 1612709919, NULL }, 32 | { "MAX", 524298, "1"}, 33 | { "universalString", 1612709920, NULL }, 34 | { "MAX", 524298, "1"}, 35 | { "utf8String", 1612709922, NULL }, 36 | { "MAX", 524298, "1"}, 37 | { "bmpString", 1612709921, NULL }, 38 | { "MAX", 524298, "1"}, 39 | { "ia5String", 538968093, NULL }, 40 | { "MAX", 524298, "1"}, 41 | { "SubjectAltName", 1073741826, "GeneralNames"}, 42 | { "GeneralNames", 1612709899, NULL }, 43 | { "MAX", 1074266122, "1"}, 44 | { NULL, 2, "GeneralName"}, 45 | { "GeneralName", 1610612754, NULL }, 46 | { "otherName", 1610620930, "AnotherName"}, 47 | { NULL, 4104, "0"}, 48 | { "rfc822Name", 1610620957, NULL }, 49 | { NULL, 4104, "1"}, 50 | { "dNSName", 1610620957, NULL }, 51 | { NULL, 4104, "2"}, 52 | { "x400Address", 1610620941, NULL }, 53 | { NULL, 4104, "3"}, 54 | { "directoryName", 1610620930, "RDNSequence"}, 55 | { NULL, 2056, "4"}, 56 | { "ediPartyName", 1610620941, NULL }, 57 | { NULL, 4104, "5"}, 58 | { "uniformResourceIdentifier", 1610620957, NULL }, 59 | { NULL, 4104, "6"}, 60 | { "iPAddress", 1610620935, NULL }, 61 | { NULL, 4104, "7"}, 62 | { "registeredID", 536879116, NULL }, 63 | { NULL, 4104, "8"}, 64 | { "AnotherName", 1610612741, NULL }, 65 | { "type-id", 1073741836, NULL }, 66 | { "value", 541073421, NULL }, 67 | { NULL, 1073743880, "0"}, 68 | { "type-id", 1, NULL }, 69 | { "IssuerAltName", 1073741826, "GeneralNames"}, 70 | { "BasicConstraints", 1610612741, NULL }, 71 | { "cA", 1610645508, NULL }, 72 | { NULL, 131081, NULL }, 73 | { "pathLenConstraint", 537411587, NULL }, 74 | { "0", 10, "MAX"}, 75 | { "CRLDistributionPoints", 1612709899, NULL }, 76 | { "MAX", 1074266122, "1"}, 77 | { NULL, 2, "DistributionPoint"}, 78 | { "DistributionPoint", 1610612741, NULL }, 79 | { "distributionPoint", 1610637314, "DistributionPointName"}, 80 | { NULL, 2056, "0"}, 81 | { "reasons", 1610637314, "ReasonFlags"}, 82 | { NULL, 4104, "1"}, 83 | { "cRLIssuer", 536895490, "GeneralNames"}, 84 | { NULL, 4104, "2"}, 85 | { "DistributionPointName", 1610612754, NULL }, 86 | { "fullName", 1610620930, "GeneralNames"}, 87 | { NULL, 4104, "0"}, 88 | { "nameRelativeToCRLIssuer", 536879106, "RelativeDistinguishedName"}, 89 | { NULL, 4104, "1"}, 90 | { "ReasonFlags", 1073741830, NULL }, 91 | { "ExtKeyUsageSyntax", 1612709899, NULL }, 92 | { "MAX", 1074266122, "1"}, 93 | { NULL, 2, "KeyPurposeId"}, 94 | { "KeyPurposeId", 1073741836, NULL }, 95 | { "CRLNumber", 1611137027, NULL }, 96 | { "0", 10, "MAX"}, 97 | { "CertificateIssuer", 1073741826, "GeneralNames"}, 98 | { "NumericString", 1610620935, NULL }, 99 | { NULL, 4360, "18"}, 100 | { "IA5String", 1610620935, NULL }, 101 | { NULL, 4360, "22"}, 102 | { "TeletexString", 1610620935, NULL }, 103 | { NULL, 4360, "20"}, 104 | { "PrintableString", 1610620935, NULL }, 105 | { NULL, 4360, "19"}, 106 | { "UniversalString", 1610620935, NULL }, 107 | { NULL, 4360, "28"}, 108 | { "BMPString", 1610620935, NULL }, 109 | { NULL, 4360, "30"}, 110 | { "UTF8String", 1610620935, NULL }, 111 | { NULL, 4360, "12"}, 112 | { "Attribute", 1610612741, NULL }, 113 | { "type", 1073741826, "AttributeType"}, 114 | { "values", 536870927, NULL }, 115 | { NULL, 2, "AttributeValue"}, 116 | { "AttributeType", 1073741836, NULL }, 117 | { "AttributeValue", 1614807053, NULL }, 118 | { "type", 1, NULL }, 119 | { "AttributeTypeAndValue", 1610612741, NULL }, 120 | { "type", 1073741826, "AttributeType"}, 121 | { "value", 2, "AttributeValue"}, 122 | { "id-at", 1879048204, NULL }, 123 | { "joint-iso-ccitt", 1073741825, "2"}, 124 | { "ds", 1073741825, "5"}, 125 | { NULL, 1, "4"}, 126 | { "PostalAddress", 1610612747, NULL }, 127 | { NULL, 2, "DirectoryString"}, 128 | { "emailAddress", 1880096780, "AttributeType"}, 129 | { "iso", 1073741825, "1"}, 130 | { "member-body", 1073741825, "2"}, 131 | { "us", 1073741825, "840"}, 132 | { "rsadsi", 1073741825, "113549"}, 133 | { "pkcs", 1073741825, "1"}, 134 | { NULL, 1073741825, "9"}, 135 | { NULL, 1, "1"}, 136 | { "Pkcs9email", 1612709917, NULL }, 137 | { "ub-emailaddress-length", 524298, "1"}, 138 | { "Name", 1610612754, NULL }, 139 | { "rdnSequence", 2, "RDNSequence"}, 140 | { "RDNSequence", 1610612747, NULL }, 141 | { NULL, 2, "RelativeDistinguishedName"}, 142 | { "DistinguishedName", 1073741826, "RDNSequence"}, 143 | { "RelativeDistinguishedName", 1612709903, NULL }, 144 | { "MAX", 1074266122, "1"}, 145 | { NULL, 2, "AttributeTypeAndValue"}, 146 | { "Certificate", 1610612741, NULL }, 147 | { "tbsCertificate", 1073741826, "TBSCertificate"}, 148 | { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"}, 149 | { "signature", 6, NULL }, 150 | { "TBSCertificate", 1610612741, NULL }, 151 | { "version", 1610653698, "Version"}, 152 | { NULL, 1073741833, "v1"}, 153 | { NULL, 2056, "0"}, 154 | { "serialNumber", 1073741826, "CertificateSerialNumber"}, 155 | { "signature", 1073741826, "AlgorithmIdentifier"}, 156 | { "issuer", 1073741826, "Name"}, 157 | { "validity", 1073741826, "Validity"}, 158 | { "subject", 1073741826, "Name"}, 159 | { "subjectPublicKeyInfo", 1073741826, "SubjectPublicKeyInfo"}, 160 | { "issuerUniqueID", 1610637314, "UniqueIdentifier"}, 161 | { NULL, 4104, "1"}, 162 | { "subjectUniqueID", 1610637314, "UniqueIdentifier"}, 163 | { NULL, 4104, "2"}, 164 | { "extensions", 536895490, "Extensions"}, 165 | { NULL, 2056, "3"}, 166 | { "Version", 1610874883, NULL }, 167 | { "v1", 1073741825, "0"}, 168 | { "v2", 1073741825, "1"}, 169 | { "v3", 1, "2"}, 170 | { "CertificateSerialNumber", 1073741827, NULL }, 171 | { "Validity", 1610612741, NULL }, 172 | { "notBefore", 1073741826, "Time"}, 173 | { "notAfter", 2, "Time"}, 174 | { "Time", 1610612754, NULL }, 175 | { "utcTime", 1073741860, NULL }, 176 | { "generalTime", 37, NULL }, 177 | { "UniqueIdentifier", 1073741830, NULL }, 178 | { "SubjectPublicKeyInfo", 1610612741, NULL }, 179 | { "algorithm", 1073741826, "AlgorithmIdentifier"}, 180 | { "subjectPublicKey", 6, NULL }, 181 | { "Extensions", 1612709899, NULL }, 182 | { "MAX", 1074266122, "1"}, 183 | { NULL, 2, "Extension"}, 184 | { "Extension", 1610612741, NULL }, 185 | { "extnID", 1073741836, NULL }, 186 | { "critical", 1610645508, NULL }, 187 | { NULL, 131081, NULL }, 188 | { "extnValue", 7, NULL }, 189 | { "CertificateList", 1610612741, NULL }, 190 | { "tbsCertList", 1073741826, "TBSCertList"}, 191 | { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"}, 192 | { "signature", 6, NULL }, 193 | { "TBSCertList", 1610612741, NULL }, 194 | { "version", 1073758210, "Version"}, 195 | { "signature", 1073741826, "AlgorithmIdentifier"}, 196 | { "issuer", 1073741826, "Name"}, 197 | { "thisUpdate", 1073741826, "Time"}, 198 | { "nextUpdate", 1073758210, "Time"}, 199 | { "revokedCertificates", 1610629131, NULL }, 200 | { NULL, 536870917, NULL }, 201 | { "userCertificate", 1073741826, "CertificateSerialNumber"}, 202 | { "revocationDate", 1073741826, "Time"}, 203 | { "crlEntryExtensions", 16386, "Extensions"}, 204 | { "crlExtensions", 536895490, "Extensions"}, 205 | { NULL, 2056, "0"}, 206 | { "AlgorithmIdentifier", 1610612741, NULL }, 207 | { "algorithm", 1073741836, NULL }, 208 | { "parameters", 541081613, NULL }, 209 | { "algorithm", 1, NULL }, 210 | { "Dss-Sig-Value", 1610612741, NULL }, 211 | { "r", 1073741827, NULL }, 212 | { "s", 3, NULL }, 213 | { "DomainParameters", 1610612741, NULL }, 214 | { "p", 1073741827, NULL }, 215 | { "g", 1073741827, NULL }, 216 | { "q", 1073741827, NULL }, 217 | { "j", 1073758211, NULL }, 218 | { "validationParms", 16386, "ValidationParms"}, 219 | { "ValidationParms", 1610612741, NULL }, 220 | { "seed", 1073741830, NULL }, 221 | { "pgenCounter", 3, NULL }, 222 | { "Dss-Parms", 1610612741, NULL }, 223 | { "p", 1073741827, NULL }, 224 | { "q", 1073741827, NULL }, 225 | { "g", 3, NULL }, 226 | { "CountryName", 1610620946, NULL }, 227 | { NULL, 1073746952, "1"}, 228 | { "x121-dcc-code", 1612709916, NULL }, 229 | { NULL, 1048586, "ub-country-name-numeric-length"}, 230 | { "iso-3166-alpha2-code", 538968095, NULL }, 231 | { NULL, 1048586, "ub-country-name-alpha-length"}, 232 | { "OrganizationName", 1612709919, NULL }, 233 | { "ub-organization-name-length", 524298, "1"}, 234 | { "NumericUserIdentifier", 1612709916, NULL }, 235 | { "ub-numeric-user-id-length", 524298, "1"}, 236 | { "OrganizationalUnitNames", 1612709899, NULL }, 237 | { "ub-organizational-units", 1074266122, "1"}, 238 | { NULL, 2, "OrganizationalUnitName"}, 239 | { "OrganizationalUnitName", 1612709919, NULL }, 240 | { "ub-organizational-unit-name-length", 524298, "1"}, 241 | { "CommonName", 1073741855, NULL }, 242 | { "pkcs-7-ContentInfo", 1610612741, NULL }, 243 | { "contentType", 1073741826, "pkcs-7-ContentType"}, 244 | { "content", 541073421, NULL }, 245 | { NULL, 1073743880, "0"}, 246 | { "contentType", 1, NULL }, 247 | { "pkcs-7-DigestInfo", 1610612741, NULL }, 248 | { "digestAlgorithm", 1073741826, "pkcs-7-DigestAlgorithmIdentifier"}, 249 | { "digest", 2, "pkcs-7-Digest"}, 250 | { "pkcs-7-Digest", 1073741831, NULL }, 251 | { "pkcs-7-ContentType", 1073741836, NULL }, 252 | { "pkcs-7-SignedData", 1610612741, NULL }, 253 | { "version", 1073741826, "pkcs-7-CMSVersion"}, 254 | { "digestAlgorithms", 1073741826, "pkcs-7-DigestAlgorithmIdentifiers"}, 255 | { "encapContentInfo", 1073741826, "pkcs-7-EncapsulatedContentInfo"}, 256 | { "certificates", 1610637314, "pkcs-7-CertificateSet"}, 257 | { NULL, 4104, "0"}, 258 | { "crls", 1610637314, "pkcs-7-CertificateRevocationLists"}, 259 | { NULL, 4104, "1"}, 260 | { "signerInfos", 2, "pkcs-7-SignerInfos"}, 261 | { "pkcs-7-CMSVersion", 1610874883, NULL }, 262 | { "v0", 1073741825, "0"}, 263 | { "v1", 1073741825, "1"}, 264 | { "v2", 1073741825, "2"}, 265 | { "v3", 1073741825, "3"}, 266 | { "v4", 1, "4"}, 267 | { "pkcs-7-DigestAlgorithmIdentifiers", 1610612751, NULL }, 268 | { NULL, 2, "pkcs-7-DigestAlgorithmIdentifier"}, 269 | { "pkcs-7-DigestAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"}, 270 | { "pkcs-7-EncapsulatedContentInfo", 1610612741, NULL }, 271 | { "eContentType", 1073741826, "pkcs-7-ContentType"}, 272 | { "eContent", 536895495, NULL }, 273 | { NULL, 2056, "0"}, 274 | { "pkcs-7-CertificateRevocationLists", 1610612751, NULL }, 275 | { NULL, 13, NULL }, 276 | { "pkcs-7-CertificateChoices", 1610612754, NULL }, 277 | { "certificate", 13, NULL }, 278 | { "pkcs-7-CertificateSet", 1610612751, NULL }, 279 | { NULL, 2, "pkcs-7-CertificateChoices"}, 280 | { "pkcs-7-SignerInfos", 1610612751, NULL }, 281 | { NULL, 13, NULL }, 282 | { "pkcs-10-CertificationRequestInfo", 1610612741, NULL }, 283 | { "version", 1610874883, NULL }, 284 | { "v1", 1, "0"}, 285 | { "subject", 1073741826, "Name"}, 286 | { "subjectPKInfo", 1073741826, "SubjectPublicKeyInfo"}, 287 | { "attributes", 536879106, "Attributes"}, 288 | { NULL, 4104, "0"}, 289 | { "Attributes", 1610612751, NULL }, 290 | { NULL, 2, "Attribute"}, 291 | { "pkcs-10-CertificationRequest", 1610612741, NULL }, 292 | { "certificationRequestInfo", 1073741826, "pkcs-10-CertificationRequestInfo"}, 293 | { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"}, 294 | { "signature", 6, NULL }, 295 | { "pkcs-9-at-challengePassword", 1879048204, NULL }, 296 | { "iso", 1073741825, "1"}, 297 | { "member-body", 1073741825, "2"}, 298 | { "us", 1073741825, "840"}, 299 | { "rsadsi", 1073741825, "113549"}, 300 | { "pkcs", 1073741825, "1"}, 301 | { NULL, 1073741825, "9"}, 302 | { NULL, 1, "7"}, 303 | { "pkcs-9-challengePassword", 1610612754, NULL }, 304 | { "printableString", 1073741855, NULL }, 305 | { "utf8String", 34, NULL }, 306 | { "pkcs-9-localKeyId", 1073741831, NULL }, 307 | { "pkcs-8-PrivateKeyInfo", 1610612741, NULL }, 308 | { "version", 1073741826, "pkcs-8-Version"}, 309 | { "privateKeyAlgorithm", 1073741826, "AlgorithmIdentifier"}, 310 | { "privateKey", 1073741826, "pkcs-8-PrivateKey"}, 311 | { "attributes", 536895490, "Attributes"}, 312 | { NULL, 4104, "0"}, 313 | { "pkcs-8-Version", 1610874883, NULL }, 314 | { "v1", 1, "0"}, 315 | { "pkcs-8-PrivateKey", 1073741831, NULL }, 316 | { "pkcs-8-Attributes", 1610612751, NULL }, 317 | { NULL, 2, "Attribute"}, 318 | { "pkcs-8-EncryptedPrivateKeyInfo", 1610612741, NULL }, 319 | { "encryptionAlgorithm", 1073741826, "AlgorithmIdentifier"}, 320 | { "encryptedData", 2, "pkcs-8-EncryptedData"}, 321 | { "pkcs-8-EncryptedData", 1073741831, NULL }, 322 | { "pkcs-5-des-EDE3-CBC-params", 1612709895, NULL }, 323 | { NULL, 1048586, "8"}, 324 | { "pkcs-5-aes128-CBC-params", 1612709895, NULL }, 325 | { NULL, 1048586, "16"}, 326 | { "pkcs-5-aes192-CBC-params", 1612709895, NULL }, 327 | { NULL, 1048586, "16"}, 328 | { "pkcs-5-aes256-CBC-params", 1612709895, NULL }, 329 | { NULL, 1048586, "16"}, 330 | { "pkcs-5-PBES2-params", 1610612741, NULL }, 331 | { "keyDerivationFunc", 1073741826, "AlgorithmIdentifier"}, 332 | { "encryptionScheme", 2, "AlgorithmIdentifier"}, 333 | { "pkcs-5-PBKDF2-params", 1610612741, NULL }, 334 | { "salt", 1610612754, NULL }, 335 | { "specified", 1073741831, NULL }, 336 | { "otherSource", 2, "AlgorithmIdentifier"}, 337 | { "iterationCount", 1611137027, NULL }, 338 | { "1", 10, "MAX"}, 339 | { "keyLength", 1611153411, NULL }, 340 | { "1", 10, "MAX"}, 341 | { "prf", 16386, "AlgorithmIdentifier"}, 342 | { "pkcs-12-PFX", 1610612741, NULL }, 343 | { "version", 1610874883, NULL }, 344 | { "v3", 1, "3"}, 345 | { "authSafe", 1073741826, "pkcs-7-ContentInfo"}, 346 | { "macData", 16386, "pkcs-12-MacData"}, 347 | { "pkcs-12-PbeParams", 1610612741, NULL }, 348 | { "salt", 1073741831, NULL }, 349 | { "iterations", 3, NULL }, 350 | { "pkcs-12-MacData", 1610612741, NULL }, 351 | { "mac", 1073741826, "pkcs-7-DigestInfo"}, 352 | { "macSalt", 1073741831, NULL }, 353 | { "iterations", 536903683, NULL }, 354 | { NULL, 9, "1"}, 355 | { "pkcs-12-AuthenticatedSafe", 1610612747, NULL }, 356 | { NULL, 2, "pkcs-7-ContentInfo"}, 357 | { "pkcs-12-SafeContents", 1610612747, NULL }, 358 | { NULL, 2, "pkcs-12-SafeBag"}, 359 | { "pkcs-12-SafeBag", 1610612741, NULL }, 360 | { "bagId", 1073741836, NULL }, 361 | { "bagValue", 1614815245, NULL }, 362 | { NULL, 1073743880, "0"}, 363 | { "badId", 1, NULL }, 364 | { "bagAttributes", 536887311, NULL }, 365 | { NULL, 2, "pkcs-12-PKCS12Attribute"}, 366 | { "pkcs-12-KeyBag", 1073741826, "pkcs-8-PrivateKeyInfo"}, 367 | { "pkcs-12-PKCS8ShroudedKeyBag", 1073741826, "pkcs-8-EncryptedPrivateKeyInfo"}, 368 | { "pkcs-12-CertBag", 1610612741, NULL }, 369 | { "certId", 1073741836, NULL }, 370 | { "certValue", 541073421, NULL }, 371 | { NULL, 1073743880, "0"}, 372 | { "certId", 1, NULL }, 373 | { "pkcs-12-CRLBag", 1610612741, NULL }, 374 | { "crlId", 1073741836, NULL }, 375 | { "crlValue", 541073421, NULL }, 376 | { NULL, 1073743880, "0"}, 377 | { "crlId", 1, NULL }, 378 | { "pkcs-12-SecretBag", 1610612741, NULL }, 379 | { "secretTypeId", 1073741836, NULL }, 380 | { "secretValue", 541073421, NULL }, 381 | { NULL, 1073743880, "0"}, 382 | { "secretTypeId", 1, NULL }, 383 | { "pkcs-12-PKCS12Attribute", 1073741826, "Attribute"}, 384 | { "pkcs-7-Data", 1073741831, NULL }, 385 | { "pkcs-7-EncryptedData", 1610612741, NULL }, 386 | { "version", 1073741826, "pkcs-7-CMSVersion"}, 387 | { "encryptedContentInfo", 1073741826, "pkcs-7-EncryptedContentInfo"}, 388 | { "unprotectedAttrs", 536895490, "pkcs-7-UnprotectedAttributes"}, 389 | { NULL, 4104, "1"}, 390 | { "pkcs-7-EncryptedContentInfo", 1610612741, NULL }, 391 | { "contentType", 1073741826, "pkcs-7-ContentType"}, 392 | { "contentEncryptionAlgorithm", 1073741826, "pkcs-7-ContentEncryptionAlgorithmIdentifier"}, 393 | { "encryptedContent", 536895490, "pkcs-7-EncryptedContent"}, 394 | { NULL, 4104, "0"}, 395 | { "pkcs-7-ContentEncryptionAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"}, 396 | { "pkcs-7-EncryptedContent", 1073741831, NULL }, 397 | { "pkcs-7-UnprotectedAttributes", 1612709903, NULL }, 398 | { "MAX", 1074266122, "1"}, 399 | { NULL, 2, "Attribute"}, 400 | { "ProxyCertInfo", 1610612741, NULL }, 401 | { "pCPathLenConstraint", 1611153411, NULL }, 402 | { "0", 10, "MAX"}, 403 | { "proxyPolicy", 2, "ProxyPolicy"}, 404 | { "ProxyPolicy", 536870917, NULL }, 405 | { "policyLanguage", 1073741836, NULL }, 406 | { "policy", 16391, NULL }, 407 | { NULL, 0, NULL } 408 | }; 409 | -------------------------------------------------------------------------------- /src/sessions.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include "tpm20_compat.h" 28 | #include "sessions.h" 29 | 30 | #include 31 | #include 32 | 33 | 34 | #define DEFAULT_DEVICE "/dev/tpm0" 35 | #define DEFAULT_HOSTNAME "127.0.0.1" 36 | #define DEFAULT_PORT 2323 37 | 38 | unsigned int open_sessions; 39 | 40 | int session_init(struct session* session, struct config *config) { 41 | memset(session, 0, sizeof(struct session)); 42 | 43 | size_t size = 0; 44 | TSS2_TCTI_CONTEXT *tcti_ctx = NULL; 45 | TSS2_RC rc; 46 | 47 | #ifdef TCTI_DEVICE_ENABLED 48 | TSS_COMPAT_TCTI_DEVICE_CONF device_conf; 49 | #endif // TCTI_DEVICE_ENABLED 50 | 51 | switch(config->type) { 52 | #ifdef TCTI_SOCKET_ENABLED 53 | case TPM_TYPE_SOCKET: 54 | rc = InitSocketTcti(NULL, &size, NULL, 0); 55 | break; 56 | #endif // TCTI_SOCKET_ENABLED 57 | #ifdef TCTI_MSSIM_ENABLED 58 | case TPM_TYPE_SOCKET: 59 | rc = Tss2_Tcti_Mssim_Init(NULL, &size, NULL); 60 | break; 61 | #endif // TCTI_SOCKET_ENABLED 62 | #ifdef TCTI_DEVICE_ENABLED 63 | case TPM_TYPE_DEVICE: 64 | rc = Tss2_Tcti_Device_Init(NULL, &size, device_conf); 65 | break; 66 | #endif // TCTI_DEVICE_ENABLED 67 | #ifdef TCTI_TABRMD_ENABLED 68 | case TPM_TYPE_TABRMD: 69 | rc = Tss2_Tcti_Tabrmd_Init(NULL, &size, NULL); 70 | break; 71 | #endif // TCTI_TABRMD_ENABLED 72 | default: 73 | rc = TSS2_TCTI_RC_NOT_IMPLEMENTED; 74 | break; 75 | } 76 | 77 | if (rc != TSS2_RC_SUCCESS) 78 | goto cleanup; 79 | 80 | tcti_ctx = (TSS2_TCTI_CONTEXT*) calloc(1, size); 81 | if (tcti_ctx == NULL) 82 | goto cleanup; 83 | 84 | #ifdef TCTI_SOCKET_ENABLED 85 | TCTI_SOCKET_CONF socket_conf; 86 | #endif // TCTI_SOCKET_ENABLED 87 | #ifdef TCTI_MSSIM_ENABLED 88 | const char tcti_uri[256]; 89 | #endif // TCTI_MSSIM_ENABLED 90 | 91 | switch(config->type) { 92 | #ifdef TCTI_SOCKET_ENABLED 93 | case TPM_TYPE_SOCKET: 94 | socket_conf = (TCTI_SOCKET_CONF) { .hostname = config->hostname != NULL ? config->hostname : DEFAULT_HOSTNAME, .port = config->port > 0 ? config->port : DEFAULT_PORT }; 95 | rc = InitSocketTcti(tcti_ctx, &size, &socket_conf, 0); 96 | break; 97 | #endif // TCTI_SOCKET_ENABLED 98 | #ifdef TCTI_MSSIM_ENABLED 99 | case TPM_TYPE_SOCKET: 100 | snprintf("tcp://%s:%d", sizeof(tcti_uri), config->hostname != NULL ? config->hostname : DEFAULT_HOSTNAME, config->port > 0 ? config->port : DEFAULT_PORT); 101 | rc = Tss2_Tcti_Mssim_Init(tcti_ctx, &size, (const char*) &tcti_uri); 102 | break; 103 | #endif // TCTI_MSSIM_ENABLED 104 | #ifdef TCTI_DEVICE_ENABLED 105 | case TPM_TYPE_DEVICE: { 106 | TSS_COMPAT_DEVICE_CONF(device_conf, config->device != NULL ? config->device : DEFAULT_DEVICE); 107 | rc = Tss2_Tcti_Device_Init(tcti_ctx, &size, device_conf); 108 | break; 109 | } 110 | #endif // TCTI_DEVICE_ENABLED 111 | #ifdef TCTI_TABRMD_ENABLED 112 | case TPM_TYPE_TABRMD: 113 | rc = Tss2_Tcti_Tabrmd_Init(tcti_ctx, &size, NULL); 114 | break; 115 | #endif // TCTI_TABRMD_ENABLED 116 | default: 117 | rc = TSS2_TCTI_RC_NOT_IMPLEMENTED; 118 | break; 119 | } 120 | 121 | if (rc != TSS2_RC_SUCCESS) 122 | goto cleanup; 123 | 124 | size = Tss2_Sys_GetContextSize(0); 125 | session->context = (TSS2_SYS_CONTEXT*) calloc(1, size); 126 | if (session->context == NULL) 127 | goto cleanup; 128 | 129 | TSS2_ABI_VERSION abi_version = { 130 | .tssCreator = TSSWG_INTEROP, 131 | .tssFamily = TSS_SAPI_FIRST_FAMILY, 132 | .tssLevel = TSS_SAPI_FIRST_LEVEL, 133 | .tssVersion = TSS_SAPI_FIRST_VERSION, 134 | }; 135 | rc = Tss2_Sys_Initialize(session->context, size, tcti_ctx, &abi_version); 136 | 137 | session->objects = object_load(session->context, config); 138 | open_sessions++; 139 | 140 | return 0; 141 | 142 | cleanup: 143 | if (tcti_ctx != NULL) 144 | free(tcti_ctx); 145 | 146 | if (session->context != NULL) 147 | free(session->context); 148 | 149 | return -1; 150 | } 151 | 152 | void session_close(struct session* session) { 153 | if (session->password) 154 | free(session->password); 155 | 156 | object_free(session->objects); 157 | Tss2_Sys_Finalize(session->context); 158 | open_sessions--; 159 | } 160 | -------------------------------------------------------------------------------- /src/sessions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include "config.h" 28 | #include "objects.h" 29 | #include "tpm20_compat.h" 30 | 31 | #include 32 | #include 33 | 34 | struct session { 35 | TSS2_SYS_CONTEXT *context; 36 | pObjectList objects; 37 | TPMI_DH_OBJECT key_handle; 38 | pObjectList find_cursor; 39 | CK_ATTRIBUTE_PTR filters; 40 | size_t num_filters; 41 | pObject current_object; 42 | char *password; 43 | }; 44 | 45 | extern unsigned int open_sessions; 46 | 47 | int session_init(struct session* session, struct config *config); 48 | void session_close(struct session* session); 49 | -------------------------------------------------------------------------------- /src/tpm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include "tpm.h" 28 | 29 | #include 30 | #include 31 | 32 | const unsigned char oid_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14}; 33 | const unsigned char oid_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}; 34 | const unsigned char oid_sha384[] = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,0x00, 0x04, 0x30}; 35 | const unsigned char oid_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,0x00, 0x04, 0x40}; 36 | 37 | static void tpm_set_session_password(TSS2L_SYS_AUTH_COMMAND *sessions_data, char *password) { 38 | TPMS_AUTH_COMMAND *cmd = TSS_COMPAT_AUTHS(sessions_data); 39 | strncat(cmd->hmac.TSS_COMPAT_TMPB(buffer), password, sizeof(TPMU_HA)); 40 | cmd->hmac.TSS_COMPAT_TMPB(size) = strlen(password) >= sizeof(TPMU_HA) ? 0 : strlen(password); 41 | } 42 | 43 | TPM2_RC tpm_readpublic(TSS2_SYS_CONTEXT *context, TPMI_DH_OBJECT handle, TPM2B_PUBLIC *public, TPM2B_NAME *name) { 44 | TSS_COMPAT_AUTH_RESPONSE_BEGIN; 45 | TSS2L_SYS_AUTH_RESPONSE sessions_data_out = TSS_COMPAT_AUTH_RESPONSE_VALUE; 46 | 47 | TPM2B_NAME qualified_name = { .TSS_COMPAT_TMPB(size) = sizeof(TPMU_NAME) }; 48 | 49 | return Tss2_Sys_ReadPublic(context, handle, 0, public, name, &qualified_name, &sessions_data_out); 50 | } 51 | 52 | TPM2_RC tpm_sign(TSS2_SYS_CONTEXT *context, TPMI_DH_OBJECT handle, unsigned char *hash, unsigned long hash_length, TPMT_SIGNATURE *signature, char *password) { 53 | TSS_COMPAT_AUTH_COMMAND_BEGIN(TPM2_RS_PW); 54 | TSS2L_SYS_AUTH_COMMAND sessions_data = TSS_COMPAT_AUTH_COMMAND_VALUE(TPM2_RS_PW); 55 | if (password) 56 | tpm_set_session_password(&sessions_data, password); 57 | 58 | TSS_COMPAT_AUTH_RESPONSE_BEGIN; 59 | TSS2L_SYS_AUTH_RESPONSE sessions_data_out = TSS_COMPAT_AUTH_RESPONSE_VALUE; 60 | 61 | TPMT_TK_HASHCHECK validation = {0}; 62 | validation.tag = TPM2_ST_HASHCHECK; 63 | validation.hierarchy = TPM2_RH_NULL; 64 | 65 | TPMT_SIG_SCHEME scheme; 66 | scheme.scheme = TPM2_ALG_RSASSA; 67 | 68 | int digest_size; 69 | if (sizeof(oid_sha1) < hash_length && memcmp(hash, oid_sha1, sizeof(oid_sha1)) == 0) { 70 | scheme.details.rsassa.hashAlg = TPM2_ALG_SHA1; 71 | digest_size = TPM2_SHA1_DIGEST_SIZE; 72 | } else if (sizeof(oid_sha256) < hash_length && memcmp(hash, oid_sha256, sizeof(oid_sha256)) == 0) { 73 | scheme.details.rsassa.hashAlg = TPM2_ALG_SHA256; 74 | digest_size = TPM2_SHA256_DIGEST_SIZE; 75 | } else if (sizeof(oid_sha384) < hash_length && memcmp(hash, oid_sha384, sizeof(oid_sha384)) == 0) { 76 | scheme.details.rsassa.hashAlg = TPM2_ALG_SHA384; 77 | digest_size = TPM2_SHA384_DIGEST_SIZE; 78 | } else if (sizeof(oid_sha512) < hash_length && memcmp(hash, oid_sha512, sizeof(oid_sha512)) == 0) { 79 | scheme.details.rsassa.hashAlg = TPM2_ALG_SHA512; 80 | digest_size = TPM2_SHA512_DIGEST_SIZE; 81 | } else 82 | return TPM2_RC_FAILURE; 83 | 84 | TPM2B_DIGEST digest = { .TSS_COMPAT_TMPB(size) = digest_size }; 85 | // Remove OID from hash if provided 86 | memcpy(digest.TSS_COMPAT_TMPB(buffer), hash - digest_size + hash_length, digest_size); 87 | 88 | return Tss2_Sys_Sign(context, handle, &sessions_data, &digest, &scheme, &validation, signature, &sessions_data_out); 89 | } 90 | 91 | TPM2_RC tpm_decrypt(TSS2_SYS_CONTEXT *context, TPMI_DH_OBJECT handle, unsigned char *cipher_text, unsigned long cipher_length, TPM2B_PUBLIC_KEY_RSA *message, char *password) { 92 | TSS_COMPAT_AUTH_COMMAND_BEGIN(TPM2_RS_PW); 93 | TSS2L_SYS_AUTH_COMMAND sessions_data = TSS_COMPAT_AUTH_COMMAND_VALUE(TPM2_RS_PW); 94 | if (password) 95 | tpm_set_session_password(&sessions_data, password); 96 | 97 | TSS_COMPAT_AUTH_RESPONSE_BEGIN; 98 | TSS2L_SYS_AUTH_RESPONSE sessions_data_out = TSS_COMPAT_AUTH_RESPONSE_VALUE; 99 | 100 | TPM2B_DATA label = {0}; 101 | 102 | TPMT_RSA_DECRYPT scheme; 103 | scheme.scheme = TPM2_ALG_RSAES; 104 | 105 | TPM2B_PUBLIC_KEY_RSA cipher = { .TSS_COMPAT_TMPB(size) = cipher_length }; 106 | memcpy(cipher.TSS_COMPAT_TMPB(buffer), cipher_text, cipher_length); 107 | 108 | return Tss2_Sys_RSA_Decrypt(context, handle, &sessions_data, &cipher, &scheme, &label, message, &sessions_data_out); 109 | } 110 | 111 | TPM2_RC tpm_sign_encrypt(TSS2_SYS_CONTEXT *context, TPMI_DH_OBJECT handle, size_t key_size, unsigned char *hash, size_t hash_length, TPM2B_PUBLIC_KEY_RSA *signature, char *password) { 112 | TSS_COMPAT_AUTH_COMMAND_BEGIN(TPM2_RS_PW); 113 | TSS2L_SYS_AUTH_COMMAND sessions_data = TSS_COMPAT_AUTH_COMMAND_VALUE(TPM2_RS_PW); 114 | if (password) 115 | tpm_set_session_password(&sessions_data, password); 116 | 117 | TPM2B_PUBLIC_KEY_RSA message = { .TSS_COMPAT_TMPB(size) = key_size }; 118 | unsigned char *p = message.TSS_COMPAT_TMPB(buffer); 119 | 120 | *p++ = 0; 121 | *p++ = 1; 122 | size_t nb_pad = key_size - hash_length - 3; 123 | memset(p, 0xFF, nb_pad); 124 | p += nb_pad; 125 | *p++ = 0; 126 | memcpy(p, hash, hash_length); 127 | 128 | TPM2B_DATA label = {0}; 129 | TPMT_RSA_DECRYPT scheme = { .scheme = TPM2_ALG_NULL }; 130 | 131 | return Tss2_Sys_RSA_Decrypt(context, handle, &sessions_data, &message, &scheme, &label, signature, NULL); 132 | } 133 | 134 | TPM2_RC tpm_info(TSS2_SYS_CONTEXT *context, UINT32 property, TPMS_CAPABILITY_DATA* capability_data) { 135 | TPMI_YES_NO more_data; 136 | TPM2_CAP capability; 137 | UINT32 propertyCount; 138 | 139 | switch (property) { 140 | case TPM2_HT_PERSISTENT: 141 | property = htobe32(property); 142 | capability = TPM2_CAP_HANDLES; 143 | propertyCount = TPM2_PT_TPM2_HR_PERSISTENT; 144 | break; 145 | case TPM2_PT_FIXED: 146 | capability = TPM2_CAP_TPM_PROPERTIES; 147 | propertyCount = TPM2_MAX_TPM_PROPERTIES; 148 | break; 149 | } 150 | 151 | return Tss2_Sys_GetCapability(context, 0, capability, property, propertyCount, &more_data, capability_data, 0); 152 | } 153 | 154 | TPMS_TAGGED_PROPERTY* tpm_info_get(TPMS_TAGGED_PROPERTY properties[], size_t count, TPM2_PT key) { 155 | for (int i = 0; i < count; i++) { 156 | if (properties[i].property == key) 157 | return &properties[i]; 158 | 159 | } 160 | 161 | return NULL; 162 | } 163 | -------------------------------------------------------------------------------- /src/tpm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include "tpm20_compat.h" 28 | 29 | TPM2_RC tpm_readpublic(TSS2_SYS_CONTEXT *context, TPMI_DH_OBJECT handle, TPM2B_PUBLIC *public, TPM2B_NAME *name); 30 | TPM2_RC tpm_sign(TSS2_SYS_CONTEXT *context, TPMI_DH_OBJECT handle, unsigned char *hash, unsigned long hash_length, TPMT_SIGNATURE *signature, char *password); 31 | TPM2_RC tpm_decrypt(TSS2_SYS_CONTEXT *context, TPMI_DH_OBJECT handle, unsigned char *cipher_text, unsigned long cipher_length, TPM2B_PUBLIC_KEY_RSA *message, char *password); 32 | TPM2_RC tpm_sign_encrypt(TSS2_SYS_CONTEXT *context, TPMI_DH_OBJECT handle, size_t key_size, unsigned char *message, size_t message_length, TPM2B_PUBLIC_KEY_RSA *signature, char *password); 33 | TPM2_RC tpm_info(TSS2_SYS_CONTEXT *context, UINT32 property, TPMS_CAPABILITY_DATA* capability_data); 34 | TPMS_TAGGED_PROPERTY* tpm_info_get(TPMS_TAGGED_PROPERTY properties[], size_t count, TPM2_PT key); 35 | -------------------------------------------------------------------------------- /src/tpm20_compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #pragma once 28 | 29 | #include 30 | 31 | #ifndef TSS_COMPAT 32 | #include 33 | #include 34 | #include 35 | #ifdef TCTI_MSSIM_ENABLED 36 | #include 37 | #endif /* TCTI_SOCKET_ENABLED */ 38 | #ifdef TCTI_MSSIM_ENABLED 39 | #include 40 | #endif /* TCTI_TABRMD_ENABLED */ 41 | #else /* TSS_COMPAT */ 42 | #include 43 | #ifdef TCTI_DEVICE_ENABLED 44 | #include 45 | #endif /* TCTI_DEVICE_ENABLED */ 46 | #ifdef TCTI_SOCKET_ENABLED 47 | #include 48 | #endif /* TCTI_SOCKET_ENABLED */ 49 | #ifdef TCTI_TABRMD_ENABLED 50 | #include 51 | #endif /* TCTI_TABRMD_ENABLED */ 52 | #endif /* TSS_COMPAT */ 53 | 54 | #ifndef TSS_COMPAT 55 | 56 | #define TSSWG_INTEROP 1 57 | #define TSS_SAPI_FIRST_FAMILY 2 58 | #define TSS_SAPI_FIRST_LEVEL 1 59 | #define TSS_SAPI_FIRST_VERSION 108 60 | 61 | typedef char* TSS_COMPAT_TCTI_DEVICE_CONF; 62 | 63 | #define TSS_COMPAT_AUTH_COMMAND_BEGIN 64 | #define TSS_COMPAT_AUTH_RESPONSE_BEGIN 65 | 66 | #define TSS_COMPAT_AUTH_COMMAND_VALUE(x) { .count = 1, .auths[0] = { .sessionHandle = x } } 67 | #define TSS_COMPAT_AUTH_RESPONSE_VALUE { .count = 1 } 68 | 69 | #define TSS_COMPAT_TMPB(x) x 70 | 71 | #define TSS_COMPAT_DEVICE_CONF(x, y) x = y 72 | 73 | #define TSS_COMPAT_AUTHS(x) &x->auths[0] 74 | 75 | #else /* TSS_COMPAT */ 76 | 77 | #define Tss2_Tcti_Device_Init(x, y, z) InitDeviceTcti(x, y, &z) 78 | #define Tss2_Tcti_Tabrmd_Init(x, y, z) tss2_tcti_tabrmd_init(x, y) 79 | 80 | #define TPM2_RC TPM_RC 81 | #define TPM2_RC_SUCCESS TPM_RC_SUCCESS 82 | #define TPM2_RC_FAILURE TPM_RC_FAILURE 83 | 84 | #define TPM2_ST_HASHCHECK TPM_ST_HASHCHECK 85 | 86 | #define TPM2_CAP TPM_CAP 87 | #define TPM2_CAP_HANDLES TPM_CAP_HANDLES 88 | #define TPM2_CAP_TPM_PROPERTIES TPM_CAP_TPM_PROPERTIES 89 | 90 | #define TPM2_HT_PERSISTENT TPM_HT_PERSISTENT 91 | 92 | #define TPM2_PT TPM_PT 93 | #define TPM2_PT_FIXED PT_FIXED 94 | #define TPM2_PT_HR_PERSISTENT TPM_PT_HR_PERSISTENT 95 | #define TPM2_PT_TPM2_HR_PERSISTENT TPM_PT_HR_PERSISTENT 96 | #define TPM2_PT_MANUFACTURER TPM_PT_MANUFACTURER 97 | #define TPM2_PT_REVISION TPM_PT_REVISION 98 | #define TPM2_PT_FIRMWARE_VERSION_1 TPM_PT_FIRMWARE_VERSION_1 99 | #define TPM2_PT_FIRMWARE_VERSION_2 TPM_PT_FIRMWARE_VERSION_2 100 | #define TPM2_PT_ACTIVE_SESSIONS_MAX TPM_PT_ACTIVE_SESSIONS_MAX 101 | 102 | #define TPM2_RS_PW TPM_RS_PW 103 | 104 | #define TPM2_RH_NULL TPM_RH_NULL 105 | 106 | #define TPM2_ALG_NULL TPM_ALG_NULL 107 | #define TPM2_ALG_RSASSA TPM_ALG_RSASSA 108 | #define TPM2_ALG_RSAES TPM_ALG_RSAES 109 | #define TPM2_ALG_SHA1 TPM_ALG_SHA1 110 | #define TPM2_ALG_SHA256 TPM_ALG_SHA256 111 | #define TPM2_ALG_SHA384 TPM_ALG_SHA384 112 | #define TPM2_ALG_SHA512 TPM_ALG_SHA512 113 | 114 | #define TPM2_MAX_RSA_KEY_BYTES MAX_RSA_KEY_BYTES 115 | #define TPM2_MAX_TPM_PROPERTIES MAX_TPM_PROPERTIES 116 | 117 | #define TPM2_SHA1_DIGEST_SIZE SHA1_DIGEST_SIZE 118 | #define TPM2_SHA256_DIGEST_SIZE SHA256_DIGEST_SIZE 119 | #define TPM2_SHA384_DIGEST_SIZE SHA384_DIGEST_SIZE 120 | #define TPM2_SHA512_DIGEST_SIZE SHA512_DIGEST_SIZE 121 | 122 | #define TSS2L_SYS_AUTH_RESPONSE TSS2_SYS_RSP_AUTHS 123 | #define TSS2L_SYS_AUTH_COMMAND TSS2_SYS_CMD_AUTHS 124 | 125 | #define TSS_COMPAT_AUTH_COMMAND_BEGIN(x) TPMS_AUTH_COMMAND session_data = { .sessionHandle = x}; \ 126 | TPMS_AUTH_COMMAND *session_data_array[1] = { &session_data }; 127 | 128 | #define TSS_COMPAT_AUTH_RESPONSE_BEGIN TPMS_AUTH_RESPONSE session_data_out; \ 129 | TPMS_AUTH_RESPONSE *session_data_out_array[1] = { &session_data_out } 130 | 131 | #define TSS_COMPAT_AUTH_COMMAND_VALUE(x) { .cmdAuths = &session_data_array[0], .cmdAuthsCount = 1} 132 | #define TSS_COMPAT_AUTH_RESPONSE_VALUE { .rspAuths = &session_data_out_array[0], .rspAuthsCount = 1 } 133 | 134 | #define TSS_COMPAT_TMPB(x) t.x 135 | 136 | #define TSS_COMPAT_DEVICE_CONF(x, y) x = (TCTI_DEVICE_CONF) { .device_path = y } 137 | 138 | #define TSS_COMPAT_AUTHS(x) x->cmdAuths[0] 139 | 140 | typedef TCTI_DEVICE_CONF TSS_COMPAT_TCTI_DEVICE_CONF; 141 | 142 | #endif /* TSS_COMPAT */ 143 | -------------------------------------------------------------------------------- /src/utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | void strncpy_pad(char *dest, size_t dest_len, const char *src, size_t n) { 36 | size_t src_len = strlen(src); 37 | if (src_len > n) 38 | src_len = n; 39 | 40 | memcpy(dest, src, src_len < dest_len ? src_len : dest_len); 41 | if (src_len < dest_len) 42 | memset(dest + src_len, ' ', dest_len - src_len); 43 | } 44 | 45 | void retmem(void* dest, size_t* size, const void* src, size_t n) { 46 | if (dest && n <= *size) 47 | memcpy(dest, src, n); 48 | 49 | *size = n; 50 | } 51 | 52 | void* read_file(const char* filename, size_t* length) { 53 | int fd = open(filename, O_RDONLY); 54 | if (fd < 0) { 55 | *length = 0; 56 | return NULL; 57 | } 58 | 59 | struct stat s; 60 | char* buffer = NULL; 61 | int ret = fstat(fd, &s); 62 | if (ret < 0) { 63 | *length = 0; 64 | goto cleanup; 65 | } 66 | 67 | size_t pre_length = *length; 68 | *length = s.st_size; 69 | buffer = malloc(*length + pre_length); 70 | if (buffer == NULL || read(fd, buffer + pre_length, *length) != *length) 71 | *length = 0; 72 | 73 | cleanup: 74 | close(fd); 75 | return buffer; 76 | } 77 | -------------------------------------------------------------------------------- /src/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Iwan Timmer 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24 | * THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include 28 | 29 | void strncpy_pad(char *dest, size_t dest_len, const char *src, size_t n); 30 | void retmem(void* dest, size_t* size, const void* src, size_t n); 31 | void* read_file(const char* filename, size_t* length); 32 | -------------------------------------------------------------------------------- /test/bat/bats.bat: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load test_util 4 | 5 | @test "Confirm SSH client functionality" { 6 | create_key 7 | run ssh-keygen -D ./libtpm2-pk11.so 8 | [ $status -eq 0 ] 9 | echo $output >> $HOME/.ssh/authorized_keys 10 | host_hostname=`hostname -s` 11 | test_hostname=`ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -I ./libtpm2-pk11.so localhost hostname -s` 12 | [ ${test_hostname} == ${host_hostname} ] 13 | delete_key 14 | } 15 | -------------------------------------------------------------------------------- /test/bat/test_util.bash: -------------------------------------------------------------------------------- 1 | create_key() { 2 | tpm2_createprimary -a o -g sha256 -G rsa -o po.ctx 3 | tpm2_create -C po.ctx -g sha256 -G rsa -u key.pub -r key.priv 4 | tpm2_load -C po.ctx -u key.pub -r key.priv -o obj.ctx 5 | tpm2_evictcontrol -a o -c obj.ctx -p 0x81010010 6 | } 7 | 8 | delete_key() { 9 | tpm2_evictcontrol -a o -c 0x81010010 10 | rm key.pub 11 | rm key.priv 12 | } 13 | -------------------------------------------------------------------------------- /test/travis_run_bat.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # fail if any failure 4 | set -e 5 | 6 | # only test against master tss for now 7 | if [ ${TSS_BRANCH} == "master" ]; then 8 | pushd ${TRAVIS_BUILD_DIR}/build 9 | bats ${TRAVIS_BUILD_DIR}/test/bat/bats.bat 10 | popd 11 | fi 12 | -------------------------------------------------------------------------------- /tpm2-pk11.module.in: -------------------------------------------------------------------------------- 1 | module: ${P11_KIT_1_P11_MODULE_PATH}/libtpm2-pk11.so 2 | critical: no 3 | --------------------------------------------------------------------------------