- OpenSSL 1.1.0 portability, --disable-dsa configure option.

git-svn-id: file:///svn/unbound/trunk@3689 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2016-03-23 08:19:49 +00:00
parent 59fd18e8ce
commit fbae76885a
10 changed files with 159 additions and 37 deletions

View File

@ -128,6 +128,9 @@
/* Define to 1 if you have the <event.h> header file. */
#undef HAVE_EVENT_H
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
#undef HAVE_EVP_MD_CTX_NEW
/* Define to 1 if you have the `EVP_sha1' function. */
#undef HAVE_EVP_SHA1
@ -586,6 +589,9 @@
/* Define to 1 to enable dnstap support */
#undef USE_DNSTAP
/* Define this to enable DSA support. */
#undef USE_DSA
/* Define this to enable ECDSA support. */
#undef USE_ECDSA

33
configure vendored
View File

@ -832,6 +832,7 @@ with_ssl
enable_sha2
enable_gost
enable_ecdsa
enable_dsa
enable_event_api
with_libevent
with_libexpat
@ -1495,6 +1496,7 @@ Optional Features:
--disable-sha2 Disable SHA256 and SHA512 RRSIG support
--disable-gost Disable GOST support
--disable-ecdsa Disable ECDSA support
--disable-dsa Disable DSA support
--enable-event-api Enable (experimental) pluggable event base
libunbound API installed to unbound-event.h
--enable-static-exe enable to compile executables statically against
@ -17483,7 +17485,7 @@ fi
done
for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode
for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_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"
@ -17850,6 +17852,35 @@ _ACEOF
;;
esac
# Check whether --enable-dsa was given.
if test "${enable_dsa+set}" = set; then :
enableval=$enable_dsa;
fi
use_dsa="no"
case "$enable_ecdsa" in
no)
;;
*)
# detect if DSA is supported, and turn it off if not.
ac_fn_c_check_func "$LINENO" "EVP_dss1" "ac_cv_func_EVP_dss1"
if test "x$ac_cv_func_EVP_dss1" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define USE_DSA 1
_ACEOF
else
if test "x$enable_dsa" = "xyes"; then as_fn_error $? "OpenSSL does not support DSA and you used --enable-dsa." "$LINENO" 5
fi
fi
;;
esac
# Check whether --enable-event-api was given.
if test "${enable_event_api+set}" = set; then :
enableval=$enable_event_api;

View File

@ -658,7 +658,7 @@ else
fi
AC_CHECK_HEADERS([openssl/conf.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new])
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
AC_INCLUDES_DEFAULT
#ifdef HAVE_OPENSSL_ERR_H
@ -840,6 +840,21 @@ case "$enable_ecdsa" in
;;
esac
AC_ARG_ENABLE(dsa, AC_HELP_STRING([--disable-dsa], [Disable DSA support]))
use_dsa="no"
case "$enable_ecdsa" in
no)
;;
*)
# detect if DSA is supported, and turn it off if not.
AC_CHECK_FUNC(EVP_dss1, [
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 ])
;;
esac
AC_ARG_ENABLE(event-api, AC_HELP_STRING([--enable-event-api], [Enable (experimental) pluggable event base libunbound API installed to unbound-event.h]))
case "$enable_event_api" in
yes)

View File

@ -644,17 +644,23 @@ daemon_delete(struct daemon* daemon)
# endif
# if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE
# ifndef S_SPLINT_S
# if OPENSSL_VERSION_NUMBER < 0x10100000
sk_SSL_COMP_pop_free(comp_meth, (void(*)())CRYPTO_free);
# endif
# endif
# endif
# ifdef HAVE_OPENSSL_CONFIG
EVP_cleanup();
# if OPENSSL_VERSION_NUMBER < 0x10100000
ENGINE_cleanup();
# endif
CONF_modules_free();
# endif
CRYPTO_cleanup_all_ex_data(); /* safe, no more threads right now */
ERR_free_strings();
# if OPENSSL_VERSION_NUMBER < 0x10100000
RAND_cleanup();
# endif
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
ub_openssl_lock_delete();
# endif

