diff --git a/net/ldns/utils/Makefile b/net/ldns/utils/Makefile index 78e56bb705c..2405eb54b26 100644 --- a/net/ldns/utils/Makefile +++ b/net/ldns/utils/Makefile @@ -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 diff --git a/net/ldns/utils/patches/patch-dnssec_c b/net/ldns/utils/patches/patch-dnssec_c new file mode 100644 index 00000000000..a07ddc8d098 --- /dev/null +++ b/net/ldns/utils/patches/patch-dnssec_c @@ -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; + } diff --git a/net/ldns/utils/patches/patch-dnssec_sign_c b/net/ldns/utils/patches/patch-dnssec_sign_c new file mode 100644 index 00000000000..a447e10d242 --- /dev/null +++ b/net/ldns/utils/patches/patch-dnssec_sign_c @@ -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 */ diff --git a/net/ldns/utils/patches/patch-ldns_dnssec_h b/net/ldns/utils/patches/patch-ldns_dnssec_h new file mode 100644 index 00000000000..0f6bbea47ba --- /dev/null +++ b/net/ldns/utils/patches/patch-ldns_dnssec_h @@ -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