]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
merges crypto_evp_api branch back to trunk
authorJelte Jansen <jeltejan@NLnetLabs.nl>
Thu, 24 May 2007 12:53:00 +0000 (12:53 +0000)
committerJelte Jansen <jeltejan@NLnetLabs.nl>
Thu, 24 May 2007 12:53:00 +0000 (12:53 +0000)
dnssec.c
error.c
examples/configure.ac
examples/ldns-signzone.c
host2str.c
keys.c
ldns/dnssec.h
ldns/error.h
ldns/keys.h

index 9a1bcb44a5fad54c1547dd0be494629b7c94d267..a51f067affdd4d3ddf6225840d902d1c6b90d753 100644 (file)
--- a/dnssec.c
+++ b/dnssec.c
@@ -22,6 +22,7 @@
  * crypto...
  */
 #include <openssl/ssl.h>
+#include <openssl/evp.h>
 #include <openssl/rand.h>
 #include <openssl/err.h>
 #include <openssl/md5.h>
@@ -62,7 +63,7 @@ ldns_calc_keytag(const ldns_rr *key)
                }
                ldns_buffer_free(keybuf);
                ac16 = ntohs(ac16);
-               return (uint16_t) ac16;
+               return (uint16_t) ac16;
        } else {
                for (i = 0; (size_t)i < keysize; ++i) {
                        ac32 += (i & 1) ? *ldns_buffer_at(keybuf, i) : 
@@ -335,6 +336,7 @@ ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
                                return ldns_verify_rrsig_dsa(rawsig_buf, verify_buf, key_buf);
                                break;
                        case LDNS_RSASHA1:
+                               /*return ldns_verify_rrsig_rsasha1(rawsig_buf, verify_buf, key_buf);*/
                                return ldns_verify_rrsig_rsasha1(rawsig_buf, verify_buf, key_buf);
                                break;
                        case LDNS_RSAMD5:
@@ -411,23 +413,23 @@ ldns_verify_rrsig_keylist(ldns_rr_list *rrset, ldns_rr *rrsig, const ldns_rr_lis
        now = time(NULL);
 
        if (expiration - inception < 0) {
-                /* bad sig, expiration before inception?? Tsssg */
+               /* bad sig, expiration before inception?? Tsssg */
                ldns_buffer_free(rawsig_buf);
                ldns_buffer_free(verify_buf);
                return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
-        }
-        if (now - inception < 0) {
-                /* bad sig, inception date has passed */
+       }
+       if (now - inception < 0) {
+               /* bad sig, inception date has passed */
                ldns_buffer_free(rawsig_buf);
                ldns_buffer_free(verify_buf);
                return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
-        }
-        if (expiration - now < 0) {
-                /* bad sig, expiration date has passed */
+       }
+       if (expiration - now < 0) {
+               /* bad sig, expiration date has passed */
                ldns_buffer_free(rawsig_buf);
                ldns_buffer_free(verify_buf);
                return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
-        }
+       }
        
        /* create a buffer with b64 signature rdata */
        if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
@@ -444,7 +446,7 @@ ldns_verify_rrsig_keylist(ldns_rr_list *rrset, ldns_rr *rrsig, const ldns_rr_lis
        for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
                if (label_count < 
                        ldns_dname_label_count(
-                               ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
+                                       ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
                        (void) ldns_str2rdf_dname(&wildcard_name, "*");
                        wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)));
                        while (label_count < ldns_dname_label_count(wildcard_chopped)) {
@@ -457,7 +459,7 @@ ldns_verify_rrsig_keylist(ldns_rr_list *rrset, ldns_rr *rrsig, const ldns_rr_lis
                        ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)));
                        ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i), 
                                        wildcard_name);
-                                       
+                                       
                }
                ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
                /* convert to lowercase */
@@ -485,7 +487,7 @@ ldns_verify_rrsig_keylist(ldns_rr_list *rrset, ldns_rr *rrsig, const ldns_rr_lis
                current_key = ldns_rr_list_rr(keys, i);
                /* before anything, check if the keytags match */
                if (ldns_calc_keytag(current_key) ==
-                   ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))) {
+                       ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))) {
                        key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
                        
                        /* put the key-data in a buffer, that's the third rdf, with
@@ -573,18 +575,18 @@ ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
        now = time(NULL);
 
        if (expiration - inception < 0) {
-                /* bad sig, expiration before inception?? Tsssg */
+               /* bad sig, expiration before inception?? Tsssg */
                return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
-        }
-        if (now - inception < 0) {
-                /* bad sig, inception date has passed */
+       }
+       if (now - inception < 0) {
+               /* bad sig, inception date has passed */
                return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
-        }
+       }
 
-        if (expiration - now < 0) {
-                /* bad sig, expiration date has passed */
+       if (expiration - now < 0) {
+               /* bad sig, expiration date has passed */
                return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
-        }
+       }
        /* clone the rrset so that we can fiddle with it */
        rrset_clone = ldns_rr_list_clone(rrset);
        
@@ -635,7 +637,7 @@ ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
        for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
                if (label_count < 
                        ldns_dname_label_count(
-                               ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
+                                       ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
                        (void) ldns_str2rdf_dname(&wildcard_name, "*");
                        wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)));
                        while (label_count < ldns_dname_label_count(wildcard_chopped)) {
@@ -648,7 +650,7 @@ ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
                        ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)));
                        ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i), 
                                        wildcard_name);
-                                       
+                                       
                }
                ldns_rr_set_ttl(
                                ldns_rr_list_rr(rrset_clone, i),
@@ -677,8 +679,8 @@ ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
        }
 
        if (ldns_calc_keytag(key)
-           ==
-           ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
+               ==
+               ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
           ) {
                key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
                
@@ -716,75 +718,49 @@ ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
 }
 
 ldns_status
-ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
+ldns_verify_rrsig_evp(ldns_buffer *sig, ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
 {
-       DSA *dsakey;
-       DSA_SIG *dsasig;
-       BIGNUM *R;
-       BIGNUM *S;
-       uint8_t t;
-       int result;
+       EVP_MD_CTX ctx;
+       int res;
 
-       unsigned char *sha1_hash;
-
-       dsakey = ldns_key_buf2dsa(key);
-       if (!dsakey) {
-               return LDNS_STATUS_ERR;
-       }
-
-       /* extract the R and S field from the sig buffer */
-       t = *(ldns_buffer_at(sig, 0));
-       R = BN_new();
-       (void) BN_bin2bn((unsigned char*)ldns_buffer_at(sig, 1), SHA_DIGEST_LENGTH, R);
-       S = BN_new();
-       (void) BN_bin2bn((unsigned char*)ldns_buffer_at(sig, 21), SHA_DIGEST_LENGTH, S);
-
-       dsasig = DSA_SIG_new();
-       if (!dsasig) {
-               return LDNS_STATUS_MEM_ERR;
+       EVP_MD_CTX_init(&ctx);
+       
+       EVP_VerifyInit(&ctx, digest_type);
+       EVP_VerifyUpdate(&ctx, ldns_buffer_begin(rrset), ldns_buffer_position(rrset));
+       res = EVP_VerifyFinal(&ctx, (unsigned char *) ldns_buffer_begin(sig), ldns_buffer_position(sig), key);
+       
+       if (res == 1) {
+               return LDNS_STATUS_OK;
+       } else if (res == 0) {
+               return LDNS_STATUS_CRYPTO_BOGUS;
        }
+       return LDNS_STATUS_OK;
+}
 
-       dsasig->r = R;
-       dsasig->s = S;
-       sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(rrset), ldns_buffer_position(rrset), NULL);
-       if (!sha1_hash) {
-               return LDNS_STATUS_ERR;
-       }
+ldns_status
+ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
+{
+       EVP_PKEY *evp_key;
+       ldns_status result;
 
-       result = DSA_do_verify(sha1_hash, SHA_DIGEST_LENGTH, dsasig, dsakey);
+       evp_key = EVP_PKEY_new();
+       EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa(key));
+       result = ldns_verify_rrsig_evp(sig, rrset, evp_key, EVP_sha1());
+       EVP_PKEY_free(evp_key);
+       return result;
 
-       if (result == 1) {
-               return LDNS_STATUS_OK;
-       } else {
-               return LDNS_STATUS_CRYPTO_BOGUS;
-       }
 }
 
 ldns_status
 ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
 {
-       RSA *rsakey;
-       unsigned char *sha1_hash;
+       EVP_PKEY *evp_key;
        ldns_status result;
 
-       rsakey = ldns_key_buf2rsa(key);
-       if (!rsakey) {
-               result = LDNS_STATUS_ERR;
-       } else {
-               sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(rrset), ldns_buffer_position(rrset), NULL);
-               if (!sha1_hash) {
-                       return LDNS_STATUS_ERR;
-               }
-               if (RSA_verify(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH, 
-                                       (unsigned char*)ldns_buffer_begin(sig),
-                               (unsigned int)ldns_buffer_position(sig), rsakey) == 1) {
-                       result = LDNS_STATUS_OK;
-               } else {
-                       result = LDNS_STATUS_CRYPTO_BOGUS;
-               }
-       }
-
-       RSA_free(rsakey);
+       evp_key = EVP_PKEY_new();
+       EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa(key));
+       result = ldns_verify_rrsig_evp(sig, rrset, evp_key, EVP_sha1());
+       EVP_PKEY_free(evp_key);
 
        return result;
 }
@@ -793,26 +769,15 @@ ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key
 ldns_status
 ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
 {
-       RSA *rsakey;
-       unsigned char *md5_hash;
+       EVP_PKEY *evp_key;
+       ldns_status result;
 
-       rsakey = ldns_key_buf2rsa(key);
-       if (!rsakey) {
-               return LDNS_STATUS_ERR;
-       }
-       md5_hash = MD5((unsigned char*)ldns_buffer_begin(rrset), 
-                       (unsigned int)ldns_buffer_position(rrset), NULL);
-       if (!md5_hash) {
-               return LDNS_STATUS_ERR;
-       }
-       if (RSA_verify(NID_md5, md5_hash, MD5_DIGEST_LENGTH, 
-                               (unsigned char*)ldns_buffer_begin(sig),
-                       (unsigned int)ldns_buffer_position(sig), rsakey) == 1) {
-               return LDNS_STATUS_OK;
-       } else {
-               return LDNS_STATUS_CRYPTO_BOGUS;
-       }
-       return true;
+       evp_key = EVP_PKEY_new();
+       EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa(key));
+       result = ldns_verify_rrsig_evp(sig, rrset, evp_key, EVP_md5());
+       EVP_PKEY_free(evp_key);
+
+       return result;
 }
 
 #ifdef HAVE_SSL
@@ -901,21 +866,21 @@ ldns_key_buf2rsa(ldns_buffer *key)
 ldns_rr *
 ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
 {
-        ldns_rdf *tmp;
-        ldns_rr *ds;
-        uint16_t keytag;
-        uint8_t  sha1hash;
-        uint8_t *digest;
-        ldns_buffer *data_buf;
-
-        if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY) {
-                return NULL;
-        }
+       ldns_rdf *tmp;
+       ldns_rr *ds;
+       uint16_t keytag;
+       uint8_t  sha1hash;
+       uint8_t *digest;
+       ldns_buffer *data_buf;
 
-        ds = ldns_rr_new();
-        if (!ds) {
-                return NULL;
-        }
+       if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY) {
+               return NULL;
+       }
+
+       ds = ldns_rr_new();
+       if (!ds) {
+               return NULL;
+       }
        ldns_rr_set_type(ds, LDNS_RR_TYPE_DS);
        ldns_rr_set_owner(ds, ldns_rdf_clone(
                                ldns_rr_owner(key)));
@@ -937,28 +902,28 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
                break;
        }
 
-        data_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-        if (!data_buf) {
+       data_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+       if (!data_buf) {
                LDNS_FREE(digest);
                ldns_rr_free(ds);
-                return NULL;
-        }
+               return NULL;
+       }
 
-        /* keytag */
-        keytag = htons(ldns_calc_keytag((ldns_rr*)key));
-        tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT16, sizeof(uint16_t), &keytag);
-        ldns_rr_push_rdf(ds, tmp);
+       /* keytag */
+       keytag = htons(ldns_calc_keytag((ldns_rr*)key));
+       tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT16, sizeof(uint16_t), &keytag);
+       ldns_rr_push_rdf(ds, tmp);
 
-        /* copy the algorithm field */
-        ldns_rr_push_rdf(ds, ldns_rdf_clone( ldns_rr_rdf(key, 2))); /* second rfd */
+       /* copy the algorithm field */
+       ldns_rr_push_rdf(ds, ldns_rdf_clone( ldns_rr_rdf(key, 2))); /* second rfd */
 
-        /* digest hash type */
-        sha1hash = (uint8_t)h;
-        tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8, sizeof(uint8_t), &sha1hash);
-        ldns_rr_push_rdf(ds, tmp);
+       /* digest hash type */
+       sha1hash = (uint8_t)h;
+       tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8, sizeof(uint8_t), &sha1hash);
+       ldns_rr_push_rdf(ds, tmp);
 
-        /* digest */
-        /* owner name */
+       /* digest */
+       /* owner name */
        if (ldns_rdf2buffer_wire(data_buf, ldns_rr_owner(key)) != LDNS_STATUS_OK) {
                LDNS_FREE(digest);
                ldns_buffer_free(data_buf);
@@ -966,7 +931,7 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
                return NULL;
        }
 
-        /* all the rdata's */
+       /* all the rdata's */
        if (ldns_rr_rdata2buffer_wire(data_buf, (ldns_rr*)key) != LDNS_STATUS_OK) { 
                LDNS_FREE(digest);
                ldns_buffer_free(data_buf);
@@ -976,8 +941,8 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
        switch(h) {
                case LDNS_SHA1:
                (void) SHA1((unsigned char *) ldns_buffer_begin(data_buf),
-                           ldns_buffer_position(data_buf),
-                           (unsigned char*) digest);
+                               ldns_buffer_position(data_buf),
+                               (unsigned char*) digest);
 
                tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX, SHA_DIGEST_LENGTH,
                                digest);
@@ -990,7 +955,7 @@ ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
 
        LDNS_FREE(digest);
        ldns_buffer_free(data_buf);
