From: Willem Toorop Date: Thu, 15 Dec 2016 10:47:02 +0000 (+0100) Subject: bugfix: detect DSA support with OpenSSL >= 1.1.0 X-Git-Tag: release-1.7.0~2^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d2323f8c644dddd49bafe7367189ba4bc8178067;p=thirdparty%2Fldns.git bugfix: detect DSA support with OpenSSL >= 1.1.0 --- diff --git a/Changelog b/Changelog index 7e78c068..ebf51ddb 100644 --- a/Changelog +++ b/Changelog @@ -108,6 +108,7 @@ * Add sha384 and sha512 tsig algorithm. Thanks Michael Weiser * Clarify data ownership with consts for tsig parameters. Thanks Michael Weiser + * bugfix: Fix detection of DSA support with OpenSSL >= 1.1.0 1.6.17 2014-01-10 * Fix ldns_dnssec_zone_new_frm_fp_l to allow the last parsed line of a diff --git a/configure.ac b/configure.ac index 90146c31..08f05086 100644 --- a/configure.ac +++ b/configure.ac @@ -331,7 +331,7 @@ if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" >/dev/ else AC_MSG_RESULT([no]) fi -AC_CHECK_FUNCS([EVP_sha256 EVP_sha384 EVP_sha512 ENGINE_load_cryptodev EVP_PKEY_keygen ECDSA_SIG_get0 EVP_MD_CTX_new EVP_PKEY_base_id]) +AC_CHECK_FUNCS([EVP_sha256 EVP_sha384 EVP_sha512 ENGINE_load_cryptodev EVP_PKEY_keygen ECDSA_SIG_get0 EVP_MD_CTX_new EVP_PKEY_base_id DSA_SIG_set0 DSA_SIG_get0 EVP_dss1 DSA_get0_pqg DSA_get0_key]) # for macosx, see if glibtool exists and use that # BSD's need to know the version... @@ -393,7 +393,7 @@ case "$enable_dsa" in ;; *) dnl default # detect if DSA is supported, and turn it off if not. - AC_CHECK_FUNC(EVP_dss1, [ + AC_CHECK_FUNC(DSA_SIG_new, [ AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.]) ], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.]) fi ]) diff --git a/dnssec.c b/dnssec.c index 6faaa9c4..e3c99de2 100644 --- a/dnssec.c +++ b/dnssec.c @@ -1737,6 +1737,7 @@ ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig, #ifdef USE_DSA ldns_rdf *sigdata_rdf; DSA_SIG *dsasig; + const BIGNUM *R, *S; unsigned char *dsasig_data = (unsigned char*)ldns_buffer_begin(sig); size_t byte_offset; @@ -1754,22 +1755,28 @@ ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig, return NULL; } dsasig_data[0] = 0; - byte_offset = (size_t) (20 - BN_num_bytes(dsasig->r)); +# ifdef HAVE_DSA_SIG_GET0 + DSA_SIG_get0(dsasig, &R, &S); +# else + R = dsasig->r; + S = dsasig->s; +# endif + byte_offset = (size_t) (20 - BN_num_bytes(R)); if (byte_offset > 20) { DSA_SIG_free(dsasig); LDNS_FREE(dsasig_data); return NULL; } memset(&dsasig_data[1], 0, byte_offset); - BN_bn2bin(dsasig->r, &dsasig_data[1 + byte_offset]); - byte_offset = (size_t) (20 - BN_num_bytes(dsasig->s)); + BN_bn2bin(R, &dsasig_data[1 + byte_offset]); + byte_offset = (size_t) (20 - BN_num_bytes(S)); if (byte_offset > 20) { DSA_SIG_free(dsasig); LDNS_FREE(dsasig_data); return NULL; } memset(&dsasig_data[21], 0, byte_offset); - BN_bn2bin(dsasig->s, &dsasig_data[21 + byte_offset]); + BN_bn2bin(S, &dsasig_data[21 + byte_offset]); sigdata_rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, 41, dsasig_data); if(!sigdata_rdf) { @@ -1816,9 +1823,13 @@ ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer, BN_free(S); return LDNS_STATUS_MEM_ERR; } - +# ifdef HAVE_DSA_SIG_SET0 + if (! DSA_SIG_set0(dsasig, R, S)) + return LDNS_STATUS_SSL_ERR; +# else dsasig->r = R; dsasig->s = S; +# endif raw_sig_len = i2d_DSA_SIG(dsasig, &raw_sig); if (raw_sig_len < 0) { diff --git a/dnssec_sign.c b/dnssec_sign.c index 17766f3a..22f09816 100644 --- a/dnssec_sign.c +++ b/dnssec_sign.c @@ -128,7 +128,12 @@ ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key) b64rdf = ldns_sign_public_evp( sign_buf, ldns_key_evp_key(current_key), - EVP_dss1()); +# ifdef HAVE_EVP_DSS1 + EVP_dss1() +# else + EVP_sha1() +# endif + ); break; #endif /* USE_DSA */ case LDNS_SIGN_RSASHA1: @@ -332,6 +337,7 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key) ldns_buffer *b64sig; DSA_SIG *sig; + const BIGNUM *R, *S; uint8_t *data; size_t pad; @@ -361,17 +367,23 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key) } data[0] = 1; - pad = 20 - (size_t) BN_num_bytes(sig->r); +# ifdef HAVE_DSA_SIG_GET0 + DSA_SIG_get0(sig, &R, &S); +# else + R = sig->r; + S = sig->s; +# endif + pad = 20 - (size_t) BN_num_bytes(R); if (pad > 0) { memset(data + 1, 0, pad); } - BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad); + BN_bn2bin(R, (unsigned char *) (data + 1) + pad); - pad = 20 - (size_t) BN_num_bytes(sig->s); + pad = 20 - (size_t) BN_num_bytes(S); if (pad > 0) { memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad); } - BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad)); + BN_bn2bin(S, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad)); sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, 1 + 2 * SHA_DIGEST_LENGTH, @@ -490,7 +502,11 @@ ldns_sign_public_evp(ldns_buffer *to_sign, #ifdef USE_DSA #ifndef S_SPLINT_S /* unfortunately, OpenSSL output is different from DNS DSA format */ +# ifdef HAVE_EVP_PKEY_BASE_ID + if (EVP_PKEY_base_id(key) == EVP_PKEY_DSA) { +# else if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) { +# endif r = 1; sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen); } diff --git a/dnssec_verify.c b/dnssec_verify.c index ee080e27..c554e4f4 100644 --- a/dnssec_verify.c +++ b/dnssec_verify.c @@ -2698,7 +2698,12 @@ ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen, siglen, rrset, evp_key, - EVP_dss1()); +# ifdef HAVE_EVP_DSS1 + EVP_dss1() +# else + EVP_sha1() +# endif + ); } else { result = LDNS_STATUS_SSL_ERR; } diff --git a/keys.c b/keys.c index 11e18f53..31208cb3 100644 --- a/keys.c +++ b/keys.c @@ -1196,11 +1196,24 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) case LDNS_SIGN_DSA_NSEC3: #ifdef USE_DSA #ifdef HAVE_SSL +# 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 + if (! (d = DSA_new())) { + ldns_key_free(k); + return NULL; + } + if (! DSA_generate_parameters_ex(d, (int)size, NULL, 0, NULL, NULL, NULL)) { + DSA_free(d); + ldns_key_free(k); + return NULL; + } +# endif if (DSA_generate_key(d) != 1) { ldns_key_free(k); return NULL; @@ -1735,13 +1748,26 @@ static bool ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size) { uint8_t T; + const BIGNUM *p, *q, *g; + const BIGNUM *pub_key, *priv_key; if (!k) { return false; } /* See RFC2536 */ - *size = (uint16_t)BN_num_bytes(k->p); +# ifdef HAVE_DSA_GET0_PQG + DSA_get0_pqg(k, &p, &q, &g); +# else + p = k->p; q = k->q; g = k->g; +# endif +# ifdef HAVE_DSA_GET0_KEY + DSA_get0_key(k, &pub_key, &priv_key); +# else + pub_key = k->pub_key; priv_key = k->priv_key; +# endif + (void)priv_key; + *size = (uint16_t)BN_num_bytes(p); T = (*size - 64) / 8; if (T > 8) { @@ -1755,10 +1781,10 @@ ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size) /* size = 64 + (T * 8); */ memset(data, 0, 21 + *size * 3); data[0] = (unsigned char)T; - BN_bn2bin(k->q, data + 1 ); /* 20 octects */ - BN_bn2bin(k->p, data + 21 ); /* offset octects */ - BN_bn2bin(k->g, data + 21 + *size * 2 - BN_num_bytes(k->g)); - BN_bn2bin(k->pub_key,data + 21 + *size * 3 - BN_num_bytes(k->pub_key)); + 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; }