2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

3642. [func] Allow externally generated DNSKEY to be imported

into the DNSKEY management framework.  A new tool
                        dnssec-importkey is used to this. [RT #34698]
This commit is contained in:
Mark Andrews
2013-09-04 13:53:02 +10:00
parent b5f4cc132e
commit 0c91911b4d
28 changed files with 1107 additions and 82 deletions

View File

@@ -178,14 +178,18 @@ find_numericdata(const char *s) {
}
static int
check_rsa(const dst_private_t *priv) {
check_rsa(const dst_private_t *priv, isc_boolean_t external) {
int i, j;
isc_boolean_t have[RSA_NTAGS];
isc_boolean_t ok;
unsigned int mask;
if (external)
return ((priv->nelements == 0) ? 0 : -1);
for (i = 0; i < RSA_NTAGS; i++)
have[i] = ISC_FALSE;
for (j = 0; j < priv->nelements; j++) {
for (i = 0; i < RSA_NTAGS; i++)
if (priv->elements[j].tag == TAG(DST_ALG_RSAMD5, i))
@@ -231,10 +235,15 @@ check_dh(const dst_private_t *priv) {
}
static int
check_dsa(const dst_private_t *priv) {
check_dsa(const dst_private_t *priv, isc_boolean_t external) {
int i, j;
if (external)
return ((priv->nelements == 0)? 0 : -1);
if (priv->nelements != DSA_NTAGS)
return (-1);
for (i = 0; i < DSA_NTAGS; i++) {
for (j = 0; j < priv->nelements; j++)
if (priv->elements[j].tag == TAG(DST_ALG_DSA, i))
@@ -246,7 +255,11 @@ check_dsa(const dst_private_t *priv) {
}
static int
check_gost(const dst_private_t *priv) {
check_gost(const dst_private_t *priv, isc_boolean_t external) {
if (external)
return ((priv->nelements == 0)? 0 : -1);
if (priv->nelements != GOST_NTAGS)
return (-1);
if (priv->elements[0].tag != TAG(DST_ALG_ECCGOST, 0))
@@ -255,7 +268,11 @@ check_gost(const dst_private_t *priv) {
}
static int
check_ecdsa(const dst_private_t *priv) {
check_ecdsa(const dst_private_t *priv, isc_boolean_t external) {
if (external)
return ((priv->nelements == 0) ? 0 : -1);
if (priv->nelements != ECDSA_NTAGS)
return (-1);
if (priv->elements[0].tag != TAG(DST_ALG_ECDSA256, 0))
@@ -309,7 +326,7 @@ check_hmac_sha(const dst_private_t *priv, unsigned int ntags,
static int
check_data(const dst_private_t *priv, const unsigned int alg,
isc_boolean_t old)
isc_boolean_t old, isc_boolean_t external)
{
/* XXXVIX this switch statement is too sparse to gen a jump table. */
switch (alg) {
@@ -318,17 +335,17 @@ check_data(const dst_private_t *priv, const unsigned int alg,
case DST_ALG_NSEC3RSASHA1:
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
return (check_rsa(priv));
return (check_rsa(priv, external));
case DST_ALG_DH:
return (check_dh(priv));
case DST_ALG_DSA:
case DST_ALG_NSEC3DSA:
return (check_dsa(priv));
return (check_dsa(priv, external));
case DST_ALG_ECCGOST:
return (check_gost(priv));
return (check_gost(priv, external));
case DST_ALG_ECDSA256:
case DST_ALG_ECDSA384:
return (check_ecdsa(priv));
return (check_ecdsa(priv, external));
case DST_ALG_HMACMD5:
return (check_hmac_md5(priv, old));
case DST_ALG_HMACSHA1:
@@ -372,6 +389,7 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
unsigned int opt = ISC_LEXOPT_EOL;
isc_stdtime_t when;
isc_result_t ret;
isc_boolean_t external = ISC_FALSE;
REQUIRE(priv != NULL);
@@ -467,9 +485,15 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
if (token.type != isc_tokentype_string) {
ret = DST_R_INVALIDPRIVATEKEY;
NEXTTOKEN(lex, opt, &token);
goto fail;
}
if (strcmp(DST_AS_STR(token), "External:") == 0) {
external = ISC_TRUE;
goto next;
}
/* Numeric metadata */
tag = find_numericdata(DST_AS_STR(token));
if (tag >= 0) {
@@ -534,8 +558,14 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
READLINE(lex, opt, &token);
data = NULL;
}
done:
check = check_data(priv, alg, ISC_TRUE);
if (external && priv->nelements != 0) {
ret = DST_R_INVALIDPRIVATEKEY;
goto fail;
}
check = check_data(priv, alg, ISC_TRUE, external);
if (check < 0) {
ret = DST_R_INVALIDPRIVATEKEY;
goto fail;
@@ -544,6 +574,8 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
goto fail;
}
key->external = external;
return (ISC_R_SUCCESS);
fail:
@@ -573,7 +605,7 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
REQUIRE(priv != NULL);
ret = check_data(priv, dst_key_alg(key), ISC_FALSE);
ret = check_data(priv, dst_key_alg(key), ISC_FALSE, key->external);
if (ret < 0)
return (DST_R_INVALIDPRIVATEKEY);
else if (ret != ISC_R_SUCCESS)
@@ -691,6 +723,9 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
fprintf(fp, "%s %.*s\n", s, (int)r.length, r.base);
}
if (key->external)
fprintf(fp, "External:\n");
/* Add the metadata tags */
if (major > 1 || (major == 1 && minor >= 3)) {
for (i = 0; i < NUMERIC_NTAGS; i++) {
@@ -706,14 +741,14 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
isc_buffer_init(&b, buffer, sizeof(buffer));
result = dns_time32_totext(when, &b);
if (result != ISC_R_SUCCESS) {
if (result != ISC_R_SUCCESS) {
fclose(fp);
return (DST_R_INVALIDPRIVATEKEY);
}
}
isc_buffer_usedregion(&b, &r);
fprintf(fp, "%s %.*s\n", timetags[i], (int)r.length,
fprintf(fp, "%s %.*s\n", timetags[i], (int)r.length,
r.base);
}
}