-        return ds;
+       return ds;
 }
 
 /*
@@ -1059,9 +1024,9 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
                /* sign all RRs with keys that have ZSKbit, !SEPbit.
                   sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
                if (
-                        ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY &&
-                        (!(ldns_key_flags(current_key) & LDNS_KEY_SEP_KEY) ||
-                        ldns_rr_get_type(ldns_rr_list_rr(rrset, 0)) == LDNS_RR_TYPE_DNSKEY)
+                       ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY &&
+                       (!(ldns_key_flags(current_key) & LDNS_KEY_SEP_KEY) ||
+                       ldns_rr_get_type(ldns_rr_list_rr(rrset, 0)) == LDNS_RR_TYPE_DNSKEY)
                   ) {
                        current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
                        
@@ -1138,13 +1103,13 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
                        
                        switch(ldns_key_algorithm(current_key)) {
                                case LDNS_SIGN_DSA:
-                                       b64rdf = ldns_sign_public_dsa(sign_buf, ldns_key_dsa_key(current_key));
+                                       b64rdf = ldns_sign_public_evp(sign_buf, ldns_key_evp_key(current_key), EVP_sha1());
                                        break;
                                case LDNS_SIGN_RSASHA1:
-                                       b64rdf = ldns_sign_public_rsasha1(sign_buf, ldns_key_rsa_key(current_key));
+                                       b64rdf = ldns_sign_public_evp(sign_buf, ldns_key_evp_key(current_key), EVP_sha1());
                                        break;
                                case LDNS_SIGN_RSAMD5:
-                                       b64rdf = ldns_sign_public_rsamd5(sign_buf, ldns_key_rsa_key(current_key));
+                                       b64rdf = ldns_sign_public_evp(sign_buf, ldns_key_evp_key(current_key), EVP_md5());
                                        break;
                                default:
                                        /* do _you_ know this alg? */
@@ -1161,8 +1126,8 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
                        ldns_rr_list_push_rr(signatures, current_sig);
                }
                ldns_buffer_free(sign_buf); /* restart for the next key */
-        }
-        ldns_rr_list_deep_free(rrset_clone);
+       }
+       ldns_rr_list_deep_free(rrset_clone);
 
        return signatures;
 }
@@ -1216,6 +1181,43 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
        return sigdata_rdf;
 }
 
+ldns_rdf *
+ldns_sign_public_evp(ldns_buffer *to_sign, EVP_PKEY *key, const EVP_MD *digest_type)
+{
+       unsigned int siglen;
+       ldns_rdf *sigdata_rdf;
+       ldns_buffer *b64sig;
+       EVP_MD_CTX ctx;
+       const EVP_MD *md_type;
+
+       siglen = 0;
+       b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+       if (!b64sig) {
+               return NULL;
+       }
+
+       /* initializes a signing context */
+       md_type = digest_type;
+       if(!md_type) {
+               printf("Unknown message digest");
+               exit(1);
+       }
+
+       EVP_MD_CTX_init(&ctx);
+       EVP_SignInit(&ctx, md_type);
+
+       EVP_SignUpdate(&ctx, (unsigned char*)ldns_buffer_begin(to_sign), ldns_buffer_position(to_sign));
+
+       EVP_SignFinal(&ctx, (unsigned char*)ldns_buffer_begin(b64sig), &siglen, key);
+
+       sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
+                       ldns_buffer_begin(b64sig));
+       ldns_buffer_free(b64sig);
+       EVP_MD_CTX_cleanup(&ctx);
+       return sigdata_rdf;
+}
+
+
 ldns_rdf *
 ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
 {
@@ -1315,7 +1317,7 @@ ldns_create_nsec(ldns_rdf *cur_owner, ldns_rdf *next_owner, ldns_rr_list *rrs)
                i_rr = ldns_rr_list_rr(rrs, i);
 
                if (ldns_rdf_compare(cur_owner,
-                                    ldns_rr_owner(i_rr)) == 0) {
+                                        ldns_rr_owner(i_rr)) == 0) {
                        /* add type to bitmap */
                        i_type = ldns_rr_get_type(i_rr);
                        if ((i_type / 8) + 1 > bm_len) {
@@ -1407,7 +1409,7 @@ ldns_nsec_bitmap_covers_type(const ldns_rdf *nsec_bitmap, ldns_rr_type type)
                if (bitmap[i] == window_block_nr) {
                        /* this is the right window, check the bit */
                        if ((uint8_t) (type / 8) < bitmap[i + 1] &&
-                           ldns_get_bit(&bitmap[i + 1 + (type / 8)], (size_t) (7 - (type % 8)))) {
+                               ldns_get_bit(&bitmap[i + 1 + (type / 8)], (size_t) (7 - (type % 8)))) {
                                return true;
                        } else {
                                return false;
@@ -1434,7 +1436,7 @@ ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name)
                        ldns_dname_compare(name, nsec_next) < 0);
 
        return (ldns_dname_compare(nsec_owner, name) <= 0 &&
-           ldns_dname_compare(name, nsec_next) < 0);
+               ldns_dname_compare(name, nsec_next) < 0);
 }
 
 /* sig may be null - if so look in the packet */
@@ -1536,8 +1538,8 @@ ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
        ldns_rr_list_push_rr(orig_zone_rrs, ldns_rr_clone(ldns_zone_soa(zone)));
        
        /* canon now, needed for correct nsec creation */
-        /*
-        for (i = 0; i < ldns_rr_list_rr_count(orig_zone_rrs); i++) {
+       /*
+       for (i = 0; i < ldns_rr_list_rr_count(orig_zone_rrs); i++) {
                ldns_rr2canonical(ldns_rr_list_rr(orig_zone_rrs, i));
        }
        */
@@ -1596,14 +1598,14 @@ ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
 
                /* if we have KSKs, use them for DNSKEYS, otherwise
                   make them selfsigned (?) */
-                /* don't sign sigs, delegations, and glue */
+               /* don't sign sigs, delegations, and glue */
                if (cur_rrset_type != LDNS_RR_TYPE_RRSIG &&
-                   ((ldns_dname_is_subdomain(cur_dname, ldns_rr_owner(ldns_zone_soa(signed_zone)))
-                      && cur_rrset_type != LDNS_RR_TYPE_NS
-                     ) ||
-                    ldns_rdf_compare(cur_dname, ldns_rr_owner(ldns_zone_soa(signed_zone))) == 0
-                   ) &&
-                   !(ldns_rr_list_contains_rr(glue_rrs, ldns_rr_list_rr(cur_rrset, 0)))
+                       ((ldns_dname_is_subdomain(cur_dname, ldns_rr_owner(ldns_zone_soa(signed_zone)))
+                         && cur_rrset_type != LDNS_RR_TYPE_NS
+                        ) ||
+                        ldns_rdf_compare(cur_dname, ldns_rr_owner(ldns_zone_soa(signed_zone))) == 0
+                       ) &&
+                       !(ldns_rr_list_contains_rr(glue_rrs, ldns_rr_list_rr(cur_rrset, 0)))
                   ) {
                        cur_rrsigs = ldns_sign_public(cur_rrset, key_list);
 
@@ -1665,4 +1667,11 @@ ldns_init_random(FILE *fd, uint16_t bytes)
        LDNS_FREE(buf);
        return LDNS_STATUS_OK;
 }
+
+/* taken from the ENGINE man page */
+/*
+int ldns_load_engine_fn(const char *engine_id, const char **pre_cmds, int pre_num, const char **post_cmds, int post_num)
+{
+       ENGINE *e
+*/
 #endif /* HAVE_SSL */
diff --git a/error.c b/error.c
index af67039ac1687bb9092af9e1e2e6dec1650b1f58..8476df624083fbd5a3e55ffd6fa4a4be833d6b04 100644 (file)
--- a/error.c
+++ b/error.c
@@ -53,6 +53,7 @@ ldns_lookup_table ldns_error_str[] = {
        { LDNS_STATUS_CRYPTO_TSIG_BOGUS, "Bogus TSIG signature" },
        { LDNS_STATUS_CRYPTO_TSIG_ERR, "Could not create TSIG signature" },
         { LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION, "DNSSEC signature has expiration date earlier than inception date" },
+       { LDNS_STATUS_ENGINE_KEY_NOT_LOADED, "Unable to load private key from engine" },
        { LDNS_STATUS_RES_NO_NS, "No nameservers defined in the resolver" },
        { LDNS_STATUS_RES_QUERY, "No correct query given to resolver" },
        { LDNS_STATUS_WIRE_INCOMPLETE_HEADER, "header section incomplete" },
index cffcb571421367afe1b40a9344a4921001a9a3ec..67a9624b04ac04669de8087d526859f9ef3da6af 100644 (file)
@@ -43,6 +43,48 @@ $3
 fi
 ])
 
+# Checks for libraries.
+# Check for SSL, original taken from
+# http://www.gnu.org/software/ac-archive/htmldoc/check_ssl.html and
+# modified for NSD and 
+# copied again for use in ldns
+AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
+                                    [enable SSL (will check /usr/local/ssl
+                            /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr/sfw /usr)]),[
+        ],[
+            withval="yes"
+        ])
+    if test x_$withval != x_no; then
+        AC_MSG_CHECKING(for SSL)
+        if test x_$withval = x_ -o x_$withval = x_yes; then
+            withval="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr/sfw /usr"
+        fi
+        for dir in $withval; do
+            ssldir="$dir"
+            if test -f "$dir/include/openssl/ssl.h"; then
+                found_ssl="yes";
+                AC_DEFINE_UNQUOTED([HAVE_SSL], [], [Define if you have the SSL libraries installed.])
+                CPPFLAGS="$CPPFLAGS -I$ssldir/include";
+                break;
+            fi
+        done
+        if test x_$found_ssl != x_yes; then
+            AC_MSG_ERROR(Cannot find the SSL libraries in $withval)
+        else
+            AC_MSG_RESULT(found in $ssldir)
+            HAVE_SSL=yes
+            LDFLAGS="$LDFLAGS -L$ssldir/lib -lcrypto";
+           RUNTIME_PATH="$RUNTIME_PATH -R$ssldir/lib"
+            AC_CHECK_LIB(crypto, HMAC_CTX_init,, [
+                    AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
+                ])
+        fi
+        AC_SUBST(HAVE_SSL)
+       AC_SUBST(RUNTIME_PATH)
+    fi
+
+
+
 dnl routine to help check for needed compiler flags.
 # if the given code compiles without the flag, execute argument 4
 # if the given code only compiles with the flag, execute argument 3
index b7c9722cdcc06cb346fbc9ca952aee5d612c6db7..41decf2d4cc0226363532bf261db38433b6e19e2 100644 (file)
 #include <time.h>
 
 #include <ldns/ldns.h>
+#include <ldns/keys.h>
+
+#include <openssl/conf.h>
+#include <openssl/engine.h>
+
 
 #define MAX_FILENAME_LEN 250
 
@@ -26,11 +31,22 @@ usage(FILE *fp, const char *prog) {
        fprintf(fp, "  -i <date>\tinception date\n");
        fprintf(fp, "  -o <domain>\torigin for the zone\n");
        fprintf(fp, "  -v\t\tprint version and exit\n");
+       fprintf(fp, "  -E <name>\tuse <name> as the crypto engine for signing\n");
+       fprintf(fp, "           \tThis can have a lot of extra options, see -E help for more info\n");
+       fprintf(fp, "  -k <id>,<int>\tuse key id with algorithm int from engine\n");
+       fprintf(fp, "  -K <id>,<int>\tuse key id with algorithm int from engine as KSK\n");
+       fprintf(fp, "\t\tif no key is given (but an external one is used through the engine support, it might be necessary to provide the right algorithm number.\n");
        fprintf(fp, "  keys must be specified by their base name: K<name>+<alg>+<id>\n");
        fprintf(fp, "  both a .key and .private file must present\n");
        fprintf(fp, "  A date can be a timestamp (seconds since the epoch), or of\n  the form <YYYYMMdd[hhmmss]>\n");
 }
 
+void
+usage_openssl(FILE *fp, const char *prog) {
+       fprintf(fp, "Special commands for openssl engines:\n");
+       fprintf(fp, "-c <file>\tOpenSSL config file\n");
+}
+
 void check_tm(struct tm tm)
 {
        if (tm.tm_year < 70) {
@@ -72,6 +88,7 @@ main(int argc, char *argv[])
        int line_nr = 0;
        int c;
        int argi;
+       ENGINE *engine = NULL;
 
        ldns_zone *orig_zone;
        ldns_rr_list *orig_rrs = NULL;
@@ -84,12 +101,19 @@ main(int argc, char *argv[])
        ldns_key *key = NULL;
        ldns_rr *pubkey;
        ldns_key_list *keys;
+       size_t key_i;
        ldns_status s;
 
 
        char *outputfile_name = NULL;
        FILE *outputfile;
        
+       /* tmp vars for engine keys */
+       char *eng_key_l;
+       size_t eng_key_id_len;
+       char *eng_key_id;
+       int eng_key_algo;
+       
        /* we need to know the origin before reading ksk's,
         * so keep an array of filenames until we know it
         */
@@ -105,7 +129,11 @@ main(int argc, char *argv[])
        inception = 0;
        expiration = 0;
        
-       while ((c = getopt(argc, argv, "e:f:i:o:v")) != -1) {
+       keys = ldns_key_list_new();
+
+/*     OPENSSL_config(NULL);*/
+
+       while ((c = getopt(argc, argv, "e:f:i:o:vE:ak:K:")) != -1) {
                switch (c) {
                case 'e':
                        /* try to parse YYYYMMDD first,
@@ -169,6 +197,84 @@ main(int argc, char *argv[])
                        printf("zone signer version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
                        exit(EXIT_SUCCESS);
                        break;
+               case 'E':
+                       if (strncmp("help", optarg, 5) == 0) {
+                               printf("help\n");
+                               exit(EXIT_SUCCESS);
+                       }
+                       ENGINE_load_openssl();
+                       ENGINE_load_builtin_engines();
+                       ENGINE_load_dynamic();
+                       ENGINE_load_cryptodev();
+                       engine = ENGINE_by_id(optarg);
+                       if (!engine) {
+                               printf("No such engine: %s\n", optarg);
+                               engine = ENGINE_get_first();
+                               printf("Available engines:\n");
+                               while (engine) {
+                                       printf("%s\n", ENGINE_get_id(engine));
+                                       engine = ENGINE_get_next(engine);
+                               }
+                               exit(EXIT_FAILURE);
+                       } else {
+                               if (!ENGINE_init(engine)) {
+                                       printf("The engine couldn't initialize\n");
+                                       exit(EXIT_FAILURE);
+                               }
+                               ENGINE_set_default_RSA(engine);
+                               ENGINE_set_default_DSA(engine);
+                               ENGINE_set_default(engine, 0);
+                       }
+                       break;
+               case 'k':
+                       eng_key_l = index(optarg, ',');
+                       if (eng_key_l && strlen(eng_key_l) > 1) {
+                               if (eng_key_l > optarg) {
+                                       eng_key_id_len = (size_t) (eng_key_l - optarg);
+                                       eng_key_id = malloc(eng_key_id_len + 1);
+                                       memcpy(eng_key_id, optarg, eng_key_id_len);
+                                       eng_key_id[eng_key_id_len] = '\0';
+                               } else {
+                                       /* no id given, use default from engine */
+                                       eng_key_id = NULL;
+                               }
+                               
+                               eng_key_algo = atoi(eng_key_l + 1);
+
+                               printf("Engine key id: %s, algo %d\n", eng_key_id, eng_key_algo);
+                               
+                               if (expiration != 0) {
+                                       ldns_key_set_expiration(key, expiration);
+                               }
+                               if (inception != 0) {
+                                       ldns_key_set_inception(key, inception);
+                               }
+
+                               s = ldns_key_new_frm_engine(&key, engine, eng_key_id, eng_key_algo);
+                               if (s == LDNS_STATUS_OK) {
+                                       ldns_key_list_push_key(keys, key);
+                                       /*printf("Added key at %p:\n", key);*/
+                                       /*ldns_key_print(stdout, key);*/
+                               } else {
+                                       printf("Error reading key '%s' from engine: %s\n", eng_key_id, ldns_get_errorstr_by_id(s));
+                                       printf("The available key id's are:\n");
+                                       printf("TODO\n");
+                                       exit(EXIT_FAILURE);
+                               }
+                               
+                               if (eng_key_id) {
+                                       free(eng_key_id);
+                               }
+                       } else {
+                               printf("Error: bad engine key specification (should be: -k <id>,<algorithm>)).\n");
+                               exit(EXIT_FAILURE);
+                       }
+                       
+                       break;
+               case 'K':
+                       printf("Not implemented yet\n");
+                       exit(EXIT_FAILURE);
+                       break;
                default:
                        usage(stderr, prog);
                        exit(EXIT_SUCCESS);
@@ -178,7 +284,8 @@ main(int argc, char *argv[])
        argc -= optind;
        argv += optind;
 
-       if (argc < 2) {
+       if (argc < 1) {
+               printf("Error: not enough arguments\n");
                usage(stdout, prog);
                exit(EXIT_FAILURE);
        } else {
@@ -218,8 +325,6 @@ main(int argc, char *argv[])
                origin = ldns_rr_owner(orig_soa);
        }
 
-       keys = ldns_key_list_new();
-
        /* read the ZSKs */
        argi = 1;
        while (argi < argc) {
@@ -247,6 +352,7 @@ main(int argc, char *argv[])
                                LDNS_FREE(keyfile_name);
                                keyfile_name = LDNS_XMALLOC(char, strlen(keyfile_name_base) + 5);
                                snprintf(keyfile_name, strlen(keyfile_name_base) + 5, "%s.key", keyfile_name_base);
+                               fprintf(stderr, "trying to read %s\n", keyfile_name);
                                keyfile = fopen(keyfile_name, "r");
                                line_nr = 0;
                                if (!keyfile) {
@@ -261,9 +367,9 @@ main(int argc, char *argv[])
                                        ldns_key_list_push_key(keys, key);
                                        ldns_zone_push_rr(orig_zone, ldns_rr_clone(pubkey));
                                        ldns_rr_free(pubkey);
+                                       fclose(keyfile);
                                }
                                LDNS_FREE(keyfile_name);
-                               
                        } else {
                                fprintf(stderr, "Error reading key from %s at line %d\n", argv[argi], line_nr);
                        }
@@ -277,6 +383,20 @@ main(int argc, char *argv[])
                usage(stderr, prog);
                exit(EXIT_FAILURE);
        }
+       
+       /* walk through the keys, and add pubkeys to the orig zone */
+       for (key_i = 0; key_i < ldns_key_list_key_count(keys); key_i++) {
+               key = ldns_key_list_key(keys, key_i);
+               if (!ldns_key_pubkey_owner(key)) {
+                       ldns_key_set_pubkey_owner(key, ldns_rdf_clone(origin));
+                       pubkey = ldns_key2rr(key);
+                       ldns_key_set_flags(key, ldns_rdf2native_int16(ldns_rr_rdf(pubkey, 0)));
+                       ldns_key_set_keytag(key, ldns_calc_keytag(pubkey));
+                       ldns_zone_push_rr(orig_zone, pubkey);
+                       printf("Derived DNSKEY RR:\n");
+                       ldns_rr_print(stdout, pubkey);
+               }
+       }
                        
        signed_zone = ldns_zone_sign(orig_zone, keys);
 
@@ -284,7 +404,7 @@ main(int argc, char *argv[])
                outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN);
                snprintf(outputfile_name, MAX_FILENAME_LEN, "%s.signed", zonefile_name);
        }
-       
+
        if (signed_zone) {
                outputfile = fopen(outputfile_name, "w");
                if (!outputfile) {
@@ -304,6 +424,8 @@ main(int argc, char *argv[])
        
        LDNS_FREE(outputfile_name);
        
+       CRYPTO_cleanup_all_ex_data();
+
        free(prog);
-        exit(EXIT_SUCCESS);
+       exit(EXIT_SUCCESS);
 }
index 5252f3e9b99021e0520f08d2210c12aca5afd0dc..de6e5145e69d85405cd2cbad1637dbe6b14c26cb 100644 (file)
@@ -1065,10 +1065,14 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
 {
        ldns_status status = LDNS_STATUS_OK;
        unsigned char  *bignum;
+       
 #ifdef HAVE_SSL
        /* not used when ssl is not defined */
        ldns_rdf *b64_bignum = NULL;
        uint16_t i;
+       
+       RSA *rsa;
+       DSA *dsa;
 #endif /* HAVE_SSL */
 
        if (!k) {
@@ -1087,6 +1091,8 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
                        case LDNS_SIGN_RSAMD5:
                                /* copied by looking at dnssec-keygen output */
                                /* header */
+                               rsa = ldns_key_rsa_key(k);
+                               
                                ldns_buffer_printf(output,"Private-key-format: v1.2\n");
                                if (ldns_key_algorithm(k) == LDNS_SIGN_RSAMD5) {
                                        ldns_buffer_printf(output,"Algorithm: 1 (RSA)\n");
@@ -1097,7 +1103,7 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
                                /* print to buf, convert to bin, convert to b64,
                                 * print to buf */
                                ldns_buffer_printf(output, "Modulus: "); 
-                               i = (uint16_t)BN_bn2bin(ldns_key_rsa_key(k)->n, bignum);
+                               i = (uint16_t)BN_bn2bin(rsa->n, bignum);
                                if (i > LDNS_MAX_KEYLEN) {
                                        goto error;
                                }
@@ -1107,9 +1113,8 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
                                }
                                ldns_rdf_deep_free(b64_bignum);
                                ldns_buffer_printf(output, "\n"); 
-                               
                                ldns_buffer_printf(output, "PublicExponent: "); 
-                               i = (uint16_t)BN_bn2bin(ldns_key_rsa_key(k)->e, bignum);
+                               i = (uint16_t)BN_bn2bin(rsa->e, bignum);
                                if (i > LDNS_MAX_KEYLEN) {
                                        goto error;
                                }
@@ -1121,142 +1126,190 @@ ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
                                ldns_buffer_printf(output, "\n"); 
 
                                ldns_buffer_printf(output, "PrivateExponent: "); 
-                               i = (uint16_t)BN_bn2bin(ldns_key_rsa_key(k)->d, bignum);
-                               if (i > LDNS_MAX_KEYLEN) {
-                                       goto error;
-                               }
-                               b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                               if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-                                       goto error;
+                               if (rsa->d) {
+                                       i = (uint16_t)BN_bn2bin(rsa->d, bignum);
+                                       if (i > LDNS_MAX_KEYLEN) {
+                                               goto error;
+                                       }
+                                       b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                       if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                               goto error;
+                                       }
+                                       ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n"); 
+                               } else {
+                                       ldns_buffer_printf(output, "(Not available)\n");
                                }
-                               ldns_rdf_deep_free(b64_bignum);
-                               ldns_buffer_printf(output, "\n"); 
-
+                               
                                ldns_buffer_printf(output, "Prime1: "); 
-                               i = (uint16_t)BN_bn2bin(ldns_key_rsa_key(k)->p, bignum);
-                               if (i > LDNS_MAX_KEYLEN) {
-                                       goto error;
-                               }
-                               b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                               if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-                                       goto error;
+                               if (rsa->p) {
+                                       i = (uint16_t)BN_bn2bin(rsa->p, bignum);
+                                       if (i > LDNS_MAX_KEYLEN) {
+                                               goto error;
+                                       }
+                                       b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                       if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                               goto error;
+                                       }
+                                       ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n"); 
+                               } else {
+                                       ldns_buffer_printf(output, "(Not available)\n");
                                }
-                               ldns_rdf_deep_free(b64_bignum);
-                               ldns_buffer_printf(output, "\n"); 
 
                                ldns_buffer_printf(output, "Prime2: ");
-                               i = (uint16_t)BN_bn2bin(ldns_key_rsa_key(k)->q, bignum);
-                               if (i > LDNS_MAX_KEYLEN) {
-                                       goto error;
-                               }
-                               b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                               if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-                                       goto error;
+                               if (rsa->q) {
+                                       i = (uint16_t)BN_bn2bin(rsa->q, bignum);
+                                       if (i > LDNS_MAX_KEYLEN) {
+                                               goto error;
+                                       }
+                                       b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                       if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                               goto error;
+                                       }
+                                       ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n"); 
+                               } else {
+                                       ldns_buffer_printf(output, "(Not available)\n");
                                }
-                               ldns_rdf_deep_free(b64_bignum);
-                               ldns_buffer_printf(output, "\n"); 
 
                                ldns_buffer_printf(output, "Exponent1: ");
-                               i = (uint16_t)BN_bn2bin(ldns_key_rsa_key(k)->dmp1, bignum);
-                               if (i > LDNS_MAX_KEYLEN) {
-                                       goto error;
-                               }
-                               b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                               if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-                                       goto error;
+                               if (rsa->dmp1) {
+                                       i = (uint16_t)BN_bn2bin(rsa->dmp1, bignum);
+                                       if (i > LDNS_MAX_KEYLEN) {
+                                               goto error;
+                                       }
+                                       b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                       if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                               goto error;
+                                       }
+                                       ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n"); 
+                               } else {
+                                       ldns_buffer_printf(output, "(Not available)\n");
                                }
-                               ldns_rdf_deep_free(b64_bignum);
-                               ldns_buffer_printf(output, "\n"); 
 
                                ldns_buffer_printf(output, "Exponent2: "); 
-                               i = (uint16_t)BN_bn2bin(ldns_key_rsa_key(k)->dmq1, bignum);
-                               if (i > LDNS_MAX_KEYLEN) {
-                                       goto error;
-                               }
-                               b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                               if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-                                       goto error;
+                               if (rsa->dmq1) {
+                                       i = (uint16_t)BN_bn2bin(rsa->dmq1, bignum);
+                                       if (i > LDNS_MAX_KEYLEN) {
+                                               goto error;
+                                       }
+                                       b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                       if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                               goto error;
+                                       }
+                                       ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n"); 
+                               } else {
+                                       ldns_buffer_printf(output, "(Not available)\n");
                                }
-                               ldns_rdf_deep_free(b64_bignum);
-                               ldns_buffer_printf(output, "\n"); 
 
                                ldns_buffer_printf(output, "Coefficient: "); 
-                               i = (uint16_t)BN_bn2bin(ldns_key_rsa_key(k)->iqmp, bignum);
-                               if (i > LDNS_MAX_KEYLEN) {
-                                       goto error;
-                               }
-                               b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                               if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-                                       goto error;
+                               if (rsa->iqmp) {
+                                       i = (uint16_t)BN_bn2bin(rsa->iqmp, bignum);
+                                       if (i > LDNS_MAX_KEYLEN) {
+                                               goto error;
+                                       }
+                                       b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                       if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                               goto error;
+                                       }
+                                       ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n"); 
+                               } else {
+                                       ldns_buffer_printf(output, "(Not available)\n");
                                }
-                               ldns_rdf_deep_free(b64_bignum);
-                               ldns_buffer_printf(output, "\n"); 
+                               
+                               RSA_free(rsa);
                                break;
                        case LDNS_SIGN_DSA:
+                               dsa = ldns_key_dsa_key(k);
+                       
                                ldns_buffer_printf(output,"Private-key-format: v1.2\n");
                                ldns_buffer_printf(output,"Algorithm: 3 (DSA)\n");
 
                                /* print to buf, convert to bin, convert to b64,
                                 * print to buf */
                                ldns_buffer_printf(output, "Prime(p): "); 
-                               i = (uint16_t)BN_bn2bin(ldns_key_dsa_key(k)->p, bignum);
-                               if (i > LDNS_MAX_KEYLEN) {
-                                       goto error;
-                               }
-                               b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                               if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-                                       goto error;
+                               if (dsa->p) {
+                                       i = (uint16_t)BN_bn2bin(dsa->p, bignum);
+                                       if (i > LDNS_MAX_KEYLEN) {
+                                               goto error;
+                                       }
+                                       b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                       if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                               goto error;
+                                       }
+                                       ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n"); 
+                               } else {
+                                       printf("(Not available)\n");
                                }
-                               ldns_rdf_deep_free(b64_bignum);
-                               ldns_buffer_printf(output, "\n"); 
 
                                ldns_buffer_printf(output, "Subprime(q): "); 
-                               i = (uint16_t)BN_bn2bin(ldns_key_dsa_key(k)->q, bignum);
-                               if (i > LDNS_MAX_KEYLEN) {
-                                       goto error;
-                               }
-                               b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                               if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-                                       goto error;
+                               if (dsa->q) {
+                                       i = (uint16_t)BN_bn2bin(dsa->q, bignum);
+                                       if (i > LDNS_MAX_KEYLEN) {
+                                               goto error;
+                                       }
+                                       b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                       if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                               goto error;
+                                       }
+                                       ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n"); 
+                               } else {
+                                       printf("(Not available)\n");
                                }
