]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
no convert to der for DSA signatures
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 29 Aug 2007 14:27:04 +0000 (14:27 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 29 Aug 2007 14:27:04 +0000 (14:27 +0000)
signature test.

git-svn-id: file:///svn/unbound/trunk@564 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
testdata/val_positive.rpl [new file with mode: 0644]
validator/val_sigcrypt.c
validator/val_utils.c

index 8042649d59ed828628575ca6f0608ac3a9e43231..60f3886aa858c32eea5c14a95c1ded5f7c44b127 100644 (file)
@@ -3,6 +3,9 @@
        - added RSA and DSA test keys, public and private pairs, 512 bits.
        - default configuration is with validation enabled.
          Only a trust-anchor needs to be configured for DNSSEC to work.
+       - do not convert to DER for DSA signature verification.
+       - validator replay test file, for a DS to DNSKEY DSA key prime and
+         positive response.
 
 28 August 2007: Wouter
        - removed double use for udp buffers, that could fail,
diff --git a/testdata/val_positive.rpl b/testdata/val_positive.rpl
new file mode 100644 (file)
index 0000000..cad6b10
--- /dev/null
@@ -0,0 +1,121 @@
+; config options
+; The island of trust is at example.com
+server:
+       trust-anchor: "example.com.    3600    IN      DS      2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+       val-override-date: "20070916134226"
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test validator with positive response
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+       ADDRESS 193.0.14.129 
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS        K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET.    IN      A       193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+com.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ENTRY_END
+RANGE_END
+
+; ns.example.com.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.4
+
+; response to DNSKEY priming query
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com.    3600    IN      DNSKEY  256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com.    3600    IN      RRSIG   DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; response to query of interest
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A  10.20.30.40
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+www.example.com.        3600    IN      RRSIG   A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all
+REPLY QR RD RA AD NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. IN A  10.20.30.40
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ENTRY_END
+
+SCENARIO_END
index ef848b99b625a05b1b5479db60469623d24e37aa..cfa57a77fb9e12cba2eb965d72ea91b222a95a00 100644 (file)
@@ -312,7 +312,10 @@ ds_create_dnskey_digest(struct module_env* env,
                                ldns_buffer_limit(b), (unsigned char*)digest);
                        return 1;
 #endif
-               default: break;
+               default: 
+                       verbose(VERB_DETAIL, "unknown DS digest algorithm %d", 
+                               (int) ds_get_digest_algo(ds_rrset, ds_idx));
+                       break;
        }
        return 0;
 }
@@ -326,21 +329,33 @@ int ds_digest_match_dnskey(struct module_env* env,
        uint8_t* digest; /* generated digest */
        size_t digestlen = ds_digest_size_algo(ds_rrset, ds_idx);
        
-       if(digestlen == 0)
+       if(digestlen == 0) {
+               verbose(VERB_DETAIL, "DS fail: not supported, or DS RR "
+                       "format error");
                return 0; /* not supported, or DS RR format error */
+       }
        /* check digest length in DS with length from hash function */
        ds_get_sigdata(ds_rrset, ds_idx, &ds, &dslen);
-       if(!ds || dslen != digestlen)
+       if(!ds || dslen != digestlen) {
+               verbose(VERB_DETAIL, "DS fail: DS RR algo and digest do not "
+                       "match each other");
                return 0; /* DS algorithm and digest do not match */
+       }
 
        digest = region_alloc(env->scratch, digestlen);
-       if(!digest)
+       if(!digest) {
+               verbose(VERB_DETAIL, "DS fail: out of memory");
                return 0; /* mem error */
+       }
        if(!ds_create_dnskey_digest(env, dnskey_rrset, dnskey_idx, ds_rrset, 
-               ds_idx, digest))
+               ds_idx, digest)) {
+               verbose(VERB_DETAIL, "DS fail: could not calc key digest");
                return 0; /* digest algo failed */
-       if(memcmp(digest, ds, dslen) != 0)
+       }
+       if(memcmp(digest, ds, dslen) != 0) {
+               verbose(VERB_DETAIL, "DS fail: digest is different");
                return 0; /* digest different */
+       }
        return 1;
 }
 
@@ -1164,91 +1179,6 @@ log_crypto_error(const char* str, unsigned long e)
        log_err("%s crypto %s", str, buf);
 }
 
-/**
- * Convert DSA RRsig sigblock to a DSA_SIG structure.
- * @param sig: sigblock field of RRSIG
- * @param siglen: length of sig.
- * @return DSA_SIG or NULL
- */
-static DSA_SIG*
-dsa_rrsig_to_dsa_sig(unsigned char* sig, unsigned int siglen)
-{
-       uint8_t t;
-       BIGNUM *R, *S;
-       DSA_SIG *dsasig;
-
-       /* extract the R and S field from the sig buffer */
-       if(siglen < 1 + SHA_DIGEST_LENGTH*2) {
-               verbose(VERB_DETAIL, "verify: short DSA RRSIG");
-               return NULL;
-       }
-       t = sig[0];
-       R = BN_new();
-       if(!R) {
-               log_err("verify: alloc failure");
-               return NULL;
-       }
-       S = BN_new();
-       if(!S) {
-               BN_free(R);
-               log_err("verify: alloc failure");
-               return NULL;
-       }
-       if(!BN_bin2bn(sig + 1, SHA_DIGEST_LENGTH, R)) {
-               log_err("verify: bignum failure");
-               BN_free(R);
-               BN_free(S);
-               return NULL;
-       }
-       if(!BN_bin2bn(sig + 21, SHA_DIGEST_LENGTH, S)) {
-               log_err("verify: bignum failure");
-               BN_free(R);
-               BN_free(S);
-               return NULL;
-       }
-
-       dsasig = DSA_SIG_new();
-       if(!dsasig) {
-               log_err("verify: alloc failure");
-               BN_free(R);
-               BN_free(S);
-               return NULL;
-       }
-       dsasig->r = R;
-       dsasig->s = S;
-       return dsasig;
-}
-
-/**
- * Convert DSA signature to a DER signature.
- * @param sig: signature, used to read, then replaced with malloced 
- *     DER signature on success.
- * @param siglen: read to get input len, then updated to new length.
- * @return false on (alloc) error.
- */
-static int
-dsa_convert_to_der(unsigned char** sig, unsigned int* siglen)
-{
-       DSA_SIG* dsasig;
-       int res;
-
-       dsasig = dsa_rrsig_to_dsa_sig(*sig, *siglen);
-       if(!dsasig) {
-               return 0;
-       }
-       *sig = NULL; /* needs libcrypto >= 0.9.7 */
-       res = i2d_DSA_SIG(dsasig, sig);
-       if(res < 0) {
-               log_crypto_error("verify: bad dsa sig ",
-                       ERR_get_error());
-               DSA_SIG_free(dsasig);
-               return 0;
-       }
-       DSA_SIG_free(dsasig);
-       *siglen = (unsigned int)res;
-       return 1;
-}
-
 /**
  * Setup key and digest for verification. Adjust sig if necessary.
  *
@@ -1257,14 +1187,11 @@ dsa_convert_to_der(unsigned char** sig, unsigned int* siglen)
  * @param digest_type: digest type to use
  * @param key: key to setup for.
  * @param keylen: length of key.
- * @param sig: sig to update if necessary.
- * @param siglen: length of sig.
  * @return false on failure.
  */
 static int
 setup_key_digest(int algo, EVP_PKEY* evp_key, const EVP_MD** digest_type, 
-       unsigned char* key, size_t keylen, 
-       unsigned char** sig, unsigned int* siglen)
+       unsigned char* key, size_t keylen)
 {
        switch(algo) {
                case LDNS_DSA:
@@ -1272,8 +1199,6 @@ setup_key_digest(int algo, EVP_PKEY* evp_key, const EVP_MD** digest_type,
                        EVP_PKEY_assign_DSA(evp_key, 
                                ldns_key_buf2dsa_raw(key, keylen));
                        *digest_type = EVP_dss1();
-                       if(!dsa_convert_to_der(sig, siglen))
-                               return 0;
 
                        break;
                case LDNS_RSASHA1:
@@ -1297,23 +1222,6 @@ setup_key_digest(int algo, EVP_PKEY* evp_key, const EVP_MD** digest_type,
        return 1;
 }
 
-/**
- * Desetup what setup_key_digest setup.
- * @param algo: key algorithm
- * @param sig: signature.
- */
-static void
-desetup_key_digest(int algo, unsigned char* sig)
-{
-       switch(algo) {
-               case LDNS_DSA:
-               case LDNS_DSA_NSEC3:
-                       /* free converted signature */
-                       free(sig);
-                       break;
-       }
-}
-
 /**
  * Check a canonical sig+rrset and signature against a dnskey
  * @param buf: buffer with data to verify, the first rrsig part and the
@@ -1339,8 +1247,8 @@ verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock,
                return sec_status_unchecked;
        }
 
-       if(!setup_key_digest(algo, evp_key, &digest_type, key, keylen,
-               &sigblock, &sigblock_len)) {
+       if(!setup_key_digest(algo, evp_key, &digest_type, key, keylen)) {
+               verbose(VERB_DETAIL, "verify: failed to setup key");
                EVP_PKEY_free(evp_key);
                return sec_status_bogus;
        }
@@ -1353,7 +1261,6 @@ verify_canonrrset(ldns_buffer* buf, int algo, unsigned char* sigblock,
        res = EVP_VerifyFinal(&ctx, sigblock, sigblock_len, evp_key);
        EVP_MD_CTX_cleanup(&ctx);
        EVP_PKEY_free(evp_key);
-       desetup_key_digest(algo, sigblock);
 
        if(res == 1) {
                return sec_status_secure;
index 0590d0b705ac9437ec1fdbc53595c26e0a2996c7..0b39adcbfd72257576caa4e3ac9131dcfdc86692 100644 (file)
@@ -365,8 +365,10 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
                 * same DS hash algorithm. */
                if(!ds_digest_match_dnskey(env, dnskey_rrset, i, ds_rrset, 
                        ds_idx)) {
+                       verbose(VERB_ALGO, "DS match attempt failed");
                        continue;
                }
+               verbose(VERB_ALGO, "DS match digest ok, trying signature");
 
                /* Otherwise, we have a match! Make sure that the DNSKEY 
                 * verifies *with this key*  */