summaryrefslogtreecommitdiff
path: root/lib/dns/dst_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns/dst_parse.c')
-rw-r--r--lib/dns/dst_parse.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c
index ca43cb3d12414..2b950d5a3b9cf 100644
--- a/lib/dns/dst_parse.c
+++ b/lib/dns/dst_parse.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -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);
@@ -470,6 +488,11 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
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 +557,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 +573,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 +604,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 +722,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 +740,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);
}
}