diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c index 762fcee..7bcbc50 100644 --- a/lib/dns/hmac_link.c +++ b/lib/dns/hmac_link.c @@ -211,6 +211,8 @@ hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) { key->key_size = keylen * 8; key->opaque = hkey; + isc_buffer_forward(data, r.length); + return (ISC_R_SUCCESS); } diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h index 44ac18c..1d0b08a 100644 --- a/lib/dns/include/dst/dst.h +++ b/lib/dns/include/dst/dst.h @@ -51,6 +51,7 @@ typedef struct dst_context dst_context_t; #define DST_ALG_RSASHA1 5 #define DST_ALG_HMACMD5 157 #define DST_ALG_GSSAPI 160 +#define DST_ALG_INDIRECT 252 #define DST_ALG_PRIVATE 254 #define DST_ALG_EXPAND 255 #define DST_MAX_ALGS 255 diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c index 1138855..3f76a49 100644 --- a/lib/dns/openssldh_link.c +++ b/lib/dns/openssldh_link.c @@ -221,8 +221,10 @@ openssldh_destroy(dst_key_t *key) { static void uint16_toregion(isc_uint16_t val, isc_region_t *region) { - *region->base++ = (val & 0xff00) >> 8; - *region->base++ = (val & 0x00ff); + *region->base = (val & 0xff00) >> 8; + isc_region_consume(region, 1); + *region->base = (val & 0x00ff); + isc_region_consume(region, 1); } static isc_uint16_t @@ -233,7 +235,8 @@ uint16_fromregion(isc_region_t *region) { val = ((unsigned int)(cp[0])) << 8; val |= ((unsigned int)(cp[1])); - region->base += 2; + isc_region_consume(region, 2); + return (val); } @@ -274,16 +277,16 @@ openssldh_todns(const dst_key_t *key, isc_buffer_t *data) { } else BN_bn2bin(dh->p, r.base); - r.base += plen; + isc_region_consume(&r, plen); uint16_toregion(glen, &r); if (glen > 0) BN_bn2bin(dh->g, r.base); - r.base += glen; + isc_region_consume(&r, glen); uint16_toregion(publen, &r); BN_bn2bin(dh->pub_key, r.base); - r.base += publen; + isc_region_consume(&r, publen); isc_buffer_add(data, dnslen); @@ -324,10 +327,12 @@ openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) { return (DST_R_INVALIDPUBLICKEY); } if (plen == 1 || plen == 2) { - if (plen == 1) - special = *r.base++; - else + if (plen == 1) { + special = *r.base; + isc_region_consume(&r, 1); + } else { special = uint16_fromregion(&r); + } switch (special) { case 1: dh->p = &bn768; @@ -345,7 +350,7 @@ openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) { } else { dh->p = BN_bin2bn(r.base, plen, NULL); - r.base += plen; + isc_region_consume(&r, plen); } /* @@ -384,7 +389,7 @@ openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) { } dh->g = BN_bin2bn(r.base, glen, NULL); } - r.base += glen; + isc_region_consume(&r, glen); if (r.length < 2) { DH_free(dh); @@ -396,7 +401,7 @@ openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) { return (DST_R_INVALIDPUBLICKEY); } dh->pub_key = BN_bin2bn(r.base, publen, NULL); - r.base += publen; + isc_region_consume(&r, publen); key->key_size = BN_num_bits(dh->p); diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c index fbfcfba..0498f4a 100644 --- a/lib/dns/openssldsa_link.c +++ b/lib/dns/openssldsa_link.c @@ -85,6 +85,7 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { dst_key_t *key = dctx->key; DSA *dsa = key->opaque; DSA_SIG *dsasig; + unsigned int klen; isc_region_t r; unsigned char digest[ISC_SHA1_DIGESTLENGTH]; @@ -98,11 +99,16 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { if (dsasig == NULL) return (dst__openssl_toresult(DST_R_SIGNFAILURE)); - *r.base++ = (key->key_size - 512)/64; + klen = (key->key_size - 512)/64; + if (klen > 255) + return (ISC_R_FAILURE); + *r.base = klen; + isc_region_consume(&r, 1); + BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH); - r.base += ISC_SHA1_DIGESTLENGTH; + isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH); - r.base += ISC_SHA1_DIGESTLENGTH; + isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); DSA_SIG_free(dsasig); isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); @@ -254,15 +260,16 @@ openssldsa_todns(const dst_key_t *key, isc_buffer_t *data) { if (r.length < (unsigned int) dnslen) return (ISC_R_NOSPACE); - *r.base++ = t; + *r.base = t; + isc_region_consume(&r, 1); BN_bn2bin_fixed(dsa->q, r.base, ISC_SHA1_DIGESTLENGTH); - r.base += ISC_SHA1_DIGESTLENGTH; + isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8); - r.base += p_bytes; + isc_region_consume(&r, p_bytes); BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8); - r.base += p_bytes; + isc_region_consume(&r, p_bytes); BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8); - r.base += p_bytes; + isc_region_consume(&r, p_bytes); isc_buffer_add(data, dnslen); @@ -287,29 +294,30 @@ openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) { return (ISC_R_NOMEMORY); dsa->flags &= ~DSA_FLAG_CACHE_MONT_P; - t = (unsigned int) *r.base++; + t = (unsigned int) *r.base; + isc_region_consume(&r, 1); if (t > 8) { DSA_free(dsa); return (DST_R_INVALIDPUBLICKEY); } p_bytes = 64 + 8 * t; - if (r.length < 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { + if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { DSA_free(dsa); return (DST_R_INVALIDPUBLICKEY); } dsa->q = BN_bin2bn(r.base, ISC_SHA1_DIGESTLENGTH, NULL); - r.base += ISC_SHA1_DIGESTLENGTH; + isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); dsa->p = BN_bin2bn(r.base, p_bytes, NULL); - r.base += p_bytes; + isc_region_consume(&r, p_bytes); dsa->g = BN_bin2bn(r.base, p_bytes, NULL); - r.base += p_bytes; + isc_region_consume(&r, p_bytes); dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL); - r.base += p_bytes; + isc_region_consume(&r, p_bytes); key->key_size = p_bytes * 8; diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c index 765d9ed..74e7ee1 100644 --- a/lib/dns/opensslrsa_link.c +++ b/lib/dns/opensslrsa_link.c @@ -396,10 +396,12 @@ opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) { RSA *rsa; isc_region_t r; unsigned int e_bytes; + unsigned int length; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); + length = r.length; rsa = RSA_new(); if (rsa == NULL) @@ -410,17 +412,18 @@ opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } - e_bytes = *r.base++; - r.length--; + e_bytes = *r.base; + isc_region_consume(&r, 1); if (e_bytes == 0) { if (r.length < 2) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } - e_bytes = ((*r.base++) << 8); - e_bytes += *r.base++; - r.length -= 2; + e_bytes = (*r.base) << 8; + isc_region_consume(&r, 1); + e_bytes += *r.base; + isc_region_consume(&r, 1); } if (r.length < e_bytes) { @@ -428,14 +431,13 @@ opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) { return (DST_R_INVALIDPUBLICKEY); } rsa->e = BN_bin2bn(r.base, e_bytes, NULL); - r.base += e_bytes; - r.length -= e_bytes; + isc_region_consume(&r, e_bytes); rsa->n = BN_bin2bn(r.base, r.length, NULL); key->key_size = BN_num_bits(rsa->n); - isc_buffer_forward(data, r.length); + isc_buffer_forward(data, length); key->opaque = (void *) rsa; diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 711b862..b0f982e 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -6822,6 +6822,12 @@ dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name, REQUIRE(VALID_RESOLVER(resolver)); + /* + * DH is unsupported for DNSKEYs, see RFC 4034 sec. A.1. + */ + if ((alg == DST_ALG_DH) || (alg == DST_ALG_INDIRECT)) + return (ISC_FALSE); + #if USE_ALGLOCK RWLOCK(&resolver->alglock, isc_rwlocktype_read); #endif