summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>2018-04-05 16:41:11 +0200
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>2018-04-05 16:41:11 +0200
commit794ee34c6d064ae4ec6a5aab9445ba156735eefe (patch)
tree8e3e491d2f32c0ab8ebc4943f501c7a11fedd31c
parenta2ecd64c9dd9831335bb5de50ef02488e78092d2 (diff)
downloadldns-794ee34c6d064ae4ec6a5aab9445ba156735eefe.tar.gz
ED448 support.
-rw-r--r--Changelog1
-rw-r--r--dnssec_verify.c30
-rw-r--r--host2str.c22
-rw-r--r--keys.c58
4 files changed, 27 insertions, 84 deletions
diff --git a/Changelog b/Changelog
index 4eef010d..3a8faaae 100644
--- 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.
diff --git a/dnssec_verify.c b/dnssec_verify.c
index a6b98504..ed07e4e0 100644
--- a/dnssec_verify.c
+++ b/dnssec_verify.c
@@ -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;
}
diff --git a/host2str.c b/host2str.c
index f459c476..154504c8 100644
--- a/host2str.c
+++ b/host2str.c
@@ -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 ca2883fc..bb7bd6cd 100644
--- 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 */