mirror of
https://github.com/monero-project/monero.git
synced 2025-12-15 16:19:18 -05:00
update unbound, fix unbound openssl issue on OS X
This commit is contained in:
parent
32a26332f8
commit
2d43ae8063
101 changed files with 4685 additions and 3057 deletions
10
external/unbound/validator/autotrust.c
vendored
10
external/unbound/validator/autotrust.c
vendored
|
|
@ -1195,6 +1195,14 @@ void autr_write_file(struct module_env* env, struct trust_anchor* tp)
|
|||
fatal_exit("could not completely write: %s", fname);
|
||||
return;
|
||||
}
|
||||
if(fflush(out) != 0)
|
||||
log_err("could not fflush(%s): %s", fname, strerror(errno));
|
||||
#ifdef HAVE_FSYNC
|
||||
if(fsync(fileno(out)) != 0)
|
||||
log_err("could not fsync(%s): %s", fname, strerror(errno));
|
||||
#else
|
||||
FlushFileBuffers((HANDLE)_fileno(out));
|
||||
#endif
|
||||
if(fclose(out) != 0) {
|
||||
fatal_exit("could not complete write: %s: %s",
|
||||
fname, strerror(errno));
|
||||
|
|
@ -2162,7 +2170,7 @@ int autr_process_prime(struct module_env* env, struct val_env* ve,
|
|||
if(!verify_dnskey(env, ve, tp, dnskey_rrset)) {
|
||||
verbose(VERB_ALGO, "autotrust: dnskey did not verify.");
|
||||
/* only increase failure count if this is not the first prime,
|
||||
* this means there was a previous succesful probe */
|
||||
* this means there was a previous successful probe */
|
||||
if(tp->autr->last_success) {
|
||||
tp->autr->query_failed += 1;
|
||||
autr_write_file(env, tp);
|
||||
|
|
|
|||
2
external/unbound/validator/val_neg.c
vendored
2
external/unbound/validator/val_neg.c
vendored
|
|
@ -38,7 +38,7 @@
|
|||
*
|
||||
* This file contains helper functions for the validator module.
|
||||
* The functions help with aggressive negative caching.
|
||||
* This creates new denials of existance, and proofs for absence of types
|
||||
* This creates new denials of existence, and proofs for absence of types
|
||||
* from cached NSEC records.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
|
|
|||
2
external/unbound/validator/val_neg.h
vendored
2
external/unbound/validator/val_neg.h
vendored
|
|
@ -38,7 +38,7 @@
|
|||
*
|
||||
* This file contains helper functions for the validator module.
|
||||
* The functions help with aggressive negative caching.
|
||||
* This creates new denials of existance, and proofs for absence of types
|
||||
* This creates new denials of existence, and proofs for absence of types
|
||||
* from cached NSEC records.
|
||||
*/
|
||||
|
||||
|
|
|
|||
28
external/unbound/validator/val_nsec.c
vendored
28
external/unbound/validator/val_nsec.c
vendored
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* validator/val_nsec.c - validator NSEC denial of existance functions.
|
||||
* validator/val_nsec.c - validator NSEC denial of existence functions.
|
||||
*
|
||||
* Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||
*
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
*
|
||||
* This file contains helper functions for the validator module.
|
||||
* The functions help with NSEC checking, the different NSEC proofs
|
||||
* for denial of existance, and proofs for presence of types.
|
||||
* for denial of existence, and proofs for presence of types.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "validator/val_nsec.h"
|
||||
|
|
@ -279,7 +279,7 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
|
|||
return sec_status_insecure;
|
||||
}
|
||||
|
||||
/* NSEC proof did not conlusively point to DS or no DS */
|
||||
/* NSEC proof did not conclusively point to DS or no DS */
|
||||
return sec_status_unchecked;
|
||||
}
|
||||
|
||||
|
|
@ -340,6 +340,28 @@ int nsec_proves_nodata(struct ub_packed_rrset_key* nsec,
|
|||
*wc = ce;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
/* See if the next owner name covers a wildcard
|
||||
* empty non-terminal. */
|
||||
while (dname_strict_subdomain_c(nm, nsec->rk.dname)) {
|
||||
/* wildcard does not apply if qname below
|
||||
* the name that exists under the '*' */
|
||||
if (dname_subdomain_c(qinfo->qname, nm))
|
||||
break;
|
||||
/* but if it is a wildcard and qname is below
|
||||
* it, then the wildcard applies. The wildcard
|
||||
* is an empty nonterminal. nodata proven. */
|
||||
if (dname_is_wild(nm)) {
|
||||
size_t ce_len = ln;
|
||||
uint8_t* ce = nm;
|
||||
dname_remove_label(&ce, &ce_len);
|
||||
if(dname_strict_subdomain_c(qinfo->qname, ce)) {
|
||||
*wc = ce;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
dname_remove_label(&nm, &ln);
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, this NSEC does not prove ENT and is not a
|
||||
|
|
|
|||
6
external/unbound/validator/val_nsec.h
vendored
6
external/unbound/validator/val_nsec.h
vendored
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* validator/val_nsec.h - validator NSEC denial of existance functions.
|
||||
* validator/val_nsec.h - validator NSEC denial of existence functions.
|
||||
*
|
||||
* Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||
*
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
*
|
||||
* This file contains helper functions for the validator module.
|
||||
* The functions help with NSEC checking, the different NSEC proofs
|
||||
* for denial of existance, and proofs for presence of types.
|
||||
* for denial of existence, and proofs for presence of types.
|
||||
*/
|
||||
|
||||
#ifndef VALIDATOR_VAL_NSEC_H
|
||||
|
|
@ -54,7 +54,7 @@ struct key_entry_key;
|
|||
/**
|
||||
* Check DS absence.
|
||||
* There is a NODATA reply to a DS that needs checking.
|
||||
* NSECs can prove this is not a delegation point, or sucessfully prove
|
||||
* NSECs can prove this is not a delegation point, or successfully prove
|
||||
* that there is no DS. Or this fails.
|
||||
*
|
||||
* @param env: module env for rrsig verification routines.
|
||||
|
|
|
|||
136
external/unbound/validator/val_nsec3.c
vendored
136
external/unbound/validator/val_nsec3.c
vendored
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* validator/val_nsec3.c - validator NSEC3 denial of existance functions.
|
||||
* validator/val_nsec3.c - validator NSEC3 denial of existence functions.
|
||||
*
|
||||
* Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||
*
|
||||
|
|
@ -38,18 +38,12 @@
|
|||
*
|
||||
* This file contains helper functions for the validator module.
|
||||
* The functions help with NSEC3 checking, the different NSEC3 proofs
|
||||
* for denial of existance, and proofs for presence of types.
|
||||
* for denial of existence, and proofs for presence of types.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include "openssl/ssl.h"
|
||||
#endif
|
||||
#ifdef HAVE_NSS
|
||||
/* nss3 */
|
||||
#include "sechash.h"
|
||||
#endif
|
||||
#include "validator/val_nsec3.h"
|
||||
#include "validator/val_secalgo.h"
|
||||
#include "validator/validator.h"
|
||||
#include "validator/val_kentry.h"
|
||||
#include "services/cache/rrset.h"
|
||||
|
|
@ -370,8 +364,8 @@ filter_next(struct nsec3_filter* filter, size_t* rrsetnum, int* rrnum)
|
|||
/**
|
||||
* Start iterating over NSEC3 records.
|
||||
* @param filter: the filter structure, must have been filter_init-ed.
|
||||
* @param rrsetnum: can be undefined on call, inited.
|
||||
* @param rrnum: can be undefined on call, inited.
|
||||
* @param rrsetnum: can be undefined on call, initialised.
|
||||
* @param rrnum: can be undefined on call, initialised.
|
||||
* @return first rrset of an NSEC3, together with rrnum this points to
|
||||
* the first RR to examine. Is NULL on empty list.
|
||||
*/
|
||||
|
|
@ -545,46 +539,24 @@ nsec3_get_hashed(sldns_buffer* buf, uint8_t* nm, size_t nmlen, int algo,
|
|||
query_dname_tolower(sldns_buffer_begin(buf));
|
||||
sldns_buffer_write(buf, salt, saltlen);
|
||||
sldns_buffer_flip(buf);
|
||||
switch(algo) {
|
||||
#if defined(HAVE_EVP_SHA1) || defined(HAVE_NSS)
|
||||
case NSEC3_HASH_SHA1:
|
||||
#ifdef HAVE_SSL
|
||||
hash_len = SHA_DIGEST_LENGTH;
|
||||
#else
|
||||
hash_len = SHA1_LENGTH;
|
||||
#endif
|
||||
if(hash_len > max)
|
||||
return 0;
|
||||
# ifdef HAVE_SSL
|
||||
(void)SHA1((unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned long)sldns_buffer_limit(buf),
|
||||
(unsigned char*)res);
|
||||
# else
|
||||
(void)HASH_HashBuf(HASH_AlgSHA1, (unsigned char*)res,
|
||||
(unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned long)sldns_buffer_limit(buf));
|
||||
# endif
|
||||
for(i=0; i<iter; i++) {
|
||||
sldns_buffer_clear(buf);
|
||||
sldns_buffer_write(buf, res, hash_len);
|
||||
sldns_buffer_write(buf, salt, saltlen);
|
||||
sldns_buffer_flip(buf);
|
||||
# ifdef HAVE_SSL
|
||||
(void)SHA1(
|
||||
(unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned long)sldns_buffer_limit(buf),
|
||||
(unsigned char*)res);
|
||||
# else
|
||||
(void)HASH_HashBuf(HASH_AlgSHA1,
|
||||
(unsigned char*)res,
|
||||
(unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned long)sldns_buffer_limit(buf));
|
||||
# endif
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_EVP_SHA1 or NSS */
|
||||
default:
|
||||
log_err("nsec3 hash of unknown algo %d", algo);
|
||||
hash_len = nsec3_hash_algo_size_supported(algo);
|
||||
if(hash_len == 0) {
|
||||
log_err("nsec3 hash of unknown algo %d", algo);
|
||||
return 0;
|
||||
}
|
||||
if(hash_len > max)
|
||||
return 0;
|
||||
if(!secalgo_nsec3_hash(algo, (unsigned char*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_limit(buf), (unsigned char*)res))
|
||||
return 0;
|
||||
for(i=0; i<iter; i++) {
|
||||
sldns_buffer_clear(buf);
|
||||
sldns_buffer_write(buf, res, hash_len);
|
||||
sldns_buffer_write(buf, salt, saltlen);
|
||||
sldns_buffer_flip(buf);
|
||||
if(!secalgo_nsec3_hash(algo,
|
||||
(unsigned char*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_limit(buf), (unsigned char*)res))
|
||||
return 0;
|
||||
}
|
||||
return hash_len;
|
||||
|
|
@ -607,50 +579,24 @@ nsec3_calc_hash(struct regional* region, sldns_buffer* buf,
|
|||
query_dname_tolower(sldns_buffer_begin(buf));
|
||||
sldns_buffer_write(buf, salt, saltlen);
|
||||
sldns_buffer_flip(buf);
|
||||
switch(algo) {
|
||||
#if defined(HAVE_EVP_SHA1) || defined(HAVE_NSS)
|
||||
case NSEC3_HASH_SHA1:
|
||||
#ifdef HAVE_SSL
|
||||
c->hash_len = SHA_DIGEST_LENGTH;
|
||||
#else
|
||||
c->hash_len = SHA1_LENGTH;
|
||||
#endif
|
||||
c->hash = (uint8_t*)regional_alloc(region,
|
||||
c->hash_len);
|
||||
if(!c->hash)
|
||||
return 0;
|
||||
# ifdef HAVE_SSL
|
||||
(void)SHA1((unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned long)sldns_buffer_limit(buf),
|
||||
(unsigned char*)c->hash);
|
||||
# else
|
||||
(void)HASH_HashBuf(HASH_AlgSHA1,
|
||||
(unsigned char*)c->hash,
|
||||
(unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned long)sldns_buffer_limit(buf));
|
||||
# endif
|
||||
for(i=0; i<iter; i++) {
|
||||
sldns_buffer_clear(buf);
|
||||
sldns_buffer_write(buf, c->hash, c->hash_len);
|
||||
sldns_buffer_write(buf, salt, saltlen);
|
||||
sldns_buffer_flip(buf);
|
||||
# ifdef HAVE_SSL
|
||||
(void)SHA1(
|
||||
(unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned long)sldns_buffer_limit(buf),
|
||||
(unsigned char*)c->hash);
|
||||
# else
|
||||
(void)HASH_HashBuf(HASH_AlgSHA1,
|
||||
(unsigned char*)c->hash,
|
||||
(unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned long)sldns_buffer_limit(buf));
|
||||
# endif
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_EVP_SHA1 or NSS */
|
||||
default:
|
||||
log_err("nsec3 hash of unknown algo %d", algo);
|
||||
return -1;
|
||||
c->hash_len = nsec3_hash_algo_size_supported(algo);
|
||||
if(c->hash_len == 0) {
|
||||
log_err("nsec3 hash of unknown algo %d", algo);
|
||||
return -1;
|
||||
}
|
||||
c->hash = (uint8_t*)regional_alloc(region, c->hash_len);
|
||||
if(!c->hash)
|
||||
return 0;
|
||||
(void)secalgo_nsec3_hash(algo, (unsigned char*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_limit(buf), (unsigned char*)c->hash);
|
||||
for(i=0; i<iter; i++) {
|
||||
sldns_buffer_clear(buf);
|
||||
sldns_buffer_write(buf, c->hash, c->hash_len);
|
||||
sldns_buffer_write(buf, salt, saltlen);
|
||||
sldns_buffer_flip(buf);
|
||||
(void)secalgo_nsec3_hash(algo,
|
||||
(unsigned char*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_limit(buf), (unsigned char*)c->hash);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
6
external/unbound/validator/val_nsec3.h
vendored
6
external/unbound/validator/val_nsec3.h
vendored
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* validator/val_nsec3.h - validator NSEC3 denial of existance functions.
|
||||
* validator/val_nsec3.h - validator NSEC3 denial of existence functions.
|
||||
*
|
||||
* Copyright (c) 2007, NLnet Labs. All rights reserved.
|
||||
*
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
*
|
||||
* This file contains helper functions for the validator module.
|
||||
* The functions help with NSEC3 checking, the different NSEC3 proofs
|
||||
* for denial of existance, and proofs for presence of types.
|
||||
* for denial of existence, and proofs for presence of types.
|
||||
*
|
||||
* NSEC3
|
||||
* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
|
||||
|
|
@ -256,7 +256,7 @@ int nsec3_hash_cmp(const void* c1, const void* c2);
|
|||
* Used internally by the nsec3 proof functions in this file.
|
||||
* published to enable unit testing of hash algorithms and cache.
|
||||
*
|
||||
* @param table: the cache table. Must be inited at start.
|
||||
* @param table: the cache table. Must be initialised at start.
|
||||
* @param region: scratch region to use for allocation.
|
||||
* This region holds the tree, if you wipe the region, reinit the tree.
|
||||
* @param buf: temporary buffer.
|
||||
|
|
|
|||
520
external/unbound/validator/val_secalgo.c
vendored
520
external/unbound/validator/val_secalgo.c
vendored
|
|
@ -44,12 +44,13 @@
|
|||
/* packed_rrset on top to define enum types (forced by c99 standard) */
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "validator/val_secalgo.h"
|
||||
#include "validator/val_nsec3.h"
|
||||
#include "util/log.h"
|
||||
#include "sldns/rrdef.h"
|
||||
#include "sldns/keyraw.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
#if !defined(HAVE_SSL) && !defined(HAVE_NSS)
|
||||
#if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE)
|
||||
#error "Need crypto library to do digital signature cryptography"
|
||||
#endif
|
||||
|
||||
|
|
@ -71,10 +72,36 @@
|
|||
#include <openssl/engine.h>
|
||||
#endif
|
||||
|
||||
/* return size of digest if supported, or 0 otherwise */
|
||||
size_t
|
||||
nsec3_hash_algo_size_supported(int id)
|
||||
{
|
||||
switch(id) {
|
||||
case NSEC3_HASH_SHA1:
|
||||
return SHA_DIGEST_LENGTH;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* perform nsec3 hash. return false on failure */
|
||||
int
|
||||
secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
|
||||
unsigned char* res)
|
||||
{
|
||||
switch(algo) {
|
||||
case NSEC3_HASH_SHA1:
|
||||
(void)SHA1(buf, len, res);
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return size of DS digest according to its hash algorithm.
|
||||
* @param algo: DS digest algo.
|
||||
* @return size in bytes of digest, or 0 if not supported.
|
||||
* @return size in bytes of digest, or 0 if not supported.
|
||||
*/
|
||||
size_t
|
||||
ds_digest_size_supported(int algo)
|
||||
|
|
@ -565,6 +592,32 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
|
|||
/* nspr4 */
|
||||
#include "prerror.h"
|
||||
|
||||
/* return size of digest if supported, or 0 otherwise */
|
||||
size_t
|
||||
nsec3_hash_algo_size_supported(int id)
|
||||
{
|
||||
switch(id) {
|
||||
case NSEC3_HASH_SHA1:
|
||||
return SHA1_LENGTH;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* perform nsec3 hash. return false on failure */
|
||||
int
|
||||
secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
|
||||
unsigned char* res)
|
||||
{
|
||||
switch(algo) {
|
||||
case NSEC3_HASH_SHA1:
|
||||
(void)HASH_HashBuf(HASH_AlgSHA1, res, buf, (unsigned long)len);
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
ds_digest_size_supported(int algo)
|
||||
{
|
||||
|
|
@ -1069,5 +1122,466 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
|
|||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_NETTLE)
|
||||
|
||||
#endif /* HAVE_SSL or HAVE_NSS */
|
||||
#include "sha.h"
|
||||
#include "bignum.h"
|
||||
#include "macros.h"
|
||||
#include "rsa.h"
|
||||
#include "dsa.h"
|
||||
#include "asn1.h"
|
||||
#ifdef USE_ECDSA
|
||||
#include "ecdsa.h"
|
||||
#include "ecc-curve.h"
|
||||
#endif
|
||||
|
||||
static int
|
||||
_digest_nettle(int algo, uint8_t* buf, size_t len,
|
||||
unsigned char* res)
|
||||
{
|
||||
switch(algo) {
|
||||
case SHA1_DIGEST_SIZE:
|
||||
{
|
||||
struct sha1_ctx ctx;
|
||||
sha1_init(&ctx);
|
||||
sha1_update(&ctx, len, buf);
|
||||
sha1_digest(&ctx, SHA1_DIGEST_SIZE, res);
|
||||
return 1;
|
||||
}
|
||||
case SHA256_DIGEST_SIZE:
|
||||
{
|
||||
struct sha256_ctx ctx;
|
||||
sha256_init(&ctx);
|
||||
sha256_update(&ctx, len, buf);
|
||||
sha256_digest(&ctx, SHA256_DIGEST_SIZE, res);
|
||||
return 1;
|
||||
}
|
||||
case SHA384_DIGEST_SIZE:
|
||||
{
|
||||
struct sha384_ctx ctx;
|
||||
sha384_init(&ctx);
|
||||
sha384_update(&ctx, len, buf);
|
||||
sha384_digest(&ctx, SHA384_DIGEST_SIZE, res);
|
||||
return 1;
|
||||
}
|
||||
case SHA512_DIGEST_SIZE:
|
||||
{
|
||||
struct sha512_ctx ctx;
|
||||
sha512_init(&ctx);
|
||||
sha512_update(&ctx, len, buf);
|
||||
sha512_digest(&ctx, SHA512_DIGEST_SIZE, res);
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return size of digest if supported, or 0 otherwise */
|
||||
size_t
|
||||
nsec3_hash_algo_size_supported(int id)
|
||||
{
|
||||
switch(id) {
|
||||
case NSEC3_HASH_SHA1:
|
||||
return SHA1_DIGEST_SIZE;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* perform nsec3 hash. return false on failure */
|
||||
int
|
||||
secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
|
||||
unsigned char* res)
|
||||
{
|
||||
switch(algo) {
|
||||
case NSEC3_HASH_SHA1:
|
||||
return _digest_nettle(SHA1_DIGEST_SIZE, (uint8_t*)buf, len,
|
||||
res);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return size of DS digest according to its hash algorithm.
|
||||
* @param algo: DS digest algo.
|
||||
* @return size in bytes of digest, or 0 if not supported.
|
||||
*/
|
||||
size_t
|
||||
ds_digest_size_supported(int algo)
|
||||
{
|
||||
switch(algo) {
|
||||
case LDNS_SHA1:
|
||||
return SHA1_DIGEST_SIZE;
|
||||
#ifdef USE_SHA2
|
||||
case LDNS_SHA256:
|
||||
return SHA256_DIGEST_SIZE;
|
||||
#endif
|
||||
#ifdef USE_ECDSA
|
||||
case LDNS_SHA384:
|
||||
return SHA384_DIGEST_SIZE;
|
||||
#endif
|
||||
/* GOST not supported */
|
||||
case LDNS_HASH_GOST:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
|
||||
unsigned char* res)
|
||||
{
|
||||
switch(algo) {
|
||||
case LDNS_SHA1:
|
||||
return _digest_nettle(SHA1_DIGEST_SIZE, buf, len, res);
|
||||
#if defined(USE_SHA2)
|
||||
case LDNS_SHA256:
|
||||
return _digest_nettle(SHA256_DIGEST_SIZE, buf, len, res);
|
||||
#endif
|
||||
#ifdef USE_ECDSA
|
||||
case LDNS_SHA384:
|
||||
return _digest_nettle(SHA384_DIGEST_SIZE, buf, len, res);
|
||||
|
||||
#endif
|
||||
case LDNS_HASH_GOST:
|
||||
default:
|
||||
verbose(VERB_QUERY, "unknown DS digest algorithm %d",
|
||||
algo);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dnskey_algo_id_is_supported(int id)
|
||||
{
|
||||
/* uses libnettle */
|
||||
switch(id) {
|
||||
case LDNS_DSA:
|
||||
case LDNS_DSA_NSEC3:
|
||||
case LDNS_RSASHA1:
|
||||
case LDNS_RSASHA1_NSEC3:
|
||||
#ifdef USE_SHA2
|
||||
case LDNS_RSASHA256:
|
||||
case LDNS_RSASHA512:
|
||||
#endif
|
||||
#ifdef USE_ECDSA
|
||||
case LDNS_ECDSAP256SHA256:
|
||||
case LDNS_ECDSAP384SHA384:
|
||||
#endif
|
||||
return 1;
|
||||
case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */
|
||||
case LDNS_ECC_GOST:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
_verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock,
|
||||
unsigned int sigblock_len, unsigned char* key, unsigned int keylen)
|
||||
{
|
||||
uint8_t digest[SHA1_DIGEST_SIZE];
|
||||
uint8_t key_t;
|
||||
int res = 0;
|
||||
size_t offset;
|
||||
struct dsa_public_key pubkey;
|
||||
struct dsa_signature signature;
|
||||
unsigned int expected_len;
|
||||
|
||||
/* Extract DSA signature from the record */
|
||||
nettle_dsa_signature_init(&signature);
|
||||
/* Signature length: 41 bytes - RFC 2536 sec. 3 */
|
||||
if(sigblock_len == 41) {
|
||||
if(key[0] != sigblock[0])
|
||||
return "invalid T value in DSA signature or pubkey";
|
||||
nettle_mpz_set_str_256_u(signature.r, 20, sigblock+1);
|
||||
nettle_mpz_set_str_256_u(signature.s, 20, sigblock+1+20);
|
||||
} else {
|
||||
/* DER encoded, decode the ASN1 notated R and S bignums */
|
||||
/* SEQUENCE { r INTEGER, s INTEGER } */
|
||||
struct asn1_der_iterator i, seq;
|
||||
if(asn1_der_iterator_first(&i, sigblock_len,
|
||||
(uint8_t*)sigblock) != ASN1_ITERATOR_CONSTRUCTED
|
||||
|| i.type != ASN1_SEQUENCE)
|
||||
return "malformed DER encoded DSA signature";
|
||||
/* decode this element of i using the seq iterator */
|
||||
if(asn1_der_decode_constructed(&i, &seq) !=
|
||||
ASN1_ITERATOR_PRIMITIVE || seq.type != ASN1_INTEGER)
|
||||
return "malformed DER encoded DSA signature";
|
||||
if(!asn1_der_get_bignum(&seq, signature.r, 20*8))
|
||||
return "malformed DER encoded DSA signature";
|
||||
if(asn1_der_iterator_next(&seq) != ASN1_ITERATOR_PRIMITIVE
|
||||
|| seq.type != ASN1_INTEGER)
|
||||
return "malformed DER encoded DSA signature";
|
||||
if(!asn1_der_get_bignum(&seq, signature.s, 20*8))
|
||||
return "malformed DER encoded DSA signature";
|
||||
if(asn1_der_iterator_next(&i) != ASN1_ITERATOR_END)
|
||||
return "malformed DER encoded DSA signature";
|
||||
}
|
||||
|
||||
/* Validate T values constraints - RFC 2536 sec. 2 & sec. 3 */
|
||||
key_t = key[0];
|
||||
if (key_t > 8) {
|
||||
return "invalid T value in DSA pubkey";
|
||||
}
|
||||
|
||||
/* Pubkey minimum length: 21 bytes - RFC 2536 sec. 2 */
|
||||
if (keylen < 21) {
|
||||
return "DSA pubkey too short";
|
||||
}
|
||||
|
||||
expected_len = 1 + /* T */
|
||||
20 + /* Q */
|
||||
(64 + key_t*8) + /* P */
|
||||
(64 + key_t*8) + /* G */
|
||||
(64 + key_t*8); /* Y */
|
||||
if (keylen != expected_len ) {
|
||||
return "invalid DSA pubkey length";
|
||||
}
|
||||
|
||||
/* Extract DSA pubkey from the record */
|
||||
nettle_dsa_public_key_init(&pubkey);
|
||||
offset = 1;
|
||||
nettle_mpz_set_str_256_u(pubkey.q, 20, key+offset);
|
||||
offset += 20;
|
||||
nettle_mpz_set_str_256_u(pubkey.p, (64 + key_t*8), key+offset);
|
||||
offset += (64 + key_t*8);
|
||||
nettle_mpz_set_str_256_u(pubkey.g, (64 + key_t*8), key+offset);
|
||||
offset += (64 + key_t*8);
|
||||
nettle_mpz_set_str_256_u(pubkey.y, (64 + key_t*8), key+offset);
|
||||
|
||||
/* Digest content of "buf" and verify its DSA signature in "sigblock"*/
|
||||
res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
|
||||
res &= dsa_sha1_verify_digest(&pubkey, digest, &signature);
|
||||
|
||||
/* Clear and return */
|
||||
nettle_dsa_signature_clear(&signature);
|
||||
nettle_dsa_public_key_clear(&pubkey);
|
||||
if (!res)
|
||||
return "DSA signature verification failed";
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
_verify_nettle_rsa(sldns_buffer* buf, unsigned int digest_size, char* sigblock,
|
||||
unsigned int sigblock_len, uint8_t* key, unsigned int keylen)
|
||||
{
|
||||
uint16_t exp_len = 0;
|
||||
size_t exp_offset = 0, mod_offset = 0;
|
||||
struct rsa_public_key pubkey;
|
||||
mpz_t signature;
|
||||
int res = 0;
|
||||
|
||||
/* RSA pubkey parsing as per RFC 3110 sec. 2 */
|
||||
if( keylen <= 1) {
|
||||
return "null RSA key";
|
||||
}
|
||||
if (key[0] != 0) {
|
||||
/* 1-byte length */
|
||||
exp_len = key[0];
|
||||
exp_offset = 1;
|
||||
} else {
|
||||
/* 1-byte NUL + 2-bytes exponent length */
|
||||
if (keylen < 3) {
|
||||
return "incorrect RSA key length";
|
||||
}
|
||||
exp_len = READ_UINT16(key+1);
|
||||
if (exp_len == 0)
|
||||
return "null RSA exponent length";
|
||||
exp_offset = 3;
|
||||
}
|
||||
/* Check that we are not over-running input length */
|
||||
if (keylen < exp_offset + exp_len + 1) {
|
||||
return "RSA key content shorter than expected";
|
||||
}
|
||||
mod_offset = exp_offset + exp_len;
|
||||
nettle_rsa_public_key_init(&pubkey);
|
||||
pubkey.size = keylen - mod_offset;
|
||||
nettle_mpz_set_str_256_u(pubkey.e, exp_len, &key[exp_offset]);
|
||||
nettle_mpz_set_str_256_u(pubkey.n, pubkey.size, &key[mod_offset]);
|
||||
|
||||
/* Digest content of "buf" and verify its RSA signature in "sigblock"*/
|
||||
nettle_mpz_init_set_str_256_u(signature, sigblock_len, (uint8_t*)sigblock);
|
||||
switch (digest_size) {
|
||||
case SHA1_DIGEST_SIZE:
|
||||
{
|
||||
uint8_t digest[SHA1_DIGEST_SIZE];
|
||||
res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
|
||||
res &= rsa_sha1_verify_digest(&pubkey, digest, signature);
|
||||
break;
|
||||
}
|
||||
case SHA256_DIGEST_SIZE:
|
||||
{
|
||||
uint8_t digest[SHA256_DIGEST_SIZE];
|
||||
res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
|
||||
res &= rsa_sha256_verify_digest(&pubkey, digest, signature);
|
||||
break;
|
||||
}
|
||||
case SHA512_DIGEST_SIZE:
|
||||
{
|
||||
uint8_t digest[SHA512_DIGEST_SIZE];
|
||||
res = _digest_nettle(SHA512_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
|
||||
res &= rsa_sha512_verify_digest(&pubkey, digest, signature);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear and return */
|
||||
nettle_rsa_public_key_clear(&pubkey);
|
||||
mpz_clear(signature);
|
||||
if (!res) {
|
||||
return "RSA signature verification failed";
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_ECDSA
|
||||
static char *
|
||||
_verify_nettle_ecdsa(sldns_buffer* buf, unsigned int digest_size, unsigned char* sigblock,
|
||||
unsigned int sigblock_len, unsigned char* key, unsigned int keylen)
|
||||
{
|
||||
int res = 0;
|
||||
struct ecc_point pubkey;
|
||||
struct dsa_signature signature;
|
||||
|
||||
/* Always matched strength, as per RFC 6605 sec. 1 */
|
||||
if (sigblock_len != 2*digest_size || keylen != 2*digest_size) {
|
||||
return "wrong ECDSA signature length";
|
||||
}
|
||||
|
||||
/* Parse ECDSA signature as per RFC 6605 sec. 4 */
|
||||
nettle_dsa_signature_init(&signature);
|
||||
switch (digest_size) {
|
||||
case SHA256_DIGEST_SIZE:
|
||||
{
|
||||
uint8_t digest[SHA256_DIGEST_SIZE];
|
||||
mpz_t x, y;
|
||||
nettle_ecc_point_init(&pubkey, &nettle_secp_256r1);
|
||||
nettle_mpz_init_set_str_256_u(x, SHA256_DIGEST_SIZE, key);
|
||||
nettle_mpz_init_set_str_256_u(y, SHA256_DIGEST_SIZE, key+SHA256_DIGEST_SIZE);
|
||||
nettle_mpz_set_str_256_u(signature.r, SHA256_DIGEST_SIZE, sigblock);
|
||||
nettle_mpz_set_str_256_u(signature.s, SHA256_DIGEST_SIZE, sigblock+SHA256_DIGEST_SIZE);
|
||||
res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
|
||||
res &= nettle_ecc_point_set(&pubkey, x, y);
|
||||
res &= nettle_ecdsa_verify (&pubkey, SHA256_DIGEST_SIZE, digest, &signature);
|
||||
mpz_clear(x);
|
||||
mpz_clear(y);
|
||||
break;
|
||||
}
|
||||
case SHA384_DIGEST_SIZE:
|
||||
{
|
||||
uint8_t digest[SHA384_DIGEST_SIZE];
|
||||
mpz_t x, y;
|
||||
nettle_ecc_point_init(&pubkey, &nettle_secp_384r1);
|
||||
nettle_mpz_init_set_str_256_u(x, SHA384_DIGEST_SIZE, key);
|
||||
nettle_mpz_init_set_str_256_u(y, SHA384_DIGEST_SIZE, key+SHA384_DIGEST_SIZE);
|
||||
nettle_mpz_set_str_256_u(signature.r, SHA384_DIGEST_SIZE, sigblock);
|
||||
nettle_mpz_set_str_256_u(signature.s, SHA384_DIGEST_SIZE, sigblock+SHA384_DIGEST_SIZE);
|
||||
res = _digest_nettle(SHA384_DIGEST_SIZE, (unsigned char*)sldns_buffer_begin(buf),
|
||||
(unsigned int)sldns_buffer_limit(buf), (unsigned char*)digest);
|
||||
res &= nettle_ecc_point_set(&pubkey, x, y);
|
||||
res &= nettle_ecdsa_verify (&pubkey, SHA384_DIGEST_SIZE, digest, &signature);
|
||||
mpz_clear(x);
|
||||
mpz_clear(y);
|
||||
nettle_ecc_point_clear(&pubkey);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return "unknown ECDSA algorithm";
|
||||
}
|
||||
|
||||
/* Clear and return */
|
||||
nettle_dsa_signature_clear(&signature);
|
||||
if (!res)
|
||||
return "ECDSA signature verification failed";
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Check a canonical sig+rrset and signature against a dnskey
|
||||
* @param buf: buffer with data to verify, the first rrsig part and the
|
||||
* canonicalized rrset.
|
||||
* @param algo: DNSKEY algorithm.
|
||||
* @param sigblock: signature rdata field from RRSIG
|
||||
* @param sigblock_len: length of sigblock data.
|
||||
* @param key: public key data from DNSKEY RR.
|
||||
* @param keylen: length of keydata.
|
||||
* @param reason: bogus reason in more detail.
|
||||
* @return secure if verification succeeded, bogus on crypto failure,
|
||||
* unchecked on format errors and alloc failures.
|
||||
*/
|
||||
enum sec_status
|
||||
verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
|
||||
unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
|
||||
char** reason)
|
||||
{
|
||||
unsigned int digest_size = 0;
|
||||
|
||||
if (sigblock_len == 0 || keylen == 0) {
|
||||
*reason = "null signature";
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
switch(algo) {
|
||||
case LDNS_DSA:
|
||||
case LDNS_DSA_NSEC3:
|
||||
*reason = _verify_nettle_dsa(buf, sigblock, sigblock_len, key, keylen);
|
||||
if (*reason != NULL)
|
||||
return sec_status_bogus;
|
||||
else
|
||||
return sec_status_secure;
|
||||
|
||||
case LDNS_RSASHA1:
|
||||
case LDNS_RSASHA1_NSEC3:
|
||||
digest_size = (digest_size ? digest_size : SHA1_DIGEST_SIZE);
|
||||
#ifdef USE_SHA2
|
||||
case LDNS_RSASHA256:
|
||||
digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
|
||||
case LDNS_RSASHA512:
|
||||
digest_size = (digest_size ? digest_size : SHA512_DIGEST_SIZE);
|
||||
|
||||
#endif
|
||||
*reason = _verify_nettle_rsa(buf, digest_size, (char*)sigblock,
|
||||
sigblock_len, key, keylen);
|
||||
if (*reason != NULL)
|
||||
return sec_status_bogus;
|
||||
else
|
||||
return sec_status_secure;
|
||||
|
||||
#ifdef USE_ECDSA
|
||||
case LDNS_ECDSAP256SHA256:
|
||||
digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
|
||||
case LDNS_ECDSAP384SHA384:
|
||||
digest_size = (digest_size ? digest_size : SHA384_DIGEST_SIZE);
|
||||
*reason = _verify_nettle_ecdsa(buf, digest_size, sigblock,
|
||||
sigblock_len, key, keylen);
|
||||
if (*reason != NULL)
|
||||
return sec_status_bogus;
|
||||
else
|
||||
return sec_status_secure;
|
||||
#endif
|
||||
case LDNS_RSAMD5:
|
||||
case LDNS_ECC_GOST:
|
||||
default:
|
||||
*reason = "unable to verify signature, unknown algorithm";
|
||||
return sec_status_bogus;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_SSL or HAVE_NSS or HAVE_NETTLE */
|
||||
|
|
|
|||
15
external/unbound/validator/val_secalgo.h
vendored
15
external/unbound/validator/val_secalgo.h
vendored
|
|
@ -44,6 +44,21 @@
|
|||
#define VALIDATOR_VAL_SECALGO_H
|
||||
struct sldns_buffer;
|
||||
|
||||
/** Return size of nsec3 hash algorithm, 0 if not supported */
|
||||
size_t nsec3_hash_algo_size_supported(int id);
|
||||
|
||||
/**
|
||||
* Hash a single hash call of an NSEC3 hash algorithm.
|
||||
* Iterations and salt are done by the caller.
|
||||
* @param algo: nsec3 hash algorithm.
|
||||
* @param buf: the buffer to digest
|
||||
* @param len: length of buffer to digest.
|
||||
* @param res: result stored here (must have sufficient space).
|
||||
* @return false on failure.
|
||||
*/
|
||||
int secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
|
||||
unsigned char* res);
|
||||
|
||||
/**
|
||||
* Return size of DS digest according to its hash algorithm.
|
||||
* @param algo: DS digest algo.
|
||||
|
|
|
|||
6
external/unbound/validator/val_sigcrypt.c
vendored
6
external/unbound/validator/val_sigcrypt.c
vendored
|
|
@ -57,7 +57,7 @@
|
|||
#include "sldns/wire2str.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#if !defined(HAVE_SSL) && !defined(HAVE_NSS)
|
||||
#if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE)
|
||||
#error "Need crypto library to do digital signature cryptography"
|
||||
#endif
|
||||
|
||||
|
|
@ -795,10 +795,6 @@ canonical_compare(struct ub_packed_rrset_key* rrset, size_t i, size_t j)
|
|||
|
||||
if(i==j)
|
||||
return 0;
|
||||
/* in case rdata-len is to be compared for canonical order
|
||||
c = memcmp(d->rr_data[i], d->rr_data[j], 2);
|
||||
if(c != 0)
|
||||
return c; */
|
||||
|
||||
switch(type) {
|
||||
/* These RR types have only a name as RDATA.
|
||||
|
|
|
|||
2
external/unbound/validator/val_utils.h
vendored
2
external/unbound/validator/val_utils.h
vendored
|
|
@ -391,7 +391,7 @@ int val_favorite_ds_algo(struct ub_packed_rrset_key* ds_rrset);
|
|||
* Find DS denial message in cache. Saves new qstate allocation and allows
|
||||
* the validator to use partial content which is not enough to construct a
|
||||
* message for network (or user) consumption. Without SOA for example,
|
||||
* which is a common occurence in the unbound code since the referrals contain
|
||||
* which is a common occurrence in the unbound code since the referrals contain
|
||||
* NSEC/NSEC3 rrs without the SOA element, thus do not allow synthesis of a
|
||||
* full negative reply, but do allow synthesis of sufficient proof.
|
||||
* @param env: query env with caches and time.
|
||||
|
|
|
|||
6
external/unbound/validator/validator.c
vendored
6
external/unbound/validator/validator.c
vendored
|
|
@ -749,7 +749,7 @@ validate_nodata_response(struct module_env* env, struct val_env* ve,
|
|||
/* Since we are here, there must be nothing in the ANSWER section to
|
||||
* validate. */
|
||||
/* (Note: CNAME/DNAME responses will not directly get here --
|
||||
* instead, they are chased down into indiviual CNAME validations,
|
||||
* instead, they are chased down into individual CNAME validations,
|
||||
* and at the end of the cname chain a POSITIVE, or CNAME_NOANSWER
|
||||
* validation.) */
|
||||
|
||||
|
|
@ -1597,7 +1597,7 @@ processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id)
|
|||
target_key_name) != 0) {
|
||||
/* check if there is a cache entry : pick up an NSEC if
|
||||
* there is no DS, check if that NSEC has DS-bit unset, and
|
||||
* thus can disprove the secure delagation we seek.
|
||||
* thus can disprove the secure delegation we seek.
|
||||
* We can then use that NSEC even in the absence of a SOA
|
||||
* record that would be required by the iterator to supply
|
||||
* a completely protocol-correct response.
|
||||
|
|
@ -1829,7 +1829,7 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
|||
* @return true if there is no DLV.
|
||||
* false: processing is finished for the validator operate().
|
||||
* This function may exit in three ways:
|
||||
* o no DLV (agressive cache), so insecure. (true)
|
||||
* o no DLV (aggressive cache), so insecure. (true)
|
||||
* o error - stop processing (false)
|
||||
* o DLV lookup was started, stop processing (false)
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue