--- /dev/null
+; 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
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;
}
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;
}
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.
*
* @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:
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:
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
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;
}
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;