]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
ED448 support.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 5 Apr 2018 14:41:11 +0000 (16:41 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 5 Apr 2018 14:41:11 +0000 (16:41 +0200)
Changelog
dnssec_verify.c
host2str.c
keys.c

index 4eef010db20655fc068c63bf22b05e6be9da75db..3a8faaaecd89b8c3b48f1d6d95b24b112aded682 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -26,6 +26,7 @@
          Thanks Jan Vcelak
        * bugfix #1399: ldns_pkt2wire() Python binding is broken.
          Thanks James Raftery
+       * ED25519 and ED448 support.
 
 1.7.0  2016-12-20
        * Fix lookup of relative names in ldns_resolver_search.
index a6b985041264c09e50ed3f5ae9fc05f63e8b247f..ed07e4e03a90f9f01646400c84e005c41d0a0fac 100644 (file)
@@ -1899,27 +1899,19 @@ ldns_verify_rrsig_ed25519_raw(unsigned char* sig, size_t siglen,
 EVP_PKEY*
 ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
 {
-        const unsigned char* pp = key; /* pp gets modified by o2i() */
+       /* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
+       uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
+               0x71, 0x03, 0x3a, 0x00};
+        int pre_len = 12;
+       uint8_t buf[256];
         EVP_PKEY *evp_key;
-        EC_KEY *ec;
-       if(keylen != 57)
+       /* pp gets modified by d2i() */
+        const unsigned char* pp = (unsigned char*)buf;
+       if(keylen != 57 || keylen + pre_len > sizeof(buf))
                return NULL; /* wrong length */
-        ec = EC_KEY_new_by_curve_name(NID_ED448);
-       if(!ec) return NULL;
-        if(!o2i_ECPublicKey(&ec, &pp, (int)keylen)) {
-                EC_KEY_free(ec);
-                return NULL;
-       }
-        evp_key = EVP_PKEY_new();
-        if(!evp_key) {
-                EC_KEY_free(ec);
-                return NULL;
-        }
-        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
-               EVP_PKEY_free(evp_key);
-               EC_KEY_free(ec);
-               return NULL;
-       }
+       memmove(buf, pre, pre_len);
+       memmove(buf+pre_len, key, keylen);
+       evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
         return evp_key;
 }
 
index f459c476aca7d9d0ed29431ac1e0bc0ef782662a..154504c80629bf56102ef793831bb71f34e38757 100644 (file)
@@ -1966,22 +1966,6 @@ ldns_ed25519_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
 }
 #endif
 
-#if defined(USE_ED448)
-/* debug printout routine */
-static void ed448_print_hex(const char* str, uint8_t* d, int len)
-{
-       const char hex[] = "0123456789abcdef";
-       int i;
-       printf("%s [len=%d]: ", str, len);
-       for(i=0; i<len; i++) {
-               int x = (d[i]&0xf0)>>4;
-               int y = (d[i]&0x0f);
-               printf("%c%c", hex[x], hex[y]);
-       }
-       printf("\n");
-}
-#endif
-
 #if defined(HAVE_SSL) && defined(USE_ED448)
 static ldns_status
 ldns_ed448_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
@@ -1994,10 +1978,8 @@ ldns_ed448_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
        ldns_buffer_printf(output, "PrivateKey: ");
 
        ret = i2d_PrivateKey(p, &pp);
-       /* printout hex to find length of ASN */
-       ed448_print_hex("ED448 privkey i2d", pp, ret);
-       /* some-ASN (??) + 56byte key */
-       if(ret != 16 + 56) {
+       /* some-ASN + 57byte key */
+       if(ret != 16 + 57) {
                OPENSSL_free(pp);
                return LDNS_STATUS_ERR;
        }
diff --git a/keys.c b/keys.c
index ca2883fc17fe29325029acaf6566c1226c8a60d1..bb7bd6cd7cae2635aad910ce618b41d7deb64a25 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -358,22 +358,6 @@ ldns_key_new_frm_fp_ed25519_l(FILE* fp, int* line_nr)
 }
 #endif
 
-#if defined(USE_ED448)
-/* debug printout routine */
-static void print_hex(const char* str, uint8_t* d, int len)
-{
-       const char hex[] = "0123456789abcdef";
-       int i;
-       printf("%s [len=%d]: ", str, len);
-       for(i=0; i<len; i++) {
-               int x = (d[i]&0xf0)>>4;
-               int y = (d[i]&0x0f);
-               printf("%c%c", hex[x], hex[y]);
-       }
-       printf("\n");
-}
-#endif
-
 #ifdef USE_ED448
 /** turn private key buffer into EC_KEY structure */
 static EVP_PKEY*
@@ -382,31 +366,20 @@ ldns_ed448_priv_raw(uint8_t* pkey, int plen)
        const unsigned char* pp;
        uint8_t buf[256];
        int buflen = 0;
-       uint8_t pre[] = {0x30, 0x4b, 0x02, 0x01, 0x01, 0x04, 0x39};
-       int pre_len = 7;
-       uint8_t post[] = {0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
-               0x01, 0xda, 0x47, 0x0f, 0x02};
-       int post_len = 13;
-       int i;
-       /* ASN looks like this for ED25519
-        * And for ED448, the parameters are ...02 instead of ...01
-        * For ED25519 it was:
-        * 30320201010420 <32byteskey>
-        * andparameters a00b06092b06010401da470f01
-        * (noparameters, preamble is 30250201010420).
+       uint8_t pre[] = {0x30, 0x47, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x71, 0x04, 0x3b, 0x04, 0x39};
+       int pre_len = 16;
+       /* ASN looks like this for ED448
+        * 3047020100300506032b6571043b0439 <57bytekey>
         * the key is reversed (little endian).
-        *
-        * For ED448 the key is 57 bytes, and that changes lengths.
-        * 304b0201010439 <57bytekey> a00b06092b06010401da470f02
         */
-       buflen = pre_len + plen + post_len;
+       buflen = pre_len + plen;
        if((size_t)buflen > sizeof(buf))
                return NULL;
        memmove(buf, pre, pre_len);
-       /* reverse the pkey into the buf */
-       for(i=0; i<plen; i++)
-               buf[pre_len+i] = pkey[plen-1-i];
-       memmove(buf+pre_len+plen, post, post_len);
+       memmove(buf+pre_len, pkey, plen);
+       /* reverse the pkey into the buf - key is not reversed it seems */
+       /* for(i=0; i<plen; i++)
+               buf[pre_len+i] = pkey[plen-1-i]; */
        pp = buf;
        return d2i_PrivateKey(NID_ED448, NULL, &pp, buflen);
 }
@@ -1800,21 +1773,16 @@ ldns_key_ed4482bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
 {
        int i;
        unsigned char* pp = NULL;
-       unsigned len = i2d_PUBKEY(k, &pp);
-       /* printout ASN format for pubkey */
-       print_hex("ed448 pubkey i2d", pp, len);
-       free(pp); pp = NULL;
-       /* untested, not sure what the lengths are for the prefix */
-       if(i2d_PUBKEY(k, &pp) != 12 + 56) {
-               /* expect 12 byte(ASN header) and 56 byte(pubkey) */
+       if(i2d_PUBKEY(k, &pp) != 12 + 57) {
+               /* expect 12 byte(ASN header) and 57 byte(pubkey) */
                free(pp);
                return false;
        }
        /* omit ASN header */
-       for(i=0; i<56; i++)
+       for(i=0; i<57; i++)
                data[i] = pp[i+12];
        free(pp);
-       *size = 56;
+       *size = 57;
        return true;
 }
 #endif /* USE_ED448 */