-                               ldns_rdf_deep_free(b64_bignum);
-                               ldns_buffer_printf(output, "\n"); 
 
                                ldns_buffer_printf(output, "Base(g): "); 
-                               i = (uint16_t)BN_bn2bin(ldns_key_dsa_key(k)->g, bignum);
-                               if (i > LDNS_MAX_KEYLEN) {
-                                       goto error;
-                               }
-                               b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                               if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-                                       goto error;
+                               if (dsa->g) {
+                                       i = (uint16_t)BN_bn2bin(dsa->g, bignum);
+                                       if (i > LDNS_MAX_KEYLEN) {
+                                               goto error;
+                                       }
+                                       b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                       if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                               goto error;
+                                       }
+                                       ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n"); 
+                               } else {
+                                       printf("(Not available)\n");
                                }
-                               ldns_rdf_deep_free(b64_bignum);
-                               ldns_buffer_printf(output, "\n"); 
 
                                ldns_buffer_printf(output, "Private_value(x): "); 
-                               i = (uint16_t)BN_bn2bin(ldns_key_dsa_key(k)->priv_key, bignum);
-                               if (i > LDNS_MAX_KEYLEN) {
-                                       goto error;
-                               }
-                               b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                               if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-                                       goto error;
+                               if (dsa->priv_key) {
+                                       i = (uint16_t)BN_bn2bin(dsa->priv_key, bignum);
+                                       if (i > LDNS_MAX_KEYLEN) {
+                                               goto error;
+                                       }
+                                       b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                       if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                               goto error;
+                                       }
+                                       ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n"); 
+                               } else {
+                                       printf("(Not available)\n");
                                }
-                               ldns_rdf_deep_free(b64_bignum);
-                               ldns_buffer_printf(output, "\n"); 
 
                                ldns_buffer_printf(output, "Public_value(y): "); 
-                               i = (uint16_t)BN_bn2bin(ldns_key_dsa_key(k)->pub_key, bignum);
-                               if (i > LDNS_MAX_KEYLEN) {
-                                       goto error;
-                               }
-                               b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                               if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-                                       goto error;
+                               if (dsa->pub_key) {
+                                       i = (uint16_t)BN_bn2bin(dsa->pub_key, bignum);
+                                       if (i > LDNS_MAX_KEYLEN) {
+                                               goto error;
+                                       }
+                                       b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                       if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+                                               goto error;
+                                       }
+                                       ldns_rdf_deep_free(b64_bignum);
+                                       ldns_buffer_printf(output, "\n"); 
+                               } else {
+                                       printf("(Not available)\n");
                                }
-                               ldns_rdf_deep_free(b64_bignum);
-                               ldns_buffer_printf(output, "\n"); 
                                break;
                        case LDNS_SIGN_HMACMD5:
                                /* is the filefmt specified for TSIG.. don't know */
diff --git a/keys.c b/keys.c
index 53f3aab7a7519007b7433a87eb6dc3046c50ba44..116176fb00ab151ac08ef111816799f5c43163f0 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -16,6 +16,7 @@
 
 #ifdef HAVE_SSL
 #include <openssl/ssl.h>
+#include <openssl/engine.h>
 #endif /* HAVE_SSL */
 
 ldns_lookup_table ldns_signing_algorithms[] = {
@@ -56,11 +57,10 @@ ldns_key_new()
                ldns_key_set_inception(newkey, 0);
                ldns_key_set_expiration(newkey, 0);
                ldns_key_set_pubkey_owner(newkey, NULL);
-               ldns_key_set_rsa_key(newkey, NULL);
-               ldns_key_set_dsa_key(newkey, NULL);
                ldns_key_set_hmac_key(newkey, NULL);
                return newkey;
        }
+return NULL;
 }
 
 ldns_status 
@@ -69,6 +69,24 @@ ldns_key_new_frm_fp(ldns_key **k, FILE *fp)
        return ldns_key_new_frm_fp_l(k, fp, NULL);
 }
 
+#ifdef HAVE_SSL
+ldns_status
+ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg)
+{
+       ldns_key *k;
+       
+       k = ldns_key_new();
+       k->_key.key = ENGINE_load_private_key(e, key_id, UI_OpenSSL(), NULL);
+       ldns_key_set_algorithm(k, alg);
+       if (!k->_key.key) {
+               return LDNS_STATUS_ENGINE_KEY_NOT_LOADED;
+       } else {
+               *key = k;
+               return LDNS_STATUS_OK;
+       }
+}
+#endif
+
 ldns_status
 ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
 {
@@ -76,6 +94,8 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
        char *d;
        ldns_signing_algorithm alg;
        ldns_rr *key_rr;
+       RSA *rsa;
+       DSA *dsa;
 
        k = ldns_key_new();
 
@@ -128,20 +148,23 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
                        return LDNS_STATUS_SYNTAX_ALG_ERR;
                case LDNS_SIGN_RSAMD5:
                case LDNS_SIGN_RSASHA1:
-
                        ldns_key_set_algorithm(k, alg);
-                       ldns_key_set_rsa_key(k, ldns_key_new_frm_fp_rsa_l(fp, line_nr));
-
+                       rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr);
+                       ldns_key_set_rsa_key(k, rsa);
+                       RSA_free(rsa);
                        break;
                case LDNS_SIGN_DSA:
                        ldns_key_set_algorithm(k, alg);
-                       ldns_key_set_dsa_key(k, ldns_key_new_frm_fp_dsa_l(fp, line_nr));
+                       dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr);
+                       ldns_key_set_dsa_key(k, dsa);
+                       DSA_free(dsa);
                        break;
        }
 
        key_rr = ldns_key2rr(k);
        ldns_key_set_keytag(k, ldns_calc_keytag(key_rr));
        ldns_rr_free(key_rr);
+
        if (key) {
                *key = k;
                return LDNS_STATUS_OK;
@@ -393,6 +416,7 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
                        if (RSA_check_key(r) != 1) {
                                return NULL;
                        }
+                       
                        ldns_key_set_rsa_key(k, r);
                        break;
                case LDNS_SIGN_DSA:
@@ -438,16 +462,26 @@ ldns_key_set_flags(ldns_key *k, uint16_t f)
        k->_extra.dnssec.flags = f;
 }
 
+void
+ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e)
+{
+       k->_key.key = e;
+}
+
 void
 ldns_key_set_rsa_key(ldns_key *k, RSA *r)
 {
-       k->_key.rsa = r;
+       EVP_PKEY *key = EVP_PKEY_new();
+       EVP_PKEY_set1_RSA(key, r);
+       k->_key.key = key;
 }
 
 void
 ldns_key_set_dsa_key(ldns_key *k, DSA *d)
 {
-       k->_key.dsa  = d;
+       EVP_PKEY *key = EVP_PKEY_new();
+       EVP_PKEY_set1_DSA(key, d);
+       k->_key.key  = key;
 }
 
 void
@@ -509,16 +543,22 @@ ldns_key_algorithm(const ldns_key *k)
        return k->_alg;
 }
 
+EVP_PKEY *
+ldns_key_evp_key(const ldns_key *k)
+{
+       return k->_key.key;
+}
+
 RSA *
 ldns_key_rsa_key(const ldns_key *k)
 {
-       return k->_key.rsa;
+       return EVP_PKEY_get1_RSA(k->_key.key);
 }
 
 DSA *
 ldns_key_dsa_key(const ldns_key *k)
 {
-       return k->_key.dsa;
+       return EVP_PKEY_get1_DSA(k->_key.key);
 }
 
 unsigned char *
