]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] address buffer accounting error
authorEvan Hunt <each@isc.org>
Fri, 7 Aug 2015 20:16:10 +0000 (13:16 -0700)
committerEvan Hunt <each@isc.org>
Fri, 7 Aug 2015 20:16:10 +0000 (13:16 -0700)
4168. [security] A buffer accounting error could trigger an
assertion failure when parsing certain malformed
DNSSEC keys. (CVE-2015-5722) [RT #40212]

14 files changed:
CHANGES
README
doc/arm/notes.xml
lib/dns/hmac_link.c
lib/dns/include/dst/dst.h
lib/dns/ncache.c
lib/dns/openssldh_link.c
lib/dns/openssldsa_link.c
lib/dns/opensslecdsa_link.c
lib/dns/opensslrsa_link.c
lib/dns/pkcs11dh_link.c
lib/dns/pkcs11dsa_link.c
lib/dns/pkcs11rsa_link.c
lib/dns/resolver.c

diff --git a/CHANGES b/CHANGES
index 75f15c625e36879f5441334ee359e3d305508ace..2f20d3acb8c282d09c8cb8f694443999b19dd2db 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+4168.  [security]      A buffer accounting error could trigger an
+                       assertion failure when parsing certain malformed 
+                       DNSSEC keys. (CVE-2015-5722) [RT #40212]
+
 4167.  [func]          Update rndc's usage output to include recently added
                        commands. Thanks to Tony Finch for submitting a
                        patch. [RT #40010]
diff --git a/README b/README
index 67982136e21b6aa010d99e162945802be3e9e26c..a40dc5d15bf7d6f842e3cd308c5490aefa494573 100644 (file)
--- a/README
+++ b/README
@@ -119,7 +119,7 @@ BIND 9.11.0
 
        This release addresses the security flaws described in
        CVE-2014-3214, CVE-2014-3859, CVE-2014-8500, CVE-2014-8680,
-       CVE-2015-1349 and CVE-2015-5477.
+       CVE-2015-1349, CVE-2015-5477 and CVE-2015-5722.
 
 BIND 9.10.0
 
index 8b3237e94f9ed49e91445dda03ac6544dafa2c77..1f6ca5b8576d9f8bb2708ec5a6e1d83f756aaab1 100644 (file)
   <sect2 id="relnotes_security">
     <title>Security Fixes</title>
     <itemizedlist>
+      <listitem>
+       <para>
+         A buffer accounting error could trigger an assertion failure
+         when parsing certain malformed DNSSEC keys.
+       </para>
+       <para>
+         This flaw was discovered by Hanno B&ouml;ck of the Fuzzing
+         Project, and is disclosed in CVE-2015-5722. [RT #40212]
+       </para>
+      </listitem>
       <listitem>
        <para>
          A specially crafted query could trigger an assertion failure
-         in message.c
+         in message.c.
        </para>
        <para>
          This flaw was discovered by Jonathan Foote, and is disclosed
index 01876d336ab588dcd05b386c712f48c25b243c23..b1ef314e4e6c63ac777154ec21bc83abe6dfc670 100644 (file)
@@ -76,7 +76,7 @@ hmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) {
        hmacmd5ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacmd5_t));
        if (hmacmd5ctx == NULL)
                return (ISC_R_NOMEMORY);
-       isc_hmacmd5_init(hmacmd5ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH);
+       isc_hmacmd5_init(hmacmd5ctx, hkey->key, ISC_MD5_BLOCK_LENGTH);
        dctx->ctxdata.hmacmd5ctx = hmacmd5ctx;
        return (ISC_R_SUCCESS);
 }
@@ -139,7 +139,7 @@ hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) {
        else if (hkey1 == NULL || hkey2 == NULL)
                return (ISC_FALSE);
 
-       if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH))
+       if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_MD5_BLOCK_LENGTH))
                return (ISC_TRUE);
        else
                return (ISC_FALSE);
@@ -150,17 +150,17 @@ hmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) {
        isc_buffer_t b;
        isc_result_t ret;
        unsigned int bytes;
-       unsigned char data[ISC_SHA1_BLOCK_LENGTH];
+       unsigned char data[ISC_MD5_BLOCK_LENGTH];
 
        UNUSED(callback);
 
        bytes = (key->key_size + 7) / 8;
-       if (bytes > ISC_SHA1_BLOCK_LENGTH) {
-               bytes = ISC_SHA1_BLOCK_LENGTH;
-               key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
+       if (bytes > ISC_MD5_BLOCK_LENGTH) {
+               bytes = ISC_MD5_BLOCK_LENGTH;
+               key->key_size = ISC_MD5_BLOCK_LENGTH * 8;
        }
 
-       memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
+       memset(data, 0, ISC_MD5_BLOCK_LENGTH);
        ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
 
        if (ret != ISC_R_SUCCESS)
@@ -169,7 +169,7 @@ hmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) {
        isc_buffer_init(&b, data, bytes);
        isc_buffer_add(&b, bytes);
        ret = hmacmd5_fromdns(key, &b);
-       memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
+       memset(data, 0, ISC_MD5_BLOCK_LENGTH);
 
        return (ret);
 }
@@ -223,7 +223,7 @@ hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
 
        memset(hkey->key, 0, sizeof(hkey->key));
 
-       if (r.length > ISC_SHA1_BLOCK_LENGTH) {
+       if (r.length > ISC_MD5_BLOCK_LENGTH) {
                isc_md5_init(&md5ctx);
                isc_md5_update(&md5ctx, r.base, r.length);
                isc_md5_final(&md5ctx, hkey->key);
@@ -236,6 +236,8 @@ hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
        key->key_size = keylen * 8;
        key->keydata.hmacmd5 = hkey;
 
+       isc_buffer_forward(data, r.length);
+
        return (ISC_R_SUCCESS);
 }
 
@@ -519,6 +521,8 @@ hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
        key->key_size = keylen * 8;
        key->keydata.hmacsha1 = hkey;
 
+       isc_buffer_forward(data, r.length);
+
        return (ISC_R_SUCCESS);
 }
 
@@ -804,6 +808,8 @@ hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
        key->key_size = keylen * 8;
        key->keydata.hmacsha224 = hkey;
 
+       isc_buffer_forward(data, r.length);
+
        return (ISC_R_SUCCESS);
 }
 
@@ -1089,6 +1095,8 @@ hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
        key->key_size = keylen * 8;
        key->keydata.hmacsha256 = hkey;
 
+       isc_buffer_forward(data, r.length);
+
        return (ISC_R_SUCCESS);
 }
 
@@ -1374,6 +1382,8 @@ hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
        key->key_size = keylen * 8;
        key->keydata.hmacsha384 = hkey;
 
+       isc_buffer_forward(data, r.length);
+
        return (ISC_R_SUCCESS);
 }
 
@@ -1659,6 +1669,8 @@ hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
        key->key_size = keylen * 8;
        key->keydata.hmacsha512 = hkey;
 
+       isc_buffer_forward(data, r.length);
+
        return (ISC_R_SUCCESS);
 }
 
index 080b405480bb497d38fc27b773660f843f890b30..df81b398c79a9b510cf396c9cd4c40efee0fd985 100644 (file)
@@ -69,6 +69,7 @@ typedef struct dst_context    dst_context_t;
 #define DST_ALG_HMACSHA256     163     /* XXXMPA */
 #define DST_ALG_HMACSHA384     164     /* XXXMPA */
 #define DST_ALG_HMACSHA512     165     /* XXXMPA */
+#define DST_ALG_INDIRECT       252
 #define DST_ALG_PRIVATE                254
 #define DST_ALG_EXPAND         255
 #define DST_MAX_ALGS           255
index de9f5f4c2d0cac7b37fa2c82726af688a69e5323..9252762a01b493f2f721bf77faad52666c973f9a 100644 (file)
@@ -615,13 +615,11 @@ dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
                dns_name_fromregion(&tname, &remaining);
                INSIST(remaining.length >= tname.length);
                isc_buffer_forward(&source, tname.length);
-               remaining.length -= tname.length;
-               remaining.base += tname.length;
+               isc_region_consume(&remaining, tname.length);
 
                INSIST(remaining.length >= 2);
                type = isc_buffer_getuint16(&source);
-               remaining.length -= 2;
-               remaining.base += 2;
+               isc_region_consume(&remaining, 2);
 
                if (type != dns_rdatatype_rrsig ||
                    !dns_name_equal(&tname, name)) {
@@ -633,8 +631,7 @@ dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
                INSIST(remaining.length >= 1);
                trust = isc_buffer_getuint8(&source);
                INSIST(trust <= dns_trust_ultimate);
-               remaining.length -= 1;
-               remaining.base += 1;
+               isc_region_consume(&remaining, 1);
 
                raw = remaining.base;
                count = raw[0] * 256 + raw[1];
index d41fee38b27c56724723a97fbf635bedbdbe9f42..9f422198064153451f12b85402b0794712bd3819 100644 (file)
@@ -277,8 +277,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
@@ -289,7 +291,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);
 }
 
@@ -330,16 +333,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);
 
@@ -380,10 +383,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;
@@ -398,10 +403,9 @@ openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) {
                                DH_free(dh);
                                return (DST_R_INVALIDPUBLICKEY);
                }
-       }
-       else {
+       } else {
                dh->p = BN_bin2bn(r.base, plen, NULL);
-               r.base += plen;
+               isc_region_consume(&r, plen);
        }
 
        /*
@@ -432,15 +436,14 @@ openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) {
                                return (DST_R_INVALIDPUBLICKEY);
                        }
                }
-       }
-       else {
+       } else {
                if (glen == 0) {
                        DH_free(dh);
                        return (DST_R_INVALIDPUBLICKEY);
                }
                dh->g = BN_bin2bn(r.base, glen, NULL);
        }
-       r.base += glen;
+       isc_region_consume(&r, glen);
 
        if (r.length < 2) {
                DH_free(dh);
@@ -452,7 +455,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);
 
index 510e78e5ae36e299787fc36beb70ee86ad2bf99d..963e2f508e416d789a983d95a3613eeb3c1017c8 100644 (file)
@@ -29,8 +29,6 @@
  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id$ */
-
 #ifdef OPENSSL
 #ifndef USE_EVP
 #define USE_EVP 1
@@ -137,6 +135,7 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
        DSA *dsa = key->keydata.dsa;
        isc_region_t r;
        DSA_SIG *dsasig;
+       unsigned int klen;
 #if USE_EVP
        EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
        EVP_PKEY *pkey;
@@ -188,6 +187,7 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
                                               ISC_R_FAILURE));
        }
        free(sigbuf);
+
 #elif 0
        /* Only use EVP for the Digest */
        if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
@@ -209,11 +209,17 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
                                               "DSA_do_sign",
                                               DST_R_SIGNFAILURE));
 #endif
-       *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);
 
@@ -457,15 +463,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);
 
@@ -490,29 +497,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;
 
index b881880c7d845e33af7741d8ff5363d1b457a005..b6b34611cea6bbb427b1112b6bccaed5dbb5f6c7 100644 (file)
@@ -14,8 +14,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id$ */
-
 #include <config.h>
 
 #if defined(OPENSSL) && defined(HAVE_OPENSSL_ECDSA)
@@ -159,9 +157,9 @@ opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
                                               "ECDSA_do_sign",
                                               DST_R_SIGNFAILURE));
        BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2);
-       r.base += siglen / 2;
+       isc_region_consume(&r, siglen / 2);
        BN_bn2bin_fixed(ecdsasig->s, r.base, siglen / 2);
-       r.base += siglen / 2;
+       isc_region_consume(&r, siglen / 2);
        ECDSA_SIG_free(ecdsasig);
        isc_buffer_add(sig, siglen);
        ret = ISC_R_SUCCESS;
index 301e4697104d994028602d07e3b6f9fd8e164a2b..e34cdd823d540d7e2bb0c6968d70a2c643529e1d 100644 (file)
@@ -971,6 +971,7 @@ opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
        RSA *rsa;
        isc_region_t r;
        unsigned int e_bytes;
+       unsigned int length;
 #if USE_EVP
        EVP_PKEY *pkey;
 #endif
@@ -978,6 +979,7 @@ opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
        isc_buffer_remainingregion(data, &r);
        if (r.length == 0)
                return (ISC_R_SUCCESS);
+       length = r.length;
 
        rsa = RSA_new();
        if (rsa == NULL)
@@ -988,17 +990,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) {
@@ -1006,14 +1009,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);
 
 #if USE_EVP
        pkey = EVP_PKEY_new();
index c4d16d47acf479a9aef08b96e48f61ab53dd9f5a..7679f4b2deecd625bf442adf9345fd0cee8d8236 100644 (file)
@@ -14,8 +14,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id$ */
-
 #ifdef PKCS11CRYPTO
 
 #include <config.h>
@@ -632,8 +630,10 @@ pkcs11dh_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
@@ -644,7 +644,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);
 }
 
@@ -708,16 +709,16 @@ pkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data) {
        }
        else
                memmove(r.base, prime, plen);
-       r.base += plen;
+       isc_region_consume(&r, plen);
 
        uint16_toregion(glen, &r);
        if (glen > 0)
                memmove(r.base, base, glen);
-       r.base += glen;
+       isc_region_consume(&r, glen);
 
        uint16_toregion(publen, &r);
        memmove(r.base, pub, publen);
-       r.base += publen;
+       isc_region_consume(&r, publen);
 
        isc_buffer_add(data, dnslen);
 
@@ -764,10 +765,12 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) {
        }
        plen_ = plen;
        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:
                                prime = pk11_dh_bn768;
@@ -789,7 +792,7 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) {
        }
        else {
                prime = r.base;
-               r.base += plen;
+               isc_region_consume(&r, plen);
        }
 
        /*
@@ -835,7 +838,7 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) {
                }
                base = r.base;
        }
-       r.base += glen;
+       isc_region_consume(&r, glen);
 
        if (r.length < 2) {
                memset(dh, 0, sizeof(*dh));
@@ -849,7 +852,7 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) {
                return (DST_R_INVALIDPUBLICKEY);
        }
        pub = r.base;
-       r.base += publen;
+       isc_region_consume(&r, publen);
 
        key->key_size = pk11_numbits(prime, plen_);
 
index be31f72c55ad91f8014989d087732bde2cc75f57..809f7f4b14f8377c91eb2d6a80e6f7800fa28d94 100644 (file)
@@ -388,6 +388,7 @@ pkcs11dsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
        isc_region_t r;
        pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
        isc_result_t ret = ISC_R_SUCCESS;
+       unsigned int klen;
 
        isc_buffer_availableregion(sig, &r);
        if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1)
@@ -399,7 +400,10 @@ pkcs11dsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
        if (siglen != ISC_SHA1_DIGESTLENGTH * 2)
                return (DST_R_SIGNFAILURE);
 
-       *r.base = (dctx->key->key_size - 512)/64;
+       klen = (dctx->key->key_size - 512)/64;
+       if (klen > 255)
+               return (ISC_R_FAILURE);
+       *r.base = klen;
        isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1);
 
     err:
@@ -744,23 +748,25 @@ pkcs11dsa_todns(const dst_key_t *key, isc_buffer_t *data) {
                return (ISC_R_NOSPACE);
 
        memset(r.base, 0, dnslen);
-       *r.base++ = t;
+       *r.base = t;
+       isc_region_consume(&r, 1);
+
        cp = (CK_BYTE *) subprime->pValue;
        memmove(r.base + ISC_SHA1_DIGESTLENGTH - subprime->ulValueLen,
                cp, subprime->ulValueLen);
-       r.base += ISC_SHA1_DIGESTLENGTH;
+       isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
        cp = (CK_BYTE *) prime->pValue;
        memmove(r.base + key->key_size/8 - prime->ulValueLen,
                cp, prime->ulValueLen);
-       r.base += p_bytes;
+       isc_region_consume(&r, p_bytes);
        cp = (CK_BYTE *) base->pValue;
        memmove(r.base + key->key_size/8 - base->ulValueLen,
                cp, base->ulValueLen);
-       r.base += p_bytes;
+       isc_region_consume(&r, p_bytes);
        cp = (CK_BYTE *) pub_key->pValue;
        memmove(r.base + key->key_size/8 - pub_key->ulValueLen,
                cp, pub_key->ulValueLen);
-       r.base += p_bytes;
+       isc_region_consume(&r, p_bytes);
 
        isc_buffer_add(data, dnslen);
 
@@ -784,7 +790,8 @@ pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
                return (ISC_R_NOMEMORY);
        memset(dsa, 0, sizeof(*dsa));
 
-       t = (unsigned int) *r.base++;
+       t = (unsigned int) *r.base;
+       isc_region_consume(&r, 1);
        if (t > 8) {
                memset(dsa, 0, sizeof(*dsa));
                isc_mem_put(key->mctx, dsa, sizeof(*dsa));
@@ -792,23 +799,23 @@ pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
        }
        p_bytes = 64 + 8 * t;
 
-       if (r.length < 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) {
+       if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) {
                memset(dsa, 0, sizeof(*dsa));
                isc_mem_put(key->mctx, dsa, sizeof(*dsa));
                return (DST_R_INVALIDPUBLICKEY);
        }
 
        subprime = r.base;
-       r.base += ISC_SHA1_DIGESTLENGTH;
+       isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
 
        prime = r.base;
-       r.base += p_bytes;
+       isc_region_consume(&r, p_bytes);
 
        base = r.base;
-       r.base += p_bytes;
+       isc_region_consume(&r, p_bytes);
 
        pub_key = r.base;
-       r.base += p_bytes;
+       isc_region_consume(&r, p_bytes);
 
        key->key_size = p_bytes * 8;
 
index a028925b6c2ee3e47969ef706be247b88a0e6ca8..bca1392ab88ee36cf94705ca8f9ef0ca3f845eab 100644 (file)
@@ -791,23 +791,21 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
        unsigned int e_bytes, mod_bytes;
        CK_BYTE *exponent = NULL, *modulus = NULL;
        CK_ATTRIBUTE *attr;
+       unsigned int length;
 
        isc_buffer_remainingregion(data, &r);
        if (r.length == 0)
                return (ISC_R_SUCCESS);
+       length = r.length;
 
        rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa));
        if (rsa == NULL)
                return (ISC_R_NOMEMORY);
+
        memset(rsa, 0, sizeof(*rsa));
 
-       if (r.length < 1) {
-               memset(rsa, 0, sizeof(*rsa));
-               isc_mem_put(key->mctx, rsa, sizeof(*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) {
@@ -815,9 +813,10 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
                        isc_mem_put(key->mctx, rsa, sizeof(*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) {
@@ -826,14 +825,13 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
                return (DST_R_INVALIDPUBLICKEY);
        }
        exponent = r.base;
-       r.base += e_bytes;
-       r.length -= e_bytes;
+       isc_region_consume(&r, e_bytes);
        modulus = r.base;
        mod_bytes = r.length;
 
        key->key_size = pk11_numbits(modulus, mod_bytes);
 
-       isc_buffer_forward(data, r.length);
+       isc_buffer_forward(data, length);
 
        rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2);
        if (rsa->repr == NULL)
index 843ff1a43a929cd93570220192b72cb284d90955..bd93b5275592dff7df8200c2fcbd6b5b26934e65 100644 (file)
@@ -9678,6 +9678,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
@@ -9697,6 +9703,7 @@ dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name,
 #endif
        if (found)
                return (ISC_FALSE);
+
        return (dst_algorithm_supported(alg));
 }