From 153dd1b3e0cf6752bf82856d5bbb1c88b914654c Mon Sep 17 00:00:00 2001 From: Petr Gotthard Date: Wed, 2 Jun 2021 12:34:14 +0200 Subject: [PATCH] Add support for OpenSSL 3.0.0, drop support for OpenSSL < 1.1.0 --- .gitignore | 1 - CMakeLists.txt | 15 +++++++++++++-- ChangeLog | 6 ++++++ Makefile.am | 6 ++++-- README.md | 4 +++- VERSION | 2 +- bootstrap.sh | 1 - configure.ac | 10 +++++++--- scripts/sscep.spec | 4 ++-- src/cmd.h | 2 ++ src/conf.h | 4 +++- src/configuration.c | 3 ++- src/engine.c | 42 ++++++++++++++++++------------------------ src/fileutils_capi.c | 2 -- src/sceputils.c | 19 ++++++++----------- src/sscep.c | 25 +++++++++++++++++-------- src/sscep.h | 4 ++-- 17 files changed, 88 insertions(+), 62 deletions(-) diff --git a/.gitignore b/.gitignore index 1bf1728..b855ca3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ /sscep_static /sscep_dyn /.git_checkout -/src/config.h* /src/*.o /sscep-*.tar.gz /sscep-*.tar.bz2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 6479302..a6e73fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,12 @@ project(sscep) if (WIN32) set(OPENSSL_USE_STATIC_LIBS TRUE) endif() + +set(OPENSSL_MIN_VERSION 1.1.0) find_package(OpenSSL REQUIRED) +option(ENABLE_ENGINES "Enable support for OpenSSL ENGINE API") + # For IDE such as Visual Studio we include also the header files set(SSCEP_SOURCES src/sscep.c @@ -17,8 +21,6 @@ set(SSCEP_SOURCES src/getopt.h src/configuration.c src/configuration.h - src/engine.c - src/engine.h src/net.c src/picohttpparser.c src/picohttpparser.h @@ -30,6 +32,15 @@ set(SSCEP_SOURCES src/sceputils.c ) +if (ENABLE_ENGINES) + set(SSCEP_SOURCES + ${SSCEP_SOURCES} + src/engine.c + src/engine.h + ) + add_definitions(-DWITH_ENGINES) +endif() + if (MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) endif() diff --git a/ChangeLog b/ChangeLog index 0d325bc..a37a7fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ SSCEP Release history ======================================== +v0.10.0 (2021-?-?) +* Compatible with OpenSSL 3.0.0 +* Engines are now disabled by default and need to be enabled by + `./configure --enable-engines` or `cmake . -DENABLE_ENGINES=ON` +* Removed support for OpenSSL < 1.1.0 + v0.9.1 (2021-07-31) * Fixed missing Host header (@papperlapapp) * Fixed multiple numeric overflows (@ziemleszcz) diff --git a/Makefile.am b/Makefile.am index 315ec49..ed418d0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,8 +9,6 @@ sscep_SOURCES = src/sscep.c \ src/getopt.h \ src/configuration.c \ src/configuration.h \ - src/engine.c \ - src/engine.h \ src/net.c \ src/picohttpparser.c \ src/picohttpparser.h \ @@ -20,6 +18,10 @@ sscep_SOURCES = src/sscep.c \ src/fileutils.c \ src/fileutils_capi.h \ src/sceputils.c +if WITH_ENGINES +sscep_SOURCES += src/engine.c \ + src/engine.h +endif dist_doc_DATA = COPYING \ README.md diff --git a/README.md b/README.md index f82d22e..ba2e7d4 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,9 @@ Currently, SSCEP implements: * All of the SCEP operations using SCEP query messages * HTTP/1.1 queries via IPv4 or IPv6 * Integration with OpenSSL cryptographic engines + * sscep 0.3.0 - 0.6.1 works with openssl 0.9.7 - 1.0.2 + * sscep 0.7.0 - 0.9.0 works with openssl 0.9.7 - 1.1.1 + * sscep 0.10.0 works with openssl 1.1.0 - 3.0.0 There's no LDAP support, and probably there will never be (that's why it is simple). @@ -127,7 +130,6 @@ $ brew install autoconf automake libtool pkg-config openssl To generate the configure script when checking out from github source: ```cmd -$ autoheader $ glibtoolize $ aclocal $ automake -a -c -f diff --git a/VERSION b/VERSION index f374f66..78bc1ab 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.1 +0.10.0 diff --git a/bootstrap.sh b/bootstrap.sh index 59dfeda..4256de0 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,6 +1,5 @@ #!/bin/sh libtoolize aclocal -autoheader automake --add-missing autoconf diff --git a/configure.ac b/configure.ac index fc806b7..9f3ee15 100644 --- a/configure.ac +++ b/configure.ac @@ -2,20 +2,24 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([sscep],[0.9.1],[certnanny@github.com]) +AC_INIT([sscep],[0.10.0],[certnanny@github.com]) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign subdir-objects dist-bzip2]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -AC_CONFIG_HEADERS([src/config.h]) AC_CONFIG_SRCDIR([src/sscep.c]) AC_CONFIG_MACRO_DIR([m4]) LT_INIT +AC_ARG_ENABLE([engines], + AS_HELP_STRING([--enable-engines], [Enable support for OpenSSL ENGINE API])) +AM_CONDITIONAL(WITH_ENGINES, test "x$enable_engines" = "xyes") +AS_IF([test "x$enable_engines" = "xyes"], [AC_DEFINE([WITH_ENGINES], [1], [ENGINE API enabled])]) + # Checks for programs. AC_PROG_CC # Checks for libraries. -PKG_CHECK_MODULES(openssl, openssl >= 0.9.7) +PKG_CHECK_MODULES(openssl, openssl >= 1.1.0) # CFLAGS="$CFLAGS $openssl_CFLAGS" CPPFLAGS="$CPPFLAGS $openssl_CPPFLAGS" diff --git a/scripts/sscep.spec b/scripts/sscep.spec index c1bcf5b..4dbca58 100644 --- a/scripts/sscep.spec +++ b/scripts/sscep.spec @@ -4,14 +4,14 @@ # Name: sscep -Version: 0.9.1 +Version: 0.10.0 Release: 1 Summary: Simple SCEP client License: BSD Group: Productivity/Security Source: %{name}-%{version}.tar.gz URL: https://github.com/certnanny/sscep -Requires: openssl >= 1:0.9.7 +Requires: openssl >= 1:1.1.0 %description Simple SCEP (Simple Certificate Enrollment Protocol) client. diff --git a/src/cmd.h b/src/cmd.h index ebe5028..a86ff9d 100644 --- a/src/cmd.h +++ b/src/cmd.h @@ -39,9 +39,11 @@ extern char *f_char; extern char *F_char; extern int F_flag; +#ifdef WITH_ENGINES /* enable EnGine support */ extern char *g_char; extern int g_flag; +#endif /* enable hwcrhk keys * To set this means that the new key (for which you have the diff --git a/src/conf.h b/src/conf.h index f4a5988..d589d99 100644 --- a/src/conf.h +++ b/src/conf.h @@ -4,7 +4,8 @@ * Copyright (c) Jarkko Turkulainen 2003. All rights reserved. * See the file COPYRIGHT for licensing information. */ - +#ifndef CONF_H +#define CONF_H /* Network timeout */ #define TIMEOUT 120 @@ -27,3 +28,4 @@ /* Transaction id for GetCert and GetCrl methods */ #define TRANS_ID_GETCERT "SSCEP transactionId" +#endif /* ifndef CONF_H */ diff --git a/src/configuration.c b/src/configuration.c index 7043da8..c795011 100644 --- a/src/configuration.c +++ b/src/configuration.c @@ -160,11 +160,12 @@ int scep_conf_init(char *filename, int operation_flag) { //write g_char, but ONLY if not defined already (command line overwrites config file) +#ifdef WITH_ENGINES if(!g_flag) { g_flag = 1; g_char = strdup(scep_conf->engine->engine_id); } - +#endif //load the special section string engine_special_section = (char *) malloc(sizeof(SCEP_CONFIGURATION_SECTION_ENGINE_TEMPLATE) + sizeof(scep_conf->engine->engine_id)); sprintf(engine_special_section, SCEP_CONFIGURATION_SECTION_ENGINE_TEMPLATE, scep_conf->engine->engine_id); diff --git a/src/engine.c b/src/engine.c index 58ae34d..169a5bc 100644 --- a/src/engine.c +++ b/src/engine.c @@ -23,7 +23,7 @@ ENGINE *scep_engine_init() { if(scep_conf && scep_conf->engine->module_path) { if(ENGINE_ctrl_cmd_string(e, "MODULE_PATH", scep_conf->engine->module_path, 0) == 0) { fprintf(stderr, "%s: Adding MODULE PATH %s was not successful!\n", pname, scep_conf->engine->module_path); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } } @@ -31,7 +31,7 @@ ENGINE *scep_engine_init() { //define this engine as a default for all our crypto operations. This way OpenSSL automatically chooses the right functions if(ENGINE_set_default(e, ENGINE_METHOD_ALL) == 0) { fprintf(stderr, "%s: Error loading on setting defaults\n", pname); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } else if(v_flag) printf("%s: Engine %s made default for all operations\n", pname, g_char); @@ -39,7 +39,7 @@ ENGINE *scep_engine_init() { //we need a functional reference and as such need to initialize if(ENGINE_init(e) == 0) { fprintf(stderr, "%s: Engine Init did not work\n", pname); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } else if(v_flag) printf("%s: Engine %s initialized\n", pname, g_char); @@ -52,13 +52,13 @@ ENGINE *scep_engine_init() { // set debug level if(!ENGINE_ctrl(e, (ENGINE_CMD_BASE + 2), 2, NULL, NULL)) { fprintf(stderr, "%s: Could not set debug level to %i\n", pname, 2); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } // set debug file (log) if(!ENGINE_ctrl(e, (ENGINE_CMD_BASE + 3), 0, "capi.log", NULL)) { fprintf(stderr, "%s: Could not set debug file to %s\n", pname, "capi.log"); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } } @@ -68,7 +68,7 @@ ENGINE *scep_engine_init() { if(scep_conf->engine->storepass) { if(!ENGINE_ctrl(e, 2, 0, scep_conf->engine->storepass, NULL)) { fprintf(stderr, "%s: Could not set %s\n", pname, SCEP_CONFIGURATION_ENGINE_JKSENGINE_KEYSTOREPASS); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } } @@ -76,7 +76,7 @@ ENGINE *scep_engine_init() { if(scep_conf->engine->jconnpath) { if(!ENGINE_ctrl(e, 3, 0, scep_conf->engine->jconnpath, 0)) { fprintf(stderr, "%s: Could not set %s\n", pname, SCEP_CONFIGURATION_ENGINE_JKSENGINE_JCONNPATH); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } } @@ -84,7 +84,7 @@ ENGINE *scep_engine_init() { if(scep_conf->engine->provider) { if(!ENGINE_ctrl(e, 4, 0, scep_conf->engine->provider, 0)) { fprintf(stderr, "%s: Could not set %s\n", pname, SCEP_CONFIGURATION_ENGINE_JKSENGINE_PROVIDER); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } } @@ -92,7 +92,7 @@ ENGINE *scep_engine_init() { if(scep_conf->engine->javapath) { if(!ENGINE_ctrl(e, 5, 0, scep_conf->engine->javapath, 0)) { fprintf(stderr, "%s: Could not set %s\n", pname, SCEP_CONFIGURATION_ENGINE_JKSENGINE_JAVAPATH); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } } @@ -103,7 +103,7 @@ ENGINE *scep_engine_init() { if(scep_conf->engine->pin) { if(!ENGINE_ctrl(e, (ENGINE_CMD_BASE + 2), 0, scep_conf->engine->pin, NULL)) { fprintf(stderr, "%s: Could not define PIN\n", pname); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } } @@ -121,7 +121,7 @@ ENGINE *scep_engine_load_dynamic() { //if we can't even load the dynamic engine, something is seriously wrong. We can't go on from here! if(e == NULL) { fprintf(stderr, "%s: Engine dynamic could not be loaded, Error message\n", pname); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } else if(v_flag) printf("%s: Engine dynamic was loaded\n", pname); @@ -130,7 +130,7 @@ ENGINE *scep_engine_load_dynamic() { if(scep_conf && scep_conf->engine->dynamic_path) { if(ENGINE_ctrl_cmd_string(e, "SO_PATH", scep_conf->engine->dynamic_path, 0) == 0) { fprintf(stderr, "%s: Loading %s did not succeed\n", pname, g_char); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } else if (v_flag) printf("%s: %s was found.\n", pname, g_char); @@ -139,7 +139,7 @@ ENGINE *scep_engine_load_dynamic() { //engine will be added to the list of available engines. Should be done for complete import. if(ENGINE_ctrl_cmd_string(e, "LIST_ADD", "1", 0) == 0) { fprintf(stderr, "%s: Executing LIST_ADD did not succeed:\n", pname); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } else if(v_flag) printf("%s: Added %s to list of engines.\n", pname, g_char); @@ -151,7 +151,7 @@ ENGINE *scep_engine_load_dynamic() { //Finally we load the engine. if(ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0) == 0) { fprintf(stderr, "%s: Executing LOAD did not succeed:\n", pname); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } else if(v_flag) printf("%s: Loading engine %s succeeded\n", pname, g_char); @@ -163,7 +163,7 @@ ENGINE *scep_engine_load_dynamic() { NAME_VALUE_PAIR *cmd = scep_conf->engine->cmds[i]; if(ENGINE_ctrl_cmd_string(e, cmd->name, cmd->value, 0) == 0) { fprintf(stderr, "%s: Executing %s=%s failed\n", pname, cmd->name, cmd->value); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_ERROR); } else if(v_flag) { fprintf(stderr, "%s: Engine command %s=%s succeeded\n", pname, cmd->name, cmd->value); @@ -192,7 +192,7 @@ void sscep_engine_read_key(EVP_PKEY **key, char *id, ENGINE *e) { if(*key == 0) { printf("Could not load private key!\n"); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit(SCEP_PKISTATUS_FILE); } } @@ -225,7 +225,7 @@ void sscep_engine_read_key_capi(EVP_PKEY **key, char *id, ENGINE *e, char *store if(!ENGINE_ctrl(e, CAPI_CMD_STORE_FLAGS, scep_conf->engine->storelocation, NULL, NULL)) { fprintf(stderr, "%s: Executing CAPI_CMD_STORE_FLAGS did not succeed\n", pname); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit(SCEP_PKISTATUS_ERROR); } else { printf("%s: Set storelocation to %i\n", pname, scep_conf->engine->storelocation); @@ -233,14 +233,8 @@ void sscep_engine_read_key_capi(EVP_PKEY **key, char *id, ENGINE *e, char *store if(!ENGINE_ctrl(e, CAPI_CMD_STORE_NAME, 0, (void*)storename, NULL)) { fprintf(stderr, "%s: Executing CAPI_CMD_STORE_NAME did not succeed\n", pname); - sscep_engine_report_error(); + ERR_print_errors_fp(stderr); exit(SCEP_PKISTATUS_ERROR); } sscep_engine_read_key(key, id, e); } - -void sscep_engine_report_error() { - ERR_load_crypto_strings(); - ERR_print_errors_fp(stderr); - ERR_free_strings(); -} diff --git a/src/fileutils_capi.c b/src/fileutils_capi.c index 2758503..b17f701 100644 --- a/src/fileutils_capi.c +++ b/src/fileutils_capi.c @@ -8,9 +8,7 @@ void capi_read_key_Engine(EVP_PKEY** key, char* id, ENGINE *e, char* storename); void capi_read_key_Engine(EVP_PKEY** key, char* id, ENGINE *e, char* storename) { if(!ENGINE_ctrl(e, CAPI_CMD_STORE_NAME, 0, (void*)storename, NULL)) { - ERR_load_CRYPTO_strings(); fprintf(stderr, "Executing CAPI_CMD_STORE_NAME did not succeed: %s\n", ERR_error_string(ERR_peek_last_error(), NULL)); - ERR_free_strings(); exit(SCEP_PKISTATUS_ERROR); } //loading the key diff --git a/src/sceputils.c b/src/sceputils.c index 3e57e96..68589d5 100644 --- a/src/sceputils.c +++ b/src/sceputils.c @@ -136,12 +136,12 @@ int new_selfsigned(struct scep *s) { exit (SCEP_PKISTATUS_SS); } /* Set duration */ - if (!(X509_gmtime_adj(X509_get_notBefore(cert), 0))) { + if (!(X509_gmtime_adj(X509_getm_notBefore(cert), 0))) { fprintf(stderr, "%s: error setting begin time", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_SS); } - if (!(X509_gmtime_adj(X509_get_notAfter(cert), + if (!(X509_gmtime_adj(X509_getm_notAfter(cert), SELFSIGNED_EXPIRE_DAYS * 24 * 60))) { fprintf(stderr, "%s: error setting end time", pname); ERR_print_errors_fp(stderr); @@ -173,12 +173,7 @@ int new_selfsigned(struct scep *s) { * Initialize SCEP */ int init_scep() { - /* Initialize OpenSSL crypto */ - OpenSSL_add_all_algorithms(); - ERR_load_crypto_strings(); - /* Create OpenSSL NIDs */ - nid_messageType = OBJ_create("2.16.840.1.113733.1.9.2", "messageType", "messageType"); if (nid_messageType == 0) { @@ -232,7 +227,7 @@ key_fingerprint(X509_REQ *req) { unsigned char *data, md[MD5_DIGEST_LENGTH]; int c, len; BIO *bio; - MD5_CTX ctx; + EVP_MD_CTX *mdctx; /* Assign space for ASCII presentation of the digest */ str = (char *)malloc(2 * MD5_DIGEST_LENGTH + 1); @@ -244,9 +239,11 @@ key_fingerprint(X509_REQ *req) { len = BIO_get_mem_data(bio, &data); /* Calculate MD5 hash: */ - MD5_Init(&ctx); - MD5_Update(&ctx, data, len); - MD5_Final(md, &ctx); + mdctx = EVP_MD_CTX_new(); + EVP_DigestInit_ex(mdctx, EVP_md5(), NULL); + EVP_DigestUpdate(mdctx, data, len); + EVP_DigestFinal_ex(mdctx, md, NULL); + EVP_MD_CTX_free(mdctx); /* Copy as ASCII string and return: */ for (c = 0; c < MD5_DIGEST_LENGTH; c++, str += 2) { diff --git a/src/sscep.c b/src/sscep.c index 9f7d744..770e7ba 100644 --- a/src/sscep.c +++ b/src/sscep.c @@ -26,7 +26,9 @@ char *f_char; char *F_char; int F_flag; char *g_char; +#ifdef WITH_ENGINES int g_flag; +#endif int h_flag; int H_flag; char *l_char; @@ -272,10 +274,12 @@ main(int argc, char **argv) { f_flag = 1; f_char = optarg; break; +#ifdef WITH_ENGINES case 'g': g_flag = 1; g_char = optarg; break; +#endif case 'h'://TODO change to eg. ID --inform=ID h_flag = 1; break; @@ -405,11 +409,12 @@ main(int argc, char **argv) { fprintf(stdout, "%s: new transaction\n", pname); new_transaction(&scep_t, operation_flag); +#ifdef WITH_ENGINES /*enable Engine Support */ if (g_flag) { scep_t.e = scep_engine_init(); } - +#endif /* * Check argument logic. */ @@ -922,11 +927,12 @@ main(int argc, char **argv) { exit (SCEP_PKISTATUS_FILE); } - if(g_flag) { +#ifdef WITH_ENGINES + if(g_flag) sscep_engine_read_key_new(&rsa, k_char, scep_t.e); - } else { + else +#endif rsa = read_key(k_char); - } if ((K_flag && !O_flag) || (!K_flag && O_flag)) { @@ -936,11 +942,12 @@ main(int argc, char **argv) { if (K_flag) { //TODO auf hwcrhk prfen? - if(g_flag) { +#ifdef WITH_ENGINES + if(g_flag) sscep_engine_read_key_old(&renewal_key, K_char, scep_t.e); - } else { + else +#endif renewal_key = read_key(K_char); - } } if (O_flag) { @@ -1245,8 +1252,10 @@ usage() { " -u SCEP server URL\n" " -p Use proxy server at host:port\n" " -M Monitor Information String name=value&name=value ...\n" +#ifdef WITH_ENGINES " -g Use the given cryptographic engine\n" - " -h Keyforme=ID. \n"//TODO +#endif + " -h Keyforme=ID. \n"//TODO " -f Use configuration file\n" " -c CA certificate file or '-n' suffixed files (write if OPERATION is getca)\n" " -E PKCS#7 encryption algorithm (des|3des|blowfish|aes[128]|aes192|aes256)\n" diff --git a/src/sscep.h b/src/sscep.h index 75916d9..d95acca 100644 --- a/src/sscep.h +++ b/src/sscep.h @@ -66,7 +66,7 @@ #include /* Global defines */ -#define VERSION "0.9.1" +#define VERSION "0.10.0" /* SCEP operations */ #define SCEP_OPERATION_GETCA 1 @@ -257,7 +257,7 @@ struct scep { /* Request */ PKCS7 *request_p7; - unsigned char *request_payload; + char *request_payload; int request_len; PKCS7_ISSUER_AND_SUBJECT *ias_getcertinit; PKCS7_ISSUER_AND_SERIAL *ias_getcert;