@@ -691,6 +731,8 @@ ldns_key2rr(const ldns_key *k)
        ldns_rdf *keybin;
        unsigned char *bin;
        uint16_t size;
+       RSA *rsa = NULL;
+       DSA *dsa = NULL;
 
        pubkey = ldns_rr_new();
        if (!k) {
@@ -720,22 +762,40 @@ ldns_key2rr(const ldns_key *k)
                case LDNS_SIGN_RSAMD5:
                        ldns_rr_push_rdf(pubkey,
                                        ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_RSAMD5));
-                       if (!ldns_key_rsa2bin(bin, ldns_key_rsa_key(k), &size)) {
+                       rsa =  ldns_key_rsa_key(k);
+                       if (!rsa) {
                                return NULL;
+                       } else {
+                               if (!ldns_key_rsa2bin(bin, rsa, &size)) {
+                                       return NULL;
+                               }
+                               RSA_free(rsa);
                        }
                        break;
                case LDNS_SIGN_RSASHA1:
                        ldns_rr_push_rdf(pubkey,
                                        ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_RSASHA1));
-                       if (!ldns_key_rsa2bin(bin, ldns_key_rsa_key(k), &size)) {
+                       rsa =  ldns_key_rsa_key(k);
+                       if (!rsa) {
                                return NULL;
+                       } else {
+                               if (!ldns_key_rsa2bin(bin, rsa, &size)) {
+                                       return NULL;
+                               }
+                               RSA_free(rsa);
                        }
                        break;
                case LDNS_SIGN_DSA:
                        ldns_rr_push_rdf(pubkey,
                                        ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA));
-                       if (!ldns_key_dsa2bin(bin, ldns_key_dsa_key(k), &size)) {
+                       rsa =  ldns_key_dsa_key(k);
+                       if (!rsa) {
                                return NULL;
+                       } else {
+                               if (!ldns_key_dsa2bin(bin, dsa, &size)) {
+                                       return NULL;
+                               }
+                               DSA_free(dsa);
                        }
                        break;
                case LDNS_SIGN_HMACMD5:
@@ -762,6 +822,7 @@ ldns_key_deep_free(ldns_key *key)
        if (ldns_key_pubkey_owner(key)) {
                ldns_rdf_deep_free(ldns_key_pubkey_owner(key));
        }
+/*
        switch(ldns_key_algorithm(key)) {
        case LDNS_SIGN_RSASHA1:
        case LDNS_SIGN_RSAMD5:
@@ -777,6 +838,10 @@ ldns_key_deep_free(ldns_key *key)
        case LDNS_SIGN_HMACMD5:
                break;
        }
+*/
+       if (ldns_key_evp_key(key)) {
+               EVP_PKEY_free(ldns_key_evp_key(key));
+       }
        LDNS_FREE(key);
 }
 
index 0e4c26fbf27e9aea9de5a24858889ce1675ef6be..de0cade1440add6942a59e4095d054c3c99d5f47 100644 (file)
@@ -24,6 +24,7 @@
 
 #ifdef HAVE_SSL
 #include <openssl/ssl.h>
+#include <openssl/evp.h>
 #endif /* HAVE_SSL */
 #include <ldns/common.h>
 #include <ldns/packet.h>
@@ -86,6 +87,19 @@ ldns_status ldns_verify_rrsig_keylist(ldns_rr_list *rrset, ldns_rr *rrsig, const
  */
 ldns_status ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key);
 
+/**
+ * verifies a buffer with signature data for a buffer with rrset data 
+ * with an EVP_PKEY
+ *
+ * \param[in] sig the signature data
+ * \param[in] rrset the rrset data, sorted and processed for verification
+ * \param[in] key the EVP key structure
+ * \param[in] digest_type The digest type of the signature
+ */
+#ifdef HAVE_SSL
+ldns_status ldns_verify_rrsig_evp(ldns_buffer *sig, ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type);
+#endif
+
 /**
  * verifies a buffer with signature data (DSA) for a buffer with rrset data 
  * with a buffer with key data.
@@ -161,6 +175,7 @@ ldns_rr_list *ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys);
  * \return a ldns_rdf with the signed data
  */
 ldns_rdf *ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key);
+ldns_rdf *ldns_sign_public_evp(ldns_buffer *to_sign, EVP_PKEY *key, const EVP_MD *digest_type);
 /**
  * Sign a buffer with the RSA key (hash with MD5)
  * \param[in] to_sign buffer with the data
@@ -229,7 +244,7 @@ ldns_status ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, ldns_rr_li
  * \return the signed zone
  */
 ldns_zone *ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list);
+
 /**
  * Initialize the random function. This calls OpenSSL
  * \param[in] fd a file providing entropy data
index 0e01f1a01781eeb360cf72fb51fde2b3b5c18fb1..a3a867613468969f2e1038dbfcbdf7e1ba10e5cd 100644 (file)
@@ -60,6 +60,7 @@ enum ldns_enum_status
         LDNS_STATUS_CRYPTO_TSIG_ERR,
        LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION,
         LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR,
+        LDNS_STATUS_ENGINE_KEY_NOT_LOADED,
         LDNS_STATUS_RES_NO_NS,
         LDNS_STATUS_RES_QUERY,
         LDNS_STATUS_WIRE_INCOMPLETE_HEADER,
index eeced611f81e4180c611d75552fe761e4587d146..757d0384aad04f48802e16b1956c1bb09e6e3868 100644 (file)
@@ -87,8 +87,7 @@ struct ldns_struct_key {
        /* TODO remove unions? */
        union {
 #ifdef HAVE_SSL
-               RSA     *rsa;
-               DSA     *dsa;
+                EVP_PKEY *key;
 #endif /* HAVE_SSL */
                unsigned char *hmac;
        } _key;
@@ -171,6 +170,13 @@ ldns_status ldns_key_new_frm_fp(ldns_key **k, FILE *fp);
 ldns_status ldns_key_new_frm_fp_l(ldns_key **k, FILE *fp, int *line_nr);
 
 #ifdef HAVE_SSL
+/**
+ * Read the key with the given id from the given engine and store it
+ * in the given ldns_key structure. The algorithm type is set
+ */
+ldns_status ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm);
+
+
 /**
  * frm_fp helper function. This function parsed the
  * remainder of the (RSA) priv. key file generated from bind9
@@ -220,6 +226,12 @@ DSA *ldns_key_new_frm_fp_dsa_l(FILE *fp, int *line_nr);
  */
 void ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l);
 #ifdef HAVE_SSL
+/**
+ * Set the key's evp key
+ * \param[in] k the key
+ * \param[in] e the evp key
+ */
+void ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e);
 /**
  * Set the key's rsa data
  * \param[in] k the key
@@ -312,6 +324,12 @@ ldns_key *ldns_key_list_key(const ldns_key_list *key, size_t nr);
  * \return the RSA * structure in the key
  */
 RSA *ldns_key_rsa_key(const ldns_key *k);
+/**
+ * returns the (openssl) EVP struct contained in the key
+ * \param[in] k the key to look in
+ * \return the RSA * structure in the key
+ */
+EVP_PKEY *ldns_key_evp_key(const ldns_key *k);
 #endif /* HAVE_SSL */
 
 /**