Changeset View
Changeset View
Standalone View
Standalone View
contrib/ldns/keys.c
Show All 9 Lines | |||||
* See the file LICENSE for the license | * See the file LICENSE for the license | ||||
*/ | */ | ||||
#include <ldns/config.h> | #include <ldns/config.h> | ||||
#include <ldns/ldns.h> | #include <ldns/ldns.h> | ||||
#ifdef HAVE_SSL | #ifdef HAVE_SSL | ||||
#include <openssl/ui.h> | |||||
#include <openssl/ssl.h> | #include <openssl/ssl.h> | ||||
#include <openssl/engine.h> | |||||
#include <openssl/rand.h> | #include <openssl/rand.h> | ||||
#include <openssl/bn.h> | |||||
#include <openssl/rsa.h> | |||||
#ifdef USE_DSA | |||||
#include <openssl/dsa.h> | |||||
#endif | |||||
#ifndef OPENSSL_NO_ENGINE | |||||
#include <openssl/engine.h> | |||||
#endif | |||||
#endif /* HAVE_SSL */ | #endif /* HAVE_SSL */ | ||||
ldns_lookup_table ldns_signing_algorithms[] = { | ldns_lookup_table ldns_signing_algorithms[] = { | ||||
{ LDNS_SIGN_RSAMD5, "RSAMD5" }, | { LDNS_SIGN_RSAMD5, "RSAMD5" }, | ||||
{ LDNS_SIGN_RSASHA1, "RSASHA1" }, | { LDNS_SIGN_RSASHA1, "RSASHA1" }, | ||||
{ LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" }, | { LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" }, | ||||
#ifdef USE_SHA2 | #ifdef USE_SHA2 | ||||
{ LDNS_SIGN_RSASHA256, "RSASHA256" }, | { LDNS_SIGN_RSASHA256, "RSASHA256" }, | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
ldns_key_new(void) | ldns_key_new(void) | ||||
{ | { | ||||
ldns_key *newkey; | ldns_key *newkey; | ||||
newkey = LDNS_MALLOC(ldns_key); | newkey = LDNS_MALLOC(ldns_key); | ||||
if (!newkey) { | if (!newkey) { | ||||
return NULL; | return NULL; | ||||
} else { | } else { | ||||
/* some defaults - not sure wether to do this */ | /* some defaults - not sure whether to do this */ | ||||
ldns_key_set_use(newkey, true); | ldns_key_set_use(newkey, true); | ||||
ldns_key_set_flags(newkey, LDNS_KEY_ZONE_KEY); | ldns_key_set_flags(newkey, LDNS_KEY_ZONE_KEY); | ||||
ldns_key_set_origttl(newkey, 0); | ldns_key_set_origttl(newkey, 0); | ||||
ldns_key_set_keytag(newkey, 0); | ldns_key_set_keytag(newkey, 0); | ||||
ldns_key_set_inception(newkey, 0); | ldns_key_set_inception(newkey, 0); | ||||
ldns_key_set_expiration(newkey, 0); | ldns_key_set_expiration(newkey, 0); | ||||
ldns_key_set_pubkey_owner(newkey, NULL); | ldns_key_set_pubkey_owner(newkey, NULL); | ||||
#ifdef HAVE_SSL | #ifdef HAVE_SSL | ||||
ldns_key_set_evp_key(newkey, NULL); | ldns_key_set_evp_key(newkey, NULL); | ||||
#endif /* HAVE_SSL */ | #endif /* HAVE_SSL */ | ||||
ldns_key_set_hmac_key(newkey, NULL); | ldns_key_set_hmac_key(newkey, NULL); | ||||
ldns_key_set_external_key(newkey, NULL); | ldns_key_set_external_key(newkey, NULL); | ||||
return newkey; | return newkey; | ||||
} | } | ||||
} | } | ||||
ldns_status | ldns_status | ||||
ldns_key_new_frm_fp(ldns_key **k, FILE *fp) | ldns_key_new_frm_fp(ldns_key **k, FILE *fp) | ||||
{ | { | ||||
return ldns_key_new_frm_fp_l(k, fp, NULL); | return ldns_key_new_frm_fp_l(k, fp, NULL); | ||||
} | } | ||||
#ifdef HAVE_SSL | #if defined(HAVE_SSL) && !defined(OPENSSL_NO_ENGINE) | ||||
ldns_status | ldns_status | ||||
ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg) | ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg) | ||||
{ | { | ||||
ldns_key *k; | ldns_key *k; | ||||
k = ldns_key_new(); | k = ldns_key_new(); | ||||
if(!k) return LDNS_STATUS_MEM_ERR; | if(!k) return LDNS_STATUS_MEM_ERR; | ||||
#ifndef S_SPLINT_S | #ifndef S_SPLINT_S | ||||
▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | EVP_PKEY_free(evp_key); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
return evp_key; | return evp_key; | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef USE_ED25519 | #ifdef USE_ED25519 | ||||
/** turn private key buffer into EC_KEY structure */ | /** turn private key buffer into EC_KEY structure */ | ||||
static EC_KEY* | static EVP_PKEY* | ||||
ldns_ed25519_priv_raw(uint8_t* pkey, int plen) | ldns_ed25519_priv_raw(uint8_t* pkey, int plen) | ||||
{ | { | ||||
const unsigned char* pp; | const unsigned char* pp; | ||||
uint8_t buf[256]; | uint8_t buf[256]; | ||||
int buflen = 0; | int buflen = 0; | ||||
uint8_t pre[] = {0x30, 0x32, 0x02, 0x01, 0x01, 0x04, 0x20}; | uint8_t pre[] = {0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, | ||||
int pre_len = 7; | 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20}; | ||||
uint8_t post[] = {0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, | int pre_len = 16; | ||||
0x01, 0xda, 0x47, 0x0f, 0x01}; | /* ASN looks like this for ED25519 public key | ||||
int post_len = 13; | * 302a300506032b6570032100 <32byteskey> | ||||
int i; | * for ED25519 private key | ||||
/* ASN looks like this for ED25519 | * 302e020100300506032b657004220420 <32bytes> | ||||
* | |||||
* for X25519 this was | |||||
* 30320201010420 <32byteskey> | * 30320201010420 <32byteskey> | ||||
* andparameters a00b06092b06010401da470f01 | * andparameters a00b06092b06010401da470f01 | ||||
* (noparameters, preamble is 30250201010420). | * (noparameters, preamble is 30250201010420). | ||||
* the key is reversed (little endian). | * the key is reversed (little endian). | ||||
*/ | */ | ||||
buflen = pre_len + plen + post_len; | buflen = pre_len + plen; | ||||
if((size_t)buflen > sizeof(buf)) | if((size_t)buflen > sizeof(buf)) | ||||
return NULL; | return NULL; | ||||
memmove(buf, pre, pre_len); | memmove(buf, pre, pre_len); | ||||
/* reverse the pkey into the buf */ | memmove(buf+pre_len, pkey, plen); | ||||
for(i=0; i<plen; i++) | /* reverse the pkey into the buf - key is not reversed it seems */ | ||||
buf[pre_len+i] = pkey[plen-1-i]; | /* for(i=0; i<plen; i++) | ||||
memmove(buf+pre_len+plen, post, post_len); | buf[pre_len+i] = pkey[plen-1-i]; */ | ||||
pp = buf; | pp = buf; | ||||
return d2i_ECPrivateKey(NULL, &pp, buflen); | return d2i_PrivateKey(NID_ED25519, NULL, &pp, buflen); | ||||
} | } | ||||
/** read ED25519 private key */ | /** read ED25519 private key */ | ||||
static EVP_PKEY* | static EVP_PKEY* | ||||
ldns_key_new_frm_fp_ed25519_l(FILE* fp, int* line_nr) | ldns_key_new_frm_fp_ed25519_l(FILE* fp, int* line_nr) | ||||
{ | { | ||||
char token[16384]; | char token[16384]; | ||||
ldns_rdf* b64rdf = NULL; | ldns_rdf* b64rdf = NULL; | ||||
EVP_PKEY* evp_key; | EVP_PKEY* evp_key; | ||||
EC_KEY* ec; | |||||
if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", | if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", | ||||
sizeof(token), line_nr) == -1) | sizeof(token), line_nr) == -1) | ||||
return NULL; | return NULL; | ||||
if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) | if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) | ||||
return NULL; | return NULL; | ||||
/* we use d2i_ECPrivateKey because it calculates the public key | /* we use d2i_ECPrivateKey because it calculates the public key | ||||
* from the private part, which others, EC_KEY_set_private_key, | * from the private part, which others, EC_KEY_set_private_key, | ||||
* and o2i methods, do not do */ | * and o2i methods, do not do */ | ||||
/* for that the private key has to be encoded in ASN1 notation | /* for that the private key has to be encoded in ASN1 notation | ||||
* with a X25519 prefix on it */ | * with a ED25519 prefix on it */ | ||||
ec = ldns_ed25519_priv_raw(ldns_rdf_data(b64rdf), | evp_key = ldns_ed25519_priv_raw(ldns_rdf_data(b64rdf), | ||||
(int)ldns_rdf_size(b64rdf)); | (int)ldns_rdf_size(b64rdf)); | ||||
ldns_rdf_deep_free(b64rdf); | ldns_rdf_deep_free(b64rdf); | ||||
if(!ec) return NULL; | |||||
if(EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)) != NID_X25519) { | |||||
/* wrong group, bad asn conversion */ | |||||
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; | |||||
} | |||||
return evp_key; | return evp_key; | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef USE_ED448 | #ifdef USE_ED448 | ||||
/** turn private key buffer into EC_KEY structure */ | /** turn private key buffer into EC_KEY structure */ | ||||
static EC_KEY* | static EVP_PKEY* | ||||
ldns_ed448_priv_raw(uint8_t* pkey, int plen) | ldns_ed448_priv_raw(uint8_t* pkey, int plen) | ||||
{ | { | ||||
const unsigned char* pp; | const unsigned char* pp; | ||||
uint8_t buf[256]; | uint8_t buf[256]; | ||||
int buflen = 0; | int buflen = 0; | ||||
uint8_t pre[] = {0x30, 0x4b, 0x02, 0x01, 0x01, 0x04, 0x39}; | uint8_t pre[] = {0x30, 0x47, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x71, 0x04, 0x3b, 0x04, 0x39}; | ||||
int pre_len = 7; | int pre_len = 16; | ||||
uint8_t post[] = {0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, | /* ASN looks like this for ED448 | ||||
0x01, 0xda, 0x47, 0x0f, 0x02}; | * 3047020100300506032b6571043b0439 <57bytekey> | ||||
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). | |||||
* the key is reversed (little endian). | * 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)) | if((size_t)buflen > sizeof(buf)) | ||||
return NULL; | return NULL; | ||||
memmove(buf, pre, pre_len); | memmove(buf, pre, pre_len); | ||||
/* reverse the pkey into the buf */ | memmove(buf+pre_len, pkey, plen); | ||||
for(i=0; i<plen; i++) | /* reverse the pkey into the buf - key is not reversed it seems */ | ||||
buf[pre_len+i] = pkey[plen-1-i]; | /* for(i=0; i<plen; i++) | ||||
memmove(buf+pre_len+plen, post, post_len); | buf[pre_len+i] = pkey[plen-1-i]; */ | ||||
pp = buf; | pp = buf; | ||||
return d2i_ECPrivateKey(NULL, &pp, buflen); | return d2i_PrivateKey(NID_ED448, NULL, &pp, buflen); | ||||
} | } | ||||
/** read ED448 private key */ | /** read ED448 private key */ | ||||
static EVP_PKEY* | static EVP_PKEY* | ||||
ldns_key_new_frm_fp_ed448_l(FILE* fp, int* line_nr) | ldns_key_new_frm_fp_ed448_l(FILE* fp, int* line_nr) | ||||
{ | { | ||||
char token[16384]; | char token[16384]; | ||||
ldns_rdf* b64rdf = NULL; | ldns_rdf* b64rdf = NULL; | ||||
EVP_PKEY* evp_key; | EVP_PKEY* evp_key; | ||||
EC_KEY* ec; | |||||
if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", | if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", | ||||
sizeof(token), line_nr) == -1) | sizeof(token), line_nr) == -1) | ||||
return NULL; | return NULL; | ||||
if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) | if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) | ||||
return NULL; | return NULL; | ||||
/* convert private key into ASN notation and then convert that */ | /* convert private key into ASN notation and then convert that */ | ||||
ec = ldns_ed448_priv_raw(ldns_rdf_data(b64rdf), | evp_key = ldns_ed448_priv_raw(ldns_rdf_data(b64rdf), | ||||
(int)ldns_rdf_size(b64rdf)); | (int)ldns_rdf_size(b64rdf)); | ||||
ldns_rdf_deep_free(b64rdf); | ldns_rdf_deep_free(b64rdf); | ||||
if(!ec) return NULL; | |||||
if(EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)) != NID_X448) { | |||||
/* wrong group, bad asn conversion */ | |||||
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; | |||||
} | |||||
return evp_key; | return evp_key; | ||||
} | } | ||||
#endif | #endif | ||||
ldns_status | ldns_status | ||||
ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr) | ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr) | ||||
{ | { | ||||
ldns_key *k; | ldns_key *k; | ||||
▲ Show 20 Lines • Show All 351 Lines • ▼ Show 20 Lines | ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr) | ||||
b = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); | b = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); | ||||
buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); | buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); | ||||
rsa = RSA_new(); | rsa = RSA_new(); | ||||
if (!b || !rsa || !buf) { | if (!b || !rsa || !buf) { | ||||
goto error; | goto error; | ||||
} | } | ||||
/* I could use functions again, but that seems an overkill, | /* I could use functions again, but that seems an overkill, | ||||
* allthough this also looks tedious | * although this also looks tedious | ||||
*/ | */ | ||||
/* Modules, rsa->n */ | /* Modules, rsa->n */ | ||||
if (ldns_fget_keyword_data_l(f, "Modulus", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { | if (ldns_fget_keyword_data_l(f, "Modulus", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { | ||||
goto error; | goto error; | ||||
} | } | ||||
i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); | i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); | ||||
#ifndef S_SPLINT_S | #ifndef S_SPLINT_S | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | #ifndef S_SPLINT_S | ||||
} | } | ||||
i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); | i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); | ||||
iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL); | iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL); | ||||
if (!iqmp) { | if (!iqmp) { | ||||
goto error; | goto error; | ||||
} | } | ||||
#endif /* splint */ | #endif /* splint */ | ||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) | #if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000) | ||||
# ifndef S_SPLINT_S | # ifndef S_SPLINT_S | ||||
rsa->n = n; | rsa->n = n; | ||||
rsa->e = e; | rsa->e = e; | ||||
rsa->d = d; | rsa->d = d; | ||||
rsa->p = p; | rsa->p = p; | ||||
rsa->q = q; | rsa->q = q; | ||||
rsa->dmp1 = dmp1; | rsa->dmp1 = dmp1; | ||||
rsa->dmq1 = dmq1; | rsa->dmq1 = dmq1; | ||||
Show All 27 Lines | error: | ||||
BN_free(p); | BN_free(p); | ||||
BN_free(q); | BN_free(q); | ||||
BN_free(dmp1); | BN_free(dmp1); | ||||
BN_free(dmq1); | BN_free(dmq1); | ||||
BN_free(iqmp); | BN_free(iqmp); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
#ifdef USE_DSA | |||||
DSA * | DSA * | ||||
ldns_key_new_frm_fp_dsa(FILE *f) | ldns_key_new_frm_fp_dsa(FILE *f) | ||||
{ | { | ||||
return ldns_key_new_frm_fp_dsa_l(f, NULL); | return ldns_key_new_frm_fp_dsa_l(f, NULL); | ||||
} | } | ||||
DSA * | DSA * | ||||
ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) | ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | #ifndef S_SPLINT_S | ||||
} | } | ||||
i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); | i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); | ||||
pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL); | pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL); | ||||
if (!pub_key) { | if (!pub_key) { | ||||
goto error; | goto error; | ||||
} | } | ||||
#endif /* splint */ | #endif /* splint */ | ||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) | #if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000) | ||||
# ifndef S_SPLINT_S | # ifndef S_SPLINT_S | ||||
dsa->p = p; | dsa->p = p; | ||||
dsa->q = q; | dsa->q = q; | ||||
dsa->g = g; | dsa->g = g; | ||||
dsa->priv_key = priv_key; | dsa->priv_key = priv_key; | ||||
dsa->pub_key = pub_key; | dsa->pub_key = pub_key; | ||||
# endif | # endif | ||||
#else | #else | ||||
Show All 17 Lines | LDNS_FREE(buf); | ||||
DSA_free(dsa); | DSA_free(dsa); | ||||
BN_free(p); | BN_free(p); | ||||
BN_free(q); | BN_free(q); | ||||
BN_free(g); | BN_free(g); | ||||
BN_free(priv_key); | BN_free(priv_key); | ||||
BN_free(pub_key); | BN_free(pub_key); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
#endif /* USE_DSA */ | |||||
unsigned char * | unsigned char * | ||||
ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size) | ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size) | ||||
{ | { | ||||
return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size); | return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size); | ||||
} | } | ||||
unsigned char * | unsigned char * | ||||
ldns_key_new_frm_fp_hmac_l( FILE *f | ldns_key_new_frm_fp_hmac_l( FILE *f | ||||
, ATTR_UNUSED(int *line_nr) | , ATTR_UNUSED(int *line_nr) | ||||
, size_t *hmac_size | , size_t *hmac_size | ||||
) | ) | ||||
{ | { | ||||
size_t i, bufsz; | size_t bufsz; | ||||
char d[LDNS_MAX_LINELEN]; | char d[LDNS_MAX_LINELEN]; | ||||
unsigned char *buf = NULL; | unsigned char *buf = NULL; | ||||
if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { | *hmac_size = ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", | ||||
goto error; | LDNS_MAX_LINELEN, line_nr) == -1 | ||||
} | ? 0 | ||||
bufsz = ldns_b64_ntop_calculate_size(strlen(d)); | : (buf = LDNS_XMALLOC( unsigned char, (bufsz = | ||||
buf = LDNS_XMALLOC(unsigned char, bufsz); | ldns_b64_ntop_calculate_size(strlen(d))))) == NULL | ||||
i = (size_t) ldns_b64_pton((const char*)d, buf, bufsz); | ? 0 | ||||
: (size_t) ldns_b64_pton((const char*)d, buf, bufsz); | |||||
*hmac_size = i; | |||||
return buf; | return buf; | ||||
error: | |||||
LDNS_FREE(buf); | |||||
*hmac_size = 0; | |||||
return NULL; | |||||
} | } | ||||
#endif /* HAVE_SSL */ | #endif /* HAVE_SSL */ | ||||
#ifdef USE_GOST | #ifdef USE_GOST | ||||
static EVP_PKEY* | static EVP_PKEY* | ||||
ldns_gen_gost_key(void) | ldns_gen_gost_key(void) | ||||
{ | { | ||||
EVP_PKEY_CTX* ctx; | EVP_PKEY_CTX* ctx; | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | #else /* HAVE_EVP_PKEY_KEYGEN */ | ||||
ldns_key_free(k); | ldns_key_free(k); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
ldns_key_set_rsa_key(k, r); | ldns_key_set_rsa_key(k, r); | ||||
RSA_free(r); | RSA_free(r); | ||||
#endif /* HAVE_EVP_PKEY_KEYGEN */ | #endif /* HAVE_EVP_PKEY_KEYGEN */ | ||||
#endif /* HAVE_SSL */ | #endif /* HAVE_SSL */ | ||||
break; | break; | ||||
#ifdef USE_DSA | |||||
case LDNS_SIGN_DSA: | case LDNS_SIGN_DSA: | ||||
case LDNS_SIGN_DSA_NSEC3: | case LDNS_SIGN_DSA_NSEC3: | ||||
#ifdef USE_DSA | |||||
#ifdef HAVE_SSL | #ifdef HAVE_SSL | ||||
# if OPENSSL_VERSION_NUMBER < 0x00908000L | # if OPENSSL_VERSION_NUMBER < 0x00908000L | ||||
d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL); | d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL); | ||||
if (!d) { | if (!d) { | ||||
ldns_key_free(k); | ldns_key_free(k); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | |||||
#else | #else | ||||
ldns_key_free(k); | ldns_key_free(k); | ||||
return NULL; | return NULL; | ||||
#endif /* ECDSA */ | #endif /* ECDSA */ | ||||
break; | break; | ||||
#ifdef USE_ED25519 | #ifdef USE_ED25519 | ||||
case LDNS_SIGN_ED25519: | case LDNS_SIGN_ED25519: | ||||
#ifdef HAVE_EVP_PKEY_KEYGEN | #ifdef HAVE_EVP_PKEY_KEYGEN | ||||
ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); | ctx = EVP_PKEY_CTX_new_id(NID_ED25519, NULL); | ||||
if(!ctx) { | if(!ctx) { | ||||
ldns_key_free(k); | ldns_key_free(k); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
if(EVP_PKEY_keygen_init(ctx) <= 0) { | if(EVP_PKEY_keygen_init(ctx) <= 0) { | ||||
ldns_key_free(k); | ldns_key_free(k); | ||||
EVP_PKEY_CTX_free(ctx); | EVP_PKEY_CTX_free(ctx); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, | |||||
NID_X25519) <= 0) { | |||||
ldns_key_free(k); | |||||
EVP_PKEY_CTX_free(ctx); | |||||
return NULL; | |||||
} | |||||
if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) { | if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) { | ||||
ldns_key_free(k); | ldns_key_free(k); | ||||
EVP_PKEY_CTX_free(ctx); | EVP_PKEY_CTX_free(ctx); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
EVP_PKEY_CTX_free(ctx); | EVP_PKEY_CTX_free(ctx); | ||||
#endif | #endif | ||||
break; | break; | ||||
#endif /* ED25519 */ | #endif /* ED25519 */ | ||||
#ifdef USE_ED448 | #ifdef USE_ED448 | ||||
case LDNS_SIGN_ED448: | case LDNS_SIGN_ED448: | ||||
#ifdef HAVE_EVP_PKEY_KEYGEN | #ifdef HAVE_EVP_PKEY_KEYGEN | ||||
ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); | ctx = EVP_PKEY_CTX_new_id(NID_ED448, NULL); | ||||
if(!ctx) { | if(!ctx) { | ||||
ldns_key_free(k); | ldns_key_free(k); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
if(EVP_PKEY_keygen_init(ctx) <= 0) { | if(EVP_PKEY_keygen_init(ctx) <= 0) { | ||||
ldns_key_free(k); | ldns_key_free(k); | ||||
EVP_PKEY_CTX_free(ctx); | EVP_PKEY_CTX_free(ctx); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, | |||||
NID_X448) <= 0) { | |||||
ldns_key_free(k); | |||||
EVP_PKEY_CTX_free(ctx); | |||||
return NULL; | |||||
} | |||||
if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) { | if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) { | ||||
ldns_key_free(k); | ldns_key_free(k); | ||||
EVP_PKEY_CTX_free(ctx); | EVP_PKEY_CTX_free(ctx); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
EVP_PKEY_CTX_free(ctx); | EVP_PKEY_CTX_free(ctx); | ||||
#endif | #endif | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
k->_extra.dnssec.keytag = tag; | k->_extra.dnssec.keytag = tag; | ||||
} | } | ||||
/* read */ | /* read */ | ||||
size_t | size_t | ||||
ldns_key_list_key_count(const ldns_key_list *key_list) | ldns_key_list_key_count(const ldns_key_list *key_list) | ||||
{ | { | ||||
return key_list->_key_count; | return key_list ? key_list->_key_count : 0; | ||||
} | } | ||||
ldns_key * | ldns_key * | ||||
ldns_key_list_key(const ldns_key_list *key, size_t nr) | ldns_key_list_key(const ldns_key_list *key, size_t nr) | ||||
{ | { | ||||
if (nr < ldns_key_list_key_count(key)) { | if (nr < ldns_key_list_key_count(key)) { | ||||
return key->_keys[nr]; | return key->_keys[nr]; | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 197 Lines • ▼ Show 20 Lines | |||||
ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size) | ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size) | ||||
{ | { | ||||
int i,j; | int i,j; | ||||
const BIGNUM *n=NULL, *e=NULL; | const BIGNUM *n=NULL, *e=NULL; | ||||
if (!k) { | if (!k) { | ||||
return false; | return false; | ||||
} | } | ||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) | #if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000) | ||||
n = k->n; | n = k->n; | ||||
e = k->e; | e = k->e; | ||||
#else | #else | ||||
RSA_get0_key(k, &n, &e, NULL); | RSA_get0_key(k, &n, &e, NULL); | ||||
#endif | #endif | ||||
if (BN_num_bytes(e) <= 256) { | if (BN_num_bytes(e) <= 256) { | ||||
/* normally only this path is executed (small factors are | /* normally only this path is executed (small factors are | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size) | ||||
/* omit ASN header */ | /* omit ASN header */ | ||||
for(i=0; i<64; i++) | for(i=0; i<64; i++) | ||||
data[i] = pp[i+37]; | data[i] = pp[i+37]; | ||||
free(pp); | free(pp); | ||||
*size = 64; | *size = 64; | ||||
return true; | return true; | ||||
} | } | ||||
#endif /* USE_GOST */ | #endif /* USE_GOST */ | ||||
#ifdef USE_ED25519 | |||||
static bool | |||||
ldns_key_ed255192bin(unsigned char* data, EVP_PKEY* k, uint16_t* size) | |||||
{ | |||||
int i; | |||||
unsigned char* pp = NULL; | |||||
if(i2d_PUBKEY(k, &pp) != 12 + 32) { | |||||
/* expect 12 byte(ASN header) and 32 byte(pubkey) */ | |||||
free(pp); | |||||
return false; | |||||
} | |||||
/* omit ASN header */ | |||||
for(i=0; i<32; i++) | |||||
data[i] = pp[i+12]; | |||||
free(pp); | |||||
*size = 32; | |||||
return true; | |||||
} | |||||
#endif /* USE_ED25519 */ | |||||
#ifdef USE_ED448 | |||||
static bool | |||||
ldns_key_ed4482bin(unsigned char* data, EVP_PKEY* k, uint16_t* size) | |||||
{ | |||||
int i; | |||||
unsigned char* pp = NULL; | |||||
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<57; i++) | |||||
data[i] = pp[i+12]; | |||||
free(pp); | |||||
*size = 57; | |||||
return true; | |||||
} | |||||
#endif /* USE_ED448 */ | |||||
#endif /* splint */ | #endif /* splint */ | ||||
#endif /* HAVE_SSL */ | #endif /* HAVE_SSL */ | ||||
ldns_rr * | ldns_rr * | ||||
ldns_key2rr(const ldns_key *k) | ldns_key2rr(const ldns_key *k) | ||||
{ | { | ||||
/* this function will convert a the keydata contained in | /* this function will convert a the keydata contained in | ||||
* rsa/dsa pointers to a DNSKEY rr. It will fill in as | * rsa/dsa pointers to a DNSKEY rr. It will fill in as | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | #ifdef HAVE_SSL | ||||
return NULL; | return NULL; | ||||
} | } | ||||
RSA_free(rsa); | RSA_free(rsa); | ||||
internal_data = 1; | internal_data = 1; | ||||
} | } | ||||
#endif | #endif | ||||
size++; | size++; | ||||
break; | break; | ||||
#ifdef USE_DSA | |||||
case LDNS_SIGN_DSA: | case LDNS_SIGN_DSA: | ||||
ldns_rr_push_rdf(pubkey, | ldns_rr_push_rdf(pubkey, | ||||
ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA)); | ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA)); | ||||
#ifdef USE_DSA | |||||
#ifdef HAVE_SSL | #ifdef HAVE_SSL | ||||
dsa = ldns_key_dsa_key(k); | dsa = ldns_key_dsa_key(k); | ||||
if (dsa) { | if (dsa) { | ||||
bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); | bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); | ||||
if (!bin) { | if (!bin) { | ||||
ldns_rr_free(pubkey); | ldns_rr_free(pubkey); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
if (!ldns_key_dsa2bin(bin, dsa, &size)) { | if (!ldns_key_dsa2bin(bin, dsa, &size)) { | ||||
LDNS_FREE(bin); | LDNS_FREE(bin); | ||||
ldns_rr_free(pubkey); | ldns_rr_free(pubkey); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
DSA_free(dsa); | DSA_free(dsa); | ||||
internal_data = 1; | internal_data = 1; | ||||
} | } | ||||
#endif /* HAVE_SSL */ | #endif /* HAVE_SSL */ | ||||
#endif /* USE_DSA */ | #endif /* USE_DSA */ | ||||
break; | break; | ||||
#ifdef USE_DSA | |||||
case LDNS_SIGN_DSA_NSEC3: | case LDNS_SIGN_DSA_NSEC3: | ||||
ldns_rr_push_rdf(pubkey, | ldns_rr_push_rdf(pubkey, | ||||
ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3)); | ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3)); | ||||
#ifdef USE_DSA | |||||
#ifdef HAVE_SSL | #ifdef HAVE_SSL | ||||
dsa = ldns_key_dsa_key(k); | dsa = ldns_key_dsa_key(k); | ||||
if (dsa) { | if (dsa) { | ||||
bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); | bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); | ||||
if (!bin) { | if (!bin) { | ||||
ldns_rr_free(pubkey); | ldns_rr_free(pubkey); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | #else | ||||
ldns_rr_free(pubkey); | ldns_rr_free(pubkey); | ||||
return NULL; | return NULL; | ||||
#endif /* ECDSA */ | #endif /* ECDSA */ | ||||
break; | break; | ||||
#ifdef USE_ED25519 | #ifdef USE_ED25519 | ||||
case LDNS_SIGN_ED25519: | case LDNS_SIGN_ED25519: | ||||
ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( | ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( | ||||
LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); | LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); | ||||
bin = NULL; | bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); | ||||
ec = EVP_PKEY_get1_EC_KEY(k->_key.key); | if (!bin) { | ||||
EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); | |||||
size = (uint16_t)i2o_ECPublicKey(ec, NULL); | |||||
if(!i2o_ECPublicKey(ec, &bin)) { | |||||
EC_KEY_free(ec); | |||||
ldns_rr_free(pubkey); | ldns_rr_free(pubkey); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
/* down the reference count for ec, its still assigned | if (!ldns_key_ed255192bin(bin, k->_key.key, &size)) { | ||||
* to the pkey */ | LDNS_FREE(bin); | ||||
EC_KEY_free(ec); | ldns_rr_free(pubkey); | ||||
return NULL; | |||||
} | |||||
internal_data = 1; | internal_data = 1; | ||||
break; | break; | ||||
#endif | #endif | ||||
#ifdef USE_ED448 | #ifdef USE_ED448 | ||||
case LDNS_SIGN_ED448: | case LDNS_SIGN_ED448: | ||||
ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( | ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( | ||||
LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); | LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); | ||||
bin = NULL; | bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); | ||||
ec = EVP_PKEY_get1_EC_KEY(k->_key.key); | if (!bin) { | ||||
EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); | |||||
size = (uint16_t)i2o_ECPublicKey(ec, NULL); | |||||
if(!i2o_ECPublicKey(ec, &bin)) { | |||||
EC_KEY_free(ec); | |||||
ldns_rr_free(pubkey); | ldns_rr_free(pubkey); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
/* down the reference count for ec, its still assigned | if (!ldns_key_ed4482bin(bin, k->_key.key, &size)) { | ||||
* to the pkey */ | LDNS_FREE(bin); | ||||
EC_KEY_free(ec); | ldns_rr_free(pubkey); | ||||
return NULL; | |||||
} | |||||
internal_data = 1; | internal_data = 1; | ||||
break; | break; | ||||
#endif | #endif | ||||
case LDNS_SIGN_HMACMD5: | case LDNS_SIGN_HMACMD5: | ||||
case LDNS_SIGN_HMACSHA1: | case LDNS_SIGN_HMACSHA1: | ||||
case LDNS_SIGN_HMACSHA224: | case LDNS_SIGN_HMACSHA224: | ||||
case LDNS_SIGN_HMACSHA256: | case LDNS_SIGN_HMACSHA256: | ||||
case LDNS_SIGN_HMACSHA384: | case LDNS_SIGN_HMACSHA384: | ||||
▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name) | ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name) | ||||
{ | { | ||||
/* list of (signing algorithm id, alias_name) */ | /* list of (signing algorithm id, alias_name) */ | ||||
ldns_lookup_table aliases[] = { | ldns_lookup_table aliases[] = { | ||||
/* from bind dnssec-keygen */ | /* from bind dnssec-keygen */ | ||||
{LDNS_SIGN_HMACMD5, "HMAC-MD5"}, | {LDNS_SIGN_HMACMD5, "HMAC-MD5"}, | ||||
#ifdef USE_DSA | |||||
{LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"}, | {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"}, | ||||
#endif /* USE_DSA */ | |||||
{LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"}, | {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"}, | ||||
/* old ldns usage, now RFC names */ | /* old ldns usage, now RFC names */ | ||||
#ifdef USE_DSA | #ifdef USE_DSA | ||||
{LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" }, | {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" }, | ||||
#endif | #endif | ||||
{LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" }, | {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" }, | ||||
#ifdef USE_GOST | #ifdef USE_GOST | ||||
{LDNS_SIGN_ECC_GOST, "GOST"}, | {LDNS_SIGN_ECC_GOST, "GOST"}, | ||||
Show All 29 Lines |