X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/5339abd42366811e8cd412008910e66f0baa0caf..188cd41447c6d13ba978a9c67045d1c299a82d91:/contrib/ldns/keys.c diff --git a/contrib/ldns/keys.c b/contrib/ldns/keys.c index 12fd92d87b..da72b3d8dd 100644 --- a/contrib/ldns/keys.c +++ b/contrib/ldns/keys.c @@ -37,16 +37,27 @@ ldns_lookup_table ldns_signing_algorithms[] = { { LDNS_SIGN_ECDSAP256SHA256, "ECDSAP256SHA256" }, { LDNS_SIGN_ECDSAP384SHA384, "ECDSAP384SHA384" }, #endif +#ifdef USE_ED25519 + { LDNS_SIGN_ED25519, "ED25519" }, +#endif +#ifdef USE_ED448 + { LDNS_SIGN_ED448, "ED448" }, +#endif +#ifdef USE_DSA { LDNS_SIGN_DSA, "DSA" }, { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" }, +#endif { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" }, { LDNS_SIGN_HMACSHA1, "hmac-sha1" }, { LDNS_SIGN_HMACSHA256, "hmac-sha256" }, + { LDNS_SIGN_HMACSHA224, "hmac-sha224" }, + { LDNS_SIGN_HMACSHA384, "hmac-sha384" }, + { LDNS_SIGN_HMACSHA512, "hmac-sha512" }, { 0, NULL } }; ldns_key_list * -ldns_key_list_new() +ldns_key_list_new(void) { ldns_key_list *key_list = LDNS_MALLOC(ldns_key_list); if (!key_list) { @@ -59,7 +70,7 @@ ldns_key_list_new() } ldns_key * -ldns_key_new() +ldns_key_new(void) { ldns_key *newkey; @@ -246,7 +257,7 @@ ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr) BIGNUM* bn; 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) return NULL; if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) @@ -288,7 +299,159 @@ ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr) return evp_key; } #endif - + +#ifdef USE_ED25519 +/** turn private key buffer into EC_KEY structure */ +static EC_KEY* +ldns_ed25519_priv_raw(uint8_t* pkey, int plen) +{ + const unsigned char* pp; + uint8_t buf[256]; + int buflen = 0; + uint8_t pre[] = {0x30, 0x32, 0x02, 0x01, 0x01, 0x04, 0x20}; + int pre_len = 7; + uint8_t post[] = {0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0xda, 0x47, 0x0f, 0x01}; + int post_len = 13; + int i; + /* ASN looks like this for ED25519 + * 30320201010420 <32byteskey> + * andparameters a00b06092b06010401da470f01 + * (noparameters, preamble is 30250201010420). + * the key is reversed (little endian). + */ + buflen = pre_len + plen + post_len; + if((size_t)buflen > sizeof(buf)) + return NULL; + memmove(buf, pre, pre_len); + /* reverse the pkey into the buf */ + for(i=0; i + * andparameters a00b06092b06010401da470f01 + * (noparameters, preamble is 30250201010420). + * 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; + if((size_t)buflen > sizeof(buf)) + return NULL; + memmove(buf, pre, pre_len); + /* reverse the pkey into the buf */ + for(i=0; i_key.key) { + ldns_key_free(k); + return LDNS_STATUS_ERR; + } +#endif /* splint */ + break; +#endif +#ifdef USE_ED448 + case LDNS_SIGN_ED448: + ldns_key_set_algorithm(k, alg); + ldns_key_set_evp_key(k, + ldns_key_new_frm_fp_ed448_l(fp, line_nr)); +#ifndef S_SPLINT_S + if(!k->_key.key) { + ldns_key_free(k); + return LDNS_STATUS_ERR; + } +#endif /* splint */ + break; #endif default: ldns_key_free(k); @@ -544,15 +800,17 @@ ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr) * // ... * */ - char *d; + char *b; RSA *rsa; uint8_t *buf; int i; + BIGNUM *n=NULL, *e=NULL, *d=NULL, *p=NULL, *q=NULL, + *dmp1=NULL, *dmq1=NULL, *iqmp=NULL; - d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); + b = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); rsa = RSA_new(); - if (!d || !rsa || !buf) { + if (!b || !rsa || !buf) { goto error; } @@ -561,95 +819,128 @@ ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr) */ /* Modules, rsa->n */ - if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\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; } - i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); + i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); #ifndef S_SPLINT_S - rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!rsa->n) { + n = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!n) { goto error; } /* PublicExponent, rsa->e */ - if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { goto error; } - i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); - rsa->e = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!rsa->e) { + i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + e = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!e) { goto error; } /* PrivateExponent, rsa->d */ - if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { goto error; } - i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); - rsa->d = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!rsa->d) { + i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + d = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!d) { goto error; } /* Prime1, rsa->p */ - if (ldns_fget_keyword_data_l(f, "Prime1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + if (ldns_fget_keyword_data_l(f, "Prime1", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { goto error; } - i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); - rsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!rsa->p) { + i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + p = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!p) { goto error; } /* Prime2, rsa->q */ - if (ldns_fget_keyword_data_l(f, "Prime2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + if (ldns_fget_keyword_data_l(f, "Prime2", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { goto error; } - i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); - rsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!rsa->q) { + i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + q = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!q) { goto error; } /* Exponent1, rsa->dmp1 */ - if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { goto error; } - i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); - rsa->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!rsa->dmp1) { + i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!dmp1) { goto error; } /* Exponent2, rsa->dmq1 */ - if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { goto error; } - i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); - rsa->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!rsa->dmq1) { + i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!dmq1) { goto error; } /* Coefficient, rsa->iqmp */ - if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { + if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { goto error; } - i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); - rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!rsa->iqmp) { + i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b))); + iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!iqmp) { goto error; } #endif /* splint */ +#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) +# ifndef S_SPLINT_S + rsa->n = n; + rsa->e = e; + rsa->d = d; + rsa->p = p; + rsa->q = q; + rsa->dmp1 = dmp1; + rsa->dmq1 = dmq1; + rsa->iqmp = iqmp; +# endif +#else + if(!RSA_set0_key(rsa, n, e, d)) + goto error; + n = NULL; + e = NULL; + d = NULL; + if(!RSA_set0_factors(rsa, p, q)) + goto error; + p = NULL; + q = NULL; + if(!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) + goto error; +#endif + LDNS_FREE(buf); - LDNS_FREE(d); + LDNS_FREE(b); return rsa; error: RSA_free(rsa); - LDNS_FREE(d); + LDNS_FREE(b); LDNS_FREE(buf); + BN_free(n); + BN_free(e); + BN_free(d); + BN_free(p); + BN_free(q); + BN_free(dmp1); + BN_free(dmq1); + BN_free(iqmp); return NULL; } @@ -666,6 +957,7 @@ ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) char *d; DSA *dsa; uint8_t *buf; + BIGNUM *p=NULL, *q=NULL, *g=NULL, *priv_key=NULL, *pub_key=NULL; d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); @@ -682,8 +974,8 @@ ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) } i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); #ifndef S_SPLINT_S - dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!dsa->p) { + p = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!p) { goto error; } @@ -692,8 +984,8 @@ ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) goto error; } i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); - dsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!dsa->q) { + q = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!q) { goto error; } @@ -702,8 +994,8 @@ ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) goto error; } i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); - dsa->g = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!dsa->g) { + g = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!g) { goto error; } @@ -712,8 +1004,8 @@ ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) goto error; } i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); - dsa->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!dsa->priv_key) { + priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!priv_key) { goto error; } @@ -722,12 +1014,30 @@ ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) goto error; } i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); - dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL); - if (!dsa->pub_key) { + pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL); + if (!pub_key) { goto error; } #endif /* splint */ +#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) +# ifndef S_SPLINT_S + dsa->p = p; + dsa->q = q; + dsa->g = g; + dsa->priv_key = priv_key; + dsa->pub_key = pub_key; +# endif +#else + if(!DSA_set0_pqg(dsa, p, q, g)) + goto error; + p = NULL; + q = NULL; + g = NULL; + if(!DSA_set0_key(dsa, pub_key, priv_key)) + goto error; +#endif + LDNS_FREE(buf); LDNS_FREE(d); @@ -737,6 +1047,11 @@ error: LDNS_FREE(d); LDNS_FREE(buf); DSA_free(dsa); + BN_free(p); + BN_free(q); + BN_free(g); + BN_free(priv_key); + BN_free(pub_key); return NULL; } @@ -812,11 +1127,17 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) { ldns_key *k; #ifdef HAVE_SSL +#ifdef USE_DSA DSA *d; - RSA *r; +#endif /* USE_DSA */ # ifdef USE_ECDSA EC_KEY *ec = NULL; # endif +# ifdef HAVE_EVP_PKEY_KEYGEN + EVP_PKEY_CTX *ctx; +# else + RSA *r; +# endif #else int i; uint16_t offset = 0; @@ -834,6 +1155,31 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) case LDNS_SIGN_RSASHA256: case LDNS_SIGN_RSASHA512: #ifdef HAVE_SSL +#ifdef HAVE_EVP_PKEY_KEYGEN + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if(!ctx) { + ldns_key_free(k); + return NULL; + } + if(EVP_PKEY_keygen_init(ctx) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; + } + if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, size) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; + } +#ifndef S_SPLINT_S + if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; + } +#endif + EVP_PKEY_CTX_free(ctx); +#else /* HAVE_EVP_PKEY_KEYGEN */ r = RSA_generate_key((int)size, RSA_F4, NULL, NULL); if(!r) { ldns_key_free(k); @@ -845,16 +1191,31 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) } ldns_key_set_rsa_key(k, r); RSA_free(r); +#endif /* HAVE_EVP_PKEY_KEYGEN */ #endif /* HAVE_SSL */ break; case LDNS_SIGN_DSA: case LDNS_SIGN_DSA_NSEC3: +#ifdef USE_DSA #ifdef HAVE_SSL +# if OPENSSL_VERSION_NUMBER < 0x00908000L d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL); if (!d) { ldns_key_free(k); return NULL; } + +# else + if (! (d = DSA_new())) { + ldns_key_free(k); + return NULL; + } + if (! DSA_generate_parameters_ex(d, (int)size, NULL, 0, NULL, NULL, NULL)) { + DSA_free(d); + ldns_key_free(k); + return NULL; + } +# endif if (DSA_generate_key(d) != 1) { ldns_key_free(k); return NULL; @@ -862,10 +1223,14 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) ldns_key_set_dsa_key(k, d); DSA_free(d); #endif /* HAVE_SSL */ +#endif /* USE_DSA */ break; case LDNS_SIGN_HMACMD5: case LDNS_SIGN_HMACSHA1: + case LDNS_SIGN_HMACSHA224: case LDNS_SIGN_HMACSHA256: + case LDNS_SIGN_HMACSHA384: + case LDNS_SIGN_HMACSHA512: #ifdef HAVE_SSL #ifndef S_SPLINT_S k->_key.key = NULL; @@ -948,6 +1313,62 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) return NULL; #endif /* ECDSA */ break; +#ifdef USE_ED25519 + case LDNS_SIGN_ED25519: +#ifdef HAVE_EVP_PKEY_KEYGEN + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + if(!ctx) { + ldns_key_free(k); + return NULL; + } + if(EVP_PKEY_keygen_init(ctx) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + 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) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; + } + EVP_PKEY_CTX_free(ctx); +#endif + break; +#endif /* ED25519 */ +#ifdef USE_ED448 + case LDNS_SIGN_ED448: +#ifdef HAVE_EVP_PKEY_KEYGEN + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + if(!ctx) { + ldns_key_free(k); + return NULL; + } + if(EVP_PKEY_keygen_init(ctx) <= 0) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + 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) { + ldns_key_free(k); + EVP_PKEY_CTX_free(ctx); + return NULL; + } + EVP_PKEY_CTX_free(ctx); +#endif + break; +#endif /* ED448 */ } ldns_key_set_algorithm(k, alg); return k; @@ -997,9 +1418,13 @@ ldns_key_set_rsa_key(ldns_key *k, RSA *r) void ldns_key_set_dsa_key(ldns_key *k, DSA *d) { +#ifdef USE_DSA EVP_PKEY *key = EVP_PKEY_new(); EVP_PKEY_set1_DSA(key, d); k->_key.key = key; +#else + (void)k; (void)d; +#endif } void @@ -1013,9 +1438,13 @@ ldns_key_assign_rsa_key(ldns_key *k, RSA *r) void ldns_key_assign_dsa_key(ldns_key *k, DSA *d) { +#ifdef USE_DSA EVP_PKEY *key = EVP_PKEY_new(); EVP_PKEY_assign_DSA(key, d); k->_key.key = key; +#else + (void)k; (void)d; +#endif } #endif /* splint */ #endif /* HAVE_SSL */ @@ -1129,11 +1558,16 @@ ldns_key_rsa_key(const ldns_key *k) DSA * ldns_key_dsa_key(const ldns_key *k) { +#ifdef USE_DSA if (k->_key.key) { return EVP_PKEY_get1_DSA(k->_key.key); } else { return NULL; } +#else + (void)k; + return NULL; +#endif } #endif /* splint */ #endif /* HAVE_SSL */ @@ -1276,63 +1710,87 @@ static bool ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size) { int i,j; + const BIGNUM *n=NULL, *e=NULL; if (!k) { return false; } +#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) + n = k->n; + e = k->e; +#else + RSA_get0_key(k, &n, &e, NULL); +#endif - if (BN_num_bytes(k->e) <= 256) { + if (BN_num_bytes(e) <= 256) { /* normally only this path is executed (small factors are * more common */ - data[0] = (unsigned char) BN_num_bytes(k->e); - i = BN_bn2bin(k->e, data + 1); - j = BN_bn2bin(k->n, data + i + 1); + data[0] = (unsigned char) BN_num_bytes(e); + i = BN_bn2bin(e, data + 1); + j = BN_bn2bin(n, data + i + 1); *size = (uint16_t) i + j; - } else if (BN_num_bytes(k->e) <= 65536) { + } else if (BN_num_bytes(e) <= 65536) { data[0] = 0; /* BN_bn2bin does bigendian, _uint16 also */ - ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e)); + ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(e)); - BN_bn2bin(k->e, data + 3); - BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e)); - *size = (uint16_t) BN_num_bytes(k->n) + 6; + BN_bn2bin(e, data + 3); + BN_bn2bin(n, data + 4 + BN_num_bytes(e)); + *size = (uint16_t) BN_num_bytes(n) + 6; } else { return false; } return true; } +#ifdef USE_DSA /* data pointer must be large enough (LDNS_MAX_KEYLEN) */ static bool ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size) { uint8_t T; + const BIGNUM *p, *q, *g; + const BIGNUM *pub_key, *priv_key; if (!k) { return false; } /* See RFC2536 */ - *size = (uint16_t)BN_num_bytes(k->p); +# ifdef HAVE_DSA_GET0_PQG + DSA_get0_pqg(k, &p, &q, &g); +# else + p = k->p; q = k->q; g = k->g; +# endif +# ifdef HAVE_DSA_GET0_KEY + DSA_get0_key(k, &pub_key, &priv_key); +# else + pub_key = k->pub_key; priv_key = k->priv_key; +# endif + (void)priv_key; + *size = (uint16_t)BN_num_bytes(p); T = (*size - 64) / 8; - memcpy(data, &T, 1); if (T > 8) { +#ifdef STDERR_MSGS fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)"); fprintf(stderr, " not implemented\n"); +#endif return false; } /* size = 64 + (T * 8); */ + memset(data, 0, 21 + *size * 3); data[0] = (unsigned char)T; - BN_bn2bin(k->q, data + 1 ); /* 20 octects */ - BN_bn2bin(k->p, data + 21 ); /* offset octects */ - BN_bn2bin(k->g, data + 21 + *size); /* offset octets */ - BN_bn2bin(k->pub_key, data + 21 + *size + *size); /* offset octets */ - *size = 21 + (*size * 3); + BN_bn2bin(q, data + 1 ); /* 20 octects */ + BN_bn2bin(p, data + 21 ); /* offset octects */ + BN_bn2bin(g, data + 21 + *size * 2 - BN_num_bytes(g)); + BN_bn2bin(pub_key,data + 21 + *size * 3 - BN_num_bytes(pub_key)); + *size = 21 + *size * 3; return true; } +#endif /* USE_DSA */ #ifdef USE_GOST static bool @@ -1342,13 +1800,13 @@ ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size) unsigned char* pp = NULL; if(i2d_PUBKEY(k, &pp) != 37 + 64) { /* expect 37 byte(ASN header) and 64 byte(X and Y) */ - CRYPTO_free(pp); + free(pp); return false; } /* omit ASN header */ for(i=0; i<64; i++) data[i] = pp[i+37]; - CRYPTO_free(pp); + free(pp); *size = 64; return true; } @@ -1370,7 +1828,9 @@ ldns_key2rr(const ldns_key *k) uint16_t size = 0; #ifdef HAVE_SSL RSA *rsa = NULL; +#ifdef USE_DSA DSA *dsa = NULL; +#endif /* USE_DSA */ #endif /* HAVE_SSL */ #ifdef USE_ECDSA EC_KEY* ec; @@ -1385,7 +1845,10 @@ ldns_key2rr(const ldns_key *k) switch (ldns_key_algorithm(k)) { case LDNS_SIGN_HMACMD5: case LDNS_SIGN_HMACSHA1: + case LDNS_SIGN_HMACSHA224: case LDNS_SIGN_HMACSHA256: + case LDNS_SIGN_HMACSHA384: + case LDNS_SIGN_HMACSHA512: ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY); break; default: @@ -1435,6 +1898,7 @@ ldns_key2rr(const ldns_key *k) case LDNS_SIGN_DSA: ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA)); +#ifdef USE_DSA #ifdef HAVE_SSL dsa = ldns_key_dsa_key(k); if (dsa) { @@ -1452,10 +1916,12 @@ ldns_key2rr(const ldns_key *k) internal_data = 1; } #endif /* HAVE_SSL */ +#endif /* USE_DSA */ break; case LDNS_SIGN_DSA_NSEC3: ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3)); +#ifdef USE_DSA #ifdef HAVE_SSL dsa = ldns_key_dsa_key(k); if (dsa) { @@ -1473,6 +1939,7 @@ ldns_key2rr(const ldns_key *k) internal_data = 1; } #endif /* HAVE_SSL */ +#endif /* USE_DSA */ break; case LDNS_SIGN_ECC_GOST: ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( @@ -1530,9 +1997,50 @@ ldns_key2rr(const ldns_key *k) return NULL; #endif /* ECDSA */ break; +#ifdef USE_ED25519 + case LDNS_SIGN_ED25519: + ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( + LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); + bin = NULL; + ec = EVP_PKEY_get1_EC_KEY(k->_key.key); + 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); + return NULL; + } + /* down the reference count for ec, its still assigned + * to the pkey */ + EC_KEY_free(ec); + internal_data = 1; + break; +#endif +#ifdef USE_ED448 + case LDNS_SIGN_ED448: + ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( + LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); + bin = NULL; + ec = EVP_PKEY_get1_EC_KEY(k->_key.key); + 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); + return NULL; + } + /* down the reference count for ec, its still assigned + * to the pkey */ + EC_KEY_free(ec); + internal_data = 1; + break; +#endif case LDNS_SIGN_HMACMD5: case LDNS_SIGN_HMACSHA1: + case LDNS_SIGN_HMACSHA224: case LDNS_SIGN_HMACSHA256: + case LDNS_SIGN_HMACSHA384: + case LDNS_SIGN_HMACSHA512: bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k)); if (!bin) { ldns_rr_free(pubkey); @@ -1607,7 +2115,9 @@ ldns_read_anchor_file(const char *filename) fp = fopen(filename, "r"); if (!fp) { +#ifdef STDERR_MSGS fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno)); +#endif LDNS_FREE(line); return NULL; } @@ -1621,7 +2131,9 @@ ldns_read_anchor_file(const char *filename) fclose(fp); if (i <= 0) { +#ifdef STDERR_MSGS fprintf(stderr, "nothing read from %s", filename); +#endif LDNS_FREE(line); return NULL; } else { @@ -1630,7 +2142,9 @@ ldns_read_anchor_file(const char *filename) LDNS_FREE(line); return r; } else { +#ifdef STDERR_MSGS fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status)); +#endif LDNS_FREE(line); return NULL; } @@ -1638,7 +2152,7 @@ ldns_read_anchor_file(const char *filename) } char * -ldns_key_get_file_base_name(ldns_key *key) +ldns_key_get_file_base_name(const ldns_key *key) { ldns_buffer *buffer; char *file_base_name; @@ -1675,7 +2189,9 @@ ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name) {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"}, {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"}, /* old ldns usage, now RFC names */ +#ifdef USE_DSA {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" }, +#endif {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" }, #ifdef USE_GOST {LDNS_SIGN_ECC_GOST, "GOST"}, @@ -1688,6 +2204,9 @@ ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name) {LDNS_PRIVATEOID, "PRIVATEOID"}, {0, NULL}}; ldns_lookup_table* lt = ldns_signing_algorithms; + ldns_signing_algorithm a; + char *endptr; + while(lt->name) { if(strcasecmp(lt->name, name) == 0) return lt->id; @@ -1699,7 +2218,9 @@ ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name) return lt->id; lt++; } - if(atoi(name) != 0) - return atoi(name); + a = strtol(name, &endptr, 10); + if (*name && !*endptr) + return a; + return 0; }