Native signature verification

This commit is contained in:
Willem Toorop 2015-09-25 11:48:58 +02:00
parent 2e4c0928f7
commit d8cc7b1ba3
4 changed files with 231 additions and 25 deletions

View File

@ -193,7 +193,204 @@ case "$enable_native_stub_dnssec" in
;;
esac
USE_NSS="no"
# openssl
if test $USE_NSS = "no"; then
ACX_WITH_SSL_OPTIONAL
ACX_LIB_SSL
AC_MSG_CHECKING([for LibreSSL])
if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" >/dev/null; then
AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_LIBRESSL], [1], [Define if we have LibreSSL])
# libressl provides these compat functions, but they may also be
# declared by the OS in libc. See if they have been declared.
AC_CHECK_DECLS([strlcpy,strlcat,arc4random,arc4random_uniform,reallocarray])
else
AC_MSG_RESULT([no])
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_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
AC_INCLUDES_DEFAULT
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
#endif
#ifdef HAVE_OPENSSL_RAND_H
#include <openssl/rand.h>
#endif
#ifdef HAVE_OPENSSL_CONF_H
#include <openssl/conf.h>
#endif
#ifdef HAVE_OPENSSL_ENGINE_H
#include <openssl/engine.h>
#endif
#include <openssl/ssl.h>
#include <openssl/evp.h>
])
fi
AC_ARG_ENABLE(sha2, AC_HELP_STRING([--disable-sha2], [Disable SHA256 and SHA512 RRSIG support]))
case "$enable_sha2" in
no)
;;
yes|*)
AC_DEFINE([USE_SHA2], [1], [Define this to enable SHA256 and SHA512 support.])
;;
esac
# check wether gost also works
AC_DEFUN([AC_CHECK_GOST_WORKS],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING([if GOST works])
if test c${cross_compiling} = cno; then
BAKCFLAGS="$CFLAGS"
if test -n "$ssldir"; then
CFLAGS="$CFLAGS -Wl,-rpath,$ssldir/lib"
fi
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <string.h>
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/engine.h>
#include <openssl/conf.h>
/* routine to load gost (from sldns) */
int load_gost_id(void)
{
static int gost_id = 0;
const EVP_PKEY_ASN1_METHOD* meth;
ENGINE* e;
if(gost_id) return gost_id;
/* see if configuration loaded gost implementation from other engine*/
meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
if(meth) {
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
return gost_id;
}
/* see if engine can be loaded already */
e = ENGINE_by_id("gost");
if(!e) {
/* load it ourself, in case statically linked */
ENGINE_load_builtin_engines();
ENGINE_load_dynamic();
e = ENGINE_by_id("gost");
}
if(!e) {
/* no gost engine in openssl */
return 0;
}
if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
ENGINE_finish(e);
ENGINE_free(e);
return 0;
}
meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
if(!meth) {
/* algo not found */
ENGINE_finish(e);
ENGINE_free(e);
return 0;
}
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
return gost_id;
}
int main(void) {
EVP_MD_CTX* ctx;
const EVP_MD* md;
unsigned char digest[64]; /* its a 256-bit digest, so uses 32 bytes */
const char* str = "Hello world";
const unsigned char check[] = {
0x40 , 0xed , 0xf8 , 0x56 , 0x5a , 0xc5 , 0x36 , 0xe1 ,
0x33 , 0x7c , 0x7e , 0x87 , 0x62 , 0x1c , 0x42 , 0xe0 ,
0x17 , 0x1b , 0x5e , 0xce , 0xa8 , 0x46 , 0x65 , 0x4d ,
0x8d , 0x3e , 0x22 , 0x9b , 0xe1 , 0x30 , 0x19 , 0x9d
};
OPENSSL_config(NULL);
(void)load_gost_id();
md = EVP_get_digestbyname("md_gost94");
if(!md) return 1;
memset(digest, 0, sizeof(digest));
ctx = EVP_MD_CTX_create();
if(!ctx) return 2;
if(!EVP_DigestInit_ex(ctx, md, NULL)) return 3;
if(!EVP_DigestUpdate(ctx, str, 10)) return 4;
if(!EVP_DigestFinal_ex(ctx, digest, NULL)) return 5;
/* uncomment to see the hash calculated.
{int i;
for(i=0; i<32; i++)
printf(" %2.2x", (int)digest[i]);
printf("\n");}
*/
if(memcmp(digest, check, sizeof(check)) != 0)
return 6;
return 0;
}
]])] , [eval "ac_cv_c_gost_works=yes"], [eval "ac_cv_c_gost_works=no"])
CFLAGS="$BAKCFLAGS"
else
eval "ac_cv_c_gost_works=maybe"
fi
AC_MSG_RESULT($ac_cv_c_gost_works)
])dnl
AC_ARG_ENABLE(gost, AC_HELP_STRING([--disable-gost], [Disable GOST support]))
use_gost="no"
if test $USE_NSS = "no"; then
case "$enable_gost" in
no)
;;
*)
AC_CHECK_FUNC(EVP_PKEY_set_type_str, [:],[AC_MSG_ERROR([OpenSSL 1.0.0 is needed for GOST support])])
AC_CHECK_FUNC(EC_KEY_new, [], [AC_MSG_ERROR([OpenSSL does not support ECC, needed for GOST support])])
AC_CHECK_GOST_WORKS
if test "$ac_cv_c_gost_works" != no; then
use_gost="yes"
AC_DEFINE([USE_GOST], [1], [Define this to enable GOST support.])
fi
;;
esac
fi dnl !USE_NSS
AC_ARG_ENABLE(ecdsa, AC_HELP_STRING([--disable-ecdsa], [Disable ECDSA support]))
use_ecdsa="no"
case "$enable_ecdsa" in
no)
;;
*)
if test $USE_NSS = "no"; then
AC_CHECK_FUNC(ECDSA_sign, [], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa])])
AC_CHECK_FUNC(SHA384_Init, [], [AC_MSG_ERROR([OpenSSL does not support SHA384: please upgrade or rerun with --disable-ecdsa])])
AC_CHECK_DECLS([NID_X9_62_prime256v1, NID_secp384r1], [], [AC_MSG_ERROR([OpenSSL does not support the ECDSA curves: please upgrade or rerun with --disable-ecdsa])], [AC_INCLUDES_DEFAULT
#include <openssl/evp.h>
])
# see if OPENSSL 1.0.0 or later (has EVP MD and Verify independency)
AC_MSG_CHECKING([if openssl supports SHA2 and ECDSA with EVP])
if grep OPENSSL_VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "OpenSSL" >/dev/null; then
if grep OPENSSL_VERSION_NUMBER $ssldir/include/openssl/opensslv.h | grep 0x0 >/dev/null; then
AC_MSG_RESULT([no])
AC_DEFINE_UNQUOTED([USE_ECDSA_EVP_WORKAROUND], [1], [Define this to enable an EVP workaround for older openssl])
else
AC_MSG_RESULT([yes])
fi
else
# not OpenSSL, thus likely LibreSSL, which supports it
AC_MSG_RESULT([yes])
fi
fi
# we now know we have ECDSA and the required curves.
AC_DEFINE_UNQUOTED([USE_ECDSA], [1], [Define this to enable ECDSA support.])
use_ecdsa="yes"
;;
esac
AC_ARG_ENABLE(draft-edns-cookies, AC_HELP_STRING([--enable-draft-edns-cookies], [Enable experimental edns cookies]))

