]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Move RSA and DSA to use OpenSSL 3.0.0 API.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 2 Aug 2021 12:43:51 +0000 (14:43 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 2 Aug 2021 12:43:51 +0000 (14:43 +0200)
config.h.in
configure
configure.ac
doc/Changelog
sldns/keyraw.c
sldns/keyraw.h

index 3d45a095351aad7cab9ee41bcdbeeba185ed69c4..8fdf83e7406d108648942939ab3e0b4c11f25df4 100644 (file)
 /* Define to 1 if you have the `OPENSSL_init_ssl' function. */
 #undef HAVE_OPENSSL_INIT_SSL
 
+/* Define to 1 if you have the <openssl/param_build.h> header file. */
+#undef HAVE_OPENSSL_PARAM_BUILD_H
+
 /* Define to 1 if you have the <openssl/rand.h> header file. */
 #undef HAVE_OPENSSL_RAND_H
 
 /* Define to 1 if you have the <openssl/ssl.h> 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
 
index ede92e73250dd5aae80f6fcef8edac5387e0aae3..84c97357f72c3ac5b42cbcc9e7c79d713d6fb1cc 100755 (executable)
--- a/configure
+++ b/configure
@@ -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"
index 933529690d7634fb0e95dc9b3281d3541bbb7bfa..2ec11b970211547987685b0ed028a9e5e7f96202 100644 (file)
@@ -859,8 +859,8 @@ 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"
index 8557baf18dfd0d0a5d7aa01dfbef312319691f1c..686203b8e511c5942655c9e7d90d63f73b7a6efc 100644 (file)
@@ -1,6 +1,7 @@
 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.
 
 30 July 2021: Wouter
        - Fix #515: Compilation against openssl 3.0.0 beta2 is failing to
index 34cf9433266cbc25df63e070910f089cd05542b4..ce94dd74edf6d1ab129f453f03e1985e0ef5338f 100644 (file)
 #ifdef HAVE_OPENSSL_BN_H
 #include <openssl/bn.h>
 #endif
-#ifdef HAVE_OPENSSL_RSA_H
-#include <openssl/rsa.h>
-#endif
-#ifdef HAVE_OPENSSL_DSA_H
-#include <openssl/dsa.h>
+#ifdef HAVE_OPENSSL_PARAM_BUILD_H
+#  include <openssl/param_build.h>
+#else
+#  ifdef HAVE_OPENSSL_RSA_H
+#  include <openssl/rsa.h>
+#  endif
+#  ifdef HAVE_OPENSSL_DSA_H
+#  include <openssl/dsa.h>
+#  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,42 +279,110 @@ sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
 
        return dsa;
 }
+#endif /* HAVE_OSSL_PARAM_BLD_NEW */
 
 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) {
+               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 0;
+               return NULL;
        }
        dsa = sldns_key_buf2dsa_raw(key, len);
        if(!dsa) {
                EVP_PKEY_free(evp_key);
-               return 0;
+               return NULL;
        }
        if(EVP_PKEY_assign_DSA(evp_key, dsa) == 0) {
                DSA_free(dsa);
                EVP_PKEY_free(evp_key);
-               return 0;
+               return NULL;
        }
        return evp_key;
+#endif
 }
 
-RSA *
-sldns_key_buf2rsa_raw(unsigned char* key, size_t len)
+/* 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;
@@ -307,23 +393,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);
@@ -347,25 +444,86 @@ 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) {
+               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 0;
+               return NULL;
        }
        rsa = sldns_key_buf2rsa_raw(key, len);
        if(!rsa) {
                EVP_PKEY_free(evp_key);
-               return 0;
+               return NULL;
        }
        if(EVP_PKEY_assign_RSA(evp_key, rsa) == 0) {
                RSA_free(rsa);
                EVP_PKEY_free(evp_key);
-               return 0;
+               return NULL;
        }
        return evp_key;
+#endif
 }
 
 #ifdef USE_GOST
index 0166129b334277e23dcdf68a1051cead2ad01037..b1f19740cd6c9a37bf763b7d38a00ac5988ec4a9 100644 (file)
@@ -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,7 @@ 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.
@@ -92,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.
@@ -99,6 +102,7 @@ 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.