From 47ad23493a29cd58685af99ddf8e5303754fd23f Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Wed, 27 Nov 2024 14:35:51 -0800 Subject: [PATCH] When compiling with OpenSSL 3, deprecate functions that use deprecated OpenSSL structs and update the implementation to not use those functions --- dnssec.c | 196 ++++++++++ dnssec_sign.c | 65 ++-- dnssec_verify.c | 177 +++++++-- host2str.c | 78 +++- keys.c | 920 +++++++++++++++++++++++++++++++++++++++------ ldns/dnssec.h | 49 +++ ldns/dnssec_sign.h | 8 +- ldns/keys.h | 67 +++- ldns/util.h.in | 1 + util.c | 13 + 10 files changed, 1394 insertions(+), 180 deletions(-) diff --git a/dnssec.c b/dnssec.c index 1339e73c..9b3e1fb7 100644 --- a/dnssec.c +++ b/dnssec.c @@ -28,6 +28,9 @@ #ifdef USE_DSA #include #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif #endif ldns_rr * @@ -334,6 +337,7 @@ uint16_t ldns_calc_keytag_raw(const uint8_t* key, size_t keysize) #ifdef HAVE_SSL #ifdef USE_DSA +#ifndef OPENSSL_NO_DEPRECATED_3_0 DSA * ldns_key_buf2dsa(const ldns_buffer *key) { @@ -409,8 +413,111 @@ ldns_key_buf2dsa_raw(const unsigned char* key, size_t len) #endif /* OPENSSL_VERSION_NUMBER */ return dsa; } +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + +EVP_PKEY * +ldns_dsa2pkey(const ldns_buffer *key) +{ + return ldns_dsa2pkey_raw((const unsigned char*)ldns_buffer_begin(key), + ldns_buffer_position(key)); +} + +EVP_PKEY * +ldns_dsa2pkey_raw(const unsigned char* key, size_t len) +{ + uint8_t T; + uint16_t length; + uint16_t offset; + EVP_PKEY_CTX *ctx; + OSSL_PARAM params[5]; + EVP_PKEY *pkey = NULL; + unsigned char *Q = NULL; + unsigned char *P = NULL; + unsigned char *G = NULL; + unsigned char *Y = NULL; + + if(len == 0) + return NULL; + T = (uint8_t)key[0]; + length = (64 + T * 8); + offset = 1; + + if (T > 8) { + return NULL; + } + if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length) + return NULL; + + Q = OPENSSL_zalloc(SHA_DIGEST_LENGTH); + P = OPENSSL_zalloc(length); + G = OPENSSL_zalloc(length); + Y = OPENSSL_zalloc(length); + + if (!Q || !P || !G || !Y) { + OPENSSL_clear_free(Q, SHA_DIGEST_LENGTH); + OPENSSL_clear_free(P, length); + OPENSSL_clear_free(G, length); + OPENSSL_clear_free(Y, length); + } + + memcpy(Q, key+offset, SHA_DIGEST_LENGTH); + ldns_swap_bytes(Q, SHA_DIGEST_LENGTH); + offset += SHA_DIGEST_LENGTH; + + memcpy(P, key+offset, length); + ldns_swap_bytes(P, length); + offset += length; + + memcpy(G, key+offset, length); + ldns_swap_bytes(G, length); + offset += length; + + memcpy(Y, key+offset, length); + ldns_swap_bytes(Y, length); + + /* Exponent */ + + params[0] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_Q, Q, SHA_DIGEST_LENGTH); + + params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_P, P, length); + + params[2] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_G, G, length); + + params[3] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PUB_KEY, Y, length); + + params[4] = OSSL_PARAM_construct_end(); + + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL); + + if(EVP_PKEY_fromdata_init(ctx) <= 0) { + OPENSSL_clear_free(Q, SHA_DIGEST_LENGTH); + OPENSSL_clear_free(P, length); + OPENSSL_clear_free(G, length); + OPENSSL_clear_free(Y, length); + return NULL; + } + + if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) { + EVP_PKEY_CTX_free(ctx); + OPENSSL_clear_free(Q, SHA_DIGEST_LENGTH); + OPENSSL_clear_free(P, length); + OPENSSL_clear_free(G, length); + OPENSSL_clear_free(Y, length); + return NULL; + } + + EVP_PKEY_CTX_free(ctx); + + return pkey; +} +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ + #endif /* USE_DSA */ +#ifndef OPENSSL_NO_DEPRECATED_3_0 RSA * ldns_key_buf2rsa(const ldns_buffer *key) { @@ -485,6 +592,95 @@ ldns_key_buf2rsa_raw(const unsigned char* key, size_t len) return rsa; } +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +EVP_PKEY * +ldns_rsa2pkey(const ldns_buffer *key) +{ + return ldns_rsa2pkey_raw((const unsigned char*)ldns_buffer_begin(key), + ldns_buffer_position(key)); +} + +EVP_PKEY * +ldns_rsa2pkey_raw(const unsigned char* key, size_t len) +{ + uint16_t offset; + uint16_t exp; + uint16_t int16; + EVP_PKEY_CTX *ctx; + OSSL_PARAM params[3]; + EVP_PKEY *pkey = NULL; + unsigned char *modulus = NULL; + unsigned char *exponent = NULL; + + if (len == 0) + return NULL; + if (key[0] == 0) { + if(len < 3) + return NULL; + /* need some smart comment here XXX*/ + /* the exponent is too large so it's places + * further...???? */ + memmove(&int16, key+1, 2); + exp = ntohs(int16); + offset = 3; + } else { + exp = key[0]; + offset = 1; + } + + /* key length at least one */ + if(len < (size_t)offset + exp + 1) + return NULL; + + /* Exponent */ + exponent = OPENSSL_zalloc(exp); + memcpy(exponent, key+offset, exp); + if (!exponent) { + return NULL; + } + ldns_swap_bytes(exponent, exp); + offset += exp; + + /* Modulus */ + modulus = OPENSSL_zalloc(len - offset); + if(!modulus) { + OPENSSL_clear_free(exponent, exp); + return NULL; + } + /* length of the buffer must match the key length! */ + memcpy(modulus, key+offset, len-offset); + ldns_swap_bytes(modulus, len - offset); + + params[0] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_N, modulus, len - offset); + + params[1] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_E, exponent, exp); + + params[2] = OSSL_PARAM_construct_end(); + + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + + if(EVP_PKEY_fromdata_init(ctx) <= 0) { + OPENSSL_clear_free(modulus, len - offset); + OPENSSL_clear_free(exponent, exp); + return NULL; + } + + if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) { + EVP_PKEY_CTX_free(ctx); + OPENSSL_clear_free(modulus, len - offset); + OPENSSL_clear_free(exponent, exp); + return NULL; + } + + EVP_PKEY_CTX_free(ctx); + + return pkey; +} +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ int ldns_digest_evp(const unsigned char* data, unsigned int len, unsigned char* dest, diff --git a/dnssec_sign.c b/dnssec_sign.c index dba2d1c2..bd6e69c1 100644 --- a/dnssec_sign.c +++ b/dnssec_sign.c @@ -22,6 +22,9 @@ #ifdef USE_DSA #include #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif #endif /* HAVE_SSL */ #define LDNS_SIGN_WITH_ZONEMD ( LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384 \ @@ -328,6 +331,7 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys) return signatures; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 ldns_rdf * ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key) { @@ -400,6 +404,7 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key) return NULL; #endif } +#endif /* # OPENSSL_NO_DEPRECATED_3_0 */ #ifdef USE_ECDSA #ifndef S_SPLINT_S @@ -407,35 +412,45 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key) static int ldns_pkey_is_ecdsa(EVP_PKEY* pkey) { - EC_KEY* ec; - const EC_GROUP* g; +#if OPENSSL_VERSION_NUMBER < 0x30000000L + EC_KEY* ec; + const EC_GROUP* g; +#endif + #ifdef HAVE_EVP_PKEY_GET_BASE_ID - if(EVP_PKEY_get_base_id(pkey) != EVP_PKEY_EC) - return 0; + if(EVP_PKEY_get_base_id(pkey) != EVP_PKEY_EC) + return 0; #elif defined(HAVE_EVP_PKEY_BASE_ID) - if(EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) - return 0; + if(EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) + return 0; #else - if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) - return 0; + if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) + return 0; #endif - ec = EVP_PKEY_get1_EC_KEY(pkey); - g = EC_KEY_get0_group(ec); - if(!g) { - EC_KEY_free(ec); - return 0; - } - if(EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1) { - EC_KEY_free(ec); - return 32; /* 256/8 */ + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int bits = 0; + EVP_PKEY_get_int_param(pkey, OSSL_PKEY_PARAM_BITS, &bits); + return bits / 8; +#else + ec = EVP_PKEY_get1_EC_KEY(pkey); + g = EC_KEY_get0_group(ec); + if(!g) { + EC_KEY_free(ec); + return 0; } - if(EC_GROUP_get_curve_name(g) == NID_secp384r1) { - EC_KEY_free(ec); - return 48; /* 384/8 */ - } - /* downref the eckey, the original is still inside the pkey */ - EC_KEY_free(ec); - return 0; + if(EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1) { + EC_KEY_free(ec); + return 32; /* 256/8 */ + } + if(EC_GROUP_get_curve_name(g) == NID_secp384r1) { + EC_KEY_free(ec); + return 48; /* 384/8 */ + } + /* downref the eckey, the original is still inside the pkey */ + EC_KEY_free(ec); + return 0; +#endif } #endif /* splint */ #endif /* USE_ECDSA */ @@ -569,6 +584,7 @@ ldns_sign_public_evp(ldns_buffer *to_sign, return sigdata_rdf; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 ldns_rdf * ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key) { @@ -636,6 +652,7 @@ ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key) ldns_buffer_free(b64sig); return sigdata_rdf; } +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ #endif /* HAVE_SSL */ /** diff --git a/dnssec_verify.c b/dnssec_verify.c index d76f32eb..6bf43ce6 100644 --- a/dnssec_verify.c +++ b/dnssec_verify.c @@ -15,6 +15,10 @@ #include #include +# if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +# endif + ldns_dnssec_data_chain * ldns_dnssec_data_chain_new(void) { @@ -1947,40 +1951,99 @@ ldns_verify_rrsig_ed448_raw(unsigned char* sig, size_t siglen, EVP_PKEY* ldns_ecdsa2pkey_raw(const unsigned char* key, size_t keylen, uint8_t algo) { + EVP_PKEY *evp_key = NULL; unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ - const unsigned char* pp = buf; - EVP_PKEY *evp_key; - EC_KEY *ec; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + const char *n = NULL; + char *group_name = NULL; + /* check length, which uncompressed must be 2 bignums */ - if(algo == LDNS_ECDSAP256SHA256) { + if(algo == LDNS_ECDSAP256SHA256) { if(keylen != 2*256/8) return NULL; - ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - } else if(algo == LDNS_ECDSAP384SHA384) { + n = EC_curve_nid2nist(NID_X9_62_prime256v1); + } else if(algo == LDNS_ECDSAP384SHA384) { if(keylen != 2*384/8) return NULL; - ec = EC_KEY_new_by_curve_name(NID_secp384r1); - } else ec = NULL; - if(!ec) return NULL; + n = EC_curve_nid2nist(NID_secp384r1); + } else { + return NULL; + } + + if(n) { + group_name = OPENSSL_zalloc(strlen(n) + 1); + } else { + return NULL; + } + + if(group_name) { + int ret = 0; + OSSL_PARAM params[3] = { 0 }; + + memcpy(group_name, n, strlen(n)); + + /* prepend the 0x02 (from docs) (or actually 0x04 from implementation + * of openssl) for uncompressed data */ + buf[0] = POINT_CONVERSION_UNCOMPRESSED; + memmove(buf+1, key, keylen); + + params[0] = + OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + group_name, 0); + + params[1] = + OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, + buf, keylen); + + params[2] = OSSL_PARAM_construct_end(); + + if(EVP_PKEY_fromdata_init(ctx) > 0) { + ret = EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, + params); + } + + if(group_name) { + OPENSSL_clear_free(group_name, strlen(n)); + } + + if(ret <= 0) { + return NULL; + } + } +#else + const unsigned char* pp = buf; + EC_KEY *ec; + /* check length, which uncompressed must be 2 bignums */ + if(algo == LDNS_ECDSAP256SHA256) { + if(keylen != 2*256/8) return NULL; + ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + } else if(algo == LDNS_ECDSAP384SHA384) { + if(keylen != 2*384/8) return NULL; + ec = EC_KEY_new_by_curve_name(NID_secp384r1); + } else ec = NULL; + if(!ec) return NULL; if(keylen+1 > sizeof(buf)) return NULL; /* sanity check */ /* prepend the 0x02 (from docs) (or actually 0x04 from implementation * of openssl) for uncompressed data */ buf[0] = POINT_CONVERSION_UNCOMPRESSED; memmove(buf+1, key, keylen); - if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) { - EC_KEY_free(ec); - return NULL; - } - evp_key = EVP_PKEY_new(); - if(!evp_key) { - EC_KEY_free(ec); - return NULL; - } - if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) { + if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) { + EC_KEY_free(ec); + return NULL; + } + evp_key = EVP_PKEY_new(); + if(!evp_key) { + EC_KEY_free(ec); + return NULL; + } + if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) { EVP_PKEY_free(evp_key); EC_KEY_free(ec); return NULL; } - return evp_key; +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ + return evp_key; } static ldns_status @@ -2684,10 +2747,20 @@ ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen, { #ifdef USE_DSA EVP_PKEY *evp_key; - ldns_status result; + ldns_status result = LDNS_STATUS_OK; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + evp_key = ldns_dsa2pkey_raw(key, keylen); + if (!evp_key) { + result = LDNS_STATUS_SSL_ERR; + } +#else evp_key = EVP_PKEY_new(); - if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) { + if (!EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) { + result = LDNS_STATUS_SSL_ERR; + } +#endif + if (result == LDNS_STATUS_OK) { result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, @@ -2698,8 +2771,6 @@ ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen, EVP_sha1() # endif ); - } else { - result = LDNS_STATUS_SSL_ERR; } EVP_PKEY_free(evp_key); return result; @@ -2714,17 +2785,25 @@ ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen, ldns_buffer* rrset, unsigned char* key, size_t keylen) { EVP_PKEY *evp_key; - ldns_status result; + ldns_status result = LDNS_STATUS_OK; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + evp_key = ldns_rsa2pkey_raw(key, keylen); + if (!evp_key) { + result = LDNS_STATUS_SSL_ERR; + } +#else evp_key = EVP_PKEY_new(); - if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { + if (!EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { + result = LDNS_STATUS_SSL_ERR; + } +#endif + if (result == LDNS_STATUS_OK) { result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, EVP_sha1()); - } else { - result = LDNS_STATUS_SSL_ERR; } EVP_PKEY_free(evp_key); @@ -2740,10 +2819,20 @@ ldns_verify_rrsig_rsasha256_raw(unsigned char* sig, { #ifdef USE_SHA2 EVP_PKEY *evp_key; - ldns_status result; + ldns_status result = LDNS_STATUS_OK; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + evp_key = ldns_rsa2pkey_raw(key, keylen); + if (!evp_key) { + result = LDNS_STATUS_SSL_ERR; + } +#else evp_key = EVP_PKEY_new(); - if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { + if (!EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { + result = LDNS_STATUS_SSL_ERR; + } +#endif + if (result == LDNS_STATUS_OK) { result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, @@ -2775,10 +2864,20 @@ ldns_verify_rrsig_rsasha512_raw(unsigned char* sig, { #ifdef USE_SHA2 EVP_PKEY *evp_key; - ldns_status result; + ldns_status result = LDNS_STATUS_OK; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + evp_key = ldns_rsa2pkey_raw(key, keylen); + if (!evp_key) { + result = LDNS_STATUS_SSL_ERR; + } +#else evp_key = EVP_PKEY_new(); - if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { + if (!EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { + result = LDNS_STATUS_SSL_ERR; + } +#endif + if (result == LDNS_STATUS_OK) { result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, @@ -2810,10 +2909,20 @@ ldns_verify_rrsig_rsamd5_raw(unsigned char* sig, size_t keylen) { EVP_PKEY *evp_key; - ldns_status result; + ldns_status result = LDNS_STATUS_OK; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + evp_key = ldns_rsa2pkey_raw(key, keylen); + if (!evp_key) { + result = LDNS_STATUS_SSL_ERR; + } +#else evp_key = EVP_PKEY_new(); - if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { + if (!EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) { + result = LDNS_STATUS_SSL_ERR; + } +#endif + if (result == LDNS_STATUS_OK) { result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, diff --git a/host2str.c b/host2str.c index deeeaf63..3240d9d1 100644 --- a/host2str.c +++ b/host2str.c @@ -34,6 +34,9 @@ #ifdef USE_DSA #include #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif #endif #ifndef INET_ADDRSTRLEN @@ -2963,10 +2966,14 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k) ldns_status status = LDNS_STATUS_OK; unsigned char *bignum; #ifdef HAVE_SSL +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY *pkey = NULL; +#else RSA *rsa; #ifdef USE_DSA DSA *dsa; #endif /* USE_DSA */ +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ #endif /* HAVE_SSL */ if (!k) { @@ -2988,7 +2995,11 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k) case LDNS_SIGN_RSAMD5: /* copied by looking at dnssec-keygen output */ /* header */ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + pkey = ldns_key_evp_key(k); +#else rsa = ldns_key_rsa_key(k); +#endif ldns_buffer_printf(output,"Private-key-format: v1.2\n"); switch(ldns_key_algorithm(k)) { @@ -3037,10 +3048,25 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k) #ifndef S_SPLINT_S if(1) { - const BIGNUM *n=NULL, *e=NULL, *d=NULL, + BIGNUM *n=NULL, *e=NULL, *d=NULL, *p=NULL, *q=NULL, *dmp1=NULL, *dmq1=NULL, *iqmp=NULL; -#if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000) +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &e); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &n); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_D, &d); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, + &p); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, + &q); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, + &dmp1); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, + &dmq1); + EVP_PKEY_get_bn_param(pkey, + OSSL_PKEY_PARAM_RSA_COEFFICIENT1, + &iqmp); +#elif OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000) n = rsa->n; e = rsa->e; d = rsa->d; @@ -3074,12 +3100,18 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k) } #endif /* splint */ +#if OPENSSL_VERSION_NUMBER < 0x30000000L RSA_free(rsa); +#endif break; #ifdef USE_DSA case LDNS_SIGN_DSA: case LDNS_SIGN_DSA_NSEC3: +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + pkey = ldns_key_evp_key(k); +#else dsa = ldns_key_dsa_key(k); +#endif ldns_buffer_printf(output,"Private-key-format: v1.2\n"); if (ldns_key_algorithm(k) == LDNS_SIGN_DSA) { @@ -3091,9 +3123,17 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k) /* print to buf, convert to bin, convert to b64, * print to buf */ if(1) { - const BIGNUM *p=NULL, *q=NULL, *g=NULL, + BIGNUM *p=NULL, *q=NULL, *g=NULL, *priv_key=NULL, *pub_key=NULL; -#if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000) +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_P, &p); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_Q, &q); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_FFC_G, &g); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, + &priv_key); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, + &pub_key); +#elif OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000) #ifndef S_SPLINT_S p = dsa->p; q = dsa->q; @@ -3117,6 +3157,10 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k) goto error; } break; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + DSA_free(dsa); +#endif #endif /* USE_DSA */ case LDNS_SIGN_ECC_GOST: /* no format defined, use blob */ @@ -3137,20 +3181,28 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k) case LDNS_SIGN_ECDSAP256SHA256: case LDNS_SIGN_ECDSAP384SHA384: #ifdef USE_ECDSA - ldns_buffer_printf(output, "Private-key-format: v1.2\n"); + ldns_buffer_printf(output, "Private-key-format: v1.2\n"); ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k)); - status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k)); + status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k)); #ifndef S_SPLINT_S ldns_buffer_printf(output, ")\n"); - if(k->_key.key) { - EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key); - const BIGNUM* b = EC_KEY_get0_private_key(ec); + if(k->_key.key) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + BIGNUM *b = NULL; + EVP_PKEY_get_bn_param(k->_key.key, + OSSL_PKEY_PARAM_PRIV_KEY, &b); +#else + EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key); + const BIGNUM* b = EC_KEY_get0_private_key(ec); +#endif if(!ldns_print_bignum_b64_line(output, "PrivateKey", b)) goto error; - /* down reference count in EC_KEY - * its still assigned to the PKEY */ - EC_KEY_free(ec); - } +#if OPENSSL_VERSION_NUMBER < 0x30000000L + /* down reference count in EC_KEY + * its still assigned to the PKEY */ + EC_KEY_free(ec); +#endif + } #endif /* splint */ #else goto error; diff --git a/keys.c b/keys.c index 8125de3f..ea5b73f0 100644 --- a/keys.c +++ b/keys.c @@ -30,6 +30,9 @@ # define OPENSSL_NO_ENGINE # endif #endif +# if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +# endif #endif /* HAVE_SSL */ ldns_lookup_table ldns_signing_algorithms[] = { @@ -228,6 +231,7 @@ ldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr) #ifdef USE_ECDSA /** calculate public key from private key */ +#if OPENSSL_VERSION_NUMBER < 0x30000000L static int ldns_EC_KEY_calc_public(EC_KEY* ec) { @@ -252,59 +256,114 @@ ldns_EC_KEY_calc_public(EC_KEY* ec) EC_POINT_free(pub_key); return 1; } +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ +#endif /* USE_ECDSA */ /** read ECDSA private key */ static EVP_PKEY* ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr) { - char token[16384]; - ldns_rdf* b64rdf = NULL; - unsigned char* pp; - BIGNUM* bn; - EVP_PKEY* evp_key; - EC_KEY* ec; - if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", - sizeof(token), line_nr) == -1) - return NULL; - if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) - return NULL; - pp = (unsigned char*)ldns_rdf_data(b64rdf); - - if(alg == LDNS_ECDSAP256SHA256) - ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - else if(alg == LDNS_ECDSAP384SHA384) - ec = EC_KEY_new_by_curve_name(NID_secp384r1); - else ec = NULL; - if(!ec) { - ldns_rdf_deep_free(b64rdf); - return NULL; - } - bn = BN_bin2bn(pp, (int)ldns_rdf_size(b64rdf), NULL); - ldns_rdf_deep_free(b64rdf); - if(!bn) { - EC_KEY_free(ec); - return NULL; + char token[16384]; + ldns_rdf* b64rdf = NULL; + unsigned char* pp; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY* evp_key = NULL; + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + const char *n = NULL; + char *group_name = NULL; +#else + BIGNUM* bn; + EC_KEY* ec; +#endif + + if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", + sizeof(token), line_nr) == -1) + return NULL; + if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) + return NULL; + pp = (unsigned char*)ldns_rdf_data(b64rdf); + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if(alg == LDNS_ECDSAP256SHA256) { + n = EC_curve_nid2nist(NID_X9_62_prime256v1); + } else if(alg == LDNS_ECDSAP384SHA384) { + n = EC_curve_nid2nist(NID_secp384r1); + } + + if(n) { + group_name = OPENSSL_zalloc(strlen(n) + 1); + } else { + ldns_rdf_deep_free(b64rdf); + return NULL; + } + + if(group_name) { + int ret = 0; + OSSL_PARAM params[3] = { 0 }; + + memcpy(group_name, n, strlen(n)); + + params[0] = + OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + group_name, 0); + + params[1] = + OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, + pp, ldns_rdf_size(b64rdf)); + + params[2] = OSSL_PARAM_construct_end(); + + if(EVP_PKEY_fromdata_init(ctx) > 0) { + ret = EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, + params); } - EC_KEY_set_private_key(ec, bn); - BN_free(bn); - if(!ldns_EC_KEY_calc_public(ec)) { - EC_KEY_free(ec); - return NULL; + + if(group_name) { + OPENSSL_clear_free(group_name, strlen(n)); } - evp_key = EVP_PKEY_new(); - if(!evp_key) { - EC_KEY_free(ec); - return NULL; + if(ret <= 0) { + ldns_rdf_deep_free(b64rdf); + return NULL; } - if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) { - EVP_PKEY_free(evp_key); - EC_KEY_free(ec); - return NULL; - } - return evp_key; + } +#else + if(alg == LDNS_ECDSAP256SHA256) + ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + else if(alg == LDNS_ECDSAP384SHA384) + ec = EC_KEY_new_by_curve_name(NID_secp384r1); + else ec = NULL; + if(!ec) { + ldns_rdf_deep_free(b64rdf); + return NULL; + } + bn = BN_bin2bn(pp, (int)ldns_rdf_size(b64rdf), NULL); + ldns_rdf_deep_free(b64rdf); + if(!bn) { + EC_KEY_free(ec); + return NULL; + } + EC_KEY_set_private_key(ec, bn); + BN_free(bn); + if(!ldns_EC_KEY_calc_public(ec)) { + EC_KEY_free(ec); + return NULL; + } + + evp_key = EVP_PKEY_new(); + if(!evp_key) { + EC_KEY_free(ec); + return NULL; + } + if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) { + EVP_PKEY_free(evp_key); + EC_KEY_free(ec); + return NULL; + } +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ + return evp_key; } -#endif #ifdef USE_ED25519 /** turn private key buffer into EC_KEY structure */ @@ -421,10 +480,14 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr) ldns_signing_algorithm alg; ldns_rr *key_rr; #ifdef HAVE_SSL +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY *pkey; +#else RSA *rsa; #ifdef USE_DSA DSA *dsa; #endif +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ unsigned char *hmac; size_t hmac_size; #endif /* HAVE_SSL */ @@ -614,12 +677,21 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr) #endif ldns_key_set_algorithm(k, alg); #ifdef HAVE_SSL +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + pkey = ldns_pkey_new_frm_fp_rsa_l(fp, line_nr); + if (!pkey) { + ldns_key_free(k); + return LDNS_STATUS_ERR; + } + ldns_key_set_evp_key(k, pkey); +#else rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr); if (!rsa) { ldns_key_free(k); return LDNS_STATUS_ERR; } ldns_key_assign_rsa_key(k, rsa); +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ #endif /* HAVE_SSL */ break; #ifdef USE_DSA @@ -627,12 +699,21 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr) case LDNS_SIGN_DSA_NSEC3: ldns_key_set_algorithm(k, alg); #ifdef HAVE_SSL +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + pkey = ldns_pkey_new_frm_fp_dsa_l(fp, line_nr); + if (!pkey) { + ldns_key_free(k); + return LDNS_STATUS_ERR; + } + ldns_key_set_evp_key(k, pkey); +#else dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr); if (!dsa) { ldns_key_free(k); return LDNS_STATUS_ERR; } ldns_key_assign_dsa_key(k, dsa); +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ #endif /* HAVE_SSL */ break; #endif /* USE_DSA */ @@ -727,12 +808,271 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr) } #ifdef HAVE_SSL +# if OPENSSL_VERSION_NUMBER >= 0x30000000L +EVP_PKEY * +ldns_pkey_new_frm_fp_rsa(FILE *f) +{ + return ldns_pkey_new_frm_fp_rsa_l(f, NULL); +} +# endif + +#ifndef OPENSSL_NO_DEPRECATED_3_0 RSA * ldns_key_new_frm_fp_rsa(FILE *f) { return ldns_key_new_frm_fp_rsa_l(f, NULL); } +#endif + +# if OPENSSL_VERSION_NUMBER >= 0x30000000L +EVP_PKEY * +ldns_pkey_new_frm_fp_rsa_l(FILE *f, int *line_nr) +{ + /* we parse + * Modulus: + * PublicExponent: + * PrivateExponent: + * Prime1: + * Prime2: + * Exponent1: + * Exponent2: + * Coefficient: + * + * man 3 RSA: + * + * struct + * { + * BIGNUM *n; // public modulus + * BIGNUM *e; // public exponent + * BIGNUM *d; // private exponent + * BIGNUM *p; // secret prime factor + * BIGNUM *q; // secret prime factor + * BIGNUM *dmp1; // d mod (p-1) + * BIGNUM *dmq1; // d mod (q-1) + * BIGNUM *iqmp; // q^-1 mod p + * // ... + * + */ + char *b; + int num_params = 0; + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM params[9]; + EVP_PKEY *pkey = NULL; + uint8_t *buf; + size_t n_len=0, e_len=0, d_len=0, p_len=0, q_len=0, + dmp1_len=0, dmq1_len=0, iqmp_len=0; + unsigned char *n=NULL, *e=NULL, *d=NULL, *p=NULL, *q=NULL, + *dmp1=NULL, *dmq1=NULL, *iqmp=NULL; + + b = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); + buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); + if (!b || !buf) { + goto error; + } + + /* I could use functions again, but that seems an overkill, + * although this also looks tedious + */ + + /* Modules, rsa->n */ + if (ldns_fget_keyword_data_l(f, "Modulus", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + n_len = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); +#ifndef S_SPLINT_S + n = OPENSSL_zalloc(n_len); + if (!n) { + goto error; + } + memcpy(n, buf, n_len); + ldns_swap_bytes(n, n_len); + + /* PublicExponent, rsa->e */ + if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + e_len = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + if (!e) { + goto error; + } + e = OPENSSL_zalloc(e_len); + if (!e) { + goto error; + } + memcpy(e, buf, e_len); + ldns_swap_bytes(e, e_len); + + /* PrivateExponent, rsa->d */ + if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + d_len = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + if (!d) { + goto error; + } + d = OPENSSL_zalloc(d_len); + if (!d) { + goto error; + } + memcpy(d, buf, d_len); + ldns_swap_bytes(d, d_len); + + /* Prime1, rsa->p */ + if (ldns_fget_keyword_data_l(f, "Prime1", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + p_len = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + if (!p) { + goto error; + } + p = OPENSSL_zalloc(p_len); + if (!p) { + goto error; + } + memcpy(p, buf, p_len); + ldns_swap_bytes(p, p_len); + + /* Prime2, rsa->q */ + if (ldns_fget_keyword_data_l(f, "Prime2", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + q_len = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + if (!q) { + goto error; + } + q = OPENSSL_zalloc(q_len); + if (!q) { + goto error; + } + memcpy(q, buf, q_len); + ldns_swap_bytes(q, q_len); + + /* Exponent1, rsa->dmp1 */ + if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + dmp1_len = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + if (!dmp1) { + goto error; + } + dmp1 = OPENSSL_zalloc(dmp1_len); + if (!dmp1) { + goto error; + } + memcpy(dmp1, buf, dmp1_len); + ldns_swap_bytes(dmp1, dmp1_len); + + /* Exponent2, rsa->dmq1 */ + if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + dmq1_len = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + if (!dmq1) { + goto error; + } + dmq1 = OPENSSL_zalloc(dmq1_len); + if (!dmq1) { + goto error; + } + memcpy(dmq1, buf, dmq1_len); + ldns_swap_bytes(dmq1, dmq1_len); + + /* Coefficient, rsa->iqmp */ + if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + iqmp_len = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + if (!iqmp) { + goto error; + } + iqmp = OPENSSL_zalloc(iqmp_len); + if (!iqmp) { + goto error; + } + memcpy(iqmp, buf, iqmp_len); + ldns_swap_bytes(iqmp, iqmp_len); +#endif /* splint */ + + if (n) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_N, n, n_len); + } + + if (e) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_E, e, e_len); + } + + if (d) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_D, d, d_len); + } + + if (p) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_FACTOR1, p, p_len); + } + + if (q) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_FACTOR2, q, q_len); + } + + if (dmp1) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1, + dmp1_len); + } + + if (dmq1) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_EXPONENT1, dmq1, + dmq1_len); + } + + if (iqmp) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp, + iqmp_len); + } + + params[num_params++] = OSSL_PARAM_construct_end(); + + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + + if(EVP_PKEY_fromdata_init(ctx) <= 0) { + goto error; + } + + if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) { + goto error; + } + EVP_PKEY_CTX_free(ctx); + + LDNS_FREE(buf); + LDNS_FREE(b); + EVP_PKEY_CTX_free(ctx); + return pkey; + +error: + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + LDNS_FREE(b); + LDNS_FREE(buf); + OPENSSL_clear_free(n, n_len); + OPENSSL_clear_free(e, e_len); + OPENSSL_clear_free(d, d_len); + OPENSSL_clear_free(p, p_len); + OPENSSL_clear_free(q, q_len); + OPENSSL_clear_free(dmp1, dmp1_len); + OPENSSL_clear_free(dmq1, dmq1_len); + OPENSSL_clear_free(iqmp, iqmp_len); + return NULL; +} +#endif + +#ifndef OPENSSL_NO_DEPRECATED_3_0 RSA * ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr) { @@ -904,8 +1244,152 @@ ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr) BN_free(iqmp); return NULL; } +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ #ifdef USE_DSA +# if OPENSSL_VERSION_NUMBER >= 0x30000000L +EVP_PKEY * +ldns_pkey_new_frm_fp_dsa(FILE *f) +{ + return ldns_pkey_new_frm_fp_dsa_l(f, NULL); +} + +EVP_PKEY * +ldns_pkey_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) +{ + char *d; + int num_params = 0; + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM params[9]; + EVP_PKEY *pkey = NULL; + uint8_t *buf; + size_t p_len=0, q_len=0, g_len=0, priv_key_len=0, pub_key_len=0; + unsigned char *p=NULL, *q=NULL, *g=NULL, *priv_key=NULL, *pub_key=NULL; + + d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); + buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); + if (!d || !buf) { + goto error; + } + + /* the line parser removes the () from the input... */ + + /* Prime, dsa->p */ + if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + p_len = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); +#ifndef S_SPLINT_S + p = OPENSSL_zalloc(p_len); + if (!p) { + goto error; + } + memcpy(p, buf, p_len); + + /* Subprime, dsa->q */ + if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + q_len = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); + q = OPENSSL_zalloc(p_len); + if (!q) { + goto error; + } + memcpy(q, buf, q_len); + + /* Base, dsa->g */ + if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + g_len = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); + g = OPENSSL_zalloc(g_len); + if (!g) { + goto error; + } + memcpy(g, buf, g_len); + + /* Private key, dsa->priv_key */ + if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + priv_key_len = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); + priv_key = OPENSSL_zalloc(g_len); + if (!priv_key) { + goto error; + } + memcpy(priv_key, buf, priv_key_len); + + /* Public key, dsa->priv_key */ + if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + goto error; + } + pub_key_len = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); + pub_key = OPENSSL_zalloc(g_len); + if (!pub_key) { + goto error; + } + memcpy(pub_key, buf, pub_key_len); +#endif /* splint */ + + if (p) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_P, p, p_len); + } + + if (q) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_Q, q, q_len); + } + + if (g) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_G, g, g_len); + } + + if (priv_key) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PRIV_KEY, priv_key, + priv_key_len); + } + + if (pub_key) { + params[num_params++] = + OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PUB_KEY, pub_key, + pub_key_len); + } + + params[num_params++] = OSSL_PARAM_construct_end(); + + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL); + + if(EVP_PKEY_fromdata_init(ctx) <= 0) { + goto error; + } + + if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) { + goto error; + } + + EVP_PKEY_CTX_free(ctx); + + LDNS_FREE(buf); + LDNS_FREE(d); + + return pkey; + +error: + LDNS_FREE(d); + LDNS_FREE(buf); + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + OPENSSL_clear_free(p, p_len); + OPENSSL_clear_free(q, q_len); + OPENSSL_clear_free(g, g_len); + OPENSSL_clear_free(priv_key, priv_key_len); + OPENSSL_clear_free(pub_key, pub_key_len); + return NULL; +} +#else DSA * ldns_key_new_frm_fp_dsa(FILE *f) { @@ -1016,6 +1500,7 @@ ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) BN_free(pub_key); return NULL; } +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ #endif /* USE_DSA */ unsigned char * @@ -1084,17 +1569,21 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) { ldns_key *k; #ifdef HAVE_SSL -#ifdef USE_DSA +# if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_CTX *ctx = NULL; +# else +# ifdef USE_DSA DSA *d; -#endif /* USE_DSA */ +# endif /* USE_DSA */ # ifdef USE_ECDSA - EC_KEY *ec = NULL; + EC_KEY *ec = NULL; # endif # ifdef HAVE_EVP_PKEY_KEYGEN EVP_PKEY_CTX *ctx; # else RSA *r; # endif +# endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ #else int i; uint16_t offset = 0; @@ -1138,7 +1627,7 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) EVP_PKEY_CTX_free(ctx); #else /* HAVE_EVP_PKEY_KEYGEN */ r = RSA_generate_key((int)size, RSA_F4, NULL, NULL); - if(!r) { + if(!r) { ldns_key_free(k); return NULL; } @@ -1155,14 +1644,39 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) case LDNS_SIGN_DSA: case LDNS_SIGN_DSA_NSEC3: #ifdef HAVE_SSL -# if OPENSSL_VERSION_NUMBER < 0x00908000L +# if OPENSSL_VERSION_NUMBER >= 0x30000000L + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL); + if(!ctx) { + ldns_key_free(k); + return NULL; + } + if(EVP_PKEY_keygen_init(ctx) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; + } + if (EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, size) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; + } +#ifndef S_SPLINT_S + if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; + } +#endif + EVP_PKEY_CTX_free(ctx); +#else +#if OPENSSL_VERSION_NUMBER < 0x00908000L d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL); if (!d) { ldns_key_free(k); return NULL; } -# else +#else if (! (d = DSA_new())) { ldns_key_free(k); return NULL; @@ -1172,13 +1686,14 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) ldns_key_free(k); return NULL; } -# endif +# endif if (DSA_generate_key(d) != 1) { ldns_key_free(k); return NULL; } ldns_key_set_dsa_key(k, d); DSA_free(d); +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ #endif /* HAVE_SSL */ #endif /* USE_DSA */ break; @@ -1197,10 +1712,10 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) ldns_key_set_hmac_size(k, size); hmac = LDNS_XMALLOC(unsigned char, size); - if(!hmac) { + if(!hmac) { ldns_key_free(k); return NULL; - } + } #ifdef HAVE_SSL if (RAND_bytes(hmac, (int) size) != 1) { LDNS_FREE(hmac); @@ -1209,13 +1724,13 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) } #else while (offset + sizeof(i) < size) { - i = random(); - memcpy(&hmac[offset], &i, sizeof(i)); - offset += sizeof(i); + i = random(); + memcpy(&hmac[offset], &i, sizeof(i)); + offset += sizeof(i); } if (offset < size) { - i = random(); - memcpy(&hmac[offset], &i, size - offset); + i = random(); + memcpy(&hmac[offset], &i, size - offset); } #endif /* HAVE_SSL */ ldns_key_set_hmac_key(k, hmac); @@ -1226,45 +1741,79 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) #if defined(HAVE_SSL) && defined(USE_GOST) ldns_key_set_evp_key(k, ldns_gen_gost_key()); #ifndef S_SPLINT_S - if(!k->_key.key) { - ldns_key_free(k); - return NULL; - } + if(!k->_key.key) { + ldns_key_free(k); + return NULL; + } #endif /* splint */ #else ldns_key_free(k); return NULL; #endif /* HAVE_SSL and USE_GOST */ - break; - case LDNS_SIGN_ECDSAP256SHA256: - case LDNS_SIGN_ECDSAP384SHA384: + break; + case LDNS_SIGN_ECDSAP256SHA256: + case LDNS_SIGN_ECDSAP384SHA384: #ifdef USE_ECDSA - if(alg == LDNS_SIGN_ECDSAP256SHA256) - ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - else if(alg == LDNS_SIGN_ECDSAP384SHA384) - ec = EC_KEY_new_by_curve_name(NID_secp384r1); - if(!ec) { - ldns_key_free(k); - return NULL; - } - if(!EC_KEY_generate_key(ec)) { - ldns_key_free(k); - EC_KEY_free(ec); - return NULL; - } +# if OPENSSL_VERSION_NUMBER >= 0x30000000L + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + if(!ctx) { + ldns_key_free(k); + return NULL; + } + if(EVP_PKEY_keygen_init(ctx) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; + } + if(alg == LDNS_SIGN_ECDSAP256SHA256) { + if(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, NID_X9_62_prime256v1) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; + } + } else if(alg == LDNS_SIGN_ECDSAP384SHA384) { + if(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, NID_secp384r1) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; + } + } #ifndef S_SPLINT_S - k->_key.key = EVP_PKEY_new(); - if(!k->_key.key) { - ldns_key_free(k); - EC_KEY_free(ec); - return NULL; - } - if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) { - ldns_key_free(k); - EC_KEY_free(ec); - return NULL; + if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; } -#endif /* splint */ +#endif + EVP_PKEY_CTX_free(ctx); +# else + if(alg == LDNS_SIGN_ECDSAP256SHA256) + ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + else if(alg == LDNS_SIGN_ECDSAP384SHA384) + ec = EC_KEY_new_by_curve_name(NID_secp384r1); + if(!ec) { + ldns_key_free(k); + return NULL; + } + if(!EC_KEY_generate_key(ec)) { + ldns_key_free(k); + EC_KEY_free(ec); + return NULL; + } +# ifndef S_SPLINT_S + k->_key.key = EVP_PKEY_new(); + if(!k->_key.key) { + ldns_key_free(k); + EC_KEY_free(ec); + return NULL; + } + if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) { + ldns_key_free(k); + EC_KEY_free(ec); + return NULL; + } +# endif /* splint */ +# endif /* if OPENSSL_VERSION_NUMBER >= 0x30000000L */ #else ldns_key_free(k); return NULL; @@ -1352,6 +1901,7 @@ ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e) k->_key.key = e; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 void ldns_key_set_rsa_key(ldns_key *k, RSA *r) { @@ -1391,6 +1941,7 @@ ldns_key_assign_dsa_key(ldns_key *k, DSA *d) (void)k; (void)d; #endif } +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ #endif /* splint */ #endif /* HAVE_SSL */ @@ -1490,6 +2041,7 @@ ldns_key_evp_key(const ldns_key *k) return k->_key.key; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 RSA * ldns_key_rsa_key(const ldns_key *k) { @@ -1514,6 +2066,7 @@ ldns_key_dsa_key(const ldns_key *k) return NULL; #endif } +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ #endif /* splint */ #endif /* HAVE_SSL */ @@ -1650,6 +2203,7 @@ ldns_key_list_pop_key(ldns_key_list *key_list) #ifdef HAVE_SSL #ifndef S_SPLINT_S +#ifndef OPENSSL_NO_DEPRECATED_3_0 /* data pointer must be large enough (LDNS_MAX_KEYLEN) */ static bool ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size) @@ -1736,6 +2290,87 @@ ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size) return true; } #endif /* USE_DSA */ +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +/* data pointer must be large enough (LDNS_MAX_KEYLEN) */ +static bool +ldns_key_rsa2bin(unsigned char *data, EVP_PKEY *k, uint16_t *size) +{ + int i,j; + BIGNUM *n=NULL, *e=NULL; + + if (!k) { + return false; + } + + EVP_PKEY_get_bn_param(k, OSSL_PKEY_PARAM_RSA_E, &e); + EVP_PKEY_get_bn_param(k, OSSL_PKEY_PARAM_RSA_N, &n); + + if (BN_num_bytes(e) <= 256) { + /* normally only this path is executed (small factors are + * more common + */ + data[0] = (unsigned char) BN_num_bytes(e); + i = BN_bn2bin(e, data + 1); + j = BN_bn2bin(n, data + i + 1); + *size = (uint16_t) i + j; + } else if (BN_num_bytes(e) <= 65536) { + data[0] = 0; + /* BN_bn2bin does bigendian, _uint16 also */ + ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(e)); + + BN_bn2bin(e, data + 3); + BN_bn2bin(n, data + 4 + BN_num_bytes(e)); + *size = (uint16_t) BN_num_bytes(n) + 6; + } else { + return false; + } + return true; +} + +#ifdef USE_DSA +/* data pointer must be large enough (LDNS_MAX_KEYLEN) */ +static bool +ldns_key_dsa2bin(unsigned char *data, EVP_PKEY *k, uint16_t *size) +{ + uint8_t T; + BIGNUM *p, *q, *g; + BIGNUM *pub_key; + + if (!k) { + return false; + } + + /* See RFC2536 */ + EVP_PKEY_get_bn_param(k, OSSL_PKEY_PARAM_FFC_P, &p); + EVP_PKEY_get_bn_param(k, OSSL_PKEY_PARAM_FFC_Q, &q); + EVP_PKEY_get_bn_param(k, OSSL_PKEY_PARAM_FFC_G, &g); + EVP_PKEY_get_bn_param(k, OSSL_PKEY_PARAM_PUB_KEY, &pub_key); + + *size = (uint16_t)BN_num_bytes(p); + T = (*size - 64) / 8; + + if (T > 8) { +#ifdef STDERR_MSGS + fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)"); + fprintf(stderr, " not implemented\n"); +#endif + return false; + } + + /* size = 64 + (T * 8); */ + memset(data, 0, 21 + *size * 3); + data[0] = (unsigned char)T; + BN_bn2bin(q, data + 1 ); /* 20 octects */ + BN_bn2bin(p, data + 21 ); /* offset octects */ + BN_bn2bin(g, data + 21 + *size * 2 - BN_num_bytes(g)); + BN_bn2bin(pub_key,data + 21 + *size * 3 - BN_num_bytes(pub_key)); + *size = 21 + *size * 3; + return true; +} +#endif /* USE_DSA */ +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ #ifdef USE_GOST static bool @@ -1812,14 +2447,18 @@ ldns_key2rr(const ldns_key *k) unsigned char *bin = NULL; uint16_t size = 0; #ifdef HAVE_SSL +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY *pkey = NULL; +#else RSA *rsa = NULL; #ifdef USE_DSA DSA *dsa = NULL; #endif /* USE_DSA */ -#endif /* HAVE_SSL */ #ifdef USE_ECDSA - EC_KEY* ec; + EC_KEY* ec; #endif +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ +#endif /* HAVE_SSL */ int internal_data = 0; if (!k) { @@ -1862,6 +2501,22 @@ ldns_key2rr(const ldns_key *k) ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); #ifdef HAVE_SSL +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + pkey = ldns_key_evp_key(k); + if (pkey) { + bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); + if (!bin) { + ldns_rr_free(pubkey); + return NULL; + } + if (!ldns_key_rsa2bin(bin, pkey, &size)) { + LDNS_FREE(bin); + ldns_rr_free(pubkey); + return NULL; + } + internal_data = 1; + } +#else rsa = ldns_key_rsa_key(k); if (rsa) { bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); @@ -1877,7 +2532,8 @@ ldns_key2rr(const ldns_key *k) RSA_free(rsa); internal_data = 1; } -#endif +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ +#endif /* HAVE_SSL */ size++; break; #ifdef USE_DSA @@ -1885,6 +2541,22 @@ ldns_key2rr(const ldns_key *k) ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA)); #ifdef HAVE_SSL +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + pkey = ldns_key_evp_key(k); + if (pkey) { + bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); + if (!bin) { + ldns_rr_free(pubkey); + return NULL; + } + if (!ldns_key_dsa2bin(bin, pkey, &size)) { + LDNS_FREE(bin); + ldns_rr_free(pubkey); + return NULL; + } + internal_data = 1; + } +#else dsa = ldns_key_dsa_key(k); if (dsa) { bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); @@ -1900,6 +2572,7 @@ ldns_key2rr(const ldns_key *k) DSA_free(dsa); internal_data = 1; } +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ #endif /* HAVE_SSL */ #endif /* USE_DSA */ break; @@ -1908,6 +2581,22 @@ ldns_key2rr(const ldns_key *k) ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3)); #ifdef HAVE_SSL +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + pkey = ldns_key_evp_key(k); + if (pkey) { + bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); + if (!bin) { + ldns_rr_free(pubkey); + return NULL; + } + if (!ldns_key_dsa2bin(bin, pkey, &size)) { + LDNS_FREE(bin); + ldns_rr_free(pubkey); + return NULL; + } + internal_data = 1; + } +#else dsa = ldns_key_dsa_key(k); if (dsa) { bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); @@ -1923,6 +2612,7 @@ ldns_key2rr(const ldns_key *k) DSA_free(dsa); internal_data = 1; } +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ #endif /* HAVE_SSL */ #endif /* USE_DSA */ break; @@ -1952,18 +2642,17 @@ ldns_key2rr(const ldns_key *k) case LDNS_SIGN_ECDSAP384SHA384: #ifdef USE_ECDSA ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( - LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); - bin = NULL; + LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); + bin = NULL; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L #ifndef S_SPLINT_S - ec = EVP_PKEY_get1_EC_KEY(k->_key.key); + size = EVP_PKEY_get1_encoded_public_key(pkey, &bin); #endif - EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); - size = (uint16_t)i2o_ECPublicKey(ec, NULL); - if(!i2o_ECPublicKey(ec, &bin)) { - EC_KEY_free(ec); - ldns_rr_free(pubkey); - return NULL; - } + if(size <= 0) { + ldns_rr_free(pubkey); + return NULL; + } if(size > 1) { /* move back one byte to shave off the 0x02 * 'uncompressed' indicator that openssl made @@ -1973,12 +2662,33 @@ ldns_key2rr(const ldns_key *k) size -= 1; memmove(bin, bin+1, size); } - /* down the reference count for ec, its still assigned - * to the pkey */ - EC_KEY_free(ec); +#else +#ifndef S_SPLINT_S + ec = EVP_PKEY_get1_EC_KEY(k->_key.key); +#endif + EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); + size = (uint16_t)i2o_ECPublicKey(ec, NULL); + if(!i2o_ECPublicKey(ec, &bin)) { + EC_KEY_free(ec); + ldns_rr_free(pubkey); + return NULL; + } + if(size > 1) { + /* move back one byte to shave off the 0x02 + * 'uncompressed' indicator that openssl made + * Actually its 0x04 (from implementation). + */ + assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED); + size -= 1; + memmove(bin, bin+1, size); + } + /* down the reference count for ec, its still assigned + * to the pkey */ + EC_KEY_free(ec); internal_data = 1; +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ #else - ldns_rr_free(pubkey); + ldns_rr_free(pubkey); return NULL; #endif /* ECDSA */ break; diff --git a/ldns/dnssec.h b/ldns/dnssec.h index 6ce305ae..c4cf02df 100644 --- a/ldns/dnssec.h +++ b/ldns/dnssec.h @@ -38,6 +38,10 @@ extern "C" { #endif +#if LDNS_BUILD_CONFIG_HAVE_SSL && !defined(OSSL_DEPRECATEDIN_3_0) +#define OSSL_DEPRECATEDIN_3_0 +#endif + #define LDNS_MAX_KEYLEN 2048 #define LDNS_DNSSEC_KEYPROTO 3 /* default time before sigs expire */ @@ -128,6 +132,8 @@ uint16_t ldns_calc_keytag(const ldns_rr *key); uint16_t ldns_calc_keytag_raw(const uint8_t* key, size_t keysize); #if LDNS_BUILD_CONFIG_HAVE_SSL +# ifndef OPENSSL_NO_DEPRECATED_3_0 +OSSL_DEPRECATEDIN_3_0 /** * converts a buffer holding key material to a DSA key in openssl. * @@ -135,6 +141,8 @@ uint16_t ldns_calc_keytag_raw(const uint8_t* key, size_t keysize); * \return a DSA * structure with the key material */ DSA *ldns_key_buf2dsa(const ldns_buffer *key); + +OSSL_DEPRECATEDIN_3_0 /** * Like ldns_key_buf2dsa, but uses raw buffer. * \param[in] key the uncompressed wireformat of the key. @@ -142,6 +150,25 @@ DSA *ldns_key_buf2dsa(const ldns_buffer *key); * \return a DSA * structure with the key material */ DSA *ldns_key_buf2dsa_raw(const unsigned char* key, size_t len); +# endif /* OPENSSL_NO_DEPRECATED_3_0 */ + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +/** + * converts a buffer holding DSA key material to an EVP_PKEY key in openssl. + * + * \param[in] key the key to convert + * \return an EVP_PKEY * structure with the key material + */ +EVP_PKEY *ldns_dsa2pkey(const ldns_buffer *key); + +/** + * Like ldns_dsa2pkey, but uses raw buffer. + * \param[in] key the uncompressed wireformat of the key. + * \param[in] len length of key data + * \return an EVP_PKEY * structure with the key material + */ +EVP_PKEY *ldns_dsa2pkey_raw(const unsigned char* key, size_t len); +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ /** * Utility function to calculate hash using generic EVP_MD pointer. @@ -194,6 +221,8 @@ EVP_PKEY* ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen); #endif /* LDNS_BUILD_CONFIG_HAVE_SSL */ #if LDNS_BUILD_CONFIG_HAVE_SSL +# ifndef OPENSSL_NO_DEPRECATED_3_0 +OSSL_DEPRECATEDIN_3_0 /** * converts a buffer holding key material to a RSA key in openssl. * @@ -202,6 +231,7 @@ EVP_PKEY* ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen); */ RSA *ldns_key_buf2rsa(const ldns_buffer *key); +OSSL_DEPRECATEDIN_3_0 /** * Like ldns_key_buf2rsa, but uses raw buffer. * \param[in] key the uncompressed wireformat of the key. @@ -209,6 +239,25 @@ RSA *ldns_key_buf2rsa(const ldns_buffer *key); * \return a RSA * structure with the key material */ RSA *ldns_key_buf2rsa_raw(const unsigned char* key, size_t len); +# endif /* OPENSSL_NO_DEPRECATED_3_0 */ + +# if OPENSSL_VERSION_NUMBER >= 0x30000000L +/** + * converts a buffer holding RSA key material to an EVP_PKEY key in openssl. + * + * \param[in] key the key to convert + * \return an EVP_PKEY * structure with the key material + */ +EVP_PKEY *ldns_rsa2pkey(const ldns_buffer *key); + +/** + * Like ldns_rsa2pkey, but uses raw buffer. + * \param[in] key the uncompressed wireformat of the key. + * \param[in] len length of key data + * \return an EVP_PKEY * structure with the key material + */ +EVP_PKEY *ldns_rsa2pkey_raw(const unsigned char* key, size_t len); +# endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ #endif /* LDNS_BUILD_CONFIG_HAVE_SSL */ /** diff --git a/ldns/dnssec_sign.h b/ldns/dnssec_sign.h index 4523811f..878d80ee 100644 --- a/ldns/dnssec_sign.h +++ b/ldns/dnssec_sign.h @@ -47,6 +47,8 @@ ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *key); ldns_rr_list *ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys); #if LDNS_BUILD_CONFIG_HAVE_SSL +# ifndef OPENSSL_NO_DEPRECATED_3_0 +OSSL_DEPRECATEDIN_3_0 /** * Sign a buffer with the DSA key (hash with SHA1) * @@ -55,7 +57,7 @@ ldns_rr_list *ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys); * \return a ldns_rdf for the RRSIG ldns_rr */ ldns_rdf *ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key); - +#endif /* OPENSSL_NO_DEPRECATED_3_0 */ /** * Sign data with EVP (general method for different algorithms) * @@ -70,6 +72,8 @@ ldns_rdf *ldns_sign_public_evp(ldns_buffer *to_sign, EVP_PKEY *key, const EVP_MD *digest_type); +# ifndef OPENSSL_NO_DEPRECATED_3_0 +OSSL_DEPRECATEDIN_3_0 /** * Sign a buffer with the RSA key (hash with SHA1) * \param[in] to_sign buffer with the data @@ -78,6 +82,7 @@ ldns_rdf *ldns_sign_public_evp(ldns_buffer *to_sign, */ ldns_rdf *ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key); +OSSL_DEPRECATEDIN_3_0 /** * Sign a buffer with the RSA key (hash with MD5) * \param[in] to_sign buffer with the data @@ -85,6 +90,7 @@ ldns_rdf *ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key); * \return a ldns_rdf with the signed data */ ldns_rdf *ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key); +# endif /* OPENSSL_NO_DEPRECATED_3_0 */ #endif /* LDNS_BUILD_CONFIG_HAVE_SSL */ /** diff --git a/ldns/keys.h b/ldns/keys.h index 847825e5..9dd0aff4 100644 --- a/ldns/keys.h +++ b/ldns/keys.h @@ -32,6 +32,10 @@ extern "C" { #endif +#if LDNS_BUILD_CONFIG_HAVE_SSL && !defined(OSSL_DEPRECATEDIN_3_0) +#define OSSL_DEPRECATEDIN_3_0 +#endif + extern ldns_lookup_table ldns_signing_algorithms[]; #define LDNS_KEY_ZONE_KEY 0x0100 /* rfc 4034 */ @@ -236,7 +240,27 @@ ldns_status ldns_key_new_frm_fp_l(ldns_key **k, FILE *fp, int *line_nr); */ ldns_status ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm a); +# if OPENSSL_VERSION_NUMBER >= 0x30000000L +/** + * frm_fp helper function. This function parses the + * remainder of the (RSA) priv. key file generated from bind9 + * \param[in] fp the file to parse + * \return NULL on failure otherwise an EVP_PKEY structure + */ +EVP_PKEY *ldns_pkey_new_frm_fp_rsa(FILE *fp); +/** + * frm_fp helper function. This function parses the + * remainder of the (RSA) priv. key file generated from bind9 + * \param[in] fp the file to parse + * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes) + * \return NULL on failure otherwise an EVP_PKEY structure + */ +EVP_PKEY *ldns_pkey_new_frm_fp_rsa_l(FILE *fp, int *line_nr); +# endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +OSSL_DEPRECATEDIN_3_0 /** * frm_fp helper function. This function parses the * remainder of the (RSA) priv. key file generated from bind9 @@ -245,6 +269,7 @@ ldns_status ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldn */ RSA *ldns_key_new_frm_fp_rsa(FILE *fp); +OSSL_DEPRECATEDIN_3_0 /** * frm_fp helper function. This function parses the * remainder of the (RSA) priv. key file generated from bind9 @@ -253,25 +278,49 @@ RSA *ldns_key_new_frm_fp_rsa(FILE *fp); * \return NULL on failure otherwise a RSA structure */ RSA *ldns_key_new_frm_fp_rsa_l(FILE *fp, int *line_nr); +# endif /* OPENSSL_NO_DEPRECATED_3_0 */ # if LDNS_BUILD_CONFIG_USE_DSA +# if OPENSSL_VERSION_NUMBER >= 0x30000000L /** * frm_fp helper function. This function parses the * remainder of the (DSA) priv. key file * \param[in] fp the file to parse - * \return NULL on failure otherwise a RSA structure + * \return NULL on failure otherwise an EVP_PKEY structure + */ +EVP_PKEY *ldns_pkey_new_frm_fp_dsa(FILE *fp); + +/** + * frm_fp helper function. This function parses the + * remainder of the (DSA) priv. key file + * \param[in] fp the file to parse + * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes) + * \return NULL on failure otherwise an EVP_PKEY structure + */ +EVP_PKEY *ldns_pkey_new_frm_fp_dsa_l(FILE *fp, int *line_nr); +# endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +OSSL_DEPRECATEDIN_3_0 +/** + * frm_fp helper function. This function parses the + * remainder of the (DSA) priv. key file + * \param[in] fp the file to parse + * \return NULL on failure otherwise a DSA structure */ DSA *ldns_key_new_frm_fp_dsa(FILE *fp); +OSSL_DEPRECATEDIN_3_0 /** * frm_fp helper function. This function parses the * remainder of the (DSA) priv. key file * \param[in] fp the file to parse * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes) - * \return NULL on failure otherwise a RSA structure + * \return NULL on failure otherwise a DSA structure */ DSA *ldns_key_new_frm_fp_dsa_l(FILE *fp, int *line_nr); +# endif /* OPENSSL_NO_DEPRECATED_3_0 */ # endif /* LDNS_BUILD_CONFIG_USE_DSA */ /** @@ -312,6 +361,8 @@ void ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l); */ void ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e); +# ifndef OPENSSL_NO_DEPRECATED_3_0 +OSSL_DEPRECATEDIN_3_0 /** * Set the key's rsa data. * The rsa data should be freed by the user. @@ -321,6 +372,7 @@ void ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e); void ldns_key_set_rsa_key(ldns_key *k, RSA *r); # if LDNS_BUILD_CONFIG_USE_DSA +OSSL_DEPRECATEDIN_3_0 /** * Set the key's dsa data * The dsa data should be freed by the user. @@ -330,6 +382,7 @@ void ldns_key_set_rsa_key(ldns_key *k, RSA *r); void ldns_key_set_dsa_key(ldns_key *k, DSA *d); # endif /* LDNS_BUILD_CONFIG_USE_DSA */ +OSSL_DEPRECATEDIN_3_0 /** * Assign the key's rsa data * The rsa data will be freed automatically when the key is freed. @@ -339,6 +392,7 @@ void ldns_key_set_dsa_key(ldns_key *k, DSA *d); void ldns_key_assign_rsa_key(ldns_key *k, RSA *r); # if LDNS_BUILD_CONFIG_USE_DSA +OSSL_DEPRECATEDIN_3_0 /** * Assign the key's dsa data * The dsa data will be freed automatically when the key is freed. @@ -346,7 +400,8 @@ void ldns_key_assign_rsa_key(ldns_key *k, RSA *r); * \param[in] d the dsa data */ void ldns_key_assign_dsa_key(ldns_key *k, DSA *d); -# endif /* LDNS_BUILD_CONFIG_USE_DSA */ +# endif /* LDNS_BUILD_CONFIG_USE_DSA */ +# endif /* OPENSSL_NO_DEPRECATED_3_0 */ /** * Get the PKEY id for GOST, loads GOST into openssl as a side effect. @@ -451,12 +506,15 @@ size_t ldns_key_list_key_count(const ldns_key_list *key_list); ldns_key *ldns_key_list_key(const ldns_key_list *key, size_t nr); #if LDNS_BUILD_CONFIG_HAVE_SSL +# ifndef OPENSSL_NO_DEPRECATED_3_0 +OSSL_DEPRECATEDIN_3_0 /** * returns the (openssl) RSA struct contained in the key * \param[in] k the key to look in * \return the RSA * structure in the key */ RSA *ldns_key_rsa_key(const ldns_key *k); +# endif /* OPENSSL_NO_DEPRECATED_3_0 */ /** * returns the (openssl) EVP struct contained in the key * \param[in] k the key to look in @@ -465,10 +523,13 @@ RSA *ldns_key_rsa_key(const ldns_key *k); EVP_PKEY *ldns_key_evp_key(const ldns_key *k); # if LDNS_BUILD_CONFIG_USE_DSA +# ifndef OPENSSL_NO_DEPRECATED_3_0 +OSSL_DEPRECATEDIN_3_0 /** * returns the (openssl) DSA struct contained in the key */ DSA *ldns_key_dsa_key(const ldns_key *k); +# endif /* OPENSSL_NO_DEPRECATED_3_0 */ # endif /* LDNS_BUILD_CONFIG_USE_DSA */ #endif /* LDNS_BUILD_CONFIG_HAVE_SSL */ diff --git a/ldns/util.h.in b/ldns/util.h.in index 7115a2b7..3799e325 100644 --- a/ldns/util.h.in +++ b/ldns/util.h.in @@ -388,6 +388,7 @@ int b32_pton_extended_hex(const char* src_text, size_t src_text_length, #endif /* ! LDNS_BUILD_CONFIG_HAVE_B32_PTON */ +void ldns_swap_bytes(unsigned char *buf, size_t len); #ifdef __cplusplus } diff --git a/util.c b/util.c index 662aa23a..e353b049 100644 --- a/util.c +++ b/util.c @@ -792,3 +792,16 @@ b32_pton_extended_hex(const char* src, size_t src_sz, #endif /* ! HAVE_B32_PTON */ +void +ldns_swap_bytes(unsigned char *buf, size_t len) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + size_t i, j, temp; + for(i = 0, j = len - 1; i < j; i++, j--) { + temp = buf[i]; + buf[i] = buf[j]; + buf[j] = temp; + } +#endif +} +