View File

@ -1553,6 +1553,7 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
size_t cdname_len, pos;
uint32_t orig_ttl;
gldns_buffer valbuf;
char *reason;
/* nc_name should already have been initialized by the parent! */
assert(nc_name);
@ -1646,30 +1647,15 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
, gldns_buffer_position(&valbuf));
assert(gldns_buffer_position(&valbuf) == valbuf_sz);
/* Check with ldns to verify we're still on the right path.
*/
if (1) {
ldns_buffer lvalbuf;
r = _getdns_verify_canonrrset(&valbuf, key->rr_i.rr_type[13],
signer->nxt, rrsig->rr_i.nxt - signer->nxt,
key->rr_i.rr_type+14, key->rr_i.nxt - key->rr_i.rr_type-14,
&reason);
ldns_buffer_new_frm_data( &lvalbuf
, gldns_buffer_begin(&valbuf)
, gldns_buffer_position(&valbuf));
ldns_buffer_set_position( &lvalbuf
, gldns_buffer_position(&valbuf));
r = ldns_verify_rrsig_buffers_raw(
/* sig, siglen */
signer->nxt, rrsig->rr_i.nxt - signer->nxt,
/* verify buf */
&lvalbuf,
/* key, keylen */
key->rr_i.rr_type+14, key->rr_i.nxt - key->rr_i.rr_type-14,
/* algo */
key->rr_i.rr_type[13]) == LDNS_STATUS_OK;
}
#if defined(SEC_DEBUG) && SEC_DEBUG
if (r == 0)
DEBUG_SEC("verification failed: %s\n", reason);
#endif
if (val_rrset != val_rrset_spc)
GETDNS_FREE(*mf, val_rrset);
if (valbuf_buf != valbuf_spc)
@ -1806,7 +1792,7 @@ static int nsec3_iteration_count_high(rrtype_iter *dnskey, getdns_rrset *nsec3)
|| rr->rr_i.rr_type + 14 > rr->rr_i.nxt)
return 1;
bits = ldns_rr_dnskey_key_size_raw(dnskey->rr_i.rr_type + 10,
bits = gldns_rr_dnskey_key_size_raw(dnskey->rr_i.rr_type + 10,
dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10,
dnskey->rr_i.rr_type[13]);

View File

@ -165,6 +165,20 @@ getdns_return_t _getdns_validate_extensions(struct getdns_dict * extensions);
fprintf(stderr, __VA_ARGS__); \
} while (0)
#define DEBUG_NL(...) do { \
struct timeval tv; \
struct tm tm; \
char buf[10]; \
\
gettimeofday(&tv, NULL); \
gmtime_r(&tv.tv_sec, &tm); \
strftime(buf, 10, "%T", &tm); \
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} while (0)
#define DEBUG_OFF(...) do {} while (0)
#if defined(SCHED_DEBUG) && SCHED_DEBUG

View File

@ -34,9 +34,18 @@
#ifndef UTIL_LOG_H
#define UTIL_LOG_H
#define log_assert(x)
#include "config.h"
#include "util-internal.h"
#if defined(SEC_DEBUG) && SEC_DEBUG
#define verbose(x, ...) DEBUG_NL(__VA_ARGS__)
#define log_err(...) DEBUG_NL(__VA_ARGS__)
#else
#define verbose(...)
#define log_err(...)
#endif
#define log_assert(x)
#endif /* UTIL_LOG_H */