diff --git a/acx_nlnetlabs.m4 b/acx_nlnetlabs.m4 index 7ce790708..39e92d875 100644 --- a/acx_nlnetlabs.m4 +++ b/acx_nlnetlabs.m4 @@ -2,7 +2,8 @@ # Copyright 2009, Wouter Wijngaards, NLnet Labs. # BSD licensed. # -# Version 40 +# Version 41 +# 2021-07-30 fix for openssl use of lib64 directory. # 2021-06-14 fix nonblocking test to use host instead of target for mingw test. # 2021-05-17 fix nonblocking socket test from grep on mingw32 to mingw for # 64bit compatibility. @@ -669,9 +670,15 @@ AC_DEFUN([ACX_SSL_CHECKS], [ HAVE_SSL=yes dnl assume /usr is already in the lib and dynlib paths. if test "$ssldir" != "/usr" -a "$ssldir" != ""; then - LDFLAGS="$LDFLAGS -L$ssldir/lib" - LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib" - ACX_RUNTIME_PATH_ADD([$ssldir/lib]) + if test ! -d "$ssldir/lib" -a -d "$ssldir/lib64"; then + LDFLAGS="$LDFLAGS -L$ssldir/lib64" + LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib64" + ACX_RUNTIME_PATH_ADD([$ssldir/lib64]) + else + LDFLAGS="$LDFLAGS -L$ssldir/lib" + LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib" + ACX_RUNTIME_PATH_ADD([$ssldir/lib]) + fi fi AC_MSG_CHECKING([for EVP_sha256 in -lcrypto]) diff --git a/config.h.in b/config.h.in index cb27afa4f..8fdf83e74 100644 --- a/config.h.in +++ b/config.h.in @@ -429,6 +429,9 @@ /* Define to 1 if you have the `OPENSSL_init_ssl' function. */ #undef HAVE_OPENSSL_INIT_SSL +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_PARAM_BUILD_H + /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_RAND_H @@ -438,6 +441,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_SSL_H +/* Define to 1 if you have the `OSSL_PARAM_BLD_new' function. */ +#undef HAVE_OSSL_PARAM_BLD_NEW + /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD @@ -541,6 +547,9 @@ /* Define to 1 if you have the `SSL_get0_peername' function. */ #undef HAVE_SSL_GET0_PEERNAME +/* Define to 1 if you have the `SSL_get1_peer_certificate' function. */ +#undef HAVE_SSL_GET1_PEER_CERTIFICATE + /* Define to 1 if you have the `SSL_set1_host' function. */ #undef HAVE_SSL_SET1_HOST diff --git a/configure b/configure index 7e722b59e..84c97357f 100755 --- a/configure +++ b/configure @@ -811,7 +811,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -962,7 +961,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1215,15 +1213,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1361,7 +1350,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1514,7 +1503,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -18020,8 +18008,19 @@ _ACEOF $as_echo "found in $ssldir" >&6; } HAVE_SSL=yes if test "$ssldir" != "/usr" -a "$ssldir" != ""; then - LDFLAGS="$LDFLAGS -L$ssldir/lib" - LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib" + if test ! -d "$ssldir/lib" -a -d "$ssldir/lib64"; then + LDFLAGS="$LDFLAGS -L$ssldir/lib64" + LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib64" + + if test "x$enable_rpath" = xyes; then + if echo "$ssldir/lib64" | grep "^/" >/dev/null; then + RUNTIME_PATH="$RUNTIME_PATH -R$ssldir/lib64" + fi + fi + + else + LDFLAGS="$LDFLAGS -L$ssldir/lib" + LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib" if test "x$enable_rpath" = xyes; then if echo "$ssldir/lib" | grep "^/" >/dev/null; then @@ -18029,6 +18028,7 @@ $as_echo "found in $ssldir" >&6; } fi fi + fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_sha256 in -lcrypto" >&5 @@ -18411,7 +18411,7 @@ else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi -for ac_header in openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h +for ac_header in openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h openssl/param_build.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default @@ -18425,7 +18425,7 @@ fi done -for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params +for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -18441,7 +18441,7 @@ done # these check_funcs need -lssl BAKLIBS="$LIBS" LIBS="-lssl $LIBS" -for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos +for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.ac b/configure.ac index 5ffbe6834..2ec11b970 100644 --- a/configure.ac +++ b/configure.ac @@ -859,13 +859,13 @@ if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" >/dev/ else AC_MSG_RESULT([no]) fi -AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h],,, [AC_INCLUDES_DEFAULT]) -AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params]) +AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h openssl/param_build.h],,, [AC_INCLUDES_DEFAULT]) +AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new]) # these check_funcs need -lssl BAKLIBS="$LIBS" LIBS="-lssl $LIBS" -AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos]) +AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate]) LIBS="$BAKLIBS" AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [ diff --git a/daemon/remote.c b/daemon/remote.c index dd17bff91..923ddefa4 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -3338,7 +3338,11 @@ int remote_control_callback(struct comm_point* c, void* arg, int err, if (!rc->use_cert) { verbose(VERB_ALGO, "unauthenticated remote control connection"); } else if(SSL_get_verify_result(s->ssl) == X509_V_OK) { +#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE + X509* x = SSL_get1_peer_certificate(s->ssl); +#else X509* x = SSL_get_peer_certificate(s->ssl); +#endif if(!x) { verbose(VERB_DETAIL, "remote control connection " "provided no client certificate"); diff --git a/doc/Changelog b/doc/Changelog index 94daab83b..8544a8266 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -2,6 +2,21 @@ - Listen to read or write events after the SSL handshake. Sticky events on windows would stick on read when write was needed. +2 August 2021: Wouter + - Prepare for OpenSSL 3.0.0 provider API usage, move the sldns + keyraw functions to produce EVP_PKEY results. + - Move RSA and DSA to use OpenSSL 3.0.0 API. + - Move ECDSA functions to use OpenSSL 3.0.0 API. + - iana portlist update. + - Fix verbose printout failure in tcp reuse unit test. + +30 July 2021: Wouter + - Fix #515: Compilation against openssl 3.0.0 beta2 is failing to + build unbound. + - For #515: Fix compilation with openssl 3.0.0 beta2, lib64 dir and + SSL_get_peer_certificate. + - Move acx_nlnetlabs.m4 to version 41, with lib64 openssl dir check. + 26 July 2021: George - Merge #513: Stream reuse, attempt to fix #411, #439, #469. This introduces a couple of fixes for the stream reuse functionality diff --git a/services/outside_network.c b/services/outside_network.c index 73cb4ff32..a3f982e72 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -347,6 +347,8 @@ log_reuse_tcp(enum verbosity_value v, const char* msg, struct reuse_tcp* reuse) uint16_t port; char addrbuf[128]; if(verbosity < v) return; + if(!reuse || !reuse->pending || !reuse->pending->c) + return; addr_to_str(&reuse->addr, reuse->addrlen, addrbuf, sizeof(addrbuf)); port = ntohs(((struct sockaddr_in*)&reuse->addr)->sin_port); verbose(v, "%s %s#%u fd %d", msg, addrbuf, (unsigned)port, diff --git a/sldns/keyraw.c b/sldns/keyraw.c index 2ec225bc5..b1e60d8b5 100644 --- a/sldns/keyraw.c +++ b/sldns/keyraw.c @@ -26,11 +26,15 @@ #ifdef HAVE_OPENSSL_BN_H #include #endif -#ifdef HAVE_OPENSSL_RSA_H -#include -#endif -#ifdef HAVE_OPENSSL_DSA_H -#include +#ifdef HAVE_OPENSSL_PARAM_BUILD_H +# include +#else +# ifdef HAVE_OPENSSL_RSA_H +# include +# endif +# ifdef HAVE_OPENSSL_DSA_H +# include +# endif #endif #endif /* HAVE_SSL */ @@ -191,45 +195,59 @@ void sldns_key_EVP_unload_gost(void) } #endif /* USE_GOST */ -DSA * -sldns_key_buf2dsa_raw(unsigned char* key, size_t len) +/* Retrieve params as BIGNUM from raw buffer */ +static int +sldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p, + BIGNUM** q, BIGNUM** g, BIGNUM** y) { uint8_t T; uint16_t length; uint16_t offset; - DSA *dsa; - BIGNUM *Q; BIGNUM *P; - BIGNUM *G; BIGNUM *Y; if(len == 0) - return NULL; + return 0; T = (uint8_t)key[0]; length = (64 + T * 8); offset = 1; if (T > 8) { - return NULL; + return 0; } if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length) - return NULL; + return 0; - Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL); + *q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL); offset += SHA_DIGEST_LENGTH; - P = BN_bin2bn(key+offset, (int)length, NULL); + *p = BN_bin2bn(key+offset, (int)length, NULL); offset += length; - G = BN_bin2bn(key+offset, (int)length, NULL); + *g = BN_bin2bn(key+offset, (int)length, NULL); offset += length; - Y = BN_bin2bn(key+offset, (int)length, NULL); + *y = BN_bin2bn(key+offset, (int)length, NULL); + if(!*q || !*p || !*g || !*y) { + BN_free(*q); + BN_free(*p); + BN_free(*g); + BN_free(*y); + return 0; + } + return 1; +} + +#ifndef HAVE_OSSL_PARAM_BLD_NEW +DSA * +sldns_key_buf2dsa_raw(unsigned char* key, size_t len) +{ + DSA *dsa; + BIGNUM *Q=NULL, *P=NULL, *G=NULL, *Y=NULL; + if(!sldns_key_dsa_buf_bignum(key, len, &P, &Q, &G, &Y)) { + return NULL; + } /* create the key and set its properties */ - if(!Q || !P || !G || !Y || !(dsa = DSA_new())) { - BN_free(Q); - BN_free(P); - BN_free(G); - BN_free(Y); + if(!(dsa = DSA_new())) { return NULL; } #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) @@ -261,22 +279,111 @@ sldns_key_buf2dsa_raw(unsigned char* key, size_t len) return dsa; } +#endif /* HAVE_OSSL_PARAM_BLD_NEW */ -RSA * -sldns_key_buf2rsa_raw(unsigned char* key, size_t len) +EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len) +{ +#ifdef HAVE_OSSL_PARAM_BLD_NEW + EVP_PKEY* evp_key = NULL; + EVP_PKEY_CTX* ctx; + BIGNUM *p=NULL, *q=NULL, *g=NULL, *y=NULL; + OSSL_PARAM_BLD* param_bld; + OSSL_PARAM* params = NULL; + if(!sldns_key_dsa_buf_bignum(key, len, &p, &q, &g, &y)) { + return NULL; + } + + param_bld = OSSL_PARAM_BLD_new(); + if(!param_bld) { + BN_free(p); + BN_free(q); + BN_free(g); + BN_free(y); + return NULL; + } + if(!OSSL_PARAM_BLD_push_BN(param_bld, "p", p) || + !OSSL_PARAM_BLD_push_BN(param_bld, "g", g) || + !OSSL_PARAM_BLD_push_BN(param_bld, "q", q) || + !OSSL_PARAM_BLD_push_BN(param_bld, "pub", y)) { + OSSL_PARAM_BLD_free(param_bld); + BN_free(p); + BN_free(q); + BN_free(g); + BN_free(y); + return NULL; + } + params = OSSL_PARAM_BLD_to_param(param_bld); + OSSL_PARAM_BLD_free(param_bld); + + ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL); + if(!ctx) { + OSSL_PARAM_free(params); + BN_free(p); + BN_free(q); + BN_free(g); + BN_free(y); + return NULL; + } + if(EVP_PKEY_fromdata_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + BN_free(p); + BN_free(q); + BN_free(g); + BN_free(y); + return NULL; + } + if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + BN_free(p); + BN_free(q); + BN_free(g); + BN_free(y); + return NULL; + } + + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + BN_free(p); + BN_free(q); + BN_free(g); + BN_free(y); + return evp_key; +#else + DSA* dsa; + EVP_PKEY* evp_key = EVP_PKEY_new(); + if(!evp_key) { + return NULL; + } + dsa = sldns_key_buf2dsa_raw(key, len); + if(!dsa) { + EVP_PKEY_free(evp_key); + return NULL; + } + if(EVP_PKEY_assign_DSA(evp_key, dsa) == 0) { + DSA_free(dsa); + EVP_PKEY_free(evp_key); + return NULL; + } + return evp_key; +#endif +} + +/* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */ +static int +sldns_key_rsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** n, + BIGNUM** e) { uint16_t offset; uint16_t exp; uint16_t int16; - RSA *rsa; - BIGNUM *modulus; - BIGNUM *exponent; if (len == 0) - return NULL; + return 0; if (key[0] == 0) { if(len < 3) - return NULL; + return 0; memmove(&int16, key+1, 2); exp = ntohs(int16); offset = 3; @@ -287,23 +394,34 @@ sldns_key_buf2rsa_raw(unsigned char* key, size_t len) /* key length at least one */ if(len < (size_t)offset + exp + 1) - return NULL; + return 0; /* Exponent */ - exponent = BN_new(); - if(!exponent) return NULL; - (void) BN_bin2bn(key+offset, (int)exp, exponent); + *e = BN_new(); + if(!*e) return 0; + (void) BN_bin2bn(key+offset, (int)exp, *e); offset += exp; /* Modulus */ - modulus = BN_new(); - if(!modulus) { - BN_free(exponent); - return NULL; + *n = BN_new(); + if(!*n) { + BN_free(*e); + return 0; } /* length of the buffer must match the key length! */ - (void) BN_bin2bn(key+offset, (int)(len - offset), modulus); + (void) BN_bin2bn(key+offset, (int)(len - offset), *n); + return 1; +} +#ifndef HAVE_OSSL_PARAM_BLD_NEW +RSA * +sldns_key_buf2rsa_raw(unsigned char* key, size_t len) +{ + BIGNUM* modulus = NULL; + BIGNUM* exponent = NULL; + RSA *rsa; + if(!sldns_key_rsa_buf_bignum(key, len, &modulus, &exponent)) + return NULL; rsa = RSA_new(); if(!rsa) { BN_free(exponent); @@ -327,6 +445,88 @@ sldns_key_buf2rsa_raw(unsigned char* key, size_t len) return rsa; } +#endif /* HAVE_OSSL_PARAM_BLD_NEW */ + +EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len) +{ +#ifdef HAVE_OSSL_PARAM_BLD_NEW + EVP_PKEY* evp_key = NULL; + EVP_PKEY_CTX* ctx; + BIGNUM *n=NULL, *e=NULL; + OSSL_PARAM_BLD* param_bld; + OSSL_PARAM* params = NULL; + + if(!sldns_key_rsa_buf_bignum(key, len, &n, &e)) { + return NULL; + } + + param_bld = OSSL_PARAM_BLD_new(); + if(!param_bld) { + BN_free(n); + BN_free(e); + return NULL; + } + if(!OSSL_PARAM_BLD_push_BN(param_bld, "n", n)) { + OSSL_PARAM_BLD_free(param_bld); + BN_free(n); + BN_free(e); + return NULL; + } + if(!OSSL_PARAM_BLD_push_BN(param_bld, "e", e)) { + OSSL_PARAM_BLD_free(param_bld); + BN_free(n); + BN_free(e); + return NULL; + } + params = OSSL_PARAM_BLD_to_param(param_bld); + OSSL_PARAM_BLD_free(param_bld); + + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if(!ctx) { + OSSL_PARAM_free(params); + BN_free(n); + BN_free(e); + return NULL; + } + if(EVP_PKEY_fromdata_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + BN_free(n); + BN_free(e); + return NULL; + } + if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + BN_free(n); + BN_free(e); + return NULL; + } + + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + BN_free(n); + BN_free(e); + return evp_key; +#else + RSA* rsa; + EVP_PKEY *evp_key = EVP_PKEY_new(); + if(!evp_key) { + return NULL; + } + rsa = sldns_key_buf2rsa_raw(key, len); + if(!rsa) { + EVP_PKEY_free(evp_key); + return NULL; + } + if(EVP_PKEY_assign_RSA(evp_key, rsa) == 0) { + RSA_free(rsa); + EVP_PKEY_free(evp_key); + return NULL; + } + return evp_key; +#endif +} #ifdef USE_GOST EVP_PKEY* @@ -357,6 +557,62 @@ sldns_gost2pkey_raw(unsigned char* key, size_t keylen) EVP_PKEY* sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo) { +#ifdef HAVE_OSSL_PARAM_BLD_NEW + unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ + EVP_PKEY *evp_key = NULL; + EVP_PKEY_CTX* ctx; + OSSL_PARAM_BLD* param_bld; + OSSL_PARAM* params = NULL; + char* group = NULL; + + /* check length, which uncompressed must be 2 bignums */ + if(algo == LDNS_ECDSAP256SHA256) { + if(keylen != 2*256/8) return NULL; + group = "prime256v1"; + } else if(algo == LDNS_ECDSAP384SHA384) { + if(keylen != 2*384/8) return NULL; + group = "P-384"; + } else { + return NULL; + } + if(keylen+1 > sizeof(buf)) { /* sanity check */ + return NULL; + } + /* prepend the 0x04 for uncompressed format */ + buf[0] = POINT_CONVERSION_UNCOMPRESSED; + memmove(buf+1, key, keylen); + + param_bld = OSSL_PARAM_BLD_new(); + if(!param_bld) { + return NULL; + } + if(!OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", group, 0) || + !OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", buf, keylen+1)) { + OSSL_PARAM_BLD_free(param_bld); + return NULL; + } + params = OSSL_PARAM_BLD_to_param(param_bld); + OSSL_PARAM_BLD_free(param_bld); + + ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + if(!ctx) { + OSSL_PARAM_free(params); + return NULL; + } + if(EVP_PKEY_fromdata_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + return NULL; + } + if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) { + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + return NULL; + } + EVP_PKEY_CTX_free(ctx); + OSSL_PARAM_free(params); + return evp_key; +#else unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ const unsigned char* pp = buf; EVP_PKEY *evp_key; @@ -393,6 +649,7 @@ sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo) return NULL; } return evp_key; +#endif /* HAVE_OSSL_PARAM_BLD_NEW */ } #endif /* USE_ECDSA */ diff --git a/sldns/keyraw.h b/sldns/keyraw.h index 989b02ce0..b1f19740c 100644 --- a/sldns/keyraw.h +++ b/sldns/keyraw.h @@ -57,6 +57,7 @@ int sldns_key_EVP_load_gost_id(void); /** Release the engine reference held for the GOST engine. */ void sldns_key_EVP_unload_gost(void); +#ifndef HAVE_OSSL_PARAM_BLD_NEW /** * Like sldns_key_buf2dsa, but uses raw buffer. * \param[in] key the uncompressed wireformat of the key. @@ -64,6 +65,15 @@ void sldns_key_EVP_unload_gost(void); * \return a DSA * structure with the key material */ DSA *sldns_key_buf2dsa_raw(unsigned char* key, size_t len); +#endif + +/** + * Converts a holding buffer with DSA key material to EVP PKEY in openssl. + * \param[in] key the uncompressed wireformat of the key. + * \param[in] len length of key data + * \return the key or NULL on error. + */ +EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len); /** * Converts a holding buffer with key material to EVP PKEY in openssl. @@ -84,6 +94,7 @@ EVP_PKEY* sldns_gost2pkey_raw(unsigned char* key, size_t keylen); */ EVP_PKEY* sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo); +#ifndef HAVE_OSSL_PARAM_BLD_NEW /** * Like sldns_key_buf2rsa, but uses raw buffer. * \param[in] key the uncompressed wireformat of the key. @@ -91,6 +102,15 @@ EVP_PKEY* sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo); * \return a RSA * structure with the key material */ RSA *sldns_key_buf2rsa_raw(unsigned char* key, size_t len); +#endif + +/** + * Converts a holding buffer with RSA key material to EVP PKEY in openssl. + * \param[in] key the uncompressed wireformat of the key. + * \param[in] len length of key data + * \return the key or NULL on error. + */ +EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len); /** * Converts a holding buffer with key material to EVP PKEY in openssl. diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index af72f2a4e..a3df25795 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -499,9 +499,7 @@ static void ssl_path_err(const char* s, const char *path) { unsigned long err; err = ERR_peek_error(); - if (ERR_GET_LIB(err) == ERR_LIB_SYS && - (ERR_GET_FUNC(err) == SYS_F_FOPEN || - ERR_GET_FUNC(err) == SYS_F_FREAD) ) { + if (ERR_GET_LIB(err) == ERR_LIB_SYS) { fprintf(stderr, "error: %s\n%s: %s\n", s, path, ERR_reason_error_string(err)); exit(1); diff --git a/util/iana_ports.inc b/util/iana_ports.inc index f928d0669..b93af015d 100644 --- a/util/iana_ports.inc +++ b/util/iana_ports.inc @@ -4244,6 +4244,7 @@ 5504, 5505, 5506, +5540, 5553, 5554, 5555, diff --git a/util/netevent.c b/util/netevent.c index 9c99c677b..48dbdf18d 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -1271,7 +1271,11 @@ ssl_handshake(struct comm_point* c) if((SSL_get_verify_mode(c->ssl)&SSL_VERIFY_PEER)) { /* verification */ if(SSL_get_verify_result(c->ssl) == X509_V_OK) { +#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE + X509* x = SSL_get1_peer_certificate(c->ssl); +#else X509* x = SSL_get_peer_certificate(c->ssl); +#endif if(!x) { log_addr(VERB_ALGO, "SSL connection failed: " "no certificate", @@ -1297,7 +1301,11 @@ ssl_handshake(struct comm_point* c) #endif X509_free(x); } else { +#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE + X509* x = SSL_get1_peer_certificate(c->ssl); +#else X509* x = SSL_get_peer_certificate(c->ssl); +#endif if(x) { log_cert(VERB_ALGO, "peer certificate", x); X509_free(x); diff --git a/validator/val_secalgo.c b/validator/val_secalgo.c index a4d020143..7abf66f01 100644 --- a/validator/val_secalgo.c +++ b/validator/val_secalgo.c @@ -513,29 +513,13 @@ static int setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, unsigned char* key, size_t keylen) { -#if defined(USE_DSA) && defined(USE_SHA1) - DSA* dsa; -#endif - RSA* rsa; - switch(algo) { #if defined(USE_DSA) && defined(USE_SHA1) case LDNS_DSA: case LDNS_DSA_NSEC3: - *evp_key = EVP_PKEY_new(); + *evp_key = sldns_key_dsa2pkey_raw(key, keylen); if(!*evp_key) { - log_err("verify: malloc failure in crypto"); - return 0; - } - dsa = sldns_key_buf2dsa_raw(key, keylen); - if(!dsa) { - verbose(VERB_QUERY, "verify: " - "sldns_key_buf2dsa_raw failed"); - return 0; - } - if(EVP_PKEY_assign_DSA(*evp_key, dsa) == 0) { - verbose(VERB_QUERY, "verify: " - "EVP_PKEY_assign_DSA failed"); + verbose(VERB_QUERY, "verify: sldns_key_dsa2pkey failed"); return 0; } #ifdef HAVE_EVP_DSS1 @@ -558,20 +542,9 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) case LDNS_RSASHA512: #endif - *evp_key = EVP_PKEY_new(); + *evp_key = sldns_key_rsa2pkey_raw(key, keylen); if(!*evp_key) { - log_err("verify: malloc failure in crypto"); - return 0; - } - rsa = sldns_key_buf2rsa_raw(key, keylen); - if(!rsa) { - verbose(VERB_QUERY, "verify: " - "sldns_key_buf2rsa_raw SHA failed"); - return 0; - } - if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { - verbose(VERB_QUERY, "verify: " - "EVP_PKEY_assign_RSA SHA failed"); + verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey SHA failed"); return 0; } @@ -595,20 +568,9 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type, #endif /* defined(USE_SHA1) || (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) */ case LDNS_RSAMD5: - *evp_key = EVP_PKEY_new(); + *evp_key = sldns_key_rsa2pkey_raw(key, keylen); if(!*evp_key) { - log_err("verify: malloc failure in crypto"); - return 0; - } - rsa = sldns_key_buf2rsa_raw(key, keylen); - if(!rsa) { - verbose(VERB_QUERY, "verify: " - "sldns_key_buf2rsa_raw MD5 failed"); - return 0; - } - if(EVP_PKEY_assign_RSA(*evp_key, rsa) == 0) { - verbose(VERB_QUERY, "verify: " - "EVP_PKEY_assign_RSA MD5 failed"); + verbose(VERB_QUERY, "verify: sldns_key_rsa2pkey MD5 failed"); return 0; } *digest_type = EVP_md5();