diff options
Diffstat (limited to 'lib/dns/dst_parse.c')
| -rw-r--r-- | lib/dns/dst_parse.c | 64 |
1 files changed, 49 insertions, 15 deletions
diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c index ca43cb3d1241..2b950d5a3b9c 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); } } |
