Add upstream patches to ldns-utils to include the required leading zeros

when generating ECDSA RRSIG records. From dhill. More information at
https://open.nlnetlabs.nl/pipermail/ldns-users/2015-August/000814.html
This commit is contained in:
sthen 2016-01-16 13:15:26 +00:00
parent 647c81e037
commit b12af54d6d
4 changed files with 119 additions and 1 deletions

View File

@ -1,8 +1,9 @@
# $OpenBSD: Makefile,v 1.30 2014/06/15 20:20:34 sthen Exp $
# $OpenBSD: Makefile,v 1.31 2016/01/16 13:15:26 sthen Exp $
COMMENT= LDNS utilities
PKGNAME= ldns-utils-${VERSION}
REVISION= 0
WANTLIB= c crypto ldns>=6.1 pcap ssl
LIB_DEPENDS+= net/ldns/libldns>=1.6.17

View File

@ -0,0 +1,46 @@
$OpenBSD: patch-dnssec_c,v 1.1 2016/01/16 13:15:26 sthen Exp $
Fix ECDSA signature generation, do not omit leading zeroes.
http://git.nlnetlabs.nl/ldns/commit/?h=develop&id=1139fdc7f6d78cc9a93e46d3defcd05d15c45af0
--- dnssec.c.orig Fri Jan 10 16:04:41 2014
+++ dnssec.c Fri Jan 15 23:06:29 2016
@@ -1806,7 +1806,8 @@ ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_bu
#ifdef USE_ECDSA
#ifndef S_SPLINT_S
ldns_rdf *
-ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len)
+ldns_convert_ecdsa_rrsig_asn1len2rdf(const ldns_buffer *sig,
+ const long sig_len, int num_bytes)
{
ECDSA_SIG* ecdsa_sig;
unsigned char *data = (unsigned char*)ldns_buffer_begin(sig);
@@ -1815,16 +1816,22 @@ ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *s
if(!ecdsa_sig) return NULL;
/* "r | s". */
- data = LDNS_XMALLOC(unsigned char,
- BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s));
+ if(BN_num_bytes(ecdsa_sig->r) > num_bytes ||
+ BN_num_bytes(ecdsa_sig->s) > num_bytes) {
+ ECDSA_SIG_free(ecdsa_sig);
+ return NULL; /* numbers too big for passed curve size */
+ }
+ data = LDNS_XMALLOC(unsigned char, num_bytes*2);
if(!data) {
ECDSA_SIG_free(ecdsa_sig);
return NULL;
}
- BN_bn2bin(ecdsa_sig->r, data);
- BN_bn2bin(ecdsa_sig->s, data+BN_num_bytes(ecdsa_sig->r));
- rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, (size_t)(
- BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s)), data);
+ /* write the bignums (in big-endian) a little offset if the BN code
+ * wants to write a shorter number of bytes, with zeroes prefixed */
+ memset(data, 0, num_bytes*2);
+ BN_bn2bin(ecdsa_sig->r, data+num_bytes-BN_num_bytes(ecdsa_sig->r));
+ BN_bn2bin(ecdsa_sig->s, data+num_bytes*2-BN_num_bytes(ecdsa_sig->s));
+ rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, (size_t)(num_bytes*2), data);
ECDSA_SIG_free(ecdsa_sig);
return rdf;
}

View File

@ -0,0 +1,43 @@
$OpenBSD: patch-dnssec_sign_c,v 1.1 2016/01/16 13:15:26 sthen Exp $
Fix ECDSA signature generation, do not omit leading zeroes.
http://git.nlnetlabs.nl/ldns/commit/?h=develop&id=1139fdc7f6d78cc9a93e46d3defcd05d15c45af0
--- dnssec_sign.c.orig Fri Jan 10 16:04:41 2014
+++ dnssec_sign.c Fri Jan 15 23:06:29 2016
@@ -367,6 +367,7 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
#ifdef USE_ECDSA
#ifndef S_SPLINT_S
+/** returns the number of bytes per signature-component (i.e. bits/8), or 0. */
static int
ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
{
@@ -380,11 +381,13 @@ ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
EC_KEY_free(ec);
return 0;
}
- if(EC_GROUP_get_curve_name(g) == NID_secp224r1 ||
- EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 ||
- EC_GROUP_get_curve_name(g) == NID_secp384r1) {
+ if(EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1) {
EC_KEY_free(ec);
- return 1;
+ return 32; /* 256/8 */
+ }
+ if(EC_GROUP_get_curve_name(g) == NID_secp384r1) {
+ EC_KEY_free(ec);
+ return 48; /* 384/8 */
}
/* downref the eckey, the original is still inside the pkey */
EC_KEY_free(ec);
@@ -448,7 +451,8 @@ ldns_sign_public_evp(ldns_buffer *to_sign,
#ifdef USE_ECDSA
} else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC &&
ldns_pkey_is_ecdsa(key)) {
- sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen);
+ sigdata_rdf = ldns_convert_ecdsa_rrsig_asn1len2rdf(
+ b64sig, siglen, ldns_pkey_is_ecdsa(key));
#endif
} else {
/* ok output for other types is the same */

View File

@ -0,0 +1,28 @@
$OpenBSD: patch-ldns_dnssec_h,v 1.1 2016/01/16 13:15:26 sthen Exp $
Fix ECDSA signature generation, do not omit leading zeroes.
http://git.nlnetlabs.nl/ldns/commit/?h=develop&id=1139fdc7f6d78cc9a93e46d3defcd05d15c45af0
--- ldns/dnssec.h.orig Fri Jan 10 16:04:41 2014
+++ ldns/dnssec.h Fri Jan 15 23:06:29 2016
@@ -511,13 +511,19 @@ ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_bu
* Converts the ECDSA signature from ASN1 representation (as
* used by OpenSSL) to raw signature data as used in DNS
* This routine is only present if ldns is compiled with ecdsa support.
+ * The older ldns_convert_ecdsa_rrsig_asn12rdf routine could not (always)
+ * construct a valid rdf because it did not have the num_bytes parameter.
+ * The num_bytes parameter is 32 for p256 and 48 for p384 (bits/8).
*
* \param[in] sig The signature in ASN1 format
* \param[in] sig_len The length of the signature
+ * \param[in] num_bytes number of bytes for values in the curve, the curve
+ * size divided by 8.
* \return a new rdf with the signature
*/
ldns_rdf *
-ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len);
+ldns_convert_ecdsa_rrsig_asn1len2rdf(const ldns_buffer *sig,
+ const long sig_len, int num_bytes);
/**
* Converts the RRSIG signature RDF (from DNS) to a buffer with the