From: Wouter Wijngaards Date: Mon, 14 Apr 2008 15:57:52 +0000 (+0000) Subject: Check sig type for DSA. X-Git-Tag: release-0.11~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3fced109b99b6f9dc87a067cf479d7accc85133e;p=thirdparty%2Funbound.git Check sig type for DSA. git-svn-id: file:///svn/unbound/trunk@1043 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 538ea702a..00f0010bb 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -4,6 +4,7 @@ - documented 0x20 status. - fixup chroot and checkconf, it is much smarter now. - fixup DSA EVP signature decoding. Solution that Jelte found copied. + - and check first sig byte for the encoding type. 11 April 2008: Wouter - random port selection out of the configged ports. diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index 595afa338..bedcedc45 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -108,6 +108,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr, &val, (socklen_t)sizeof(val)) < 0) { log_err("setsockopt(..., IPV6_V6ONLY" ", ...) failed: %s", strerror(errno)); + close(s); *inuse = 0; return -1; } @@ -126,6 +127,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr, &on, (socklen_t)sizeof(on)) < 0) { log_err("setsockopt(..., IPV6_USE_MIN_MTU, " "...) failed: %s", strerror(errno)); + close(s); *inuse = 0; return -1; } @@ -137,10 +139,12 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr, if(errno != EADDRINUSE) #endif log_err("can't bind socket: %s", strerror(errno)); + close(s); return -1; } if(!fd_set_nonblock(s)) { *inuse = 0; + close(s); return -1; } return s; diff --git a/validator/val_sigcrypt.c b/validator/val_sigcrypt.c index 6b2a1d21c..e1f35eccb 100644 --- a/validator/val_sigcrypt.c +++ b/validator/val_sigcrypt.c @@ -1194,6 +1194,7 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len) { unsigned char* orig = *sig; unsigned int origlen = *len; + int newlen; uint8_t t; BIGNUM *R, *S; @@ -1215,11 +1216,12 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len) dsasig->r = R; dsasig->s = S; *sig = NULL; - *len = i2d_DSA_SIG(dsasig, sig); - if(*len == 0) { + newlen = i2d_DSA_SIG(dsasig, sig); + if(newlen < 0) { free(sig); return 0; } + *len = (unsigned int)newlen; DSA_SIG_free(dsasig); return 1; } @@ -1285,7 +1287,7 @@ verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock, { const EVP_MD *digest_type; EVP_MD_CTX ctx; - int res; + int res, dofree = 0; EVP_PKEY *evp_key = EVP_PKEY_new(); if(!evp_key) { log_err("verify: malloc failure in crypto"); @@ -1297,12 +1299,14 @@ verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock, EVP_PKEY_free(evp_key); return sec_status_bogus; } - if(algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) { + /* if it is a DSA signature in XXX format, convert to DER format */ + if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) && + sigblock_len > 0 && sigblock[0] == 0) { if(!setup_dsa_sig(&sigblock, &sigblock_len)) { verbose(VERB_QUERY, "verify: failed to setup DSA sig"); - EVP_PKEY_free(evp_key); return sec_status_bogus; } + dofree = 1; } /* do the signature cryptography work */ @@ -1314,15 +1318,15 @@ verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock, EVP_MD_CTX_cleanup(&ctx); EVP_PKEY_free(evp_key); - if(algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) { + if(dofree) free(sigblock); - } if(res == 1) { return sec_status_secure; } else if(res == 0) { return sec_status_bogus; } + log_crypto_error("verify:", ERR_get_error()); return sec_status_unchecked; } @@ -1438,7 +1442,7 @@ dnskey_verify_rrset_sig(struct regional* region, ldns_buffer* buf, /* verify */ sec = verify_canonrrset(buf, (int)sig[2+2], sigblock, sigblock_len, key, keylen); - + /* check if TTL is too high - reduce if so */ if(sec == sec_status_secure) { adjust_ttl(ve, now, rrset, sig+2+4, sig+2+8, sig+2+12);