]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
added two way conversion for asn1 representation of DSA signatures (as
authorJelte Jansen <jelte@NLnetLabs.nl>
Mon, 21 Apr 2008 10:04:07 +0000 (10:04 +0000)
committerJelte Jansen <jelte@NLnetLabs.nl>
Mon, 21 Apr 2008 10:04:07 +0000 (10:04 +0000)
specified in RFC2459). This is now used when creating signatures too.

string representation of DSA signature algorithm fixed
added some 'const' values to function arguments

dnssec.c
dnssec_sign.c
dnssec_verify.c
keys.c
ldns/buffer.h
ldns/dnssec.h

index 0d3fa802f422f341abaa0418ff785367f9835384..c58470f892e2290f12a880d91a51690affc7d917 100644 (file)
--- a/dnssec.c
+++ b/dnssec.c
@@ -1595,4 +1595,70 @@ ldns_dnssec_default_replace_signatures(ldns_rr *sig, void *n)
        return LDNS_SIGNATURE_REMOVE_ADD_NEW;
 }
 
+ldns_rdf *
+ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
+                                                 const long sig_len)
+{
+       ldns_rdf *sigdata_rdf;
+       DSA_SIG *dsasig;
+       unsigned char *dsasig_data = ldns_buffer_begin(sig);
+
+       dsasig = d2i_DSA_SIG(NULL,
+                                        (const unsigned char **)&dsasig_data,
+                                        sig_len);
+       if (!dsasig) {
+               return NULL;
+       }
+
+       dsasig_data = LDNS_XMALLOC(unsigned char, 41);
+       dsasig_data[0] = 0;
+       BN_bn2bin(dsasig->r, &dsasig_data[1]);
+       BN_bn2bin(dsasig->s, &dsasig_data[21]);
+       
+       sigdata_rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, 41, dsasig_data);
+       DSA_SIG_free(dsasig);
+
+       return sigdata_rdf;
+}
+
+ldns_status
+ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+                                                 const ldns_rdf *sig_rdf)
+{
+       /* the EVP api wants the DER encoding of the signature... */
+       uint8_t t;
+       BIGNUM *R, *S;
+       DSA_SIG *dsasig;
+       unsigned char *raw_sig = NULL;
+       int raw_sig_len;
+       
+       /* extract the R and S field from the sig buffer */
+       t = ldns_rdf_data(sig_rdf)[0];
+       R = BN_new();
+       (void) BN_bin2bn(ldns_rdf_data(sig_rdf) + 1, SHA_DIGEST_LENGTH, R);
+       S = BN_new();
+       (void) BN_bin2bn(ldns_rdf_data(sig_rdf) + 21, SHA_DIGEST_LENGTH, S);
+
+       dsasig = DSA_SIG_new();
+       if (!dsasig) {
+               return LDNS_STATUS_MEM_ERR;
+       }
+
+       dsasig->r = R;
+       dsasig->s = S;
+       
+       raw_sig_len = i2d_DSA_SIG(dsasig, &raw_sig);
+       
+       if (ldns_buffer_reserve(target_buffer, raw_sig_len)) {
+               ldns_buffer_write(target_buffer, raw_sig, raw_sig_len);
+       }
+
+       DSA_SIG_free(dsasig);
+       free(raw_sig);
+
+       return ldns_buffer_status(target_buffer);
+}
+
+
+
 #endif /* HAVE_SSL */
index 49176cbe73938999b1aa8d331437704add234645..6ba7a218568470d92cb2e3422efc28a6dfbf3e31 100644 (file)
@@ -178,8 +178,12 @@ ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
                        switch(ldns_key_algorithm(current_key)) {
                        case LDNS_SIGN_DSA:
                        case LDNS_DSA_NSEC3:
-                               b64rdf = ldns_sign_public_evp(sign_buf, ldns_key_evp_key(current_key), EVP_dss1());
-                               /*                                      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_dss1());
+                               /*
+                               b64rdf = ldns_sign_public_dsa(sign_buf, ldns_key_dsa_key(current_key));
+                               */
                                break;
                        case LDNS_SIGN_RSASHA1:
                        case LDNS_SIGN_RSASHA1_NSEC3:
@@ -280,6 +284,17 @@ ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
        return sigdata_rdf;
 }
 
+#ifdef HAVE_PKCS
+ldns_rdf *
+ldns_Sign_public_pkcs(ldns_Buffer *to_sign,
+                                 char *key_id,
+                                 const digest_type
+                                 )
+{
+
+}
+#endif
+
 ldns_rdf *
 ldns_sign_public_evp(ldns_buffer *to_sign,
                                 EVP_PKEY *key,
@@ -307,20 +322,34 @@ ldns_sign_public_evp(ldns_buffer *to_sign,
 
        EVP_MD_CTX_init(&ctx);
        r = EVP_SignInit(&ctx, md_type);
-       if(r == 1)
+       if(r == 1) {
                r = EVP_SignUpdate(&ctx, (unsigned char*)
                                            ldns_buffer_begin(to_sign), 
                                            ldns_buffer_position(to_sign));
-       if(r == 1)
+       } else {
+               ldns_buffer_free(b64sig);
+               return NULL;
+       }
+       if(r == 1) {
                r = EVP_SignFinal(&ctx, (unsigned char*)
                                           ldns_buffer_begin(b64sig), &siglen, key);
+       } else {
+               ldns_buffer_free(b64sig);
+               return NULL;
+       }
        if(r != 1) {
                ldns_buffer_free(b64sig);
                return NULL;
        }
 
-       sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
-                                                                ldns_buffer_begin(b64sig));
+       /* unfortunately, OpenSSL output is differenct from DNS DSA format */
+       if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
+               sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
+       } else {
+               /* ok output for other types is the same */
+               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;
index 9f0783e76f0b84da571735dc1155ec72e3b14b15..bdf406c7be004ef63fa07700083bfc9ccba5baf9 100644 (file)
@@ -1459,7 +1459,19 @@ ldns_verify_rrsig_keylist(ldns_rr_list *rrset, ldns_rr *rrsig, const ldns_rr_lis
        }
        
        /* create a buffer with b64 signature rdata */
-       if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+       if (sig_algo == LDNS_DSA) {
+               if (ldns_convert_dsa_rrsig_rdf2asn1(rawsig_buf,
+                                                                        ldns_rr_rdf(rrsig, 8))
+                   != LDNS_STATUS_OK) {
+                       ldns_buffer_free(rawsig_buf);
+                       ldns_buffer_free(verify_buf);
+                       ldns_rr_list_deep_free(rrset_clone);
+                       ldns_rr_list_deep_free(validkeys);
+                       return LDNS_STATUS_MEM_ERR;
+               }
+       } else if (ldns_rdf2buffer_wire(rawsig_buf, 
+                                                       ldns_rr_rdf(rrsig, 8))
+                   != LDNS_STATUS_OK) {
                ldns_buffer_free(rawsig_buf);
                ldns_buffer_free(verify_buf);
                ldns_rr_list_deep_free(rrset_clone);
@@ -1583,44 +1595,6 @@ ldns_verify_rrsig_keylist(ldns_rr_list *rrset, ldns_rr *rrsig, const ldns_rr_lis
        }
 }
 
-ldns_status
-ldns_convert_dsa_rrsig_rdata(ldns_buffer *target_buffer,
-                             ldns_rdf *sig_rdf)
-{
-       /* the EVP api wants the DER encoding of the signature... */
-       uint8_t t;
-       BIGNUM *R, *S;
-       DSA_SIG *dsasig;
-       unsigned char *raw_sig = NULL;
-       int raw_sig_len;
-       
-       /* extract the R and S field from the sig buffer */
-       t = ldns_rdf_data(sig_rdf)[0];
-       R = BN_new();
-       (void) BN_bin2bn(ldns_rdf_data(sig_rdf) + 1, SHA_DIGEST_LENGTH, R);
-       S = BN_new();
-       (void) BN_bin2bn(ldns_rdf_data(sig_rdf) + 21, SHA_DIGEST_LENGTH, S);
-
-       dsasig = DSA_SIG_new();
-       if (!dsasig) {
-               return LDNS_STATUS_MEM_ERR;
-       }
-
-       dsasig->r = R;
-       dsasig->s = S;
-       
-       raw_sig_len = i2d_DSA_SIG(dsasig, &raw_sig);
-       
-       if (ldns_buffer_reserve(target_buffer, raw_sig_len)) {
-               ldns_buffer_write(target_buffer, raw_sig, raw_sig_len);
-       }
-
-       DSA_SIG_free(dsasig);
-       free(raw_sig);
-
-       return ldns_buffer_status(target_buffer);
-}
-
 #if 0
 void
 print_dates(time_t now, time_t inception)
@@ -1716,12 +1690,15 @@ ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
                break;
        case LDNS_DSA:
        case LDNS_DSA_NSEC3:
-               if (ldns_convert_dsa_rrsig_rdata(rawsig_buf,
-                                                                  ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
-               /*
-               if (ldns_rdf2buffer_wire(rawsig_buf,
-                                                       ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
-               */
+               /* EVP takes rfc2459 format, which is a tad longer than dns format */
+               exit(0);
+               if (ldns_convert_dsa_rrsig_rdf2asn1(rawsig_buf,
+                                                                        ldns_rr_rdf(rrsig, 8))
+                   != LDNS_STATUS_OK) {
+                       /*
+                         if (ldns_rdf2buffer_wire(rawsig_buf,
+                         ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+                       */
                        ldns_buffer_free(rawsig_buf);
                        ldns_buffer_free(verify_buf);
                        return LDNS_STATUS_MEM_ERR;
diff --git a/keys.c b/keys.c
index d4e1d615eaeb530128f1f3e0e6cd7d0cea461116..ab74e9a5e951299c0d26efbe072f576db47266bf 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -25,7 +25,7 @@ ldns_lookup_table ldns_signing_algorithms[] = {
         { LDNS_SIGN_RSASHA1, "RSASHA1" },
         { LDNS_SIGN_RSASHA256, "RSASHA256" },
         { LDNS_SIGN_RSASHA512, "RSASHA512" },
-        { LDNS_SIGN_DSA, "DSAMD5" },
+        { LDNS_SIGN_DSA, "DSA" },
         { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" },
         { 0, NULL }
 };
@@ -860,6 +860,8 @@ ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
        memcpy(data, &T, 1);
 
        if (T > 8) {
+               fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)");
+               fprintf(stderr, " not implemented\n");
                return false;
        }
 
index a8c21703d7489d92ebe757188bd801a2723f367f..f2edb842df2eab05ce09932fade1953836655c07 100644 (file)
@@ -250,7 +250,7 @@ bool ldns_buffer_reserve(ldns_buffer *buffer, size_t amount);
  * \return the pointer to the data
  */
 INLINE uint8_t *
-ldns_buffer_at(ldns_buffer *buffer, size_t at)
+ldns_buffer_at(const ldns_buffer *buffer, size_t at)
 {
        assert(at <= buffer->_limit);
        return buffer->_data + at;
@@ -263,7 +263,7 @@ ldns_buffer_at(ldns_buffer *buffer, size_t at)
  * \return the pointer
  */
 INLINE uint8_t *
-ldns_buffer_begin(ldns_buffer *buffer)
+ldns_buffer_begin(const ldns_buffer *buffer)
 {
        return ldns_buffer_at(buffer, 0);
 }
index 8c622e2643b93b0c5bc0ef26a51760534067420f..775960a6c573750fe3764f1e0ee50b4547888170 100644 (file)
@@ -411,4 +411,29 @@ int ldns_dnssec_default_delete_signatures(ldns_rr *sig, void *n);
  */
 int ldns_dnssec_default_replace_signatures(ldns_rr *sig, void *n);
 
+/**
+ * Converts the DSA signature from ASN1 representation (RFC2459, as 
+ * used by OpenSSL) to raw signature data as used in DNS (rfc2536)
+ *
+ * \param[in] asn1_sig The signature in RFC2459 format
+ * \param[in] sig_len The length of the signature
+ * \return a new rdf with the signature
+ */
+ldns_rdf *
+ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
+                                                 const long sig_len);
+
+/**
+ * Converts the RRSIG signature RDF (in rfc2536 format) to a buffer
+ * with the signature in rfc2459 format
+ *
+ * \param[out] target_buffer, buffer to place the signature data
+ * \param[in] sig_rdf The signature rdf to convert
+ * \return LDNS_STATUS_OK on success, error code otherwise
+ */
+ldns_status
+ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+                                                 const ldns_rdf *sig_rdf);
+
+
 #endif /* LDNS_DNSSEC_H */