From 62808c7d44e5936de83c50fe8af0f39c0814baf1 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Tue, 29 Jun 2021 16:31:23 +0200 Subject: [PATCH 01/28] feat add windows support --- .appveyor.yml | 28 ++ CMakeLists.txt | 60 ++++ digest.cc | 7 + pkcs11-env.h | 4 + pkcs11test.cc | 85 +++--- third_party/win32/cryptoki.h | 85 ++++++ third_party/win32/getopt.cpp | 519 +++++++++++++++++++++++++++++++++++ third_party/win32/getopt.h | 101 +++++++ 8 files changed, 841 insertions(+), 48 deletions(-) create mode 100644 .appveyor.yml create mode 100644 CMakeLists.txt create mode 100644 third_party/win32/cryptoki.h create mode 100644 third_party/win32/getopt.cpp create mode 100644 third_party/win32/getopt.h diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000..1d286e8 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,28 @@ +version: 0.0.0-{dev} +configuration: Release +platform: +- x86 +cache: + - C:/Tools/vcpkg/installed/ +environment: + APPVEYOR_SAVE_CACHE_ON_ERROR: true +install: +# Update vcpkg +- cd c:\tools\vcpkg +- cmd: git fetch +- cmd: git checkout 2021.05.12 +- cmd: bootstrap-vcpkg.bat +- cmd: vcpkg install gtest:x86-windows +- cmd: vcpkg update +- cmd: vcpkg upgrade --no-dry-run +build_script: +- cmd: if exist "C:\projects\pkcs11test\build" rd /s /q C:\projects\pkcs11test\build +- cmd: mkdir C:\projects\pkcs11test\build +- cmd: cd C:\projects\pkcs11test\build +- cmd: vcpkg integrate install +- cmd: cmake .. -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake +- cmd: cmake --build . --config RelWithDebInfo +- cmd: ctest -C RelWithDebInfo --progress --verbose +- cmd: cmake -DCMAKE_INSTALL_PREFIX=build/SoftHSMv2-$(Platform) -DCMAKE_INSTALL_CONFIG_NAME=RelWithDebInfo -P cmake_install.cmake +on_finish: + - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6a018c3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 3.20) +#set(CMAKE_CXX_STANDARD 11) +#set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +project(p11test) + + +set(SOURCES cipher.cc + describe.cc + digest.cc + dual.cc + globals.cc + hmac.cc + init.cc + key.cc + keypair.cc + login.cc + object.cc + pkcs11-describe.cc + pkcs11test.cc + rng.cc + session.cc + sign.cc + slot.cc + tookan.cc +) + +if(MSVC) + list(APPEND INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/win32) + + list(APPEND SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/win32/getopt.cpp) + +endif() + +list(APPEND INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/pkcs11) + + + +find_package(GTest CONFIG REQUIRED COMPONENTS CXX_LIB) +add_executable(${PROJECT_NAME} ${SOURCES}) +target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main) +target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIRS} ) + +install(TARGETS ${PROJECT_NAME} + DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + +install(FILES $ DESTINATION bin OPTIONAL) +#install(FILES $/gmock.dll DESTINATION bin OPTIONAL) +message("$") +install(FILES "C:/Projects/pkcs11test/tmp/Debug/gmockd.dll" DESTINATION bin OPTIONAL) + +get_cmake_property(_variableNames VARIABLES) +list (SORT _variableNames) +foreach (_variableName ${_variableNames}) + #message(STATUS "${_variableName}=${${_variableName}}") +endforeach() diff --git a/digest.cc b/digest.cc index 3433e6f..9198ca2 100644 --- a/digest.cc +++ b/digest.cc @@ -22,6 +22,13 @@ #include #include "pkcs11test.h" + +#ifdef _WIN32 +#include +#include +#endif + + #include #include #include diff --git a/pkcs11-env.h b/pkcs11-env.h index b20b813..3ace5c6 100644 --- a/pkcs11-env.h +++ b/pkcs11-env.h @@ -14,6 +14,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +#ifdef _WIN32 +#include "cryptoki.h" +#else /* From 2.1 of [PKCS11-base-v2.40]: Cryptoki structures SHALL be packed with 1-byte alignment. */ #if defined(STRICT_P11) # pragma pack(push, 1) @@ -28,6 +31,7 @@ #ifndef NULL_PTR #define NULL_PTR 0 #endif +#endif //_WIN32 #include diff --git a/pkcs11test.cc b/pkcs11test.cc index f55c12e..4e54712 100644 --- a/pkcs11test.cc +++ b/pkcs11test.cc @@ -13,8 +13,14 @@ // limitations under the License. // C headers +#include +#ifdef _WIN32 +#include +#include +#else #include #include +#endif // C++ headers #include @@ -24,7 +30,6 @@ #include #include #include -#include // Local headers #include "pkcs11test.h" @@ -54,11 +59,11 @@ int GetInteger(const CK_CHAR *val, int len) { } typedef vector TestList; -typedef map > SkippedTestMap; +typedef map SkippedTestMap; static SkippedTestMap skipped_tests; void TestSkipped(const char *testcase, const char *test, const string& reason) { if (skipped_tests.find(reason) == skipped_tests.end()) { - skipped_tests[reason] = std::unique_ptr(new TestList); + skipped_tests[reason] = new TestList; } string testname(testcase); testname += "."; @@ -83,22 +88,10 @@ void usage() { cerr << " -m name : name of PKCS#11 library" << endl; cerr << " -l path : path to PKCS#11 library" << endl; cerr << " -s id : slot ID to perform tests against" << endl; - cerr << " -S n : slot index (0 for first slot)" << endl; cerr << " -X : skip tests requiring SO login" << endl; cerr << " -v : verbose output" << endl; cerr << " -u pwd : user PIN/password" << endl; cerr << " -o pwd : security officer PIN/password" << endl; - cerr << " -w name : cipher to use for keys being wrapped, one of: { "; - for (const auto &key : kCipherInfo) { - static int i = 0; - if ((i % 3) == 0) { - cerr << endl; - cerr << " "; - } - cerr << ", " << key.first; - i++; - } - cerr << " }" << endl; cerr << " -I : perform token init tests **WILL WIPE TOKEN CONTENTS**" << endl; exit(1); } @@ -121,13 +114,25 @@ CK_C_GetFunctionList load_pkcs11_library(const char* libpath, const char* libnam exit(1); } - void* lib = dlopen(fullname.c_str(), RTLD_NOW); + void* lib; +#if defined WIN32 + fullname = "C:\\Projects\\SoftHSMv2\\tmp32\\src\\lib\\Debug\\softhsm2.dll"; + lib = LoadLibraryA(fullname.c_str()); +#else + lib = dlopen(fullname.c_str(), RTLD_NOW); +#endif if (lib == nullptr) { cerr << "Failed to dlopen(" << fullname << ")" << endl; exit(1); } - void* fn = dlsym(lib, "C_GetFunctionList"); + void* fn; +#if defined WIN32 + fn = GetProcAddress((HMODULE)lib, "C_GetFunctionList"); +#else + fn = dlsym(lib, "C_GetFunctionList"); +#endif + if (fn == nullptr) { cerr<< "Failed to dlsym(\"C_GetFunctionList\")" << endl; exit(1); @@ -148,12 +153,10 @@ int main(int argc, char* argv[]) { // Retrieve PKCS module location. bool explicit_slotid = false; - bool use_slot_index = false; - unsigned slot_index = 0; int opt; const char* module_name = nullptr; const char* module_path = nullptr; - while ((opt = getopt(argc, argv, "vIXl:m:s:S:u:o:w:h")) != -1) { + while ((opt = getopt(argc, argv, "vIXl:m:s:u:o:h")) != -1) { switch (opt) { case 'v': g_verbose = true; @@ -174,18 +177,12 @@ int main(int argc, char* argv[]) { g_slot_id = atoi(optarg); explicit_slotid = true; break; - case 'S': - slot_index = atoi(optarg); - use_slot_index = true; case 'u': g_user_pin = optarg; break; case 'o': g_so_pin = optarg; break; - case 'w': - g_wrap_mechanism = optarg; - break; case 'h': default: usage(); @@ -196,6 +193,10 @@ int main(int argc, char* argv[]) { // Load the module. CK_C_GetFunctionList get_fn_list = load_pkcs11_library(module_path, module_name); +// CK_FUNCTION_LIST_PTR p11; +// (*get_fn_list)(&p11); +// p11->C_Initialize(NULL_PTR); + // Retrieve the set of function pointers (C_GetFunctionList is the only function it's OK to call before C_Initialize). if (get_fn_list(&g_fns) != CKR_OK) { cerr << "Failed to retrieve list of functions" << endl; @@ -209,32 +210,20 @@ int main(int argc, char* argv[]) { exit(1); } - if (use_slot_index || !explicit_slotid) { - CK_SLOT_ID slots[32]; - CK_ULONG slot_count = 32; + if (!explicit_slotid) { + // No slot specified; OK if there's only one accessible slot. + CK_SLOT_ID slots[2]; + CK_ULONG slot_count = 2; rv = g_fns->C_GetSlotList(CK_TRUE, slots, &slot_count); if (rv == CKR_OK) { - if (slot_count == 0) { + if (slot_count == 1) { + g_slot_id = slots[0]; + } else if (slot_count == 0) { cerr << "No slots with tokens available" << endl; exit(1); } else { - if (!use_slot_index) { - if (slot_count > 1) { - cerr << "Multiple slots with tokens available; specify one with -s" << endl; - for (unsigned i = 0; i < slot_count; i++) { - cerr << "Slot " << i << "= ID: " << slots[i] << endl; - } - exit(1); - } - // default to the first slot (slot_index = 0) - } - - if (slot_index >= slot_count) { - cerr << "Slot index " << slot_index << " invalid, there are only " << slot_count << " slots." << endl; - exit(1); - } - - g_slot_id = slots[slot_index]; + cerr << "Multiple slots with tokens available; specify one with -s" << endl; + exit(1); } } else { cerr << "Failed to retrieve slot list" << endl; @@ -269,7 +258,7 @@ int main(int argc, char* argv[]) { g_token_flags = token.flags; memcpy(g_token_label, token.label, sizeof(g_token_label)); - if (!(g_token_flags & CKF_LOGIN_REQUIRED)) { + if ((g_token_flags & CKF_LOGIN_REQUIRED)) { // Disable all tests that require login in their fixture. // This unfortunately relies on some gTest innards. string filter(testing::GTEST_FLAG(filter).c_str()); diff --git a/third_party/win32/cryptoki.h b/third_party/win32/cryptoki.h new file mode 100644 index 0000000..01354aa --- /dev/null +++ b/third_party/win32/cryptoki.h @@ -0,0 +1,85 @@ +/* cryptoki.h include file for PKCS #11. */ +/* $Revision: 1.4 $ */ + +/* License to copy and use this software is granted provided that it is + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface + * (Cryptoki)" in all material mentioning or referencing this software. + + * License is also granted to make and use derivative works provided that + * such works are identified as "derived from the RSA Security Inc. PKCS #11 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or + * referencing the derived work. + + * RSA Security Inc. makes no representations concerning either the + * merchantability of this software or the suitability of this software for + * any particular purpose. It is provided "as is" without express or implied + * warranty of any kind. + */ + +/* This is a sample file containing the top level include directives + * for building Win32 Cryptoki libraries and applications. + */ + +#ifndef ___CRYPTOKI_H_INC___ +#define ___CRYPTOKI_H_INC___ + +#ifdef _WIN32 +#pragma pack(push, cryptoki, 1) + +/* Specifies that the function is a DLL entry point. */ +#define CK_IMPORT_SPEC __declspec(dllimport) + +/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do + * not define it in applications. + */ +#ifdef CRYPTOKI_EXPORTS +/* Specified that the function is an exported DLL entry point. */ +#define CK_EXPORT_SPEC __declspec(dllexport) +#else +#define CK_EXPORT_SPEC CK_IMPORT_SPEC +#endif + +/* Ensures the calling convention for Win32 builds */ +#define CK_CALL_SPEC __cdecl + +#define CK_PTR * + +#define CK_DEFINE_FUNCTION(returnType, name) \ + returnType CK_EXPORT_SPEC CK_CALL_SPEC name + +#define CK_DECLARE_FUNCTION(returnType, name) \ + returnType CK_EXPORT_SPEC CK_CALL_SPEC name + +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name) + +#define CK_CALLBACK_FUNCTION(returnType, name) \ + returnType (CK_CALL_SPEC CK_PTR name) + +#ifndef NULL_PTR +#define NULL_PTR 0 +#endif + +#include "pkcs11.h" + +#pragma pack(pop, cryptoki) + +#else +/* UNIX version */ +#define CK_PTR * +#define CK_DEFINE_FUNCTION(returnType, name) \ + returnType name +#define CK_DECLARE_FUNCTION(returnType, name) \ + returnType name +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + returnType (CK_PTR name) +#define CK_CALLBACK_FUNCTION(returnType, name) \ + returnType (CK_PTR name) +#ifndef NULL_PTR +#define NULL_PTR 0 +#endif +#include "pkcs11.h" + +#endif + +#endif /* ___CRYPTOKI_H_INC___ */ diff --git a/third_party/win32/getopt.cpp b/third_party/win32/getopt.cpp new file mode 100644 index 0000000..d60ef88 --- /dev/null +++ b/third_party/win32/getopt.cpp @@ -0,0 +1,519 @@ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#include +#include +#include + +#ifdef _WIN32 + +/* Windows needs warnx(). We change the definition though: + * 1. (another) global is defined, opterrmsg, which holds the error message + * 2. errors are always printed out on stderr w/o the program name + * Note that opterrmsg always gets set no matter what opterr is set to. The + * error message will not be printed if opterr is 0 as usual. + */ + +#include +#include + +extern char opterrmsg[128]; +char opterrmsg[128]; /* last error message is stored here */ + +static void warnx(int print_error, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (fmt != NULL) + _vsnprintf(opterrmsg, 128, fmt, ap); + else + opterrmsg[0]='\0'; + va_end(ap); + if (print_error) { + fprintf(stderr, opterrmsg); + fprintf(stderr, "\n"); + } +} + +#endif /*_WIN32*/ + +/* not part of the original file */ +#ifndef _DIAGASSERT +#define _DIAGASSERT(X) +#endif + +#if HAVE_CONFIG_H && !HAVE_GETOPT_LONG && !HAVE_DECL_OPTIND +#define REPLACE_GETOPT +#endif + +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#if !HAVE_GETOPT_LONG +#define IGNORE_FIRST (*options == '-' || *options == '+') +#define PRINT_ERROR ((opterr) && ((*options != ':') \ + || (IGNORE_FIRST && options[1] != ':'))) +#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL) +#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST) +/* XXX: GNU ignores PC if *options == '-' */ +#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-') + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((IGNORE_FIRST && options[1] == ':') \ + || (*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +static int getopt_internal(int, char * const *, const char *); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return b; +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, + int opt_end, char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + _DIAGASSERT(nargv != NULL); + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + * Returns -2 if -- is found (can be long option or end of options marker). + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options) +{ + char *oli; /* option letter list index */ + int optchar; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + + optarg = NULL; + + /* + * XXX Some programs (like rsyncd) expect to be able to + * XXX re-initialize optind to 0 and have getopt_long(3) + * XXX properly function again. Work around this braindamage. + */ + if (optind == 0) + optind = 1; + + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return -1; + } + if ((*(place = nargv[optind]) != '-') + || (place[1] == '\0')) { /* found non-option */ + place = EMSG; + if (IN_ORDER) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return INORDER; + } + if (!PERMUTE) { + /* + * if no permutation wanted, stop parsing + * at first non-option + */ + return -1; + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + if (place[1] && *++place == '-') { /* found "--" */ + place++; + return -2; + } + } + if ((optchar = (int)*place++) == (int)':' || + (oli = (char *) strchr(options + (IGNORE_FIRST ? 1 : 0), + optchar)) == NULL) { + /* option letter unknown or ':' */ + if (!*place) + ++optind; +#ifndef _WIN32 + if (PRINT_ERROR) + warnx(illoptchar, optchar); +#else + warnx(PRINT_ERROR, illoptchar, optchar); +#endif + optopt = optchar; + return BADCH; + } + if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ + /* XXX: what if no long options provided (called by getopt)? */ + if (*place) + return -2; + + if (++optind >= nargc) { /* no arg */ + place = EMSG; +#ifndef _WIN32 + if (PRINT_ERROR) + warnx(recargchar, optchar); +#else + warnx(PRINT_ERROR, recargchar, optchar); +#endif + optopt = optchar; + return BADARG; + } else /* white space */ + place = nargv[optind]; + /* + * Handle -W arg the same as --arg (which causes getopt to + * stop parsing). + */ + return -2; + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + /* XXX: disable test for :: if PC? (GNU doesn't) */ + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; +#ifndef _WIN32 + if (PRINT_ERROR) + warnx(recargchar, optchar); +#else + warnx(PRINT_ERROR, recargchar, optchar); +#endif + optopt = optchar; + return BADARG; + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return optchar; +} + +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the real getopt] + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + int retval; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + + if ((retval = getopt_internal(nargc, nargv, options)) == -2) { + ++optind; + /* + * We found an option (--), so if we skipped non-options, + * we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, optind, + nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + retval = -1; + } + return retval; +} + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, + char * const *nargv, + const char *options, + const struct option *long_options, + int *idx) +{ + int retval; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + _DIAGASSERT(long_options != NULL); + /* idx may be NULL */ + + if ((retval = getopt_internal(nargc, nargv, options)) == -2) { + char *current_argv, *has_equal; + size_t current_argv_len; + int i, match; + + current_argv = place; + match = -1; + + optind++; + place = EMSG; + + if (*current_argv == '\0') { /* found "--" */ + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return -1; + } + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == + (unsigned)current_argv_len) { + /* exact match */ + match = i; + break; + } + if (match == -1) /* partial match */ + match = i; + else { + /* ambiguous abbreviation */ +#ifndef _WIN32 + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); +#else + warnx(PRINT_ERROR, ambig, (int)current_argv_len, + current_argv); +#endif + optopt = 0; + return BADCH; + } + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { +#ifndef _WIN32 + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); +#else + warnx(PRINT_ERROR, noarg, (int)current_argv_len, + current_argv); +#endif + /* + * XXX: GNU sets optopt to val regardless of + * flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return BADARG; + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use + * next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' + * indicates no error should be generated + */ +#ifndef _WIN32 + if (PRINT_ERROR) + warnx(recargstring, current_argv); +#else + warnx(PRINT_ERROR, recargstring, current_argv); +#endif + /* + * XXX: GNU sets optopt to val regardless + * of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return BADARG; + } + } else { /* unknown option */ +#ifndef _WIN32 + if (PRINT_ERROR) + warnx(illoptstring, current_argv); +#else + warnx(PRINT_ERROR, illoptstring, current_argv); +#endif + optopt = 0; + return BADCH; + } + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + retval = 0; + } else + retval = long_options[match].val; + if (idx) + *idx = match; + } + return retval; +} +#endif /* !GETOPT_LONG */ diff --git a/third_party/win32/getopt.h b/third_party/win32/getopt.h new file mode 100644 index 0000000..f6b65a5 --- /dev/null +++ b/third_party/win32/getopt.h @@ -0,0 +1,101 @@ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +#ifdef _WIN32 +/* from */ +# ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +# else +# define __BEGIN_DECLS +# define __END_DECLS +# endif +# define __P(args) args +#endif + +/*#ifndef _WIN32 +#include +#include +#endif*/ + +/* + * Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions + */ +#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE) +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +struct option { + /* name of long option */ + const char *name; + /* + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; + /* if not NULL, set *flag to val when option found */ + int *flag; + /* if flag not NULL, value to set *flag to; else return value */ + int val; +}; + +__BEGIN_DECLS +int getopt_long __P((int, char * const *, const char *, + const struct option *, int *)); +__END_DECLS +#endif + +#ifdef _WIN32 +/* These are global getopt variables */ +__BEGIN_DECLS + +extern int opterr, /* if error message should be printed */ + optind, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +extern char* optarg; /* argument associated with option */ + +/* Original getopt */ +int getopt __P((int, char * const *, const char *)); + +__END_DECLS +#endif + +#endif /* !_GETOPT_H_ */ From 8b52bc6f8779b5817d33d5fb618ad1edab5cd7f0 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Tue, 29 Jun 2021 16:57:44 +0200 Subject: [PATCH 02/28] fix cmake minimal version --- .appveyor.yml | 5 +++-- CMakeLists.txt | 19 +++++++------------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 1d286e8..457bcdc 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,6 +2,7 @@ version: 0.0.0-{dev} configuration: Release platform: - x86 +#- x64 cache: - C:/Tools/vcpkg/installed/ environment: @@ -12,7 +13,7 @@ install: - cmd: git fetch - cmd: git checkout 2021.05.12 - cmd: bootstrap-vcpkg.bat -- cmd: vcpkg install gtest:x86-windows +- cmd: vcpkg install gtest - cmd: vcpkg update - cmd: vcpkg upgrade --no-dry-run build_script: @@ -23,6 +24,6 @@ build_script: - cmd: cmake .. -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake - cmd: cmake --build . --config RelWithDebInfo - cmd: ctest -C RelWithDebInfo --progress --verbose -- cmd: cmake -DCMAKE_INSTALL_PREFIX=build/SoftHSMv2-$(Platform) -DCMAKE_INSTALL_CONFIG_NAME=RelWithDebInfo -P cmake_install.cmake +- cmd: cmake -DCMAKE_INSTALL_PREFIX=out/ -DCMAKE_INSTALL_CONFIG_NAME=RelWithDebInfo -P cmake_install.cmake on_finish: - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a018c3..380d83a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,4 @@ -cmake_minimum_required(VERSION 3.20) -#set(CMAKE_CXX_STANDARD 11) -#set(CMAKE_CXX_EXTENSIONS OFF) +cmake_minimum_required(VERSION 3.16) set(CMAKE_CXX_STANDARD_REQUIRED ON) project(p11test) @@ -49,12 +47,9 @@ install(TARGETS ${PROJECT_NAME} ) install(FILES $ DESTINATION bin OPTIONAL) -#install(FILES $/gmock.dll DESTINATION bin OPTIONAL) -message("$") -install(FILES "C:/Projects/pkcs11test/tmp/Debug/gmockd.dll" DESTINATION bin OPTIONAL) - -get_cmake_property(_variableNames VARIABLES) -list (SORT _variableNames) -foreach (_variableName ${_variableNames}) - #message(STATUS "${_variableName}=${${_variableName}}") -endforeach() + +#get_cmake_property(_variableNames VARIABLES) +#list (SORT _variableNames) +#foreach (_variableName ${_variableNames}) +# message(STATUS "${_variableName}=${${_variableName}}") +#endforeach() From 37b6adab291e6dd83198d4cb92592383f2ec714d Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Tue, 29 Jun 2021 17:03:58 +0200 Subject: [PATCH 03/28] fix build set version --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 457bcdc..76e7f68 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,4 @@ -version: 0.0.0-{dev} +version: 0.0.0 configuration: Release platform: - x86 From 0bfde54438e6bf97eb26a2045438f3ecd634aae7 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Tue, 29 Jun 2021 17:20:57 +0200 Subject: [PATCH 04/28] fix disable appveyor remote desktop --- .appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 76e7f68..d1a6966 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -25,5 +25,5 @@ build_script: - cmd: cmake --build . --config RelWithDebInfo - cmd: ctest -C RelWithDebInfo --progress --verbose - cmd: cmake -DCMAKE_INSTALL_PREFIX=out/ -DCMAKE_INSTALL_CONFIG_NAME=RelWithDebInfo -P cmake_install.cmake -on_finish: - - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +#on_finish: +# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) From 6306bc6b4c9859834aa36ec5cd4a52370eea8947 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Tue, 29 Jun 2021 21:44:53 +0200 Subject: [PATCH 05/28] fix static cast size_t to CK_ULONG error C2397: conversion from 'unsigned __int64' to 'CK_ULONG' requires a narrow ing conversion --- cipher.cc | 4 ++-- hmac.cc | 2 +- keypair.cc | 20 ++++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cipher.cc b/cipher.cc index 42302a9..f08eb2e 100644 --- a/cipher.cc +++ b/cipher.cc @@ -577,7 +577,7 @@ TEST_F(ReadOnlySessionTest, CreateSecretKeyAttributes) { {CKA_DECRYPT, (CK_VOID_PTR)&g_ck_true, sizeof(CK_BBOOL)}, {CKA_CLASS, &key_class, sizeof(key_class)}, {CKA_KEY_TYPE, (CK_VOID_PTR)&key_type, sizeof(key_type)}, - {CKA_VALUE, (CK_VOID_PTR)key.data(), key.size()}, + {CKA_VALUE, (CK_VOID_PTR)key.data(), static_cast(key.size())}, }; CK_OBJECT_HANDLE key_object; ASSERT_CKR_OK(g_fns->C_CreateObject(session_, attrs.data(), attrs.size(), &key_object)); @@ -626,7 +626,7 @@ TEST_F(ReadOnlySessionTest, SecretKeyTestVectors) { {CKA_DECRYPT, (CK_VOID_PTR)&g_ck_true, sizeof(CK_BBOOL)}, {CKA_CLASS, &key_class, sizeof(key_class)}, {CKA_KEY_TYPE, (CK_VOID_PTR)&key_type, sizeof(key_type)}, - {CKA_VALUE, (CK_VOID_PTR)key.data(), key.size()}, + {CKA_VALUE, (CK_VOID_PTR)key.data(), static_cast(key.size())}, }; CK_OBJECT_HANDLE key_object; ASSERT_CKR_OK(g_fns->C_CreateObject(session_, attrs.data(), attrs.size(), &key_object)); diff --git a/hmac.cc b/hmac.cc index 38c56c8..c2491bf 100644 --- a/hmac.cc +++ b/hmac.cc @@ -188,7 +188,7 @@ TEST_F(ReadOnlySessionTest, HmacTestVectors) { {CKA_VERIFY, (CK_VOID_PTR)&g_ck_true, sizeof(CK_BBOOL)}, {CKA_CLASS, &key_class, sizeof(key_class)}, {CKA_KEY_TYPE, (CK_VOID_PTR)&key_type, sizeof(key_type)}, - {CKA_VALUE, (CK_VOID_PTR)key.data(), key.size()}, + {CKA_VALUE, (CK_VOID_PTR)key.data(), static_cast(key.size())}, }; CK_OBJECT_HANDLE key_object; ASSERT_CKR_OK(g_fns->C_CreateObject(session_, attrs.data(), attrs.size(), &key_object)); diff --git a/keypair.cc b/keypair.cc index 449b10f..173a7cb 100644 --- a/keypair.cc +++ b/keypair.cc @@ -234,8 +234,8 @@ TEST_F(ReadOnlySessionTest, CreateKeyPairObjects) { {CKA_PRIVATE, (CK_VOID_PTR)&g_ck_false, sizeof(CK_BBOOL)}, {CKA_CLASS, &public_key_class, sizeof(public_key_class)}, {CKA_KEY_TYPE, (CK_VOID_PTR)&key_type, sizeof(key_type)}, - {CKA_PUBLIC_EXPONENT, (CK_VOID_PTR)public_exponent.data(), public_exponent.size()}, - {CKA_MODULUS, (CK_VOID_PTR)public_modulus.data(), public_modulus.size()}, + {CKA_PUBLIC_EXPONENT, (CK_VOID_PTR)public_exponent.data(), static_cast(public_exponent.size())}, + {CKA_MODULUS, (CK_VOID_PTR)public_modulus.data(), static_cast(public_modulus.size())}, }; EXPECT_CKR_OK(g_fns->C_CreateObject(session_, public_attrs.data(), @@ -254,34 +254,34 @@ TEST_F(ReadOnlySessionTest, CreateKeyPairObjects) { {CKA_PRIVATE, (CK_VOID_PTR)&g_ck_false, sizeof(CK_BBOOL)}, {CKA_CLASS, &private_key_class, sizeof(private_key_class)}, {CKA_KEY_TYPE, (CK_VOID_PTR)&key_type, sizeof(key_type)}, - {CKA_PUBLIC_EXPONENT, (CK_VOID_PTR)public_exponent.data(), public_exponent.size()}, - {CKA_PRIVATE_EXPONENT, (CK_BYTE_PTR)private_exponent.data(), private_exponent.size()}, - {CKA_MODULUS, (CK_VOID_PTR)public_modulus.data(), public_modulus.size()}, + {CKA_PUBLIC_EXPONENT, (CK_VOID_PTR)public_exponent.data(), static_cast(public_exponent.size())}, + {CKA_PRIVATE_EXPONENT, (CK_BYTE_PTR)private_exponent.data(), static_cast(private_exponent.size())}, + {CKA_MODULUS, (CK_VOID_PTR)public_modulus.data(), static_cast(public_modulus.size())}, }; string prime1data; if (!keydata.prime1.empty()) { prime1data = hex_decode(keydata.prime1); - private_attrs.push_back({CKA_PRIME_1, (CK_BYTE_PTR)prime1data.data(), prime1data.size()}); + private_attrs.push_back({CKA_PRIME_1, (CK_BYTE_PTR)prime1data.data(), static_cast(prime1data.size())}); } string prime2data; if (!keydata.prime2.empty()) { prime2data = hex_decode(keydata.prime2); - private_attrs.push_back({CKA_PRIME_2, (CK_BYTE_PTR)prime2data.data(), prime2data.size()}); + private_attrs.push_back({CKA_PRIME_2, (CK_BYTE_PTR)prime2data.data(), static_cast(prime2data.size())}); } string exponent1data; if (!keydata.exponent1.empty()) { exponent1data = hex_decode(keydata.exponent1); - private_attrs.push_back({CKA_EXPONENT_1, (CK_BYTE_PTR)exponent1data.data(), exponent1data.size()}); + private_attrs.push_back({CKA_EXPONENT_1, (CK_BYTE_PTR)exponent1data.data(),static_cast(exponent1data.size())}); } string exponent2data; if (!keydata.exponent2.empty()) { exponent2data = hex_decode(keydata.exponent2); - private_attrs.push_back({CKA_EXPONENT_2, (CK_BYTE_PTR)exponent2data.data(), exponent2data.size()}); + private_attrs.push_back({CKA_EXPONENT_2, (CK_BYTE_PTR)exponent2data.data(), static_cast(exponent2data.size())}); } string coefficientdata; if (!keydata.coefficient.empty()) { coefficientdata = hex_decode(keydata.coefficient); - private_attrs.push_back({CKA_COEFFICIENT, (CK_BYTE_PTR)coefficientdata.data(), coefficientdata.size()}); + private_attrs.push_back({CKA_COEFFICIENT, (CK_BYTE_PTR)coefficientdata.data(), static_cast(coefficientdata.size())}); } EXPECT_CKR_OK(g_fns->C_CreateObject(session_, private_attrs.data(), From 7dc0df028e1343bc3ed61862d83ae8666c2350b1 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Tue, 29 Jun 2021 21:46:17 +0200 Subject: [PATCH 06/28] feat add Win64 compilation support --- .appveyor.yml | 7 ++++++- CMakeLists.txt | 10 +++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index d1a6966..e02f505 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -7,6 +7,11 @@ cache: - C:/Tools/vcpkg/installed/ environment: APPVEYOR_SAVE_CACHE_ON_ERROR: true + matrix: + - GENERATOR: "Visual Studio 15 2017" + TARGET: x86-windows + - GENERATOR: "Visual Studio 15 2017 Win64" + TARGET: x64-windows install: # Update vcpkg - cd c:\tools\vcpkg @@ -21,7 +26,7 @@ build_script: - cmd: mkdir C:\projects\pkcs11test\build - cmd: cd C:\projects\pkcs11test\build - cmd: vcpkg integrate install -- cmd: cmake .. -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake +- cmd: cmake .. -G %GENERATOR% -DVCPKG_TARGET_TRIPLET=%TARGET% -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake - cmd: cmake --build . --config RelWithDebInfo - cmd: ctest -C RelWithDebInfo --progress --verbose - cmd: cmake -DCMAKE_INSTALL_PREFIX=out/ -DCMAKE_INSTALL_CONFIG_NAME=RelWithDebInfo -P cmake_install.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 380d83a..b618e8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,12 +36,20 @@ list(APPEND INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/pkcs11) - find_package(GTest CONFIG REQUIRED COMPONENTS CXX_LIB) add_executable(${PROJECT_NAME} ${SOURCES}) target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main) target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIRS} ) +if(${VCPKG_TARGET_TRIPLET} MATCHES ".*windows-static$") + message(FATAL_ERROR "GTest library doesn't support static linking for now") + # switch to MultiThreaded runtime library (MT) vs MultiThreaded DLL (MD) + set_property(TARGET ${PROJECT_NAME} PROPERTY + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +endif() + + + install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} ) From e6db92df93711c8cb8cad24bd8af296ffc7599ff Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Tue, 29 Jun 2021 21:54:09 +0200 Subject: [PATCH 07/28] fix appveyor error 'version already exists' --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index e02f505..7143556 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,4 +1,4 @@ -version: 0.0.0 +version: 0.0.0-{build} configuration: Release platform: - x86 From 9a83334576bdcac9f92b39aa9ead146c206e944c Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Tue, 29 Jun 2021 22:05:25 +0200 Subject: [PATCH 08/28] fix windows CMake generator name add vcpkg install gtest:x64-windows --- .appveyor.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 7143556..0f2ead7 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -18,7 +18,8 @@ install: - cmd: git fetch - cmd: git checkout 2021.05.12 - cmd: bootstrap-vcpkg.bat -- cmd: vcpkg install gtest +- cmd: vcpkg install gtest:x86-windows +- cmd: vcpkg install gtest:x64-windows - cmd: vcpkg update - cmd: vcpkg upgrade --no-dry-run build_script: @@ -26,7 +27,7 @@ build_script: - cmd: mkdir C:\projects\pkcs11test\build - cmd: cd C:\projects\pkcs11test\build - cmd: vcpkg integrate install -- cmd: cmake .. -G %GENERATOR% -DVCPKG_TARGET_TRIPLET=%TARGET% -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake +- cmd: cmake .. -G "%GENERATOR%" -DVCPKG_TARGET_TRIPLET=%TARGET% -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake - cmd: cmake --build . --config RelWithDebInfo - cmd: ctest -C RelWithDebInfo --progress --verbose - cmd: cmake -DCMAKE_INSTALL_PREFIX=out/ -DCMAKE_INSTALL_CONFIG_NAME=RelWithDebInfo -P cmake_install.cmake From 223a83b8eed4acd6fe5742566e0d1887f1e8ecf9 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Tue, 29 Jun 2021 22:11:59 +0200 Subject: [PATCH 09/28] fix downgrade to Visual Studio 14 2015 --- .appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 0f2ead7..18a115b 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -8,9 +8,9 @@ cache: environment: APPVEYOR_SAVE_CACHE_ON_ERROR: true matrix: - - GENERATOR: "Visual Studio 15 2017" + - GENERATOR: "Visual Studio 14 2015" TARGET: x86-windows - - GENERATOR: "Visual Studio 15 2017 Win64" + - GENERATOR: "Visual Studio 14 2015 Win64" TARGET: x64-windows install: # Update vcpkg From e0f7c141cee9ffb6899cf7ac94e2aa433bd1a587 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Tue, 29 Jun 2021 22:51:55 +0200 Subject: [PATCH 10/28] doc add windows compilation notes --- NOTES.WIN.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 NOTES.WIN.md diff --git a/NOTES.WIN.md b/NOTES.WIN.md new file mode 100644 index 0000000..9f31bfa --- /dev/null +++ b/NOTES.WIN.md @@ -0,0 +1,38 @@ +# Building pkcs11test for Windows + +This document describes process of building both 32-bit and 64-bit versions of pkcs11test on 64-bit Windows machine. + +## Required software + +- [Visual Studio](https://visualstudio.microsoft.com/vs/community/) (Community) +- [C/C++ dependency manager from Microsoft](https://vcpkg.io/) +- [CMake](https://cmake.org/) + +## Prepare working directories + + set P11TEST_HOME=C:\Projects\pkcs11test + set VCPKG_HOME=C:\Projects\vcpkg + +## Build GTest + + cd %VCPKG_HOME% + bootstrap-vcpkg.bat + vcpkg install gtest:x86-windows + vcpkg install gtest:x64-windows + vcpkg integrate install + +## Build pkcs11test + git clone https://github.com/google/pkcs11test.git %P11TEST_HOME% +## x86 + mkdir %P11TEST_HOME%\tmp + cd %P11TEST_HOME%\tmp + cmake .. -A Win32 -DCMAKE_TOOLCHAIN_FILE=%VCPKG_HOME%/scripts/buildsystems/vcpkg.cmake + cmake --build . --config RelWithDebInfo + cmake -DCMAKE_INSTALL_PREFIX=%P11TEST_HOME%\out32 -DCMAKE_INSTALL_CONFIG_NAME=RelWithDebInfo -P cmake_install.cmake + +## x64 + mkdir %P11TEST_HOME%\tmp + cd %P11TEST_HOME%\tmp + cmake .. -A x64 -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_TOOLCHAIN_FILE=%VCPKG_HOME%/scripts/buildsystems/vcpkg.cmake + cmake --build . --config RelWithDebInfo + cmake -DCMAKE_INSTALL_PREFIX=%P11TEST_HOME%\out64 -DCMAKE_INSTALL_CONFIG_NAME=RelWithDebInfo -P cmake_install.cmake From ed359d6c7864723f51c3ac21ffb489e9b142f7dd Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Wed, 30 Jun 2021 10:50:12 +0200 Subject: [PATCH 11/28] feat publish github release --- .appveyor.yml | 18 +++++++++++++++++- CMakeLists.txt | 25 +++++++++++++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 18a115b..a2bf445 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -30,6 +30,22 @@ build_script: - cmd: cmake .. -G "%GENERATOR%" -DVCPKG_TARGET_TRIPLET=%TARGET% -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake - cmd: cmake --build . --config RelWithDebInfo - cmd: ctest -C RelWithDebInfo --progress --verbose -- cmd: cmake -DCMAKE_INSTALL_PREFIX=out/ -DCMAKE_INSTALL_CONFIG_NAME=RelWithDebInfo -P cmake_install.cmake +- cmd: cpack #on_finish: # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +artifacts: + - path: **\*.zip + name: artifacts-zip + +deploy: + release: pkcs11test-win32-v$(APPVEYOR_BUILD_VERSION) + description: 'Release x86' + provider: GitHub + auth_token: + secure: KX9JW8h86LzNA1TDJy2adlFIV+E455sZqXTc/HQDPLSbHRTwEv5zpcdRA/n9xJGp + artifact: artifacts-zip + draft: true + prerelease: false + on: + branch: dev + APPVEYOR_REPO_TAG: true \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index b618e8e..e8d943a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.16) set(CMAKE_CXX_STANDARD_REQUIRED ON) project(p11test) +set(VERSION "0.0.0") +set(VERSION_MAJOR 0) +set(VERSION_MINOR 0) +set(VERSION_PATCH 0) set(SOURCES cipher.cc describe.cc @@ -50,12 +54,25 @@ endif() -install(TARGETS ${PROJECT_NAME} - DESTINATION ${CMAKE_INSTALL_BINDIR} - ) - +install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES $ DESTINATION bin OPTIONAL) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gmock.dll DESTINATION bin OPTIONAL) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gtest.dll DESTINATION bin OPTIONAL) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gtest_main.dll DESTINATION bin OPTIONAL) +# Packaging +set(CPACK_PACKAGE_NAME ${PACKAGE_NAME}) +set(CPACK_PACKAGE_VENDOR "plcs11test") +set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH}) +set(CPACK_GENERATOR "ZIP") +set(CPACK_SOURCE_GENERATOR "ZIP") +set(CPACK_SOURCE_IGNORE_FILES "build/*;\.git/*") + +include(CPack) + +##debug #get_cmake_property(_variableNames VARIABLES) #list (SORT _variableNames) #foreach (_variableName ${_variableNames}) From 1e143db6162a3f7426df4a3b3a67c2f13f7290be Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Wed, 30 Jun 2021 10:52:17 +0200 Subject: [PATCH 12/28] fix change artifact zip path --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index a2bf445..e281a6f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -34,7 +34,7 @@ build_script: #on_finish: # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) artifacts: - - path: **\*.zip + - path: *.zip name: artifacts-zip deploy: From 762c4724b0d2e197716ad6df46628f8256d43f86 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Wed, 30 Jun 2021 10:52:17 +0200 Subject: [PATCH 13/28] fix change artifact zip path --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index a2bf445..53ccd06 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -34,7 +34,7 @@ build_script: #on_finish: # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) artifacts: - - path: **\*.zip + - path: "*.zip" name: artifacts-zip deploy: From c229b27ff95e6ccf06f24711847995ce7b063a60 Mon Sep 17 00:00:00 2001 From: Arnaud Grandville Date: Wed, 30 Jun 2021 10:55:01 +0200 Subject: [PATCH 14/28] Update .appveyor.yml --- .appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index e281a6f..2119bf5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -34,7 +34,7 @@ build_script: #on_finish: # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) artifacts: - - path: *.zip + - path: "*.zip" name: artifacts-zip deploy: @@ -48,4 +48,4 @@ deploy: prerelease: false on: branch: dev - APPVEYOR_REPO_TAG: true \ No newline at end of file + APPVEYOR_REPO_TAG: true From 8ad94deb1770bfe71db68713740175013693bc75 Mon Sep 17 00:00:00 2001 From: Arnaud Grandville Date: Wed, 30 Jun 2021 11:31:47 +0200 Subject: [PATCH 15/28] Update CMakeLists.txt --- CMakeLists.txt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e8d943a..729b960 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,11 +54,13 @@ endif() -install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) -install(FILES $ DESTINATION bin OPTIONAL) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gmock.dll DESTINATION bin OPTIONAL) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gtest.dll DESTINATION bin OPTIONAL) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gtest_main.dll DESTINATION bin OPTIONAL) +#install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) +#install(FILES $ DESTINATION bin OPTIONAL) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/p11test.exe DESTINATION bin) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/p11test.pdb DESTINATION bin OPTIONAL) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gmock.dll DESTINATION bin) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gtest.dll DESTINATION bin) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gtest_main.dll DESTINATION bin) # Packaging set(CPACK_PACKAGE_NAME ${PACKAGE_NAME}) From ae4eb73db4e9f52566910d5d7f691a353b2ab6e4 Mon Sep 17 00:00:00 2001 From: Arnaud Grandville Date: Wed, 30 Jun 2021 13:21:56 +0200 Subject: [PATCH 16/28] Update .appveyor.yml --- .appveyor.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 2119bf5..8b49392 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -31,10 +31,10 @@ build_script: - cmd: cmake --build . --config RelWithDebInfo - cmd: ctest -C RelWithDebInfo --progress --verbose - cmd: cpack -#on_finish: -# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +on_finish: + - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) artifacts: - - path: "*.zip" + - path: "%APPVEYOR_BUILD_FOLDER%/*.zip" name: artifacts-zip deploy: From 292cb09fd57c42e2461821be87c9288380770d3e Mon Sep 17 00:00:00 2001 From: Arnaud Grandville Date: Wed, 30 Jun 2021 13:31:13 +0200 Subject: [PATCH 17/28] Update .appveyor.yml --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 8b49392..ac6ce1f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -34,7 +34,7 @@ build_script: on_finish: - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) artifacts: - - path: "%APPVEYOR_BUILD_FOLDER%/*.zip" + - path: "build/*.zip" name: artifacts-zip deploy: From 172a6dc4b4352f96f59241e0907993b5db29c509 Mon Sep 17 00:00:00 2001 From: Arnaud Grandville Date: Wed, 30 Jun 2021 13:35:18 +0200 Subject: [PATCH 18/28] Update .appveyor.yml --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index ac6ce1f..11b4ab6 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -48,4 +48,4 @@ deploy: prerelease: false on: branch: dev - APPVEYOR_REPO_TAG: true +# APPVEYOR_REPO_TAG: true # deploy on tag push only From c75abcb7ca329edff02e9ed44409acaf77c7923f Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Wed, 30 Jun 2021 15:16:04 +0200 Subject: [PATCH 19/28] feat disable appveyor RDP on finish --- .appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 205b562..c595f59 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -31,8 +31,8 @@ build_script: - cmd: cmake --build . --config RelWithDebInfo - cmd: ctest -C RelWithDebInfo --progress --verbose - cmd: cpack -on_finish: - - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +#on_finish: +# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) artifacts: - path: "build/*.zip" name: artifacts-zip From 8322301cc8b75f3a9645bd50629c3f3c0b71e22e Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Wed, 30 Jun 2021 17:56:29 +0200 Subject: [PATCH 20/28] fix PR regression remove static path to p11 library --- pkcs11-env.h | 2 ++ pkcs11test.cc | 67 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/pkcs11-env.h b/pkcs11-env.h index 3ace5c6..3f9f675 100644 --- a/pkcs11-env.h +++ b/pkcs11-env.h @@ -16,6 +16,7 @@ #ifdef _WIN32 #include "cryptoki.h" +constexpr auto FILEPATH_NATIVE = '\\'; #else /* From 2.1 of [PKCS11-base-v2.40]: Cryptoki structures SHALL be packed with 1-byte alignment. */ #if defined(STRICT_P11) @@ -31,6 +32,7 @@ #ifndef NULL_PTR #define NULL_PTR 0 #endif +constexpr auto FILEPATH_NATIVE = '/'; #endif //_WIN32 #include diff --git a/pkcs11test.cc b/pkcs11test.cc index 4e54712..dbf9e90 100644 --- a/pkcs11test.cc +++ b/pkcs11test.cc @@ -30,6 +30,7 @@ #include #include #include +#include // Local headers #include "pkcs11test.h" @@ -59,11 +60,11 @@ int GetInteger(const CK_CHAR *val, int len) { } typedef vector TestList; -typedef map SkippedTestMap; +typedef map > SkippedTestMap; static SkippedTestMap skipped_tests; void TestSkipped(const char *testcase, const char *test, const string& reason) { if (skipped_tests.find(reason) == skipped_tests.end()) { - skipped_tests[reason] = new TestList; + skipped_tests[reason] = std::unique_ptr(new TestList); } string testname(testcase); testname += "."; @@ -88,10 +89,22 @@ void usage() { cerr << " -m name : name of PKCS#11 library" << endl; cerr << " -l path : path to PKCS#11 library" << endl; cerr << " -s id : slot ID to perform tests against" << endl; + cerr << " -S n : slot index (0 for first slot)" << endl; cerr << " -X : skip tests requiring SO login" << endl; cerr << " -v : verbose output" << endl; cerr << " -u pwd : user PIN/password" << endl; cerr << " -o pwd : security officer PIN/password" << endl; + cerr << " -w name : cipher to use for keys being wrapped, one of: { "; + for (const auto &key : kCipherInfo) { + static int i = 0; + if ((i % 3) == 0) { + cerr << endl; + cerr << " "; + } + cerr << ", " << key.first; + i++; + } + cerr << " }" << endl; cerr << " -I : perform token init tests **WILL WIPE TOKEN CONTENTS**" << endl; exit(1); } @@ -104,8 +117,8 @@ CK_C_GetFunctionList load_pkcs11_library(const char* libpath, const char* libnam string fullname; if (libpath != nullptr) { fullname = libpath; - if (fullname.at(fullname.size() - 1) != '/') { - fullname += '/'; + if (fullname.at(fullname.size() - 1) != FILEPATH_NATIVE) { + fullname += FILEPATH_NATIVE; } } fullname += libname; @@ -153,10 +166,12 @@ int main(int argc, char* argv[]) { // Retrieve PKCS module location. bool explicit_slotid = false; + bool use_slot_index = false; + unsigned slot_index = 0; int opt; const char* module_name = nullptr; const char* module_path = nullptr; - while ((opt = getopt(argc, argv, "vIXl:m:s:u:o:h")) != -1) { + while ((opt = getopt(argc, argv, "vIXl:m:s:S:u:o:w:h")) != -1) { switch (opt) { case 'v': g_verbose = true; @@ -177,12 +192,18 @@ int main(int argc, char* argv[]) { g_slot_id = atoi(optarg); explicit_slotid = true; break; + case 'S': + slot_index = atoi(optarg); + use_slot_index = true; case 'u': g_user_pin = optarg; break; case 'o': g_so_pin = optarg; break; + case 'w': + g_wrap_mechanism = optarg; + break; case 'h': default: usage(); @@ -193,9 +214,6 @@ int main(int argc, char* argv[]) { // Load the module. CK_C_GetFunctionList get_fn_list = load_pkcs11_library(module_path, module_name); -// CK_FUNCTION_LIST_PTR p11; -// (*get_fn_list)(&p11); -// p11->C_Initialize(NULL_PTR); // Retrieve the set of function pointers (C_GetFunctionList is the only function it's OK to call before C_Initialize). if (get_fn_list(&g_fns) != CKR_OK) { @@ -210,20 +228,33 @@ int main(int argc, char* argv[]) { exit(1); } - if (!explicit_slotid) { - // No slot specified; OK if there's only one accessible slot. - CK_SLOT_ID slots[2]; - CK_ULONG slot_count = 2; + if (use_slot_index || !explicit_slotid) { + CK_SLOT_ID slots[32]; + CK_ULONG slot_count = 32; + rv = g_fns->C_GetSlotList(CK_TRUE, slots, &slot_count); if (rv == CKR_OK) { - if (slot_count == 1) { - g_slot_id = slots[0]; - } else if (slot_count == 0) { + if (slot_count == 0) { cerr << "No slots with tokens available" << endl; exit(1); } else { - cerr << "Multiple slots with tokens available; specify one with -s" << endl; - exit(1); + if (!use_slot_index) { + if (slot_count > 1) { + cerr << "Multiple slots with tokens available; specify one with -s" << endl; + for (unsigned i = 0; i < slot_count; i++) { + cerr << "Slot " << i << "= ID: " << slots[i] << endl; + } + exit(1); + } + // default to the first slot (slot_index = 0) + } + + if (slot_index >= slot_count) { + cerr << "Slot index " << slot_index << " invalid, there are only " << slot_count << " slots." << endl; + exit(1); + } + + g_slot_id = slots[slot_index]; } } else { cerr << "Failed to retrieve slot list" << endl; @@ -258,7 +289,7 @@ int main(int argc, char* argv[]) { g_token_flags = token.flags; memcpy(g_token_label, token.label, sizeof(g_token_label)); - if ((g_token_flags & CKF_LOGIN_REQUIRED)) { + if (!(g_token_flags & CKF_LOGIN_REQUIRED)) { // Disable all tests that require login in their fixture. // This unfortunately relies on some gTest innards. string filter(testing::GTEST_FLAG(filter).c_str()); From 92fa35759941d0e87cc96e9e89f8447dad164235 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Wed, 30 Jun 2021 21:13:23 +0200 Subject: [PATCH 21/28] fix merge win32/cryptoki.h with pkcs11-env.h fix move FILEPATH_NATIVE definition from pkcs11-env.h to pkcs11test.cc --- CMakeLists.txt | 2 +- pkcs11-env.h | 46 ++++++++++++++++--- pkcs11test.cc | 3 +- third_party/win32/cryptoki.h | 85 ------------------------------------ 4 files changed, 43 insertions(+), 93 deletions(-) delete mode 100644 third_party/win32/cryptoki.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 729b960..dbb0374 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ endif() list(APPEND INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/pkcs11) - +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTRICT_P11") find_package(GTest CONFIG REQUIRED COMPONENTS CXX_LIB) add_executable(${PROJECT_NAME} ${SOURCES}) target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main) diff --git a/pkcs11-env.h b/pkcs11-env.h index 3f9f675..b5c2916 100644 --- a/pkcs11-env.h +++ b/pkcs11-env.h @@ -14,26 +14,60 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifdef _WIN32 -#include "cryptoki.h" -constexpr auto FILEPATH_NATIVE = '\\'; -#else /* From 2.1 of [PKCS11-base-v2.40]: Cryptoki structures SHALL be packed with 1-byte alignment. */ #if defined(STRICT_P11) # pragma pack(push, 1) #endif + + +#ifdef _WIN32 + +/* Specifies that the function is a DLL entry point. */ +#define CK_IMPORT_SPEC __declspec(dllimport) + +#ifdef CRYPTOKI_EXPORTS + /* Specified that the function is an exported DLL entry point. */ +#define CK_EXPORT_SPEC __declspec(dllexport) +#else +#define CK_EXPORT_SPEC CK_IMPORT_SPEC +#endif + + /* Ensures the calling convention for Win32 builds */ +#define CK_CALL_SPEC __cdecl + +#define CK_PTR * + +#define CK_DEFINE_FUNCTION(returnType, name) \ + returnType CK_EXPORT_SPEC CK_CALL_SPEC name + +#define CK_DECLARE_FUNCTION(returnType, name) \ + returnType CK_EXPORT_SPEC CK_CALL_SPEC name + +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name) + +#define CK_CALLBACK_FUNCTION(returnType, name) \ + returnType (CK_CALL_SPEC CK_PTR name) + + + +#else //_WIN32 + +/* UNIX version */ /* The following definitions need to be provided to the preprocessor before the PKCS#11 header file can be included */ #define CK_PTR * #define CK_DEFINE_FUNCTION(returnType, name) returnType name #define CK_DECLARE_FUNCTION(returnType, name) returnType name #define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (*name) #define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name) + + +#endif //_WIN32 + #ifndef NULL_PTR #define NULL_PTR 0 #endif -constexpr auto FILEPATH_NATIVE = '/'; -#endif //_WIN32 #include diff --git a/pkcs11test.cc b/pkcs11test.cc index dbf9e90..b7eb56e 100644 --- a/pkcs11test.cc +++ b/pkcs11test.cc @@ -15,9 +15,11 @@ // C headers #include #ifdef _WIN32 +constexpr auto FILEPATH_NATIVE = '\\'; #include #include #else +constexpr auto FILEPATH_NATIVE = '/'; #include #include #endif @@ -129,7 +131,6 @@ CK_C_GetFunctionList load_pkcs11_library(const char* libpath, const char* libnam void* lib; #if defined WIN32 - fullname = "C:\\Projects\\SoftHSMv2\\tmp32\\src\\lib\\Debug\\softhsm2.dll"; lib = LoadLibraryA(fullname.c_str()); #else lib = dlopen(fullname.c_str(), RTLD_NOW); diff --git a/third_party/win32/cryptoki.h b/third_party/win32/cryptoki.h deleted file mode 100644 index 01354aa..0000000 --- a/third_party/win32/cryptoki.h +++ /dev/null @@ -1,85 +0,0 @@ -/* cryptoki.h include file for PKCS #11. */ -/* $Revision: 1.4 $ */ - -/* License to copy and use this software is granted provided that it is - * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface - * (Cryptoki)" in all material mentioning or referencing this software. - - * License is also granted to make and use derivative works provided that - * such works are identified as "derived from the RSA Security Inc. PKCS #11 - * Cryptographic Token Interface (Cryptoki)" in all material mentioning or - * referencing the derived work. - - * RSA Security Inc. makes no representations concerning either the - * merchantability of this software or the suitability of this software for - * any particular purpose. It is provided "as is" without express or implied - * warranty of any kind. - */ - -/* This is a sample file containing the top level include directives - * for building Win32 Cryptoki libraries and applications. - */ - -#ifndef ___CRYPTOKI_H_INC___ -#define ___CRYPTOKI_H_INC___ - -#ifdef _WIN32 -#pragma pack(push, cryptoki, 1) - -/* Specifies that the function is a DLL entry point. */ -#define CK_IMPORT_SPEC __declspec(dllimport) - -/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do - * not define it in applications. - */ -#ifdef CRYPTOKI_EXPORTS -/* Specified that the function is an exported DLL entry point. */ -#define CK_EXPORT_SPEC __declspec(dllexport) -#else -#define CK_EXPORT_SPEC CK_IMPORT_SPEC -#endif - -/* Ensures the calling convention for Win32 builds */ -#define CK_CALL_SPEC __cdecl - -#define CK_PTR * - -#define CK_DEFINE_FUNCTION(returnType, name) \ - returnType CK_EXPORT_SPEC CK_CALL_SPEC name - -#define CK_DECLARE_FUNCTION(returnType, name) \ - returnType CK_EXPORT_SPEC CK_CALL_SPEC name - -#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ - returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name) - -#define CK_CALLBACK_FUNCTION(returnType, name) \ - returnType (CK_CALL_SPEC CK_PTR name) - -#ifndef NULL_PTR -#define NULL_PTR 0 -#endif - -#include "pkcs11.h" - -#pragma pack(pop, cryptoki) - -#else -/* UNIX version */ -#define CK_PTR * -#define CK_DEFINE_FUNCTION(returnType, name) \ - returnType name -#define CK_DECLARE_FUNCTION(returnType, name) \ - returnType name -#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ - returnType (CK_PTR name) -#define CK_CALLBACK_FUNCTION(returnType, name) \ - returnType (CK_PTR name) -#ifndef NULL_PTR -#define NULL_PTR 0 -#endif -#include "pkcs11.h" - -#endif - -#endif /* ___CRYPTOKI_H_INC___ */ From 38dd4a79cdc6596886bd179ef6ecc3ae0a46c99a Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Thu, 1 Jul 2021 16:09:36 +0200 Subject: [PATCH 22/28] fix remove getopt source --- third_party/win32/getopt.cpp | 519 ----------------------------------- third_party/win32/getopt.h | 101 ------- 2 files changed, 620 deletions(-) delete mode 100644 third_party/win32/getopt.cpp delete mode 100644 third_party/win32/getopt.h diff --git a/third_party/win32/getopt.cpp b/third_party/win32/getopt.cpp deleted file mode 100644 index d60ef88..0000000 --- a/third_party/win32/getopt.cpp +++ /dev/null @@ -1,519 +0,0 @@ -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dieter Baron and Thomas Klausner. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -#include -#include -#include - -#ifdef _WIN32 - -/* Windows needs warnx(). We change the definition though: - * 1. (another) global is defined, opterrmsg, which holds the error message - * 2. errors are always printed out on stderr w/o the program name - * Note that opterrmsg always gets set no matter what opterr is set to. The - * error message will not be printed if opterr is 0 as usual. - */ - -#include -#include - -extern char opterrmsg[128]; -char opterrmsg[128]; /* last error message is stored here */ - -static void warnx(int print_error, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - if (fmt != NULL) - _vsnprintf(opterrmsg, 128, fmt, ap); - else - opterrmsg[0]='\0'; - va_end(ap); - if (print_error) { - fprintf(stderr, opterrmsg); - fprintf(stderr, "\n"); - } -} - -#endif /*_WIN32*/ - -/* not part of the original file */ -#ifndef _DIAGASSERT -#define _DIAGASSERT(X) -#endif - -#if HAVE_CONFIG_H && !HAVE_GETOPT_LONG && !HAVE_DECL_OPTIND -#define REPLACE_GETOPT -#endif - -int opterr = 1; /* if error message should be printed */ -int optind = 1; /* index into parent argv vector */ -int optopt = '?'; /* character checked for validity */ -int optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ - -#if !HAVE_GETOPT_LONG -#define IGNORE_FIRST (*options == '-' || *options == '+') -#define PRINT_ERROR ((opterr) && ((*options != ':') \ - || (IGNORE_FIRST && options[1] != ':'))) -#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL) -#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST) -/* XXX: GNU ignores PC if *options == '-' */ -#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-') - -/* return values */ -#define BADCH (int)'?' -#define BADARG ((IGNORE_FIRST && options[1] == ':') \ - || (*options == ':') ? (int)':' : (int)'?') -#define INORDER (int)1 - -#define EMSG "" - -static int getopt_internal(int, char * const *, const char *); -static int gcd(int, int); -static void permute_args(int, int, int, char * const *); - -static char *place = EMSG; /* option letter processing */ - -/* XXX: set optreset to 1 rather than these two */ -static int nonopt_start = -1; /* first non option argument (for permute) */ -static int nonopt_end = -1; /* first option after non options (for permute) */ - -/* Error messages */ -static const char recargchar[] = "option requires an argument -- %c"; -static const char recargstring[] = "option requires an argument -- %s"; -static const char ambig[] = "ambiguous option -- %.*s"; -static const char noarg[] = "option doesn't take an argument -- %.*s"; -static const char illoptchar[] = "unknown option -- %c"; -static const char illoptstring[] = "unknown option -- %s"; - - -/* - * Compute the greatest common divisor of a and b. - */ -static int -gcd(int a, int b) -{ - int c; - - c = a % b; - while (c != 0) { - a = b; - b = c; - c = a % b; - } - - return b; -} - -/* - * Exchange the block from nonopt_start to nonopt_end with the block - * from nonopt_end to opt_end (keeping the same order of arguments - * in each block). - */ -static void -permute_args(int panonopt_start, int panonopt_end, - int opt_end, char * const *nargv) -{ - int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; - char *swap; - - _DIAGASSERT(nargv != NULL); - - /* - * compute lengths of blocks and number and size of cycles - */ - nnonopts = panonopt_end - panonopt_start; - nopts = opt_end - panonopt_end; - ncycle = gcd(nnonopts, nopts); - cyclelen = (opt_end - panonopt_start) / ncycle; - - for (i = 0; i < ncycle; i++) { - cstart = panonopt_end+i; - pos = cstart; - for (j = 0; j < cyclelen; j++) { - if (pos >= panonopt_end) - pos -= nnonopts; - else - pos += nopts; - swap = nargv[pos]; - /* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; - /* LINTED const cast */ - ((char **)nargv)[cstart] = swap; - } - } -} - -/* - * getopt_internal -- - * Parse argc/argv argument vector. Called by user level routines. - * Returns -2 if -- is found (can be long option or end of options marker). - */ -static int -getopt_internal(int nargc, char * const *nargv, const char *options) -{ - char *oli; /* option letter list index */ - int optchar; - - _DIAGASSERT(nargv != NULL); - _DIAGASSERT(options != NULL); - - optarg = NULL; - - /* - * XXX Some programs (like rsyncd) expect to be able to - * XXX re-initialize optind to 0 and have getopt_long(3) - * XXX properly function again. Work around this braindamage. - */ - if (optind == 0) - optind = 1; - - if (optreset) - nonopt_start = nonopt_end = -1; -start: - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc) { /* end of argument vector */ - place = EMSG; - if (nonopt_end != -1) { - /* do permutation, if we have to */ - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - else if (nonopt_start != -1) { - /* - * If we skipped non-options, set optind - * to the first of them. - */ - optind = nonopt_start; - } - nonopt_start = nonopt_end = -1; - return -1; - } - if ((*(place = nargv[optind]) != '-') - || (place[1] == '\0')) { /* found non-option */ - place = EMSG; - if (IN_ORDER) { - /* - * GNU extension: - * return non-option as argument to option 1 - */ - optarg = nargv[optind++]; - return INORDER; - } - if (!PERMUTE) { - /* - * if no permutation wanted, stop parsing - * at first non-option - */ - return -1; - } - /* do permutation */ - if (nonopt_start == -1) - nonopt_start = optind; - else if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - nonopt_start = optind - - (nonopt_end - nonopt_start); - nonopt_end = -1; - } - optind++; - /* process next argument */ - goto start; - } - if (nonopt_start != -1 && nonopt_end == -1) - nonopt_end = optind; - if (place[1] && *++place == '-') { /* found "--" */ - place++; - return -2; - } - } - if ((optchar = (int)*place++) == (int)':' || - (oli = (char *) strchr(options + (IGNORE_FIRST ? 1 : 0), - optchar)) == NULL) { - /* option letter unknown or ':' */ - if (!*place) - ++optind; -#ifndef _WIN32 - if (PRINT_ERROR) - warnx(illoptchar, optchar); -#else - warnx(PRINT_ERROR, illoptchar, optchar); -#endif - optopt = optchar; - return BADCH; - } - if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ - /* XXX: what if no long options provided (called by getopt)? */ - if (*place) - return -2; - - if (++optind >= nargc) { /* no arg */ - place = EMSG; -#ifndef _WIN32 - if (PRINT_ERROR) - warnx(recargchar, optchar); -#else - warnx(PRINT_ERROR, recargchar, optchar); -#endif - optopt = optchar; - return BADARG; - } else /* white space */ - place = nargv[optind]; - /* - * Handle -W arg the same as --arg (which causes getopt to - * stop parsing). - */ - return -2; - } - if (*++oli != ':') { /* doesn't take argument */ - if (!*place) - ++optind; - } else { /* takes (optional) argument */ - optarg = NULL; - if (*place) /* no white space */ - optarg = place; - /* XXX: disable test for :: if PC? (GNU doesn't) */ - else if (oli[1] != ':') { /* arg not optional */ - if (++optind >= nargc) { /* no arg */ - place = EMSG; -#ifndef _WIN32 - if (PRINT_ERROR) - warnx(recargchar, optchar); -#else - warnx(PRINT_ERROR, recargchar, optchar); -#endif - optopt = optchar; - return BADARG; - } else - optarg = nargv[optind]; - } - place = EMSG; - ++optind; - } - /* dump back option letter */ - return optchar; -} - -/* - * getopt -- - * Parse argc/argv argument vector. - * - * [eventually this will replace the real getopt] - */ -int -getopt(int nargc, char * const *nargv, const char *options) -{ - int retval; - - _DIAGASSERT(nargv != NULL); - _DIAGASSERT(options != NULL); - - if ((retval = getopt_internal(nargc, nargv, options)) == -2) { - ++optind; - /* - * We found an option (--), so if we skipped non-options, - * we have to permute. - */ - if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, optind, - nargv); - optind -= nonopt_end - nonopt_start; - } - nonopt_start = nonopt_end = -1; - retval = -1; - } - return retval; -} - -/* - * getopt_long -- - * Parse argc/argv argument vector. - */ -int -getopt_long(int nargc, - char * const *nargv, - const char *options, - const struct option *long_options, - int *idx) -{ - int retval; - - _DIAGASSERT(nargv != NULL); - _DIAGASSERT(options != NULL); - _DIAGASSERT(long_options != NULL); - /* idx may be NULL */ - - if ((retval = getopt_internal(nargc, nargv, options)) == -2) { - char *current_argv, *has_equal; - size_t current_argv_len; - int i, match; - - current_argv = place; - match = -1; - - optind++; - place = EMSG; - - if (*current_argv == '\0') { /* found "--" */ - /* - * We found an option (--), so if we skipped - * non-options, we have to permute. - */ - if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - nonopt_start = nonopt_end = -1; - return -1; - } - if ((has_equal = strchr(current_argv, '=')) != NULL) { - /* argument found (--option=arg) */ - current_argv_len = has_equal - current_argv; - has_equal++; - } else - current_argv_len = strlen(current_argv); - - for (i = 0; long_options[i].name; i++) { - /* find matching long option */ - if (strncmp(current_argv, long_options[i].name, - current_argv_len)) - continue; - - if (strlen(long_options[i].name) == - (unsigned)current_argv_len) { - /* exact match */ - match = i; - break; - } - if (match == -1) /* partial match */ - match = i; - else { - /* ambiguous abbreviation */ -#ifndef _WIN32 - if (PRINT_ERROR) - warnx(ambig, (int)current_argv_len, - current_argv); -#else - warnx(PRINT_ERROR, ambig, (int)current_argv_len, - current_argv); -#endif - optopt = 0; - return BADCH; - } - } - if (match != -1) { /* option found */ - if (long_options[match].has_arg == no_argument - && has_equal) { -#ifndef _WIN32 - if (PRINT_ERROR) - warnx(noarg, (int)current_argv_len, - current_argv); -#else - warnx(PRINT_ERROR, noarg, (int)current_argv_len, - current_argv); -#endif - /* - * XXX: GNU sets optopt to val regardless of - * flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - return BADARG; - } - if (long_options[match].has_arg == required_argument || - long_options[match].has_arg == optional_argument) { - if (has_equal) - optarg = has_equal; - else if (long_options[match].has_arg == - required_argument) { - /* - * optional argument doesn't use - * next nargv - */ - optarg = nargv[optind++]; - } - } - if ((long_options[match].has_arg == required_argument) - && (optarg == NULL)) { - /* - * Missing argument; leading ':' - * indicates no error should be generated - */ -#ifndef _WIN32 - if (PRINT_ERROR) - warnx(recargstring, current_argv); -#else - warnx(PRINT_ERROR, recargstring, current_argv); -#endif - /* - * XXX: GNU sets optopt to val regardless - * of flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - --optind; - return BADARG; - } - } else { /* unknown option */ -#ifndef _WIN32 - if (PRINT_ERROR) - warnx(illoptstring, current_argv); -#else - warnx(PRINT_ERROR, illoptstring, current_argv); -#endif - optopt = 0; - return BADCH; - } - if (long_options[match].flag) { - *long_options[match].flag = long_options[match].val; - retval = 0; - } else - retval = long_options[match].val; - if (idx) - *idx = match; - } - return retval; -} -#endif /* !GETOPT_LONG */ diff --git a/third_party/win32/getopt.h b/third_party/win32/getopt.h deleted file mode 100644 index f6b65a5..0000000 --- a/third_party/win32/getopt.h +++ /dev/null @@ -1,101 +0,0 @@ -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dieter Baron and Thomas Klausner. - * - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - */ - -#ifndef _GETOPT_H_ -#define _GETOPT_H_ - -#ifdef _WIN32 -/* from */ -# ifdef __cplusplus -# define __BEGIN_DECLS extern "C" { -# define __END_DECLS } -# else -# define __BEGIN_DECLS -# define __END_DECLS -# endif -# define __P(args) args -#endif - -/*#ifndef _WIN32 -#include -#include -#endif*/ - -/* - * Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions - */ -#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE) -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -struct option { - /* name of long option */ - const char *name; - /* - * one of no_argument, required_argument, and optional_argument: - * whether option takes an argument - */ - int has_arg; - /* if not NULL, set *flag to val when option found */ - int *flag; - /* if flag not NULL, value to set *flag to; else return value */ - int val; -}; - -__BEGIN_DECLS -int getopt_long __P((int, char * const *, const char *, - const struct option *, int *)); -__END_DECLS -#endif - -#ifdef _WIN32 -/* These are global getopt variables */ -__BEGIN_DECLS - -extern int opterr, /* if error message should be printed */ - optind, /* index into parent argv vector */ - optopt, /* character checked for validity */ - optreset; /* reset getopt */ -extern char* optarg; /* argument associated with option */ - -/* Original getopt */ -int getopt __P((int, char * const *, const char *)); - -__END_DECLS -#endif - -#endif /* !_GETOPT_H_ */ From 6644bdc3b9003dd01ad87f3c4e9aec148cc51f84 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Thu, 1 Jul 2021 16:20:24 +0200 Subject: [PATCH 23/28] Import pristine copy of NetBSD getopt code code taken from https://github.com/openbsd/src/blob/0025f5bb9c9be650004db9e38ab09eea44e2b392/lib/libc/stdlib/getopt_long.c and https://github.com/openbsd/src/blob/0025f5bb9c9be650004db9e38ab09eea44e2b392/include/getopt.h --- third_party/netbsd/getopt.h | 76 +++++ third_party/netbsd/getopt_long.c | 513 +++++++++++++++++++++++++++++++ 2 files changed, 589 insertions(+) create mode 100644 third_party/netbsd/getopt.h create mode 100644 third_party/netbsd/getopt_long.c diff --git a/third_party/netbsd/getopt.h b/third_party/netbsd/getopt.h new file mode 100644 index 0000000..dd51864 --- /dev/null +++ b/third_party/netbsd/getopt.h @@ -0,0 +1,76 @@ +/* $OpenBSD: getopt.h,v 1.3 2013/11/22 21:32:49 millert Exp $ */ +/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +#include + +/* + * GNU-like getopt_long() + */ +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +struct option { + /* name of long option */ + const char *name; + /* + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; + /* if not NULL, set *flag to val when option found */ + int *flag; + /* if flag not NULL, value to set *flag to; else return value */ + int val; +}; + +__BEGIN_DECLS +int getopt_long(int, char * const *, const char *, + const struct option *, int *); +int getopt_long_only(int, char * const *, const char *, + const struct option *, int *); +#ifndef _GETOPT_DEFINED_ +#define _GETOPT_DEFINED_ +int getopt(int, char * const *, const char *); + +extern char *optarg; /* getopt(3) external variables */ +extern int opterr; +extern int optind; +extern int optopt; +extern int optreset; +#endif +__END_DECLS + +#endif /* !_GETOPT_H_ */ diff --git a/third_party/netbsd/getopt_long.c b/third_party/netbsd/getopt_long.c new file mode 100644 index 0000000..0de5045 --- /dev/null +++ b/third_party/netbsd/getopt_long.c @@ -0,0 +1,513 @@ +/* $OpenBSD: getopt_long.c,v 1.32 2020/05/27 22:25:09 schwarze Exp $ */ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#include +#include +#include +#include +#include + +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#if 0 +/* DEF_* only work on initialized (non-COMMON) variables */ +DEF_WEAK(opterr); +DEF_WEAK(optind); +DEF_WEAK(optopt); +#endif + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + ((char **)nargv)[pos] = nargv[cstart]; + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too, int flags) +{ + char *current_argv, *has_equal; + size_t current_argv_len; + int i, match, exact_match, second_partial_match; + + current_argv = place; + match = -1; + exact_match = 0; + second_partial_match = 0; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + exact_match = 1; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* first partial match */ + match = i; + else if ((flags & FLAG_LONGONLY) || + long_options[i].has_arg != long_options[match].has_arg || + long_options[i].flag != long_options[match].flag || + long_options[i].val != long_options[match].val) + second_partial_match = 1; + } + if (!exact_match && second_partial_match) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, current_argv); + optopt = 0; + return (BADCH); + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + char *oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; + + if (options == NULL) + return (-1); + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + */ + if (posixly_correct == -1 || optreset) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + if (*options == '+' || *options == '-') + options++; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too, flags); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if ((optchar = (int)*place++) == (int)':' || + (oli = strchr(options, optchar)) == NULL) { + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, + idx, 0, flags); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); +} + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ +int +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} From 524e6aadd21fdf010a0c45010e09b9640ad0b9e7 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Thu, 1 Jul 2021 16:28:50 +0200 Subject: [PATCH 24/28] fix windows portability --- third_party/netbsd/getopt.h | 15 +++++++++++ third_party/netbsd/getopt_long.c | 45 ++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/third_party/netbsd/getopt.h b/third_party/netbsd/getopt.h index dd51864..f501655 100644 --- a/third_party/netbsd/getopt.h +++ b/third_party/netbsd/getopt.h @@ -33,7 +33,22 @@ #ifndef _GETOPT_H_ #define _GETOPT_H_ +#ifdef _WIN32 + /* from */ + /* C++ needs to know that types and declarations are C, not C++. */ +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS +# define __END_DECLS +#endif + +extern char opterrmsg[]; // error message + +#else //_WIN32 #include +#endif // _WIN32 /* * GNU-like getopt_long() diff --git a/third_party/netbsd/getopt_long.c b/third_party/netbsd/getopt_long.c index 0de5045..a985d6c 100644 --- a/third_party/netbsd/getopt_long.c +++ b/third_party/netbsd/getopt_long.c @@ -49,7 +49,52 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef _WIN32 #include +#else //_WIN32 +#pragma warning(disable : 4996) //getenv +/* warnx definition for windows*/ +#include +#include +#include + +char opterrmsg[128]; + +static void warnx(const char *fmt, ...) +{ + const int TRUNCATED = -1; + va_list ap; + va_start(ap, fmt); + + if (fmt != NULL) { + int c = _vsnprintf_s(opterrmsg, sizeof(opterrmsg) - 4, _TRUNCATE, fmt, ap); + + // enough space are reserved to add continuation mark or NL + if (c == TRUNCATED) { + c = sizeof(opterrmsg) - 5; + opterrmsg[c++] = '.'; + opterrmsg[c++] = '.'; + opterrmsg[c++] = '.'; + opterrmsg[c++] = '\n'; + opterrmsg[c++] = '\0'; + } + else{ + opterrmsg[c++] = '\n'; + opterrmsg[c++] = '\0'; + } + } + else { + opterrmsg[0] = '\0'; + } + + OutputDebugStringA(opterrmsg); + fprintf(stderr, opterrmsg); + + va_end(ap); +} + +#endif //_WIN32 + #include #include #include From 2decd758c883fc50385edbd2cb20f44bdfd522ba Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Thu, 1 Jul 2021 16:29:20 +0200 Subject: [PATCH 25/28] fix update getopt build --- CMakeLists.txt | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dbb0374..5167960 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,10 +29,10 @@ set(SOURCES cipher.cc if(MSVC) list(APPEND INCLUDE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/win32) + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/netbsd) list(APPEND SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/win32/getopt.cpp) + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/netbsd/getopt_long.c) endif() @@ -53,9 +53,6 @@ if(${VCPKG_TARGET_TRIPLET} MATCHES ".*windows-static$") endif() - -#install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) -#install(FILES $ DESTINATION bin OPTIONAL) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/p11test.exe DESTINATION bin) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/p11test.pdb DESTINATION bin OPTIONAL) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gmock.dll DESTINATION bin) @@ -73,10 +70,3 @@ set(CPACK_SOURCE_GENERATOR "ZIP") set(CPACK_SOURCE_IGNORE_FILES "build/*;\.git/*") include(CPack) - -##debug -#get_cmake_property(_variableNames VARIABLES) -#list (SORT _variableNames) -#foreach (_variableName ${_variableNames}) -# message(STATUS "${_variableName}=${${_variableName}}") -#endforeach() From f5a1536de17093298789e4f9049ac1b47607db8b Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Thu, 1 Jul 2021 16:30:58 +0200 Subject: [PATCH 26/28] fix remove unnecessary include windows.h and stdlib.h --- digest.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/digest.cc b/digest.cc index 9198ca2..419554d 100644 --- a/digest.cc +++ b/digest.cc @@ -24,8 +24,7 @@ #ifdef _WIN32 -#include -#include +#define min(a,b) (((a) < (b)) ? (a) : (b)) #endif From 71f3f71f37fbe46825f8e259ecd8d614af87a137 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Thu, 1 Jul 2021 16:42:10 +0200 Subject: [PATCH 27/28] fix remove unnecessary GTest libraries GTest::gtest_main GTest::gmock GTest::gmock_main --- CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5167960..d46ff47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ list(APPEND INCLUDE_DIRS set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTRICT_P11") find_package(GTest CONFIG REQUIRED COMPONENTS CXX_LIB) add_executable(${PROJECT_NAME} ${SOURCES}) -target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main) +target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest) target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIRS} ) if(${VCPKG_TARGET_TRIPLET} MATCHES ".*windows-static$") @@ -55,9 +55,7 @@ endif() install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/p11test.exe DESTINATION bin) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/p11test.pdb DESTINATION bin OPTIONAL) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gmock.dll DESTINATION bin) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gtest.dll DESTINATION bin) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/gtest_main.dll DESTINATION bin) # Packaging set(CPACK_PACKAGE_NAME ${PACKAGE_NAME}) From 0c8badcfe18590673080aa694ccd87d2c823ce21 Mon Sep 17 00:00:00 2001 From: Arnaud G Date: Thu, 1 Jul 2021 16:43:39 +0200 Subject: [PATCH 28/28] fix remove appveyor RDP on finish --- .appveyor.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index c595f59..08cdcb5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -31,8 +31,6 @@ build_script: - cmd: cmake --build . --config RelWithDebInfo - cmd: ctest -C RelWithDebInfo --progress --verbose - cmd: cpack -#on_finish: -# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) artifacts: - path: "build/*.zip" name: artifacts-zip