View File

@ -1,3 +1,6 @@
23 March 2016: Wouter
- OpenSSL 1.1.0 portability, --disable-dsa configure option.
21 March 2016: Wouter
- Fix compile of getentropy_linux for SLES11 servicepack 4.
- Fix dnstap-log-resolver-response-messages, from Nikolay Edigaryev.

View File

@ -643,6 +643,5 @@ int main(int argc, char* argv[])
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
RAND_cleanup();
return 0;
}

View File

@ -497,12 +497,14 @@ verify_test(void)
{
unit_show_feature("signature verify");
verifytest_file("testdata/test_signatures.1", "20070818005004");
#ifdef USE_DSA
verifytest_file("testdata/test_signatures.2", "20080414005004");
verifytest_file("testdata/test_signatures.3", "20080416005004");
verifytest_file("testdata/test_signatures.4", "20080416005004");
verifytest_file("testdata/test_signatures.5", "20080416005004");
verifytest_file("testdata/test_signatures.6", "20080416005004");
verifytest_file("testdata/test_signatures.7", "20070829144150");
#endif /* USE_DSA */
verifytest_file("testdata/test_signatures.8", "20070829144150");
#if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
verifytest_file("testdata/test_sigs.rsasha256", "20070829144150");

View File

@ -783,7 +783,7 @@ void* outgoing_ssl_fd(void* sslctx, int fd)
#endif
}
#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK)
/** global lock list for openssl locks */
static lock_basic_t *ub_openssl_locks = NULL;
@ -808,7 +808,7 @@ ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file),
int ub_openssl_lock_init(void)
{
#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK)
int i;
ub_openssl_locks = (lock_basic_t*)reallocarray(
NULL, (size_t)CRYPTO_num_locks(), sizeof(lock_basic_t));
@ -825,7 +825,7 @@ int ub_openssl_lock_init(void)
void ub_openssl_lock_delete(void)
{
#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK)
int i;
if(!ub_openssl_locks)
return;

View File

@ -1030,6 +1030,8 @@ anchors_assemble_rrsets(struct val_anchors* anchors)
")", b);
(void)rbtree_delete(anchors->tree, &ta->node);
lock_basic_unlock(&ta->lock);
if(anchors->dlv_anchor == ta)
anchors->dlv_anchor = NULL;
anchors_delfunc(&ta->node, NULL);
ta = next;
continue;

View File

@ -186,8 +186,10 @@ dnskey_algo_id_is_supported(int id)
case LDNS_RSAMD5:
/* RFC 6725 deprecates RSAMD5 */
return 0;
#ifdef USE_DSA
case LDNS_DSA:
case LDNS_DSA_NSEC3:
#endif
case LDNS_RSASHA1:
case LDNS_RSASHA1_NSEC3:
#if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
@ -227,6 +229,7 @@ log_crypto_error(const char* str, unsigned long e)
log_err("%s crypto %s", str, buf);
}
#ifdef USE_DSA
/**
* Setup DSA key digest in DER encoding ...
* @param sig: input is signature output alloced ptr (unless failure).
@ -268,6 +271,7 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len)
DSA_SIG_free(dsasig);
return 1;
}
#endif /* USE_DSA */
#ifdef USE_ECDSA
/**
@ -281,32 +285,61 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len)
static int
setup_ecdsa_sig(unsigned char** sig, unsigned int* len)
{
ECDSA_SIG* ecdsa_sig;
int newlen;
/* convert from two BIGNUMs in the rdata buffer, to ASN notation.
* ASN preable: 30440220 <R 32bytefor256> 0220 <S 32bytefor256>
* the '20' is the length of that field (=bnsize).
i * the '44' is the total remaining length.
* if negative, start with leading zero.
* if starts with 00s, remove them from the number.
*/
uint8_t pre[] = {0x30, 0x44, 0x02, 0x20};
int pre_len = 4;
uint8_t mid[] = {0x02, 0x20};
int mid_len = 2;
int raw_sig_len, r_high, s_high, r_rem=0, s_rem=0;
int bnsize = (int)((*len)/2);
unsigned char* d = *sig;
unsigned char* p;
/* if too short or not even length, fails */
if(*len < 16 || bnsize*2 != (int)*len)
return 0;
/* use the raw data to parse two evenly long BIGNUMs, "r | s". */
ecdsa_sig = ECDSA_SIG_new();
if(!ecdsa_sig) return 0;
ecdsa_sig->r = BN_bin2bn(*sig, bnsize, ecdsa_sig->r);
ecdsa_sig->s = BN_bin2bn(*sig+bnsize, bnsize, ecdsa_sig->s);
if(!ecdsa_sig->r || !ecdsa_sig->s) {
ECDSA_SIG_free(ecdsa_sig);
return 0;
}
/* spool it into ASN format */
*sig = NULL;
newlen = i2d_ECDSA_SIG(ecdsa_sig, sig);
if(newlen <= 0) {
ECDSA_SIG_free(ecdsa_sig);
free(*sig);
/* strip leading zeroes from r (but not last one) */
while(r_rem < bnsize-1 && d[r_rem] == 0)
r_rem++;
/* strip leading zeroes from s (but not last one) */
while(s_rem < bnsize-1 && d[bnsize+s_rem] == 0)
s_rem++;
r_high = ((d[0+r_rem]&0x80)?1:0);
s_high = ((d[bnsize+s_rem]&0x80)?1:0);
raw_sig_len = pre_len + r_high + bnsize - r_rem + mid_len +
s_high + bnsize - s_rem;
*sig = (unsigned char*)malloc(raw_sig_len);
if(!*sig)
return 0;
p = *sig;
p[0] = pre[0];
p[1] = raw_sig_len-2;
p[2] = pre[2];
p[3] = bnsize + r_high - r_rem;
p += 4;
if(r_high) {
*p = 0;
p += 1;
}
*len = (unsigned int)newlen;
ECDSA_SIG_free(ecdsa_sig);
memmove(p, d+r_rem, bnsize-r_rem);
p += bnsize-r_rem;
memmove(p, mid, mid_len-1);
p += mid_len-1;
*p = bnsize + s_high - s_rem;
p += 1;
if(s_high) {
*p = 0;
p += 1;
}
memmove(p, d+bnsize+s_rem, bnsize-s_rem);
*len = (unsigned int)raw_sig_len;
return 1;
}
#endif /* USE_ECDSA */
@ -325,10 +358,13 @@ static int
setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
unsigned char* key, size_t keylen)
{
#ifdef USE_DSA
DSA* dsa;
#endif
RSA* rsa;
switch(algo) {
#ifdef USE_DSA
case LDNS_DSA:
case LDNS_DSA_NSEC3:
*evp_key = EVP_PKEY_new();
@ -350,6 +386,7 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
*digest_type = EVP_dss1();
break;
#endif /* USE_DSA */
case LDNS_RSASHA1:
case LDNS_RSASHA1_NSEC3:
#if defined(HAVE_EVP_SHA256) && defined(USE_SHA2)
@ -508,7 +545,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
char** reason)
{
const EVP_MD *digest_type;
EVP_MD_CTX ctx;
EVP_MD_CTX* ctx;
int res, dofree = 0;
EVP_PKEY *evp_key = NULL;
@ -518,6 +555,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
EVP_PKEY_free(evp_key);
return sec_status_bogus;
}
#ifdef USE_DSA
/* if it is a DSA signature in bind format, convert to DER format */
if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&
sigblock_len == 1+2*SHA_DIGEST_LENGTH) {
@ -529,8 +567,12 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
}
dofree = 1;
}
#endif
#if defined(USE_ECDSA) && defined(USE_DSA)
else
#endif
#ifdef USE_ECDSA
else if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) {
if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) {
/* EVP uses ASN prefix on sig, which is not in the wire data */
if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) {
verbose(VERB_QUERY, "verify: failed to setup ECDSA sig");
@ -543,14 +585,25 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
#endif /* USE_ECDSA */
/* do the signature cryptography work */
EVP_MD_CTX_init(&ctx);
if(EVP_VerifyInit(&ctx, digest_type) == 0) {
#ifdef HAVE_EVP_MD_CTX_NEW
ctx = EVP_MD_CTX_new();
#else
ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
if(ctx) EVP_MD_CTX_init(ctx);
#endif
if(!ctx) {
log_err("EVP_MD_CTX_new: malloc failure");
EVP_PKEY_free(evp_key);
if(dofree) free(sigblock);
return sec_status_unchecked;
}
if(EVP_VerifyInit(ctx, digest_type) == 0) {
verbose(VERB_QUERY, "verify: EVP_VerifyInit failed");
EVP_PKEY_free(evp_key);
if(dofree) free(sigblock);
return sec_status_unchecked;
}
if(EVP_VerifyUpdate(&ctx, (unsigned char*)sldns_buffer_begin(buf),
if(EVP_VerifyUpdate(ctx, (unsigned char*)sldns_buffer_begin(buf),
(unsigned int)sldns_buffer_limit(buf)) == 0) {
verbose(VERB_QUERY, "verify: EVP_VerifyUpdate failed");
EVP_PKEY_free(evp_key);
@ -558,13 +611,8 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
return sec_status_unchecked;
}
res = EVP_VerifyFinal(&ctx, sigblock, sigblock_len, evp_key);
if(EVP_MD_CTX_cleanup(&ctx) == 0) {
verbose(VERB_QUERY, "verify: EVP_MD_CTX_cleanup failed");
EVP_PKEY_free(evp_key);
if(dofree) free(sigblock);
return sec_status_unchecked;
}
res = EVP_VerifyFinal(ctx, sigblock, sigblock_len, evp_key);
EVP_MD_CTX_destroy(ctx);
EVP_PKEY_free(evp_key);
if(dofree)
@ -678,8 +726,10 @@ dnskey_algo_id_is_supported(int id)
case LDNS_RSAMD5:
/* RFC 6725 deprecates RSAMD5 */
return 0;
#ifdef USE_DSA
case LDNS_DSA:
case LDNS_DSA_NSEC3:
#endif
case LDNS_RSASHA1:
case LDNS_RSASHA1_NSEC3:
#ifdef USE_SHA2
@ -920,6 +970,7 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
*/
switch(algo) {
#ifdef USE_DSA
case LDNS_DSA:
case LDNS_DSA_NSEC3:
*pubkey = nss_buf2dsa(key, keylen);
@ -930,6 +981,7 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
*htype = HASH_AlgSHA1;
/* no prefix for DSA verification */
break;
#endif
case LDNS_RSASHA1:
case LDNS_RSASHA1_NSEC3:
#ifdef USE_SHA2
@ -1046,6 +1098,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
return sec_status_bogus;
}
#ifdef USE_DSA
/* need to convert DSA, ECDSA signatures? */
if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) {
if(sigblock_len == 1+2*SHA1_LENGTH) {
@ -1068,6 +1121,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
SECITEM_FreeItem(p, PR_TRUE);
}
}
#endif /* USE_DSA */
/* do the signature cryptography work */
/* hash the data */
@ -1263,8 +1317,10 @@ dnskey_algo_id_is_supported(int id)
{
/* uses libnettle */
switch(id) {
#ifdef USE_DSA
case LDNS_DSA:
case LDNS_DSA_NSEC3:
#endif
case LDNS_RSASHA1:
case LDNS_RSASHA1_NSEC3:
#ifdef USE_SHA2
@ -1541,6 +1597,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
}
switch(algo) {
#ifdef USE_DSA
case LDNS_DSA:
case LDNS_DSA_NSEC3:
*reason = _verify_nettle_dsa(buf, sigblock, sigblock_len, key, keylen);
@ -1548,6 +1605,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
return sec_status_bogus;
else
return sec_status_secure;
#endif /* USE_DSA */
case LDNS_RSASHA1:
case LDNS_RSASHA1_NSEC3: