diff --git a/.dockerignore b/.dockerignore index 4f9521841..b4fc88967 100644 --- a/.dockerignore +++ b/.dockerignore @@ -14,3 +14,5 @@ Dockerfile docker-compose.yml *.md +**/build + diff --git a/Dockerfile b/Dockerfile index 03cd30559..0ba4b10e4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ ARG UBUNTU_VERSION=jammy-20230126 -FROM ubuntu:$UBUNTU_VERSION +FROM ubuntu:$UBUNTU_VERSION AS dependencies ENV DEBIAN_FRONTEND=noninteractive ADD scripts/install_dependencies.sh /usr/local/bin/ -RUN sed -i 's|http://archive.ubuntu.com|http://us.archive.ubuntu.com|g' /etc/apt/sources.list && \ - /usr/local/bin/install_dependencies.sh +RUN sed -i 's|http://archive.ubuntu.com|http://us.archive.ubuntu.com|g' /etc/apt/sources.list +RUN /usr/local/bin/install_dependencies.sh # build out ext components COPY ./ext /home/V2X-Hub/ext @@ -14,6 +14,7 @@ RUN ./build.sh ADD container/wait-for-it.sh /usr/local/bin/ ADD container/service.sh /usr/local/bin/ + COPY ./container /home/V2X-Hub/container WORKDIR /home/V2X-Hub/container/ RUN ./database.sh @@ -26,8 +27,33 @@ WORKDIR /home/V2X-Hub/src/ RUN ./build.sh release RUN ldconfig -WORKDIR /home/V2X-Hub/ +# run final image +FROM ubuntu:$UBUNTU_VERSION AS v2xhub +ENV DEBIAN_FRONTEND=noninteractive +ADD scripts/deployment_dependencies.sh /usr/local/bin/ +RUN /usr/local/bin/deployment_dependencies.sh + +COPY ./container /home/V2X-Hub/container/ +WORKDIR /home/V2X-Hub/container/ +RUN ./database.sh +RUN ./library.sh +RUN ldconfig + +COPY --from=dependencies /usr/local/plugins/ /usr/local/plugins/ +COPY --from=dependencies /usr/local/lib/ /usr/local/lib/ +COPY --from=dependencies /usr/local/bin/ /usr/local/bin/ +COPY --from=dependencies /usr/lib/ /usr/lib/ +COPY --from=dependencies /usr/bin/ /usr/bin/ +COPY --from=dependencies /usr/local/share/ /usr/local/share/ +COPY --from=dependencies /var/www/plugins/ /var/www/plugins/ +COPY --from=dependencies /var/log/tmx/ /var/log/tmx/ +COPY --from=dependencies /opt/ /opt/ +ADD src/tmx/TmxCore/tmxcore.service /lib/systemd/system/ +ADD src/tmx/TmxCore/tmxcore.service /usr/sbin/ +RUN ldconfig + RUN /home/V2X-Hub/container/setup.sh + WORKDIR /var/log/tmx # Set metadata labels diff --git a/configuration/amd64/docker-compose.yml b/configuration/amd64/docker-compose.yml index ffafacc38..201463578 100755 --- a/configuration/amd64/docker-compose.yml +++ b/configuration/amd64/docker-compose.yml @@ -20,7 +20,7 @@ services: - mysql-datavolume:/var/lib/mysql php: - image: usdotfhwaops/php:k900 + image: usdotfhwaops/php:7.5.1 container_name: php network_mode: host depends_on: @@ -30,7 +30,7 @@ services: tty: true v2xhub: - image: usdotfhwaops/v2xhubamd:k900 + image: usdotfhwaops/v2xhubamd:7.5.1 container_name: v2xhub network_mode: host restart: always @@ -44,7 +44,7 @@ services: - ./logs:/var/log/tmx - ./MAP:/var/www/plugins/MAP port_drayage_webservice: - image: usdotfhwaops/port-drayage-webservice:k900 + image: usdotfhwaops/port-drayage-webservice:7.5.1 container_name: port_drayage_webservice network_mode: host secrets: diff --git a/configuration/arm64/docker-compose.yml b/configuration/arm64/docker-compose.yml index 38c3359c6..4974d26ee 100644 --- a/configuration/arm64/docker-compose.yml +++ b/configuration/arm64/docker-compose.yml @@ -20,7 +20,7 @@ services: - mysql-datavolume:/var/lib/mysql php: - image: usdotfhwaops/php_arm:k900 + image: usdotfhwaops/php_arm:7.5.1 container_name: php network_mode: host depends_on: @@ -30,7 +30,7 @@ services: tty: true v2xhub: - image: usdotfhwaops/v2xhubarm:k900 + image: usdotfhwaops/v2xhubarm:7.5.1 container_name: v2xhub network_mode: host restart: always @@ -44,7 +44,7 @@ services: - ./logs:/var/log/tmx - ./MAP:/var/www/plugins/MAP port_drayage_webservice: - image: usdotfhwaops/port-drayage-webservice_arm:k900 + image: usdotfhwaops/port-drayage-webservice_arm:7.5.1 container_name: port_drayage_webservice network_mode: host secrets: diff --git a/container/setup.sh b/container/setup.sh index 954c7dba5..375eb1a0b 100755 --- a/container/setup.sh +++ b/container/setup.sh @@ -1,9 +1,6 @@ #!/bin/sh set -ex -cp src/tmx/TmxCore/tmxcore.service /lib/systemd/system/ -cp src/tmx/TmxCore/tmxcore.service /usr/sbin/ - mkdir -p /var/www/plugins/MAP /var/www/plugins/.ssl openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout /var/www/plugins/.ssl/tmxcmd.key -out /var/www/plugins/.ssl/tmxcmd.crt -subj "/CN= <127.0.0.1> " -days 3650 chown -R plugin:www-data /var/www/plugins/.ssl diff --git a/docs/V2X-Hub_Plugins.pdf b/docs/V2X-Hub_Plugins.pdf new file mode 100755 index 000000000..67455b1e7 Binary files /dev/null and b/docs/V2X-Hub_Plugins.pdf differ diff --git a/ext/pkcs11-proxy/.gitignore b/ext/pkcs11-proxy/.gitignore deleted file mode 100644 index 80eadb770..000000000 --- a/ext/pkcs11-proxy/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -build/ -*.o -moc_*.cpp -ui_*.h -*~ -vb-agent -res/.directory -.\#* -\#*# -Makefile -Trolltech.conf -obj-i686-linux-gnu -syscall-names.h diff --git a/ext/pkcs11-proxy/CMakeLists.txt b/ext/pkcs11-proxy/CMakeLists.txt deleted file mode 100644 index 2929a0aa5..000000000 --- a/ext/pkcs11-proxy/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -cmake_minimum_required (VERSION 2.4) - -if(COMMAND cmake_policy) - cmake_policy(SET CMP0003 NEW) -endif(COMMAND cmake_policy) - -set(CMAKE_VERBOSE_MAKEFILE ON) -set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(CMAKE_AUTOMOC ON) - -OPTION(NODEBUG "Deactivate No debugging option" "OFF") - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -Wall -Wno-unused-variable") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -std=c++14 -Wall -Wno-unused-variable") - -if(${NODEBUG} STREQUAL "OFF") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg -g3") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg -g3") -else (${NODEBUG} STREQUAL "OFF") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s -O3") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s -O3") -endif(${NODEBUG} STREQUAL "OFF") - - -set(PKCS11_PROXY_SRCS gck-rpc-module.c gck-rpc-message.c gck-rpc-util.c egg-buffer.c gck-rpc-tls-psk.c) -set(PKCS11_DAEMON_SRCS egg-buffer.c gck-rpc-daemon-standalone.c gck-rpc-dispatch.c gck-rpc-message.c gck-rpc-util.c syscall-reporter.c syscall-names.h gck-rpc-tls-psk.c) - -add_definitions(-Wall) -add_library(pkcs11-proxy SHARED ${PKCS11_PROXY_SRCS}) - - -#add_executable (pkcs11-daemon ${GUI_TYPE} ${PKCS11_DAEMON_SRCS}) - -set_target_properties(pkcs11-proxy PROPERTIES VERSION 0.1 SOVERSION 0) - - -target_link_libraries (pkcs11-proxy pthread ssl crypto) -target_link_libraries (pkcs11-daemon dl pthread ssl crypto seccomp) - -#install_targets (/lib pkcs11-proxy) -#install_targets (/bin pkcs11-daemon) - -install(EXPORT pkcs11-proxyAPIConfig DESTINATION share/pkcs11proxyAPI/cmake) - -export(TARGETS pkcs11-proxy FILE pkcs11proxyAPIConfig.cmake) - diff --git a/ext/pkcs11-proxy/CMakeLists.txtbackup b/ext/pkcs11-proxy/CMakeLists.txtbackup deleted file mode 100644 index f16862e34..000000000 --- a/ext/pkcs11-proxy/CMakeLists.txtbackup +++ /dev/null @@ -1,45 +0,0 @@ -cmake_minimum_required (VERSION 2.4) - -if(COMMAND cmake_policy) - cmake_policy(SET CMP0003 NEW) -endif(COMMAND cmake_policy) - -project (pkcs11 C) - -set(PKCS11_PROXY_SRCS gck-rpc-module.c gck-rpc-message.c gck-rpc-util.c egg-buffer.c gck-rpc-tls-psk.c) -set(PKCS11_DAEMON_SRCS egg-buffer.c gck-rpc-daemon-standalone.c gck-rpc-dispatch.c gck-rpc-message.c gck-rpc-util.c syscall-reporter.c syscall-names.h gck-rpc-tls-psk.c) - -add_definitions(-Wall) -add_library(pkcs11-proxy SHARED ${PKCS11_PROXY_SRCS}) - -# Disable console when building Win32 binary in release mode -if (WIN32 - if("${CMAKE_BUILD_TYPE}" MATCHES "^Rel.*") - set(GUI_TYPE WIN32) - endif() -endif() - -add_executable (pkcs11-daemon ${GUI_TYPE} ${PKCS11_DAEMON_SRCS}) - -set_target_properties(pkcs11-proxy PROPERTIES VERSION 0.1 SOVERSION 0) - -if (WIN32) - include_directories("ext/include") - - add_library(dl STATIC IMPORTED) - set_property(TARGET dl PROPERTY - IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/ext/lib/libdl.a) - target_link_libraries (pkcs11-daemon ws2_32) - target_link_libraries (pkcs11-proxy ws2_32) -endif (WIN32) - -target_link_libraries (pkcs11-proxy pthread ssl crypto) -target_link_libraries (pkcs11-daemon dl pthread ssl crypto seccomp) - -install_targets (/lib pkcs11-proxy) -install_targets (/bin pkcs11-daemon) - -add_custom_command( - OUTPUT syscall-names.h - COMMAND ${CMAKE_SOURCE_DIR}/mksyscalls.sh - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) diff --git a/ext/pkcs11-proxy/Dockerfile.jenkins b/ext/pkcs11-proxy/Dockerfile.jenkins deleted file mode 100644 index 620f8e21d..000000000 --- a/ext/pkcs11-proxy/Dockerfile.jenkins +++ /dev/null @@ -1,2 +0,0 @@ -FROM docker.sunet.se/jenkins-job -RUN apt-get install -y libssl-dev libseccomp-dev diff --git a/ext/pkcs11-proxy/README.rst b/ext/pkcs11-proxy/README.rst deleted file mode 100644 index fd5bb2ae9..000000000 --- a/ext/pkcs11-proxy/README.rst +++ /dev/null @@ -1,15 +0,0 @@ - -PKCS11 Proxy -============ - -This fork has the following additional features: - -- support for running in "inetd mode", useful for calling directly from stunnel -- seccomp syscall filtering (only tested in inetd-mode) -- getaddrinfo support for IPv6, fallback and DNS resolution -- TLS-PSK support to optionally encrypt communication - -Plus a number of important bug fixes. This version passes the SoftHSM test -suite. - -An ubuntu PPA that tracks this version is ppa:leifj diff --git a/ext/pkcs11-proxy/THANKS b/ext/pkcs11-proxy/THANKS deleted file mode 100644 index dcf22ed79..000000000 --- a/ext/pkcs11-proxy/THANKS +++ /dev/null @@ -1,2 +0,0 @@ -Gnome Project - gnome keyring http://live.gnome.org/GnomeKeyring -Casper Gielen - documentation \ No newline at end of file diff --git a/ext/pkcs11-proxy/UPSTREAM_REV b/ext/pkcs11-proxy/UPSTREAM_REV deleted file mode 100644 index 8686b4f96..000000000 --- a/ext/pkcs11-proxy/UPSTREAM_REV +++ /dev/null @@ -1 +0,0 @@ -r1724 \ No newline at end of file diff --git a/ext/pkcs11-proxy/USAGE b/ext/pkcs11-proxy/USAGE deleted file mode 100644 index f79297522..000000000 --- a/ext/pkcs11-proxy/USAGE +++ /dev/null @@ -1,82 +0,0 @@ -PKCS11-Proxy is a proxy for the PKCS11-library. - -This project is based on a stripped down Gnome Keyring without all gnome -dependencies and other features. - -The proxy tunnels PKCS11-requests over the network. One possible use -is to store cryptograhic information on a seperate server. This way -the crypto can be isolated from the rest of the system. - -Example -======= - -Here is an example of using pkcs11-proxy together with SoftHSM (from the -OpenDNSSEC project). The benefit of this setup is that no extra hardware -is needed at all. This could also be considered the greatest weakeness. -For demonstration purposes, however, security is not a consideration. - -$ sudo adduser cgielen pkcs11 -$ sudo adduser cgielen softhsm - -$ softhsm --init-token --slot 0 --label test -The SO PIN must have a length between 4 and 255 characters. -Enter SO PIN: -The user PIN must have a length between 4 and 255 characters. -Enter user PIN: -The token has been initialized. - -$ PKCS11_DAEMON_SOCKET="tcp://127.0.0.1:2345" pkcs11-daemon /usr/lib/libsofthsm.so -$ PKCS11_PROXY_SOCKET="tcp://127.0.0.1:2345" pkcs11-tool --module=/usr/lib/libpkcs11-proxy.so -L Available -slots: Slot 0 SoftHSM - token label: test token manuf: SoftHSM token model: SoftHSM - token flags: rng, login required, PIN initialized, token initialized, - other flags=0x40 serial num : 1 - - -IPv6 and DNS -============ - -The PKCS11_DAEMON_SOCKET and PKCS11_PROXY_SOCKET environment variables can -have both hostnames and IPv6 addresses in them. getaddrinfo(3) is used to -resolve any DNS name. - -$ PKCS11_DAEMON_SOCKET="tcp://server.example.com:2345" ... - -If `server.example.com' resolves to more than one IP address (such as one -IPv4 and one IPv6 address), these will be tried sequentially. Currently, -no attempt is made to speed up connection establishment using Happy Eyeballs -(RFC 6555) or similar, so timeouts in case of unreachable addresses could -be expected to be quite problematic. - -IPv6 addresses should be enclosed by square brackets. - -$ PKCS11_DAEMON_SOCKET="tcp://[::1]:2345" ... - - -Encryption -========== - -This version supports encrypting the communication between the client and -proxy using OpenSSL TLS-PSK (pre-shared key). The PSK is read from a file -that usees the GnuTLS psktool format. This format includes PSK identity -as well as key. - -Currently, there is no way to specify the identity to use on the client -side (client tells server what identity should be used), and the first -identity found in the PSK file is used. The server side will correctly -look up the identity requested by the client in it's PSK file, so it is -possible to have one unique PSK identity and key per PKCS11 client, and -have all the identitys and keys in the PSK file for the PKCS11 daemon. - -$ cat test.psk -test:e9622c85018998993fcc16f5ce9c15e9 -$ PKCS11_PROXY_TLS_PSK_FILE="test.psk" \ - PKCS11_DAEMON_SOCKET="tls://server.example.com:2345" \ - pkcs11-daemon /usr/lib/libsofthsm.so -$ PKCS11_PROXY_TLS_PSK_FILE="test.psk" \ - PKCS11_PROXY_SOCKET="tls://server.example.com:2345" \ - pkcs11-tool --module=/usr/lib/libpkcs11-proxy.so -L Available -slots: Slot 0 SoftHSM - token label: test token manuf: SoftHSM token model: SoftHSM - token flags: rng, login required, PIN initialized, token initialized, - other flags=0x40 serial num : 1 diff --git a/ext/pkcs11-proxy/cmake_install.cmake b/ext/pkcs11-proxy/cmake_install.cmake deleted file mode 100644 index 563c5d0cd..000000000 --- a/ext/pkcs11-proxy/cmake_install.cmake +++ /dev/null @@ -1,97 +0,0 @@ -# Install script for directory: /home/anjanrayamajhi/Projects/pkcs11-proxy - -# Set the install prefix -if(NOT DEFINED CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX "/usr/local") -endif() -string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") - -# Set the install configuration name. -if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) - if(BUILD_TYPE) - string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" - CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") - else() - set(CMAKE_INSTALL_CONFIG_NAME "") - endif() - message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") -endif() - -# Set the component getting installed. -if(NOT CMAKE_INSTALL_COMPONENT) - if(COMPONENT) - message(STATUS "Install component: \"${COMPONENT}\"") - set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") - else() - set(CMAKE_INSTALL_COMPONENT) - endif() -endif() - -# Install shared libraries without execute permission? -if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) - set(CMAKE_INSTALL_SO_NO_EXE "1") -endif() - -# Is this installation the result of a crosscompile? -if(NOT DEFINED CMAKE_CROSSCOMPILING) - set(CMAKE_CROSSCOMPILING "FALSE") -endif() - -if("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "xUnspecifiedx" OR NOT CMAKE_INSTALL_COMPONENT) - if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/pkcs11-daemon" AND - NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/pkcs11-daemon") - file(RPATH_CHECK - FILE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/pkcs11-daemon" - RPATH "") - endif() - file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" TYPE EXECUTABLE FILES "/home/anjanrayamajhi/Projects/pkcs11-proxy/pkcs11-daemon") - if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/pkcs11-daemon" AND - NOT IS_SYMLINK "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/pkcs11-daemon") - if(CMAKE_INSTALL_DO_STRIP) - execute_process(COMMAND "/usr/bin/strip" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/pkcs11-daemon") - endif() - endif() -endif() - -if("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "xUnspecifiedx" OR NOT CMAKE_INSTALL_COMPONENT) - foreach(file - "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libpkcs11-proxy.so.0.1" - "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libpkcs11-proxy.so.0" - "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libpkcs11-proxy.so" - ) - if(EXISTS "${file}" AND - NOT IS_SYMLINK "${file}") - file(RPATH_CHECK - FILE "${file}" - RPATH "") - endif() - endforeach() - file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" TYPE SHARED_LIBRARY FILES - "/home/anjanrayamajhi/Projects/pkcs11-proxy/libpkcs11-proxy.so.0.1" - "/home/anjanrayamajhi/Projects/pkcs11-proxy/libpkcs11-proxy.so.0" - "/home/anjanrayamajhi/Projects/pkcs11-proxy/libpkcs11-proxy.so" - ) - foreach(file - "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libpkcs11-proxy.so.0.1" - "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libpkcs11-proxy.so.0" - "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/libpkcs11-proxy.so" - ) - if(EXISTS "${file}" AND - NOT IS_SYMLINK "${file}") - if(CMAKE_INSTALL_DO_STRIP) - execute_process(COMMAND "/usr/bin/strip" "${file}") - endif() - endif() - endforeach() -endif() - -if(CMAKE_INSTALL_COMPONENT) - set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") -else() - set(CMAKE_INSTALL_MANIFEST "install_manifest.txt") -endif() - -string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT - "${CMAKE_INSTALL_MANIFEST_FILES}") -file(WRITE "/home/anjanrayamajhi/Projects/pkcs11-proxy/${CMAKE_INSTALL_MANIFEST}" - "${CMAKE_INSTALL_MANIFEST_CONTENT}") diff --git a/ext/pkcs11-proxy/config.h b/ext/pkcs11-proxy/config.h deleted file mode 100644 index f2e0a88f9..000000000 --- a/ext/pkcs11-proxy/config.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef CONFIG_H -# define CONFIG_H - -# define DEBUG_OUTPUT 0 // change to 1 to enable debugging - -# define PKCS11PROXY_LISTEN_BACKLOG 128 -# define PKCS11PROXY_MAX_SESSION_COUNT 256 - -# define PKCS11PROXY_TLS_PSK_CIPHERS "PSK-AES128-CBC-SHA:PSK-AES256-CBC-SHA"; - -//# define DEBUG_SECCOMP -//# define SECCOMP - -#ifdef __MINGW32__ - -# include -# include -# include -# include - -typedef uint32_t __uid32_t; -typedef uint32_t __gid32_t; -typedef uint32_t uid_t; -typedef int socklen_t; - -struct sockaddr_un { - uint16_t sun_family; - char sun_path[PATH_MAX]; -}; - -enum { - SHUT_RD = 0, /* No more receptions. */ - SHUT_WR, /* No more transmissions. */ - SHUT_RDWR /* No more receptions or transmissions. */ -}; - -#ifdef __MINGW32__ -static inline int inet_aton(const char * cp, struct in_addr *pin) -{ - int rc = inet_addr(cp); - if (rc == -1 && strcmp(cp, "255.255.255.255")) - return 0; - - pin->s_addr = rc; - return 1; -} -#endif - -#endif - -#endif /* CONFIG_H */ diff --git a/ext/pkcs11-proxy/debian/.gitignore b/ext/pkcs11-proxy/debian/.gitignore deleted file mode 100644 index 9a94fb2a5..000000000 --- a/ext/pkcs11-proxy/debian/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -files -pkcs11-daemon.debhelper.log -pkcs11-daemon.substvars -pkcs11-proxy1.debhelper.log -pkcs11-proxy1.postinst.debhelper -pkcs11-proxy1.postrm.debhelper -pkcs11-proxy1.substvars -stamp-makefile-build -stamp-makefile-install -tmp -pkcs11-daemon -pkcs11-proxy1 diff --git a/ext/pkcs11-proxy/debian/changelog b/ext/pkcs11-proxy/debian/changelog deleted file mode 100644 index 1aac0c9a8..000000000 --- a/ext/pkcs11-proxy/debian/changelog +++ /dev/null @@ -1,53 +0,0 @@ -pkcs11-proxy (0.4-1ubuntu4) trusty; urgency=medium - - * debian updates - - -- Leif Johansson Fri, 17 Jul 2015 11:02:03 +0200 - -pkcs11-proxy (0.4-1ubuntu3) trusty; urgency=medium - - [ Klaus Darilion ] - * Update seccomp usage to match Ubuntu 14.04. - - -- Fredrik Thulin Tue, 17 Feb 2015 19:20:13 +0100 - -pkcs11-proxy (0.4-1ubuntu2) precise; urgency=low - - * Support IPv6 and connect-fallback through getaddrinfo() - * Implement TLS-PSK using OpenSSL - * Use libseccomp and reduce number of syscalls allowed in dispatchers - * Several important bug fixes (now passes SoftHSM test suite) - - -- Fredrik Thulin Wed, 30 Jan 2013 09:56:34 +0100 - -pkcs11-proxy (0.4-1ubuntu1) precise; urgency=low - - * disable debugging by default - * use syslog instead of stderr unless DEBUG_OUTPUT is 1 - - -- Leif Johansson Tue, 04 Sep 2012 15:58:45 +0200 - -pkcs11-proxy (0.3-1ubuntu~seccomp1) precise; urgency=low - - [ Corentin Chary ] - * debian: remove commonit specific stuff - - [ Andre Grueneberg ] - * Compile in normal debian environment - * Error in SetPIN - - [ Leif Johansson ] - * basic seccmp filter - - -- Leif Johansson Tue, 04 Sep 2012 13:37:56 +0200 - -pkcs11-proxy (0.2-1ubuntu1) precise; urgency=low - - [ Corentin Chary ] - * Initial release. - - [ Leif Johansson ] - * Make it build without the opt prefix - * support for calling pkcs11-daemon from inetd/stunnel directly - - -- Leif Johansson Tue, 04 Sep 2012 09:02:52 +0200 diff --git a/ext/pkcs11-proxy/debian/compat b/ext/pkcs11-proxy/debian/compat deleted file mode 100644 index 7f8f011eb..000000000 --- a/ext/pkcs11-proxy/debian/compat +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/ext/pkcs11-proxy/debian/control b/ext/pkcs11-proxy/debian/control deleted file mode 100755 index 5336e0cfd..000000000 --- a/ext/pkcs11-proxy/debian/control +++ /dev/null @@ -1,22 +0,0 @@ -Source: pkcs11-proxy -Priority: extra -Maintainer: Corentin Chary -Uploaders: Leif Johansson -Build-Depends: cdbs, debhelper (>= 6), cmake, libssl-dev (>= 1.0.0), libseccomp-dev (>= 1.0.0) -Standards-Version: 3.8.0 -Section: libs - -Package: pkcs11-proxy1 -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Recommends: -Description: pkcs11-proxy - A pkcs11 proxy to use pkcs11 over the network - -Package: pkcs11-daemon -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Recommends: -Description: pkcs11-proxy - A pkcs11 daemon to talk with pkcs11-proxy - diff --git a/ext/pkcs11-proxy/debian/copyright b/ext/pkcs11-proxy/debian/copyright deleted file mode 100755 index 4a784223e..000000000 --- a/ext/pkcs11-proxy/debian/copyright +++ /dev/null @@ -1,18 +0,0 @@ -License: - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301, USA. - - -On Debian systems, the complete text of the GNU General -Public License can be found in `/usr/share/common-licenses/GPL-2'. diff --git a/ext/pkcs11-proxy/debian/pkcs11-daemon.install b/ext/pkcs11-proxy/debian/pkcs11-daemon.install deleted file mode 100644 index 972c9c1c9..000000000 --- a/ext/pkcs11-proxy/debian/pkcs11-daemon.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/bin/pkcs11-daemon /usr/bin diff --git a/ext/pkcs11-proxy/debian/pkcs11-proxy1.install b/ext/pkcs11-proxy/debian/pkcs11-proxy1.install deleted file mode 100644 index cce099314..000000000 --- a/ext/pkcs11-proxy/debian/pkcs11-proxy1.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/libpkcs11-proxy*.so* /usr/lib diff --git a/ext/pkcs11-proxy/debian/rules b/ext/pkcs11-proxy/debian/rules deleted file mode 100755 index 6355c4729..000000000 --- a/ext/pkcs11-proxy/debian/rules +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/make -f - -%: - dh $@ --buildsystem=cmake --builddirectory=build --sourcedirectory=. diff --git a/ext/pkcs11-proxy/debian/source/format b/ext/pkcs11-proxy/debian/source/format deleted file mode 100644 index 89ae9db8f..000000000 --- a/ext/pkcs11-proxy/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (native) diff --git a/ext/pkcs11-proxy/egg-buffer.c b/ext/pkcs11-proxy/egg-buffer.c deleted file mode 100644 index 843cec76c..000000000 --- a/ext/pkcs11-proxy/egg-buffer.c +++ /dev/null @@ -1,544 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* egg-buffer.c - Generic data buffer, used by openssh, gnome-keyring - - Copyright (C) 2007 Stefan Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter -*/ -#include "config.h" - -#include -#include - -#include "egg-buffer.h" - -#define DEFAULT_ALLOCATOR ((EggBufferAllocator)realloc) - -int egg_buffer_init(EggBuffer * buffer, size_t reserve) -{ - return egg_buffer_init_full(buffer, reserve, NULL); -} - -int -egg_buffer_init_full(EggBuffer * buffer, size_t reserve, - EggBufferAllocator allocator) -{ - memset(buffer, 0, sizeof(*buffer)); - - if (!allocator) - allocator = DEFAULT_ALLOCATOR; - if (reserve == 0) - reserve = 64; - - buffer->buf = (allocator) (NULL, reserve); - if (!buffer->buf) { - buffer->failures++; - return 0; - } - - buffer->len = 0; - buffer->allocated_len = reserve; - buffer->failures = 0; - buffer->allocator = allocator; - - return 1; -} - -void egg_buffer_init_static(EggBuffer * buffer, unsigned char *buf, size_t len) -{ - memset(buffer, 0, sizeof(*buffer)); - - buffer->buf = buf; - buffer->len = len; - buffer->allocated_len = len; - buffer->failures = 0; - - /* A null allocator, and the buffer can't change in size */ - buffer->allocator = NULL; -} - -void -egg_buffer_init_allocated(EggBuffer * buffer, unsigned char *buf, size_t len, - EggBufferAllocator allocator) -{ - memset(buffer, 0, sizeof(*buffer)); - - if (!allocator) - allocator = DEFAULT_ALLOCATOR; - - buffer->buf = buf; - buffer->len = len; - buffer->allocated_len = len; - buffer->failures = 0; - buffer->allocator = allocator; -} - -void egg_buffer_reset(EggBuffer * buffer) -{ - memset(buffer->buf, 0, buffer->allocated_len); - buffer->len = 0; - buffer->failures = 0; -} - -void egg_buffer_uninit(EggBuffer * buffer) -{ - if (!buffer) - return; - - /* - * Free the memory block using allocator. If no allocator, - * then this memory is ownerd elsewhere and not to be freed. - */ - if (buffer->buf && buffer->allocator) - (buffer->allocator) (buffer->buf, 0); - - memset(buffer, 0, sizeof(*buffer)); -} - -int egg_buffer_set_allocator(EggBuffer * buffer, EggBufferAllocator allocator) -{ - unsigned char *buf = NULL; - - if (!allocator) - allocator = DEFAULT_ALLOCATOR; - if (buffer->allocator == allocator) - return 1; - - if (buffer->allocated_len) { - /* Reallocate memory block using new allocator */ - buf = (allocator) (NULL, buffer->allocated_len); - if (buf == NULL) - return 0; - - /* Copy stuff into new memory */ - memcpy(buf, buffer->buf, buffer->allocated_len); - } - - /* If old wasn't static, then free it */ - if (buffer->allocator && buffer->buf) - (buffer->allocator) (buffer->buf, 0); - - buffer->buf = buf; - buffer->allocator = allocator; - - return 1; -} - -int egg_buffer_equal(EggBuffer * b1, EggBuffer * b2) -{ - if (b1->len != b2->len) - return 0; - return memcmp(b1->buf, b2->buf, b1->len) == 0; -} - -int egg_buffer_reserve(EggBuffer * buffer, size_t len) -{ - unsigned char *newbuf; - size_t newlen; - - if (len < buffer->allocated_len) - return 1; - - /* Calculate a new length, minimize number of buffer allocations */ - newlen = buffer->allocated_len * 2; - if (len > newlen) - newlen += len; - - /* Memory owned elsewhere can't be reallocated */ - if (!buffer->allocator) { - buffer->failures++; - return 0; - } - - /* Reallocate built in buffer using allocator */ - newbuf = (buffer->allocator) (buffer->buf, newlen); - if (!newbuf) { - buffer->failures++; - return 0; - } - - buffer->buf = newbuf; - buffer->allocated_len = newlen; - - return 1; -} - -int egg_buffer_resize(EggBuffer * buffer, size_t len) -{ - if (!egg_buffer_reserve(buffer, len)) - return 0; - - buffer->len = len; - return 1; -} - -unsigned char *egg_buffer_add_empty(EggBuffer * buffer, size_t len) -{ - size_t pos = buffer->len; - if (!egg_buffer_reserve(buffer, buffer->len + len)) - return NULL; - buffer->len += len; - return buffer->buf + pos; -} - -int egg_buffer_append(EggBuffer * buffer, const unsigned char *val, size_t len) -{ - if (!egg_buffer_reserve(buffer, buffer->len + len)) - return 0; /* failures already incremented */ - memcpy(buffer->buf + buffer->len, val, len); - buffer->len += len; - return 1; -} - -int egg_buffer_add_byte(EggBuffer * buffer, unsigned char val) -{ - if (!egg_buffer_reserve(buffer, buffer->len + 1)) - return 0; /* failures already incremented */ - buffer->buf[buffer->len] = val; - buffer->len++; - return 1; -} - -int -egg_buffer_get_byte(EggBuffer * buffer, size_t offset, - size_t * next_offset, unsigned char *val) -{ - unsigned char *ptr; - if (buffer->len < 1 || offset > buffer->len - 1) { - buffer->failures++; - return 0; - } - ptr = (unsigned char *)buffer->buf + offset; - if (val != NULL) - *val = *ptr; - if (next_offset != NULL) - *next_offset = offset + 1; - return 1; -} - -void egg_buffer_encode_uint16(unsigned char *buf, uint16_t val) -{ - buf[0] = (val >> 8) & 0xff; - buf[1] = (val >> 0) & 0xff; -} - -uint16_t egg_buffer_decode_uint16(unsigned char *buf) -{ - uint16_t val = buf[0] << 8 | buf[1]; - return val; -} - -int egg_buffer_add_uint16(EggBuffer * buffer, uint16_t val) -{ - if (!egg_buffer_reserve(buffer, buffer->len + 2)) - return 0; /* failures already incremented */ - buffer->len += 2; - egg_buffer_set_uint16(buffer, buffer->len - 2, val); - return 1; -} - -int egg_buffer_set_uint16(EggBuffer * buffer, size_t offset, uint16_t val) -{ - unsigned char *ptr; - if (buffer->len < 2 || offset > buffer->len - 2) { - buffer->failures++; - return 0; - } - ptr = (unsigned char *)buffer->buf + offset; - egg_buffer_encode_uint16(ptr, val); - return 1; -} - -int -egg_buffer_get_uint16(EggBuffer * buffer, size_t offset, - size_t * next_offset, uint16_t * val) -{ - unsigned char *ptr; - if (buffer->len < 2 || offset > buffer->len - 2) { - buffer->failures++; - return 0; - } - ptr = (unsigned char *)buffer->buf + offset; - if (val != NULL) - *val = egg_buffer_decode_uint16(ptr); - if (next_offset != NULL) - *next_offset = offset + 2; - return 1; -} - -void egg_buffer_encode_uint32(unsigned char *buf, uint32_t val) -{ - buf[0] = (val >> 24) & 0xff; - buf[1] = (val >> 16) & 0xff; - buf[2] = (val >> 8) & 0xff; - buf[3] = (val >> 0) & 0xff; -} - -uint32_t egg_buffer_decode_uint32(unsigned char *ptr) -{ - uint32_t val = ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]; - return val; -} - -int egg_buffer_add_uint32(EggBuffer * buffer, uint32_t val) -{ - if (!egg_buffer_reserve(buffer, buffer->len + 4)) - return 0; /* failures already incremented */ - buffer->len += 4; - egg_buffer_set_uint32(buffer, buffer->len - 4, val); - return 1; -} - -int egg_buffer_set_uint32(EggBuffer * buffer, size_t offset, uint32_t val) -{ - unsigned char *ptr; - if (buffer->len < 4 || offset > buffer->len - 4) { - buffer->failures++; - return 0; - } - ptr = (unsigned char *)buffer->buf + offset; - egg_buffer_encode_uint32(ptr, val); - return 1; -} - -int -egg_buffer_get_uint32(EggBuffer * buffer, size_t offset, size_t * next_offset, - uint32_t * val) -{ - unsigned char *ptr; - if (buffer->len < 4 || offset > buffer->len - 4) { - buffer->failures++; - return 0; - } - ptr = (unsigned char *)buffer->buf + offset; - if (val != NULL) - *val = egg_buffer_decode_uint32(ptr); - if (next_offset != NULL) - *next_offset = offset + 4; - return 1; -} - -int egg_buffer_add_uint64(EggBuffer * buffer, uint64_t val) -{ - if (!egg_buffer_add_uint32(buffer, ((val >> 32) & 0xffffffff))) - return 0; - return egg_buffer_add_uint32(buffer, (val & 0xffffffff)); -} - -int -egg_buffer_get_uint64(EggBuffer * buffer, size_t offset, - size_t * next_offset, uint64_t * val) -{ - uint32_t a, b; - if (!egg_buffer_get_uint32(buffer, offset, &offset, &a)) - return 0; - if (!egg_buffer_get_uint32(buffer, offset, &offset, &b)) - return 0; - if (val != NULL) - *val = ((uint64_t) a) << 32 | b; - if (next_offset != NULL) - *next_offset = offset; - return 1; -} - -int -egg_buffer_add_byte_array(EggBuffer * buffer, const unsigned char *val, - size_t len) -{ - if (val == NULL) - return egg_buffer_add_uint32(buffer, 0xffffffff); - if (len >= 0x7fffffff) { - buffer->failures++; - return 0; - } - if (!egg_buffer_add_uint32(buffer, len)) - return 0; - return egg_buffer_append(buffer, val, len); -} - -unsigned char *egg_buffer_add_byte_array_empty(EggBuffer * buffer, size_t vlen) -{ - if (vlen >= 0x7fffffff) { - buffer->failures++; - return NULL; - } - if (!egg_buffer_add_uint32(buffer, vlen)) - return NULL; - return egg_buffer_add_empty(buffer, vlen); -} - -int -egg_buffer_get_byte_array(EggBuffer * buffer, size_t offset, - size_t * next_offset, const unsigned char **val, - size_t * vlen) -{ - uint32_t len; - if (!egg_buffer_get_uint32(buffer, offset, &offset, &len)) - return 0; - if (len == 0xffffffff) { - if (next_offset) - *next_offset = offset; - if (val) - *val = NULL; - if (vlen) - *vlen = 0; - return 1; - } else if (len >= 0x7fffffff) { - buffer->failures++; - return 0; - } - - if (buffer->len < len || offset > buffer->len - len) { - buffer->failures++; - return 0; - } - - if (val) - *val = buffer->buf + offset; - if (vlen) - *vlen = len; - if (next_offset) - *next_offset = offset + len; - - return 1; -} - -int egg_buffer_add_string(EggBuffer * buffer, const char *str) -{ - if (str == NULL) { - return egg_buffer_add_uint32(buffer, 0xffffffff); - } else { - size_t len = strlen(str); - if (len >= 0x7fffffff) - return 0; - if (!egg_buffer_add_uint32(buffer, len)) - return 0; - return egg_buffer_append(buffer, (unsigned char *)str, len); - } -} - -int -egg_buffer_get_string(EggBuffer * buffer, size_t offset, size_t * next_offset, - char **str_ret, EggBufferAllocator allocator) -{ - uint32_t len; - - if (!allocator) - allocator = buffer->allocator; - if (!allocator) - allocator = DEFAULT_ALLOCATOR; - - if (!egg_buffer_get_uint32(buffer, offset, &offset, &len)) { - return 0; - } - if (len == 0xffffffff) { - *next_offset = offset; - *str_ret = NULL; - return 1; - } else if (len >= 0x7fffffff) { - return 0; - } - - if (buffer->len < len || offset > buffer->len - len) { - return 0; - } - - /* Make sure no null characters in string */ - if (memchr(buffer->buf + offset, 0, len) != NULL) - return 0; - - /* The passed allocator may be for non-pageable memory */ - *str_ret = (allocator) (NULL, len + 1); - if (!*str_ret) - return 0; - memcpy(*str_ret, buffer->buf + offset, len); - - /* Always zero terminate */ - (*str_ret)[len] = 0; - *next_offset = offset + len; - - return 1; -} - -int egg_buffer_add_stringv(EggBuffer * buffer, const char **strv) -{ - const char **v; - uint32_t n = 0; - - if (!strv) - return 0; - - /* Add the number of strings coming */ - for (v = strv; *v; ++v) - ++n; - if (!egg_buffer_add_uint32(buffer, n)) - return 0; - - /* Add the individual strings */ - for (v = strv; *v; ++v) { - if (!egg_buffer_add_string(buffer, *v)) - return 0; - } - - return 1; -} - -int -egg_buffer_get_stringv(EggBuffer * buffer, size_t offset, size_t * next_offset, - char ***strv_ret, EggBufferAllocator allocator) -{ - uint32_t n, i, j; - size_t len; - - if (!allocator) - allocator = buffer->allocator; - if (!allocator) - allocator = DEFAULT_ALLOCATOR; - - /* First the number of environment variable lines */ - if (!egg_buffer_get_uint32(buffer, offset, &offset, &n)) - return 0; - - /* Then that number of strings */ - len = (n + 1) * sizeof(char *); - *strv_ret = (char **)(allocator) (NULL, len); - if (!*strv_ret) - return 0; - - /* All null strings */ - memset(*strv_ret, 0, len); - - for (i = 0; i < n; ++i) { - if (!egg_buffer_get_string(buffer, offset, &offset, - &((*strv_ret)[i]), allocator)) { - - /* Free all the strings on failure */ - for (j = 0; j < i; ++j) { - if ((*strv_ret)[j]) - (allocator) ((*strv_ret)[j], 0); - } - - return 0; - } - } - - if (next_offset != NULL) - *next_offset = offset; - - return 1; -} diff --git a/ext/pkcs11-proxy/egg-buffer.h b/ext/pkcs11-proxy/egg-buffer.h deleted file mode 100644 index 23cb40f0b..000000000 --- a/ext/pkcs11-proxy/egg-buffer.h +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* egg-buffer.h - Generic data buffer, used by openssh, gnome-keyring - - Copyright (C) 2007, Stefan Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter -*/ - -#ifndef EGG_BUFFER_H -#define EGG_BUFFER_H - -#include -#include - -/* ------------------------------------------------------------------- - * EggBuffer - * - * IMPORTANT: This is pure vanila standard C, no glib. We need this - * because certain consumers of this protocol need to be built - * without linking in any special libraries. ie: the PKCS#11 module. - * - * Memory Allocation - * - * Callers can set their own allocator. If NULL is used then standard - * C library heap memory is used and failures will not be fatal. Memory - * failures will instead result in a zero return value or - * egg_buffer_has_error() returning one. - * - * If you use something like g_realloc as the allocator, then memory - * failures become fatal just like in a standard GTK program. - * - * Don't change the allocator manually in the EggBuffer structure. The - * egg_buffer_set_allocator() func will reallocate and handle things - * properly. - * - * Pointers into the Buffer - * - * Any write operation has the posibility of reallocating memory - * and invalidating any direct pointers into the buffer. - */ - -/* The allocator for the EggBuffer. This follows the realloc() syntax and logic */ -typedef void* (*EggBufferAllocator) (void* p, size_t len); - -typedef struct _EggBuffer { - unsigned char *buf; - size_t len; - size_t allocated_len; - int failures; - EggBufferAllocator allocator; -} EggBuffer; - -#define EGG_BUFFER_EMPTY { NULL, 0, 0, 0, NULL } - -int egg_buffer_init (EggBuffer *buffer, size_t reserve); - -int egg_buffer_init_full (EggBuffer *buffer, - size_t reserve, - EggBufferAllocator allocator); - -void egg_buffer_init_static (EggBuffer *buffer, - unsigned char *buf, - size_t len); - -void egg_buffer_init_allocated (EggBuffer *buffer, - unsigned char *buf, - size_t len, - EggBufferAllocator allocator); - -void egg_buffer_uninit (EggBuffer *buffer); - -int egg_buffer_set_allocator (EggBuffer *buffer, - EggBufferAllocator allocator); - -void egg_buffer_reset (EggBuffer *buffer); - -int egg_buffer_equal (EggBuffer *b1, - EggBuffer *b2); - -int egg_buffer_reserve (EggBuffer *buffer, - size_t len); - -int egg_buffer_resize (EggBuffer *buffer, - size_t len); - -int egg_buffer_append (EggBuffer *buffer, - const unsigned char *val, - size_t len); - -unsigned char* egg_buffer_add_empty (EggBuffer *buffer, - size_t len); - -int egg_buffer_add_byte (EggBuffer *buffer, - unsigned char val); - -int egg_buffer_get_byte (EggBuffer *buffer, - size_t offset, - size_t *next_offset, - unsigned char *val); - -void egg_buffer_encode_uint32 (unsigned char* buf, - uint32_t val); - -uint32_t egg_buffer_decode_uint32 (unsigned char* buf); - -int egg_buffer_add_uint32 (EggBuffer *buffer, - uint32_t val); - -int egg_buffer_set_uint32 (EggBuffer *buffer, - size_t offset, - uint32_t val); - -int egg_buffer_get_uint32 (EggBuffer *buffer, - size_t offset, - size_t *next_offset, - uint32_t *val); - -void egg_buffer_encode_uint16 (unsigned char* buf, - uint16_t val); - -uint16_t egg_buffer_decode_uint16 (unsigned char* buf); - -int egg_buffer_add_uint16 (EggBuffer *buffer, - uint16_t val); - -int egg_buffer_set_uint16 (EggBuffer *buffer, - size_t offset, - uint16_t val); - -int egg_buffer_get_uint16 (EggBuffer *buffer, - size_t offset, - size_t *next_offset, - uint16_t *val); - -int egg_buffer_add_byte_array (EggBuffer *buffer, - const unsigned char *val, - size_t len); - -int egg_buffer_get_byte_array (EggBuffer *buffer, - size_t offset, - size_t *next_offset, - const unsigned char **val, - size_t *vlen); - -unsigned char* egg_buffer_add_byte_array_empty (EggBuffer *buffer, - size_t vlen); - -int egg_buffer_add_string (EggBuffer *buffer, - const char *str); - -int egg_buffer_get_string (EggBuffer *buffer, - size_t offset, - size_t *next_offset, - char **str_ret, - EggBufferAllocator allocator); - -int egg_buffer_add_stringv (EggBuffer *buffer, - const char** strv); - -int egg_buffer_get_stringv (EggBuffer *buffer, - size_t offset, - size_t *next_offset, - char ***strv_ret, - EggBufferAllocator allocator); - -int egg_buffer_add_uint64 (EggBuffer *buffer, - uint64_t val); - -int egg_buffer_get_uint64 (EggBuffer *buffer, - size_t offset, - size_t *next_offset, - uint64_t *val); - -#define egg_buffer_length(b) ((b)->len) - -#define egg_buffer_has_error(b) ((b)->failures > 0) - -#endif /* EGG_BUFFER_H */ - diff --git a/ext/pkcs11-proxy/ext/include/dlfcn.h b/ext/pkcs11-proxy/ext/include/dlfcn.h deleted file mode 100644 index dfc255118..000000000 --- a/ext/pkcs11-proxy/ext/include/dlfcn.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * dlfcn-win32 - * Copyright (c) 2007 Ramiro Polla - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef DLFCN_H -#define DLFCN_H - -/* POSIX says these are implementation-defined. - * To simplify use with Windows API, we treat them the same way. - */ - -#define RTLD_LAZY 0 -#define RTLD_NOW 0 - -#define RTLD_GLOBAL (1 << 1) -#define RTLD_LOCAL (1 << 2) - -/* These two were added in The Open Group Base Specifications Issue 6. - * Note: All other RTLD_* flags in any dlfcn.h are not standard compliant. - */ - -#define RTLD_DEFAULT 0 -#define RTLD_NEXT 0 - -void *dlopen ( const char *file, int mode ); -int dlclose( void *handle ); -void *dlsym ( void *handle, const char *name ); -char *dlerror( void ); - -#endif /* DLFCN_H */ diff --git a/ext/pkcs11-proxy/gck-rpc-daemon-standalone.c b/ext/pkcs11-proxy/gck-rpc-daemon-standalone.c deleted file mode 100644 index 3d0564f38..000000000 --- a/ext/pkcs11-proxy/gck-rpc-daemon-standalone.c +++ /dev/null @@ -1,358 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gck-rpc-daemon-standalone.c - A sample daemon. - - Copyright (C) 2008, Stef Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter -*/ - -#include "config.h" - -#include "pkcs11/pkcs11.h" - -#include "gck-rpc-layer.h" -#include "gck-rpc-tls-psk.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#ifdef __MINGW32__ -# include -#endif - -#define SOCKET_PATH "tcp://127.0.0.1" - -#ifdef SECCOMP -#include -//#include "seccomp-bpf.h" -#ifdef DEBUG_SECCOMP -# include "syscall-reporter.h" -#endif /* DEBUG_SECCOMP */ -#include /* for seccomp init */ -#endif /* SECCOMP */ - - -static int install_syscall_filter(const int sock, const char *tls_psk_keyfile, const char *path) -{ -#ifdef SECCOMP - int rc = -1; - scmp_filter_ctx ctx; - -#ifdef DEBUG_SECCOMP - ctx = seccomp_init(SCMP_ACT_TRAP); -#else - ctx = seccomp_init(SCMP_ACT_KILL); -#endif /* DEBUG_SECCOMP */ - if (ctx == NULL) - goto failure_scmp; - /* - * These are the basic syscalls needed to be able to use - * the syscall-reporter to figure out the rest - */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(write), 0); -#ifdef DEBUG_SECCOMP - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); -# ifdef __NR_sigreturn - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(sigreturn), 0); -# endif -#endif /* DEBUG_SECCOMP */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(exit), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); - - /* - * Network related syscalls. - */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(read), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(select), 0); - if (sock) - /* Allow accept() only for the listening socket */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(accept), 1, - SCMP_A0(SCMP_CMP_EQ, sock)); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(sendto), 0); - if (path[0] && - strncmp(path, "tcp://", strlen("tcp://")) == 0) { - /* TCP socket - not needed for TLS */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(recvfrom), 0); - } - - /* - * These are probably pthreads-related. - */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(clone), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(set_robust_list), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(madvise), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(munlock), 0); - - /* - * Both pthreads (? file is "/sys/devices/system/cpu/online") and TLS-PSK open files. - */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(open), 1, - SCMP_A1(SCMP_CMP_EQ, O_RDONLY | O_CLOEXEC)); - - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(close), 0); - - /* - * UNIX domain socket - */ - if (path[0] && - strncmp(path, "tcp://", strlen("tcp://")) != 0 && - strncmp(path, "tls://", strlen("tls://")) != 0) { - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(unlink), 0); - } - - /* - * Allow spawned threads to initialize a new seccomp policy (subset of this). - */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(prctl), 0); - - /* - * SoftHSM 1.3.0 required syscalls - */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(getcwd), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(stat), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(open), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(fcntl), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(fstat), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(lseek), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(access), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(fsync), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(unlink), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(ftruncate), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(select), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(futex), 0); - -#ifdef DEBUG_SECCOMP - /* Dumps the generated BPF rules in sort-of human readable syntax. */ - seccomp_export_pfc(ctx,STDERR_FILENO); - - /* Print the name of syscalls stopped by seccomp. Should not be used in production. */ - if (install_syscall_reporter()) - return 1; -#endif /* DEBUG_SECCOMP */ - - rc = seccomp_load(ctx); - if (rc < 0) - goto failure_scmp; - seccomp_release(ctx); - - return 0; - -failure_scmp: - errno = -rc; - fprintf(stderr, "Seccomp filter initialization failed, errno = %u\n", errno); - return errno; -#else /* SECCOMP */ - return 0; -#endif /* SECCOMP */ -} - - -#if 0 -/* Sample configuration for loading NSS remotely */ -static CK_C_INITIALIZE_ARGS p11_init_args = { - NULL, - NULL, - NULL, - NULL, - CKF_OS_LOCKING_OK, - "init-string = configdir='/tmp' certPrefix='' keyPrefix='' secmod='/tmp/secmod.db' flags=" -}; -#endif - -static int is_running = 1; - -static int usage(void) -{ - fprintf(stderr, "usage: pkcs11-daemon pkcs11-module [|\"-\"]\n\tUsing \"-\" results in a single-thread inetd-type daemon\n"); - exit(2); -} - -void termination_handler (int signum) -{ - is_running = 0; -} - -enum { - /* Used to un-confuse clang checker */ - GCP_RPC_DAEMON_MODE_INETD = 0, - GCP_RPC_DAEMON_MODE_SOCKET -}; - -int main(int argc, char *argv[]) -{ - CK_C_GetFunctionList func_get_list; - CK_FUNCTION_LIST_PTR funcs; - void *module; - const char *path, *tls_psk_keyfile; - fd_set read_fds; - int sock, ret, mode; - CK_RV rv; - CK_C_INITIALIZE_ARGS init_args; - GckRpcTlsPskState *tls; - - /* The module to load is the argument */ - if (argc != 2 && argc != 3) - usage(); - - openlog("pkcs11-proxy",LOG_CONS|LOG_PID,LOG_DAEMON); - - /* Load the library */ - module = dlopen(argv[1], RTLD_NOW); - if (!module) { - fprintf(stderr, "couldn't open library: %s: %s\n", argv[1], - dlerror()); - exit(1); - } - - /* Lookup the appropriate function in library */ - func_get_list = - (CK_C_GetFunctionList) dlsym(module, "C_GetFunctionList"); - if (!func_get_list) { - fprintf(stderr, - "couldn't find C_GetFunctionList in library: %s: %s\n", - argv[1], dlerror()); - exit(1); - } - - /* Get the function list */ - rv = (func_get_list) (&funcs); - if (rv != CKR_OK || !funcs) { - fprintf(stderr, - "couldn't get function list from C_GetFunctionList" - "in libary: %s: 0x%08x\n", - argv[1], (int)rv); - exit(1); - } - - /* RPC layer expects initialized module */ - memset(&init_args, 0, sizeof(init_args)); - init_args.flags = CKF_OS_LOCKING_OK; - - rv = (funcs->C_Initialize) (&init_args); - if (rv != CKR_OK) { - fprintf(stderr, "couldn't initialize module: %s: 0x%08x\n", - argv[1], (int)rv); - exit(1); - } - - path = getenv("PKCS11_DAEMON_SOCKET"); - if (!path && argc == 3) - path = argv[2]; - if (!path) - path = SOCKET_PATH; - - /* Initialize TLS, if appropriate */ - tls = NULL; - tls_psk_keyfile = NULL; - if (! strncmp("tls://", path, 6)) { - tls_psk_keyfile = getenv("PKCS11_PROXY_TLS_PSK_FILE"); - if (! tls_psk_keyfile || ! tls_psk_keyfile[0]) { - fprintf(stderr, "key file must be specified for tls:// socket.\n"); - exit(1); - } - - tls = calloc(1, sizeof(GckRpcTlsPskState)); - if (tls == NULL) { - fprintf(stderr, "can't allocate memory for TLS-PSK"); - exit(1); - } - - if (! gck_rpc_init_tls_psk(tls, tls_psk_keyfile, NULL, GCK_RPC_TLS_PSK_SERVER)) { - fprintf(stderr, "TLS-PSK initialization failed"); - exit(1); - } - } - - if (strcmp(path,"-") == 0) { - /* inetd mode */ - sock = 0; - mode = GCP_RPC_DAEMON_MODE_INETD; - } else { - /* Do some initialization before enabling seccomp. */ - sock = gck_rpc_layer_initialize(path, funcs); - if (sock == -1) - exit(1); - - /* Shut down gracefully on SIGTERM. */ - if (signal (SIGTERM, termination_handler) == SIG_IGN) - signal (SIGTERM, SIG_IGN); - - mode = GCP_RPC_DAEMON_MODE_SOCKET; - } - - /* - * Enable seccomp. This is essentially a whitelist containing all the syscalls - * we expect to call from here on. Anything not whitelisted will cause the - * process to terminate. - */ - if (install_syscall_filter(sock, tls_psk_keyfile, path)) - return 1; - - if (mode == GCP_RPC_DAEMON_MODE_INETD) { - gck_rpc_layer_inetd(funcs); - } else if (mode == GCP_RPC_DAEMON_MODE_SOCKET) { - is_running = 1; - while (is_running) { - FD_ZERO(&read_fds); - FD_SET(sock, &read_fds); - ret = select(sock + 1, &read_fds, NULL, NULL, NULL); - if (ret < 0) { - if (errno == EINTR) - continue; - fprintf(stderr, "error watching socket: %s\n", - strerror(errno)); - exit(1); - } - - if (FD_ISSET(sock, &read_fds)) - gck_rpc_layer_accept(tls); - } - - gck_rpc_layer_uninitialize(); - } else { - /* Not reached */ - exit(-1); - } - - rv = (funcs->C_Finalize) (NULL); - if (rv != CKR_OK) - fprintf(stderr, "couldn't finalize module: %s: 0x%08x\n", - argv[1], (int)rv); - - dlclose(module); - - if (tls) { - gck_rpc_close_tls(tls); - free(tls); - tls = NULL; - } - - return 0; -} diff --git a/ext/pkcs11-proxy/gck-rpc-dispatch.c b/ext/pkcs11-proxy/gck-rpc-dispatch.c deleted file mode 100644 index fd0ef389c..000000000 --- a/ext/pkcs11-proxy/gck-rpc-dispatch.c +++ /dev/null @@ -1,2735 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gck-rpc-dispatch.h - receiver of our PKCS#11 protocol. - - Copyright (C) 2008, Stef Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter -*/ - -#include "config.h" - -#include "gck-rpc-layer.h" -#include "gck-rpc-private.h" -#include "gck-rpc-tls-psk.h" - -#include "pkcs11/pkcs11.h" -#include "pkcs11/pkcs11g.h" -#include "pkcs11/pkcs11i.h" - -#include -#include -#ifdef __MINGW32__ -# include -#else -# include -# include -# include -# include -# include -# include -# include -#endif -#include - -#include -#include -#include -#include -#include -#include - -#ifdef SECCOMP -#include -//#include "seccomp-bpf.h" -#ifdef DEBUG_SECCOMP -# include "syscall-reporter.h" -#endif /* DEBUG_SECCOMP */ -#include /* for seccomp init */ -#endif /* SECCOMP */ -#include - -/* Where we dispatch the calls to */ -static CK_FUNCTION_LIST_PTR pkcs11_module = NULL; - -/* The error returned on protocol failures */ -#define PARSE_ERROR CKR_DEVICE_ERROR -#define PREP_ERROR CKR_DEVICE_MEMORY - -typedef struct { - CK_SESSION_HANDLE id; - CK_SLOT_ID slot; -} SessionState; - -typedef struct _CallState { - GckRpcMessage *req; - GckRpcMessage *resp; - void *allocated; - uint64_t appid; - int call; - int sock; - int (*read)(void *cs, unsigned char *,size_t); - int (*write)(void *cs, unsigned char *,size_t); - struct sockaddr_storage addr; - socklen_t addrlen; - /* XXX Maybe sessions should be a linked list instead, to remove the hard - * upper limit and reduce typical memory use. - */ - SessionState sessions[PKCS11PROXY_MAX_SESSION_COUNT]; - GckRpcTlsPskState *tls; -} CallState; - -typedef struct _DispatchState { - struct _DispatchState *next; - pthread_t thread; - CallState cs; -} DispatchState; - -/* A linked list of dispatcher threads */ -static DispatchState *pkcs11_dispatchers = NULL; - -/* A mutex to protect the dispatcher list */ -static pthread_mutex_t pkcs11_dispatchers_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* To be able to call C_Finalize from call_uninit. */ -static CK_RV rpc_C_Finalize(CallState *); - -static int _install_dispatch_syscall_filter(int use_tls); - -/* ----------------------------------------------------------------------------- - * LOGGING and DEBUGGING - */ -#ifndef DEBUG_OUTPUT -#define DEBUG_OUTPUT 1 -#endif -#if DEBUG_OUTPUT -#define debug(x) gck_rpc_debug x -#else -#define debug(x) -#endif - -#define warning(x) gck_rpc_warn x - -#define return_val_if_fail(x, v) \ - if (!(x)) { rpc_warn ("'%s' not true at %s", #x, __func__); return v; } - -void gck_rpc_log(const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); -#if DEBUG_OUTPUT - vfprintf(stderr, msg, ap); - fprintf(stderr, "\n"); -#else - vsyslog(LOG_INFO,msg,ap); -#endif - va_end(ap); -} - -/* ------------------------------------------------------------------------------- - * CALL STRUCTURES - */ - -static int call_init(CallState * cs) -{ - assert(cs); - - cs->req = gck_rpc_message_new((EggBufferAllocator) realloc); - cs->resp = gck_rpc_message_new((EggBufferAllocator) realloc); - if (!cs->req || !cs->resp) { - gck_rpc_message_free(cs->req); - gck_rpc_message_free(cs->resp); - return 0; - } - - cs->allocated = NULL; - return 1; -} - -static void *call_alloc(CallState * cs, size_t length) -{ - void **data; - - assert(cs); - - if (length > 0x7fffffff) - return NULL; - - data = malloc(sizeof(void *) + length); - if (!data) - return NULL; - - /* Munch up the memory to help catch bugs */ - memset(data, 0xff, sizeof(void *) + length); - - /* Store pointer to next allocated block at beginning */ - *data = cs->allocated; - cs->allocated = data; - - /* Data starts after first pointer */ - return (void *)(data + 1); -} - -static void call_reset(CallState * cs) -{ - void *allocated; - void **data; - - assert(cs); - - allocated = cs->allocated; - while (allocated) { - data = (void **)allocated; - - /* Pointer to the next allocation */ - allocated = *data; - free(data); - } - - cs->allocated = NULL; - gck_rpc_message_reset(cs->req); - gck_rpc_message_reset(cs->resp); -} - -static void call_uninit(CallState * cs) -{ - assert(cs); - - /* Close any open sessions. Without this, the application won't be able - * to reconnect (possibly after a crash). - */ - if (cs->req) - rpc_C_Finalize(cs); - - call_reset(cs); - - gck_rpc_message_free(cs->req); - gck_rpc_message_free(cs->resp); -} - -/* ------------------------------------------------------------------- - * PROTOCOL CODE - */ - -static CK_RV -proto_read_byte_buffer(CallState * cs, CK_BYTE_PTR * buffer, - CK_ULONG_PTR * n_buffer) -{ - GckRpcMessage *msg; - uint8_t flags; - uint32_t length; - - assert(cs); - assert(buffer); - assert(n_buffer); - - msg = cs->req; - - /* Check that we're supposed to be reading this at this point */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "fy")); - - if (!egg_buffer_get_byte - (&msg->buffer, msg->parsed, &msg->parsed, &flags)) - return PARSE_ERROR; - - /* The number of ulongs there's room for on the other end */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &length)) - return PARSE_ERROR; - - - **n_buffer = length; - *buffer = NULL_PTR; - - if ((flags & GCK_RPC_BYTE_BUFFER_NULL_COUNT)) - *n_buffer = NULL_PTR; - - if (! (flags & GCK_RPC_BYTE_BUFFER_NULL_DATA)) { - *buffer = call_alloc(cs, length * sizeof(CK_BYTE)); - if (!*buffer) - return CKR_DEVICE_MEMORY; - } - - return CKR_OK; -} - -static CK_RV -proto_read_byte_array(CallState * cs, CK_BYTE_PTR * array, CK_ULONG * n_array) -{ - GckRpcMessage *msg; - const unsigned char *data; - unsigned char valid; - size_t n_data; - - assert(cs); - - msg = cs->req; - - /* Check that we're supposed to have this at this point */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "ay")); - - /* Read out the byte which says whether data is present or not */ - if (!egg_buffer_get_byte - (&msg->buffer, msg->parsed, &msg->parsed, &valid)) - return PARSE_ERROR; - - if (!valid) { - uint32_t n_size; - /* No array, no data, just length */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &n_size)) - return PARSE_ERROR; - *n_array = (size_t) n_size; - *array = NULL; - return CKR_OK; - } - - /* Point our arguments into the buffer */ - if (!egg_buffer_get_byte_array(&msg->buffer, msg->parsed, &msg->parsed, - &data, &n_data)) - return PARSE_ERROR; - - *array = (CK_BYTE_PTR) data; - *n_array = n_data; - return CKR_OK; -} - -static CK_RV -proto_write_byte_array(CallState * cs, CK_BYTE_PTR array, CK_ULONG_PTR len, - CK_RV ret) -{ - assert(cs); - - /* - * When returning an byte array, in many cases we need to pass - * an invalid array along with a length, which signifies CKR_BUFFER_TOO_SMALL. - */ - - switch (ret) { - case CKR_BUFFER_TOO_SMALL: - array = NULL; - /* fall through */ - case CKR_OK: - break; - - /* Pass all other errors straight through */ - default: - return ret; - }; - - if (!gck_rpc_message_write_byte_array(cs->resp, array, len ? *len : 0)) - return PREP_ERROR; - - return CKR_OK; -} - -static CK_RV -proto_read_ulong_buffer(CallState * cs, CK_ULONG_PTR * buffer, - CK_ULONG * n_buffer) -{ - GckRpcMessage *msg; - uint32_t length; - - assert(cs); - assert(buffer); - assert(n_buffer); - - msg = cs->req; - - /* Check that we're supposed to be reading this at this point */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "fu")); - - /* The number of ulongs there's room for on the other end */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &length)) - return PARSE_ERROR; - - *n_buffer = length; - *buffer = NULL; - - /* If set to zero, then they just want the length */ - if (!length) - return CKR_OK; - - *buffer = call_alloc(cs, length * sizeof(CK_ULONG)); - if (!*buffer) - return CKR_DEVICE_MEMORY; - - return CKR_OK; -} - -static CK_RV -proto_write_ulong_array(CallState * cs, CK_ULONG_PTR array, CK_ULONG len, - CK_RV ret) -{ - assert(cs); - - /* - * When returning an ulong array, in many cases we need to pass - * an invalid array along with a length, which signifies CKR_BUFFER_TOO_SMALL. - */ - - switch (ret) { - case CKR_BUFFER_TOO_SMALL: - array = NULL; - /* fall through */ - case CKR_OK: - break; - - /* Pass all other errors straight through */ - default: - return ret; - }; - - if (!gck_rpc_message_write_ulong_array(cs->resp, array, len)) - return PREP_ERROR; - - return CKR_OK; -} - -static CK_RV -proto_read_attribute_buffer(CallState * cs, CK_ATTRIBUTE_PTR * result, - CK_ULONG * n_result) -{ - CK_ATTRIBUTE_PTR attrs; - GckRpcMessage *msg; - uint32_t n_attrs, i; - uint32_t value; - - assert(cs); - assert(result); - assert(n_result); - - msg = cs->req; - - /* Make sure this is in the rigth order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "fA")); - - /* Read the number of attributes */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &n_attrs)) - return PARSE_ERROR; - - /* Allocate memory for the attribute structures */ - attrs = call_alloc(cs, n_attrs * sizeof(CK_ATTRIBUTE)); - if (!attrs) - return CKR_DEVICE_MEMORY; - - /* Now go through and fill in each one */ - for (i = 0; i < n_attrs; ++i) { - - /* The attribute type */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &value)) - return PARSE_ERROR; - - attrs[i].type = value; - - /* The number of bytes to allocate */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &value)) - return PARSE_ERROR; - - if (value == 0) { - attrs[i].pValue = NULL; - attrs[i].ulValueLen = 0; - } else { - attrs[i].pValue = call_alloc(cs, value); - if (!attrs[i].pValue) - return CKR_DEVICE_MEMORY; - attrs[i].ulValueLen = value; - } - } - - *result = attrs; - *n_result = n_attrs; - return CKR_OK; -} - -static CK_RV -proto_read_attribute_array(CallState * cs, CK_ATTRIBUTE_PTR * result, - CK_ULONG * n_result) -{ - CK_ATTRIBUTE_PTR attrs; - const unsigned char *data; - unsigned char valid; - GckRpcMessage *msg; - uint32_t n_attrs, i; - uint32_t value; - size_t n_data; - - assert(cs); - assert(result); - assert(n_result); - - msg = cs->req; - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "aA")); - - /* Read the number of attributes */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &n_attrs)) - return PARSE_ERROR; - - if (! n_attrs) { - /* If there are no attributes, it makes most sense to make result - * a NULL pointer. What use could one have of a potentially dangling - * pointer anyways? - */ - *result = NULL_PTR; - *n_result = n_attrs; - return CKR_OK; - } - - /* Allocate memory for the attribute structures */ - attrs = call_alloc(cs, n_attrs * sizeof(CK_ATTRIBUTE)); - if (!attrs) - return CKR_DEVICE_MEMORY; - - /* Now go through and fill in each one */ - for (i = 0; i < n_attrs; ++i) { - - /* The attribute type */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &value)) - return PARSE_ERROR; - - attrs[i].type = value; - - /* Whether this one is valid or not */ - if (!egg_buffer_get_byte - (&msg->buffer, msg->parsed, &msg->parsed, &valid)) - return PARSE_ERROR; - - if (valid) { - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &value)) - return PARSE_ERROR; - if (!egg_buffer_get_byte_array - (&msg->buffer, msg->parsed, &msg->parsed, &data, - &n_data)) - return PARSE_ERROR; - - if (data != NULL && n_data != value) { - gck_rpc_warn - ("attribute length and data do not match"); - return PARSE_ERROR; - } - - CK_ULONG a; - - if (value == sizeof (uint64_t) && - value != sizeof (CK_ULONG) && - gck_rpc_has_ulong_parameter(attrs[i].type)) { - - value = sizeof (CK_ULONG); - a = *(uint64_t *)data; - *(CK_ULONG *)data = a; - } - attrs[i].pValue = (CK_VOID_PTR) data; - attrs[i].ulValueLen = value; - } else { - attrs[i].pValue = NULL; - attrs[i].ulValueLen = -1; - } - } - - *result = attrs; - *n_result = n_attrs; - return CKR_OK; -} - -static CK_RV -proto_write_attribute_array(CallState * cs, CK_ATTRIBUTE_PTR array, - CK_ULONG len, CK_RV ret) -{ - assert(cs); - - /* - * When returning an attribute array, certain errors aren't - * actually real errors, these are passed through to the other - * side along with the attribute array. - */ - - switch (ret) { - case CKR_ATTRIBUTE_SENSITIVE: - case CKR_ATTRIBUTE_TYPE_INVALID: - case CKR_BUFFER_TOO_SMALL: - case CKR_OK: - break; - - /* Pass all other errors straight through */ - default: - return ret; - }; - - if (!gck_rpc_message_write_attribute_array(cs->resp, array, len) || - !gck_rpc_message_write_ulong(cs->resp, ret)) - return PREP_ERROR; - - return CKR_OK; -} - -static CK_RV proto_read_space_string(CallState * cs, CK_UTF8CHAR_PTR * val, CK_ULONG length) -{ - GckRpcMessage *msg; - const unsigned char *data; - size_t n_data; - - assert(cs); - assert(val); - - msg = cs->req; - - /* Check that we're supposed to have this at this point */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "s")); - - if (!egg_buffer_get_byte_array - (&msg->buffer, msg->parsed, &msg->parsed, &data, &n_data)) - return PARSE_ERROR; - - /* Allocate a block of memory for it. */ - *val = call_alloc(cs, n_data); - if (!*val) - return CKR_DEVICE_MEMORY; - - memcpy(*val, data, n_data); - - return CKR_OK; -} - -static CK_RV proto_read_mechanism(CallState * cs, CK_MECHANISM_PTR mech) -{ - GckRpcMessage *msg; - const unsigned char *data; - uint32_t value; - size_t n_data; - - assert(cs); - assert(mech); - - msg = cs->req; - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "M")); - - /* The mechanism type */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &value)) - return PARSE_ERROR; - - /* The mechanism data */ - if (!egg_buffer_get_byte_array - (&msg->buffer, msg->parsed, &msg->parsed, &data, &n_data)) - return PARSE_ERROR; - - mech->mechanism = value; - mech->pParameter = (CK_VOID_PTR) data; - mech->ulParameterLen = n_data; - return CKR_OK; -} - -static CK_RV proto_write_info(CallState * cs, CK_INFO_PTR info) -{ - GckRpcMessage *msg; - - assert(cs); - assert(info); - - msg = cs->resp; - - if (!gck_rpc_message_write_version(msg, &info->cryptokiVersion) || - !gck_rpc_message_write_space_string(msg, info->manufacturerID, 32) - || !gck_rpc_message_write_ulong(msg, info->flags) - || !gck_rpc_message_write_space_string(msg, - info->libraryDescription, 32) - || !gck_rpc_message_write_version(msg, &info->libraryVersion)) - return PREP_ERROR; - - return CKR_OK; -} - -static CK_RV proto_write_slot_info(CallState * cs, CK_SLOT_INFO_PTR info) -{ - GckRpcMessage *msg; - - assert(cs); - assert(info); - - msg = cs->resp; - - if (!gck_rpc_message_write_space_string(msg, info->slotDescription, 64) - || !gck_rpc_message_write_space_string(msg, info->manufacturerID, - 32) - || !gck_rpc_message_write_ulong(msg, info->flags) - || !gck_rpc_message_write_version(msg, &info->hardwareVersion) - || !gck_rpc_message_write_version(msg, &info->firmwareVersion)) - return PREP_ERROR; - - return CKR_OK; -} - -static CK_RV proto_write_token_info(CallState * cs, CK_TOKEN_INFO_PTR info) -{ - GckRpcMessage *msg; - - assert(cs); - assert(info); - - msg = cs->resp; - - if (!gck_rpc_message_write_space_string(msg, info->label, 32) || - !gck_rpc_message_write_space_string(msg, info->manufacturerID, 32) - || !gck_rpc_message_write_space_string(msg, info->model, 16) - || !gck_rpc_message_write_space_string(msg, info->serialNumber, 16) - || !gck_rpc_message_write_ulong(msg, info->flags) - || !gck_rpc_message_write_ulong(msg, info->ulMaxSessionCount) - || !gck_rpc_message_write_ulong(msg, info->ulSessionCount) - || !gck_rpc_message_write_ulong(msg, info->ulMaxRwSessionCount) - || !gck_rpc_message_write_ulong(msg, info->ulRwSessionCount) - || !gck_rpc_message_write_ulong(msg, info->ulMaxPinLen) - || !gck_rpc_message_write_ulong(msg, info->ulMinPinLen) - || !gck_rpc_message_write_ulong(msg, info->ulTotalPublicMemory) - || !gck_rpc_message_write_ulong(msg, info->ulFreePublicMemory) - || !gck_rpc_message_write_ulong(msg, info->ulTotalPrivateMemory) - || !gck_rpc_message_write_ulong(msg, info->ulFreePrivateMemory) - || !gck_rpc_message_write_version(msg, &info->hardwareVersion) - || !gck_rpc_message_write_version(msg, &info->firmwareVersion) - || !gck_rpc_message_write_space_string(msg, info->utcTime, 16)) - return PREP_ERROR; - - return CKR_OK; -} - -static CK_RV -proto_write_mechanism_info(CallState * cs, CK_MECHANISM_INFO_PTR info) -{ - GckRpcMessage *msg; - - assert(cs); - assert(info); - - msg = cs->resp; - - if (!gck_rpc_message_write_ulong(msg, info->ulMinKeySize) || - !gck_rpc_message_write_ulong(msg, info->ulMaxKeySize) || - !gck_rpc_message_write_ulong(msg, info->flags)) - return PREP_ERROR; - - return CKR_OK; -} - -static CK_RV proto_write_session_info(CallState * cs, CK_SESSION_INFO_PTR info) -{ - GckRpcMessage *msg; - - assert(cs); - assert(info); - - msg = cs->resp; - - if (!gck_rpc_message_write_ulong(msg, info->slotID) || - !gck_rpc_message_write_ulong(msg, info->state) || - !gck_rpc_message_write_ulong(msg, info->flags) || - !gck_rpc_message_write_ulong(msg, info->ulDeviceError)) - return PREP_ERROR; - - return CKR_OK; -} - -/* ------------------------------------------------------------------- - * CALL MACROS - */ - -#define DECLARE_CK_ULONG_PTR(ck_ulong_ptr_name) \ - CK_ULONG ck_ulong_ptr_name ## _v ; \ - CK_ULONG_PTR ck_ulong_ptr_name ; \ - ck_ulong_ptr_name ## _v = 0; \ - ck_ulong_ptr_name = &ck_ulong_ptr_name ## _v ; - -#define BEGIN_CALL(call_id) \ - debug ((#call_id ": enter")); \ - assert (cs); \ - assert (pkcs11_module); \ - { \ - CK_ ## call_id _func = pkcs11_module-> call_id; \ - CK_RV _ret = CKR_OK; \ - if (!_func) { _ret = CKR_GENERAL_ERROR; goto _cleanup; } - -#define PROCESS_CALL(args)\ - assert (gck_rpc_message_is_verified (cs->req)); \ - _ret = _func args - -#define END_CALL \ - _cleanup: \ - debug (("ret: 0x%x", _ret)); \ - return _ret; \ - } - -#define IN_BYTE(val) \ - if (!gck_rpc_message_read_byte (cs->req, &val)) \ - { _ret = PARSE_ERROR; goto _cleanup; } - -#define IN_ULONG(val) \ - if (!gck_rpc_message_read_ulong (cs->req, &val)) \ - { _ret = PARSE_ERROR; goto _cleanup; } - -#define IN_SPACE_STRING(val, len) \ - _ret = proto_read_space_string (cs, &val, len); \ - if (_ret != CKR_OK) goto _cleanup; - -#define IN_BYTE_BUFFER(buffer, buffer_len_ptr) \ - _ret = proto_read_byte_buffer (cs, &buffer, &buffer_len_ptr); \ - if (_ret != CKR_OK) goto _cleanup; - -#define IN_BYTE_ARRAY(buffer, buffer_len) \ - _ret = proto_read_byte_array (cs, &buffer, &buffer_len); \ - if (_ret != CKR_OK) goto _cleanup; - -#define IN_ULONG_BUFFER(buffer, buffer_len) \ - _ret = proto_read_ulong_buffer (cs, &buffer, &buffer_len); \ - if (_ret != CKR_OK) goto _cleanup; - -#define IN_ATTRIBUTE_BUFFER(buffer, buffer_len) \ - _ret = proto_read_attribute_buffer (cs, &buffer, &buffer_len); \ - if (_ret != CKR_OK) goto _cleanup; - -#define IN_ATTRIBUTE_ARRAY(attrs, n_attrs) \ - _ret = proto_read_attribute_array (cs, &attrs, &n_attrs); \ - if (_ret != CKR_OK) goto _cleanup; - -#define IN_MECHANISM(mech) \ - _ret = proto_read_mechanism (cs, &mech); \ - if (_ret != CKR_OK) goto _cleanup; - -#define OUT_ULONG(val) \ - if (_ret == CKR_OK && !gck_rpc_message_write_ulong (cs->resp, val)) \ - _ret = PREP_ERROR; - -#define OUT_BYTE_ARRAY(array, len_ptr) \ - /* Note how we filter return codes */ \ - _ret = proto_write_byte_array (cs, array, len_ptr, _ret); - -#define OUT_ULONG_ARRAY(array, len) \ - /* Note how we filter return codes */ \ - _ret = proto_write_ulong_array (cs, array, len, _ret); - -#define OUT_ATTRIBUTE_ARRAY(array, len) \ - /* Note how we filter return codes */ \ - _ret = proto_write_attribute_array (cs, array, len, _ret); - -#define OUT_INFO(val) \ - if (_ret == CKR_OK) \ - _ret = proto_write_info (cs, &val); - -#define OUT_SLOT_INFO(val) \ - if (_ret == CKR_OK) \ - _ret = proto_write_slot_info (cs, &val); - -#define OUT_TOKEN_INFO(val) \ - if (_ret == CKR_OK) \ - _ret = proto_write_token_info (cs, &val); - -#define OUT_MECHANISM_INFO(val) \ - if (_ret == CKR_OK) \ - _ret = proto_write_mechanism_info (cs, &val); - -#define OUT_SESSION_INFO(val) \ - if (_ret == CKR_OK) \ - _ret = proto_write_session_info (cs, &val); - -/* --------------------------------------------------------------------------- - * DISPATCH SPECIFIC CALLS - */ - -static CK_RV rpc_C_Initialize(CallState * cs) -{ - CK_BYTE_PTR handshake; - CK_ULONG n_handshake; - CK_RV ret = CKR_OK; - - debug(("C_Initialize: enter")); - - assert(cs); - assert(pkcs11_module); - - ret = proto_read_byte_array(cs, &handshake, &n_handshake); - if (ret == CKR_OK) { - - /* Check to make sure the header matches */ - if (n_handshake != GCK_RPC_HANDSHAKE_LEN || - handshake == NULL_PTR || - memcmp(handshake, GCK_RPC_HANDSHAKE, n_handshake) != 0) { - gck_rpc_warn - ("invalid handshake received from connecting module"); - ret = CKR_GENERAL_ERROR; - } - - assert(gck_rpc_message_is_verified(cs->req)); - } - - /* - * We don't actually C_Initialize lower layers. It's assumed - * that they'll already be initialzied by the code that loaded us. - */ - - debug(("ret: %d", ret)); - return ret; -} - -static CK_RV rpc_C_Finalize(CallState * cs) -{ - CK_ULONG i; - CK_RV ret; - DispatchState *ds, *next; - - - debug(("C_Finalize: enter")); - - assert(cs); - assert(pkcs11_module); - - /* - * We don't actually C_Finalize lower layers, since this would finalize - * for all appartments, client applications. Anyway this is done by - * the code that loaded us. - */ - - ret = CKR_OK; - - /* Close all sessions that have been opened by this thread, regardless of slot */ - for (i = 0; i < PKCS11PROXY_MAX_SESSION_COUNT; i++) { - if (cs->sessions[i].id) { - gck_rpc_log("Closing session %li on position %i", cs->sessions[i].id, i); - - ret = (pkcs11_module->C_CloseSession) (cs->sessions[i].id); - if (ret != CKR_OK) - break; - cs->sessions[i].id = 0; - } - } - - /* Make all C_WaitForSlotEvent calls return */ - pthread_mutex_lock(&pkcs11_dispatchers_mutex); - for (ds = pkcs11_dispatchers; ds; ds = next) { - CallState *c = &ds->cs; - - next = ds->next; - - if (c->appid != cs->appid) - continue ; - if (c->sock == cs->sock) - continue ; - if (c->req && - (c->req->call_id == GCK_RPC_CALL_C_WaitForSlotEvent)) { - gck_rpc_log("Sending interuption signal to %i\n", - c->sock); - if (c->sock != -1) - if (shutdown(c->sock, SHUT_RDWR) == 0) - c->sock = -1; - //pthread_kill(ds->thread, SIGINT); - } - } - pthread_mutex_unlock(&pkcs11_dispatchers_mutex); - - debug(("ret: %d", ret)); - return ret; -} - -static CK_RV rpc_C_GetInfo(CallState * cs) -{ - CK_INFO info; - - BEGIN_CALL(C_GetInfo); - PROCESS_CALL((&info)); - OUT_INFO(info); - END_CALL; -} - -static CK_RV rpc_C_GetSlotList(CallState * cs) -{ - CK_BBOOL token_present; - CK_SLOT_ID_PTR slot_list; - CK_ULONG count; - - BEGIN_CALL(C_GetSlotList); - IN_BYTE(token_present); - IN_ULONG_BUFFER(slot_list, count); - PROCESS_CALL((token_present, slot_list, &count)); - OUT_ULONG_ARRAY(slot_list, count); - END_CALL; -} - -static CK_RV rpc_C_GetSlotInfo(CallState * cs) -{ - CK_SLOT_ID slot_id; - CK_SLOT_INFO info; - - /* Slot id becomes appartment so lower layers can tell clients apart. */ - - BEGIN_CALL(C_GetSlotInfo); - IN_ULONG(slot_id); - PROCESS_CALL((slot_id, &info)); - OUT_SLOT_INFO(info); - END_CALL; -} - -static CK_RV rpc_C_GetTokenInfo(CallState * cs) -{ - CK_SLOT_ID slot_id; - CK_TOKEN_INFO info; - - /* Slot id becomes appartment so lower layers can tell clients apart. */ - - BEGIN_CALL(C_GetTokenInfo); - IN_ULONG(slot_id); - PROCESS_CALL((slot_id, &info)); - OUT_TOKEN_INFO(info); - END_CALL; -} - -static CK_RV rpc_C_GetMechanismList(CallState * cs) -{ - CK_SLOT_ID slot_id; - CK_MECHANISM_TYPE_PTR mechanism_list; - CK_ULONG count; - - /* Slot id becomes appartment so lower layers can tell clients apart. */ - - BEGIN_CALL(C_GetMechanismList); - IN_ULONG(slot_id); - IN_ULONG_BUFFER(mechanism_list, count); - PROCESS_CALL((slot_id, mechanism_list, &count)); - OUT_ULONG_ARRAY(mechanism_list, count); - END_CALL; -} - -static CK_RV rpc_C_GetMechanismInfo(CallState * cs) -{ - CK_SLOT_ID slot_id; - CK_MECHANISM_TYPE type; - CK_MECHANISM_INFO info; - - /* Slot id becomes appartment so lower layers can tell clients apart. */ - - BEGIN_CALL(C_GetMechanismInfo); - IN_ULONG(slot_id); - IN_ULONG(type); - PROCESS_CALL((slot_id, type, &info)); - OUT_MECHANISM_INFO(info); - END_CALL; -} - -static CK_RV rpc_C_InitToken(CallState * cs) -{ - CK_SLOT_ID slot_id; - CK_UTF8CHAR_PTR pin; - CK_ULONG pin_len; - CK_UTF8CHAR_PTR label; - - /* Slot id becomes appartment so lower layers can tell clients apart. */ - - BEGIN_CALL(C_InitToken); - IN_ULONG(slot_id); - IN_BYTE_ARRAY(pin, pin_len); - IN_SPACE_STRING(label, 32); - PROCESS_CALL((slot_id, pin, pin_len, label)); - END_CALL; -} - -static CK_RV rpc_C_WaitForSlotEvent(CallState * cs) -{ - CK_FLAGS flags; - CK_SLOT_ID slot_id; - - /* Get slot id from appartment lower layers use. */ - - BEGIN_CALL(C_WaitForSlotEvent); - IN_ULONG(flags); - PROCESS_CALL((flags, &slot_id, NULL)); - slot_id = CK_GNOME_APPARTMENT_SLOT(slot_id); - OUT_ULONG(slot_id); - END_CALL; -} - -static CK_RV rpc_C_OpenSession(CallState * cs) -{ - CK_SLOT_ID slot_id; - CK_FLAGS flags; - CK_SESSION_HANDLE session; - - /* Slot id becomes appartment so lower layers can tell clients apart. */ - - BEGIN_CALL(C_OpenSession); - IN_ULONG(slot_id); - IN_ULONG(flags); - PROCESS_CALL((slot_id, flags, NULL, NULL, &session)); - if (_ret == CKR_OK) { - int i; - /* Remember this thread opened this session. Needed for C_CloseAllSessions. */ - for (i = 0; i < PKCS11PROXY_MAX_SESSION_COUNT; i++) { - if (! cs->sessions[i].id) { - cs->sessions[i].id = session; - cs->sessions[i].slot = slot_id; - gck_rpc_log("Session %li stored in position %i", session, i); - break; - } - } - if (i == PKCS11PROXY_MAX_SESSION_COUNT) { - _ret = CKR_SESSION_COUNT; goto _cleanup; - } - } - OUT_ULONG(session); - END_CALL; -} - -static CK_RV rpc_C_CloseSession(CallState * cs) -{ - CK_SESSION_HANDLE session; - - BEGIN_CALL(C_CloseSession); - IN_ULONG(session); - PROCESS_CALL((session)); - if (_ret == CKR_OK) { - int i; - /* Remove this session from this threads list */ - for (i = 0; i < PKCS11PROXY_MAX_SESSION_COUNT; i++) { - if (cs->sessions[i].id == session) { - gck_rpc_log("Session %li removed from position %i", session, i); - cs->sessions[i].id = 0; - break; - } - } - if (i == PKCS11PROXY_MAX_SESSION_COUNT) { - /* Ignore errors, like with close() */ - gck_rpc_log("C_CloseSession on unknown session"); - } - } - END_CALL; -} - -static CK_RV rpc_C_CloseAllSessions(CallState * cs) -{ - CK_SLOT_ID slot_id; - CK_SLOT_INFO slotInfo; - int i; - - /* Close all sessions that have been opened by this thread. PKCS#11 (v2.2) says - * C_CloseAllSessions closes all the sessions opened by one application, leaving - * sessions opened by other applications alone even if the sessions share slot. - * - * Each application on the client side of pkcs11-proxy will mean different thread - * on the server side, so we should close all sessions for a slot opened in this - * thread. - */ - - BEGIN_CALL(C_CloseAllSessions); - IN_ULONG(slot_id); - - /* To emulate real C_CloseAllSessions (well, the SoftHSM one) we check if slot_id is valid. */ - _ret = pkcs11_module->C_GetSlotInfo(slot_id, &slotInfo); - if (_ret != CKR_OK) - goto _cleanup; - - for (i = 0; i < PKCS11PROXY_MAX_SESSION_COUNT; i++) { - if (cs->sessions[i].id && (cs->sessions[i].slot == slot_id)) { - gck_rpc_log("Closing session %li on position %i with slot %i", cs->sessions[i].id, i, slot_id); - - _ret = (pkcs11_module->C_CloseSession) (cs->sessions[i].id); - if (_ret == CKR_OK || - _ret == CKR_SESSION_CLOSED || - _ret == CKR_SESSION_HANDLE_INVALID) { - cs->sessions[i].id = 0; - } - if (_ret != CKR_OK) - goto _cleanup; - } - } - END_CALL; -} - -static CK_RV rpc_C_GetFunctionStatus(CallState * cs) -{ - CK_SESSION_HANDLE session; - - BEGIN_CALL(C_GetFunctionStatus); - IN_ULONG(session); - PROCESS_CALL((session)); - END_CALL; -} - -static CK_RV rpc_C_CancelFunction(CallState * cs) -{ - CK_SESSION_HANDLE session; - - BEGIN_CALL(C_CancelFunction); - IN_ULONG(session); - PROCESS_CALL((session)); - END_CALL; -} - -static CK_RV rpc_C_GetSessionInfo(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_SESSION_INFO info; - - /* Get slot id from appartment lower layers use. */ - - BEGIN_CALL(C_GetSessionInfo); - IN_ULONG(session); - PROCESS_CALL((session, &info)); - info.slotID = CK_GNOME_APPARTMENT_SLOT(info.slotID); - OUT_SESSION_INFO(info); - END_CALL; -} - -static CK_RV rpc_C_InitPIN(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_UTF8CHAR_PTR pin; - CK_ULONG pin_len; - - BEGIN_CALL(C_InitPIN); - IN_ULONG(session); - IN_BYTE_ARRAY(pin, pin_len); - PROCESS_CALL((session, pin, pin_len)); - END_CALL; -} - -static CK_RV rpc_C_SetPIN(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_UTF8CHAR_PTR old_pin; - CK_ULONG old_len; - CK_UTF8CHAR_PTR new_pin; - CK_ULONG new_len; - - BEGIN_CALL(C_SetPIN); - IN_ULONG(session); - IN_BYTE_ARRAY(old_pin, old_len); - IN_BYTE_ARRAY(new_pin, new_len); - PROCESS_CALL((session, old_pin, old_len, new_pin, new_len)); - END_CALL; -} - -static CK_RV rpc_C_GetOperationState(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR operation_state; - DECLARE_CK_ULONG_PTR(operation_state_len); - - BEGIN_CALL(C_GetOperationState); - IN_ULONG(session); - IN_BYTE_BUFFER(operation_state, operation_state_len); - PROCESS_CALL((session, operation_state, operation_state_len)); - OUT_BYTE_ARRAY(operation_state, operation_state_len); - END_CALL; -} - -static CK_RV rpc_C_SetOperationState(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR operation_state; - CK_ULONG operation_state_len; - CK_OBJECT_HANDLE encryption_key; - CK_OBJECT_HANDLE authentication_key; - - BEGIN_CALL(C_SetOperationState); - IN_ULONG(session); - IN_BYTE_ARRAY(operation_state, operation_state_len); - IN_ULONG(encryption_key); - IN_ULONG(authentication_key); - PROCESS_CALL((session, operation_state, operation_state_len, - encryption_key, authentication_key)); - END_CALL; -} - -static CK_RV rpc_C_Login(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_USER_TYPE user_type; - CK_UTF8CHAR_PTR pin; - CK_ULONG pin_len; - - BEGIN_CALL(C_Login); - IN_ULONG(session); - IN_ULONG(user_type); - IN_BYTE_ARRAY(pin, pin_len); - PROCESS_CALL((session, user_type, pin, pin_len)); - END_CALL; -} - -static CK_RV rpc_C_Logout(CallState * cs) -{ - CK_SESSION_HANDLE session; - - BEGIN_CALL(C_Logout); - IN_ULONG(session); - PROCESS_CALL((session)); - END_CALL; -} - -/* ----------------------------------------------------------------------------- - * OBJECT OPERATIONS - */ - -static CK_RV rpc_C_CreateObject(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_ATTRIBUTE_PTR template; - CK_ULONG count; - CK_OBJECT_HANDLE new_object; - - BEGIN_CALL(C_CreateObject); - IN_ULONG(session); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL((session, template, count, &new_object)); - OUT_ULONG(new_object); - END_CALL; -} - -static CK_RV rpc_C_CopyObject(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_OBJECT_HANDLE object; - CK_ATTRIBUTE_PTR template; - CK_ULONG count; - CK_OBJECT_HANDLE new_object; - - BEGIN_CALL(C_CopyObject); - IN_ULONG(session); - IN_ULONG(object); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL((session, object, template, count, &new_object)); - OUT_ULONG(new_object); - END_CALL; -} - -static CK_RV rpc_C_DestroyObject(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_OBJECT_HANDLE object; - - BEGIN_CALL(C_DestroyObject); - IN_ULONG(session); - IN_ULONG(object); - PROCESS_CALL((session, object)); - END_CALL; -} - -static CK_RV rpc_C_GetObjectSize(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_OBJECT_HANDLE object; - CK_ULONG size; - - BEGIN_CALL(C_GetObjectSize); - IN_ULONG(session); - IN_ULONG(object); - PROCESS_CALL((session, object, &size)); - OUT_ULONG(size); - END_CALL; -} - -static CK_RV rpc_C_GetAttributeValue(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_OBJECT_HANDLE object; - CK_ATTRIBUTE_PTR template; - CK_ULONG count; - - BEGIN_CALL(C_GetAttributeValue); - IN_ULONG(session); - IN_ULONG(object); - IN_ATTRIBUTE_BUFFER(template, count); - PROCESS_CALL((session, object, template, count)); - OUT_ATTRIBUTE_ARRAY(template, count); - END_CALL; -} - -static CK_RV rpc_C_SetAttributeValue(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_OBJECT_HANDLE object; - CK_ATTRIBUTE_PTR template; - CK_ULONG count; - - BEGIN_CALL(C_SetAttributeValue); - IN_ULONG(session); - IN_ULONG(object); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL((session, object, template, count)); - END_CALL; -} - -static CK_RV rpc_C_FindObjectsInit(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_ATTRIBUTE_PTR template; - CK_ULONG count; - - BEGIN_CALL(C_FindObjectsInit); - IN_ULONG(session); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL((session, template, count)); - END_CALL; -} - -static CK_RV rpc_C_FindObjects(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_OBJECT_HANDLE_PTR objects; - CK_ULONG max_object_count; - CK_ULONG object_count; - - BEGIN_CALL(C_FindObjects); - IN_ULONG(session); - IN_ULONG_BUFFER(objects, max_object_count); - PROCESS_CALL((session, objects, max_object_count, &object_count)); - OUT_ULONG_ARRAY(objects, object_count); - END_CALL; -} - -static CK_RV rpc_C_FindObjectsFinal(CallState * cs) -{ - CK_SESSION_HANDLE session; - - BEGIN_CALL(C_FindObjectsFinal); - IN_ULONG(session); - PROCESS_CALL((session)); - END_CALL; -} - -static CK_RV rpc_C_EncryptInit(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_OBJECT_HANDLE key; - - BEGIN_CALL(C_EncryptInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL((session, &mechanism, key)); - END_CALL; - -} - -static CK_RV rpc_C_Encrypt(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR data; - CK_ULONG data_len; - CK_BYTE_PTR encrypted_data; - DECLARE_CK_ULONG_PTR(encrypted_data_len); - - BEGIN_CALL(C_Encrypt); - IN_ULONG(session); - IN_BYTE_ARRAY(data, data_len); - IN_BYTE_BUFFER(encrypted_data, encrypted_data_len); - PROCESS_CALL((session, data, data_len, encrypted_data, - encrypted_data_len)); - OUT_BYTE_ARRAY(encrypted_data, encrypted_data_len); - END_CALL; -} - -static CK_RV rpc_C_EncryptUpdate(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR part; - CK_ULONG part_len; - CK_BYTE_PTR encrypted_part; - DECLARE_CK_ULONG_PTR(encrypted_part_len); - - BEGIN_CALL(C_EncryptUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - IN_BYTE_BUFFER(encrypted_part, encrypted_part_len); - PROCESS_CALL((session, part, part_len, encrypted_part, - encrypted_part_len)); - OUT_BYTE_ARRAY(encrypted_part, encrypted_part_len); - END_CALL; -} - -static CK_RV rpc_C_EncryptFinal(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR last_encrypted_part; - DECLARE_CK_ULONG_PTR(last_encrypted_part_len); - - BEGIN_CALL(C_EncryptFinal); - IN_ULONG(session); - IN_BYTE_BUFFER(last_encrypted_part, last_encrypted_part_len); - PROCESS_CALL((session, last_encrypted_part, last_encrypted_part_len)); - OUT_BYTE_ARRAY(last_encrypted_part, last_encrypted_part_len); - END_CALL; -} - -static CK_RV rpc_C_DecryptInit(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_OBJECT_HANDLE key; - - BEGIN_CALL(C_DecryptInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL((session, &mechanism, key)); - END_CALL; -} - -static CK_RV rpc_C_Decrypt(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR encrypted_data; - CK_ULONG encrypted_data_len; - CK_BYTE_PTR data; - DECLARE_CK_ULONG_PTR(data_len); - - BEGIN_CALL(C_Decrypt); - IN_ULONG(session); - IN_BYTE_ARRAY(encrypted_data, encrypted_data_len); - IN_BYTE_BUFFER(data, data_len); - PROCESS_CALL((session, encrypted_data, encrypted_data_len, data, - data_len)); - OUT_BYTE_ARRAY(data, data_len); - END_CALL; -} - -static CK_RV rpc_C_DecryptUpdate(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR encrypted_part; - CK_ULONG encrypted_part_len; - CK_BYTE_PTR part; - DECLARE_CK_ULONG_PTR(part_len); - - BEGIN_CALL(C_DecryptUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(encrypted_part, encrypted_part_len); - IN_BYTE_BUFFER(part, part_len); - PROCESS_CALL((session, encrypted_part, encrypted_part_len, part, - part_len)); - OUT_BYTE_ARRAY(part, part_len); - END_CALL; -} - -static CK_RV rpc_C_DecryptFinal(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR last_part; - DECLARE_CK_ULONG_PTR(last_part_len); - - BEGIN_CALL(C_DecryptFinal); - IN_ULONG(session); - IN_BYTE_BUFFER(last_part, last_part_len); - PROCESS_CALL((session, last_part, last_part_len)); - OUT_BYTE_ARRAY(last_part, last_part_len); - END_CALL; -} - -static CK_RV rpc_C_DigestInit(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - - BEGIN_CALL(C_DigestInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - PROCESS_CALL((session, &mechanism)); - END_CALL; -} - -static CK_RV rpc_C_Digest(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR data; - CK_ULONG data_len; - CK_BYTE_PTR digest; - DECLARE_CK_ULONG_PTR(digest_len); - - BEGIN_CALL(C_Digest); - IN_ULONG(session); - IN_BYTE_ARRAY(data, data_len); - IN_BYTE_BUFFER(digest, digest_len); - PROCESS_CALL((session, data, data_len, digest, digest_len)); - OUT_BYTE_ARRAY(digest, digest_len); - END_CALL; -} - -static CK_RV rpc_C_DigestUpdate(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR part; - CK_ULONG part_len; - - BEGIN_CALL(C_DigestUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - PROCESS_CALL((session, part, part_len)); - END_CALL; -} - -static CK_RV rpc_C_DigestKey(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_OBJECT_HANDLE key; - - BEGIN_CALL(C_DigestKey); - IN_ULONG(session); - IN_ULONG(key); - PROCESS_CALL((session, key)); - END_CALL; -} - -static CK_RV rpc_C_DigestFinal(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR digest; - DECLARE_CK_ULONG_PTR(digest_len); - - BEGIN_CALL(C_DigestFinal); - IN_ULONG(session); - IN_BYTE_BUFFER(digest, digest_len); - PROCESS_CALL((session, digest, digest_len)); - OUT_BYTE_ARRAY(digest, digest_len); - END_CALL; -} - -static CK_RV rpc_C_SignInit(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_OBJECT_HANDLE key; - - BEGIN_CALL(C_SignInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL((session, &mechanism, key)); - END_CALL; -} - -static CK_RV rpc_C_Sign(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR part; - CK_ULONG part_len; - CK_BYTE_PTR signature; - DECLARE_CK_ULONG_PTR(signature_len); - - BEGIN_CALL(C_Sign); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - IN_BYTE_BUFFER(signature, signature_len); - PROCESS_CALL((session, part, part_len, signature, signature_len)); - OUT_BYTE_ARRAY(signature, signature_len); - END_CALL; - -} - -static CK_RV rpc_C_SignUpdate(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR part; - CK_ULONG part_len; - - BEGIN_CALL(C_SignUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - PROCESS_CALL((session, part, part_len)); - END_CALL; -} - -static CK_RV rpc_C_SignFinal(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR signature; - DECLARE_CK_ULONG_PTR(signature_len); - - BEGIN_CALL(C_SignFinal); - IN_ULONG(session); - IN_BYTE_BUFFER(signature, signature_len); - PROCESS_CALL((session, signature, signature_len)); - OUT_BYTE_ARRAY(signature, signature_len); - END_CALL; -} - -static CK_RV rpc_C_SignRecoverInit(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_OBJECT_HANDLE key; - - BEGIN_CALL(C_SignRecoverInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL((session, &mechanism, key)); - END_CALL; -} - -static CK_RV rpc_C_SignRecover(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR data; - CK_ULONG data_len; - CK_BYTE_PTR signature; - DECLARE_CK_ULONG_PTR(signature_len); - - BEGIN_CALL(C_SignRecover); - IN_ULONG(session); - IN_BYTE_ARRAY(data, data_len); - IN_BYTE_BUFFER(signature, signature_len); - PROCESS_CALL((session, data, data_len, signature, signature_len)); - OUT_BYTE_ARRAY(signature, signature_len); - END_CALL; -} - -static CK_RV rpc_C_VerifyInit(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_OBJECT_HANDLE key; - - BEGIN_CALL(C_VerifyInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL((session, &mechanism, key)); - END_CALL; -} - -static CK_RV rpc_C_Verify(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR data; - CK_ULONG data_len; - CK_BYTE_PTR signature; - CK_ULONG signature_len; - - BEGIN_CALL(C_Verify); - IN_ULONG(session); - IN_BYTE_ARRAY(data, data_len); - IN_BYTE_ARRAY(signature, signature_len); - PROCESS_CALL((session, data, data_len, signature, signature_len)); - END_CALL; -} - -static CK_RV rpc_C_VerifyUpdate(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR part; - CK_ULONG part_len; - - BEGIN_CALL(C_VerifyUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - PROCESS_CALL((session, part, part_len)); - END_CALL; -} - -static CK_RV rpc_C_VerifyFinal(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR signature; - CK_ULONG signature_len; - - BEGIN_CALL(C_VerifyFinal); - IN_ULONG(session); - IN_BYTE_ARRAY(signature, signature_len); - PROCESS_CALL((session, signature, signature_len)); - END_CALL; -} - -static CK_RV rpc_C_VerifyRecoverInit(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_OBJECT_HANDLE key; - - BEGIN_CALL(C_VerifyRecoverInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL((session, &mechanism, key)); - END_CALL; -} - -static CK_RV rpc_C_VerifyRecover(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR signature; - CK_ULONG signature_len; - CK_BYTE_PTR data; - DECLARE_CK_ULONG_PTR(data_len); - - BEGIN_CALL(C_VerifyRecover); - IN_ULONG(session); - IN_BYTE_ARRAY(signature, signature_len); - IN_BYTE_BUFFER(data, data_len); - PROCESS_CALL((session, signature, signature_len, data, data_len)); - OUT_BYTE_ARRAY(data, data_len); - END_CALL; -} - -static CK_RV rpc_C_DigestEncryptUpdate(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR part; - CK_ULONG part_len; - CK_BYTE_PTR encrypted_part; - DECLARE_CK_ULONG_PTR(encrypted_part_len); - - BEGIN_CALL(C_DigestEncryptUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - IN_BYTE_BUFFER(encrypted_part, encrypted_part_len); - PROCESS_CALL((session, part, part_len, encrypted_part, - encrypted_part_len)); - OUT_BYTE_ARRAY(encrypted_part, encrypted_part_len); - END_CALL; -} - -static CK_RV rpc_C_DecryptDigestUpdate(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR encrypted_part; - CK_ULONG encrypted_part_len; - CK_BYTE_PTR part; - DECLARE_CK_ULONG_PTR(part_len); - - BEGIN_CALL(C_DecryptDigestUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(encrypted_part, encrypted_part_len); - IN_BYTE_BUFFER(part, part_len); - PROCESS_CALL((session, encrypted_part, encrypted_part_len, part, - part_len)); - OUT_BYTE_ARRAY(part, part_len); - END_CALL; -} - -static CK_RV rpc_C_SignEncryptUpdate(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR part; - CK_ULONG part_len; - CK_BYTE_PTR encrypted_part; - DECLARE_CK_ULONG_PTR(encrypted_part_len); - - BEGIN_CALL(C_SignEncryptUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - IN_BYTE_BUFFER(encrypted_part, encrypted_part_len); - PROCESS_CALL((session, part, part_len, encrypted_part, - encrypted_part_len)); - OUT_BYTE_ARRAY(encrypted_part, encrypted_part_len); - END_CALL; -} - -static CK_RV rpc_C_DecryptVerifyUpdate(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR encrypted_part; - CK_ULONG encrypted_part_len; - CK_BYTE_PTR part; - DECLARE_CK_ULONG_PTR(part_len); - - BEGIN_CALL(C_DecryptVerifyUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(encrypted_part, encrypted_part_len); - IN_BYTE_BUFFER(part, part_len); - PROCESS_CALL((session, encrypted_part, encrypted_part_len, part, - part_len)); - OUT_BYTE_ARRAY(part, part_len); - END_CALL; -} - -/* ----------------------------------------------------------------------------- - * KEY OPERATIONS - */ - -static CK_RV rpc_C_GenerateKey(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_ATTRIBUTE_PTR template; - CK_ULONG count; - CK_OBJECT_HANDLE key; - - BEGIN_CALL(C_GenerateKey); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL((session, &mechanism, template, count, &key)); - OUT_ULONG(key); - END_CALL; -} - -static CK_RV rpc_C_GenerateKeyPair(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_ATTRIBUTE_PTR public_key_template; - CK_ULONG public_key_attribute_count; - CK_ATTRIBUTE_PTR private_key_template; - CK_ULONG private_key_attribute_count; - CK_OBJECT_HANDLE public_key; - CK_OBJECT_HANDLE private_key; - - BEGIN_CALL(C_GenerateKeyPair); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ATTRIBUTE_ARRAY(public_key_template, public_key_attribute_count); - IN_ATTRIBUTE_ARRAY(private_key_template, private_key_attribute_count); - PROCESS_CALL((session, &mechanism, public_key_template, - public_key_attribute_count, private_key_template, - private_key_attribute_count, &public_key, &private_key)); - OUT_ULONG(public_key); - OUT_ULONG(private_key); - END_CALL; - -} - -static CK_RV rpc_C_WrapKey(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_OBJECT_HANDLE wrapping_key; - CK_OBJECT_HANDLE key; - CK_BYTE_PTR wrapped_key; - DECLARE_CK_ULONG_PTR(wrapped_key_len); - - BEGIN_CALL(C_WrapKey); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(wrapping_key); - IN_ULONG(key); - IN_BYTE_BUFFER(wrapped_key, wrapped_key_len); - PROCESS_CALL((session, &mechanism, wrapping_key, key, wrapped_key, - wrapped_key_len)); - OUT_BYTE_ARRAY(wrapped_key, wrapped_key_len); - END_CALL; -} - -static CK_RV rpc_C_UnwrapKey(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_OBJECT_HANDLE unwrapping_key; - CK_BYTE_PTR wrapped_key; - CK_ULONG wrapped_key_len; - CK_ATTRIBUTE_PTR template; - CK_ULONG attribute_count; - CK_OBJECT_HANDLE key; - - BEGIN_CALL(C_UnwrapKey); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(unwrapping_key); - IN_BYTE_ARRAY(wrapped_key, wrapped_key_len); - IN_ATTRIBUTE_ARRAY(template, attribute_count); - PROCESS_CALL((session, &mechanism, unwrapping_key, wrapped_key, - wrapped_key_len, template, attribute_count, &key)); - OUT_ULONG(key); - END_CALL; -} - -static CK_RV rpc_C_DeriveKey(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_OBJECT_HANDLE base_key; - CK_ATTRIBUTE_PTR template; - CK_ULONG attribute_count; - CK_OBJECT_HANDLE key; - - BEGIN_CALL(C_DeriveKey); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(base_key); - IN_ATTRIBUTE_ARRAY(template, attribute_count); - PROCESS_CALL((session, &mechanism, base_key, template, attribute_count, - &key)); - OUT_ULONG(key); - END_CALL; -} - -static CK_RV rpc_C_SeedRandom(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR seed; - CK_ULONG seed_len; - - BEGIN_CALL(C_SeedRandom); - IN_ULONG(session); - IN_BYTE_ARRAY(seed, seed_len); - PROCESS_CALL((session, seed, seed_len)); - END_CALL; -} - -static CK_RV rpc_C_GenerateRandom(CallState * cs) -{ - CK_SESSION_HANDLE session; - CK_BYTE_PTR random_data; - DECLARE_CK_ULONG_PTR(random_len); - - BEGIN_CALL(C_GenerateRandom); - IN_ULONG(session); - IN_BYTE_BUFFER(random_data, random_len); - if (random_len == NULL_PTR) { - _ret = PARSE_ERROR; goto _cleanup; - } - PROCESS_CALL((session, random_data, *random_len)); - OUT_BYTE_ARRAY(random_data, random_len); - END_CALL; -} - -/* --------------------------------------------------------------------------- - * DISPATCH THREAD HANDLING - */ - -static int dispatch_call(CallState * cs) -{ - GckRpcMessage *req, *resp; - CK_RV ret = CKR_OK; - - assert(cs); - - req = cs->req; - resp = cs->resp; - - /* This should have been checked by the parsing code */ - assert(req->call_id > GCK_RPC_CALL_ERROR); - assert(req->call_id < GCK_RPC_CALL_MAX); - - /* Prepare a response for the function to fill in */ - if (!gck_rpc_message_prep(resp, req->call_id, GCK_RPC_RESPONSE)) { - gck_rpc_warn("couldn't prepare message"); - return 0; - } - - switch (req->call_id) { - -#define CASE_CALL(name) \ - case GCK_RPC_CALL_##name: \ - ret = rpc_##name (cs); \ - break; - CASE_CALL(C_Initialize) - CASE_CALL(C_Finalize) - CASE_CALL(C_GetInfo) - CASE_CALL(C_GetSlotList) - CASE_CALL(C_GetSlotInfo) - CASE_CALL(C_GetTokenInfo) - CASE_CALL(C_GetMechanismList) - CASE_CALL(C_GetMechanismInfo) - CASE_CALL(C_InitToken) - CASE_CALL(C_WaitForSlotEvent) - CASE_CALL(C_OpenSession) - CASE_CALL(C_CloseSession) - CASE_CALL(C_CloseAllSessions) - CASE_CALL(C_GetFunctionStatus) - CASE_CALL(C_CancelFunction) - CASE_CALL(C_GetSessionInfo) - CASE_CALL(C_InitPIN) - CASE_CALL(C_SetPIN) - CASE_CALL(C_GetOperationState) - CASE_CALL(C_SetOperationState) - CASE_CALL(C_Login) - CASE_CALL(C_Logout) - CASE_CALL(C_CreateObject) - CASE_CALL(C_CopyObject) - CASE_CALL(C_DestroyObject) - CASE_CALL(C_GetObjectSize) - CASE_CALL(C_GetAttributeValue) - CASE_CALL(C_SetAttributeValue) - CASE_CALL(C_FindObjectsInit) - CASE_CALL(C_FindObjects) - CASE_CALL(C_FindObjectsFinal) - CASE_CALL(C_EncryptInit) - CASE_CALL(C_Encrypt) - CASE_CALL(C_EncryptUpdate) - CASE_CALL(C_EncryptFinal) - CASE_CALL(C_DecryptInit) - CASE_CALL(C_Decrypt) - CASE_CALL(C_DecryptUpdate) - CASE_CALL(C_DecryptFinal) - CASE_CALL(C_DigestInit) - CASE_CALL(C_Digest) - CASE_CALL(C_DigestUpdate) - CASE_CALL(C_DigestKey) - CASE_CALL(C_DigestFinal) - CASE_CALL(C_SignInit) - CASE_CALL(C_Sign) - CASE_CALL(C_SignUpdate) - CASE_CALL(C_SignFinal) - CASE_CALL(C_SignRecoverInit) - CASE_CALL(C_SignRecover) - CASE_CALL(C_VerifyInit) - CASE_CALL(C_Verify) - CASE_CALL(C_VerifyUpdate) - CASE_CALL(C_VerifyFinal) - CASE_CALL(C_VerifyRecoverInit) - CASE_CALL(C_VerifyRecover) - CASE_CALL(C_DigestEncryptUpdate) - CASE_CALL(C_DecryptDigestUpdate) - CASE_CALL(C_SignEncryptUpdate) - CASE_CALL(C_DecryptVerifyUpdate) - CASE_CALL(C_GenerateKey) - CASE_CALL(C_GenerateKeyPair) - CASE_CALL(C_WrapKey) - CASE_CALL(C_UnwrapKey) - CASE_CALL(C_DeriveKey) - CASE_CALL(C_SeedRandom) - CASE_CALL(C_GenerateRandom) -#undef CASE_CALL - default: - /* This should have been caught by the parse code */ - assert(0 && "Unchecked call"); - break; - }; - - if (ret == CKR_OK) { - - /* Parsing errors? */ - if (gck_rpc_message_buffer_error(req)) { - gck_rpc_warn - ("invalid request from module, probably too short"); - ret = PARSE_ERROR; - } - - /* Out of memory errors? */ - if (gck_rpc_message_buffer_error(resp)) { - gck_rpc_warn - ("out of memory error putting together message"); - ret = PREP_ERROR; - } - } - - /* A filled in response */ - if (ret == CKR_OK) { - - /* - * Since we're dealing with many many functions above generating - * these messages we want to make sure each of them actually - * does what it's supposed to. - */ - - assert(gck_rpc_message_is_verified(resp)); - assert(resp->call_type == GCK_RPC_RESPONSE); - assert(resp->call_id == req->call_id); - assert(gck_rpc_calls[resp->call_id].response); - assert(strcmp(gck_rpc_calls[resp->call_id].response, - resp->signature) == 0); - - /* Fill in an error respnose */ - } else { - if (!gck_rpc_message_prep - (resp, GCK_RPC_CALL_ERROR, GCK_RPC_RESPONSE) - || !gck_rpc_message_write_ulong(resp, (uint32_t) ret) - || gck_rpc_message_buffer_error(resp)) { - gck_rpc_warn("out of memory responding with error"); - return 0; - } - } - - return 1; -} - -static int read_all(CallState *cs, void *data, size_t len) -{ - int r; - - assert(cs->sock >= 0); - assert(data); - assert(len > 0); - - while (len > 0) { - - if (cs->tls) - r = gck_rpc_tls_read_all(cs->tls, data, len); - else - r = recv(cs->sock, data, len, 0); - - if (r == 0) { - /* Connection was closed on client */ - return 0; - } else if (r == -1) { - if (errno != EAGAIN && errno != EINTR) { - gck_rpc_warn("couldn't receive data: %s", - strerror(errno)); - return 0; - } - } else { - data += r; - len -= r; - } - } - return 1; -} - -static int write_all(CallState *cs, void *data, size_t len) -{ - int r; - - assert(cs->sock >= 0); - assert(data); - assert(len > 0); - - while (len > 0) { - - if (cs->tls) - r = gck_rpc_tls_write_all(cs->tls, (void *) data, len); - else - r = send(cs->sock, data, len, MSG_NOSIGNAL); - - if (r == -1) { - if (errno == EPIPE) { - /* Connection closed from client */ - return 0; - } else if (errno != EAGAIN && errno != EINTR) { - gck_rpc_warn("couldn't send data: %s", - strerror(errno)); - return 0; - } - } else { - data += r; - len -= r; - } - } - - return 1; -} - -static void run_dispatch_loop(CallState *cs) -{ - unsigned char buf[4]; - uint32_t len, res; - char hoststr[NI_MAXHOST], portstr[NI_MAXSERV]; - - assert(cs->sock != -1); - - if ((res = getnameinfo((struct sockaddr *) & cs->addr, cs->addrlen, - hoststr, sizeof(hoststr), portstr, sizeof(portstr), - NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { - gck_rpc_warn("couldn't call getnameinfo on client addr: %.100s", - gai_strerror(res)); - hoststr[0] = portstr[0] = '\0'; - } - - /* Enable TLS for this socket */ - if (cs->tls) { - if (! gck_rpc_start_tls(cs->tls, cs->sock)) { - gck_rpc_warn("Can't enable TLS"); - return ; - } - } - - /* The client application */ - if (! cs->read(cs, (void *)&cs->appid, sizeof (cs->appid))) { - gck_rpc_warn("Can't read appid\n"); - return ; - } - - gck_rpc_log("New session %d-%d (client %s, port %s)\n", (uint32_t) (cs->appid >> 32), - (uint32_t) cs->appid, hoststr, portstr); - - /* Setup our buffers */ - if (!call_init(cs)) { - gck_rpc_warn("out of memory"); - return; - } - - /* The main thread loop */ - while (TRUE) { - - call_reset(cs); - - /* Read the number of bytes ... */ - if (! cs->read(cs, buf, 4)) - break; - - /* Calculate the number of bytes */ - len = egg_buffer_decode_uint32(buf); - if (len >= 0x0FFFFFFF) { - gck_rpc_warn - ("invalid message size from module: %u bytes", len); - break; - } - - /* Allocate memory */ - egg_buffer_reserve(&cs->req->buffer, cs->req->buffer.len + len); - if (egg_buffer_has_error(&cs->req->buffer)) { - gck_rpc_warn("error allocating buffer for message"); - break; - } - - /* ... and read/parse in the actual message */ - if (!cs->read(cs, cs->req->buffer.buf, len)) - break; - - egg_buffer_add_empty(&cs->req->buffer, len); - - if (!gck_rpc_message_parse(cs->req, GCK_RPC_REQUEST)) - break; - - /* ... send for processing ... */ - if (!dispatch_call(cs)) - break; - - /* .. send back response length, and then response data */ - egg_buffer_encode_uint32(buf, cs->resp->buffer.len); - if (!cs->write(cs, buf, 4) || - !cs->write(cs, cs->resp->buffer.buf, cs->resp->buffer.len)) - break; - } - - call_uninit(cs); -} - -static void *run_dispatch_thread(void *arg) -{ - CallState *cs = arg; - assert(cs->sock != -1); - - if (_install_dispatch_syscall_filter((cs->tls != NULL))) - return NULL; - - run_dispatch_loop(cs); - - /* The thread closes the socket and marks as done */ - assert(cs->sock != -1); - close(cs->sock); - cs->sock = -1; - - return NULL; -} - -/* --------------------------------------------------------------------------- - * MAIN THREAD - */ - -/* The main daemon socket that we're listening on */ -static int pkcs11_socket = -1; - -/* The unix socket path, that we listen on */ -static char pkcs11_socket_path[MAXPATHLEN] = { 0, }; - -void gck_rpc_layer_accept(GckRpcTlsPskState *tls) -{ - struct sockaddr_storage addr; - DispatchState *ds, **here; - int error; - socklen_t addrlen; - int new_fd; - - assert(pkcs11_socket != -1); - - /* Cleanup any completed dispatch threads */ - pthread_mutex_lock(&pkcs11_dispatchers_mutex); - for (here = &pkcs11_dispatchers, ds = *here; ds != NULL; ds = *here) { - CallState *c = &ds->cs; - if (c && c->sock == -1) { - pthread_join(ds->thread, NULL); - *here = ds->next; - free(ds); - } else { - here = &ds->next; - } - } - - addrlen = sizeof(addr); - new_fd = accept(pkcs11_socket, (struct sockaddr *)&addr, &addrlen); - if (new_fd < 0) { - gck_rpc_warn("cannot accept pkcs11 connection: %s", - strerror(errno)); - return; - } - - ds = calloc(1, sizeof(DispatchState)); - if (ds == NULL) { - gck_rpc_warn("out of memory"); - close(new_fd); - return; - } - - ds->cs.sock = new_fd; - ds->cs.read = &read_all; - ds->cs.write = &write_all; - ds->cs.addr = addr; - ds->cs.addrlen = addrlen; - ds->cs.tls = tls; - - error = pthread_create(&ds->thread, NULL, - run_dispatch_thread, &(ds->cs)); - if (error) { - gck_rpc_warn("couldn't start thread: %s", strerror(errno)); - close(new_fd); - free(ds); - return; - } - - ds->next = pkcs11_dispatchers; - pkcs11_dispatchers = ds; - pthread_mutex_unlock(&pkcs11_dispatchers_mutex); -} - -static int _inetd_read(CallState *cs, void *data, size_t len) -{ - assert(cs->sock >= 0); - return read(cs->sock, data, len); -} - -static int _inetd_write(CallState *cs, void *data, size_t len) -{ - assert(cs->sock >= 0); - return write(cs->sock, data, len); -} - -void gck_rpc_layer_inetd(CK_FUNCTION_LIST_PTR module) -{ - CallState cs; - - memset(&cs, 0, sizeof(cs)); - cs.sock = STDIN_FILENO; - cs.read = &_inetd_read; - cs.write = &_inetd_write; - - pkcs11_module = module; - - run_dispatch_thread(&cs); -} - -/* - * Try to get a listening socket for host and port (host may be either a name or - * an IP address, as string) and port (a string with a service name or a port - * number). - * - * Returns -1 on failure, and the socket fd otherwise. - */ -static int _get_listening_socket(const char *proto, const char *host, const char *port) -{ - char hoststr[NI_MAXHOST], portstr[NI_MAXSERV]; - struct addrinfo *ai, *first, hints; - int res, sock, one = 1; - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_flags = AI_PASSIVE; /* Want addr for bind() */ - hints.ai_family = AF_UNSPEC; /* Either IPv4 or IPv6 */ - hints.ai_socktype = SOCK_STREAM; /* Only stream oriented sockets */ - - if ((res = getaddrinfo(host, port, &hints, &ai)) < 0) { - gck_rpc_warn("couldn't resolve host '%.100s' or service '%.100s' : %.100s\n", - host, port, gai_strerror(res)); - return -1; - } - - sock = -1; - first = ai; - - /* Loop through the sockets returned and see if we can find one that accepts - * our options and bind() - */ - while (ai) { - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - - if (sock >= 0) { - if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, - (char *)&one, sizeof (one)) == -1) { - gck_rpc_warn("couldn't set pkcs11 " - "socket protocol options (%.100s %.100s): %.100s", - host, port, strerror (errno)); - goto next; - } - - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (char *)&one, sizeof(one)) == -1) { - gck_rpc_warn - ("couldn't set pkcs11 socket options (%.100s %.100s): %.100s", - host, port, strerror(errno)); - goto next; - } - - if (bind(sock, ai->ai_addr, ai->ai_addrlen) == 0) - break; - - next: - close(sock); - sock = -1; - } - ai = ai->ai_next; - } - - if (sock < 0) { - gck_rpc_warn("couldn't create pkcs11 socket (%.100s %.100s): %.100s\n", - host, port, strerror(errno)); - sock = -1; - goto out; - } - - if (listen(sock, PKCS11PROXY_LISTEN_BACKLOG) < 0) { - gck_rpc_warn("couldn't listen on pkcs11 socket (%.100s %.100s): %.100s", - host, port, strerror(errno)); - sock = -1; - goto out; - } - - /* Format a string describing the socket we're listening on into pkcs11_socket_path */ - if ((res = getnameinfo(ai->ai_addr, ai->ai_addrlen, - hoststr, sizeof(hoststr), portstr, sizeof(portstr), - NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { - gck_rpc_warn("couldn't call getnameinfo on pkcs11 socket (%.100s %.100s): %.100s", - host, port, gai_strerror(res)); - sock = -1; - goto out; - } - - snprintf(pkcs11_socket_path, sizeof(pkcs11_socket_path), - (ai->ai_family == AF_INET6) ? "%s://[%s]:%s" : "%s://%s:%s", proto, hoststr, portstr); - - out: - freeaddrinfo(first); - - return sock; -} - -int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module) -{ - struct sockaddr_un addr; - int sock; - -#ifdef _DEBUG - GCK_RPC_CHECK_CALLS(); -#endif - - assert(module); - assert(prefix); - - /* cannot be called more than once */ - assert(!pkcs11_module); - assert(pkcs11_socket == -1); - assert(pkcs11_dispatchers == NULL); - - memset(&addr, 0, sizeof(addr)); - -#ifdef __MINGW32__ - { - WSADATA wsaData; - int iResult; - - iResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if (iResult != 0) { - gck_rpc_warn("WSAStartup failed: %d\n", iResult); - return -1; - } - } -#endif - - if (!strncmp("tcp://", prefix, 6) || - !strncmp("tls://", prefix, 6)) { - /* - * TCP socket - */ - char *host, *port; - char proto[4]; /* strlen("tcp") and strlen("tls") */ - - snprintf(proto, sizeof(proto), "%s", prefix); - - if (! gck_rpc_parse_host_port(prefix + 6, &host, &port)) { - free(host); - return -1; - } - - if ((sock = _get_listening_socket(proto, host, port)) == -1) { - free(host); - return -1; - } - - free(host); - } else { - /* - * UNIX domain socket - */ - snprintf(pkcs11_socket_path, sizeof(pkcs11_socket_path), - "%s/socket.pkcs11", prefix); - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - - if (sock < 0) { - gck_rpc_warn("couldn't create pkcs11 socket: %s", - strerror(errno)); - return -1; - } - - addr.sun_family = AF_UNIX; - unlink(pkcs11_socket_path); - strncpy(addr.sun_path, pkcs11_socket_path, - sizeof(addr.sun_path)); - - if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - gck_rpc_warn("couldn't bind to pkcs11 socket: %s: %s", - pkcs11_socket_path, strerror(errno)); - return -1; - } - - if (listen(sock, PKCS11PROXY_LISTEN_BACKLOG) < 0) { - gck_rpc_warn("couldn't listen on pkcs11 socket: %s: %s", - pkcs11_socket_path, strerror(errno)); - return -1; - } - } - - gck_rpc_log("Listening on: %s\n", pkcs11_socket_path); - - pkcs11_module = module; - pkcs11_socket = sock; - pkcs11_dispatchers = NULL; - - return sock; -} - -void gck_rpc_layer_uninitialize(void) -{ - DispatchState *ds, *next; - - if (!pkcs11_module) - return; - - /* Close our main listening socket */ - if (pkcs11_socket != -1) - close(pkcs11_socket); - pkcs11_socket = -1; - - /* Delete our unix socket */ - if (pkcs11_socket_path[0] && - strncmp(pkcs11_socket_path, "tcp://", strlen("tcp://")) != 0 && - strncmp(pkcs11_socket_path, "tls://", strlen("tls://")) != 0) - unlink(pkcs11_socket_path); - pkcs11_socket_path[0] = 0; - - /* Stop all of the dispatch threads */ - pthread_mutex_lock(&pkcs11_dispatchers_mutex); - for (ds = pkcs11_dispatchers; ds; ds = next) { - CallState *c = &ds->cs; - next = ds->next; - - /* Forcibly shutdown the connection */ - if (c && c->sock != -1) - if (shutdown(c->sock, SHUT_RDWR) == 0) - c->sock = -1; - - pthread_join(ds->thread, NULL); - - /* This is always closed by dispatch thread */ - if (c) - assert(c->sock == -1); - free(ds); - } - pthread_mutex_unlock(&pkcs11_dispatchers_mutex); - - pkcs11_module = NULL; -} - -/* - * Reduce the syscalls allowed to a subset of the syscalls allowed for - * the parent thread. - */ -static int _install_dispatch_syscall_filter(int use_tls) -{ -#ifdef SECCOMP - int rc = -1; - scmp_filter_ctx ctx; - -#ifdef DEBUG_SECCOMP - ctx = seccomp_init(SCMP_ACT_TRAP); -#else - ctx = seccomp_init(SCMP_ACT_KILL); -#endif /* DEBUG_SECCOMP */ - if (ctx == NULL) - goto failure_scmp; - /* - * These are the basic syscalls needed to be able to use - * the syscall-reporter to figure out the rest - */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(write), 0); -#ifdef DEBUG_SECCOMP - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); -# ifdef __NR_sigreturn - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(sigreturn), 0); -# endif -#endif /* DEBUG_SECCOMP */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(exit), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); - - /* - * Network related syscalls. - */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(read), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(sendto), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(recvfrom), 0); - - /* - * TLS-PSK - */ - if (use_tls) - /* Allow open() of the TLS-PSK keyfile. */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(open), 1, - SCMP_A1(SCMP_CMP_EQ, O_RDONLY | O_CLOEXEC)); - - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(close), 0); - - /* - * pthreads? - */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(madvise), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 1, - SCMP_A2(SCMP_CMP_EQ, PROT_READ|PROT_WRITE)); - - /* - * SoftHSM 1.3.0 - */ - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(getcwd), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(stat), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(open), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(fcntl), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(fstat), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(lseek), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(access), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(fsync), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(unlink), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(ftruncate), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(select), 0); - seccomp_rule_add(ctx,SCMP_ACT_ALLOW, SCMP_SYS(futex), 0); - - rc = seccomp_load(ctx); - if (rc < 0) - goto failure_scmp; - seccomp_release(ctx); - - return 0; - -failure_scmp: - errno = -rc; - gck_rpc_warn("Seccomp filter initialization failed, errno = %u\n", errno); - return errno; -#else /* SECCOMP */ - return 0; -#endif /* SECCOMP */ -} diff --git a/ext/pkcs11-proxy/gck-rpc-layer.h b/ext/pkcs11-proxy/gck-rpc-layer.h deleted file mode 100644 index 8ea653b55..000000000 --- a/ext/pkcs11-proxy/gck-rpc-layer.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef GCKRPC_LAYER_H_ -#define GCKRPC_LAYER_H_ - -#include "pkcs11/pkcs11.h" - -#include "gck-rpc-tls-psk.h" - -/* ------------------------------------------------------------------ - * DISPATCHER - */ - -/* Call to initialize the module and start listening, returns socket or -1 */ -int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR funcs); - -/* Should be called to cleanup dispatcher */ -void gck_rpc_layer_uninitialize(void); - -/* Accept a new connection. Should be called when above fd has read */ -void gck_rpc_layer_accept(GckRpcTlsPskState *tls); - -/* Run a single connection off of STDIN - call from inetd or stunnel */ -void gck_rpc_layer_inetd(CK_FUNCTION_LIST_PTR funcs); - -#endif /* GCKRPC_LAYER_H_ */ diff --git a/ext/pkcs11-proxy/gck-rpc-message.c b/ext/pkcs11-proxy/gck-rpc-message.c deleted file mode 100644 index 9bb10f186..000000000 --- a/ext/pkcs11-proxy/gck-rpc-message.c +++ /dev/null @@ -1,482 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* p11-rpc-message.c - our marshalled PKCS#11 protocol. - - Copyright (C) 2008, Stef Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter -*/ - -#include "config.h" - -#include "gck-rpc-layer.h" -#include "gck-rpc-private.h" - -#include - -#ifdef G_DISABLE_ASSERT -#define assert(x) -#else -#include -#endif - -GckRpcMessage *gck_rpc_message_new(EggBufferAllocator allocator) -{ - GckRpcMessage *msg; - - assert(allocator); - - msg = (GckRpcMessage *) (allocator) (NULL, sizeof(GckRpcMessage)); - if (!msg) - return NULL; - memset(msg, 0, sizeof(*msg)); - - if (!egg_buffer_init_full(&msg->buffer, 64, allocator)) { - (allocator) (msg, 0); /* Frees allocation */ - return NULL; - } - - gck_rpc_message_reset(msg); - - return msg; -} - -void gck_rpc_message_free(GckRpcMessage * msg) -{ - EggBufferAllocator allocator; - - if (msg) { - assert(msg->buffer.allocator); - allocator = msg->buffer.allocator; - egg_buffer_uninit(&msg->buffer); - - /* frees data buffer */ - (allocator) (msg, 0); - } -} - -void gck_rpc_message_reset(GckRpcMessage * msg) -{ - assert(msg); - - msg->call_id = 0; - msg->call_type = 0; - msg->signature = NULL; - msg->sigverify = NULL; - msg->parsed = 0; - - egg_buffer_reset(&msg->buffer); -} - -int -gck_rpc_message_prep(GckRpcMessage * msg, int call_id, GckRpcMessageType type) -{ - int len; - - assert(type); - assert(call_id >= GCK_RPC_CALL_ERROR); - assert(call_id < GCK_RPC_CALL_MAX); - - gck_rpc_message_reset(msg); - - if (call_id != GCK_RPC_CALL_ERROR) { - - /* The call id and signature */ - if (type == GCK_RPC_REQUEST) - msg->signature = gck_rpc_calls[call_id].request; - else if (type == GCK_RPC_RESPONSE) - msg->signature = gck_rpc_calls[call_id].response; - else - assert(0 && "invalid message type"); - assert(msg->signature); - msg->sigverify = msg->signature; - } - - msg->call_id = call_id; - msg->call_type = type; - - /* Encode the two of them */ - egg_buffer_add_uint32(&msg->buffer, call_id); - if (msg->signature) { - len = strlen(msg->signature); - egg_buffer_add_byte_array(&msg->buffer, - (unsigned char *)msg->signature, len); - } - - msg->parsed = 0; - return !egg_buffer_has_error(&msg->buffer); -} - -int gck_rpc_message_parse(GckRpcMessage * msg, GckRpcMessageType type) -{ - const unsigned char *val; - size_t len; - uint32_t call_id; - - msg->parsed = 0; - - /* Pull out the call identifier */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &(msg->parsed), &call_id)) { - gck_rpc_warn("invalid message: couldn't read call identifier"); - return 0; - } - - msg->signature = msg->sigverify = NULL; - - /* If it's an error code then no more processing */ - if (call_id == GCK_RPC_CALL_ERROR) { - if (type == GCK_RPC_REQUEST) { - gck_rpc_warn("invalid message: error code in request"); - return 0; - } - - return 1; - } - - /* The call id and signature */ - if (call_id <= 0 || call_id >= GCK_RPC_CALL_MAX) { - gck_rpc_warn("invalid message: bad call id: %d", call_id); - return 0; - } - if (type == GCK_RPC_REQUEST) - msg->signature = gck_rpc_calls[call_id].request; - else if (type == GCK_RPC_RESPONSE) - msg->signature = gck_rpc_calls[call_id].response; - else - assert(0 && "invalid message type"); - msg->call_id = call_id; - msg->call_type = type; - msg->sigverify = msg->signature; - - /* Verify the incoming signature */ - if (!egg_buffer_get_byte_array - (&msg->buffer, msg->parsed, &(msg->parsed), &val, &len)) { - gck_rpc_warn("invalid message: couldn't read signature"); - return 0; - } - - if ((strlen(msg->signature) != len) - || (memcmp(val, msg->signature, len) != 0)) { - gck_rpc_warn("invalid message: signature doesn't match"); - return 0; - } - - return 1; -} - -int gck_rpc_message_equals(GckRpcMessage * m1, GckRpcMessage * m2) -{ - assert(m1 && m2); - - /* Any errors and messages are never equal */ - if (egg_buffer_has_error(&m1->buffer) || - egg_buffer_has_error(&m2->buffer)) - return 0; - - /* Calls and signatures must be identical */ - if (m1->call_id != m2->call_id) - return 0; - if (m1->call_type != m2->call_type) - return 0; - if (m1->signature && m2->signature) { - if (strcmp(m1->signature, m2->signature) != 0) - return 0; - } else if (m1->signature != m2->signature) { - return 0; - } - - /* Data in buffer must be identical */ - return egg_buffer_equal(&m1->buffer, &m2->buffer); -} - -int gck_rpc_message_verify_part(GckRpcMessage * msg, const char *part) -{ - int len, ok; - - if (!msg->sigverify) - return 1; - - len = strlen(part); - ok = (strncmp(msg->sigverify, part, len) == 0); - if (ok) - msg->sigverify += len; - return ok; -} - -int -gck_rpc_message_write_attribute_buffer(GckRpcMessage * msg, - CK_ATTRIBUTE_PTR arr, CK_ULONG num) -{ - CK_ATTRIBUTE_PTR attr; - CK_ULONG i; - - assert(!num || arr); - assert(msg); - - /* Make sure this is in the rigth order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "fA")); - - /* Write the number of items */ - egg_buffer_add_uint32(&msg->buffer, num); - - for (i = 0; i < num; ++i) { - attr = &(arr[i]); - - /* The attribute type */ - egg_buffer_add_uint32(&msg->buffer, attr->type); - - /* And the attribute buffer length */ - egg_buffer_add_uint32(&msg->buffer, - attr->pValue ? attr->ulValueLen : 0); - } - - return !egg_buffer_has_error(&msg->buffer); -} - -int -gck_rpc_message_write_attribute_array(GckRpcMessage * msg, - CK_ATTRIBUTE_PTR arr, CK_ULONG num) -{ - CK_ULONG i; - CK_ATTRIBUTE_PTR attr; - unsigned char validity; - - assert(!num || arr); - assert(msg); - - /* Make sure this is in the rigth order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "aA")); - - /* Write the number of items */ - egg_buffer_add_uint32(&msg->buffer, num); - - for (i = 0; i < num; ++i) { - attr = &(arr[i]); - - /* The attribute type */ - egg_buffer_add_uint32(&msg->buffer, attr->type); - - /* Write out the attribute validity */ - validity = (((CK_LONG) attr->ulValueLen) == -1) ? 0 : 1; - egg_buffer_add_byte(&msg->buffer, validity); - - /* The attribute length and value */ - if (validity) { - egg_buffer_add_uint32(&msg->buffer, attr->ulValueLen); - if (gck_rpc_has_bad_sized_ulong_parameter(attr)) { - uint64_t val = *(CK_ULONG *)attr->pValue; - - egg_buffer_add_byte_array (&msg->buffer, (unsigned char *)&val, sizeof (val)); - } else - egg_buffer_add_byte_array(&msg->buffer, attr->pValue, - attr->ulValueLen); - } - } - - return !egg_buffer_has_error(&msg->buffer); -} - -int gck_rpc_message_read_byte(GckRpcMessage * msg, CK_BYTE * val) -{ - assert(msg); - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "y")); - return egg_buffer_get_byte(&msg->buffer, msg->parsed, &msg->parsed, - val); -} - -int gck_rpc_message_write_byte(GckRpcMessage * msg, CK_BYTE val) -{ - assert(msg); - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "y")); - return egg_buffer_add_byte(&msg->buffer, val); -} - -int gck_rpc_message_read_ulong(GckRpcMessage * msg, CK_ULONG * val) -{ - uint64_t v; - assert(msg); - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "u")); - - if (!egg_buffer_get_uint64(&msg->buffer, msg->parsed, &msg->parsed, &v)) - return 0; - if (val) - *val = (CK_ULONG) v; - return 1; -} - -int gck_rpc_message_write_ulong(GckRpcMessage * msg, CK_ULONG val) -{ - assert(msg); - - /* Make sure this is in the rigth order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "u")); - return egg_buffer_add_uint64(&msg->buffer, val); -} - -int gck_rpc_message_write_byte_buffer(GckRpcMessage * msg, CK_BYTE_PTR arr, CK_ULONG *count_ptr) -{ - uint8_t flags; - assert(msg); - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "fy")); - - flags = 0; - if (! arr) - flags |= GCK_RPC_BYTE_BUFFER_NULL_DATA; - if (! count_ptr) - flags |= GCK_RPC_BYTE_BUFFER_NULL_COUNT; - - egg_buffer_add_byte(&msg->buffer, flags); - - egg_buffer_add_uint32(&msg->buffer, count_ptr ? *count_ptr : 0x0); - - return !egg_buffer_has_error(&msg->buffer); -} - -int -gck_rpc_message_write_byte_array(GckRpcMessage * msg, CK_BYTE_PTR arr, - CK_ULONG num) -{ - assert(msg); - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "ay")); - - /* No array, no data, just length */ - if (!arr) { - egg_buffer_add_byte(&msg->buffer, 0); - egg_buffer_add_uint32(&msg->buffer, num); - } else { - egg_buffer_add_byte(&msg->buffer, 1); - egg_buffer_add_byte_array(&msg->buffer, arr, num); - } - - return !egg_buffer_has_error(&msg->buffer); -} - -int gck_rpc_message_write_ulong_buffer(GckRpcMessage * msg, CK_ULONG count) -{ - assert(msg); - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "fu")); - return egg_buffer_add_uint32(&msg->buffer, count); -} - -int -gck_rpc_message_write_ulong_array(GckRpcMessage * msg, CK_ULONG_PTR array, - CK_ULONG n_array) -{ - CK_ULONG i; - - assert(msg); - - /* Check that we're supposed to have this at this point */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "au")); - - /* We send a byte which determines whether there's actual data present or not */ - egg_buffer_add_byte(&msg->buffer, array ? 1 : 0); - egg_buffer_add_uint32(&msg->buffer, n_array); - - /* Now send the data if valid */ - if (array) { - for (i = 0; i < n_array; ++i) - egg_buffer_add_uint64(&msg->buffer, array[i]); - } - - return !egg_buffer_has_error(&msg->buffer); -} - -int gck_rpc_message_read_version(GckRpcMessage * msg, CK_VERSION * version) -{ - assert(msg); - assert(version); - - /* Check that we're supposed to have this at this point */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "v")); - - return egg_buffer_get_byte(&msg->buffer, msg->parsed, &msg->parsed, - &version->major) - && egg_buffer_get_byte(&msg->buffer, msg->parsed, &msg->parsed, - &version->minor); -} - -int gck_rpc_message_write_version(GckRpcMessage * msg, CK_VERSION * version) -{ - assert(msg); - assert(version); - - /* Check that we're supposed to have this at this point */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "v")); - - egg_buffer_add_byte(&msg->buffer, version->major); - egg_buffer_add_byte(&msg->buffer, version->minor); - - return !egg_buffer_has_error(&msg->buffer); -} - -int -gck_rpc_message_read_space_string(GckRpcMessage * msg, CK_UTF8CHAR * buffer, - CK_ULONG length) -{ - const unsigned char *data; - size_t n_data; - - assert(msg); - assert(buffer); - assert(length); - - assert(!msg->signature || gck_rpc_message_verify_part(msg, "s")); - - if (!egg_buffer_get_byte_array - (&msg->buffer, msg->parsed, &msg->parsed, &data, &n_data)) - return 0; - - if (n_data != length) { - gck_rpc_warn - ("invalid length space padded string received: %d != %d", - length, n_data); - return 0; - } - - memcpy(buffer, data, length); - return 1; -} - -int -gck_rpc_message_write_space_string(GckRpcMessage * msg, CK_UTF8CHAR * buffer, - CK_ULONG length) -{ - assert(msg); - assert(buffer); - assert(length); - - assert(!msg->signature || gck_rpc_message_verify_part(msg, "s")); - - /* XXX it's not really right to treat UTF-8 input as a byte buffer, - * although CK_UTF8CHAR is currently typedef'd to unsigned char in pkcs11.h. - */ - return egg_buffer_add_byte_array(&msg->buffer, buffer, length); -} diff --git a/ext/pkcs11-proxy/gck-rpc-module.c b/ext/pkcs11-proxy/gck-rpc-module.c deleted file mode 100644 index 9ab564527..000000000 --- a/ext/pkcs11-proxy/gck-rpc-module.c +++ /dev/null @@ -1,2490 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gkr-pkcs11-rpc-module.c - a PKCS#11 module which communicates with another process - - Copyright (C) 2008, Stefan Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter -*/ - -#include "config.h" - -#include "gck-rpc-layer.h" -#include "gck-rpc-private.h" -#include "gck-rpc-tls-psk.h" - -#include "pkcs11/pkcs11.h" - -#include -#include -#ifdef __MINGW32__ -# include -#else -# include -# include -#include -#include -#include -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* ------------------------------------------------------------------- - * GLOBALS / DEFINES - */ - -/* Various mutexes */ -static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* Whether we've been initialized, and on what process id it happened */ -static int pkcs11_initialized = 0; -static pid_t pkcs11_initialized_pid = 0; -static uint64_t pkcs11_app_id = 0; - -/* The socket to connect to */ -static char pkcs11_socket_path[MAXPATHLEN] = { 0, }; -/* The TLS-PSK keyfile name */ -static char tls_psk_key_filename[MAXPATHLEN] = { 0, }; - -/* The error used by us when parsing of rpc message fails */ -#define PARSE_ERROR CKR_DEVICE_ERROR - -/* ----------------------------------------------------------------------------- - * LOGGING and DEBUGGING - */ -#if DEBUG_OUTPUT -#define debug(x) gck_rpc_debug x -#else -#define debug(x) -#endif -#define warning(x) gck_rpc_warn x - -#define return_val_if_fail(x, v) \ - if (!(x)) { gck_rpc_warn ("'%s' not true at %s", #x, __func__); return v; } - -void gck_rpc_log(const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - vfprintf(stderr, msg, ap); - fprintf(stderr, "\n"); - va_end(ap); -} - -/* ----------------------------------------------------------------------------- - * MODULE ARGUMENTS - */ - -static void parse_argument(char *arg) -{ - char *value; - - value = arg + strcspn(arg, ":="); - if (!*value) - value = NULL; - else - *(value++) = 0; - - /* Setup the socket path from the arguments */ - if (strcmp(arg, "socket") == 0) - snprintf(pkcs11_socket_path, sizeof(pkcs11_socket_path), "%s", - value); - else if (strcmp(arg, "tls_psk_file") == 0) - snprintf(tls_psk_key_filename, sizeof(tls_psk_key_filename), "%s", - value); - else - warning(("unrecognized argument: %s", arg)); -} - -static void parse_arguments(const char *string) -{ - char quote = '\0'; - char *src, *dup, *at, *arg; - - if (!string) - return; - - src = dup = strdup(string); - if (!dup) { - warning(("couldn't allocate memory for argument string")); - return; - } - - for (arg = at = src; *src; src++) { - - /* Matching quote */ - if (quote == *src) { - quote = '\0'; - - /* Inside of quotes */ - } else if (quote != '\0') { - if (*src == '\\') { - *at++ = *src++; - if (!*src) { - warning(("couldn't parse argument string: %s", string)); - goto done; - } - if (*src != quote) - *at++ = '\\'; - } - *at++ = *src; - - /* Space, not inside of quotes */ - } else if (isspace(*src)) { - *at = 0; - parse_argument(arg); - arg = at; - - /* Other character outside of quotes */ - } else { - switch (*src) { - case '\'': - case '"': - quote = *src; - break; - case '\\': - *at++ = *src++; - if (!*src) { - warning(("couldn't parse argument string: %s", string)); - goto done; - } - /* fall through */ - default: - *at++ = *src; - break; - } - } - } - - if (at != arg) - parse_argument(arg); - -done: - free(dup); -} - -/* ----------------------------------------------------------------------------- - * CALL SESSION - */ - -enum CallStatus { - CALL_INVALID, - CALL_READY, - CALL_PREP, - CALL_TRANSIT, - CALL_PARSE -}; - -typedef struct _CallState { - int socket; /* The connection we're sending on */ - GckRpcMessage *req; /* The current request */ - GckRpcMessage *resp; /* The current response */ - int call_status; - GckRpcTlsPskState *tls; - struct _CallState *next; /* For pooling of completed sockets */ -} CallState; - -/* Maximum number of idle calls */ -#define MAX_CALL_STATE_POOL 8 - -/* All call unused call states are in this list */ -static CallState *call_state_pool = NULL; -static unsigned int n_call_state_pool = 0; - -/* Mutex to protect above call state list */ -static pthread_mutex_t call_state_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* Allocator for call session buffers */ -static void *call_allocator(void *p, size_t sz) -{ - void *res = realloc(p, (size_t) sz); - if (!res && sz) - warning(("memory allocation of %lu bytes failed", sz)); - return res; -} - -static void call_disconnect(CallState * cs) -{ - assert(cs); - - if (cs->socket != -1) { - debug(("disconnected socket")); - close(cs->socket); - cs->socket = -1; - } -} - -/* Write all data to session socket. */ -static CK_RV call_write(CallState * cs, unsigned char *data, size_t len) -{ - int fd, r; - - assert(cs); - assert(data); - assert(len > 0); - - while (len > 0) { - - fd = cs->socket; - if (fd == -1) { - warning(("couldn't send data: socket has been closed")); - return CKR_DEVICE_ERROR; - } - - if (cs->tls) - r = gck_rpc_tls_write_all(cs->tls, (void *) data, len); - else - r = send(fd, (void *) data, len, 0); - - if (r == -1) { - if (errno == EPIPE) { - warning(("couldn't send data: daemon closed connection")); - call_disconnect(cs); - return CKR_DEVICE_ERROR; - } else if (errno != EAGAIN && errno != EINTR) { - warning(("couldn't send data: %s", - strerror(errno))); - return CKR_DEVICE_ERROR; - } - } else { - debug(("wrote %d bytes", r)); - data += r; - len -= r; - } - } - - return CKR_OK; -} - -/* Read a certain amount of data from session socket. */ -static CK_RV call_read(CallState * cs, unsigned char *data, size_t len) -{ - int fd, r; - - assert(cs); - assert(data); - assert(len > 0); - - while (len > 0) { - - fd = cs->socket; - if (fd == -1) { - warning(("couldn't receive data: session socket has been closed")); - return CKR_DEVICE_ERROR; - } - - if (cs->tls) - r = gck_rpc_tls_read_all(cs->tls, (void *) data, len); - else - r = recv(fd, (void *) data, len, 0); - - if (r == 0) { - warning(("couldn't receive data: daemon closed connection")); - call_disconnect(cs); - return CKR_DEVICE_ERROR; - } else if (r == -1) { - if (errno != EAGAIN && errno != EINTR) { - warning(("couldn't receive data: %s", - strerror(errno))); - return CKR_DEVICE_ERROR; - } - } else { - debug(("read %d bytes", r)); - data += r; - len -= r; - } - } - - return CKR_OK; -} - -static int _connect_to_host_port(char *host, char *port) -{ - char hoststr[NI_MAXHOST], portstr[NI_MAXSERV], hostport[NI_MAXHOST + NI_MAXSERV + 1]; - struct addrinfo *ai, *first, hints; - int res, sock, one = 1; - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; /* Either IPv4 or IPv6 */ - hints.ai_socktype = SOCK_STREAM; /* Only stream oriented sockets */ - - if ((res = getaddrinfo(host, port, &hints, &ai)) < 0) { - gck_rpc_warn("couldn't resolve host '%.100s' or service '%.100s' : %.100s\n", - host, port, gai_strerror(res)); - return -1; - } - - sock = -1; - first = ai; - - /* Loop through the sockets returned and see if we can find one that accepts - * our options and connect() - */ - while (ai) { - if ((res = getnameinfo(ai->ai_addr, ai->ai_addrlen, - hoststr, sizeof(hoststr), portstr, sizeof(portstr), - NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { - gck_rpc_warn("couldn't call getnameinfo on pkcs11 socket (%.100s %.100s): %.100s", - host, port, gai_strerror(res)); - sock = -1; - continue; - } - - snprintf(hostport, sizeof(hostport), - (ai->ai_family == AF_INET6) ? "[%s]:%s" : "%s:%s", hoststr, portstr); - - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - - if (sock >= 0) { - if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, - (char *)&one, sizeof (one)) == -1) { - gck_rpc_warn("couldn't set pkcs11 " - "socket protocol options (%.100s): %.100s", - hostport, strerror (errno)); - goto next; - } - -#ifndef __MINGW32__ - /* close on exec */ - if (fcntl(sock, F_SETFD, 1) == -1) { - gck_rpc_warn("couldn't secure socket (%.100s): %.100s", - hostport, strerror(errno)); - goto next; - } -#endif - - if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { - close(sock); - warning(("couldn't connect (%.100s): %s", - hostport, strerror(errno))); - goto next; - } - - break; - next: - close(sock); - sock = -1; - } - ai = ai->ai_next; - } - - if (sock < 0) { - gck_rpc_warn("couldn't create pkcs11 socket (%.100s): %.100s\n", - pkcs11_socket_path, strerror(errno)); - sock = -1; - goto out; - } - - out: - freeaddrinfo(first); - - return sock; -} - -static CK_RV call_connect(CallState * cs) -{ - struct sockaddr_un addr; - int sock; - - assert(cs); - assert(cs->socket == -1); - assert(cs->call_status == CALL_INVALID); - assert(pkcs11_socket_path[0]); - - debug(("connecting to: %s", pkcs11_socket_path)); - - memset(&addr, 0, sizeof(addr)); - - if (! strncmp("tcp://", pkcs11_socket_path, 6) || - ! strncmp("tls://", pkcs11_socket_path, 6)) { - char *host, *port; - - if (! gck_rpc_parse_host_port(pkcs11_socket_path + 6, &host, &port)) { - gck_rpc_warn("failed parsing pkcs11 socket : %s", - pkcs11_socket_path); - return CKR_DEVICE_ERROR; - } - - if ((sock = _connect_to_host_port(host, port)) == -1) { - free(host); - return CKR_DEVICE_ERROR; - } - - free(host); - - if (! strncmp("tls://", pkcs11_socket_path, 6)) { - cs->tls = calloc(1, sizeof(GckRpcTlsPskState)); - if (cs->tls == NULL) { - warning(("can't allocate memory for TLS-PSK")); - return CKR_HOST_MEMORY; - } - - if (! gck_rpc_init_tls_psk(cs->tls, tls_psk_key_filename, NULL, GCK_RPC_TLS_PSK_CLIENT)) { - warning(("TLS-PSK initialization failed")); - return CKR_DEVICE_ERROR; - } - - if (! gck_rpc_start_tls(cs->tls, sock)) { - gck_rpc_warn("failed starting TLS"); - return CKR_DEVICE_ERROR; - } - } - } else { - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, pkcs11_socket_path, - sizeof(addr.sun_path)); - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - warning(("couldn't open socket: %s", strerror(errno))); - return CKR_DEVICE_ERROR; - } - - -#ifndef __MINGW32__ - /* close on exec */ - if (fcntl(sock, F_SETFD, 1) == -1) { - close(sock); - warning(("couldn't secure socket: %s", strerror(errno))); - return CKR_DEVICE_ERROR; - } -#endif - - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - close(sock); - warning(("couldn't connect to: %s: %s", pkcs11_socket_path, - strerror(errno))); - return CKR_DEVICE_ERROR; - } - } - - cs->socket = sock; - cs->call_status = CALL_READY; - debug(("connected socket")); - - return call_write(cs, (unsigned char*)&pkcs11_app_id, - sizeof(pkcs11_app_id)); -} - -static void call_destroy(void *value) -{ - CallState *cs = value; - - if (value) { - call_disconnect(cs); - assert(cs->socket == -1); - - gck_rpc_message_free(cs->req); - gck_rpc_message_free(cs->resp); - - if (cs->tls) - gck_rpc_close_tls(cs->tls); - - free(cs); - - debug(("destroyed state")); - } -} - -static CK_RV call_lookup(CallState ** ret) -{ - CallState *cs = NULL; - CK_RV rv; - - assert(ret); - - pthread_mutex_lock(&call_state_mutex); - - /* Pop one from the pool if possible */ - if (call_state_pool != NULL) { - cs = call_state_pool; - call_state_pool = cs->next; - cs->next = NULL; - assert(n_call_state_pool > 0); - --n_call_state_pool; - } - - pthread_mutex_unlock(&call_state_mutex); - - if (cs == NULL) { - cs = calloc(1, sizeof(CallState)); - if (cs == NULL) - return CKR_HOST_MEMORY; - cs->socket = -1; - cs->call_status = CALL_INVALID; - - /* Try to connect the call */ - rv = call_connect(cs); - if (rv != CKR_OK) { - free(cs); - return rv; - } - } - - assert(cs->call_status == CALL_READY); - assert(cs->socket != -1); - assert(cs->next == NULL); - *ret = cs; - return CKR_OK; -} - -/* Perform the initial setup for a new call. */ -static CK_RV call_prepare(CallState * cs, int call_id) -{ - assert(cs); - assert(cs->call_status == CALL_READY); - - /* Allocate a new request if we've lost the old one */ - if (!cs->req) { - cs->req = gck_rpc_message_new(call_allocator); - if (!cs->req) { - warning(("cannot allocate request buffer: out of memory")); - return CKR_HOST_MEMORY; - } - } - - /* Put in the Call ID and signature */ - gck_rpc_message_reset(cs->req); - if (!gck_rpc_message_prep(cs->req, call_id, GCK_RPC_REQUEST)) - return CKR_HOST_MEMORY; - - debug(("prepared call: %d", call_id)); - - /* Ready to fill in arguments */ - cs->call_status = CALL_PREP; - return CKR_OK; -} - -/* - * Used by call_session_do_call() to actually send the message to the daemon. - * Note how we unlock and relock the session during the call. - */ -static CK_RV call_send_recv(CallState * cs) -{ - GckRpcMessage *req, *resp; - unsigned char buf[4]; - uint32_t len; - CK_RV ret; - - assert(cs); - assert(cs->req); - assert(cs->call_status == CALL_PREP); - - cs->call_status = CALL_TRANSIT; - - /* Setup the response buffer properly */ - if (!cs->resp) { - /* TODO: Do secrets or passwords ever flow through here? */ - cs->resp = gck_rpc_message_new(call_allocator); - if (!cs->resp) { - warning(("couldn't allocate response buffer: out of memory")); - return CKR_HOST_MEMORY; - } - } - gck_rpc_message_reset(cs->resp); - - /* - * Now as an additional check to make sure nothing nasty will - * happen while we are unlocked, we remove the request and - * response from the session during the action. - */ - req = cs->req; - resp = cs->resp; - cs->req = cs->resp = NULL; - - /* Send the number of bytes, and then the data */ - - egg_buffer_encode_uint32(buf, req->buffer.len); - ret = call_write(cs, buf, 4); - if (ret != CKR_OK) - goto cleanup; - ret = call_write(cs, req->buffer.buf, req->buffer.len); - if (ret != CKR_OK) - goto cleanup; - - /* Now read out the number of bytes, and then the data */ - ret = call_read(cs, buf, 4); - if (ret != CKR_OK) - goto cleanup; - - len = egg_buffer_decode_uint32(buf); - if (!egg_buffer_reserve(&resp->buffer, len + resp->buffer.len)) { - warning(("couldn't allocate %u byte response area: out of memory", len)); - ret = CKR_HOST_MEMORY; - goto cleanup; - } - - ret = call_read(cs, resp->buffer.buf, len); - if (ret != CKR_OK) - goto cleanup; - - egg_buffer_add_empty(&resp->buffer, len); - if (!gck_rpc_message_parse(resp, GCK_RPC_RESPONSE)) - goto cleanup; - - debug(("received response from daemon")); - -cleanup: - /* Make sure nobody else used this thread while unlocked */ - assert(cs->call_status == CALL_TRANSIT); - assert(cs->resp == NULL); - cs->resp = resp; - assert(cs->req == NULL); - cs->req = req; - - return ret; -} - -/* - * At this point the request is ready. So we validate it, and we send it to - * the daemon for a response. - */ -static CK_RV call_run(CallState * cs) -{ - CK_RV ret = CKR_OK; - CK_ULONG ckerr; - - assert(cs); - assert(cs->req); - assert(cs->call_status == CALL_PREP); - assert(cs->socket != -1); - - /* Did building the call fail? */ - if (gck_rpc_message_buffer_error(cs->req)) { - warning(("couldn't allocate request area: out of memory")); - return CKR_HOST_MEMORY; - } - - /* Make sure that the signature is valid */ - assert(gck_rpc_message_is_verified(cs->req)); - - /* Do the dialog with daemon */ - ret = call_send_recv(cs); - - cs->call_status = CALL_PARSE; - - if (ret != CKR_OK) - return ret; - - /* If it's an error code then return it */ - if (cs->resp->call_id == GCK_RPC_CALL_ERROR) { - - if (!gck_rpc_message_read_ulong(cs->resp, &ckerr)) { - warning(("invalid error response from gnome-keyring-daemon: too short")); - return CKR_DEVICE_ERROR; - } - - if (ckerr <= CKR_OK) { - warning(("invalid error response from gnome-keyring-daemon: bad error code")); - return CKR_DEVICE_ERROR; - } - - /* An error code from the daemon */ - return (CK_RV) ckerr; - } - - /* Make sure daemon answered the right call */ - if (cs->req->call_id != cs->resp->call_id) { - warning(("invalid response from gnome-keyring-daemon: call mismatch")); - return CKR_DEVICE_ERROR; - } - - assert(!gck_rpc_message_buffer_error(cs->resp)); - debug(("parsing response values")); - - return CKR_OK; -} - -static CK_RV call_done(CallState * cs, CK_RV ret) -{ - assert(cs); - assert(cs->call_status > CALL_INVALID); - - if (cs->call_status == CALL_PARSE && cs->req && cs->resp) { - - /* Check for parsing errors that were not caught elsewhere */ - if (ret == CKR_OK) { - - if (gck_rpc_message_buffer_error(cs->resp)) { - warning(("invalid response from gnome-keyring-daemon: bad argument data")); - ret = CKR_GENERAL_ERROR; - } else { - /* Double check that the signature matched our decoding */ - assert(gck_rpc_message_is_verified(cs->resp)); - } - } - } - - /* Certain error codes cause us to discard the conenction */ - if (ret != CKR_DEVICE_ERROR && ret != CKR_DEVICE_REMOVED - && cs->socket != -1) { - - /* Try and stash it away for later use */ - pthread_mutex_lock(&call_state_mutex); - - if (n_call_state_pool < MAX_CALL_STATE_POOL) { - cs->call_status = CALL_READY; - assert(cs->next == NULL); - cs->next = call_state_pool; - call_state_pool = cs; - ++n_call_state_pool; - cs = NULL; - } - - pthread_mutex_unlock(&call_state_mutex); - } - - if (cs != NULL) - call_destroy(cs); - - return ret; -} - -/* ----------------------------------------------------------------------------- - * MODULE SPECIFIC PROTOCOL CODE - */ - -static CK_RV -proto_read_attribute_array(GckRpcMessage * msg, CK_ATTRIBUTE_PTR arr, - CK_ULONG len) -{ - uint32_t i, num, value, type; - CK_ATTRIBUTE_PTR attr; - const unsigned char *attrval; - size_t attrlen; - unsigned char validity; - CK_RV ret; - - /* Removed assertion. len == 0 is valid for some ret's, - * see proto_write_attribute_array(). - * assert(len); - */ - assert(msg); - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "aA")); - - /* Get the number of items. We need this value to be correct */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &num)) - return PARSE_ERROR; - - if (len != num) { - - /* - * This should never happen in normal operation. It denotes a goof up - * on the other side of our RPC. We should be indicating the exact number - * of attributes to the other side. And it should respond with the same - * number. - */ - - warning(("received an attribute array with wrong number of attributes")); - return PARSE_ERROR; - } - - ret = CKR_OK; - - /* We need to go ahead and read everything in all cases */ - for (i = 0; i < num; ++i) { - - /* The attribute type */ - egg_buffer_get_uint32(&msg->buffer, msg->parsed, - &msg->parsed, &type); - - /* Attribute validity */ - egg_buffer_get_byte(&msg->buffer, msg->parsed, - &msg->parsed, &validity); - - /* And the data itself */ - if (validity) { - if (egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &value) - && egg_buffer_get_byte_array(&msg->buffer, - msg->parsed, - &msg->parsed, &attrval, - &attrlen)) { - if (attrval && value != attrlen) { - warning(("attribute length does not match attribute data")); - return PARSE_ERROR; - } - attrlen = value; - } else { - warning(("failed reading byte array")); - return PARSE_ERROR; - } - } - - /* Don't act on this data unless no errors */ - if (egg_buffer_has_error(&msg->buffer)) - break; - - /* Try and stuff it in the output data */ - if (arr) { - attr = &(arr[i]); - if (attr->type != type) { - warning(("returned attributes in invalid order")); - return PARSE_ERROR; - } - - if (validity) { - /* Just requesting the attribute size */ - if (!attr->pValue) { - attr->ulValueLen = attrlen; - - /* Wants attribute data, but too small */ - } else if (attr->ulValueLen < attrlen) { - attr->ulValueLen = attrlen; - ret = CKR_BUFFER_TOO_SMALL; - - /* Wants attribute data, value is null */ - } else if (attrval == NULL) { - attr->ulValueLen = 0; - - /* Wants attribute data, enough space */ - } else { - CK_ULONG a; - - /* Attribute len is an integer, but - * does not match CK_ULONG size, it's certainly - * a CK_ULONG from a different platform */ - if (attrlen == sizeof(uint64_t) && - sizeof(CK_ULONG) != sizeof(uint64_t) && - gck_rpc_has_ulong_parameter(attr->type)) { - attrlen = sizeof(CK_ULONG); - a = *(uint64_t *) attrval; - attrval = (unsigned char *)&a; - } - attr->ulValueLen = attrlen; - memcpy(attr->pValue, attrval, attrlen); - } - - /* Not a valid attribute */ - } else { - attr->ulValueLen = ((CK_ULONG) - 1); - } - } - } - - if (egg_buffer_has_error(&msg->buffer)) - return PARSE_ERROR; - - /* Read in the code that goes along with these attributes */ - if (!gck_rpc_message_read_ulong(msg, &ret)) - return PARSE_ERROR; - - return ret; -} - -static CK_RV -proto_read_byte_array(GckRpcMessage * msg, CK_BYTE_PTR arr, - CK_ULONG_PTR len, CK_ULONG max) -{ - const unsigned char *val; - unsigned char valid; - size_t vlen; - - assert(len); - assert(msg); - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "ay")); - - /* A single byte which determines whether valid or not */ - if (!egg_buffer_get_byte - (&msg->buffer, msg->parsed, &msg->parsed, &valid)) - return PARSE_ERROR; - - /* If not valid, then just the length is encoded, this can signify CKR_BUFFER_TOO_SMALL */ - if (!valid) { - uint32_t t_len; - - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, - & t_len)) - return PARSE_ERROR; - - *len = t_len; - - if (arr) - return CKR_BUFFER_TOO_SMALL; - else - return CKR_OK; - } - - /* Get the actual bytes */ - if (!egg_buffer_get_byte_array - (&msg->buffer, msg->parsed, &msg->parsed, &val, &vlen)) - return PARSE_ERROR; - - *len = vlen; - - /* Just asking us for size */ - if (!arr) - return CKR_OK; - - if (max < vlen) - return CKR_BUFFER_TOO_SMALL; - - /* Enough space, yay */ - memcpy(arr, val, vlen); - return CKR_OK; -} - -static CK_RV -proto_read_ulong_array(GckRpcMessage * msg, CK_ULONG_PTR arr, - CK_ULONG_PTR len, CK_ULONG max) -{ - uint32_t i, num; - uint64_t val; - unsigned char valid; - - assert(len); - assert(msg); - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "au")); - - /* A single byte which determines whether valid or not */ - if (!egg_buffer_get_byte - (&msg->buffer, msg->parsed, &msg->parsed, &valid)) - return PARSE_ERROR; - - /* Get the number of items. */ - if (!egg_buffer_get_uint32 - (&msg->buffer, msg->parsed, &msg->parsed, &num)) - return PARSE_ERROR; - - *len = num; - - /* If not valid, then just the length is encoded, this can signify CKR_BUFFER_TOO_SMALL */ - if (!valid) { - if (arr) - return CKR_BUFFER_TOO_SMALL; - else - return CKR_OK; - } - - if (max < num) - return CKR_BUFFER_TOO_SMALL; - - /* We need to go ahead and read everything in all cases */ - for (i = 0; i < num; ++i) { - egg_buffer_get_uint64(&msg->buffer, msg->parsed, &msg->parsed, - &val); - if (arr) - arr[i] = (CK_ULONG) val; - } - - return egg_buffer_has_error(&msg->buffer) ? PARSE_ERROR : CKR_OK; -} - -static CK_RV proto_write_mechanism(GckRpcMessage * msg, CK_MECHANISM_PTR mech) -{ - assert(msg); - assert(mech); - - /* Make sure this is in the right order */ - assert(!msg->signature || gck_rpc_message_verify_part(msg, "M")); - - /* The mechanism type */ - egg_buffer_add_uint32(&msg->buffer, mech->mechanism); - - /* - * PKCS#11 mechanism parameters are not easy to serialize. They're - * completely different for so many mechanisms, they contain - * pointers to arbitrary memory, and many callers don't initialize - * them completely or properly. - * - * We only support certain mechanisms. - * - * Also callers do yucky things like leaving parts of the structure - * pointing to garbage if they don't think it's going to be used. - */ - - if (gck_rpc_mechanism_has_no_parameters(mech->mechanism)) - egg_buffer_add_byte_array(&msg->buffer, NULL, 0); - else if (gck_rpc_mechanism_has_sane_parameters(mech->mechanism)) - egg_buffer_add_byte_array(&msg->buffer, mech->pParameter, - mech->ulParameterLen); - else - return CKR_MECHANISM_INVALID; - - return egg_buffer_has_error(&msg->buffer) ? CKR_HOST_MEMORY : CKR_OK; -} - -static CK_RV proto_read_info(GckRpcMessage * msg, CK_INFO_PTR info) -{ - assert(msg); - assert(info); - - if (!gck_rpc_message_read_version(msg, &info->cryptokiVersion) || - !gck_rpc_message_read_space_string(msg, info->manufacturerID, 32) || - !gck_rpc_message_read_ulong(msg, &info->flags) || - !gck_rpc_message_read_space_string(msg, info->libraryDescription, - 32) - || !gck_rpc_message_read_version(msg, &info->libraryVersion)) - return PARSE_ERROR; - - return CKR_OK; -} - -static CK_RV proto_read_slot_info(GckRpcMessage * msg, CK_SLOT_INFO_PTR info) -{ - assert(msg); - assert(info); - - if (!gck_rpc_message_read_space_string(msg, info->slotDescription, 64) - || !gck_rpc_message_read_space_string(msg, info->manufacturerID, 32) - || !gck_rpc_message_read_ulong(msg, &info->flags) - || !gck_rpc_message_read_version(msg, &info->hardwareVersion) - || !gck_rpc_message_read_version(msg, &info->firmwareVersion)) - return PARSE_ERROR; - - return CKR_OK; -} - -static CK_RV proto_read_token_info(GckRpcMessage * msg, CK_TOKEN_INFO_PTR info) -{ - assert(msg); - assert(info); - - if (!gck_rpc_message_read_space_string(msg, info->label, 32) || - !gck_rpc_message_read_space_string(msg, info->manufacturerID, 32) || - !gck_rpc_message_read_space_string(msg, info->model, 16) || - !gck_rpc_message_read_space_string(msg, info->serialNumber, 16) || - !gck_rpc_message_read_ulong(msg, &info->flags) || - !gck_rpc_message_read_ulong(msg, &info->ulMaxSessionCount) || - !gck_rpc_message_read_ulong(msg, &info->ulSessionCount) || - !gck_rpc_message_read_ulong(msg, &info->ulMaxRwSessionCount) || - !gck_rpc_message_read_ulong(msg, &info->ulRwSessionCount) || - !gck_rpc_message_read_ulong(msg, &info->ulMaxPinLen) || - !gck_rpc_message_read_ulong(msg, &info->ulMinPinLen) || - !gck_rpc_message_read_ulong(msg, &info->ulTotalPublicMemory) || - !gck_rpc_message_read_ulong(msg, &info->ulFreePublicMemory) || - !gck_rpc_message_read_ulong(msg, &info->ulTotalPrivateMemory) || - !gck_rpc_message_read_ulong(msg, &info->ulFreePrivateMemory) || - !gck_rpc_message_read_version(msg, &info->hardwareVersion) || - !gck_rpc_message_read_version(msg, &info->firmwareVersion) || - !gck_rpc_message_read_space_string(msg, info->utcTime, 16)) - return PARSE_ERROR; - - return CKR_OK; -} - -static CK_RV -proto_read_mechanism_info(GckRpcMessage * msg, CK_MECHANISM_INFO_PTR info) -{ - assert(msg); - assert(info); - - if (!gck_rpc_message_read_ulong(msg, &info->ulMinKeySize) || - !gck_rpc_message_read_ulong(msg, &info->ulMaxKeySize) || - !gck_rpc_message_read_ulong(msg, &info->flags)) - return PARSE_ERROR; - - return CKR_OK; -} - -static CK_RV -proto_read_sesssion_info(GckRpcMessage * msg, CK_SESSION_INFO_PTR info) -{ - assert(msg); - assert(info); - - if (!gck_rpc_message_read_ulong(msg, &info->slotID) || - !gck_rpc_message_read_ulong(msg, &info->state) || - !gck_rpc_message_read_ulong(msg, &info->flags) || - !gck_rpc_message_read_ulong(msg, &info->ulDeviceError)) - return PARSE_ERROR; - - return CKR_OK; -} - -/* ------------------------------------------------------------------- - * CALL MACROS - */ - -#define BEGIN_CALL(call_id) \ - debug ((#call_id ": enter")); \ - return_val_if_fail (pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); \ - { \ - CallState *_cs; \ - CK_RV _ret = CKR_OK; \ - _ret = call_lookup (&_cs); \ - if (_ret != CKR_OK) return _ret; \ - _ret = call_prepare (_cs, GCK_RPC_CALL_##call_id); \ - if (_ret != CKR_OK) goto _cleanup; - -#define PROCESS_CALL \ - _ret = call_run (_cs); \ - if (_ret != CKR_OK) goto _cleanup; - -#define RETURN(ret) \ - _ret = ret; \ - goto _cleanup; - -#define END_CALL \ - _cleanup: \ - _ret = call_done (_cs, _ret); \ - debug (("ret: 0x%x", _ret)); \ - return _ret; \ - } - -#define IN_BYTE(val) \ - if (!gck_rpc_message_write_byte (_cs->req, val)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_ULONG(val) \ - if (!gck_rpc_message_write_ulong (_cs->req, val)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_SPACE_STRING(val, len) \ - if (!gck_rpc_message_write_space_string (_cs->req, val, len)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_BYTE_BUFFER(arr, len) \ - if (!gck_rpc_message_write_byte_buffer (_cs->req, arr, len)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_BYTE_ARRAY(arr, len) \ - if (len != 0 && arr == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \ - if (!gck_rpc_message_write_byte_array (_cs->req, arr, len)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_ULONG_BUFFER(arr, len) \ - if (len == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \ - IN_ULONG_BUFFER2(arr, len); - -#define IN_ULONG_BUFFER2(arr, len) \ - if (!gck_rpc_message_write_ulong_buffer (_cs->req, arr ? *len : 0)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_ULONG_ARRAY(arr, len) \ - if (len != 0 && arr == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; }\ - if (!gck_rpc_message_write_ulong_array (_cs->req, arr, len)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_ATTRIBUTE_BUFFER(arr, num) \ - if (num != 0 && arr == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \ - if (!gck_rpc_message_write_attribute_buffer (_cs->req, (arr), (num))) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_ATTRIBUTE_ARRAY(arr, num) \ - if (num != 0 && arr == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \ - if (!gck_rpc_message_write_attribute_array (_cs->req, (arr), (num))) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_MECHANISM_TYPE(val) \ - if(!gck_rpc_mechanism_is_supported (val)) \ - { _ret = CKR_MECHANISM_INVALID; goto _cleanup; } \ - if (!gck_rpc_message_write_ulong (_cs->req, val)) \ - { _ret = CKR_HOST_MEMORY; goto _cleanup; } - -#define IN_MECHANISM(val) \ - if (val == NULL) \ - { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \ - _ret = proto_write_mechanism (_cs->req, val); \ - if (_ret != CKR_OK) goto _cleanup; - -#define OUT_ULONG(val) \ - if (val == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK && !gck_rpc_message_read_ulong (_cs->resp, val)) \ - _ret = PARSE_ERROR; - -#define OUT_BYTE_ARRAY(arr, len) \ - if (len == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - OUT_BYTE_ARRAY2(arr, len); - -#define OUT_BYTE_ARRAY2(arr, len) \ - if (_ret == CKR_OK) \ - _ret = proto_read_byte_array (_cs->resp, (arr), (len), *(len)); - -#define OUT_ULONG_ARRAY(a, len) \ - if (len == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_ulong_array (_cs->resp, (a), (len), *(len)); - -#define OUT_ATTRIBUTE_ARRAY(arr, num) \ - if (_ret == CKR_OK) \ - _ret = proto_read_attribute_array (_cs->resp, (arr), (num)); - -#define OUT_INFO(info) \ - if (info == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_info (_cs->resp, info); - -#define OUT_SLOT_INFO(info) \ - if (info == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_slot_info (_cs->resp, info); - -#define OUT_TOKEN_INFO(info) \ - if (info == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_token_info (_cs->resp, info); - -#define OUT_SESSION_INFO(info) \ - if (info == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_sesssion_info (_cs->resp, info); - -#define OUT_MECHANISM_TYPE_ARRAY(arr, len) \ - if (len == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_ulong_array (_cs->resp, (arr), (len), *(len)); \ - if (_ret == CKR_OK && arr) \ - gck_rpc_mechanism_list_purge (arr, len); - -#define OUT_MECHANISM_INFO(info) \ - if (info == NULL) \ - _ret = CKR_ARGUMENTS_BAD; \ - if (_ret == CKR_OK) \ - _ret = proto_read_mechanism_info (_cs->resp, info); - -/* ------------------------------------------------------------------- - * INITIALIZATION and 'GLOBAL' CALLS - */ - -static CK_RV rpc_C_Initialize(CK_VOID_PTR init_args) -{ - CK_C_INITIALIZE_ARGS_PTR args = NULL; - CK_RV ret = CKR_OK; - const char *path; - CallState *cs; - pid_t pid; - - debug(("C_Initialize: enter")); - -#ifdef _DEBUG - GCK_RPC_CHECK_CALLS(); -#endif - - pthread_mutex_lock(&init_mutex); - - if (init_args != NULL) { - int supplied_ok; - - /* pReserved must be NULL */ - args = init_args; - - /* XXX since we're never going to call the supplied mutex functions, shouldn't we reject them? */ - /* ALL supplied function pointers need to have the value either NULL or non-NULL. */ - supplied_ok = (args->CreateMutex == NULL - && args->DestroyMutex == NULL - && args->LockMutex == NULL - && args->UnlockMutex == NULL) - || (args->CreateMutex != NULL && args->DestroyMutex != NULL - && args->LockMutex != NULL - && args->UnlockMutex != NULL); - if (!supplied_ok) { - warning(("invalid set of mutex calls supplied")); - ret = CKR_ARGUMENTS_BAD; - goto done; - } - - /* - * When the CKF_OS_LOCKING_OK flag isn't set return an error. - * We must be able to use our pthread functionality. - */ - if (!(args->flags & CKF_OS_LOCKING_OK)) { - warning(("can't do without os locking")); - ret = CKR_CANT_LOCK; - goto done; - } - - /* - * We support setting the socket path and other arguments from from the - * pReserved pointer, similar to how NSS PKCS#11 components are initialized. - */ - if (args->pReserved) - parse_arguments((const char *)args->pReserved); - } - - pid = getpid(); - if (pkcs11_initialized) { - - /* This process has called C_Initialize already */ - if (pid == pkcs11_initialized_pid) { - warning(("C_Initialize called twice for same process")); - ret = CKR_CRYPTOKI_ALREADY_INITIALIZED; - goto done; - } - } - - /* Lookup the socket path, append '.pkcs11' if it is a domain socket. */ - if (pkcs11_socket_path[0] == 0) { - path = getenv("PKCS11_PROXY_SOCKET"); - if (path && path[0]) { - if ((! strncmp("tcp://", path, 6)) || - (! strncmp("tls://", path, 6))) - snprintf(pkcs11_socket_path, - sizeof(pkcs11_socket_path), "%s", - path); - else - snprintf(pkcs11_socket_path, - sizeof(pkcs11_socket_path), - "%s.pkcs11", path); - pkcs11_socket_path[sizeof(pkcs11_socket_path) - 1] = 0; - } else { - ret = CKR_FUNCTION_NOT_SUPPORTED; - goto done; - } - } - - /* If socket path indicates TLS, make sure tls_psk_key_filename is populated. */ - if (! strncmp("tls://", pkcs11_socket_path, 6)) { - if (! tls_psk_key_filename[0]) { - path = getenv("PKCS11_PROXY_TLS_PSK_FILE"); - if (path && path[0]) { - snprintf(tls_psk_key_filename, sizeof(tls_psk_key_filename), - "%s", path); - } - } - - if (! tls_psk_key_filename[0]) { - warning(("can't handle tls:// path without a tls-psk file")); - ret = CKR_FUNCTION_NOT_SUPPORTED; - goto done; - } - } - - srand(time(NULL) ^ pid); - pkcs11_app_id = (uint64_t) rand() << 32 | rand(); - - /* Call through and initialize the daemon */ - ret = call_lookup(&cs); - if (ret == CKR_OK) { - ret = call_prepare(cs, GCK_RPC_CALL_C_Initialize); - if (ret == CKR_OK) - if (!gck_rpc_message_write_byte_array - (cs->req, (unsigned char *)GCK_RPC_HANDSHAKE, - GCK_RPC_HANDSHAKE_LEN)) - ret = CKR_HOST_MEMORY; - if (ret == CKR_OK) - ret = call_run(cs); - call_done(cs, ret); - } - -done: - /* Mark us as officially initialized */ - if (ret == CKR_OK) { - pkcs11_initialized = 1; - pkcs11_initialized_pid = pid; - } else if (ret != CKR_CRYPTOKI_ALREADY_INITIALIZED) { - pkcs11_initialized = 0; - pkcs11_initialized_pid = 0; - pkcs11_socket_path[0] = 0; - } - - pthread_mutex_unlock(&init_mutex); - - debug(("C_Initialize: %d", ret)); - return ret; -} - -static CK_RV rpc_C_Finalize(CK_VOID_PTR reserved) -{ - CallState *cs; - CK_RV ret; - - debug(("C_Finalize: enter")); - return_val_if_fail(! reserved, CKR_ARGUMENTS_BAD); - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - pthread_mutex_lock(&init_mutex); - - ret = call_lookup(&cs); - if (ret == CKR_OK) { - ret = call_prepare(cs, GCK_RPC_CALL_C_Finalize); - if (ret == CKR_OK) { - ret = call_run(cs); - } - call_done(cs, ret); - } - - if (ret != CKR_OK) - warning(("finalizing the daemon returned an error: %d", ret)); - - /* This should stop all other calls in */ - pkcs11_initialized = 0; - pkcs11_initialized_pid = 0; - pkcs11_socket_path[0] = 0; - - pthread_mutex_unlock(&init_mutex); - - debug(("C_Finalize: %d", CKR_OK)); - return CKR_OK; -} - -static CK_RV rpc_C_GetInfo(CK_INFO_PTR info) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(info, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_GetInfo); - PROCESS_CALL; - OUT_INFO(info); - END_CALL; -} - -static CK_RV rpc_C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR list) -{ - /* This would be a strange call to receive */ - return C_GetFunctionList(list); -} - -static CK_RV -rpc_C_GetSlotList(CK_BBOOL token_present, CK_SLOT_ID_PTR slot_list, - CK_ULONG_PTR count) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(count, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_GetSlotList); - IN_BYTE(token_present); - IN_ULONG_BUFFER(slot_list, count); - PROCESS_CALL; - OUT_ULONG_ARRAY(slot_list, count); - END_CALL; -} - -static CK_RV rpc_C_GetSlotInfo(CK_SLOT_ID id, CK_SLOT_INFO_PTR info) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(info, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_GetSlotInfo); - IN_ULONG(id); - PROCESS_CALL; - OUT_SLOT_INFO(info); - END_CALL; -} - -static CK_RV rpc_C_GetTokenInfo(CK_SLOT_ID id, CK_TOKEN_INFO_PTR info) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(info, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_GetTokenInfo); - IN_ULONG(id); - PROCESS_CALL; - OUT_TOKEN_INFO(info); - END_CALL; -} - -static CK_RV -rpc_C_GetMechanismList(CK_SLOT_ID id, CK_MECHANISM_TYPE_PTR mechanism_list, - CK_ULONG_PTR count) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(count, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_GetMechanismList); - IN_ULONG(id); - IN_ULONG_BUFFER(mechanism_list, count); - PROCESS_CALL; - OUT_MECHANISM_TYPE_ARRAY(mechanism_list, count); - END_CALL; - -} - -static CK_RV -rpc_C_GetMechanismInfo(CK_SLOT_ID id, CK_MECHANISM_TYPE type, - CK_MECHANISM_INFO_PTR info) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(info, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_GetMechanismInfo); - IN_ULONG(id); - IN_MECHANISM_TYPE(type); - PROCESS_CALL; - OUT_MECHANISM_INFO(info); - END_CALL; -} - -static CK_RV -rpc_C_InitToken(CK_SLOT_ID id, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len, - CK_UTF8CHAR_PTR label) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_InitToken); - IN_ULONG(id); - IN_BYTE_ARRAY(pin, pin_len); - IN_SPACE_STRING(label, 32); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR slot, - CK_VOID_PTR reserved) -{ - return_val_if_fail(slot, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_WaitForSlotEvent); - IN_ULONG(flags); - PROCESS_CALL; - OUT_ULONG(slot); - END_CALL; -} - -static CK_RV -rpc_C_OpenSession(CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, - CK_NOTIFY callback, CK_SESSION_HANDLE_PTR session) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - /* It is unnecessarily intrusive to check session here. Leave it to the p11 module. - * return_val_if_fail(session, CKR_ARGUMENTS_BAD); - */ - - BEGIN_CALL(C_OpenSession); - IN_ULONG(id); - IN_ULONG(flags); - PROCESS_CALL; - OUT_ULONG(session); - END_CALL; -} - -static CK_RV rpc_C_CloseSession(CK_SESSION_HANDLE session) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_CloseSession); - IN_ULONG(session); - PROCESS_CALL; - END_CALL; -} - -static CK_RV rpc_C_CloseAllSessions(CK_SLOT_ID id) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_CloseAllSessions); - IN_ULONG(id); - PROCESS_CALL; - END_CALL; -} - -static CK_RV rpc_C_GetFunctionStatus(CK_SESSION_HANDLE session) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_GetFunctionStatus); - IN_ULONG(session); - PROCESS_CALL; - END_CALL; -} - -static CK_RV rpc_C_CancelFunction(CK_SESSION_HANDLE session) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_CancelFunction); - IN_ULONG(session); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_GetSessionInfo(CK_SESSION_HANDLE session, CK_SESSION_INFO_PTR info) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(info, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_GetSessionInfo); - IN_ULONG(session); - PROCESS_CALL; - OUT_SESSION_INFO(info); - END_CALL; -} - -static CK_RV -rpc_C_InitPIN(CK_SESSION_HANDLE session, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_InitPIN); - IN_ULONG(session); - IN_BYTE_ARRAY(pin, pin_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_SetPIN(CK_SESSION_HANDLE session, CK_UTF8CHAR_PTR old_pin, - CK_ULONG old_pin_len, CK_UTF8CHAR_PTR new_pin, - CK_ULONG new_pin_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_SetPIN); - IN_ULONG(session); - IN_BYTE_ARRAY(old_pin, old_pin_len); - IN_BYTE_ARRAY(new_pin, new_pin_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_GetOperationState(CK_SESSION_HANDLE session, CK_BYTE_PTR operation_state, - CK_ULONG_PTR operation_state_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_GetOperationState); - IN_ULONG(session); - IN_BYTE_BUFFER(operation_state, operation_state_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(operation_state, operation_state_len); - END_CALL; -} - -static CK_RV -rpc_C_SetOperationState(CK_SESSION_HANDLE session, CK_BYTE_PTR operation_state, - CK_ULONG operation_state_len, - CK_OBJECT_HANDLE encryption_key, - CK_OBJECT_HANDLE authentication_key) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_SetOperationState); - IN_ULONG(session); - IN_BYTE_ARRAY(operation_state, operation_state_len); - IN_ULONG(encryption_key); - IN_ULONG(authentication_key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Login(CK_SESSION_HANDLE session, CK_USER_TYPE user_type, - CK_UTF8CHAR_PTR pin, CK_ULONG pin_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_Login); - IN_ULONG(session); - IN_ULONG(user_type); - IN_BYTE_ARRAY(pin, pin_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV rpc_C_Logout(CK_SESSION_HANDLE session) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_Logout); - IN_ULONG(session); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_CreateObject(CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR template, - CK_ULONG count, CK_OBJECT_HANDLE_PTR new_object) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(session != CK_INVALID_HANDLE, CKR_SESSION_HANDLE_INVALID); - return_val_if_fail(template, CKR_ARGUMENTS_BAD); - return_val_if_fail(new_object, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_CreateObject); - IN_ULONG(session); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL; - OUT_ULONG(new_object); - END_CALL; -} - -static CK_RV -rpc_C_CopyObject(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, - CK_ATTRIBUTE_PTR template, CK_ULONG count, - CK_OBJECT_HANDLE_PTR new_object) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(new_object, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_CopyObject); - IN_ULONG(session); - IN_ULONG(object); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL; - OUT_ULONG(new_object); - END_CALL; -} - -static CK_RV -rpc_C_DestroyObject(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_DestroyObject); - IN_ULONG(session); - IN_ULONG(object); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_GetObjectSize(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, - CK_ULONG_PTR size) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(size, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_GetObjectSize); - IN_ULONG(session); - IN_ULONG(object); - PROCESS_CALL; - OUT_ULONG(size); - END_CALL; -} - -static CK_RV -rpc_C_GetAttributeValue(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, - CK_ATTRIBUTE_PTR template, CK_ULONG count) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(template, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_GetAttributeValue); - IN_ULONG(session); - IN_ULONG(object); - IN_ATTRIBUTE_BUFFER(template, count); - PROCESS_CALL; - OUT_ATTRIBUTE_ARRAY(template, count); - END_CALL; -} - -static CK_RV -rpc_C_SetAttributeValue(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, - CK_ATTRIBUTE_PTR template, CK_ULONG count) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - BEGIN_CALL(C_SetAttributeValue); - IN_ULONG(session); - IN_ULONG(object); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_FindObjectsInit(CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR template, - CK_ULONG count) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_FindObjectsInit); - IN_ULONG(session); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_FindObjects(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR objects, - CK_ULONG max_count, CK_ULONG_PTR count) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(count, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_FindObjects); - IN_ULONG(session); - IN_ULONG_BUFFER2(objects, &max_count); - PROCESS_CALL; - *count = max_count; - OUT_ULONG_ARRAY(objects, count); - END_CALL; -} - -static CK_RV rpc_C_FindObjectsFinal(CK_SESSION_HANDLE session) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - BEGIN_CALL(C_FindObjectsFinal); - IN_ULONG(session); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_EncryptInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_EncryptInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Encrypt(CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len, - CK_BYTE_PTR encrypted_data, CK_ULONG_PTR encrypted_data_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - /* From PKCS#11 v2.01 : - * A call to C_Encrypt always terminates the active encryption operation - * unless it returns CKR_BUFFER_TOO_SMALL or is a successful call (i.e., - * one which returns CKR_OK) to determine the length of the buffer - * needed to hold the ciphertext. - * - * Thus, we can't reject for example NULL encrypted_data_len, since then - * the encryption operation won't be terminated in the real PKCS#11 module. - */ - - BEGIN_CALL(C_Encrypt); - IN_ULONG(session); - IN_BYTE_ARRAY(data, data_len); - IN_BYTE_BUFFER(encrypted_data, encrypted_data_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(encrypted_data, encrypted_data_len); - END_CALL; -} - -static CK_RV -rpc_C_EncryptUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part, - CK_ULONG part_len, CK_BYTE_PTR encrypted_part, - CK_ULONG_PTR encrypted_part_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_EncryptUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - IN_BYTE_BUFFER(encrypted_part, encrypted_part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(encrypted_part, encrypted_part_len); - END_CALL; -} - -static CK_RV -rpc_C_EncryptFinal(CK_SESSION_HANDLE session, CK_BYTE_PTR last_part, - CK_ULONG_PTR last_part_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_EncryptFinal); - IN_ULONG(session); - IN_BYTE_BUFFER(last_part, last_part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(last_part, last_part_len); - END_CALL; -} - -static CK_RV -rpc_C_DecryptInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_DecryptInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Decrypt(CK_SESSION_HANDLE session, CK_BYTE_PTR enc_data, - CK_ULONG enc_data_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_Decrypt); - IN_ULONG(session); - IN_BYTE_ARRAY(enc_data, enc_data_len); - IN_BYTE_BUFFER(data, data_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(data, data_len); - END_CALL; -} - -static CK_RV -rpc_C_DecryptUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR enc_part, - CK_ULONG enc_part_len, CK_BYTE_PTR part, - CK_ULONG_PTR part_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_DecryptUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(enc_part, enc_part_len); - IN_BYTE_BUFFER(part, part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(part, part_len); - END_CALL; -} - -static CK_RV -rpc_C_DecryptFinal(CK_SESSION_HANDLE session, CK_BYTE_PTR last_part, - CK_ULONG_PTR last_part_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_DecryptFinal); - IN_ULONG(session); - IN_BYTE_BUFFER(last_part, last_part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(last_part, last_part_len); - END_CALL; -} - -static CK_RV -rpc_C_DigestInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - BEGIN_CALL(C_DigestInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Digest(CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len, - CK_BYTE_PTR digest, CK_ULONG_PTR digest_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_Digest); - IN_ULONG(session); - IN_BYTE_ARRAY(data, data_len); - IN_BYTE_BUFFER(digest, digest_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(digest, digest_len); - END_CALL; -} - -static CK_RV -rpc_C_DigestUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part, - CK_ULONG part_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_DigestUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV rpc_C_DigestKey(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_DigestKey); - IN_ULONG(session); - IN_ULONG(key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_DigestFinal(CK_SESSION_HANDLE session, CK_BYTE_PTR digest, - CK_ULONG_PTR digest_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_DigestFinal); - IN_ULONG(session); - IN_BYTE_BUFFER(digest, digest_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(digest, digest_len); - END_CALL; -} - -static CK_RV -rpc_C_SignInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - BEGIN_CALL(C_SignInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Sign(CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len, - CK_BYTE_PTR signature, CK_ULONG_PTR signature_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_Sign); - IN_ULONG(session); - IN_BYTE_ARRAY(data, data_len); - IN_BYTE_BUFFER(signature, signature_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(signature, signature_len); - END_CALL; -} - -static CK_RV -rpc_C_SignUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part, CK_ULONG part_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(part_len, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_SignUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_SignFinal(CK_SESSION_HANDLE session, CK_BYTE_PTR signature, - CK_ULONG_PTR signature_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_SignFinal); - IN_ULONG(session); - IN_BYTE_BUFFER(signature, signature_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(signature, signature_len); - END_CALL; -} - -static CK_RV -rpc_C_SignRecoverInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_SignRecoverInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_SignRecover(CK_SESSION_HANDLE session, CK_BYTE_PTR data, - CK_ULONG data_len, CK_BYTE_PTR signature, - CK_ULONG_PTR signature_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_SignRecover); - IN_ULONG(session); - IN_BYTE_ARRAY(data, data_len); - IN_BYTE_BUFFER(signature, signature_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(signature, signature_len); - END_CALL; -} - -static CK_RV -rpc_C_VerifyInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_VerifyInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_Verify(CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len, - CK_BYTE_PTR signature, CK_ULONG signature_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_Verify); - IN_ULONG(session); - IN_BYTE_ARRAY(data, data_len); - IN_BYTE_ARRAY(signature, signature_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_VerifyUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part, - CK_ULONG part_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_VerifyUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_VerifyFinal(CK_SESSION_HANDLE session, CK_BYTE_PTR signature, - CK_ULONG signature_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_VerifyFinal); - IN_ULONG(session); - IN_BYTE_ARRAY(signature, signature_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_VerifyRecoverInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE key) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_VerifyRecoverInit); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(key); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_VerifyRecover(CK_SESSION_HANDLE session, CK_BYTE_PTR signature, - CK_ULONG signature_len, CK_BYTE_PTR data, - CK_ULONG_PTR data_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_VerifyRecover); - IN_ULONG(session); - IN_BYTE_ARRAY(signature, signature_len); - IN_BYTE_BUFFER(data, data_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(data, data_len); - END_CALL; -} - -static CK_RV -rpc_C_DigestEncryptUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part, - CK_ULONG part_len, CK_BYTE_PTR enc_part, - CK_ULONG_PTR enc_part_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_DigestEncryptUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - IN_BYTE_BUFFER(enc_part, enc_part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(enc_part, enc_part_len); - END_CALL; -} - -static CK_RV -rpc_C_DecryptDigestUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR enc_part, - CK_ULONG enc_part_len, CK_BYTE_PTR part, - CK_ULONG_PTR part_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_DecryptDigestUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(enc_part, enc_part_len); - IN_BYTE_BUFFER(part, part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(part, part_len); - END_CALL; -} - -static CK_RV -rpc_C_SignEncryptUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR part, - CK_ULONG part_len, CK_BYTE_PTR enc_part, - CK_ULONG_PTR enc_part_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_SignEncryptUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(part, part_len); - IN_BYTE_BUFFER(enc_part, enc_part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(enc_part, enc_part_len); - END_CALL; -} - -static CK_RV -rpc_C_DecryptVerifyUpdate(CK_SESSION_HANDLE session, CK_BYTE_PTR enc_part, - CK_ULONG enc_part_len, CK_BYTE_PTR part, - CK_ULONG_PTR part_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_DecryptVerifyUpdate); - IN_ULONG(session); - IN_BYTE_ARRAY(enc_part, enc_part_len); - IN_BYTE_BUFFER(part, part_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(part, part_len); - END_CALL; -} - -static CK_RV -rpc_C_GenerateKey(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, - CK_ATTRIBUTE_PTR template, CK_ULONG count, - CK_OBJECT_HANDLE_PTR key) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_GenerateKey); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL; - OUT_ULONG(key); - END_CALL; -} - -static CK_RV -rpc_C_GenerateKeyPair(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, - CK_ATTRIBUTE_PTR pub_template, CK_ULONG pub_count, - CK_ATTRIBUTE_PTR priv_template, CK_ULONG priv_count, - CK_OBJECT_HANDLE_PTR pub_key, - CK_OBJECT_HANDLE_PTR priv_key) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(session != CK_INVALID_HANDLE, CKR_SESSION_HANDLE_INVALID); - return_val_if_fail(mechanism, CKR_ARGUMENTS_BAD); - return_val_if_fail(pub_template, CKR_ARGUMENTS_BAD); - return_val_if_fail(priv_template, CKR_ARGUMENTS_BAD); - return_val_if_fail(pub_key, CKR_ARGUMENTS_BAD); - return_val_if_fail(priv_key, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_GenerateKeyPair); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ATTRIBUTE_ARRAY(pub_template, pub_count); - IN_ATTRIBUTE_ARRAY(priv_template, priv_count); - PROCESS_CALL; - OUT_ULONG(pub_key); - OUT_ULONG(priv_key); - END_CALL; -} - -static CK_RV -rpc_C_WrapKey(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE wrapping_key, CK_OBJECT_HANDLE key, - CK_BYTE_PTR wrapped_key, CK_ULONG_PTR wrapped_key_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_WrapKey); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(wrapping_key); - IN_ULONG(key); - IN_BYTE_BUFFER(wrapped_key, wrapped_key_len); - PROCESS_CALL; - OUT_BYTE_ARRAY(wrapped_key, wrapped_key_len); - END_CALL; -} - -static CK_RV -rpc_C_UnwrapKey(CK_SESSION_HANDLE session, 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) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_UnwrapKey); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(unwrapping_key); - IN_BYTE_ARRAY(wrapped_key, wrapped_key_len); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL; - OUT_ULONG(key); - END_CALL; -} - -static CK_RV -rpc_C_DeriveKey(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE_PTR template, - CK_ULONG count, CK_OBJECT_HANDLE_PTR key) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_DeriveKey); - IN_ULONG(session); - IN_MECHANISM(mechanism); - IN_ULONG(base_key); - IN_ATTRIBUTE_ARRAY(template, count); - PROCESS_CALL; - OUT_ULONG(key); - END_CALL; -} - -static CK_RV -rpc_C_SeedRandom(CK_SESSION_HANDLE session, CK_BYTE_PTR seed, CK_ULONG seed_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - - BEGIN_CALL(C_SeedRandom); - IN_ULONG(session); - IN_BYTE_ARRAY(seed, seed_len); - PROCESS_CALL; - END_CALL; -} - -static CK_RV -rpc_C_GenerateRandom(CK_SESSION_HANDLE session, CK_BYTE_PTR random_data, - CK_ULONG random_len) -{ - return_val_if_fail(pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED); - return_val_if_fail(random_data, CKR_ARGUMENTS_BAD); - - BEGIN_CALL(C_GenerateRandom); - IN_ULONG(session); - IN_BYTE_BUFFER(random_data, &random_len); - PROCESS_CALL; - OUT_BYTE_ARRAY2(random_data, &random_len); - END_CALL; -} - -/* -------------------------------------------------------------------- - * MODULE ENTRY POINT - */ - -/* - * PKCS#11 is broken here. It states that Unix compilers automatically byte - * pack structures. This is wrong. GCC on Linux aligns to 4 by default. - * - * This results in incompatibilities. Where this structure's first version - * members take up too much or too little space depending on how this module - * is compiled. - */ - -static CK_FUNCTION_LIST functionList = { - {CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR}, /* version */ - rpc_C_Initialize, - rpc_C_Finalize, - rpc_C_GetInfo, - rpc_C_GetFunctionList, - rpc_C_GetSlotList, - rpc_C_GetSlotInfo, - rpc_C_GetTokenInfo, - rpc_C_GetMechanismList, - rpc_C_GetMechanismInfo, - rpc_C_InitToken, - rpc_C_InitPIN, - rpc_C_SetPIN, - rpc_C_OpenSession, - rpc_C_CloseSession, - rpc_C_CloseAllSessions, - rpc_C_GetSessionInfo, - rpc_C_GetOperationState, - rpc_C_SetOperationState, - rpc_C_Login, - rpc_C_Logout, - rpc_C_CreateObject, - rpc_C_CopyObject, - rpc_C_DestroyObject, - rpc_C_GetObjectSize, - rpc_C_GetAttributeValue, - rpc_C_SetAttributeValue, - rpc_C_FindObjectsInit, - rpc_C_FindObjects, - rpc_C_FindObjectsFinal, - rpc_C_EncryptInit, - rpc_C_Encrypt, - rpc_C_EncryptUpdate, - rpc_C_EncryptFinal, - rpc_C_DecryptInit, - rpc_C_Decrypt, - rpc_C_DecryptUpdate, - rpc_C_DecryptFinal, - rpc_C_DigestInit, - rpc_C_Digest, - rpc_C_DigestUpdate, - rpc_C_DigestKey, - rpc_C_DigestFinal, - rpc_C_SignInit, - rpc_C_Sign, - rpc_C_SignUpdate, - rpc_C_SignFinal, - rpc_C_SignRecoverInit, - rpc_C_SignRecover, - rpc_C_VerifyInit, - rpc_C_Verify, - rpc_C_VerifyUpdate, - rpc_C_VerifyFinal, - rpc_C_VerifyRecoverInit, - rpc_C_VerifyRecover, - rpc_C_DigestEncryptUpdate, - rpc_C_DecryptDigestUpdate, - rpc_C_SignEncryptUpdate, - rpc_C_DecryptVerifyUpdate, - rpc_C_GenerateKey, - rpc_C_GenerateKeyPair, - rpc_C_WrapKey, - rpc_C_UnwrapKey, - rpc_C_DeriveKey, - rpc_C_SeedRandom, - rpc_C_GenerateRandom, - rpc_C_GetFunctionStatus, - rpc_C_CancelFunction, - rpc_C_WaitForSlotEvent -}; - -CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR list) -{ - return_val_if_fail(list, CKR_ARGUMENTS_BAD); - - *list = &functionList; - return CKR_OK; -} diff --git a/ext/pkcs11-proxy/gck-rpc-private.h b/ext/pkcs11-proxy/gck-rpc-private.h deleted file mode 100644 index dd1f49128..000000000 --- a/ext/pkcs11-proxy/gck-rpc-private.h +++ /dev/null @@ -1,327 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* p11-rpc-private.h - various ids and signatures for our protocol - - Copyright (C) 2008, Stef Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter -*/ - -#ifndef GCK_RPC_CALLS_H -#define GCK_RPC_CALLS_H - -#include "config.h" - -#include -#include - -#include "egg-buffer.h" - -#include "pkcs11/pkcs11.h" - -/* The calls, must be in sync with array below */ -enum { - GCK_RPC_CALL_ERROR = 0, - - GCK_RPC_CALL_C_Initialize, - GCK_RPC_CALL_C_Finalize, - GCK_RPC_CALL_C_GetInfo, - GCK_RPC_CALL_C_GetSlotList, - GCK_RPC_CALL_C_GetSlotInfo, - GCK_RPC_CALL_C_GetTokenInfo, - GCK_RPC_CALL_C_GetMechanismList, - GCK_RPC_CALL_C_GetMechanismInfo, - GCK_RPC_CALL_C_InitToken, - GCK_RPC_CALL_C_WaitForSlotEvent, - - GCK_RPC_CALL_C_OpenSession, - - GCK_RPC_CALL_C_CloseSession, - GCK_RPC_CALL_C_CloseAllSessions, - GCK_RPC_CALL_C_GetFunctionStatus, - GCK_RPC_CALL_C_CancelFunction, - - GCK_RPC_CALL_C_GetSessionInfo, - GCK_RPC_CALL_C_InitPIN, - GCK_RPC_CALL_C_SetPIN, - GCK_RPC_CALL_C_GetOperationState, - GCK_RPC_CALL_C_SetOperationState, - GCK_RPC_CALL_C_Login, - GCK_RPC_CALL_C_Logout, - GCK_RPC_CALL_C_CreateObject, - GCK_RPC_CALL_C_CopyObject, - GCK_RPC_CALL_C_DestroyObject, - GCK_RPC_CALL_C_GetObjectSize, - GCK_RPC_CALL_C_GetAttributeValue, - GCK_RPC_CALL_C_SetAttributeValue, - GCK_RPC_CALL_C_FindObjectsInit, - GCK_RPC_CALL_C_FindObjects, - GCK_RPC_CALL_C_FindObjectsFinal, - GCK_RPC_CALL_C_EncryptInit, - GCK_RPC_CALL_C_Encrypt, - GCK_RPC_CALL_C_EncryptUpdate, - GCK_RPC_CALL_C_EncryptFinal, - GCK_RPC_CALL_C_DecryptInit, - GCK_RPC_CALL_C_Decrypt, - GCK_RPC_CALL_C_DecryptUpdate, - GCK_RPC_CALL_C_DecryptFinal, - GCK_RPC_CALL_C_DigestInit, - GCK_RPC_CALL_C_Digest, - GCK_RPC_CALL_C_DigestUpdate, - GCK_RPC_CALL_C_DigestKey, - GCK_RPC_CALL_C_DigestFinal, - GCK_RPC_CALL_C_SignInit, - GCK_RPC_CALL_C_Sign, - GCK_RPC_CALL_C_SignUpdate, - GCK_RPC_CALL_C_SignFinal, - GCK_RPC_CALL_C_SignRecoverInit, - GCK_RPC_CALL_C_SignRecover, - GCK_RPC_CALL_C_VerifyInit, - GCK_RPC_CALL_C_Verify, - GCK_RPC_CALL_C_VerifyUpdate, - GCK_RPC_CALL_C_VerifyFinal, - GCK_RPC_CALL_C_VerifyRecoverInit, - GCK_RPC_CALL_C_VerifyRecover, - GCK_RPC_CALL_C_DigestEncryptUpdate, - GCK_RPC_CALL_C_DecryptDigestUpdate, - GCK_RPC_CALL_C_SignEncryptUpdate, - GCK_RPC_CALL_C_DecryptVerifyUpdate, - GCK_RPC_CALL_C_GenerateKey, - GCK_RPC_CALL_C_GenerateKeyPair, - GCK_RPC_CALL_C_WrapKey, - GCK_RPC_CALL_C_UnwrapKey, - GCK_RPC_CALL_C_DeriveKey, - GCK_RPC_CALL_C_SeedRandom, - GCK_RPC_CALL_C_GenerateRandom, - - GCK_RPC_CALL_MAX -}; - -typedef struct _GckRpcCall { - int call_id; - const char *name; - const char *request; - const char *response; -} GckRpcCall; - -/* - * a_ = prefix denotes array of _ - * A = CK_ATTRIBUTE - * f_ = prefix denotes buffer for _ - * M = CK_MECHANISM - * u = CK_ULONG - * s = space padded string - * v = CK_VERSION - * y = CK_BYTE - */ - -static const GckRpcCall gck_rpc_calls[] = { - {GCK_RPC_CALL_ERROR, "ERROR", NULL, NULL}, - {GCK_RPC_CALL_C_Initialize, "C_Initialize", "ay", ""}, - {GCK_RPC_CALL_C_Finalize, "C_Finalize", "", ""}, - {GCK_RPC_CALL_C_GetInfo, "C_GetInfo", "", "vsusv"}, - {GCK_RPC_CALL_C_GetSlotList, "C_GetSlotList", "yfu", "au"}, - {GCK_RPC_CALL_C_GetSlotInfo, "C_GetSlotInfo", "u", "ssuvv"}, - {GCK_RPC_CALL_C_GetTokenInfo, "C_GetTokenInfo", "u", - "ssssuuuuuuuuuuuvvs"}, - {GCK_RPC_CALL_C_GetMechanismList, "C_GetMechanismList", "ufu", "au"}, - {GCK_RPC_CALL_C_GetMechanismInfo, "C_GetMechanismInfo", "uu", "uuu"}, - {GCK_RPC_CALL_C_InitToken, "C_InitToken", "uays", ""}, - {GCK_RPC_CALL_C_WaitForSlotEvent, "C_WaitForSlotEvent", "u", "u"}, - {GCK_RPC_CALL_C_OpenSession, "C_OpenSession", "uu", "u"}, - {GCK_RPC_CALL_C_CloseSession, "C_CloseSession", "u", ""}, - {GCK_RPC_CALL_C_CloseAllSessions, "C_CloseAllSessions", "u", ""}, - {GCK_RPC_CALL_C_GetFunctionStatus, "C_GetFunctionStatus", "u", ""}, - {GCK_RPC_CALL_C_CancelFunction, "C_CancelFunction", "u", ""}, - {GCK_RPC_CALL_C_GetSessionInfo, "C_GetSessionInfo", "u", "uuuu"}, - {GCK_RPC_CALL_C_InitPIN, "C_InitPIN", "uay", ""}, - {GCK_RPC_CALL_C_SetPIN, "C_SetPIN", "uayay", ""}, - {GCK_RPC_CALL_C_GetOperationState, "C_GetOperationState", "ufy", "ay"}, - {GCK_RPC_CALL_C_SetOperationState, "C_SetOperationState", "uayuu", ""}, - {GCK_RPC_CALL_C_Login, "C_Login", "uuay", ""}, - {GCK_RPC_CALL_C_Logout, "C_Logout", "u", ""}, - {GCK_RPC_CALL_C_CreateObject, "C_CreateObject", "uaA", "u"}, - {GCK_RPC_CALL_C_CopyObject, "C_CopyObject", "uuaA", "u"}, - {GCK_RPC_CALL_C_DestroyObject, "C_DestroyObject", "uu", ""}, - {GCK_RPC_CALL_C_GetObjectSize, "C_GetObjectSize", "uu", "u"}, - {GCK_RPC_CALL_C_GetAttributeValue, "C_GetAttributeValue", "uufA", - "aAu"}, - {GCK_RPC_CALL_C_SetAttributeValue, "C_SetAttributeValue", "uuaA", ""}, - {GCK_RPC_CALL_C_FindObjectsInit, "C_FindObjectsInit", "uaA", ""}, - {GCK_RPC_CALL_C_FindObjects, "C_FindObjects", "ufu", "au"}, - {GCK_RPC_CALL_C_FindObjectsFinal, "C_FindObjectsFinal", "u", ""}, - {GCK_RPC_CALL_C_EncryptInit, "C_EncryptInit", "uMu", ""}, - {GCK_RPC_CALL_C_Encrypt, "C_Encrypt", "uayfy", "ay"}, - {GCK_RPC_CALL_C_EncryptUpdate, "C_EncryptUpdate", "uayfy", "ay"}, - {GCK_RPC_CALL_C_EncryptFinal, "C_EncryptFinal", "ufy", "ay"}, - {GCK_RPC_CALL_C_DecryptInit, "C_DecryptInit", "uMu", ""}, - {GCK_RPC_CALL_C_Decrypt, "C_Decrypt", "uayfy", "ay"}, - {GCK_RPC_CALL_C_DecryptUpdate, "C_DecryptUpdate", "uayfy", "ay"}, - {GCK_RPC_CALL_C_DecryptFinal, "C_DecryptFinal", "ufy", "ay"}, - {GCK_RPC_CALL_C_DigestInit, "C_DigestInit", "uM", ""}, - {GCK_RPC_CALL_C_Digest, "C_Digest", "uayfy", "ay"}, - {GCK_RPC_CALL_C_DigestUpdate, "C_DigestUpdate", "uay", ""}, - {GCK_RPC_CALL_C_DigestKey, "C_DigestKey", "uu", ""}, - {GCK_RPC_CALL_C_DigestFinal, "C_DigestFinal", "ufy", "ay"}, - {GCK_RPC_CALL_C_SignInit, "C_SignInit", "uMu", ""}, - {GCK_RPC_CALL_C_Sign, "C_Sign", "uayfy", "ay"}, - {GCK_RPC_CALL_C_SignUpdate, "C_SignUpdate", "uay", ""}, - {GCK_RPC_CALL_C_SignFinal, "C_SignFinal", "ufy", "ay"}, - {GCK_RPC_CALL_C_SignRecoverInit, "C_SignRecoverInit", "uMu", ""}, - {GCK_RPC_CALL_C_SignRecover, "C_SignRecover", "uayfy", "ay"}, - {GCK_RPC_CALL_C_VerifyInit, "C_VerifyInit", "uMu", ""}, - {GCK_RPC_CALL_C_Verify, "C_Verify", "uayay", ""}, - {GCK_RPC_CALL_C_VerifyUpdate, "C_VerifyUpdate", "uay", ""}, - {GCK_RPC_CALL_C_VerifyFinal, "C_VerifyFinal", "uay", ""}, - {GCK_RPC_CALL_C_VerifyRecoverInit, "C_VerifyRecoverInit", "uMu", ""}, - {GCK_RPC_CALL_C_VerifyRecover, "C_VerifyRecover", "uayfy", "ay"}, - {GCK_RPC_CALL_C_DigestEncryptUpdate, "C_DigestEncryptUpdate", "uayfy", - "ay"}, - {GCK_RPC_CALL_C_DecryptDigestUpdate, "C_DecryptDigestUpdate", "uayfy", - "ay"}, - {GCK_RPC_CALL_C_SignEncryptUpdate, "C_SignEncryptUpdate", "uayfy", - "ay"}, - {GCK_RPC_CALL_C_DecryptVerifyUpdate, "C_DecryptVerifyUpdate", "uayfy", - "ay"}, - {GCK_RPC_CALL_C_GenerateKey, "C_GenerateKey", "uMaA", "u"}, - {GCK_RPC_CALL_C_GenerateKeyPair, "C_GenerateKeyPair", "uMaAaA", "uu"}, - {GCK_RPC_CALL_C_WrapKey, "C_WrapKey", "uMuufy", "ay"}, - {GCK_RPC_CALL_C_UnwrapKey, "C_UnwrapKey", "uMuayaA", "u"}, - {GCK_RPC_CALL_C_DeriveKey, "C_DeriveKey", "uMuaA", "u"}, - {GCK_RPC_CALL_C_SeedRandom, "C_SeedRandom", "uay", ""}, - {GCK_RPC_CALL_C_GenerateRandom, "C_GenerateRandom", "ufy", "ay"}, -}; - -#ifdef _DEBUG -#define GCK_RPC_CHECK_CALLS() \ - { int i; for (i = 0; i < GCK_RPC_CALL_MAX; ++i) assert (gck_rpc_calls[i].call_id == i); } -#endif - -#define GCK_RPC_HANDSHAKE \ - "PRIVATE-GNOME-KEYRING-PKCS11-PROTOCOL-V-3" -#define GCK_RPC_HANDSHAKE_LEN \ - (sizeof (GCK_RPC_HANDSHAKE) - 1) - -#define GCK_RPC_SOCKET_EXT "pkcs11" - -typedef enum _GckRpcMessageType { - GCK_RPC_REQUEST = 1, - GCK_RPC_RESPONSE -} GckRpcMessageType; - -typedef struct _GckRpcMessage { - int call_id; - GckRpcMessageType call_type; - const char *signature; - EggBuffer buffer; - - size_t parsed; - const char *sigverify; -} GckRpcMessage; - -#define GCK_RPC_BYTE_BUFFER_NULL_DATA 1 -#define GCK_RPC_BYTE_BUFFER_NULL_COUNT 2 - -GckRpcMessage *gck_rpc_message_new(EggBufferAllocator allocator); - -void gck_rpc_message_free(GckRpcMessage * msg); - -void gck_rpc_message_reset(GckRpcMessage * msg); - -int gck_rpc_message_equals(GckRpcMessage * m1, GckRpcMessage * m2); - -#define gck_rpc_message_is_verified(msg) (!(msg)->sigverify || (msg)->sigverify[0] == 0) - -#define gck_rpc_message_buffer_error(msg) (egg_buffer_has_error(&(msg)->buffer)) - -int gck_rpc_message_prep(GckRpcMessage * msg, - int call_id, GckRpcMessageType type); - -int gck_rpc_message_parse(GckRpcMessage * msg, GckRpcMessageType type); - -int gck_rpc_message_verify_part(GckRpcMessage * msg, const char *part); - -int gck_rpc_message_write_byte(GckRpcMessage * msg, CK_BYTE val); - -int gck_rpc_message_write_ulong(GckRpcMessage * msg, CK_ULONG val); - -int gck_rpc_message_write_space_string(GckRpcMessage * msg, - CK_UTF8CHAR * buffer, CK_ULONG length); - -int gck_rpc_message_write_byte_buffer(GckRpcMessage * msg, CK_BYTE_PTR arr, CK_ULONG *count_ptr); - -int gck_rpc_message_write_byte_array(GckRpcMessage * msg, - CK_BYTE_PTR arr, CK_ULONG num); - -int gck_rpc_message_write_ulong_buffer(GckRpcMessage * msg, CK_ULONG count); - -int gck_rpc_message_write_ulong_array(GckRpcMessage * msg, - CK_ULONG_PTR arr, CK_ULONG num); - -int gck_rpc_message_write_attribute_buffer(GckRpcMessage * msg, - CK_ATTRIBUTE_PTR arr, CK_ULONG num); - -int gck_rpc_message_write_attribute_array(GckRpcMessage * msg, - CK_ATTRIBUTE_PTR arr, CK_ULONG num); - -int gck_rpc_message_write_version(GckRpcMessage * msg, CK_VERSION * version); - -int gck_rpc_message_read_byte(GckRpcMessage * msg, CK_BYTE * val); - -int gck_rpc_message_read_ulong(GckRpcMessage * msg, CK_ULONG * val); - -int gck_rpc_message_read_space_string(GckRpcMessage * msg, - CK_UTF8CHAR * buffer, CK_ULONG length); - -int gck_rpc_message_read_version(GckRpcMessage * msg, CK_VERSION * version); - -void gck_rpc_log(const char *msg, ...); - -void gck_rpc_warn(const char *msg, ...); - -void gck_rpc_debug(const char *msg, ...); - -#ifdef G_DISABLE_ASSERT -#define assert(x) -#else -#include -#endif - -/* - * PKCS#11 mechanism parameters are not easy to serialize. They're - * completely different for so many mechanisms, they contain - * pointers to arbitrary memory, and many callers don't initialize - * them completely or properly. - * - * We only support certain mechanisms. - * - * Also callers do yucky things like leaving parts of the structure - * pointing to garbage if they don't think it's going to be used. - */ - -int gck_rpc_mechanism_is_supported(CK_MECHANISM_TYPE mech); -void gck_rpc_mechanism_list_purge(CK_MECHANISM_TYPE_PTR mechs, - CK_ULONG_PTR n_mechs); -int gck_rpc_mechanism_has_sane_parameters(CK_MECHANISM_TYPE type); -int gck_rpc_mechanism_has_no_parameters(CK_MECHANISM_TYPE mech); -int gck_rpc_has_bad_sized_ulong_parameter(CK_ATTRIBUTE_PTR attr); -int gck_rpc_has_ulong_parameter(CK_ATTRIBUTE_TYPE type); - -/* Parses strings (prefix) to host and port components. */ -int gck_rpc_parse_host_port(const char *prefix, char **host, char **port); - -#endif /* GCK_RPC_CALLS_H */ diff --git a/ext/pkcs11-proxy/gck-rpc-tls-psk.c b/ext/pkcs11-proxy/gck-rpc-tls-psk.c deleted file mode 100644 index c19ea860e..000000000 --- a/ext/pkcs11-proxy/gck-rpc-tls-psk.c +++ /dev/null @@ -1,410 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gck-rpc-tls-psk.c - TLS-PSK functionality to protect communication - - Copyright (C) 2013, NORDUnet A/S - - pkcs11-proxy is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - pkcs11-proxy is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Fredrik Thulin -*/ - -#include "config.h" - -#include "gck-rpc-private.h" -#include "gck-rpc-tls-psk.h" - -#include -#include - -/* for file I/O */ -#include -#include -#include -#include - -/* TLS pre-shared key */ -static char tls_psk_identity[128] = { 0, }; -static char tls_psk_key_filename[MAXPATHLEN] = { 0, }; - -/* ----------------------------------------------------------------------------- - * LOGGING and DEBUGGING - */ -#ifndef DEBUG_OUTPUT -#define DEBUG_OUTPUT 0 -#endif -#if DEBUG_OUTPUT -#define debug(x) gck_rpc_debug x -#else -#define debug(x) -#endif -#define warning(x) gck_rpc_warn x - - -/* ----------------------------------------------------------------------------- - * TLS-PSK (pre-shared key) functionality - */ - -/* Utility function to decode a single hex char. - * - * Returns value as integer, or -1 on invalid hex char (not 0-9, a-f or A-F). - */ -static int -_tls_psk_to_hex(char val) -{ - if (val >= '0' && val <= '9') - return val - '0'; - if (val >= 'a' && val <= 'f') - return val - 'a' + 10; - if (val >= 'A' && val <= 'F') - return val - 'A' + 10; - return -1; -} - -/* Hex decode the key from an entry in the TLS-PSK key file. Entrys are of the form - * - * identity:hex-key\n - * - * Logging debug/error messages here is a bit problematic since the key is sensitive - * and should not be logged to syslog for example. This code avoids logging the key - * part and only logs identity. - * - * Returns 0 on failure, number of bytes in hex-decoded key on success. - */ -static int -_tls_psk_decode_key(const char *identity, const char *hexkey, unsigned char *psk, unsigned int max_psk_len) -{ - int psk_len, i; - - /* check that length of the key is even */ - if ((strlen(hexkey) % 2) != 0) { - warning(("un-even length TLS-PSK key")); - return 0; - } - - memset(psk, 0, max_psk_len); - psk_len = 0; - - while (*hexkey && (psk_len < max_psk_len)) { - /* decode first half of byte, check for errors */ - if ((i = _tls_psk_to_hex(*hexkey)) < 0) { - warning(("bad TLS-PSK '%.100s' hex char at position %i (%c)", - identity, psk_len + 1, *hexkey)); - return 0; - } - *psk = i << 4; - hexkey++; - - /* decode second half of byte, check for errors */ - if ((i = _tls_psk_to_hex(*hexkey)) < 0) { - warning(("bad TLS-PSK '%.100s' hex char at position %i (%c)", - identity, psk_len + 1, *hexkey)); - return 0; - } - *psk |= i; - hexkey++; - - psk_len++; - psk++; - } - if (*hexkey) { - warning(("too long TLS-PSK '%.100s' key (max %i)", identity, max_psk_len)); - return 0; - } - - return psk_len; -} - -/* - * Read from a file descriptor until a newline is spotted. - * - * Using open() and _fgets() instead of fopen() and fgets() avoids having to - * seccomp-allow the mmap() syscall. - * - * Reading one byte at a time is perhaps not optimal from a performance - * standpoint, but the kernel will surely have pre-buffered the data anyways. - */ -int _fgets(char *buf, unsigned int len, const int fd) -{ - int bytes; - - bytes = 0; - - while (len) { - if (read(fd, buf, 1) != 1) - break; - bytes++; - if (*buf == '\n') { - buf++; - len--; - break; - } - buf++; - len--; - } - - if (! len) - /* ran out of space */ - return -1; - *buf = '\0'; - return bytes; -} - -/* - * Callbacks invoked by OpenSSL PSK initialization. - */ - - -/* Server side TLS-PSK initialization callback. Given an identity (chosen by the client), - * locate a pre-shared key and put it in psk. - * - * Returns the number of bytes put in psk, or 0 on failure. - */ -static unsigned int -_tls_psk_server_cb(SSL *ssl, const char *identity, - unsigned char *psk, unsigned int max_psk_len) -{ - char line[1024], *hexkey; - unsigned int psk_len; - int i, fd; - - debug(("Initializing TLS-PSK with keyfile '%.100s', identity '%.100s'", - tls_psk_key_filename, identity)); - - if ((fd = open(tls_psk_key_filename, O_RDONLY | O_CLOEXEC)) < 0) { - gck_rpc_warn("can't open TLS-PSK keyfile '%.100s' for reading : %s", - tls_psk_key_filename, strerror(errno)); - return 0; - } - - /* Format of PSK file is that of GnuTLS psktool. - * - * identity:hex-key - * other:another-hex-key - */ - psk_len = 0; - - while (_fgets(line, sizeof(line) - 1, fd) > 0) { - /* Find first colon and replace it with NULL */ - hexkey = strchr(line, ':'); - if (! hexkey) - continue; - *hexkey = 0; - hexkey++; - - /* Remove newline(s) at the end */ - for (i = strlen(hexkey) - 1; i && (hexkey[i] == '\n' || hexkey[i] == '\r'); i--) - hexkey[i] = 0; - - if (identity == NULL || ! identity[0] || ! strcmp(line, identity)) { - /* If the line starts with identity: or identity is not provided, parse this line. */ - psk_len = _tls_psk_decode_key(line, hexkey, psk, max_psk_len); - if (psk_len) - debug(("Loaded TLS-PSK '%.100s' from keyfile '%.100s'", - line, tls_psk_key_filename)); - else - warning(("Failed loading TLS-PSK '%.100s' from keyfile '%.100s'", - line, tls_psk_key_filename)); - break; - } - } - close(fd); - - return psk_len; -} - -/* Client side TLS-PSK initialization callback. Indicate to OpenSSL what identity to - * use, and the pre-shared key for that identity. - * - * Returns the number of bytes put in psk, or 0 on failure. - */ -static unsigned int -_tls_psk_client_cb(SSL *ssl, const char *hint, - char *identity, unsigned int max_identity_len, - unsigned char *psk, unsigned int max_psk_len) -{ - /* Client tells server which identity it wants to use in ClientKeyExchange */ - snprintf(identity, max_identity_len, "%s", tls_psk_identity); - - /* We currently just discard the hint sent to us by the server */ - return _tls_psk_server_cb(ssl, identity, psk, max_psk_len); -} - - -/* Initialize OpenSSL and create an SSL CTX. Should be called just once. - * - * Returns 0 on failure and 1 on success. - */ -int -gck_rpc_init_tls_psk(GckRpcTlsPskState *state, const char *key_filename, - const char *identity, enum gck_rpc_tls_psk_caller caller) -{ - char *tls_psk_ciphers = PKCS11PROXY_TLS_PSK_CIPHERS; - - if (state->initialized == 1) { - warning(("TLS state already initialized")); - return 0; - } - - /* Global OpenSSL initialization */ - SSL_load_error_strings(); - SSL_library_init(); - OpenSSL_add_ssl_algorithms(); - - assert(caller == GCK_RPC_TLS_PSK_CLIENT || caller == GCK_RPC_TLS_PSK_SERVER); - - state->ssl_ctx = SSL_CTX_new(TLSv1_2_method()); - - if (state->ssl_ctx == NULL) { - gck_rpc_warn("can't initialize SSL_CTX"); - return 0; - } - - /* Set up callback for TLS-PSK initialization */ - if (caller == GCK_RPC_TLS_PSK_CLIENT) - SSL_CTX_set_psk_client_callback(state->ssl_ctx, _tls_psk_client_cb); - else - SSL_CTX_set_psk_server_callback(state->ssl_ctx, _tls_psk_server_cb); - - /* Disable compression, for security (CRIME Attack). */ - SSL_CTX_set_options(state->ssl_ctx, SSL_OP_NO_COMPRESSION); - - /* Specify ciphers to use */ - SSL_CTX_set_cipher_list(state->ssl_ctx, tls_psk_ciphers); - - snprintf(tls_psk_key_filename, sizeof(tls_psk_key_filename), "%s", key_filename); - snprintf(tls_psk_identity, sizeof(tls_psk_identity), "%s", identity ? identity : ""); - - state->type = caller; - state->initialized = 1; - - debug(("Initialized TLS-PSK %s", caller == GCK_RPC_TLS_PSK_CLIENT ? "client" : "server")); - - return 1; -} - -/* Set up SSL for a new socket. Call this after accept() or connect(). - * - * When a socket has been created, call gck_rpc_start_tls() with the TLS state - * initialized using gck_rpc_init_tls_psk() and the new socket. - * - * Returns 1 on success and 0 on failure. - */ -int -gck_rpc_start_tls(GckRpcTlsPskState *state, int sock) -{ - int res; - char buf[256]; - - state->ssl = SSL_new(state->ssl_ctx); - if (! state->ssl) { - warning(("can't initialize SSL")); - return 0; - } - - state->bio = BIO_new_socket(sock, BIO_NOCLOSE); - if (! state->bio) { - warning(("can't initialize SSL BIO")); - return 0; - } - - SSL_set_bio(state->ssl, state->bio, state->bio); - - /* Set up callback for TLS-PSK initialization */ - if (state->type == GCK_RPC_TLS_PSK_CLIENT) - res = SSL_connect(state->ssl); - else - res = SSL_accept(state->ssl); - - if (res != 1) { - ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); - warning(("can't start TLS : %i/%i (%s perhaps)", - res, SSL_get_error(state->ssl, res), strerror(errno))); - warning(("SSL ERR: %s", buf)); - return 0; - } - - return 1; -} - -/* Un-initialize everything SSL related. Call this on application shut down. - */ -void -gck_rpc_close_tls(GckRpcTlsPskState *state) -{ - if (state->ssl_ctx) { - SSL_CTX_free(state->ssl_ctx); - state->ssl_ctx = NULL; - } - - if (state->ssl) { - SSL_free(state->ssl); - state->ssl = NULL; - } -} - -/* Send data using SSL. - * - * Returns the number of bytes written. - */ -int -gck_rpc_tls_write_all(GckRpcTlsPskState *state, void *data, unsigned int len) -{ - int bytes, error; - char buf[256]; - - assert(state); - assert(data); - assert(len > 0); - - bytes = SSL_write(state->ssl, data, len); - - if (bytes <= 0) { - while ((error = ERR_get_error())) { - ERR_error_string_n(error, buf, sizeof(buf)); - warning(("SSL_write error: %s", buf)); - } - return 0; - } - - return bytes; -} - -/* Read data using SSL. - * - * Returns the number of bytes read. - */ -int -gck_rpc_tls_read_all(GckRpcTlsPskState *state, void *data, unsigned int len) -{ - int bytes, error; - char buf[256]; - - assert(state); - assert(data); - assert(len > 0); - - bytes = SSL_read(state->ssl, data, len); - - if (bytes <= 0) { - while ((error = ERR_get_error())) { - ERR_error_string_n(error, buf, sizeof(buf)); - warning(("SSL_read error: %s", buf)); - } - return 0; - } - - return bytes; -} diff --git a/ext/pkcs11-proxy/gck-rpc-tls-psk.h b/ext/pkcs11-proxy/gck-rpc-tls-psk.h deleted file mode 100644 index b878376ae..000000000 --- a/ext/pkcs11-proxy/gck-rpc-tls-psk.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -#ifndef GCKRPC_TLS_PSK_H_ -#define GCKRPC_TLS_PSK_H_ - -#include "openssl/bio.h" -#include "openssl/ssl.h" -#include "openssl/err.h" - -#if OPENSSL_VERSION_NUMBER < 0x10000000 -# error "OpenSSL version >= 1.0.0 required" -#endif - -enum gck_rpc_tls_psk_caller { - GCK_RPC_TLS_PSK_CLIENT, - GCK_RPC_TLS_PSK_SERVER -}; - -typedef struct { - int initialized; - SSL_CTX *ssl_ctx; - BIO *bio; - SSL *ssl; - enum gck_rpc_tls_psk_caller type; -} GckRpcTlsPskState; - - -int gck_rpc_init_tls_psk(GckRpcTlsPskState *state, const char *key_filename, - const char *identity, enum gck_rpc_tls_psk_caller caller); -int gck_rpc_start_tls(GckRpcTlsPskState *state, int sock); - -int gck_rpc_tls_write_all(GckRpcTlsPskState *state, void *data, unsigned int len); -int gck_rpc_tls_read_all(GckRpcTlsPskState *state, void *data, unsigned int len); - -void gck_rpc_close_tls(GckRpcTlsPskState *state); - -#endif /* GCKRPC_TLS_PSK_H_ */ diff --git a/ext/pkcs11-proxy/gck-rpc-util.c b/ext/pkcs11-proxy/gck-rpc-util.c deleted file mode 100644 index 6095159ea..000000000 --- a/ext/pkcs11-proxy/gck-rpc-util.c +++ /dev/null @@ -1,284 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* p11-rpc-util.c - utilities for module and dispatcher - - Copyright (C) 2008, Stef Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter -*/ - -#include "config.h" - -#include "gck-rpc-layer.h" -#include "gck-rpc-private.h" - -#include -#include -#include - -static void do_log(const char *pref, const char *msg, va_list va) -{ - char buffer[1024]; - size_t len = 0; - - if (pref) { - snprintf(buffer, sizeof(buffer), "%s: ", pref); - len = strlen(buffer); - } - - vsnprintf(buffer + len, sizeof(buffer) - len, msg, va); - gck_rpc_log(buffer); -} - -void gck_rpc_warn(const char *msg, ...) -{ - va_list va; - va_start(va, msg); - do_log("WARNING", msg, va); - va_end(va); -} - -void gck_rpc_debug(const char *msg, ...) -{ - va_list va; - va_start(va, msg); - do_log("DEBUG", msg, va); - va_end(va); -} - -int gck_rpc_mechanism_is_supported(CK_MECHANISM_TYPE mech) -{ - if (gck_rpc_mechanism_has_no_parameters(mech) || - gck_rpc_mechanism_has_sane_parameters(mech)) - return 1; - return 0; -} - -void -gck_rpc_mechanism_list_purge(CK_MECHANISM_TYPE_PTR mechs, CK_ULONG * n_mechs) -{ - int i; - - assert(mechs); - assert(n_mechs); - - for (i = 0; i < (int)(*n_mechs); ++i) { - if (!gck_rpc_mechanism_has_no_parameters(mechs[i]) && - !gck_rpc_mechanism_has_sane_parameters(mechs[i])) { - - /* Remove the mechanism from the list */ - memmove(&mechs[i], &mechs[i + 1], - (*n_mechs - i) * sizeof(CK_MECHANISM_TYPE)); - - --(*n_mechs); - --i; - } - } -} - -int gck_rpc_mechanism_has_sane_parameters(CK_MECHANISM_TYPE type) -{ - /* This list is incomplete */ - switch (type) { - case CKM_RSA_PKCS_OAEP: - case CKM_RSA_PKCS_PSS: - return 1; - default: - return 0; - } -} - -int gck_rpc_mechanism_has_no_parameters(CK_MECHANISM_TYPE mech) -{ - /* This list is incomplete */ - - switch (mech) { - case CKM_RSA_PKCS_KEY_PAIR_GEN: - case CKM_RSA_X9_31_KEY_PAIR_GEN: - case CKM_RSA_PKCS: - case CKM_RSA_9796: - case CKM_RSA_X_509: - case CKM_RSA_X9_31: - case CKM_MD2_RSA_PKCS: - case CKM_MD5_RSA_PKCS: - case CKM_SHA1_RSA_PKCS: - case CKM_SHA256_RSA_PKCS: - case CKM_SHA384_RSA_PKCS: - case CKM_SHA512_RSA_PKCS: - case CKM_RIPEMD128_RSA_PKCS: - case CKM_RIPEMD160_RSA_PKCS: - case CKM_SHA1_RSA_X9_31: - case CKM_DSA_KEY_PAIR_GEN: - case CKM_DSA_PARAMETER_GEN: - case CKM_DSA: - case CKM_DSA_SHA1: - case CKM_FORTEZZA_TIMESTAMP: - case CKM_EC_KEY_PAIR_GEN: - case CKM_ECDSA: - case CKM_ECDSA_SHA1: - case CKM_DH_PKCS_KEY_PAIR_GEN: - case CKM_DH_PKCS_PARAMETER_GEN: - case CKM_X9_42_DH_KEY_PAIR_GEN: - case CKM_X9_42_DH_PARAMETER_GEN: - case CKM_KEA_KEY_PAIR_GEN: - case CKM_GENERIC_SECRET_KEY_GEN: - case CKM_RC2_KEY_GEN: - case CKM_RC4_KEY_GEN: - case CKM_RC4: - case CKM_RC5_KEY_GEN: - case CKM_AES_KEY_GEN: - case CKM_AES_ECB: - case CKM_AES_MAC: - case CKM_DES_KEY_GEN: - case CKM_DES2_KEY_GEN: - case CKM_DES3_KEY_GEN: - case CKM_CDMF_KEY_GEN: - case CKM_CAST_KEY_GEN: - case CKM_CAST3_KEY_GEN: - case CKM_CAST128_KEY_GEN: - case CKM_IDEA_KEY_GEN: - case CKM_SSL3_PRE_MASTER_KEY_GEN: - case CKM_TLS_PRE_MASTER_KEY_GEN: - case CKM_SKIPJACK_KEY_GEN: - case CKM_BATON_KEY_GEN: - case CKM_JUNIPER_KEY_GEN: - case CKM_RC2_ECB: - case CKM_DES_ECB: - case CKM_DES3_ECB: - case CKM_CDMF_ECB: - case CKM_CAST_ECB: - case CKM_CAST3_ECB: - case CKM_CAST128_ECB: - case CKM_RC5_ECB: - case CKM_IDEA_ECB: - case CKM_RC2_MAC: - case CKM_DES_MAC: - case CKM_DES3_MAC: - case CKM_CDMF_MAC: - case CKM_CAST_MAC: - case CKM_CAST3_MAC: - case CKM_RC5_MAC: - case CKM_IDEA_MAC: - case CKM_SSL3_MD5_MAC: - case CKM_SSL3_SHA1_MAC: - case CKM_SKIPJACK_WRAP: - case CKM_BATON_WRAP: - case CKM_JUNIPER_WRAP: - case CKM_MD2: - case CKM_MD2_HMAC: - case CKM_MD5: - case CKM_MD5_HMAC: - case CKM_SHA_1: - case CKM_SHA_1_HMAC: - case CKM_SHA256: - case CKM_SHA256_HMAC: - case CKM_SHA384: - case CKM_SHA384_HMAC: - case CKM_SHA512: - case CKM_SHA512_HMAC: - case CKM_FASTHASH: - case CKM_RIPEMD128: - case CKM_RIPEMD128_HMAC: - case CKM_RIPEMD160: - case CKM_RIPEMD160_HMAC: - case CKM_KEY_WRAP_LYNKS: - return 1; - default: - return 0; - }; -} - -int -gck_rpc_has_ulong_parameter(CK_ATTRIBUTE_TYPE type) -{ - switch (type) { - case CKA_CLASS: - case CKA_KEY_TYPE: - case CKA_CERTIFICATE_TYPE: - case CKA_HW_FEATURE_TYPE: - case CKA_MODULUS_BITS: - return 1; - default: - return 0; - } -} - -int -gck_rpc_has_bad_sized_ulong_parameter(CK_ATTRIBUTE_PTR attr) -{ - if (!attr->pValue) - return 0; - /* All this parameters are transmited on the network - * as 64bit integers */ - if (sizeof (uint64_t) != attr->ulValueLen) - return 0; - if (sizeof (CK_ULONG) == attr->ulValueLen) - return 0; - return gck_rpc_has_ulong_parameter(attr->type); -} - -/* - * Parses prefix into two strings (host and port). Port may be a NULL pointer - * if none is specified. Since this code does not decode port in any way, a - * service name works too (but requires other code (like - * _get_listening_socket()) able to resolve service names). - * - * This should work for IPv4 and IPv6 inputs : - * - * 0.0.0.0:2345 - * 0.0.0.0 - * [::]:2345 - * [::] - * [::1]:2345 - * localhost:2345 - * localhost - * localhost:p11proxy (if p11proxy is a known service name) - * - * Returns 0 on failure, and 1 on success. - */ -int gck_rpc_parse_host_port(const char *prefix, char **host, char **port) -{ - char *p = NULL; - int is_ipv6; - - is_ipv6 = (prefix[0] == '[') ? 1 : 0; - - *host = strdup(prefix + is_ipv6); - *port = NULL; - - if (*host == NULL) { - gck_rpc_warn("out of memory"); - return 0; - } - - if (is_ipv6 && prefix[0] == '[') - p = strchr(*host, ']'); - else - p = strchr(*host, ':'); - - if (p) { - is_ipv6 = (*p == ']'); /* remember if separator was ']' */ - - *p = '\0'; /* replace separator will NULL to terminate *host */ - *port = p + 1; - - if (is_ipv6 && (**port == ':')) - *port = p + 2; - } - - return 1; -} diff --git a/ext/pkcs11-proxy/install_manifest.txt b/ext/pkcs11-proxy/install_manifest.txt deleted file mode 100644 index e0b24b172..000000000 --- a/ext/pkcs11-proxy/install_manifest.txt +++ /dev/null @@ -1,4 +0,0 @@ -/usr/local/bin/pkcs11-daemon -/usr/local/lib/libpkcs11-proxy.so.0.1 -/usr/local/lib/libpkcs11-proxy.so.0 -/usr/local/lib/libpkcs11-proxy.so \ No newline at end of file diff --git a/ext/pkcs11-proxy/libpkcs11-proxy.so.0 b/ext/pkcs11-proxy/libpkcs11-proxy.so.0 deleted file mode 120000 index c5a87ce85..000000000 --- a/ext/pkcs11-proxy/libpkcs11-proxy.so.0 +++ /dev/null @@ -1 +0,0 @@ -libpkcs11-proxy.so.0.1 \ No newline at end of file diff --git a/ext/pkcs11-proxy/libpkcs11-proxy.so.0.1 b/ext/pkcs11-proxy/libpkcs11-proxy.so.0.1 deleted file mode 100755 index 84348b6e3..000000000 Binary files a/ext/pkcs11-proxy/libpkcs11-proxy.so.0.1 and /dev/null differ diff --git a/ext/pkcs11-proxy/mksyscalls.sh b/ext/pkcs11-proxy/mksyscalls.sh deleted file mode 100755 index 47b4a96d5..000000000 --- a/ext/pkcs11-proxy/mksyscalls.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -(echo "static const char *syscall_names[] = {" -echo "#include " | cpp -dM | grep '^#define __NR_' | LC_ALL=C sed -r -n -e 's/^\#define[ \t]+__NR_([a-z0-9_]+)[ \t]+([0-9]+)(.*)/ [\2] = "\1",/p' -echo "};")> syscall-names.h diff --git a/ext/pkcs11-proxy/p11proxy-mitm b/ext/pkcs11-proxy/p11proxy-mitm deleted file mode 100755 index a64015093..000000000 --- a/ext/pkcs11-proxy/p11proxy-mitm +++ /dev/null @@ -1,528 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2012, 2013, NORDUnet A/S -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or -# without modification, are permitted provided that the following -# conditions are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# 3. Neither the name of the NORDUnet nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# Author : Fredrik Thulin -# -""" -MITM (man in the middle) proxy of pkcs11-proxy. Written while learning -how the (not very documented) wire format worked, as well as to help -diagnose (and fix) a couple of bugs in the C implementation. - -Usage : - - On console 1 : - - $ PKCS11_DAEMON_SOCKET="tcp://127.0.0.1:2345" pkcs11-daemon /usr/lib/libsofthsm.so - - On console 2 : - - $ ./p11proxy-mitm --debug - - On console 3 : - - $ PKCS11_PROXY_SOCKET="tcp://127.0.0.1:2344" pkcs11-tool --show-info --module libpkcs11-proxy.so - -""" - -import sys -import struct -import socket -import logging -import argparse -import SocketServer -import PyKCS11 # used to get all the PKCS#11 defines - -default_host = "localhost" -default_port_in = 2344 -default_port_out = 2345 -default_timeout = 3 -default_debug = False - -args = None -yhsm = None -logger = None - -# Extracted from gck-rpc-private.h. The last two elements of the tuples describe -# the requests/responses. -# -# /* -# * a_ = prefix denotes array of _ -# * A = CK_ATTRIBUTE -# * f_ = prefix denotes buffer for _ -# * M = CK_MECHANISM -# * u = CK_ULONG -# * s = space padded string -# * v = CK_VERSION -# * y = CK_BYTE -# * z = null terminated string -# */ -request_list = [ - (0, "ERROR", None, None), - (1, "C_Initialize", "ay", ""), - (2, "C_Finalize", "", ""), - (3, "C_GetInfo", "", "vsusv"), - (4, "C_GetSlotList", "yfu", "au"), - (5, "C_GetSlotInfo", "u", "ssuvv"), - (6, "C_GetTokenInfo", "u", "ssssuuuuuuuuuuuvvs"), - (7, "C_GetMechanismList", "ufu", "au"), - (8, "C_GetMechanismInfo", "uu", "uuu"), - (9, "C_InitToken", "uays", ""), - (10, "C_WaitForSlotEvent", "u", "u"), - (11, "C_OpenSession", "uu", "u"), - (12, "C_CloseSession", "u", ""), - (13, "C_CloseAllSessions", "u", ""), - (14, "C_GetFunctionStatus", "u", ""), - (15, "C_CancelFunction", "u", ""), - (16, "C_GetSessionInfo", "u", "uuuu"), - (17, "C_InitPIN", "uay", ""), - (18, "C_SetPIN", "uayay", ""), - (19, "C_GetOperationState", "ufy", "ay"), - (20, "C_SetOperationState", "uayuu", ""), - (21, "C_Login", "uuay", ""), - (22, "C_Logout", "u", ""), - (23, "C_CreateObject", "uaA", "u"), - (24, "C_CopyObject", "uuaA", "u"), - (25, "C_DestroyObject", "uu", ""), - (26, "C_GetObjectSize", "uu", "u"), - (27, "C_GetAttributeValue", "uufA", "aAu"), - (28, "C_SetAttributeValue", "uuaA", ""), - (29, "C_FindObjectsInit", "uaA", ""), - (30, "C_FindObjects", "ufu", "au"), - (31, "C_FindObjectsFinal", "u", ""), - (32, "C_EncryptInit", "uMu", ""), - (33, "C_Encrypt", "uayfy", "ay"), - (34, "C_EncryptUpdate", "uayfy", "ay"), - (35, "C_EncryptFinal", "ufy", "ay"), - (36, "C_DecryptInit", "uMu", ""), - (37, "C_Decrypt", "uayfy", "ay"), - (38, "C_DecryptUpdate", "uayfy", "ay"), - (39, "C_DecryptFinal", "ufy", "ay"), - (40, "C_DigestInit", "uM", ""), - (41, "C_Digest", "uayfy", "ay"), - (42, "C_DigestUpdate", "uay", ""), - (43, "C_DigestKey", "uu", ""), - (44, "C_DigestFinal", "ufy", "ay"), - (45, "C_SignInit", "uMu", ""), - (46, "C_Sign", "uayfy", "ay"), - (47, "C_SignUpdate", "uay", ""), - (48, "C_SignFinal", "ufy", "ay"), - (49, "C_SignRecoverInit", "uMu", ""), - (50, "C_SignRecover", "uayfy", "ay"), - (51, "C_VerifyInit", "uMu", ""), - (52, "C_Verify", "uayay", ""), - (53, "C_VerifyUpdate", "uay", ""), - (54, "C_VerifyFinal", "uay", ""), - (55, "C_VerifyRecoverInit", "uMu", ""), - (56, "C_VerifyRecover", "uayfy", "ay"), - (57, "C_DigestEncryptUpdate", "uayfy", "ay"), - (58, "C_DecryptDigestUpdate", "uayfy", "ay"), - (59, "C_SignEncryptUpdate", "uayfy", "ay"), - (60, "C_DecryptVerifyUpdate", "uayfy", "ay"), - (61, "C_GenerateKey", "uMaA", "u"), - (62, "C_GenerateKeyPair", "uMaAaA", "uu"), - (63, "C_WrapKey", "uMuufy", "ay"), - (64, "C_UnwrapKey", "uMuayaA", "u"), - (65, "C_DeriveKey", "uMuaA", "u"), - (66, "C_SeedRandom", "uay", ""), - (67, "C_GenerateRandom", "ufy", "ay"), - ] - -def parse_args(): - """ - Parse the command line arguments. - """ - parser = argparse.ArgumentParser(description = "pkcs11-proxy man-in-the-middle", - add_help = True, - formatter_class = argparse.ArgumentDefaultsHelpFormatter, - ) - - parser.add_argument('-H', '--host', - dest='listen_host', - default=default_host, - help='Host address to listen on', - metavar='HOST', - ) - - parser.add_argument('--host-out', - dest='connect_to_host', - default=default_host, - help='Host address to connect to', - metavar='HOST', - ) - - parser.add_argument('--port-in', - dest='listen_port', - type=int, - default=default_port_in, - help='Port to listen on', - metavar='PORT', - ) - - parser.add_argument('--port-out', - dest='connect_to_port', - type=int, - default=default_port_out, - help='Port to connect to', - metavar='PORT', - ) - - parser.add_argument('--timeout', - dest='timeout', - type=int, default=default_timeout, - required=False, - help='Request timeout in seconds', - metavar='SECONDS', - ) - - parser.add_argument('--debug', - dest='debug', - action='store_true', default=default_debug, - help='Enable debug operation', - ) - - return parser.parse_args() - -class ProxyHandler(SocketServer.StreamRequestHandler): - """ - The RequestHandler class for our server. - - It is instantiated once per connection to the server, and must - override the handle() method to implement communication to the - client. - """ - - def __init__(self, *other_args, **kwargs): - self.timeout = args.timeout - - # Outgoing connection to the real server (pkcs11-daemon) - self.p11proxy = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.p11proxy.connect((args.connect_to_host, args.connect_to_port)) - - self.logger = logger - SocketServer.BaseRequestHandler.__init__(self, *other_args, **kwargs) - - def handle(self): - """ - Handle an incoming connection. Read requests/responses and decode them after passing - them on to the real pkcs11-proxy client/server. - """ - # self.request is the TCP socket connected to the client - try: - # 64 bits app id. Randomized on the client, and not really used in the server. - self.appid = self.request.recv(8) - self.p11proxy.send(self.appid) - - while True: - # Read request. First 32 bits are length. - length = self.request.recv(4) - if not length: - break - # Pass length to real server. - self.p11proxy.send(length) - self.logger.debug("\n\nRequest length is {}".format(length.encode('hex'))) - self._handle_request(struct.unpack('>L', length)[0]) - - # Read response. Again, first 32 bits are length. - length = self.p11proxy.recv(4) - # Pass length to client. - self.request.sendall(length) - self.logger.debug("\n\nAnswer length is {}".format(length.encode('hex'))) - self._handle_answer(struct.unpack('>L', length)[0]) - except Exception, e: - self.logger.exception("Got exception handling request from {}".format(self.client_address[0])) - return None - - def _handle_request(self, length): - """ - Given expected length, read the rest of a request, pass it on and decode whatever we can. - """ - self.logger.debug("Request({})".format(length)) - data = self.request.recv(length) - self.logger.debug(" R: {}".format(data.encode('hex'))) - self.p11proxy.send(data) - # parse request - (call_id, rest) = self._get_uint32(data) - if call_id > len(request_list): - return None - self.logger.debug(" R: call_id {}".format(call_id)) - rinfo = request_list[call_id] - self.logger.debug(" R: name {}".format(rinfo[1])) - fmt = rinfo[2] - if fmt: - self.logger.debug(" R: fmt {} ({})".format(fmt, fmt.encode('hex'))) - return self._parse_message('R', fmt, rest) - - def _handle_answer(self, length): - """ - Given expected length, read the rest of a response, pass it on and decode whatever we can. - """ - self.logger.debug("Answer({})".format(length)) - data = self.p11proxy.recv(length) - self.logger.debug(" A: {}".format(data.encode('hex'))) - self.request.sendall(data) - (call_id, rest) = self._get_uint32(data) - if call_id > len(request_list): - return None - # parse answer - (call_id, rest) = self._get_uint32(data) - if call_id > len(request_list): - return None - self.logger.debug(" A: call_id {}".format(call_id)) - rinfo = request_list[call_id] - self.logger.debug(" A: name {}".format(rinfo[1])) - if not call_id: - # This is ERROR - (ckr, _) = self._get_uint32(data[-4:]) - self.logger.debug(" A: {}".format(PyKCS11.CKR[ckr])) - fmt = rinfo[3] - if fmt: - self.logger.debug(" A: fmt {} ({})".format(fmt, fmt.encode('hex'))) - self._parse_message('A', fmt, rest) - - def _parse_message(self, msgtype, fmt, data): - """ - Parse the data in the request/response, which share format. - """ - # Check that the data is of the format we expect it to be. The format of every request/answer - # is redundantly included in the data sent over the network, although we already know what - # it should be. I guess this is a way to reduce the likeliness of undetected stream de-sync, - # because it would be wasteful if it was just used to make developers forget to update the - # handshake string when changing the format for a request/response. - (parsed_fmt, rest) = self._get_byte_array(data) - if parsed_fmt != fmt: - self.logger.error(" {}: Format mismatch, mine is {} and received is {}".format(msgtype, fmt, parsed_fmt)) - return None - self.logger.debug(" {}: format match".format(msgtype)) - try: - res = self._value_dump(msgtype, parsed_fmt, rest) - return res - except Exception: - self.logger.exception("Got exception trying to dump all data") - return [] - - def _value_dump(self, msgtype, fmt, data, res = []): - """ - Decode the data in a request/answer according to fmt. - - Will output the decoded data using self.logger.debug(). - """ - if not fmt: - if data: - self.logger.warning("{} bytes left after processing : {}".format(len(data), data.encode('hex'))) - return [] - #self.logger.debug("PARSING {} FROM {}".format(fmt[0], data.encode('hex'))) - if fmt[0] == 'u': - (this, rest) = self._get_uint64(data) - res.append(this) - self.logger.debug(" {}: uint64 {}".format(msgtype, hex(this))) - elif fmt[0] == 'a': - #self.logger.debug("PARSING {} FROM {}".format(fmt[0], data.encode('hex'))) - if fmt[1] == 'A': - valid = 1 - rest = data - else: - (valid, rest) = self._get_uint8(data) - self.logger.debug(" {}: Byte-Array valid : {}".format(msgtype, valid)) - array_num = 0 - (array_num, rest) = self._get_uint32(rest) - self.logger.debug(" {}: Byte-Array length : {}/{}".format(msgtype, array_num, hex(array_num))) - if array_num > 256: - raise Exception("Unreasonable array length : {}".format(hex(array_num))) - if not valid: - # /* If not valid, then just the length is encoded, this can signify CKR_BUFFER_TOO_SMALL */ - self.logger.debug(" {}: Array length {}/{}, not valid - maybe CKR_BUFFER_TOO_SMALL".format(msgtype, array_num, array_num)) - # array is now fully handled, remove next element of fmt - fmt = fmt[1:] - if rest: - self.logger.debug(" {}: CKR_BUFFER_TOO_SMALL leaving data {} ({} bytes) for fmt {}".format(msgtype, rest.encode('hex'), len(rest), fmt[1:])) - else: - if fmt[1] == 'y': - # simple byte array (i.e. string to us) - rest = struct.pack('>L', array_num) + rest # restore length before calling _get_byte_array - (this, rest) = self._get_byte_array(rest) - self.logger.debug(" {}: Byte-Array({}) {}".format(msgtype, len(this), repr(this))) - res.append(this) - fmt = fmt[1:] - else: - if array_num > 0: - # modify fmt to match the array length - placeholder = 'X' - array_elements = fmt[1] * (array_num - 1) - fmt_rest = fmt[1:] - fmt = placeholder + array_elements + fmt_rest - else: - # chomp the next fmt too - fmt = fmt[1:] - self.logger.debug(" {}: Array length {}, new fmt {}".format(msgtype, array_num, fmt)) - elif fmt[0] == 's': - (this, rest) = self._get_byte_array(data) - res.append(this) - self.logger.debug(" {}: string({}/{}) {}".format(msgtype, len(this), hex(len(this)), repr(this))) - elif fmt[0] == 'v': - # version, struct ck_version from pkcs11.h - (major, rest) = self._get_uint8(data) - (minor, rest) = self._get_uint8(rest) - self.logger.debug(" {}: CK_Version {}.{}".format(msgtype, major, minor)) - elif fmt[0] == 'y': - (this, rest) = self._get_uint8(data) - self.logger.debug(" {}: CK_Byte {}".format(msgtype, hex(this))) - elif fmt[0] == 'z': - # NULL-terminated string, len == -1 for empty string - (length, rest) = self._get_uint32(data) - if length == 0xffffffff: - res.append('') - else: - (this, rest) = self._get_byte_array(data) - res.append(this) - self.logger.debug(" {}: NULL-string({}/{}) {}".format(msgtype, len(this), hex(len(this)), repr(this))) - elif fmt[0] == 'M': - # Mechanism - #self.logger.debug("PARSING {} FROM {}".format(fmt[0], data.encode('hex'))) - (mech_type, rest) = self._get_uint32(data) - self.logger.debug(" {}: Mechanism {}/{}".format(msgtype, repr(mech_type), PyKCS11.CKM.get(mech_type))) - (this, rest) = self._get_byte_array(rest) - self.logger.debug(" {}: Mechanism parameter {}".format(msgtype, repr(this))) - res.append((mech_type, this)) - elif fmt[0] == 'A': - # Attribute - (this, rest) = self._get_attribute(data) - res.append(this) - #self.logger.debug(" {}: Attribute {}".format(msgtype, this)) - vl = "None" - if this['uValueLen'] is not None: - vl = hex(this['uValueLen']) - self.logger.debug(" {}: Attribute type {}/{}, valid {}, len {}, data {}".format(\ - msgtype, hex(this['type']), PyKCS11.CKA.get(this['type']), this['valid'], vl, this['data'].encode('hex'))) - elif fmt[0] == 'f': - # array buffer - if fmt[1] == 'y': - (flags, rest) = self._get_uint8(data) - else: - rest = data - (num_items, rest) = self._get_uint32(rest) - if fmt[1] == 'A': - self.logger.debug(" {}: Attribute buffer, {} elements".format(msgtype, hex(num_items))) - while num_items: - (attr_type, rest) = self._get_uint32(rest) - (buffer_len, rest) = self._get_uint32(rest) - self.logger.debug(" {}: type {}/{} len {}".format(msgtype, hex(attr_type), PyKCS11.CKA.get(attr_type), hex(buffer_len))) - res.append(('attribute buffer', attr_type, buffer_len)) - num_items -= 1 - elif fmt[1] == 'y': - self.logger.debug(" {}: Byte buffer, length {} (flags {})".format(msgtype, hex(num_items), flags)) - # just a number of bytes to alloc - pass - elif fmt[1] == 'u': - # ulong buffer, just an uint32 (?) - self.logger.debug("PARSING {} FROM {}".format(fmt[0], data.encode('hex'))) - (this, rest) = self._get_uint32(data) - self.logger.debug(" {}: ulong buffer {}".format(msgtype, hex(this))) - else: - raise Exception("Unknown array buffer fmt '{}'".format(fmt[1])) - # need to munch an extra fmt - fmt = fmt[1:] - else: - self.logger.warn(" {}: STOPPING at fmt {}, data {}".format(msgtype, fmt[0], data.encode('hex'))) - return [] - return self._value_dump(msgtype, fmt[1:], rest, res) - - def _get_uint64(self, data): - (a, rest) = self._get_uint32(data) - (b, rest) = self._get_uint32(rest) - return (a << 32 | b, data[8:]) - - def _get_uint32(self, data): - res = struct.unpack('>L', data[:4])[0] - return (res, data[4:]) - - def _get_uint8(self, data): - res = ord(data[0]) - return (res, data[1:]) - - def _get_byte_array(self, data): - (length, rest) = self._get_uint32(data) - if length == 0xffffffff: - return('', rest) - if length > len(rest): - raise Exception('Parse error, not enough bytes left for byte-array') - res = rest[:length] - return (res, rest[length:]) - - def _get_attribute(self, data): - attr = {} - (attr_type, rest) = self._get_uint32(data) - (attr_valid, rest) = self._get_uint8(rest) - attr_vallen = None - data = '' - if attr_valid: - (attr_vallen, rest) = self._get_uint32(rest) - # length doubly included, in byte array again? - (data, rest) = self._get_byte_array(rest) - # read data here! - attr['type'] = attr_type - attr['valid'] = attr_valid - attr['uValueLen'] = attr_vallen - attr['data'] = data - return (attr, rest) - -def main(): - global args - args = parse_args() - - level = logging.INFO - if args.debug: - level = logging.DEBUG - logging.basicConfig(level=level) - global logger - logger = logging.getLogger('p11proxy-mitm') - - # Create the server - server = SocketServer.TCPServer((args.listen_host, args.listen_port), \ - ProxyHandler, \ - bind_and_activate=False, \ - ) - server.allow_reuse_address = True - server.timeout = args.timeout - server.server_bind() # Manually bind, to support allow_reuse_address - server.server_activate() # (see above comment) - - # Activate the server; this will keep running until you - # interrupt the program with Ctrl-C - server.serve_forever() - -if __name__ == '__main__': - try: - if main(): - sys.exit(0) - sys.exit(1) - except KeyboardInterrupt: - pass diff --git a/ext/pkcs11-proxy/pkcs11-daemon b/ext/pkcs11-proxy/pkcs11-daemon deleted file mode 100755 index 1efabee7e..000000000 Binary files a/ext/pkcs11-proxy/pkcs11-daemon and /dev/null differ diff --git a/ext/pkcs11-proxy/pkcs11/pkcs11.h b/ext/pkcs11-proxy/pkcs11/pkcs11.h deleted file mode 100644 index 6899788a4..000000000 --- a/ext/pkcs11-proxy/pkcs11/pkcs11.h +++ /dev/null @@ -1,1312 +0,0 @@ -/* pkcs11.h - Copyright 2006, 2007 g10 Code GmbH - Copyright 2006 Andreas Jellinghaus - - This file is free software; as a special exception the author gives - unlimited permission to copy and/or distribute it, with or without - modifications, as long as this notice is preserved. - - This file is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY, to the extent permitted by law; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. */ - -/* Please submit changes back to the Scute project at - http://www.scute.org/ (or send them to marcus@g10code.com), so that - they can be picked up by other projects from there as well. */ - -/* This file is a modified implementation of the PKCS #11 standard by - RSA Security Inc. It is mostly a drop-in replacement, with the - following change: - - This header file does not require any macro definitions by the user - (like CK_DEFINE_FUNCTION etc). In fact, it defines those macros - for you (if useful, some are missing, let me know if you need - more). - - There is an additional API available that does comply better to the - GNU coding standard. It can be switched on by defining - CRYPTOKI_GNU before including this header file. For this, the - following changes are made to the specification: - - All structure types are changed to a "struct ck_foo" where CK_FOO - is the type name in PKCS #11. - - All non-structure types are changed to ck_foo_t where CK_FOO is the - lowercase version of the type name in PKCS #11. The basic types - (CK_ULONG et al.) are removed without substitute. - - All members of structures are modified in the following way: Type - indication prefixes are removed, and underscore characters are - inserted before words. Then the result is lowercased. - - Note that function names are still in the original case, as they - need for ABI compatibility. - - CK_FALSE, CK_TRUE and NULL_PTR are removed without substitute. Use - . - - If CRYPTOKI_COMPAT is defined before including this header file, - then none of the API changes above take place, and the API is the - one defined by the PKCS #11 standard. */ - -#ifndef PKCS11_H -#define PKCS11_H 1 - -#if defined(__cplusplus) -extern "C" { -#endif - -/* The version of cryptoki we implement. The revision is changed with - each modification of this file. If you do not use the "official" - version of this file, please consider deleting the revision macro - (you may use a macro with a different name to keep track of your - versions). */ -#define CRYPTOKI_VERSION_MAJOR 2 -#define CRYPTOKI_VERSION_MINOR 20 -#define CRYPTOKI_VERSION_REVISION 6 - -/* Compatibility interface is default, unless CRYPTOKI_GNU is - given. */ -#ifndef CRYPTOKI_GNU -#ifndef CRYPTOKI_COMPAT -#define CRYPTOKI_COMPAT 1 -#endif -#endif - -/* System dependencies. */ - -#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) - -/* There is a matching pop below. */ -#pragma pack(push, cryptoki, 1) - -#ifdef CRYPTOKI_EXPORTS -#define CK_SPEC __declspec(dllexport) -#else -#define CK_SPEC __declspec(dllimport) -#endif - -#else - -#define CK_SPEC - -#endif - -#ifdef CRYPTOKI_COMPAT - /* If we are in compatibility mode, switch all exposed names to the - PKCS #11 variant. There are corresponding #undefs below. */ - -#define ck_flags_t CK_FLAGS -#define ck_version _CK_VERSION - -#define ck_info _CK_INFO -#define cryptoki_version cryptokiVersion -#define manufacturer_id manufacturerID -#define library_description libraryDescription -#define library_version libraryVersion - -#define ck_notification_t CK_NOTIFICATION -#define ck_slot_id_t CK_SLOT_ID - -#define ck_slot_info _CK_SLOT_INFO -#define slot_description slotDescription -#define hardware_version hardwareVersion -#define firmware_version firmwareVersion - -#define ck_token_info _CK_TOKEN_INFO -#define serial_number serialNumber -#define max_session_count ulMaxSessionCount -#define session_count ulSessionCount -#define max_rw_session_count ulMaxRwSessionCount -#define rw_session_count ulRwSessionCount -#define max_pin_len ulMaxPinLen -#define min_pin_len ulMinPinLen -#define total_public_memory ulTotalPublicMemory -#define free_public_memory ulFreePublicMemory -#define total_private_memory ulTotalPrivateMemory -#define free_private_memory ulFreePrivateMemory -#define utc_time utcTime - -#define ck_session_handle_t CK_SESSION_HANDLE -#define ck_user_type_t CK_USER_TYPE -#define ck_state_t CK_STATE - -#define ck_session_info _CK_SESSION_INFO -#define slot_id slotID -#define device_error ulDeviceError - -#define ck_object_handle_t CK_OBJECT_HANDLE -#define ck_object_class_t CK_OBJECT_CLASS -#define ck_hw_feature_type_t CK_HW_FEATURE_TYPE -#define ck_key_type_t CK_KEY_TYPE -#define ck_certificate_type_t CK_CERTIFICATE_TYPE -#define ck_attribute_type_t CK_ATTRIBUTE_TYPE - -#define ck_attribute _CK_ATTRIBUTE -#define value pValue -#define value_len ulValueLen - -#define ck_date _CK_DATE - -#define ck_mechanism_type_t CK_MECHANISM_TYPE - -#define ck_mechanism _CK_MECHANISM -#define parameter pParameter -#define parameter_len ulParameterLen - -#define ck_mechanism_info _CK_MECHANISM_INFO -#define min_key_size ulMinKeySize -#define max_key_size ulMaxKeySize - -#define ck_rv_t CK_RV -#define ck_notify_t CK_NOTIFY - -#define ck_function_list _CK_FUNCTION_LIST - -#define ck_createmutex_t CK_CREATEMUTEX -#define ck_destroymutex_t CK_DESTROYMUTEX -#define ck_lockmutex_t CK_LOCKMUTEX -#define ck_unlockmutex_t CK_UNLOCKMUTEX - -#define ck_c_initialize_args _CK_C_INITIALIZE_ARGS -#define create_mutex CreateMutex -#define destroy_mutex DestroyMutex -#define lock_mutex LockMutex -#define unlock_mutex UnlockMutex -#define reserved pReserved - -#endif /* CRYPTOKI_COMPAT */ - - typedef unsigned long ck_flags_t; - - struct ck_version { - unsigned char major; - unsigned char minor; - }; - - struct ck_info { - struct ck_version cryptoki_version; - unsigned char manufacturer_id[32]; - ck_flags_t flags; - unsigned char library_description[32]; - struct ck_version library_version; - }; - - typedef unsigned long ck_notification_t; - -#define CKN_SURRENDER (0UL) - - typedef unsigned long ck_slot_id_t; - - struct ck_slot_info { - unsigned char slot_description[64]; - unsigned char manufacturer_id[32]; - ck_flags_t flags; - struct ck_version hardware_version; - struct ck_version firmware_version; - }; - -#define CKF_TOKEN_PRESENT (1UL << 0) -#define CKF_REMOVABLE_DEVICE (1UL << 1) -#define CKF_HW_SLOT (1UL << 2) -#define CKF_ARRAY_ATTRIBUTE (1UL << 30) - - struct ck_token_info { - unsigned char label[32]; - unsigned char manufacturer_id[32]; - unsigned char model[16]; - unsigned char serial_number[16]; - ck_flags_t flags; - unsigned long max_session_count; - unsigned long session_count; - unsigned long max_rw_session_count; - unsigned long rw_session_count; - unsigned long max_pin_len; - unsigned long min_pin_len; - unsigned long total_public_memory; - unsigned long free_public_memory; - unsigned long total_private_memory; - unsigned long free_private_memory; - struct ck_version hardware_version; - struct ck_version firmware_version; - unsigned char utc_time[16]; - }; - -#define CKF_RNG (1UL << 0) -#define CKF_WRITE_PROTECTED (1UL << 1) -#define CKF_LOGIN_REQUIRED (1UL << 2) -#define CKF_USER_PIN_INITIALIZED (1UL << 3) -#define CKF_RESTORE_KEY_NOT_NEEDED (1UL << 5) -#define CKF_CLOCK_ON_TOKEN (1UL << 6) -#define CKF_PROTECTED_AUTHENTICATION_PATH (1UL << 8) -#define CKF_DUAL_CRYPTO_OPERATIONS (1UL << 9) -#define CKF_TOKEN_INITIALIZED (1UL << 10) -#define CKF_SECONDARY_AUTHENTICATION (1UL << 11) -#define CKF_USER_PIN_COUNT_LOW (1UL << 16) -#define CKF_USER_PIN_FINAL_TRY (1UL << 17) -#define CKF_USER_PIN_LOCKED (1UL << 18) -#define CKF_USER_PIN_TO_BE_CHANGED (1UL << 19) -#define CKF_SO_PIN_COUNT_LOW (1UL << 20) -#define CKF_SO_PIN_FINAL_TRY (1UL << 21) -#define CKF_SO_PIN_LOCKED (1UL << 22) -#define CKF_SO_PIN_TO_BE_CHANGED (1UL << 23) - -#define CK_UNAVAILABLE_INFORMATION ((unsigned long)-1L) -#define CK_EFFECTIVELY_INFINITE (0UL) - - typedef unsigned long ck_session_handle_t; - -#define CK_INVALID_HANDLE (0UL) - - typedef unsigned long ck_user_type_t; - -#define CKU_SO (0UL) -#define CKU_USER (1UL) -#define CKU_CONTEXT_SPECIFIC (2UL) - - typedef unsigned long ck_state_t; - -#define CKS_RO_PUBLIC_SESSION (0UL) -#define CKS_RO_USER_FUNCTIONS (1UL) -#define CKS_RW_PUBLIC_SESSION (2UL) -#define CKS_RW_USER_FUNCTIONS (3UL) -#define CKS_RW_SO_FUNCTIONS (4UL) - - struct ck_session_info { - ck_slot_id_t slot_id; - ck_state_t state; - ck_flags_t flags; - unsigned long device_error; - }; - -#define CKF_RW_SESSION (1UL << 1) -#define CKF_SERIAL_SESSION (1UL << 2) - - typedef unsigned long ck_object_handle_t; - - typedef unsigned long ck_object_class_t; - -#define CKO_DATA (0UL) -#define CKO_CERTIFICATE (1UL) -#define CKO_PUBLIC_KEY (2UL) -#define CKO_PRIVATE_KEY (3UL) -#define CKO_SECRET_KEY (4UL) -#define CKO_HW_FEATURE (5UL) -#define CKO_DOMAIN_PARAMETERS (6UL) -#define CKO_MECHANISM (7UL) -#define CKO_VENDOR_DEFINED ((unsigned long) (1UL << 31)) - - typedef unsigned long ck_hw_feature_type_t; - -#define CKH_MONOTONIC_COUNTER (1UL) -#define CKH_CLOCK (2UL) -#define CKH_USER_INTERFACE (3UL) -#define CKH_VENDOR_DEFINED ((unsigned long) (1UL << 31)) - - typedef unsigned long ck_key_type_t; - -#define CKK_RSA (0UL) -#define CKK_DSA (1UL) -#define CKK_DH (2UL) -#define CKK_ECDSA (3UL) -#define CKK_EC (3UL) -#define CKK_X9_42_DH (4UL) -#define CKK_KEA (5UL) -#define CKK_GENERIC_SECRET (0x10UL) -#define CKK_RC2 (0x11UL) -#define CKK_RC4 (0x12UL) -#define CKK_DES (0x13UL) -#define CKK_DES2 (0x14UL) -#define CKK_DES3 (0x15UL) -#define CKK_CAST (0x16UL) -#define CKK_CAST3 (0x17UL) -#define CKK_CAST128 (0x18UL) -#define CKK_RC5 (0x19UL) -#define CKK_IDEA (0x1aUL) -#define CKK_SKIPJACK (0x1bUL) -#define CKK_BATON (0x1cUL) -#define CKK_JUNIPER (0x1dUL) -#define CKK_CDMF (0x1eUL) -#define CKK_AES (0x1fUL) -#define CKK_BLOWFISH (0x20UL) -#define CKK_TWOFISH (0x21UL) -#define CKK_VENDOR_DEFINED ((unsigned long) (1UL << 31)) - - typedef unsigned long ck_certificate_type_t; - -#define CKC_X_509 (0UL) -#define CKC_X_509_ATTR_CERT (1UL) -#define CKC_WTLS (2UL) -#define CKC_VENDOR_DEFINED ((unsigned long) (1UL << 31)) - - typedef unsigned long ck_attribute_type_t; - -#define CKA_CLASS (0UL) -#define CKA_TOKEN (1UL) -#define CKA_PRIVATE (2UL) -#define CKA_LABEL (3UL) -#define CKA_APPLICATION (0x10UL) -#define CKA_VALUE (0x11UL) -#define CKA_OBJECT_ID (0x12UL) -#define CKA_CERTIFICATE_TYPE (0x80UL) -#define CKA_ISSUER (0x81UL) -#define CKA_SERIAL_NUMBER (0x82UL) -#define CKA_AC_ISSUER (0x83UL) -#define CKA_OWNER (0x84UL) -#define CKA_ATTR_TYPES (0x85UL) -#define CKA_TRUSTED (0x86UL) -#define CKA_CERTIFICATE_CATEGORY (0x87UL) -#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88UL) -#define CKA_URL (0x89UL) -#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8aUL) -#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8bUL) -#define CKA_CHECK_VALUE (0x90UL) -#define CKA_KEY_TYPE (0x100UL) -#define CKA_SUBJECT (0x101UL) -#define CKA_ID (0x102UL) -#define CKA_SENSITIVE (0x103UL) -#define CKA_ENCRYPT (0x104UL) -#define CKA_DECRYPT (0x105UL) -#define CKA_WRAP (0x106UL) -#define CKA_UNWRAP (0x107UL) -#define CKA_SIGN (0x108UL) -#define CKA_SIGN_RECOVER (0x109UL) -#define CKA_VERIFY (0x10aUL) -#define CKA_VERIFY_RECOVER (0x10bUL) -#define CKA_DERIVE (0x10cUL) -#define CKA_START_DATE (0x110UL) -#define CKA_END_DATE (0x111UL) -#define CKA_MODULUS (0x120UL) -#define CKA_MODULUS_BITS (0x121UL) -#define CKA_PUBLIC_EXPONENT (0x122UL) -#define CKA_PRIVATE_EXPONENT (0x123UL) -#define CKA_PRIME_1 (0x124UL) -#define CKA_PRIME_2 (0x125UL) -#define CKA_EXPONENT_1 (0x126UL) -#define CKA_EXPONENT_2 (0x127UL) -#define CKA_COEFFICIENT (0x128UL) -#define CKA_PRIME (0x130UL) -#define CKA_SUBPRIME (0x131UL) -#define CKA_BASE (0x132UL) -#define CKA_PRIME_BITS (0x133UL) -#define CKA_SUB_PRIME_BITS (0x134UL) -#define CKA_VALUE_BITS (0x160UL) -#define CKA_VALUE_LEN (0x161UL) -#define CKA_EXTRACTABLE (0x162UL) -#define CKA_LOCAL (0x163UL) -#define CKA_NEVER_EXTRACTABLE (0x164UL) -#define CKA_ALWAYS_SENSITIVE (0x165UL) -#define CKA_KEY_GEN_MECHANISM (0x166UL) -#define CKA_MODIFIABLE (0x170UL) -#define CKA_ECDSA_PARAMS (0x180UL) -#define CKA_EC_PARAMS (0x180UL) -#define CKA_EC_POINT (0x181UL) -#define CKA_SECONDARY_AUTH (0x200UL) -#define CKA_AUTH_PIN_FLAGS (0x201UL) -#define CKA_ALWAYS_AUTHENTICATE (0x202UL) -#define CKA_WRAP_WITH_TRUSTED (0x210UL) -#define CKA_HW_FEATURE_TYPE (0x300UL) -#define CKA_RESET_ON_INIT (0x301UL) -#define CKA_HAS_RESET (0x302UL) -#define CKA_PIXEL_X (0x400UL) -#define CKA_PIXEL_Y (0x401UL) -#define CKA_RESOLUTION (0x402UL) -#define CKA_CHAR_ROWS (0x403UL) -#define CKA_CHAR_COLUMNS (0x404UL) -#define CKA_COLOR (0x405UL) -#define CKA_BITS_PER_PIXEL (0x406UL) -#define CKA_CHAR_SETS (0x480UL) -#define CKA_ENCODING_METHODS (0x481UL) -#define CKA_MIME_TYPES (0x482UL) -#define CKA_MECHANISM_TYPE (0x500UL) -#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501UL) -#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502UL) -#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503UL) -#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211UL) -#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212UL) -#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600UL) -#define CKA_VENDOR_DEFINED ((unsigned long) (1UL << 31)) - - struct ck_attribute { - ck_attribute_type_t type; - void *value; - unsigned long value_len; - }; - - struct ck_date { - unsigned char year[4]; - unsigned char month[2]; - unsigned char day[2]; - }; - - typedef unsigned long ck_mechanism_type_t; - -#define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL) -#define CKM_RSA_PKCS (1UL) -#define CKM_RSA_9796 (2UL) -#define CKM_RSA_X_509 (3UL) -#define CKM_MD2_RSA_PKCS (4UL) -#define CKM_MD5_RSA_PKCS (5UL) -#define CKM_SHA1_RSA_PKCS (6UL) -#define CKM_RIPEMD128_RSA_PKCS (7UL) -#define CKM_RIPEMD160_RSA_PKCS (8UL) -#define CKM_RSA_PKCS_OAEP (9UL) -#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xaUL) -#define CKM_RSA_X9_31 (0xbUL) -#define CKM_SHA1_RSA_X9_31 (0xcUL) -#define CKM_RSA_PKCS_PSS (0xdUL) -#define CKM_SHA1_RSA_PKCS_PSS (0xeUL) -#define CKM_DSA_KEY_PAIR_GEN (0x10UL) -#define CKM_DSA (0x11UL) -#define CKM_DSA_SHA1 (0x12UL) -#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20UL) -#define CKM_DH_PKCS_DERIVE (0x21UL) -#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30UL) -#define CKM_X9_42_DH_DERIVE (0x31UL) -#define CKM_X9_42_DH_HYBRID_DERIVE (0x32UL) -#define CKM_X9_42_MQV_DERIVE (0x33UL) -#define CKM_SHA256_RSA_PKCS (0x40UL) -#define CKM_SHA384_RSA_PKCS (0x41UL) -#define CKM_SHA512_RSA_PKCS (0x42UL) -#define CKM_SHA256_RSA_PKCS_PSS (0x43UL) -#define CKM_SHA384_RSA_PKCS_PSS (0x44UL) -#define CKM_SHA512_RSA_PKCS_PSS (0x45UL) -#define CKM_RC2_KEY_GEN (0x100UL) -#define CKM_RC2_ECB (0x101UL) -#define CKM_RC2_CBC (0x102UL) -#define CKM_RC2_MAC (0x103UL) -#define CKM_RC2_MAC_GENERAL (0x104UL) -#define CKM_RC2_CBC_PAD (0x105UL) -#define CKM_RC4_KEY_GEN (0x110UL) -#define CKM_RC4 (0x111UL) -#define CKM_DES_KEY_GEN (0x120UL) -#define CKM_DES_ECB (0x121UL) -#define CKM_DES_CBC (0x122UL) -#define CKM_DES_MAC (0x123UL) -#define CKM_DES_MAC_GENERAL (0x124UL) -#define CKM_DES_CBC_PAD (0x125UL) -#define CKM_DES2_KEY_GEN (0x130UL) -#define CKM_DES3_KEY_GEN (0x131UL) -#define CKM_DES3_ECB (0x132UL) -#define CKM_DES3_CBC (0x133UL) -#define CKM_DES3_MAC (0x134UL) -#define CKM_DES3_MAC_GENERAL (0x135UL) -#define CKM_DES3_CBC_PAD (0x136UL) -#define CKM_CDMF_KEY_GEN (0x140UL) -#define CKM_CDMF_ECB (0x141UL) -#define CKM_CDMF_CBC (0x142UL) -#define CKM_CDMF_MAC (0x143UL) -#define CKM_CDMF_MAC_GENERAL (0x144UL) -#define CKM_CDMF_CBC_PAD (0x145UL) -#define CKM_MD2 (0x200UL) -#define CKM_MD2_HMAC (0x201UL) -#define CKM_MD2_HMAC_GENERAL (0x202UL) -#define CKM_MD5 (0x210UL) -#define CKM_MD5_HMAC (0x211UL) -#define CKM_MD5_HMAC_GENERAL (0x212UL) -#define CKM_SHA_1 (0x220UL) -#define CKM_SHA_1_HMAC (0x221UL) -#define CKM_SHA_1_HMAC_GENERAL (0x222UL) -#define CKM_RIPEMD128 (0x230UL) -#define CKM_RIPEMD128_HMAC (0x231UL) -#define CKM_RIPEMD128_HMAC_GENERAL (0x232UL) -#define CKM_RIPEMD160 (0x240UL) -#define CKM_RIPEMD160_HMAC (0x241UL) -#define CKM_RIPEMD160_HMAC_GENERAL (0x242UL) -#define CKM_SHA256 (0x250UL) -#define CKM_SHA256_HMAC (0x251UL) -#define CKM_SHA256_HMAC_GENERAL (0x252UL) -#define CKM_SHA384 (0x260UL) -#define CKM_SHA384_HMAC (0x261UL) -#define CKM_SHA384_HMAC_GENERAL (0x262UL) -#define CKM_SHA512 (0x270UL) -#define CKM_SHA512_HMAC (0x271UL) -#define CKM_SHA512_HMAC_GENERAL (0x272UL) -#define CKM_CAST_KEY_GEN (0x300UL) -#define CKM_CAST_ECB (0x301UL) -#define CKM_CAST_CBC (0x302UL) -#define CKM_CAST_MAC (0x303UL) -#define CKM_CAST_MAC_GENERAL (0x304UL) -#define CKM_CAST_CBC_PAD (0x305UL) -#define CKM_CAST3_KEY_GEN (0x310UL) -#define CKM_CAST3_ECB (0x311UL) -#define CKM_CAST3_CBC (0x312UL) -#define CKM_CAST3_MAC (0x313UL) -#define CKM_CAST3_MAC_GENERAL (0x314UL) -#define CKM_CAST3_CBC_PAD (0x315UL) -#define CKM_CAST5_KEY_GEN (0x320UL) -#define CKM_CAST128_KEY_GEN (0x320UL) -#define CKM_CAST5_ECB (0x321UL) -#define CKM_CAST128_ECB (0x321UL) -#define CKM_CAST5_CBC (0x322UL) -#define CKM_CAST128_CBC (0x322UL) -#define CKM_CAST5_MAC (0x323UL) -#define CKM_CAST128_MAC (0x323UL) -#define CKM_CAST5_MAC_GENERAL (0x324UL) -#define CKM_CAST128_MAC_GENERAL (0x324UL) -#define CKM_CAST5_CBC_PAD (0x325UL) -#define CKM_CAST128_CBC_PAD (0x325UL) -#define CKM_RC5_KEY_GEN (0x330UL) -#define CKM_RC5_ECB (0x331UL) -#define CKM_RC5_CBC (0x332UL) -#define CKM_RC5_MAC (0x333UL) -#define CKM_RC5_MAC_GENERAL (0x334UL) -#define CKM_RC5_CBC_PAD (0x335UL) -#define CKM_IDEA_KEY_GEN (0x340UL) -#define CKM_IDEA_ECB (0x341UL) -#define CKM_IDEA_CBC (0x342UL) -#define CKM_IDEA_MAC (0x343UL) -#define CKM_IDEA_MAC_GENERAL (0x344UL) -#define CKM_IDEA_CBC_PAD (0x345UL) -#define CKM_GENERIC_SECRET_KEY_GEN (0x350UL) -#define CKM_CONCATENATE_BASE_AND_KEY (0x360UL) -#define CKM_CONCATENATE_BASE_AND_DATA (0x362UL) -#define CKM_CONCATENATE_DATA_AND_BASE (0x363UL) -#define CKM_XOR_BASE_AND_DATA (0x364UL) -#define CKM_EXTRACT_KEY_FROM_KEY (0x365UL) -#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370UL) -#define CKM_SSL3_MASTER_KEY_DERIVE (0x371UL) -#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372UL) -#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373UL) -#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374UL) -#define CKM_TLS_MASTER_KEY_DERIVE (0x375UL) -#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376UL) -#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377UL) -#define CKM_SSL3_MD5_MAC (0x380UL) -#define CKM_SSL3_SHA1_MAC (0x381UL) -#define CKM_MD5_KEY_DERIVATION (0x390UL) -#define CKM_MD2_KEY_DERIVATION (0x391UL) -#define CKM_SHA1_KEY_DERIVATION (0x392UL) -#define CKM_PBE_MD2_DES_CBC (0x3a0UL) -#define CKM_PBE_MD5_DES_CBC (0x3a1UL) -#define CKM_PBE_MD5_CAST_CBC (0x3a2UL) -#define CKM_PBE_MD5_CAST3_CBC (0x3a3UL) -#define CKM_PBE_MD5_CAST5_CBC (0x3a4UL) -#define CKM_PBE_MD5_CAST128_CBC (0x3a4UL) -#define CKM_PBE_SHA1_CAST5_CBC (0x3a5UL) -#define CKM_PBE_SHA1_CAST128_CBC (0x3a5UL) -#define CKM_PBE_SHA1_RC4_128 (0x3a6UL) -#define CKM_PBE_SHA1_RC4_40 (0x3a7UL) -#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8UL) -#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9UL) -#define CKM_PBE_SHA1_RC2_128_CBC (0x3aaUL) -#define CKM_PBE_SHA1_RC2_40_CBC (0x3abUL) -#define CKM_PKCS5_PBKD2 (0x3b0UL) -#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0UL) -#define CKM_KEY_WRAP_LYNKS (0x400UL) -#define CKM_KEY_WRAP_SET_OAEP (0x401UL) -#define CKM_SKIPJACK_KEY_GEN (0x1000UL) -#define CKM_SKIPJACK_ECB64 (0x1001UL) -#define CKM_SKIPJACK_CBC64 (0x1002UL) -#define CKM_SKIPJACK_OFB64 (0x1003UL) -#define CKM_SKIPJACK_CFB64 (0x1004UL) -#define CKM_SKIPJACK_CFB32 (0x1005UL) -#define CKM_SKIPJACK_CFB16 (0x1006UL) -#define CKM_SKIPJACK_CFB8 (0x1007UL) -#define CKM_SKIPJACK_WRAP (0x1008UL) -#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009UL) -#define CKM_SKIPJACK_RELAYX (0x100aUL) -#define CKM_KEA_KEY_PAIR_GEN (0x1010UL) -#define CKM_KEA_KEY_DERIVE (0x1011UL) -#define CKM_FORTEZZA_TIMESTAMP (0x1020UL) -#define CKM_BATON_KEY_GEN (0x1030UL) -#define CKM_BATON_ECB128 (0x1031UL) -#define CKM_BATON_ECB96 (0x1032UL) -#define CKM_BATON_CBC128 (0x1033UL) -#define CKM_BATON_COUNTER (0x1034UL) -#define CKM_BATON_SHUFFLE (0x1035UL) -#define CKM_BATON_WRAP (0x1036UL) -#define CKM_ECDSA_KEY_PAIR_GEN (0x1040UL) -#define CKM_EC_KEY_PAIR_GEN (0x1040UL) -#define CKM_ECDSA (0x1041UL) -#define CKM_ECDSA_SHA1 (0x1042UL) -#define CKM_ECDH1_DERIVE (0x1050UL) -#define CKM_ECDH1_COFACTOR_DERIVE (0x1051UL) -#define CKM_ECMQV_DERIVE (0x1052UL) -#define CKM_JUNIPER_KEY_GEN (0x1060UL) -#define CKM_JUNIPER_ECB128 (0x1061UL) -#define CKM_JUNIPER_CBC128 (0x1062UL) -#define CKM_JUNIPER_COUNTER (0x1063UL) -#define CKM_JUNIPER_SHUFFLE (0x1064UL) -#define CKM_JUNIPER_WRAP (0x1065UL) -#define CKM_FASTHASH (0x1070UL) -#define CKM_AES_KEY_GEN (0x1080UL) -#define CKM_AES_ECB (0x1081UL) -#define CKM_AES_CBC (0x1082UL) -#define CKM_AES_MAC (0x1083UL) -#define CKM_AES_MAC_GENERAL (0x1084UL) -#define CKM_AES_CBC_PAD (0x1085UL) -#define CKM_DSA_PARAMETER_GEN (0x2000UL) -#define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL) -#define CKM_X9_42_DH_PARAMETER_GEN (0x2002UL) -#define CKM_VENDOR_DEFINED ((unsigned long) (1UL << 31)) - - struct ck_mechanism { - ck_mechanism_type_t mechanism; - void *parameter; - unsigned long parameter_len; - }; - - struct ck_mechanism_info { - unsigned long min_key_size; - unsigned long max_key_size; - ck_flags_t flags; - }; - -#define CKF_HW (1UL << 0) -#define CKF_ENCRYPT (1UL << 8) -#define CKF_DECRYPT (1UL << 9) -#define CKF_DIGEST (1UL << 10) -#define CKF_SIGN (1UL << 11) -#define CKF_SIGN_RECOVER (1UL << 12) -#define CKF_VERIFY (1UL << 13) -#define CKF_VERIFY_RECOVER (1UL << 14) -#define CKF_GENERATE (1UL << 15) -#define CKF_GENERATE_KEY_PAIR (1UL << 16) -#define CKF_WRAP (1UL << 17) -#define CKF_UNWRAP (1UL << 18) -#define CKF_DERIVE (1UL << 19) -#define CKF_EXTENSION ((unsigned long) (1UL << 31)) - -/* Flags for C_WaitForSlotEvent. */ -#define CKF_DONT_BLOCK (1UL) - - typedef unsigned long ck_rv_t; - - typedef ck_rv_t(*ck_notify_t) (ck_session_handle_t session, - ck_notification_t event, - void *application); - -/* Forward reference. */ - struct ck_function_list; - -#define _CK_DECLARE_FUNCTION(name, args) \ -typedef ck_rv_t (*CK_ ## name) args; \ -ck_rv_t CK_SPEC name args - - _CK_DECLARE_FUNCTION(C_Initialize, (void *init_args)); - _CK_DECLARE_FUNCTION(C_Finalize, (void *reserved)); - _CK_DECLARE_FUNCTION(C_GetInfo, (struct ck_info * info)); - _CK_DECLARE_FUNCTION(C_GetFunctionList, - (struct ck_function_list ** function_list)); - - _CK_DECLARE_FUNCTION(C_GetSlotList, - (unsigned char token_present, - ck_slot_id_t * slot_list, unsigned long *count)); - _CK_DECLARE_FUNCTION(C_GetSlotInfo, - (ck_slot_id_t slot_id, - struct ck_slot_info * info)); - _CK_DECLARE_FUNCTION(C_GetTokenInfo, - (ck_slot_id_t slot_id, - struct ck_token_info * info)); - _CK_DECLARE_FUNCTION(C_WaitForSlotEvent, - (ck_flags_t flags, ck_slot_id_t * slot, - void *reserved)); - _CK_DECLARE_FUNCTION(C_GetMechanismList, - (ck_slot_id_t slot_id, - ck_mechanism_type_t * mechanism_list, - unsigned long *count)); - _CK_DECLARE_FUNCTION(C_GetMechanismInfo, - (ck_slot_id_t slot_id, ck_mechanism_type_t type, - struct ck_mechanism_info * info)); - _CK_DECLARE_FUNCTION(C_InitToken, - (ck_slot_id_t slot_id, unsigned char *pin, - unsigned long pin_len, unsigned char *label)); - _CK_DECLARE_FUNCTION(C_InitPIN, - (ck_session_handle_t session, unsigned char *pin, - unsigned long pin_len)); - _CK_DECLARE_FUNCTION(C_SetPIN, - (ck_session_handle_t session, - unsigned char *old_pin, unsigned long old_len, - unsigned char *new_pin, unsigned long new_len)); - - _CK_DECLARE_FUNCTION(C_OpenSession, - (ck_slot_id_t slot_id, ck_flags_t flags, - void *application, ck_notify_t notify, - ck_session_handle_t * session)); - _CK_DECLARE_FUNCTION(C_CloseSession, (ck_session_handle_t session)); - _CK_DECLARE_FUNCTION(C_CloseAllSessions, (ck_slot_id_t slot_id)); - _CK_DECLARE_FUNCTION(C_GetSessionInfo, - (ck_session_handle_t session, - struct ck_session_info * info)); - _CK_DECLARE_FUNCTION(C_GetOperationState, - (ck_session_handle_t session, - unsigned char *operation_state, - unsigned long *operation_state_len)); - _CK_DECLARE_FUNCTION(C_SetOperationState, - (ck_session_handle_t session, - unsigned char *operation_state, - unsigned long operation_state_len, - ck_object_handle_t encryption_key, - ck_object_handle_t authentiation_key)); - _CK_DECLARE_FUNCTION(C_Login, - (ck_session_handle_t session, - ck_user_type_t user_type, unsigned char *pin, - unsigned long pin_len)); - _CK_DECLARE_FUNCTION(C_Logout, (ck_session_handle_t session)); - - _CK_DECLARE_FUNCTION(C_CreateObject, - (ck_session_handle_t session, - struct ck_attribute * templ, - unsigned long count, - ck_object_handle_t * object)); - _CK_DECLARE_FUNCTION(C_CopyObject, - (ck_session_handle_t session, - ck_object_handle_t object, - struct ck_attribute * templ, unsigned long count, - ck_object_handle_t * new_object)); - _CK_DECLARE_FUNCTION(C_DestroyObject, - (ck_session_handle_t session, - ck_object_handle_t object)); - _CK_DECLARE_FUNCTION(C_GetObjectSize, - (ck_session_handle_t session, - ck_object_handle_t object, unsigned long *size)); - _CK_DECLARE_FUNCTION(C_GetAttributeValue, - (ck_session_handle_t session, - ck_object_handle_t object, - struct ck_attribute * templ, - unsigned long count)); - _CK_DECLARE_FUNCTION(C_SetAttributeValue, - (ck_session_handle_t session, - ck_object_handle_t object, - struct ck_attribute * templ, - unsigned long count)); - _CK_DECLARE_FUNCTION(C_FindObjectsInit, - (ck_session_handle_t session, - struct ck_attribute * templ, - unsigned long count)); - _CK_DECLARE_FUNCTION(C_FindObjects, - (ck_session_handle_t session, - ck_object_handle_t * object, - unsigned long max_object_count, - unsigned long *object_count)); - _CK_DECLARE_FUNCTION(C_FindObjectsFinal, - (ck_session_handle_t session)); - - _CK_DECLARE_FUNCTION(C_EncryptInit, - (ck_session_handle_t session, - struct ck_mechanism * mechanism, - ck_object_handle_t key)); - _CK_DECLARE_FUNCTION(C_Encrypt, - (ck_session_handle_t session, - unsigned char *data, unsigned long data_len, - unsigned char *encrypted_data, - unsigned long *encrypted_data_len)); - _CK_DECLARE_FUNCTION(C_EncryptUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len, - unsigned char *encrypted_part, - unsigned long *encrypted_part_len)); - _CK_DECLARE_FUNCTION(C_EncryptFinal, - (ck_session_handle_t session, - unsigned char *last_encrypted_part, - unsigned long *last_encrypted_part_len)); - - _CK_DECLARE_FUNCTION(C_DecryptInit, - (ck_session_handle_t session, - struct ck_mechanism * mechanism, - ck_object_handle_t key)); - _CK_DECLARE_FUNCTION(C_Decrypt, - (ck_session_handle_t session, - unsigned char *encrypted_data, - unsigned long encrypted_data_len, - unsigned char *data, unsigned long *data_len)); - _CK_DECLARE_FUNCTION(C_DecryptUpdate, - (ck_session_handle_t session, - unsigned char *encrypted_part, - unsigned long encrypted_part_len, - unsigned char *part, unsigned long *part_len)); - _CK_DECLARE_FUNCTION(C_DecryptFinal, - (ck_session_handle_t session, - unsigned char *last_part, - unsigned long *last_part_len)); - - _CK_DECLARE_FUNCTION(C_DigestInit, - (ck_session_handle_t session, - struct ck_mechanism * mechanism)); - _CK_DECLARE_FUNCTION(C_Digest, - (ck_session_handle_t session, - unsigned char *data, unsigned long data_len, - unsigned char *digest, - unsigned long *digest_len)); - _CK_DECLARE_FUNCTION(C_DigestUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len)); - _CK_DECLARE_FUNCTION(C_DigestKey, - (ck_session_handle_t session, - ck_object_handle_t key)); - _CK_DECLARE_FUNCTION(C_DigestFinal, - (ck_session_handle_t session, - unsigned char *digest, - unsigned long *digest_len)); - - _CK_DECLARE_FUNCTION(C_SignInit, - (ck_session_handle_t session, - struct ck_mechanism * mechanism, - ck_object_handle_t key)); - _CK_DECLARE_FUNCTION(C_Sign, - (ck_session_handle_t session, - unsigned char *data, unsigned long data_len, - unsigned char *signature, - unsigned long *signature_len)); - _CK_DECLARE_FUNCTION(C_SignUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len)); - _CK_DECLARE_FUNCTION(C_SignFinal, - (ck_session_handle_t session, - unsigned char *signature, - unsigned long *signature_len)); - _CK_DECLARE_FUNCTION(C_SignRecoverInit, - (ck_session_handle_t session, - struct ck_mechanism * mechanism, - ck_object_handle_t key)); - _CK_DECLARE_FUNCTION(C_SignRecover, - (ck_session_handle_t session, - unsigned char *data, unsigned long data_len, - unsigned char *signature, - unsigned long *signature_len)); - - _CK_DECLARE_FUNCTION(C_VerifyInit, - (ck_session_handle_t session, - struct ck_mechanism * mechanism, - ck_object_handle_t key)); - _CK_DECLARE_FUNCTION(C_Verify, - (ck_session_handle_t session, - unsigned char *data, unsigned long data_len, - unsigned char *signature, - unsigned long signature_len)); - _CK_DECLARE_FUNCTION(C_VerifyUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len)); - _CK_DECLARE_FUNCTION(C_VerifyFinal, - (ck_session_handle_t session, - unsigned char *signature, - unsigned long signature_len)); - _CK_DECLARE_FUNCTION(C_VerifyRecoverInit, - (ck_session_handle_t session, - struct ck_mechanism * mechanism, - ck_object_handle_t key)); - _CK_DECLARE_FUNCTION(C_VerifyRecover, - (ck_session_handle_t session, - unsigned char *signature, - unsigned long signature_len, - unsigned char *data, unsigned long *data_len)); - - _CK_DECLARE_FUNCTION(C_DigestEncryptUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len, - unsigned char *encrypted_part, - unsigned long *encrypted_part_len)); - _CK_DECLARE_FUNCTION(C_DecryptDigestUpdate, - (ck_session_handle_t session, - unsigned char *encrypted_part, - unsigned long encrypted_part_len, - unsigned char *part, unsigned long *part_len)); - _CK_DECLARE_FUNCTION(C_SignEncryptUpdate, - (ck_session_handle_t session, - unsigned char *part, unsigned long part_len, - unsigned char *encrypted_part, - unsigned long *encrypted_part_len)); - _CK_DECLARE_FUNCTION(C_DecryptVerifyUpdate, - (ck_session_handle_t session, - unsigned char *encrypted_part, - unsigned long encrypted_part_len, - unsigned char *part, unsigned long *part_len)); - - _CK_DECLARE_FUNCTION(C_GenerateKey, - (ck_session_handle_t session, - struct ck_mechanism * mechanism, - struct ck_attribute * templ, - unsigned long count, ck_object_handle_t * key)); - _CK_DECLARE_FUNCTION(C_GenerateKeyPair, - (ck_session_handle_t session, - struct ck_mechanism * mechanism, - struct ck_attribute * public_key_template, - unsigned long public_key_attribute_count, - struct ck_attribute * private_key_template, - unsigned long private_key_attribute_count, - ck_object_handle_t * public_key, - ck_object_handle_t * private_key)); - _CK_DECLARE_FUNCTION(C_WrapKey, - (ck_session_handle_t session, - struct ck_mechanism * mechanism, - ck_object_handle_t wrapping_key, - ck_object_handle_t key, - unsigned char *wrapped_key, - unsigned long *wrapped_key_len)); - _CK_DECLARE_FUNCTION(C_UnwrapKey, - (ck_session_handle_t session, - struct ck_mechanism * mechanism, - ck_object_handle_t unwrapping_key, - unsigned char *wrapped_key, - unsigned long wrapped_key_len, - struct ck_attribute * templ, - unsigned long attribute_count, - ck_object_handle_t * key)); - _CK_DECLARE_FUNCTION(C_DeriveKey, - (ck_session_handle_t session, - struct ck_mechanism * mechanism, - ck_object_handle_t base_key, - struct ck_attribute * templ, - unsigned long attribute_count, - ck_object_handle_t * key)); - - _CK_DECLARE_FUNCTION(C_SeedRandom, - (ck_session_handle_t session, unsigned char *seed, - unsigned long seed_len)); - _CK_DECLARE_FUNCTION(C_GenerateRandom, - (ck_session_handle_t session, - unsigned char *random_data, - unsigned long random_len)); - - _CK_DECLARE_FUNCTION(C_GetFunctionStatus, - (ck_session_handle_t session)); - _CK_DECLARE_FUNCTION(C_CancelFunction, (ck_session_handle_t session)); - - struct ck_function_list { - struct ck_version version; - CK_C_Initialize C_Initialize; - CK_C_Finalize C_Finalize; - CK_C_GetInfo C_GetInfo; - CK_C_GetFunctionList C_GetFunctionList; - CK_C_GetSlotList C_GetSlotList; - CK_C_GetSlotInfo C_GetSlotInfo; - CK_C_GetTokenInfo C_GetTokenInfo; - CK_C_GetMechanismList C_GetMechanismList; - CK_C_GetMechanismInfo C_GetMechanismInfo; - CK_C_InitToken C_InitToken; - CK_C_InitPIN C_InitPIN; - CK_C_SetPIN C_SetPIN; - CK_C_OpenSession C_OpenSession; - CK_C_CloseSession C_CloseSession; - CK_C_CloseAllSessions C_CloseAllSessions; - CK_C_GetSessionInfo C_GetSessionInfo; - CK_C_GetOperationState C_GetOperationState; - CK_C_SetOperationState C_SetOperationState; - CK_C_Login C_Login; - CK_C_Logout C_Logout; - CK_C_CreateObject C_CreateObject; - CK_C_CopyObject C_CopyObject; - CK_C_DestroyObject C_DestroyObject; - CK_C_GetObjectSize C_GetObjectSize; - CK_C_GetAttributeValue C_GetAttributeValue; - CK_C_SetAttributeValue C_SetAttributeValue; - CK_C_FindObjectsInit C_FindObjectsInit; - CK_C_FindObjects C_FindObjects; - CK_C_FindObjectsFinal C_FindObjectsFinal; - CK_C_EncryptInit C_EncryptInit; - CK_C_Encrypt C_Encrypt; - CK_C_EncryptUpdate C_EncryptUpdate; - CK_C_EncryptFinal C_EncryptFinal; - CK_C_DecryptInit C_DecryptInit; - CK_C_Decrypt C_Decrypt; - CK_C_DecryptUpdate C_DecryptUpdate; - CK_C_DecryptFinal C_DecryptFinal; - CK_C_DigestInit C_DigestInit; - CK_C_Digest C_Digest; - CK_C_DigestUpdate C_DigestUpdate; - CK_C_DigestKey C_DigestKey; - CK_C_DigestFinal C_DigestFinal; - CK_C_SignInit C_SignInit; - CK_C_Sign C_Sign; - CK_C_SignUpdate C_SignUpdate; - CK_C_SignFinal C_SignFinal; - CK_C_SignRecoverInit C_SignRecoverInit; - CK_C_SignRecover C_SignRecover; - CK_C_VerifyInit C_VerifyInit; - CK_C_Verify C_Verify; - CK_C_VerifyUpdate C_VerifyUpdate; - CK_C_VerifyFinal C_VerifyFinal; - CK_C_VerifyRecoverInit C_VerifyRecoverInit; - CK_C_VerifyRecover C_VerifyRecover; - CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; - CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; - CK_C_SignEncryptUpdate C_SignEncryptUpdate; - CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; - CK_C_GenerateKey C_GenerateKey; - CK_C_GenerateKeyPair C_GenerateKeyPair; - CK_C_WrapKey C_WrapKey; - CK_C_UnwrapKey C_UnwrapKey; - CK_C_DeriveKey C_DeriveKey; - CK_C_SeedRandom C_SeedRandom; - CK_C_GenerateRandom C_GenerateRandom; - CK_C_GetFunctionStatus C_GetFunctionStatus; - CK_C_CancelFunction C_CancelFunction; - CK_C_WaitForSlotEvent C_WaitForSlotEvent; - }; - - typedef ck_rv_t(*ck_createmutex_t) (void **mutex); - typedef ck_rv_t(*ck_destroymutex_t) (void *mutex); - typedef ck_rv_t(*ck_lockmutex_t) (void *mutex); - typedef ck_rv_t(*ck_unlockmutex_t) (void *mutex); - - struct ck_c_initialize_args { - ck_createmutex_t create_mutex; - ck_destroymutex_t destroy_mutex; - ck_lockmutex_t lock_mutex; - ck_unlockmutex_t unlock_mutex; - ck_flags_t flags; - void *reserved; - }; - -#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1UL << 0) -#define CKF_OS_LOCKING_OK (1UL << 1) - -#define CKR_OK (0UL) -#define CKR_CANCEL (1UL) -#define CKR_HOST_MEMORY (2UL) -#define CKR_SLOT_ID_INVALID (3UL) -#define CKR_GENERAL_ERROR (5UL) -#define CKR_FUNCTION_FAILED (6UL) -#define CKR_ARGUMENTS_BAD (7UL) -#define CKR_NO_EVENT (8UL) -#define CKR_NEED_TO_CREATE_THREADS (9UL) -#define CKR_CANT_LOCK (0xaUL) -#define CKR_ATTRIBUTE_READ_ONLY (0x10UL) -#define CKR_ATTRIBUTE_SENSITIVE (0x11UL) -#define CKR_ATTRIBUTE_TYPE_INVALID (0x12UL) -#define CKR_ATTRIBUTE_VALUE_INVALID (0x13UL) -#define CKR_DATA_INVALID (0x20UL) -#define CKR_DATA_LEN_RANGE (0x21UL) -#define CKR_DEVICE_ERROR (0x30UL) -#define CKR_DEVICE_MEMORY (0x31UL) -#define CKR_DEVICE_REMOVED (0x32UL) -#define CKR_ENCRYPTED_DATA_INVALID (0x40UL) -#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41UL) -#define CKR_FUNCTION_CANCELED (0x50UL) -#define CKR_FUNCTION_NOT_PARALLEL (0x51UL) -#define CKR_FUNCTION_NOT_SUPPORTED (0x54UL) -#define CKR_KEY_HANDLE_INVALID (0x60UL) -#define CKR_KEY_SIZE_RANGE (0x62UL) -#define CKR_KEY_TYPE_INCONSISTENT (0x63UL) -#define CKR_KEY_NOT_NEEDED (0x64UL) -#define CKR_KEY_CHANGED (0x65UL) -#define CKR_KEY_NEEDED (0x66UL) -#define CKR_KEY_INDIGESTIBLE (0x67UL) -#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68UL) -#define CKR_KEY_NOT_WRAPPABLE (0x69UL) -#define CKR_KEY_UNEXTRACTABLE (0x6aUL) -#define CKR_MECHANISM_INVALID (0x70UL) -#define CKR_MECHANISM_PARAM_INVALID (0x71UL) -#define CKR_OBJECT_HANDLE_INVALID (0x82UL) -#define CKR_OPERATION_ACTIVE (0x90UL) -#define CKR_OPERATION_NOT_INITIALIZED (0x91UL) -#define CKR_PIN_INCORRECT (0xa0UL) -#define CKR_PIN_INVALID (0xa1UL) -#define CKR_PIN_LEN_RANGE (0xa2UL) -#define CKR_PIN_EXPIRED (0xa3UL) -#define CKR_PIN_LOCKED (0xa4UL) -#define CKR_SESSION_CLOSED (0xb0UL) -#define CKR_SESSION_COUNT (0xb1UL) -#define CKR_SESSION_HANDLE_INVALID (0xb3UL) -#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4UL) -#define CKR_SESSION_READ_ONLY (0xb5UL) -#define CKR_SESSION_EXISTS (0xb6UL) -#define CKR_SESSION_READ_ONLY_EXISTS (0xb7UL) -#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8UL) -#define CKR_SIGNATURE_INVALID (0xc0UL) -#define CKR_SIGNATURE_LEN_RANGE (0xc1UL) -#define CKR_TEMPLATE_INCOMPLETE (0xd0UL) -#define CKR_TEMPLATE_INCONSISTENT (0xd1UL) -#define CKR_TOKEN_NOT_PRESENT (0xe0UL) -#define CKR_TOKEN_NOT_RECOGNIZED (0xe1UL) -#define CKR_TOKEN_WRITE_PROTECTED (0xe2UL) -#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0UL) -#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1UL) -#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2UL) -#define CKR_USER_ALREADY_LOGGED_IN (0x100UL) -#define CKR_USER_NOT_LOGGED_IN (0x101UL) -#define CKR_USER_PIN_NOT_INITIALIZED (0x102UL) -#define CKR_USER_TYPE_INVALID (0x103UL) -#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104UL) -#define CKR_USER_TOO_MANY_TYPES (0x105UL) -#define CKR_WRAPPED_KEY_INVALID (0x110UL) -#define CKR_WRAPPED_KEY_LEN_RANGE (0x112UL) -#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113UL) -#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114UL) -#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115UL) -#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120UL) -#define CKR_RANDOM_NO_RNG (0x121UL) -#define CKR_DOMAIN_PARAMS_INVALID (0x130UL) -#define CKR_BUFFER_TOO_SMALL (0x150UL) -#define CKR_SAVED_STATE_INVALID (0x160UL) -#define CKR_INFORMATION_SENSITIVE (0x170UL) -#define CKR_STATE_UNSAVEABLE (0x180UL) -#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190UL) -#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191UL) -#define CKR_MUTEX_BAD (0x1a0UL) -#define CKR_MUTEX_NOT_LOCKED (0x1a1UL) -#define CKR_FUNCTION_REJECTED (0x200UL) -#define CKR_VENDOR_DEFINED ((unsigned long) (1UL << 31)) - -/* Compatibility layer. */ - -#ifdef CRYPTOKI_COMPAT - -#undef CK_DEFINE_FUNCTION -#define CK_DEFINE_FUNCTION(retval, name) retval CK_SPEC name - -/* For NULL. */ -#include - - typedef unsigned char CK_BYTE; - typedef unsigned char CK_CHAR; - typedef unsigned char CK_UTF8CHAR; - typedef unsigned char CK_BBOOL; - typedef unsigned long int CK_ULONG; - typedef long int CK_LONG; - typedef CK_BYTE *CK_BYTE_PTR; - typedef CK_CHAR *CK_CHAR_PTR; - typedef CK_UTF8CHAR *CK_UTF8CHAR_PTR; - typedef CK_ULONG *CK_ULONG_PTR; - typedef void *CK_VOID_PTR; - typedef void **CK_VOID_PTR_PTR; -#define CK_FALSE 0 -#define CK_TRUE 1 -#ifndef CK_DISABLE_TRUE_FALSE -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif -#endif - - typedef struct ck_version CK_VERSION; - typedef struct ck_version *CK_VERSION_PTR; - - typedef struct ck_info CK_INFO; - typedef struct ck_info *CK_INFO_PTR; - - typedef ck_slot_id_t *CK_SLOT_ID_PTR; - - typedef struct ck_slot_info CK_SLOT_INFO; - typedef struct ck_slot_info *CK_SLOT_INFO_PTR; - - typedef struct ck_token_info CK_TOKEN_INFO; - typedef struct ck_token_info *CK_TOKEN_INFO_PTR; - - typedef ck_session_handle_t *CK_SESSION_HANDLE_PTR; - - typedef struct ck_session_info CK_SESSION_INFO; - typedef struct ck_session_info *CK_SESSION_INFO_PTR; - - typedef ck_object_handle_t *CK_OBJECT_HANDLE_PTR; - - typedef ck_object_class_t *CK_OBJECT_CLASS_PTR; - - typedef struct ck_attribute CK_ATTRIBUTE; - typedef struct ck_attribute *CK_ATTRIBUTE_PTR; - - typedef struct ck_date CK_DATE; - typedef struct ck_date *CK_DATE_PTR; - - typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; - - typedef struct ck_mechanism CK_MECHANISM; - typedef struct ck_mechanism *CK_MECHANISM_PTR; - - typedef struct ck_mechanism_info CK_MECHANISM_INFO; - typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR; - - typedef struct ck_function_list CK_FUNCTION_LIST; - typedef struct ck_function_list *CK_FUNCTION_LIST_PTR; - typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR; - - typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS; - typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; - -#define NULL_PTR NULL - -/* Delete the helper macros defined at the top of the file. */ -#undef ck_flags_t -#undef ck_version - -#undef ck_info -#undef cryptoki_version -#undef manufacturer_id -#undef library_description -#undef library_version - -#undef ck_notification_t -#undef ck_slot_id_t - -#undef ck_slot_info -#undef slot_description -#undef hardware_version -#undef firmware_version - -#undef ck_token_info -#undef serial_number -#undef max_session_count -#undef session_count -#undef max_rw_session_count -#undef rw_session_count -#undef max_pin_len -#undef min_pin_len -#undef total_public_memory -#undef free_public_memory -#undef total_private_memory -#undef free_private_memory -#undef utc_time - -#undef ck_session_handle_t -#undef ck_user_type_t -#undef ck_state_t - -#undef ck_session_info -#undef slot_id -#undef device_error - -#undef ck_object_handle_t -#undef ck_object_class_t -#undef ck_hw_feature_type_t -#undef ck_key_type_t -#undef ck_certificate_type_t -#undef ck_attribute_type_t - -#undef ck_attribute -#undef value -#undef value_len - -#undef ck_date - -#undef ck_mechanism_type_t - -#undef ck_mechanism -#undef parameter -#undef parameter_len - -#undef ck_mechanism_info -#undef min_key_size -#undef max_key_size - -#undef ck_rv_t -#undef ck_notify_t - -#undef ck_function_list - -#undef ck_createmutex_t -#undef ck_destroymutex_t -#undef ck_lockmutex_t -#undef ck_unlockmutex_t - -#undef ck_c_initialize_args -#undef create_mutex -#undef destroy_mutex -#undef lock_mutex -#undef unlock_mutex -#undef reserved - -#endif /* CRYPTOKI_COMPAT */ - -/* System dependencies. */ -#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) -#pragma pack(pop, cryptoki) -#endif - -#if defined(__cplusplus) -} -#endif -#endif /* PKCS11_H */ diff --git a/ext/pkcs11-proxy/pkcs11/pkcs11g.h b/ext/pkcs11-proxy/pkcs11/pkcs11g.h deleted file mode 100644 index 1252182c0..000000000 --- a/ext/pkcs11-proxy/pkcs11/pkcs11g.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* pkcs11g.h - GNOME extensions to PKCS#11 - - Copyright (C) 2008, Stef Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter -*/ - -#ifndef PKCS11G_H -#define PKCS11G_H - -#include "pkcs11.h" - -#define CKA_GNOME (CKA_VENDOR_DEFINED | 0x474E4D45 /* GNME */ ) -#define CKO_GNOME (CKO_VENDOR_DEFINED | 0x474E4D45 /* GNME */ ) - -/* ------------------------------------------------------------------- - * OBJECT AUTHENTICATION - */ - -#define CKA_GNOME_AUTH_CACHE (CKA_GNOME + 300) -#define CKV_GNOME_AUTH_CACHE_NEVER ((CK_ULONG)-1) -#define CKV_GNOME_AUTH_CACHE_SESSION 0x40000000 -#define CKV_GNOME_AUTH_CACHE_UNLIMITED 0x80000000 - -#define CKA_GNOME_AUTH_CACHED (CKA_GNOME + 301) - -/* ------------------------------------------------------------------- - * OBJECT UNIQUE IDENTIFIER - */ - -/* A string unique among all objects on a given machine */ -#define CKA_GNOME_UNIQUE (CKA_GNOME + 350) - -/* ------------------------------------------------------------------- - * PURPOSES - */ - -/* - * Whether the key or certificate is restricted to a set of - * purposes (ie: enhanced usages). - * - * CK_BBOOL - * - * - When CK_TRUE see CKA_PURPOSE_OIDS for the set of purposes. - * - When CK_FALSE then is not restricted to any specific purpose. - */ -#define CKA_GNOME_PURPOSE_RESTRICTED (CKA_GNOME + 12) - -/* - * The available purposes that a certificate or key can be - * used for. - * - * CK_STRING - * - * - This is only relevant if CKA_PURPOSE_RESTRICTED is CK_TRUE. - * - Use CKA_TRUSTED and CKA_CERTIFICATE_CATEGORY to validate whether - * usage of the certificate for these purposes is directly or - * indirectly trusted by the user. - * - The returned string is a space delemited set of OIDs. - * - When an empty string is returned then no purposes are valid. - */ -#define CKA_GNOME_PURPOSE_OIDS (CKA_GNOME + 11) - -/* - * The key or certificate can be used for the purpose - * indicated - * - * CK_BBOOL - * - * - These are shortcuts to using CKA_PURPOSE_OIDS - * - Use CKA_TRUSTED and CKA_CERTIFICATE_CATEGORY to validate whether - * the certificate is directly or indirectly trusted by the user. - */ -#define CKA_GNOME_PURPOSE_SSH_AUTH (CKA_GNOME + 101) -#define CKA_GNOME_PURPOSE_SERVER_AUTH (CKA_GNOME + 102) -#define CKA_GNOME_PURPOSE_CLIENT_AUTH (CKA_GNOME + 103) -#define CKA_GNOME_PURPOSE_CODE_SIGNING (CKA_GNOME + 104) -#define CKA_GNOME_PURPOSE_EMAIL_PROTECTION (CKA_GNOME + 105) -#define CKA_GNOME_PURPOSE_IPSEC_END_SYSTEM (CKA_GNOME + 106) -#define CKA_GNOME_PURPOSE_IPSEC_TUNNEL (CKA_GNOME + 107) -#define CKA_GNOME_PURPOSE_IPSEC_USER (CKA_GNOME + 108) -#define CKA_GNOME_PURPOSE_TIME_STAMPING (CKA_GNOME + 109) - -#endif /* PKCS11G_H */ diff --git a/ext/pkcs11-proxy/pkcs11/pkcs11i.h b/ext/pkcs11-proxy/pkcs11/pkcs11i.h deleted file mode 100644 index ce15393f3..000000000 --- a/ext/pkcs11-proxy/pkcs11/pkcs11i.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* pkcs11g.h - GNOME internal definitions to PKCS#11 - - Copyright (C) 2008, Stef Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter -*/ - -#ifndef PKCS11I_H -#define PKCS11I_H - -#include "pkcs11.h" -#include "pkcs11g.h" - -/* Signifies that nobody is logged in */ -#define CKU_NONE G_MAXULONG - -/* ---------------------------------------------------------------------- - * APARTMENT SLOTS - * - * The lower 10 bits of the CK_SLOT_ID are used as the actual slot identifier, - * and the remainder are used as application identifiers. - * - * This enables a single loaded module to serve multiple applications - * concurrently. The caller of a module should check the - * CKF_GNOME_VIRTUAL_SLOTS flag before using this functionality. - */ - -/* Flag for CK_INFO when virtual slots are supported */ -#define CKF_GNOME_APPARTMENTS 0x40000000 - -/* Get an actual slot id from a virtual slot */ -#define CK_GNOME_APPARTMENT_SLOT(virt) ((virt) & 0x000003FF) - -/* Get an app id from a virtual slot */ -#define CK_GNOME_APPARTMENT_APP(virt) ((virt) >> 10) - -/* Is the app id valid for use in a virtual slot? */ -#define CK_GNOME_APPARTMENT_IS_APP(app) ((app) < (((CK_ULONG)-1) >> 10)) - -/* Build a virtual slot from an actual slot id, and an app id */ -#define CK_GNOME_MAKE_APPARTMENT(slot, app) (((slot) & 0x000003FF) | ((app) << 10)) - -/* ------------------------------------------------------------------- - * LIMITED HANDLES - * - * The upper 10 bits of a CK_SESSION_HANDLE and CK_OBJECT_HANDLE are - * never used by Gnome Keyring PKCS#11 modules. These bits are used - * for tracking purposes when combining modules into a single module. - */ - -#define CK_GNOME_MAX_SLOT (0x000003FF) -#define CK_GNOME_MAX_APP (((CK_ULONG)-1) >> 10) -#define CK_GNOME_MAX_HANDLE (((CK_ULONG)-1) >> 10) - -/* ------------------------------------------------------------------- - * OBJECT HASH - */ - -#define CKA_GNOME_INTERNAL_SHA1 (CKA_GNOME + 1000) - -#endif /* PKCS11I_H */ diff --git a/ext/pkcs11-proxy/pkcs11/pkcs11n.h b/ext/pkcs11-proxy/pkcs11/pkcs11n.h deleted file mode 100644 index 39bb59f4f..000000000 --- a/ext/pkcs11-proxy/pkcs11/pkcs11n.h +++ /dev/null @@ -1,221 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Stephen Henson - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _PKCS11N_H_ -#define _PKCS11N_H_ - -#ifdef DEBUG -static const char CKT_CVS_ID[] = - "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.15 $ $Date: 2005/09/28 17:12:17 $"; - -#endif /* DEBUG */ - -/* - * pkcs11n.h - * - * This file contains the NSS-specific type definitions for Cryptoki - * (PKCS#11). - */ - -/* - * NSSCK_VENDOR_NETSCAPE - * - * Cryptoki reserves the high half of all the number spaces for - * vendor-defined use. I'd like to keep all of our Netscape- - * specific values together, but not in the oh-so-obvious - * 0x80000001, 0x80000002, etc. area. So I've picked an offset, - * and constructed values for the beginnings of our spaces. - * - * Note that some "historical" Netscape values don't fall within - * this range. - */ -#define NSSCK_VENDOR_NETSCAPE 0x4E534350 /* NSCP */ - -/* - * Netscape-defined object classes - * - */ -#define CKO_NETSCAPE (CKO_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE) - -#define CKO_NETSCAPE_CRL (CKO_NETSCAPE + 1) -#define CKO_NETSCAPE_SMIME (CKO_NETSCAPE + 2) -#define CKO_NETSCAPE_TRUST (CKO_NETSCAPE + 3) -#define CKO_NETSCAPE_BUILTIN_ROOT_LIST (CKO_NETSCAPE + 4) -#define CKO_NETSCAPE_NEWSLOT (CKO_NETSCAPE + 5) -#define CKO_NETSCAPE_DELSLOT (CKO_NETSCAPE + 6) - -/* - * Netscape-defined key types - * - */ -#define CKK_NETSCAPE (CKK_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE) - -#define CKK_NETSCAPE_PKCS8 (CKK_NETSCAPE + 1) -/* - * Netscape-defined certificate types - * - */ -#define CKC_NETSCAPE (CKC_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE) - -/* - * Netscape-defined object attributes - * - */ -#define CKA_NETSCAPE (CKA_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE) - -#define CKA_NETSCAPE_URL (CKA_NETSCAPE + 1) -#define CKA_NETSCAPE_EMAIL (CKA_NETSCAPE + 2) -#define CKA_NETSCAPE_SMIME_INFO (CKA_NETSCAPE + 3) -#define CKA_NETSCAPE_SMIME_TIMESTAMP (CKA_NETSCAPE + 4) -#define CKA_NETSCAPE_PKCS8_SALT (CKA_NETSCAPE + 5) -#define CKA_NETSCAPE_PASSWORD_CHECK (CKA_NETSCAPE + 6) -#define CKA_NETSCAPE_EXPIRES (CKA_NETSCAPE + 7) -#define CKA_NETSCAPE_KRL (CKA_NETSCAPE + 8) - -#define CKA_NETSCAPE_PQG_COUNTER (CKA_NETSCAPE + 20) -#define CKA_NETSCAPE_PQG_SEED (CKA_NETSCAPE + 21) -#define CKA_NETSCAPE_PQG_H (CKA_NETSCAPE + 22) -#define CKA_NETSCAPE_PQG_SEED_BITS (CKA_NETSCAPE + 23) -#define CKA_NETSCAPE_MODULE_SPEC (CKA_NETSCAPE + 24) - -/* - * Trust attributes: - * - * If trust goes standard, these probably will too. So I'll - * put them all in one place. - */ - -#define CKA_TRUST (CKA_NETSCAPE + 0x2000) - -/* "Usage" key information */ -#define CKA_TRUST_DIGITAL_SIGNATURE (CKA_TRUST + 1) -#define CKA_TRUST_NON_REPUDIATION (CKA_TRUST + 2) -#define CKA_TRUST_KEY_ENCIPHERMENT (CKA_TRUST + 3) -#define CKA_TRUST_DATA_ENCIPHERMENT (CKA_TRUST + 4) -#define CKA_TRUST_KEY_AGREEMENT (CKA_TRUST + 5) -#define CKA_TRUST_KEY_CERT_SIGN (CKA_TRUST + 6) -#define CKA_TRUST_CRL_SIGN (CKA_TRUST + 7) - -/* "Purpose" trust information */ -#define CKA_TRUST_SERVER_AUTH (CKA_TRUST + 8) -#define CKA_TRUST_CLIENT_AUTH (CKA_TRUST + 9) -#define CKA_TRUST_CODE_SIGNING (CKA_TRUST + 10) -#define CKA_TRUST_EMAIL_PROTECTION (CKA_TRUST + 11) -#define CKA_TRUST_IPSEC_END_SYSTEM (CKA_TRUST + 12) -#define CKA_TRUST_IPSEC_TUNNEL (CKA_TRUST + 13) -#define CKA_TRUST_IPSEC_USER (CKA_TRUST + 14) -#define CKA_TRUST_TIME_STAMPING (CKA_TRUST + 15) -#define CKA_TRUST_STEP_UP_APPROVED (CKA_TRUST + 16) - -#define CKA_CERT_SHA1_HASH (CKA_TRUST + 100) -#define CKA_CERT_MD5_HASH (CKA_TRUST + 101) - -/* Netscape trust stuff */ -/* XXX fgmr new ones here-- step-up, etc. */ - -/* HISTORICAL: define used to pass in the database key for DSA private keys */ -#define CKA_NETSCAPE_DB 0xD5A0DB00L -#define CKA_NETSCAPE_TRUST 0x80000001L - -/* - * Netscape-defined crypto mechanisms - * - */ -#define CKM_NETSCAPE (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE) - -#define CKM_NETSCAPE_AES_KEY_WRAP (CKM_NETSCAPE + 1) -#define CKM_NETSCAPE_AES_KEY_WRAP_PAD (CKM_NETSCAPE + 2) - -/* - * HISTORICAL: - * Do not attempt to use these. They are only used by NETSCAPE's internal - * PKCS #11 interface. Most of these are place holders for other mechanism - * and will change in the future. - */ -#define CKM_NETSCAPE_PBE_SHA1_DES_CBC 0x80000002L -#define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC 0x80000003L -#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC 0x80000004L -#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC 0x80000005L -#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006L -#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007L -#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008L -#define CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN 0x80000009L -#define CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN 0x8000000aL -#define CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN 0x8000000bL - -#define CKM_TLS_PRF_GENERAL 0x80000373L - -/* - * Netscape-defined return values - * - */ -#define CKR_NETSCAPE (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE) - -#define CKR_NETSCAPE_CERTDB_FAILED (CKR_NETSCAPE + 1) -#define CKR_NETSCAPE_KEYDB_FAILED (CKR_NETSCAPE + 2) - -/* - * Trust info - * - * This isn't part of the Cryptoki standard (yet), so I'm putting - * all the definitions here. Some of this would move to nssckt.h - * if trust info were made part of the standard. In view of this - * possibility, I'm putting my (Netscape) values in the netscape - * vendor space, like everything else. - */ - typedef CK_ULONG CK_TRUST; - -/* The following trust types are defined: */ -#define CKT_VENDOR_DEFINED 0x80000000 - -#define CKT_NETSCAPE (CKT_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE) - -/* If trust goes standard, these'll probably drop out of vendor space. */ -#define CKT_NETSCAPE_TRUSTED (CKT_NETSCAPE + 1) -#define CKT_NETSCAPE_TRUSTED_DELEGATOR (CKT_NETSCAPE + 2) -#define CKT_NETSCAPE_UNTRUSTED (CKT_NETSCAPE + 3) -#define CKT_NETSCAPE_MUST_VERIFY (CKT_NETSCAPE + 4) -#define CKT_NETSCAPE_TRUST_UNKNOWN (CKT_NETSCAPE + 5) /* default */ - -/* - * These may well remain Netscape-specific; I'm only using them - * to cache resolution data. - */ -#define CKT_NETSCAPE_VALID (CKT_NETSCAPE + 10) -#define CKT_NETSCAPE_VALID_DELEGATOR (CKT_NETSCAPE + 11) - -#endif /* _PKCS11N_H_ */ diff --git a/ext/pkcs11-proxy/seccomp-bpf.h b/ext/pkcs11-proxy/seccomp-bpf.h deleted file mode 100644 index 32e113764..000000000 --- a/ext/pkcs11-proxy/seccomp-bpf.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * seccomp example for x86 (32-bit and 64-bit) with BPF macros - * - * Copyright (c) 2012 The Chromium OS Authors - * Authors: - * Will Drewry - * Kees Cook - * - * The code may be used by anyone for any purpose, and can serve as a - * starting point for developing applications using mode 2 seccomp. - */ -#ifndef _SECCOMP_BPF_H_ -#define _SECCOMP_BPF_H_ - -#define _GNU_SOURCE 1 -#include -#include -#include -#include -#include -#include -#include - -#include -#ifndef PR_SET_NO_NEW_PRIVS -# define PR_SET_NO_NEW_PRIVS 38 -#endif - -#include -#include -#include -#ifdef HAVE_LINUX_SECCOMP_H -# include -#endif -#ifndef SECCOMP_MODE_FILTER -# define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */ -# define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ -# define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ -# define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ -struct seccomp_data { - int nr; - __u32 arch; - __u64 instruction_pointer; - __u64 args[6]; -}; -#endif -#ifndef SYS_SECCOMP -# define SYS_SECCOMP 1 -#endif - -#define syscall_nr (offsetof(struct seccomp_data, nr)) -#define arch_nr (offsetof(struct seccomp_data, arch)) - -#ifdef SECCOMP -#if defined(__i386__) -# define REG_SYSCALL REG_EAX -# define ARCH_NR AUDIT_ARCH_I386 -#elif defined(__x86_64__) -# define REG_SYSCALL REG_RAX -# define ARCH_NR AUDIT_ARCH_X86_64 -#else -# warning "Platform does not support seccomp filter yet" -# define REG_SYSCALL 0 -# define ARCH_NR 0 -#endif -#endif /* SECCOMP */ - -#define VALIDATE_ARCHITECTURE \ - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, arch_nr), \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \ - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) - -#define EXAMINE_SYSCALL \ - BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr) - -#define ALLOW_SYSCALL(name) \ - BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_##name, 0, 1), \ - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) - -#define KILL_PROCESS \ - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) - -#endif /* _SECCOMP_BPF_H_ */ diff --git a/ext/pkcs11-proxy/syscall-reporter.c b/ext/pkcs11-proxy/syscall-reporter.c deleted file mode 100644 index b7750a2ff..000000000 --- a/ext/pkcs11-proxy/syscall-reporter.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * syscall reporting example for seccomp - * - * Copyright (c) 2012 The Chromium OS Authors - * Authors: - * Will Drewry - * Kees Cook - * - * The code may be used by anyone for any purpose, and can serve as a - * starting point for developing applications using mode 2 seccomp. - */ -#include "syscall-reporter.h" -#include "syscall-names.h" - -const char * const msg_needed = "Looks like you also need syscall: "; - -/* Since "sprintf" is technically not signal-safe, reimplement %d here. */ -static void write_uint(char *buf, unsigned int val) -{ - int width = 0; - unsigned int tens; - - if (val == 0) { - strcpy(buf, "0"); - return; - } - for (tens = val; tens; tens /= 10) - ++ width; - buf[width] = '\0'; - for (tens = val; tens; tens /= 10) - buf[--width] = '0' + (tens % 10); -} - -static void reporter(int nr, siginfo_t *info, void *void_context) -{ -#ifdef SECCOMP - char buf[128]; - ucontext_t *ctx = (ucontext_t *)(void_context); - unsigned int syscall; - if (info->si_code != SYS_SECCOMP) - return; - if (!ctx) - return; - syscall = ctx->uc_mcontext.gregs[REG_SYSCALL]; - strcpy(buf, msg_needed); - if (syscall < sizeof(syscall_names)) { - strcat(buf, syscall_names[syscall]); - strcat(buf, "("); - } - write_uint(buf + strlen(buf), syscall); - if (syscall < sizeof(syscall_names)) - strcat(buf, ")"); - strcat(buf, "\n"); - write(STDERR_FILENO, buf, strlen(buf)); - _exit(1); -#endif -} - -int install_syscall_reporter(void) -{ -#ifdef SECCOMP - struct sigaction act; - sigset_t mask; - memset(&act, 0, sizeof(act)); - sigemptyset(&mask); - sigaddset(&mask, SIGSYS); - - act.sa_sigaction = &reporter; - act.sa_flags = SA_SIGINFO; - if (sigaction(SIGSYS, &act, NULL) < 0) { - perror("sigaction"); - return -1; - } - if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) { - perror("sigprocmask"); - return -1; - } -#endif - return 0; -} diff --git a/ext/pkcs11-proxy/syscall-reporter.h b/ext/pkcs11-proxy/syscall-reporter.h deleted file mode 100644 index ea4847e45..000000000 --- a/ext/pkcs11-proxy/syscall-reporter.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * syscall reporting example for seccomp - * - * Copyright (c) 2012 The Chromium OS Authors - * Authors: - * Kees Cook - * Will Drewry - * - * The code may be used by anyone for any purpose, and can serve as a - * starting point for developing applications using mode 2 seccomp. - */ -#ifndef _BPF_REPORTER_H_ -#define _BPF_REPORTER_H_ - -#include "seccomp-bpf.h" - -/* Since this redfines "KILL_PROCESS" into a TRAP for the reporter hook, - * we want to make sure it stands out in the build as it should not be - * used in the final program. - */ -#warning "You've included the syscall reporter. Do not use in production!" -#undef KILL_PROCESS -#define KILL_PROCESS \ - BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP) - -extern int install_syscall_reporter(void); - -#endif diff --git a/scripts/deployment_dependencies.sh b/scripts/deployment_dependencies.sh new file mode 100755 index 000000000..5281eb727 --- /dev/null +++ b/scripts/deployment_dependencies.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +# exit on errors +set -e + +# add the STOL APT repository +echo "deb [trusted=yes] http://s3.amazonaws.com/stol-apt-repository develop main" > /etc/apt/sources.list.d/stol-apt-repository.list + +apt-get update + +# NOTE: libwebsockets-dev from Ubuntu 20 on is sufficient +DEPENDENCIES="build-essential \ + cmake \ + libboost-all-dev \ + libgps-dev \ + libjsoncpp-dev \ + libmysqlclient-dev \ + libmysqlcppconn-dev \ + librdkafka-dev \ + libsnmp-dev \ + libssl-dev \ + libwebsockets-dev \ + libxerces-c-dev \ + qtbase5-dev \ + uuid-dev \ + zip \ + zlib1g \ + curl" + +# STOL library dependencies +LIBRARY_DEPENDENCIES=" \ + carma-clock-1 \ +" + +# install all things needed for deployment, always done +apt-get install -y $DEPENDENCIES ${LIBRARY_DEPENDENCIES} diff --git a/scripts/install_dependencies.sh b/scripts/install_dependencies.sh index efd5f5010..9ddc86c72 100755 --- a/scripts/install_dependencies.sh +++ b/scripts/install_dependencies.sh @@ -13,7 +13,6 @@ DEPENDENCIES="build-essential \ cmake \ git \ libboost-all-dev \ - libcpprest-dev \ libcurl4-openssl-dev \ libev-dev \ libgps-dev \ diff --git a/src/tmx/Security/softhsm/CMakeLists.txt b/src/tmx/Security/softhsm/CMakeLists.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/tmx/Security/softhsm/softhsm.cc b/src/tmx/Security/softhsm/softhsm.cc deleted file mode 100644 index ed5f40201..000000000 --- a/src/tmx/Security/softhsm/softhsm.cc +++ /dev/null @@ -1,23 +0,0 @@ -/* implementation code that allows softhsm access through the pkcs11 proxy API */ - - - - -#include "softhsm.h" - - - - -namespace tmx { - - - - - - - - - - - -} \ No newline at end of file diff --git a/src/tmx/Security/softhsm/softhsm.h b/src/tmx/Security/softhsm/softhsm.h deleted file mode 100644 index 3682c2cfe..000000000 --- a/src/tmx/Security/softhsm/softhsm.h +++ /dev/null @@ -1,77 +0,0 @@ -/***** Implimentation of pkcs11 proxy class for integrating softhsm module with V2X hub */ -/* Author: Anjan Rayamajhi, leidos Inc */ - - -#include "config.h" - -#include - - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - - - -#define SOCKET_PATH "tcp://127.0.0.1" - -#ifdef SECCOMP -#include -//#include "seccomp-bpf.h" -#ifdef DEBUG_SECCOMP -# include "syscall-reporter.h" -#endif /* DEBUG_SECCOMP */ -#include /* for seccomp init */ -#endif /* SECCOMP */ - - - - -struct hsmtoken -{ - int slotID; - char* slotLabel; - char* userID; - char* userpin; -}; - - - -namespace tmx { - - class softhsmHelper - { - public: - - char *path, *tsk_file_path, *socket_url; - - int socket; - fd_set filedesc; - - hsmtoken tk; - - - - protected: - - int get_slot_info(char *path, int slotID, char* label, char* userPIN, char* username); // returns the success/failure of slot access and info - hsmtoken create_token(char *path, int slotID, char* label, char* userPIN, char* username); - char* psk_keygen_helper(char* passcode, char* encryption); - int encrypt(char* input, char* output); - int decrypt(char* input, char* output); - int get_slot0_token(); // this might be necessary if the install process sets up a slot 0 token for general use - - int sign_messages(char* input, char* output); - - } - -}; - diff --git a/src/tmx/Security/softhsm/token.h b/src/tmx/Security/softhsm/token.h deleted file mode 100644 index 6fd63dfe7..000000000 --- a/src/tmx/Security/softhsm/token.h +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - -namespace tmx { - - class hsmtoken - { - public: - int slotID; - char* slotLable; - char* userID; - char* userpin; - } - - - -} \ No newline at end of file diff --git a/src/tmx/TmxUtils/src/Point.h b/src/tmx/TmxUtils/src/Point.h new file mode 100644 index 000000000..b075d4430 --- /dev/null +++ b/src/tmx/TmxUtils/src/Point.h @@ -0,0 +1,19 @@ +#pragma once + +namespace tmx::utils { + + + /// Cartesian Coordinates on a . + typedef struct Point + { + Point() : X(0), Y(0), Z(0) {} + + Point(double x, double y, double z = 0.0): + X(x), Y(y), Z(z) { } + + double X; + double Y; + double Z; + } Point; + +} // namespace tmx::utils diff --git a/src/tmx/TmxUtils/test/J2735MessageTest.cpp b/src/tmx/TmxUtils/test/J2735MessageTest.cpp index b70aa513e..5a72f9458 100644 --- a/src/tmx/TmxUtils/test/J2735MessageTest.cpp +++ b/src/tmx/TmxUtils/test/J2735MessageTest.cpp @@ -643,4 +643,109 @@ TEST_F(J2735MessageTest, EncodeTrafficControlMessage){ ASSERT_EQ(245, tsm5Enc.get_msgId()); } +TEST_F (J2735MessageTest, EncodeSrm) +{ + SignalRequestMessage_t *message = (SignalRequestMessage_t *)calloc(1, sizeof(SignalRequestMessage_t)); + message->second = 12; + RequestorDescription_t *requestor = (RequestorDescription_t *)calloc(1, sizeof(RequestorDescription_t)); + VehicleID_t *veh_id = (VehicleID_t *)calloc(1, sizeof(VehicleID_t)); + veh_id->present = VehicleID_PR_entityID; + TemporaryID_t *entity_id = (TemporaryID_t *)calloc(1, sizeof(TemporaryID_t)); + uint8_t my_bytes_id[4] = {(uint8_t)1, (uint8_t)12, (uint8_t)12, (uint8_t)10}; + entity_id->buf = my_bytes_id; + entity_id->size = sizeof(my_bytes_id); + veh_id->choice.entityID = *entity_id; + requestor->id = *veh_id; + RequestorType_t *requestType = (RequestorType_t *)calloc(1, sizeof(RequestorType_t)); + requestType->role = 0; + requestor->type = requestType; + RequestorPositionVector_t *position = (RequestorPositionVector_t *)calloc(1, sizeof(RequestorPositionVector_t)); + DSRC_Angle_t *heading_angle = (DSRC_Angle_t *)calloc(1, sizeof(DSRC_Angle_t)); + *heading_angle = 123; + position->heading = heading_angle; + Position3D_t *position_point = (Position3D_t *)calloc(1, sizeof(Position3D_t)); + DSRC_Elevation_t *elev = (DSRC_Elevation_t *)calloc(1, sizeof(DSRC_Elevation_t)); + *elev = 12; + position_point->elevation = elev; + position_point->lat = 3712333; + position_point->Long = 8012333; + position->position = *position_point; + TransmissionAndSpeed_t *speed = (TransmissionAndSpeed_t *)calloc(1, sizeof(TransmissionAndSpeed_t)); + speed->speed = 10; + TransmissionState_t *transmission_state = (TransmissionState_t *)calloc(1, sizeof(TransmissionState_t)); + *transmission_state = 1111; + speed->transmisson = 7; + position->speed = speed; + requestor->position = position; + message->requestor = *requestor; + + SignalRequestList_t *requests = (SignalRequestList_t *)calloc(1, sizeof(SignalRequestList_t)); + //First: Request Package + SignalRequestPackage_t *request_package = (SignalRequestPackage_t *)calloc(1, sizeof(SignalRequestPackage_t)); + MinuteOfTheYear_t *min = (MinuteOfTheYear_t *)calloc(1, sizeof(MinuteOfTheYear_t)); + *min = 123; + request_package->minute = min; + DSecond_t *duration = (DSecond_t *)calloc(1, sizeof(DSecond_t)); + *duration = 122; + request_package->duration = duration; + DSecond_t *second = (DSecond_t *)calloc(1, sizeof(DSecond_t)); + *second = 1212; + request_package->second = second; + SignalRequest_t *request = (SignalRequest_t *)calloc(1, sizeof(SignalRequest_t)); + IntersectionReferenceID_t *refer_id = (IntersectionReferenceID_t *)calloc(1, sizeof(IntersectionReferenceID_t)); + refer_id->id = 1222; + request->id = *refer_id; + request->requestID = 1; + request->requestType = 0; + IntersectionAccessPoint_t *inBoundLane = (IntersectionAccessPoint_t *)calloc(1, sizeof(IntersectionAccessPoint_t)); + inBoundLane->present = IntersectionAccessPoint_PR_lane; + inBoundLane->choice.lane = 1; + request->inBoundLane = *inBoundLane; + request_package->request = *request; + asn_sequence_add(&requests->list.array, request_package); + + //Second: Request Package + SignalRequestPackage_t *request_package_2 = (SignalRequestPackage_t *)calloc(1, sizeof(SignalRequestPackage_t)); + request_package_2->minute = min; + request_package_2->duration = duration; + request_package_2->second = second; + SignalRequest_t *request_2 = (SignalRequest_t *)calloc(1, sizeof(SignalRequest_t)); + IntersectionReferenceID_t *referId2 = (IntersectionReferenceID_t *)calloc(1, sizeof(IntersectionReferenceID_t)); + referId2->id = 2333; + request_2->id = *referId2; + request_2->requestID = 2; + request_2->requestType = 1; + IntersectionAccessPoint_t *inBoundLane2 = (IntersectionAccessPoint_t *)calloc(1, sizeof(IntersectionAccessPoint_t)); + inBoundLane2->present = IntersectionAccessPoint_PR_approach; + inBoundLane2->choice.approach = 1; + request_2->inBoundLane = *inBoundLane2; + request_package_2->request = *request_2; + asn_sequence_add(&requests->list.array, request_package_2); + message->requests = requests; + tmx::messages::SrmEncodedMessage srmEncodeMessage; + auto _srmMessage = new tmx::messages::SrmMessage(message); + tmx::messages::MessageFrameMessage frame_msg(_srmMessage->get_j2735_data()); + srmEncodeMessage.set_data(TmxJ2735EncodedMessage::encode_j2735_message>(frame_msg)); + free(message); + free(frame_msg.get_j2735_data().get()); + ASSERT_EQ(29, srmEncodeMessage.get_msgId()); + std::string expectedSRMEncHex = "001d311000605c0098c020008003d825e003d380247408910007b04bc007a60004303028001a6bbb1c9ad7882858201801ef8028"; + ASSERT_EQ(expectedSRMEncHex, srmEncodeMessage.get_payload_str()); +} + +TEST_F(J2735MessageTest, EncodeTravelerInformation){ + //Advisory + string timStr="1115549000000000023667BAC0389549775-7714918353901111111111111111115549170389549775-7714918353901111111111111111
389549775-771491835390
74
007186curve13569987654321
"; + std::stringstream ss; + TimMessage timMsg; + TimEncodedMessage timEnc; + tmx::message_container_type container; + ss<(ss); + timMsg.set_contents(container.get_storage().get_tree()); + timEnc.encode_j2735_message(timMsg); + ASSERT_EQ(31, timEnc.get_msgId()); + string expectedHex = "001f526011c35d000000000023667bac0407299b9ef9e7a9b9408230dfffe4386ba00078005a53373df3cf5372810461b90ffff53373df3cf53728104618129800010704a04c7d7976ca3501872e1bb66ad19b2620"; + ASSERT_EQ(expectedHex, timEnc.get_payload_str()); +} } diff --git a/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt b/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt index 4d4653f15..6c913e69d 100644 --- a/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt +++ b/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CARMACloudPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( CARMACloudPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "CARMACloud") add_compile_options(-fPIC) @@ -30,7 +30,7 @@ BuildTmxPlugin () TARGET_INCLUDE_DIRECTORIES ( ${PROJECT_NAME} PUBLIC ${XercesC_INCLUDE_DIRS} ${NETSNMP_INCLUDE_DIRS} ${Qt5Core_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS}) -TARGET_LINK_LIBRARIES ( ${PROJECT_NAME} PUBLIC tmxutils ${XercesC_LIBRARY} ${NETSNMP_LIBRARIES} ${QHttpEngine_LIBRARY} ${Boost_SYSTEM_LIBRARY} ZLIB::ZLIB curl cpprest Qt5Widgets Qt5Core Qt5Network ssl crypto qhttpengine v2xhubWebAPI) +TARGET_LINK_LIBRARIES ( ${PROJECT_NAME} PUBLIC tmxutils ${XercesC_LIBRARY} ${NETSNMP_LIBRARIES} ${QHttpEngine_LIBRARY} ${Boost_SYSTEM_LIBRARY} ZLIB::ZLIB curl Qt5Widgets Qt5Core Qt5Network ssl crypto qhttpengine v2xhubWebAPI) link_directories(${CMAKE_PREFIX_PATH}/lib) \ No newline at end of file diff --git a/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt b/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt index a0bc494fb..7e4e9b6c9 100644 --- a/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt +++ b/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CARMAStreetsPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( CARMAStreetsPlugin VERSION 7.5.1 LANGUAGES CXX ) BuildTmxPlugin ( ) @@ -9,7 +9,7 @@ TARGET_LINK_LIBRARIES (${PROJECT_NAME} tmxutils rdkafka++ jsoncpp) ############# enable_testing() include_directories(${PROJECT_SOURCE_DIR}/src) -add_library(${PROJECT_NAME}_lib src/J2735MapToJsonConverter.cpp src/JsonToJ2735SpatConverter.cpp) +add_library(${PROJECT_NAME}_lib src/J2735MapToJsonConverter.cpp src/JsonToJ2735SpatConverter.cpp src/J2735ToSRMJsonConverter.cpp) target_link_libraries(${PROJECT_NAME}_lib PUBLIC ${TMXAPI_LIBRARIES} ${ASN_J2735_LIBRARIES} ${MYSQL_LIBRARIES} diff --git a/src/v2i-hub/CARMAStreetsPlugin/manifest.json b/src/v2i-hub/CARMAStreetsPlugin/manifest.json index 634421f62..c4fb269cd 100644 --- a/src/v2i-hub/CARMAStreetsPlugin/manifest.json +++ b/src/v2i-hub/CARMAStreetsPlugin/manifest.json @@ -25,6 +25,11 @@ "subtype":"MAP-P", "description":"Full geometric layout of the intersection." }, + { + "type":"J2735", + "subtype":"SRM", + "description": "Signal request message for intersection" + }, { "type":"J2735", "subtype":"SPAT-P", @@ -62,6 +67,11 @@ "default": "v2xhub_mobility_operation_in", "description": "Apache Kafka topic plugin will transmit message to." }, + { + "key":"SRMTopic", + "default": "v2xhub_srm_in", + "description": "Apache Kafka topic plugin will transmit message to." + }, { "key": "MobilityPathTopic", "default": "v2xhub_mobility_path_in", diff --git a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp old mode 100644 new mode 100755 index 6b3c1ba82..2e2fdf499 --- a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp +++ b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp @@ -25,6 +25,7 @@ CARMAStreetsPlugin::CARMAStreetsPlugin(string name) : AddMessageFilter < tsm3Message > (this, &CARMAStreetsPlugin::HandleMobilityOperationMessage); AddMessageFilter < tsm2Message > (this, &CARMAStreetsPlugin::HandleMobilityPathMessage); AddMessageFilter < MapDataMessage > (this, &CARMAStreetsPlugin::HandleMapMessage); + AddMessageFilter < SrmMessage > (this, &CARMAStreetsPlugin::HandleSRMMessage); SubscribeToMessages(); @@ -50,6 +51,7 @@ void CARMAStreetsPlugin::UpdateConfigSettings() { GetConfigValue("MobilityOperationTopic", _transmitMobilityOperationTopic); GetConfigValue("MobilityPathTopic", _transmitMobilityPathTopic); GetConfigValue("MapTopic", _transmitMAPTopic); + GetConfigValue("SRMTopic", _transmitSRMTopic); // Populate strategies config string config; GetConfigValue("MobilityOperationStrategies", config); @@ -286,6 +288,35 @@ void CARMAStreetsPlugin::HandleMobilityPathMessage(tsm2Message &msg, routeable_m } } +void CARMAStreetsPlugin::HandleSRMMessage(SrmMessage &msg, routeable_message &routeableMsg) +{ + J2735ToSRMJsonConverter srmJsonConverter; + std::vector srmJsonV; + try{ + srmJsonConverter.toSRMJsonV(srmJsonV , &msg); + }catch(std::exception& ex) + { + PLOG(logERROR) << "Fatal error with SRM To JSON converter. " << ex.what() << std::endl; + SetStatus(Key_SRMMessageSkipped, ++_srmMessageSkipped); + return; + } + + if(srmJsonV.empty()) + { + PLOG(logERROR) << "SRM message content is empty." << std::endl; + SetStatus(Key_SRMMessageSkipped, ++_srmMessageSkipped); + + }else{ + for (auto srmJson : srmJsonV) + { + Json::StreamWriterBuilder builder; + const std::string srmJsonStr = Json::writeString(builder, srmJson); + PLOG(logINFO) << "SRM Json message: " << srmJsonStr << std::endl; + produce_kafka_msg(srmJsonStr, _transmitSRMTopic); + } + } +} + void CARMAStreetsPlugin::HandleBasicSafetyMessage(BsmMessage &msg, routeable_message &routeableMsg) { try diff --git a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h old mode 100644 new mode 100755 index 01856cbf4..a9111e945 --- a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h +++ b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h @@ -16,6 +16,7 @@ #include #include "J2735MapToJsonConverter.h" #include "JsonToJ2735SpatConverter.h" +#include "J2735ToSRMJsonConverter.h" @@ -49,6 +50,10 @@ class CARMAStreetsPlugin: public PluginClient { * @param routeableMsg */ void HandleMapMessage(MapDataMessage &msg, routeable_message &routeableMsg); + /** + * @brief Subscribe to SRM message received from RSU and publish the message to a Kafka topic + */ + void HandleSRMMessage (SrmMessage &msg, routeable_message &routeableMsg); /** * @brief Subcribe to scheduling plan Kafka topic created by carma-streets */ @@ -78,6 +83,7 @@ class CARMAStreetsPlugin: public PluginClient { std::string _transmitMobilityPathTopic; std::string _transmitBSMTopic; std::string _transmitMAPTopic; + std::string _transmitSRMTopic; std::string _kafkaBrokerIp; std::string _kafkaBrokerPort; RdKafka::Conf *kafka_conf; @@ -155,6 +161,14 @@ class CARMAStreetsPlugin: public PluginClient { * @brief Intersection Id for intersection */ std::string _intersectionId = "UNSET"; + /** + * @brief Status label for SRM messages skipped due to errors. + */ + const char* Key_SRMMessageSkipped = "SRM messages skipped due to errors."; + /** + * @brief Count for SRM messages skipped due to errors. + */ + uint _srmMessageSkipped = 0; }; std::mutex _cfgLock; diff --git a/src/v2i-hub/CARMAStreetsPlugin/src/J2735ToSRMJsonConverter.cpp b/src/v2i-hub/CARMAStreetsPlugin/src/J2735ToSRMJsonConverter.cpp new file mode 100755 index 000000000..0ddde3d4a --- /dev/null +++ b/src/v2i-hub/CARMAStreetsPlugin/src/J2735ToSRMJsonConverter.cpp @@ -0,0 +1,135 @@ +#include "J2735ToSRMJsonConverter.h" + +namespace CARMAStreetsPlugin +{ + J2735ToSRMJsonConverter::J2735ToSRMJsonConverter() + { + } + + J2735ToSRMJsonConverter::~J2735ToSRMJsonConverter() + { + } + + void J2735ToSRMJsonConverter::toSRMJsonV(std::vector &jsonV, tmx::messages::SrmMessage *srm) + { + if(!srm) + { + return; + } + auto srm_ptr = srm->get_j2735_data(); + if(!srm_ptr || !srm_ptr->requests || srm_ptr->requests->list.count <= 0) + { + return; + } + + for(auto i = 0; i < srm_ptr->requests->list.count; i++) + { + Json::Value srmJson; + srmJson["MsgType"] = MsgType; + /*** + * Request data for one or more signalized intersections that support SRM dialogs. + */ + Json::Value request; + if(srm_ptr->sequenceNumber) + { + request["msgCount"] = srm_ptr->sequenceNumber; + } + if(srm_ptr->timeStamp){ + request["minuteOfYear"] = srm_ptr->timeStamp; + } + request["msOfMinute"] = srm_ptr->second; + if(srm_ptr->requests->list.array[i]->minute) + { + request["minuteOfYear"] = *srm_ptr->requests->list.array[i]->minute; + } + if(srm_ptr->requests->list.array[i]->second) + { + request["msOfMinute"] = *srm_ptr->requests->list.array[i]->second; + } + request["intersectionID"] = srm_ptr->requests->list.array[i]->request.id.id; + request["priorityRequestType"] = srm_ptr->requests->list.array[i]->request.requestType; + request["basicVehicleRole"] = srm_ptr->requestor.type->role; + + Json::Value inBoundLane; + switch(srm_ptr->requests->list.array[i]->request.inBoundLane.present) + { + case IntersectionAccessPoint_PR_NOTHING: + break; + case IntersectionAccessPoint_PR_lane: + inBoundLane["LaneID"] = srm_ptr->requests->list.array[i]->request.inBoundLane.choice.lane; + break; + case IntersectionAccessPoint_PR_approach: + inBoundLane["ApproachID"] = srm_ptr->requests->list.array[i]->request.inBoundLane.choice.approach; + break; + case IntersectionAccessPoint_PR_connection: + inBoundLane["ConnectionID"] = srm_ptr->requests->list.array[i]->request.inBoundLane.choice.connection; + break; + } + request["inBoundLane"] = inBoundLane; + + Json::Value expectedTimeOfArrival; + // Minute of the year + if(srm_ptr->requests->list.array[i]->minute) + { + expectedTimeOfArrival["ETA_Minute"] = *srm_ptr->requests->list.array[i]->minute; + } + if(srm_ptr->requests->list.array[i]->second) + { + expectedTimeOfArrival["ETA_Second"] = *srm_ptr->requests->list.array[i]->second; + } + /** + * The duration value is used to provide a short interval that extends + * the ETA so that the requesting vehicle can arrive at the point of service with + * uncertainty or with some desired duration of service. This concept can be used + * to avoid needing to frequently update the request. The requester must update + * the ETA and duration values if the period if services extends beyond the duration + * time. It should be assumed that if the vehicle does not clear the intersection + * when the duration is reached, the request will be cancelled and the intersection will + * revert to normal operation. + */ + if(srm_ptr->requests->list.array[i]->duration) + { + expectedTimeOfArrival["ETA_Duration"] = *srm_ptr->requests->list.array[i]->duration; + } + request["expectedTimeOfArrival"] = expectedTimeOfArrival; + + /** + * The requestor identifies itself using its current speed, heading and location. + */ + std::stringstream ss; + ss << srm_ptr->requestor.id.choice.entityID.buf; + auto id_len = srm_ptr->requestor.id.choice.entityID.size; + unsigned long id_num = 0; + for(auto i = 0; i < id_len; i++) + { + id_num = (id_num << 8) | srm_ptr->requestor.id.choice.entityID.buf[i]; + } + std::stringstream id_fill_ss; + id_fill_ss << std::hex << id_num; + request["vehicleID"] = id_fill_ss.str(); + if( srm_ptr->requestor.position) + { + if(srm_ptr->requestor.position->heading) + { + request["heading_Degree"] = *srm_ptr->requestor.position->heading; + } + if(srm_ptr->requestor.position->speed) + { + request["speed_MeterPerSecond"] = srm_ptr->requestor.position->speed->speed / FIFTY_TH; + } + } + + Json::Value position; + position["latitude_DecimalDegree"] = srm_ptr->requestor.position->position.lat / DEGREE_TO_TENTH_MICRODEGREE; + position["longitude_DecimalDegree"] = srm_ptr->requestor.position->position.Long / DEGREE_TO_TENTH_MICRODEGREE; + if(srm_ptr->requestor.position->position.elevation) + { + position["elevation_Meter"] = *srm_ptr->requestor.position->position.elevation * 10; + } + request["position"] = position; + srmJson["SignalRequest"] = request; + jsonV.push_back(srmJson); + } + + } +} diff --git a/src/v2i-hub/CARMAStreetsPlugin/src/J2735ToSRMJsonConverter.h b/src/v2i-hub/CARMAStreetsPlugin/src/J2735ToSRMJsonConverter.h new file mode 100755 index 000000000..aed9077db --- /dev/null +++ b/src/v2i-hub/CARMAStreetsPlugin/src/J2735ToSRMJsonConverter.h @@ -0,0 +1,27 @@ +#include "jsoncpp/json/json.h" +#include + +namespace CARMAStreetsPlugin +{ + class J2735ToSRMJsonConverter + { + private: + const std::string MsgType = "SRM"; + const float FIFTY_TH = 0.02; + const float DEGREE_TO_TENTH_MICRODEGREE = 10000000.0; + const int TEN_CM_TO_METER = 10; + + public: + /*** + *@brief Constructor to initialize the SRM to JSON converter + */ + J2735ToSRMJsonConverter(); + /*** + * @brief Convert J2735 SRM message into SignalRequests in JSON format + * @param Vector of JSON to be populated with SignalRequests from J2735 + * @param SrmMessage that has the J2735 SRM information + */ + void toSRMJsonV(std::vector &jsonV, tmx::messages::SrmMessage *srm); + ~J2735ToSRMJsonConverter(); + }; +} \ No newline at end of file diff --git a/src/v2i-hub/CARMAStreetsPlugin/test/test_J2735ToSRMJsonConverter.cpp b/src/v2i-hub/CARMAStreetsPlugin/test/test_J2735ToSRMJsonConverter.cpp new file mode 100644 index 000000000..aacbcaddf --- /dev/null +++ b/src/v2i-hub/CARMAStreetsPlugin/test/test_J2735ToSRMJsonConverter.cpp @@ -0,0 +1,137 @@ +#include +#include +#include + +class test_J2735ToSRMJsonConverter : public ::testing::Test +{ + +public: + test_J2735ToSRMJsonConverter() = default; + ~test_J2735ToSRMJsonConverter() = default; + +protected: + tmx::messages::SrmMessage *_srmMessage; + SignalRequestMessage_t *_message; + void SetUp() override + { + _message = (SignalRequestMessage_t *)calloc(1, sizeof(SignalRequestMessage_t)); + _message->second = 12; + RequestorDescription_t *requestor = (RequestorDescription_t *)calloc(1, sizeof(RequestorDescription_t)); + VehicleID_t *veh_id = (VehicleID_t *)calloc(1, sizeof(VehicleID_t)); + veh_id->present = VehicleID_PR_entityID; + TemporaryID_t *entity_id = (TemporaryID_t *)calloc(1, sizeof(TemporaryID_t)); + uint8_t my_bytes_id[4] = {(uint8_t)1, (uint8_t)12, (uint8_t)12, (uint8_t)10}; + entity_id->buf = my_bytes_id; + entity_id->size = sizeof(my_bytes_id); + veh_id->choice.entityID = *entity_id; + requestor->id = *veh_id; + RequestorType_t *requestType = (RequestorType_t *)calloc(1, sizeof(RequestorType_t)); + requestType->role = 0; + requestor->type = requestType; + RequestorPositionVector_t *position = (RequestorPositionVector_t *)calloc(1, sizeof(RequestorPositionVector_t)); + DSRC_Angle_t *heading_angle = (DSRC_Angle_t *)calloc(1, sizeof(DSRC_Angle_t)); + *heading_angle = 123; + position->heading = heading_angle; + Position3D_t *position_point = (Position3D_t *)calloc(1, sizeof(Position3D_t)); + DSRC_Elevation_t *elev = (DSRC_Elevation_t *)calloc(1, sizeof(DSRC_Elevation_t)); + *elev = 12; + position_point->elevation = elev; + position_point->lat = 3712333; + position_point->Long = 8012333; + position->position = *position_point; + TransmissionAndSpeed_t *speed = (TransmissionAndSpeed_t *)calloc(1, sizeof(TransmissionAndSpeed_t)); + speed->speed = 10; + TransmissionState_t *transmission_state = (TransmissionState_t *)calloc(1, sizeof(TransmissionState_t)); + *transmission_state = 1111; + speed->transmisson = 7; + position->speed = speed; + requestor->position = position; + _message->requestor = *requestor; + + SignalRequestList_t *requests = (SignalRequestList_t *)calloc(1, sizeof(SignalRequestList_t)); + //First: Request Package + SignalRequestPackage_t *request_package = (SignalRequestPackage_t *)calloc(1, sizeof(SignalRequestPackage_t)); + MinuteOfTheYear_t *min = (MinuteOfTheYear_t *)calloc(1, sizeof(MinuteOfTheYear_t)); + *min = 123; + request_package->minute = min; + DSecond_t *duration = (DSecond_t *)calloc(1, sizeof(DSecond_t)); + *duration = 122; + request_package->duration = duration; + DSecond_t *second = (DSecond_t *)calloc(1, sizeof(DSecond_t)); + *second = 1212; + request_package->second = second; + SignalRequest_t *request = (SignalRequest_t *)calloc(1, sizeof(SignalRequest_t)); + IntersectionReferenceID_t *refer_id = (IntersectionReferenceID_t *)calloc(1, sizeof(IntersectionReferenceID_t)); + refer_id->id = 1222; + request->id = *refer_id; + request->requestID = 1; + request->requestType = 0; + IntersectionAccessPoint_t *inBoundLane = (IntersectionAccessPoint_t *)calloc(1, sizeof(IntersectionAccessPoint_t)); + inBoundLane->present = IntersectionAccessPoint_PR_lane; + inBoundLane->choice.lane = 1; + request->inBoundLane = *inBoundLane; + request_package->request = *request; + asn_sequence_add(&requests->list.array, request_package); + + //Second: Request Package + SignalRequestPackage_t *request_package_2 = (SignalRequestPackage_t *)calloc(1, sizeof(SignalRequestPackage_t)); + request_package_2->minute = min; + request_package_2->duration = duration; + request_package_2->second = second; + SignalRequest_t *request_2 = (SignalRequest_t *)calloc(1, sizeof(SignalRequest_t)); + IntersectionReferenceID_t *referId2 = (IntersectionReferenceID_t *)calloc(1, sizeof(IntersectionReferenceID_t)); + referId2->id = 2333; + request_2->id = *referId2; + request_2->requestID = 2; + request_2->requestType = 1; + IntersectionAccessPoint_t *inBoundLane2 = (IntersectionAccessPoint_t *)calloc(1, sizeof(IntersectionAccessPoint_t)); + inBoundLane2->present = IntersectionAccessPoint_PR_approach; + inBoundLane2->choice.approach = 1; + request_2->inBoundLane = *inBoundLane2; + request_package_2->request = *request_2; + asn_sequence_add(&requests->list.array, request_package_2); + _message->requests = requests; + tmx::messages::SrmEncodedMessage srmEncodeMessage; + _srmMessage = new tmx::messages::SrmMessage(_message); + } +}; + +namespace unit_test +{ + TEST_F(test_J2735ToSRMJsonConverter, toSRMJson) + { + CARMAStreetsPlugin::J2735ToSRMJsonConverter srmConverter; + std::vector srmJsonV; + srmConverter.toSRMJsonV(srmJsonV, _srmMessage); + int expectedSrmSize = 2; + ASSERT_EQ(expectedSrmSize, srmJsonV.size()); + int i = 0; + for (auto srmJson : srmJsonV) + { + Json::FastWriter fastWriter; + std::string message = fastWriter.write(srmJson); + std::string expectedSrmStr = ""; + if (i == 0) + { + expectedSrmStr = "{\"MsgType\":\"SRM\",\"SignalRequest\":{\"basicVehicleRole\":0,\"expectedTimeOfArrival\":{\"ETA_Duration\":122,\"ETA_Minute\":123,\"ETA_Second\":1212},\"heading_Degree\":123,\"inBoundLane\":{\"LaneID\":1},\"intersectionID\":1222,\"minuteOfYear\":123,\"msOfMinute\":1212,\"position\":{\"elevation_Meter\":120,\"latitude_DecimalDegree\":0.37123331427574158,\"longitude_DecimalDegree\":0.80123329162597656},\"priorityRequestType\":0,\"speed_MeterPerSecond\":500.0,\"vehicleID\":\"10c0c0a\"}}\n"; + } + else if (i == 1) + { + expectedSrmStr = "{\"MsgType\":\"SRM\",\"SignalRequest\":{\"basicVehicleRole\":0,\"expectedTimeOfArrival\":{\"ETA_Duration\":122,\"ETA_Minute\":123,\"ETA_Second\":1212},\"heading_Degree\":123,\"inBoundLane\":{\"ApproachID\":1},\"intersectionID\":2333,\"minuteOfYear\":123,\"msOfMinute\":1212,\"position\":{\"elevation_Meter\":120,\"latitude_DecimalDegree\":0.37123331427574158,\"longitude_DecimalDegree\":0.80123329162597656},\"priorityRequestType\":1,\"speed_MeterPerSecond\":500.0,\"vehicleID\":\"10c0c0a\"}}\n"; + } + ASSERT_EQ(expectedSrmStr, message); + i++; + } + } + + TEST_F(test_J2735ToSRMJsonConverter, toSRMJsonNULLObj) + { + CARMAStreetsPlugin::J2735ToSRMJsonConverter srmConverter; + std::vector invalidSRMJson; + SignalRequestMessage_t *message = (SignalRequestMessage_t *)calloc(1, sizeof(SignalRequestMessage_t)); + auto invalidSRMmMessage = new tmx::messages::SrmMessage(message); + srmConverter.toSRMJsonV(invalidSRMJson, invalidSRMmMessage); + int expectedSrmSize = 0; + ASSERT_EQ(expectedSrmSize, invalidSRMJson.size()); + } +} diff --git a/src/v2i-hub/CDASimAdapter/CMakeLists.txt b/src/v2i-hub/CDASimAdapter/CMakeLists.txt index e8e8cd794..97468a2cf 100755 --- a/src/v2i-hub/CDASimAdapter/CMakeLists.txt +++ b/src/v2i-hub/CDASimAdapter/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CDASimAdapter VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( CDASimAdapter VERSION 7.5.1 LANGUAGES CXX ) set(CMAKE_CXX_STANDARD 17) FIND_PACKAGE( carma-clock ) diff --git a/src/v2i-hub/CDASimAdapter/manifest.json b/src/v2i-hub/CDASimAdapter/manifest.json index e01753f7a..aabe404be 100755 --- a/src/v2i-hub/CDASimAdapter/manifest.json +++ b/src/v2i-hub/CDASimAdapter/manifest.json @@ -14,20 +14,31 @@ "description":"The log level for this plugin" }, { - "key":"Longitude", + "key":"X", "default":"0.0", - "description":"Longitude (in degrees) of the location of the simulated infrastructure." + "description":"Cartesian X coordinate in simulated map (in meters)." }, { - "key":"Latitude", + "key":"Y", "default":"0.0", - "description":"Latitude (in degrees) of the location of the simulated infrastructure." + "description":"Cartesian Y coordinate in simulated map (in meters)." }, { - "key":"Elevation", + "key":"Z", "default":"0.0", - "description":"Elevation (in degrees) of the location of the simulated infrastructure." + "description":"Cartesian Z coordinate in simulated map (in meters)." + }, + { + "key":"MaxConnectionAttempts", + "default":"10", + "description":"Number of connection attempts CDASimAdapter plugin will execute before failing. Valid values are any integers greater than or equal to 1. Any value less than 1 will result in unlimited connection attemtps." + }, + { + "key":"ConnectionSleepTime", + "default":"4", + "description":"Number of seconds to wait after a failed CDASim connection attempt, before retrying to establish connection. Valid values are equal or greater than 1. Any value less than 1 will be treated as 1." } + ] } diff --git a/src/v2i-hub/CDASimAdapter/src/CDASimAdapter.cpp b/src/v2i-hub/CDASimAdapter/src/CDASimAdapter.cpp index a036ff6f2..01cec61ef 100644 --- a/src/v2i-hub/CDASimAdapter/src/CDASimAdapter.cpp +++ b/src/v2i-hub/CDASimAdapter/src/CDASimAdapter.cpp @@ -13,11 +13,22 @@ namespace CDASimAdapter{ } void CDASimAdapter::UpdateConfigSettings() { - GetConfigValue("Longitude", location.Longitude); - GetConfigValue("Latitude", location.Latitude); - GetConfigValue("Elevation", location.Elevation); - PLOG(logINFO) << "Location of Simulated V2X-Hub updated to : {" << location.Longitude << ", " - << location.Latitude << ", " << location.Elevation << "}." << std::endl; + std::scoped_lock lock(_lock); + bool success = false; + success = GetConfigValue("X", location.X); + success = success && GetConfigValue("Y", location.Y); + success = success && GetConfigValue("Z", location.Z); + PLOG(logINFO) << "Location of Simulated V2X-Hub updated to : {" << location.X << ", " + << location.Y << ", " << location.Z << "}." << std::endl; + success = success && GetConfigValue("MaxConnectionAttempts", max_connection_attempts); + success = success && GetConfigValue("ConnectionSleepTime", connection_sleep_time); + if (connection_sleep_time < 1 ) { + PLOG(logWARNING) << "ConnectionSleepTime of " << connection_sleep_time << " is invalid. Valid values are <= 1." << std::endl; + connection_sleep_time = 1; + } + if (!success) { + PLOG(logWARNING) << "Some configuration parameters were not successfully loaded! Please ensure configuration parameter keys are correct!" << std::endl; + } } void CDASimAdapter::OnConfigChanged(const char *key, const char *value) { @@ -32,14 +43,27 @@ namespace CDASimAdapter{ UpdateConfigSettings(); // While CARMA Simulation connection is down, attempt to reconnect - while ( !connection || !connection->is_connected() ) { - connect(); + int connection_attempts = 0; + while ( (!connection || !connection->is_connected()) && (connection_attempts < max_connection_attempts || max_connection_attempts < 1 ) ) { + PLOG(logINFO) << "Attempting CDASim connection " << connection_attempts << "/" << max_connection_attempts << " ..." << std::endl; + bool success = connect(); + if (success) { + PLOG(logINFO) << "Connection to CDASim established!" << std::endl; + } + connection_attempts++; + // Sleep for configurable seconds in between connection attempts. No sleep is required on final failing attempt + if ( !connection->is_connected() && (connection_attempts < max_connection_attempts || max_connection_attempts < 1 ) ) { + PLOG(logDEBUG) << "Sleeping for " << connection_sleep_time << " seconds before next connection attempt ..." << std::endl; + std::this_thread::sleep_for(std::chrono::seconds(connection_sleep_time)); + } } if ( connection->is_connected() ) { start_time_sync_thread_timer(); - start_amf_msg_thread(); - start_binary_msg_thread(); + start_immediate_forward_thread(); + start_message_receiver_thread(); + }else { + PLOG(logERROR) << "CDASim connection failed!" << std::endl; } } @@ -86,7 +110,7 @@ namespace CDASimAdapter{ uint time_sync_port = std::stoul(sim::get_sim_config(sim::TIME_SYNC_PORT)); uint v2x_port = std::stoul(sim::get_sim_config(sim::V2X_PORT)); uint sim_v2x_port = std::stoul(sim::get_sim_config(sim::SIM_V2X_PORT)); - uint infrastructure_id = std::stoul(sim::get_sim_config(sim::INFRASTRUCTURE_ID));; + std::string infrastructure_id = sim::get_sim_config(sim::INFRASTRUCTURE_ID); PLOG(logINFO) << "CDASim connecting " << simulation_ip << "\nUsing Registration Port : " << std::to_string( simulation_registration_port) << @@ -106,36 +130,42 @@ namespace CDASimAdapter{ catch (const TmxException &e) { PLOG(logERROR) << "Exception occured attempting to initialize CDASim Connection : " << e.what() << std::endl; return false; + } + catch (const std::invalid_argument &e ) { + // std::stoul throws invalid arguement exception when provided with a string that contains characters that are not numbers. + PLOG(logERROR) << "Exception occured attempting to initialize CDASim Connection : " << e.what() << + ". Check environment variables are set to the correct type!"; + return false; } return connection->connect(); } - void CDASimAdapter::start_amf_msg_thread() { - if ( !amf_thread_timer ) { - amf_thread_timer = std::make_unique(); + void CDASimAdapter::start_immediate_forward_thread() { + if ( !immediate_forward_timer ) { + immediate_forward_timer = std::make_unique(); } - amf_msg_tick_id = amf_thread_timer->AddPeriodicTick([this]() { + immediate_forward_tick_id = immediate_forward_timer->AddPeriodicTick([this]() { this->attempt_message_from_v2xhub(); } // end of lambda expression , std::chrono::milliseconds(100) ); - amf_thread_timer->Start(); + immediate_forward_timer->Start(); } - void CDASimAdapter::start_binary_msg_thread() { - if ( !binary_thread_timer ) { - binary_thread_timer = std::make_unique(); + void CDASimAdapter::start_message_receiver_thread() { + if ( !message_receiver_timer ) { + message_receiver_timer = std::make_unique(); } - binary_msg_tick_id = binary_thread_timer->AddPeriodicTick([this]() { + message_receiver_tick_id = message_receiver_timer->AddPeriodicTick([this]() { this->attempt_message_from_simulation(); } // end of lambda expression , std::chrono::milliseconds(100) ); - binary_thread_timer->Start(); + message_receiver_timer->Start(); } @@ -175,15 +205,15 @@ namespace CDASimAdapter{ void CDASimAdapter::start_time_sync_thread_timer() { PLOG(logDEBUG) << "Creating Thread Timer for time sync" << std::endl; - if ( !thread_timer ) { - thread_timer = std::make_unique(); + if ( !time_sync_timer ) { + time_sync_timer = std::make_unique(); } - time_sync_tick_id = thread_timer->AddPeriodicTick([this]() { + time_sync_tick_id = time_sync_timer->AddPeriodicTick([this]() { PLOG(logDEBUG1) << "Listening for time sync messages from CDASim." << std::endl; this->attempt_time_sync(); } // end of lambda expression , std::chrono::milliseconds(100)); - thread_timer->Start(); + time_sync_timer->Start(); } void CDASimAdapter::attempt_time_sync() { diff --git a/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp b/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp index b43e8c441..51f55eaf2 100644 --- a/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp +++ b/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp @@ -4,9 +4,9 @@ using namespace tmx::utils; namespace CDASimAdapter{ - CDASimConnection::CDASimConnection(const std::string &simulation_ip, const uint infrastructure_id, const uint simulation_registration_port, const uint sim_v2x_port, + CDASimConnection::CDASimConnection(const std::string &simulation_ip, const std::string &infrastructure_id, const uint simulation_registration_port, const uint sim_v2x_port, const std::string &local_ip, const uint time_sync_port, const uint v2x_port, - const WGS84Point &location) : + const Point &location) : _simulation_ip(simulation_ip), _infrastructure_id(infrastructure_id), _simulation_registration_port(simulation_registration_port), _simulation_v2x_port(sim_v2x_port), _local_ip(local_ip), _time_sync_port(time_sync_port), _v2x_port(v2x_port), _location(location) { @@ -33,8 +33,8 @@ namespace CDASimAdapter{ return _connected; } - std::string CDASimConnection::get_handshake_json(const uint infrastructure_id, const std::string &local_ip, const uint time_sync_port, const uint v2x_port, - const WGS84Point &location) const + std::string CDASimConnection::get_handshake_json(const std::string &infrastructure_id, const std::string &local_ip, const uint time_sync_port, const uint v2x_port, + const Point &location) const { Json::Value message; @@ -44,17 +44,17 @@ namespace CDASimAdapter{ message["infrastructureId"] = infrastructure_id; message["rxMessagePort"] = v2x_port; message["timeSyncPort"] = time_sync_port; - message["location"]["latitude"] = location.Latitude; - message["location"]["longitude"] = location.Longitude; - message["location"]["elevation"] = location.Elevation; + message["location"]["x"] = location.X; + message["location"]["y"] = location.Y; + message["location"]["z"] = location.Z; Json::StyledWriter writer; message_str = writer.write(message); return message_str; } - bool CDASimConnection::carma_simulation_handshake(const std::string &simulation_ip, const uint infrastructure_id, const uint simulation_registration_port, + bool CDASimConnection::carma_simulation_handshake(const std::string &simulation_ip, const std::string &infrastructure_id, const uint simulation_registration_port, const std::string &local_ip, const uint time_sync_port, const uint v2x_port, - const WGS84Point &location) + const Point &location) { // Create JSON message with the content std::string payload = ""; @@ -193,12 +193,20 @@ namespace CDASimAdapter{ void CDASimConnection::forward_message( const std::string &msg, const std::shared_ptr _client ) const { if ( !msg.empty() && _client) { + PLOG(logDEBUG) << "Sending UDP msg " << msg << " to host " << _client->GetAddress() + << ":" << _client->GetPort() << "." << std::endl; int ret =_client->Send(msg); if ( ret < 0) { throw UdpClientRuntimeError(("Failed to send message " + msg + " to " + _client->GetAddress() + ":" + std::to_string(_client->GetPort()) + " with error code : " + std::to_string(errno)).c_str()); } } + else if ( msg.empty() ) { + PLOG(logWARNING) << "Unable to send empty message to " << _client->GetAddress() << ":" << _client->GetPort() << "." << std::endl; + } + else { + PLOG(logWARNING) << "Unable to send message from uninitialized client." << std::endl; + } } void CDASimConnection::forward_v2x_message_to_simulation(const std::string &msg) const { diff --git a/src/v2i-hub/CDASimAdapter/src/include/CDASimAdapter.hpp b/src/v2i-hub/CDASimAdapter/src/include/CDASimAdapter.hpp index 6de71bcd6..fd586fafc 100644 --- a/src/v2i-hub/CDASimAdapter/src/include/CDASimAdapter.hpp +++ b/src/v2i-hub/CDASimAdapter/src/include/CDASimAdapter.hpp @@ -1,7 +1,7 @@ //============================================================================ -// Name : EpcwPlugin.cpp -// Author : -// Version : +// Name : CDASimAdapter.cpp +// Author : Paul Bourelly +// Version : 7.5.1 // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ @@ -23,24 +23,24 @@ #include #include "ThreadWorker.h" - - - -namespace CDASimAdapter { +namespace CDASimAdapter +{ /** - * @brief V2X-Hub Plugin that acts as a adapter for integration with CARMA-Simulation. Plugin used + * @brief V2X-Hub Plugin that acts as a adapter for integration with CARMA-Simulation. Plugin used * environment variable to be installed and enabled by default. */ - class CDASimAdapter: public tmx::utils::PluginClient{ + class CDASimAdapter : public tmx::utils::PluginClient + { public: /** * @brief CARMA-Simulation Infrastructure Adapter constructor. * @param name name of plugin. */ explicit CDASimAdapter(const std::string &name); - - int Main() override ; + + int Main() override; + protected: /** * @brief Called everytime a configuration value is changed for the plugin. @@ -60,7 +60,7 @@ namespace CDASimAdapter { */ void OnStateChange(IvpPluginState state) override; // Virtual method overrides END. - + /** * @brief Get Kafka Connection string from environment variable KAFKA_BROKER_ADDRESS and time sync topic name from * CARMA_INFRASTRUCTURE_TIME_SYNC_TOPIC and initialize a Kafka producer to forward time synchronization messages to @@ -77,12 +77,12 @@ namespace CDASimAdapter { /** * @brief Method to start thread timer for processing msg from v2xhub */ - void start_amf_msg_thread(); + void start_immediate_forward_thread(); /** * @brief Method to start thread timer for processing msg from CDASimConnection */ - void start_binary_msg_thread(); + void start_message_receiver_thread(); /** * @brief Method to consume msg in amf fromat from V2Xhub and forward to CDASimConnection @@ -107,18 +107,31 @@ namespace CDASimAdapter { * @brief Method to consume time sychrononization from CDASimConnection and forward to tmx core and CARMA Streets */ void attempt_time_sync(); - - private: - tmx::utils::WGS84Point location; + private: + // Simulated location of RSU + tmx::utils::Point location; + // Stores configurable MaxConnectionAttempts. Any value > 1 will result in infinite connection attempts. + int max_connection_attempts; + // Time in seconds between connection attempts. Most be greater than zero! + uint connection_sleep_time; + // Kafka producer for sending time_sync messages to carma-streets std::shared_ptr time_producer; + // CDASim connection std::unique_ptr connection; + // Mutex for configuration parameter thread safety std::mutex _lock; - std::unique_ptr thread_timer; + // Time sync thread to forward time sync messages to PluginClientClockAware V2X-Hub plugins. + std::unique_ptr time_sync_timer; + // Time sync thread id int time_sync_tick_id; - std::unique_ptr amf_thread_timer; - std::unique_ptr binary_thread_timer; - int amf_msg_tick_id; - int binary_msg_tick_id; + // Immediate forward thread to consume messages from the immediate forward plugin and send to CDASim + std::unique_ptr immediate_forward_timer; + // Immediate forward thread id + int immediate_forward_tick_id; + // Message receiver thread to consume messages from CDASim and forward them to the message receiver. + std::unique_ptr message_receiver_timer; + // Message receiver thread id + int message_receiver_tick_id; }; } \ No newline at end of file diff --git a/src/v2i-hub/CDASimAdapter/src/include/CDASimConnection.hpp b/src/v2i-hub/CDASimAdapter/src/include/CDASimConnection.hpp index ab6771609..86bd0ff95 100644 --- a/src/v2i-hub/CDASimAdapter/src/include/CDASimConnection.hpp +++ b/src/v2i-hub/CDASimAdapter/src/include/CDASimConnection.hpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include @@ -32,9 +32,9 @@ namespace CDASimAdapter { * @param location Simulationed location of infrastructure. * @param producer Kafka Producer for forwarding time synchronization messages. */ - explicit CDASimConnection( const std::string &simulation_ip, const uint infrastructure_id, const uint simulation_registration_port, + explicit CDASimConnection( const std::string &simulation_ip, const std::string &infrastructure_id, const uint simulation_registration_port, const uint sim_v2x_port, const std::string &local_ip, const uint time_sync_port, const uint v2x_port, - const tmx::utils::WGS84Point &location); + const tmx::utils::Point &location); /** * @brief Method to forward v2x message to CARMA Simulation @@ -95,9 +95,9 @@ namespace CDASimAdapter { * @param location simulated location of infrastructure hardware. * @return true if handshake successful and false if handshake unsuccessful. */ - bool carma_simulation_handshake(const std::string &simulation_ip, const uint infrastructure_id, const uint simulation_registration_port, + bool carma_simulation_handshake(const std::string &simulation_ip, const std::string &infrastructure_id, const uint simulation_registration_port, const std::string &local_ip, const uint time_sync_port, const uint v2x_port, - const tmx::utils::WGS84Point &location); + const tmx::utils::Point &location); /** * @brief Method to setup UDP Servers and Clients after handshake to facilate message forwarding. @@ -131,17 +131,17 @@ namespace CDASimAdapter { * @param location simulated location of infrastructure hardware. * @return true if handshake successful and false if handshake unsuccessful. */ - std::string get_handshake_json(const uint infrastructure_id, const std::string &local_ip, const uint time_sync_port, - const uint v2x_port, const tmx::utils::WGS84Point &location) const; + std::string get_handshake_json(const std::string &infrastructure_id, const std::string &local_ip, const uint time_sync_port, + const uint v2x_port, const tmx::utils::Point &location) const; std::string _simulation_ip; uint _simulation_registration_port; - uint _infrastructure_id; + std::string _infrastructure_id; uint _simulation_v2x_port; std::string _local_ip; uint _time_sync_port; uint _v2x_port; - tmx::utils::WGS84Point _location; + tmx::utils::Point _location; bool _connected = false; std::shared_ptr carma_simulation_listener; diff --git a/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp b/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp index fa00203ce..28b7376ab 100644 --- a/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp +++ b/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp @@ -23,9 +23,8 @@ namespace CDASimAdapter { protected: void SetUp() override { // Initialize CARMA Simulation connection with (0,0,0) location and mock kafka producer. - WGS84Point location; - connection = std::make_shared("127.0.0.1", 1212, 4567, 4678, "127.0.0.1", 1213, 1214, location); - + Point location; + connection = std::make_shared("127.0.0.1", "1212", 4567, 4678, "127.0.0.1", 1213, 1214, location); } void TearDown() override { @@ -47,6 +46,18 @@ namespace CDASimAdapter { connection->forward_message(test_message, client); } + TEST_F( TestCARMASimulationConnection, forward_message_invalid ) { + std::shared_ptr client = std::make_shared(); + std::string test_message = ""; + // ASSERT that we never call Send message. + EXPECT_CALL( *client, Send(test_message) ).Times(0); + // sent empty message + connection->forward_message(test_message,client); + test_message = "message"; + client = nullptr; + connection->forward_message(test_message, client); + } + TEST_F( TestCARMASimulationConnection, consume_msg){ std::shared_ptr server = std::make_shared(); @@ -71,19 +82,20 @@ namespace CDASimAdapter { } TEST_F( TestCARMASimulationConnection, get_handshake_json) { - WGS84Point location; - location.Elevation = 1000; - location.Latitude = 38.955; - location.Longitude = -77.149; + Point location; + location.X = 1000; + location.Y = 38.955; + location.Z = -77.149; + + ASSERT_EQ(connection->get_handshake_json("4566", "127.0.0.1", 4567, 4568, location), + "{\n \"infrastructureId\" : \"4566\",\n \"location\" : {\n \"x\" : 1000.0,\n \"y\" : 38.954999999999998,\n \"z\" : -77.149000000000001\n },\n \"rxMessageIpAddress\" : \"127.0.0.1\",\n \"rxMessagePort\" : 4568,\n \"timeSyncPort\" : 4567\n}\n"); - ASSERT_EQ(connection->get_handshake_json(4566, "127.0.0.1", 4567, 4568, location), - "{\n \"infrastructureId\" : 4566,\n \"location\" : {\n \"elevation\" : 1000.0,\n \"latitude\" : 38.954999999999998,\n \"longitude\" : -77.149000000000001\n },\n \"rxMessageIpAddress\" : \"127.0.0.1\",\n \"rxMessagePort\" : 4568,\n \"timeSyncPort\" : 4567\n}\n"); } TEST_F( TestCARMASimulationConnection, carma_simulation_handshake) { - WGS84Point location; + Point location; // UDP creation error - ASSERT_FALSE(connection->carma_simulation_handshake("", 45, NULL, + ASSERT_FALSE(connection->carma_simulation_handshake("", "45", NULL, "", 45, 45, location)); } diff --git a/src/v2i-hub/CommandPlugin/CMakeLists.txt b/src/v2i-hub/CommandPlugin/CMakeLists.txt index 651e1af0a..a1543ab51 100644 --- a/src/v2i-hub/CommandPlugin/CMakeLists.txt +++ b/src/v2i-hub/CommandPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CommandPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( CommandPlugin VERSION 7.5.1 LANGUAGES CXX ) FIND_PACKAGE (OpenSSL REQUIRED) diff --git a/src/v2i-hub/CswPlugin/CMakeLists.txt b/src/v2i-hub/CswPlugin/CMakeLists.txt index 66d0d9545..5e154a2c7 100644 --- a/src/v2i-hub/CswPlugin/CMakeLists.txt +++ b/src/v2i-hub/CswPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CswPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( CswPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "CSW") diff --git a/src/v2i-hub/DmsPlugin/CMakeLists.txt b/src/v2i-hub/DmsPlugin/CMakeLists.txt index 4508c8084..08cf09b17 100644 --- a/src/v2i-hub/DmsPlugin/CMakeLists.txt +++ b/src/v2i-hub/DmsPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( DmsPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( DmsPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Dynamic Message Sign") diff --git a/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt b/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt index 56f71f571..cc456077a 100644 --- a/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt +++ b/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT(ERVCloudForwardingPlugin VERSION 7.5.0 LANGUAGES CXX) +PROJECT(ERVCloudForwardingPlugin VERSION 7.5.1 LANGUAGES CXX) SET(TMX_PLUGIN_NAME "ERVCloudForwarding") add_compile_options(-fPIC) diff --git a/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt b/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt index e3d2365a2..31e28d6ae 100644 --- a/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt +++ b/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( ImmediateForwardPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( ImmediateForwardPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Immediate Forward") diff --git a/src/v2i-hub/LocationPlugin/CMakeLists.txt b/src/v2i-hub/LocationPlugin/CMakeLists.txt index eb929373b..5926227c4 100644 --- a/src/v2i-hub/LocationPlugin/CMakeLists.txt +++ b/src/v2i-hub/LocationPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -project( LocationPlugin VERSION 7.5.0 LANGUAGES CXX ) +project( LocationPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME Location) diff --git a/src/v2i-hub/MapPlugin/CMakeLists.txt b/src/v2i-hub/MapPlugin/CMakeLists.txt index 7cf372de0..553f1e58a 100644 --- a/src/v2i-hub/MapPlugin/CMakeLists.txt +++ b/src/v2i-hub/MapPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( MapPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( MapPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "MAP") diff --git a/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt b/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt index b63b6d6df..514b31984 100644 --- a/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt +++ b/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( MessageLoggerPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( MessageLoggerPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "MessageLoggerPlugin") diff --git a/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt b/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt index f77e4c1a3..908bc1e90 100644 --- a/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt +++ b/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( MessageReceiverPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( MessageReceiverPlugin VERSION 7.5.1 LANGUAGES CXX ) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt b/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt index 815527534..8c594fdbe 100644 --- a/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt +++ b/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( ODEForwardPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( ODEForwardPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "ODEForwardPlugin") diff --git a/src/v2i-hub/PedestrianPlugin/CMakeLists.txt b/src/v2i-hub/PedestrianPlugin/CMakeLists.txt index 8b0ba693f..ecb8c8cec 100755 --- a/src/v2i-hub/PedestrianPlugin/CMakeLists.txt +++ b/src/v2i-hub/PedestrianPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( PedestrianPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( PedestrianPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Pedestrian") add_compile_options(-fPIC) diff --git a/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt b/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt index eb069bfd7..199be4090 100644 --- a/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt +++ b/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( PortDrayagePlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( PortDrayagePlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "PortDrayage") set(CMAKE_AUTOMOC ON) diff --git a/src/v2i-hub/PreemptionPlugin/CMakeLists.txt b/src/v2i-hub/PreemptionPlugin/CMakeLists.txt index eed709d13..1613c3b46 100644 --- a/src/v2i-hub/PreemptionPlugin/CMakeLists.txt +++ b/src/v2i-hub/PreemptionPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( PreemptionPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( PreemptionPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Preemption") diff --git a/src/v2i-hub/RtcmPlugin/CMakeLists.txt b/src/v2i-hub/RtcmPlugin/CMakeLists.txt index f10a35a31..694b04ef2 100644 --- a/src/v2i-hub/RtcmPlugin/CMakeLists.txt +++ b/src/v2i-hub/RtcmPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( RtcmPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( RtcmPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "RTCM") diff --git a/src/v2i-hub/SpatPlugin/CMakeLists.txt b/src/v2i-hub/SpatPlugin/CMakeLists.txt index ec48c6f14..fb28fcada 100644 --- a/src/v2i-hub/SpatPlugin/CMakeLists.txt +++ b/src/v2i-hub/SpatPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( SpatPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( SpatPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "SPAT") diff --git a/src/v2i-hub/SpatPlugin/src/SpatPlugin.cpp b/src/v2i-hub/SpatPlugin/src/SpatPlugin.cpp index ecdad2fb0..c47a4863f 100644 --- a/src/v2i-hub/SpatPlugin/src/SpatPlugin.cpp +++ b/src/v2i-hub/SpatPlugin/src/SpatPlugin.cpp @@ -21,19 +21,13 @@ SpatPlugin::~SpatPlugin() { void SpatPlugin::UpdateConfigSettings() { GetConfigValue("SignalGroupMapping", signalGroupMappingJson, &data_lock); - GetConfigValue("Local_IP", localIp, &data_lock); - GetConfigValue("Local_UDP_Port", localUdpPort, &data_lock); - GetConfigValue("TSC_IP", tscIp, &data_lock); - GetConfigValue("TSC_Remote_SNMP_Port", tscRemoteSnmpPort, &data_lock); - GetConfigValue("Intersection_Name", intersectionName, &data_lock); - GetConfigValue("Intersection_Id", intersectionId, &data_lock); isConfigurationLoaded = true; diff --git a/src/v2i-hub/TimPlugin/CMakeLists.txt b/src/v2i-hub/TimPlugin/CMakeLists.txt index 79a3ac8ca..3f8c9779e 100644 --- a/src/v2i-hub/TimPlugin/CMakeLists.txt +++ b/src/v2i-hub/TimPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( TimPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( TimPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "TIM") add_compile_options(-fPIC) diff --git a/src/v2i-hub/TimPlugin/manifest.json b/src/v2i-hub/TimPlugin/manifest.json index 74a910212..293c504bf 100644 --- a/src/v2i-hub/TimPlugin/manifest.json +++ b/src/v2i-hub/TimPlugin/manifest.json @@ -23,26 +23,6 @@ "default":"/var/www/plugins/MAP/IVP_GF_TIM.xml", "description":"" }, - { - "key":"Start_Broadcast_Date", - "default":"01-01-2019", - "description":"The Start Broadcast Date for the TIM message in the (mm-dd-YYYY) format." - }, - { - "key":"Stop_Broadcast_Date", - "default":"12-31-2020", - "description":"The Stop Broadcast Date for the TIM message in the (mm-dd-YYYY) format." - }, - { - "key":"Start_Broadcast_Time", - "default":"06:00:00", - "description":"The Start Broadcast Time for the TIM message in the (HH:MM:SS) format." - }, - { - "key":"Stop_Broadcast_Time", - "default":"21:00:00", - "description":"The Start Broadcast Time for the TIM message in the (HH:MM:SS) format." - }, { "key":"WebServiceIP", "default":"127.0.0.1", @@ -52,6 +32,11 @@ "key":"WebServicePort", "default":"10000", "description":"Port at which Web service exists" + }, + { + "key":"LogLevel", + "default":"DEBUG", + "description": "TIM Plugin Log Level controls which log statements are printed to the terminal." } ] diff --git a/src/v2i-hub/TimPlugin/src/TimPlugin.cpp b/src/v2i-hub/TimPlugin/src/TimPlugin.cpp index 6002d8873..6aa2d8c8f 100644 --- a/src/v2i-hub/TimPlugin/src/TimPlugin.cpp +++ b/src/v2i-hub/TimPlugin/src/TimPlugin.cpp @@ -3,7 +3,6 @@ #include "Clock.h" #include "XmlCurveParser.h" #include -#include using namespace std; using namespace tmx::messages; @@ -12,9 +11,6 @@ using namespace xercesc; using namespace boost::property_tree; namespace TimPlugin { - - - /** * Construct a new TimPlugin with the given name. * @@ -31,9 +27,13 @@ TimPlugin::~TimPlugin() { void TimPlugin::TimRequestHandler(QHttpEngine::Socket *socket) { - + if(socket->bytesAvailable() == 0) + { + PLOG(logERROR) << "TimPlugin does not receive web service request content!" <::create(); QString st; while(socket->bytesAvailable()>0) { @@ -43,54 +43,23 @@ void TimPlugin::TimRequestHandler(QHttpEngine::Socket *socket) char* _cloudUpdate = array.data(); // would be the cloud update packet, needs parsing - std::stringstream ss; ss << _cloudUpdate; - - ptree ptr; - - // Catch XML parse exceptions + PLOG(logDEBUG) << "Received from webservice: " << ss.str() << std::endl; try { - // Using open command with std::ofstream::out mode overwrites existing files - tmpTIM.open("/tmp/tmpTIM.xml", std::ofstream::out); - read_xml(ss,ptr); - lock_guard lock(_cfgLock); - BOOST_FOREACH(auto &n, ptr.get_child("timdata")) - { - std::string labeltext = n.first; - - if(labeltext == "starttime") - _startTime = n.second.get_value(); - - if(labeltext == "stoptime") - _stopTime = n.second.get_value(); - - if(labeltext == "startdate") - _startDate = n.second.get_value(); - - if(labeltext == "stopdate") - _stopDate = n.second.get_value(); - - if(labeltext == "timupdate"){ - tmpTIM<(); - - _mapFile = "/tmp/tmpTIM.xml"; - _isMapFileNew = true; - } - - } - // Close file each time to avoid appending to open file - tmpTIM.close(); + tmx::message_container_type container; + container.load(ss); + _timMsgPtr = std::make_shared(); + _timMsgPtr->set_contents(container.get_storage().get_tree()); + _isTimUpdated = true; writeResponse(QHttpEngine::Socket::Created, socket); } - catch( const ptree_error &e ) { - PLOG(logERROR) << "Error parsing file: " << e.what() << std::endl; + catch (TmxException &ex) { + PLOG(logERROR) << "Failed to encode message : " << ex.what(); writeResponse(QHttpEngine::Socket::BadRequest, socket); } - - } /** * Write HTTP response. @@ -104,8 +73,6 @@ void TimPlugin::writeResponse(int responseCode , QHttpEngine::Socket *socket) { } - - int TimPlugin::StartWebService() { //Web services @@ -114,31 +81,36 @@ int TimPlugin::StartWebService() QCoreApplication a(placeholderC,placeholderX); QHostAddress address = QHostAddress(QString::fromStdString (webip)); - quint16 port = static_cast(webport); + quint16 port = static_cast(webport); QSharedPointer handler(new OpenAPI::OAIApiRequestHandler()); handler = QSharedPointer (new OpenAPI::OAIApiRequestHandler()); + auto router = QSharedPointer::create(); + router->setUpRoutes(); + QObject::connect(handler.data(), &OpenAPI::OAIApiRequestHandler::requestReceived, [&](QHttpEngine::Socket *socket) { - this->TimRequestHandler(socket); + TimRequestHandler(socket); + }); + + QObject::connect(handler.data(), &OpenAPI::OAIApiRequestHandler::requestReceived, [&](QHttpEngine::Socket *socket) { + router->processRequest(socket); }); QHttpEngine::Server server(handler.data()); if (!server.listen(address, port)) { - qCritical("TimPlugin:: Unable to listen on the specified port."); + qCritical("TimPlugin::Unable to listen on the specified port."); return 1; } - PLOG(logDEBUG4)<<"TimPlugin:: Started web service"; + PLOG(logINFO)<<"TimPlugin:: Started web service"; return a.exec(); } - void TimPlugin::UpdateConfigSettings() { - lock_guard lock(_cfgLock); GetConfigValue("Frequency", _frequency); @@ -154,12 +126,8 @@ void TimPlugin::UpdateConfigSettings() { } - GetConfigValue("Start_Broadcast_Date", _startDate); - GetConfigValue("Stop_Broadcast_Date", _stopDate); - GetConfigValue("Start_Broadcast_Time", _startTime); - GetConfigValue("Stop_Broadcast_Time", _stopTime); - GetConfigValue("WebServiceIP",webip); - GetConfigValue("WebServicePort",webport); + GetConfigValue("WebServiceIP", webip); + GetConfigValue("WebServicePort", webport); } @@ -183,56 +151,53 @@ void TimPlugin::OnStateChange(IvpPluginState state) { } } - - -bool TimPlugin::TimDuration() +bool TimPlugin::TimDuration(std::shared_ptr TimMsg) { - PLOG(logDEBUG)<<"TimPlugin:: Reached in TimDuration"; - - ostringstream firstTimTime_; - firstTimTime_ << _startDate << " " << _startTime; - auto firstTime = firstTimTime_.str(); - - ostringstream lastTimTime_; - lastTimTime_ << _stopDate << " " << _stopTime; - auto lastTime = lastTimTime_.str(); + PLOG(logINFO)<<"TimPlugin:: Reached in TimDuration upcon receiving TIM message."; + lock_guard lock(_cfgLock); + auto timPtr = TimMsg->get_j2735_data(); + //startTime unit of minute + auto startTime = timPtr->dataFrames.list.array[0]->startTime; + if(startTime >= 527040) + { + PLOG(logERROR) << "Invalid startTime." << std::endl; + return false; + } + //Duration is unit of minute + auto duration = timPtr->dataFrames.list.array[0]->duratonTime; + bool isPersist = false; + if(duration >= 32000) + { + PLOG(logERROR) << "Duration = 32000, ignore stop time." << std::endl; + isPersist = true; + } - istringstream stopTimTime(lastTime); - istringstream startTimTime(firstTime); - - // start time in seconds - struct tm date_start; - startTimTime >> get_time( &date_start, "%m-%d-%Y %H:%M:%S" ); - time_t secondsStart = mktime( & date_start ); - PLOG(logDEBUG) << "START : " << date_start.tm_mon << "-" << date_start.tm_mday << "-" - << date_start.tm_year << " " << date_start.tm_hour << ":" << date_start.tm_min << ":" - << date_start.tm_sec << std::endl; - // stop time in seconds - struct tm date_stop; - stopTimTime >> get_time( &date_stop, "%m-%d-%Y %H:%M:%S" ); - PLOG(logDEBUG) << "STOP : " << date_stop.tm_mon << "-" << date_stop.tm_mday << "-" - << date_stop.tm_year << " " << date_stop.tm_hour << ":" << date_stop.tm_min << ":" - << date_stop.tm_sec << std::endl; - time_t secondsStop = mktime( & date_stop ); - - // Current Time in seconds + //Get year start UTC in seconds auto t = time(nullptr); - struct tm tm; - localtime_r(&t, &tm); - ostringstream oss1; - oss1 << put_time(&tm, "%m-%d-%Y %H:%M:%S"); - auto _currentTimTime = oss1.str(); - istringstream currentTimTime(_currentTimTime); - struct tm date_current; - currentTimTime >> get_time( &date_current, "%m-%d-%Y %H:%M:%S" ); - PLOG(logDEBUG) << "CURRENT : " << date_current.tm_mon << "-" << date_current.tm_mday << "-" - << date_current.tm_year << " " << date_current.tm_hour << ":" << date_current.tm_min << ":" - << date_current.tm_sec << std::endl; - time_t secondsCurrent = mktime( & date_current ); - - PLOG(logDEBUG) << "Start : " << secondsStart << " Stop : " << secondsStop << - " Current : " << secondsCurrent << std::endl; - if ( secondsStart <= secondsCurrent && secondsCurrent <= secondsStop) { + struct tm* timeInfo = gmtime(&t); + ostringstream currentYearStartOS; + currentYearStartOS << (timeInfo->tm_year+1900) <<"-01-01T00:00:00.000Z"; + struct tm currentYearStartTimeInfo; + istringstream currentYearStartIS(currentYearStartOS.str()); + currentYearStartIS >> get_time( ¤tYearStartTimeInfo, "%Y-%m-%dT%H:%M:%S%Z" ); + currentYearStartTimeInfo.tm_isdst = 0; //Day light saving flag + PLOG(logINFO) << "Year Start : " << (currentYearStartTimeInfo.tm_mon + 1) << "-" << currentYearStartTimeInfo.tm_mday << "-" + << (currentYearStartTimeInfo.tm_year + 1900) << " " << currentYearStartTimeInfo.tm_hour << ":" << currentYearStartTimeInfo.tm_min << ":" + << currentYearStartTimeInfo.tm_sec << " DST:" << currentYearStartTimeInfo.tm_isdst << std::endl; + time_t secondsYearStart = mktime( ¤tYearStartTimeInfo ); + + //Start Time in seconds + time_t secondsStart = secondsYearStart + startTime * 60; + //Stop Time in seconds + time_t secondsStop = secondsStart + duration * 60; + + // Current UTC Time in seconds; + auto secondsCurrent = time(nullptr); + + //Comparing current time with start and end time + PLOG(logINFO) << "Year Start(s): " << secondsYearStart << " Broadcast Start(s):" << secondsStart << " Broadcast Stop(s): " << secondsStop << + " Current(s):" << secondsCurrent << " Elpased minutes since year start(min):" << ((secondsCurrent-secondsYearStart)/60.0)<< std::endl; + if ( secondsStart <= secondsCurrent && (secondsCurrent <= secondsStop || isPersist)) { return true; } else { return false; @@ -241,25 +206,18 @@ bool TimPlugin::TimDuration() bool TimPlugin::LoadTim(TravelerInformation *tim, const char *mapFile) { - memset(tim, 0, sizeof(TravelerInformation)); - // J2735 packet header. - //tim->msgID = DSRCmsgID_travelerInformation; DsrcBuilder::SetPacketId(tim); - // Data Frame (1 of 1). - XmlCurveParser curveParser; - // Read the curve file, which creates and populates the data frame of the TIM. if (!curveParser.ReadCurveFile(mapFile, tim)) return false; - _speedLimit = curveParser.SpeedLimit; PluginUtil::SetStatus(_plugin, "Speed Limit", _speedLimit); @@ -267,64 +225,82 @@ bool TimPlugin::LoadTim(TravelerInformation *tim, const char *mapFile) return true; } +bool TimPlugin::LoadTim(std::shared_ptr TimMsg, const char *mapFile) +{ + std::ifstream in = std::ifstream(mapFile, ios_base::in); + if(in && in.is_open()) + { + try + { + std::stringstream ss; + ss << in.rdbuf(); + in.close(); + + tmx::message_container_type container; + container.load(ss); + TimMsg->set_contents(container.get_storage().get_tree()); + PLOG(logINFO) << "Loaded MapFile and updated TIM." << std::endl; + return true; + } + catch(const std::exception& e) + { + PLOG(logERROR)<<"Cannot read file " << mapFile<state != IvpPluginState_error) { + if (IsPluginState(IvpPluginState_registered)) + { - while (TimDuration()) { - - if (IsPluginState(IvpPluginState_registered)) - { - uint64_t sendFrequency = _frequency; - - // Load the TIM from the map file if it is new. - //cout<<"TimPlugin:: isMAPfileNEW "<<_isMapFileNew< lock(_cfgLock); + PLOG(logINFO)<<"TimPlugin:: isMAPfileNEW "<<_isMapFileNew<(); + _isTimLoaded = LoadTim(_timMsgPtr, _mapFile.c_str()); + if(!_isTimLoaded) { - { - //lock_guard lock(_cfgLock); - //mapFileCopy = _mapFile; - _isMapFileNew = false; - } - _isTimLoaded = LoadTim(&_tim, _mapFile.c_str()); + _timMsgPtr = nullptr; } - - uint64_t time = Clock::GetMillisecondsSinceEpoch(); - - if (_isTimLoaded && (time - lastUpdateTime) > updateFrequency) - { - lastUpdateTime = time; - if (_isTimLoaded) - { - DsrcBuilder::SetPacketId(&_tim); - DsrcBuilder::SetStartTimeToYesterday(_tim.dataFrames.list.array[0]); - } + } + while (_timMsgPtr && TimDuration(_timMsgPtr)) + { + lock_guard lock(_cfgLock); + uint64_t sendFrequency = _frequency; + + if(_isTimUpdated){ + PLOG(logINFO) <<"TimPlugin:: _isTimUpdated via Post request: "<< _isTimUpdated< 0 && (time - lastSendTime) > sendFrequency) + if (_timMsgPtr) { - - lastSendTime = time; - TimMessage timMsg(_tim); - //PLOG(logERROR) <<"timMsg XML to send....."<< timMsg<(&timEncMsg); - if (rMsg) BroadcastMessage(*rMsg); + if (rMsg) BroadcastMessage(*rMsg); } + + //Make sure send frequency configuration is positive, otherwise set to default 1000 milliseconds + sendFrequency = sendFrequency > 0 ? sendFrequency: 1000; + //Sleep sendFrequency for every attempt to broadcast TIM + this_thread::sleep_for(chrono::milliseconds(sendFrequency)); } } this_thread::sleep_for(chrono::milliseconds(500)); diff --git a/src/v2i-hub/TimPlugin/src/TimPlugin.h b/src/v2i-hub/TimPlugin/src/TimPlugin.h index 7409b933b..82d7420e0 100644 --- a/src/v2i-hub/TimPlugin/src/TimPlugin.h +++ b/src/v2i-hub/TimPlugin/src/TimPlugin.h @@ -64,6 +64,7 @@ #include #include #include +#include @@ -103,8 +104,17 @@ class TimPlugin: public PluginClient { //void OnMessageReceived(IvpMessage *msg); void OnStateChange(IvpPluginState state); - bool TimDuration(); + /** + * @brief Calculate tim duration based on the J2735 TIM message startTime and Duration + */ + bool TimDuration(std::shared_ptr TimMsg); bool LoadTim(TravelerInformation *tim, const char *mapFile); + /** + * @brief Read map file and populate TIM message + * @param TimMsg A shared pointer to the TIM object to be updated + * @param mapFile File path that has the standard J2735 TIM message in XML format + */ + bool LoadTim(std::shared_ptr TimMsg, const char *mapFile); int StartWebService(); void TimRequestHandler(QHttpEngine::Socket *socket); void writeResponse(int responseCode , QHttpEngine::Socket *socket); @@ -118,21 +128,19 @@ class TimPlugin: public PluginClient { uint64_t _frequency = 0; - std::string _startDate; - std::string _stopDate; - std::string _startTime; - std::string _stopTime; std::string _timupdate; uint16_t webport; std::string webip; - TravelerInformation _tim; + std::shared_ptr _timMsgPtr; mutex _mapFileLock; string _mapFile; std::ofstream tmpTIM; atomic _isMapFileNew{false}; atomic _isTimFileNew{false}; + //Post request to update TIM + atomic _isTimUpdated{false}; bool _isTimLoaded = false; unsigned int _speedLimit = 0; int _lastMsgIdSent = -1;