]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2731. [func] Additional work on change 2709. The key parser
authorEvan Hunt <each@isc.org>
Mon, 26 Oct 2009 21:18:24 +0000 (21:18 +0000)
committerEvan Hunt <each@isc.org>
Mon, 26 Oct 2009 21:18:24 +0000 (21:18 +0000)
will now ignore unrecognized fields when the
minor version number of the private key format
has been increased.  It will reject any key with
the major version number increased. [RT #20310]

CHANGES
bin/dnssec/dnssec-revoke.c
bin/dnssec/dnssec-settime.c
bin/dnssec/dnssectool.c
bin/dnssec/dnssectool.h
lib/dns/dnssec.c
lib/dns/dst_parse.c
lib/dns/dst_parse.h
lib/dns/include/dst/dst.h

diff --git a/CHANGES b/CHANGES
index 159108b04d648650e707c7d80288a5c9ece7be45..2b9eb3e9fc12908a1e78ccde26691675baa1a0e5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+2731.  [func]          Additional work on change 2709.  The key parser
+                       will now ignore unrecognized fields when the
+                       minor version number of the private key format
+                       has been increased.  It will reject any key with
+                       the major version number increased. [RT #20310]
+
 2730.  [func]          Have dnssec-keygen display a progress indication
                        a la 'openssl genrsa' on standard error. Note
                        when the first '.' is followed by a long stop
index 34798f8b9887c5fd264f31d736ed1258dd0381d4..a04cabeecb15cd6ebb51dfb0fde5a4a3a7e391ae 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dnssec-revoke.c,v 1.16 2009/10/12 20:48:10 each Exp $ */
+/* $Id: dnssec-revoke.c,v 1.17 2009/10/26 21:18:24 each Exp $ */
 
 /*! \file */
 
@@ -179,18 +179,21 @@ main(int argc, char **argv) {
                fatal("Invalid keyfile name %s: %s",
                      filename, isc_result_totext(result));
 
-       if (verbose > 2) {
-               char keystr[DST_KEY_FORMATSIZE];
+       dst_key_format(key, keystr, sizeof(keystr));
 
-               dst_key_format(key, keystr, sizeof(keystr));
+       if (verbose > 2)
                fprintf(stderr, "%s: %s\n", program, keystr);
-       }
+
+       if (force)
+               set_keyversion(key);
+       else
+               check_keyversion(key, keystr);
+
 
        flags = dst_key_flags(key);
        if ((flags & DNS_KEYFLAG_REVOKE) == 0) {
                isc_stdtime_t now;
 
-
                if ((flags & DNS_KEYFLAG_KSK) == 0)
                        fprintf(stderr, "%s: warning: Key is not flagged "
                                        "as a KSK. Revoking a ZSK is "
index 7371955a25593eae5fac9c455d1e3fb9c896276d..4a7f04811c85b4cc632a64c5c0ce59a37d3c5cd9 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dnssec-settime.c,v 1.17 2009/10/12 20:48:10 each Exp $ */
+/* $Id: dnssec-settime.c,v 1.18 2009/10/26 21:18:24 each Exp $ */
 
 /*! \file */
 
@@ -131,7 +131,6 @@ main(int argc, char **argv) {
        isc_entropy_t *ectx = NULL;
        dst_key_t *key = NULL;
        isc_buffer_t buf;
-       int major, minor;
        isc_stdtime_t   now;
        isc_stdtime_t   pub = 0, act = 0, rev = 0, inact = 0, del = 0;
        isc_boolean_t   setpub = ISC_FALSE, setact = ISC_FALSE;
@@ -143,7 +142,7 @@ main(int argc, char **argv) {
        isc_boolean_t   printcreate = ISC_FALSE, printpub = ISC_FALSE;
        isc_boolean_t   printact = ISC_FALSE,  printrev = ISC_FALSE;
        isc_boolean_t   printinact = ISC_FALSE, printdel = ISC_FALSE;
-       isc_boolean_t   forceupdate = ISC_FALSE;
+       isc_boolean_t   force = ISC_FALSE;
        isc_boolean_t   epoch = ISC_FALSE;
        isc_boolean_t   changed = ISC_FALSE;
 
@@ -167,7 +166,7 @@ main(int argc, char **argv) {
                        engine = isc_commandline_argument;
                        break;
                case 'f':
-                       forceupdate = ISC_TRUE;
+                       force = ISC_TRUE;
                        break;
                case 'p':
                        p = isc_commandline_argument;
@@ -346,20 +345,10 @@ main(int argc, char **argv) {
 
        dst_key_format(key, keystr, sizeof(keystr));
 
-       /* Is this an old-style key? */
-       dst_key_getprivateformat(key, &major, &minor);
-       if (major <= 1 && minor <= 2) {
-               if (forceupdate) {
-                       /*
-                        * Updating to new-style key: set
-                        * Private-key-format to 1.3
-                        */
-                       dst_key_setprivateformat(key, 1, 3);
-                       dst_key_settime(key, DST_TIME_CREATED, now);
-               } else
-                       fatal("Incompatible key %s, "
-                             "use -f to force update.", keystr);
-       }
+       if (force)
+               set_keyversion(key);
+       else
+               check_keyversion(key, keystr);
 
        if (verbose > 2)
                fprintf(stderr, "%s: %s\n", program, keystr);
index 541dda0b12de414df5916d636216c1baa7fe8583..d8c4ea48659bd9146ba30aeef3014e599ecc1ac0 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dnssectool.c,v 1.56 2009/10/24 00:00:06 each Exp $ */
+/* $Id: dnssectool.c,v 1.57 2009/10/26 21:18:24 each Exp $ */
 
 /*! \file */
 
@@ -362,3 +362,43 @@ try_dir(const char *dirname) {
        }
        return (result);
 }
+
+/*
+ * Check private key version compatibility.
+ */
+void
+check_keyversion(dst_key_t *key, char *keystr) {
+       int major, minor;
+       dst_key_getprivateformat(key, &major, &minor);
+        INSIST(major <= DST_MAJOR_VERSION); /* invalid private key */
+
+       if (major < DST_MAJOR_VERSION || minor < DST_MINOR_VERSION) 
+               fatal("Key %s has incompatible format version %d.%d, "
+                     "use -f to force upgrade to new version.",
+                     keystr, major, minor);
+       if (minor > DST_MINOR_VERSION)
+               fatal("Key %s has incompatible format version %d.%d, "
+                     "use -f to force downgrade to current version.",
+                     keystr, major, minor);
+}
+
+void
+set_keyversion(dst_key_t *key) {
+       int major, minor;
+       dst_key_getprivateformat(key, &major, &minor);
+        INSIST(major <= DST_MAJOR_VERSION);
+
+       if (major != DST_MAJOR_VERSION || minor != DST_MINOR_VERSION)
+               dst_key_setprivateformat(key, DST_MAJOR_VERSION,
+                                        DST_MINOR_VERSION);
+
+       /*
+        * If the key is from a version older than 1.3, set
+        * set the creation date
+        */
+       if (major < 1 || (major == 1 && minor <= 2)) {
+               isc_stdtime_t now;
+               isc_stdtime_get(&now);
+               dst_key_settime(key, DST_TIME_CREATED, now);
+       }
+}
index c1a0ee1767ea6051ad294fff6a3ee547d3fe11b8..249d7054e6161cdee1f9dc61e931edf209af5b3f 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dnssectool.h,v 1.28 2009/10/24 00:00:06 each Exp $ */
+/* $Id: dnssectool.h,v 1.29 2009/10/26 21:18:24 each Exp $ */
 
 #ifndef DNSSECTOOL_H
 #define DNSSECTOOL_H 1
@@ -70,4 +70,10 @@ strtoclass(const char *str);
 
 isc_result_t
 try_dir(const char *dirname);
+
+void
+check_keyversion(dst_key_t *key, char *keystr);
+
+void
+set_keyversion(dst_key_t *key);
 #endif /* DNSSEC_DNSSECTOOL_H */
index 9c90215bed3dc1b73049f107ee8022d50c77ed56..5a40d2e80ae15182dae3f048e3acabe3e5062092 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 /*
- * $Id: dnssec.c,v 1.106 2009/10/16 23:47:54 tbox Exp $
+ * $Id: dnssec.c,v 1.107 2009/10/26 21:18:24 each Exp $
  */
 
 /*! \file */
@@ -985,6 +985,8 @@ dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey,
 
        /* Is this an old-style key? */
        result = dst_key_getprivateformat(dk->key, &major, &minor);
+
+       /* Smart signing started with key format 1.3 */
        dk->legacy = ISC_TF(major == 1 && minor <= 2);
 
        ISC_LINK_INIT(dk, link);
index c5dc612f416c4d1242ab207d5cdde2c058b661e3..5fc5638193901d0978e2920226a2cf0e91f2147b 100644 (file)
@@ -31,7 +31,7 @@
 
 /*%
  * Principal Author: Brian Wellington
- * $Id: dst_parse.c,v 1.22 2009/10/22 02:21:30 each Exp $
+ * $Id: dst_parse.c,v 1.23 2009/10/26 21:18:24 each Exp $
  */
 
 #include <config.h>
@@ -385,9 +385,7 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
                goto fail;
        }
 
-       if (major > MAJOR_VERSION ||
-           (major == MAJOR_VERSION && minor > MINOR_VERSION))
-       {
+       if (major > DST_MAJOR_VERSION) {
                ret = DST_R_INVALIDPRIVATEKEY;
                goto fail;
        }
@@ -476,10 +474,13 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
 
                /* Key data */
                tag = find_value(DST_AS_STR(token), alg);
-               if (tag < 0) {
+               if (tag < 0 && minor > DST_MINOR_VERSION)
+                       goto next;
+               else if (tag < 0) {
                        ret = DST_R_INVALIDPRIVATEKEY;
                        goto fail;
                }
+
                priv->elements[n].tag = tag;
 
                data = (unsigned char *) isc_mem_get(mctx, MAXFIELDSIZE);
@@ -490,6 +491,7 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
                ret = isc_base64_tobuffer(lex, &b, -1);
                if (ret != ISC_R_SUCCESS)
                        goto fail;
+
                isc_buffer_usedregion(&b, &r);
                priv->elements[n].length = r.length;
                priv->elements[n].data = r.base;
@@ -550,8 +552,8 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
 
        dst_key_getprivateformat(key, &major, &minor);
        if (major == 0 && minor == 0) {
-               major = MAJOR_VERSION;
-               minor = MINOR_VERSION;
+               major = DST_MAJOR_VERSION;
+               minor = DST_MINOR_VERSION;
        }
 
        /* XXXDCL return value should be checked for full filesystem */
index d893c2dc2afedf975edd5515645d4ae95e3cadfe..ceb8b188bd863fc0d39bb406ad5f14c7c698ad8f 100644 (file)
@@ -29,7 +29,7 @@
  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dst_parse.h,v 1.14 2009/09/02 06:29:01 each Exp $ */
+/* $Id: dst_parse.h,v 1.15 2009/10/26 21:18:24 each Exp $ */
 
 /*! \file */
 #ifndef DST_DST_PARSE_H
@@ -39,9 +39,6 @@
 
 #include <dst/dst.h>
 
-#define MAJOR_VERSION          1
-#define MINOR_VERSION          3
-
 #define MAXFIELDSIZE           512
 
 /*
index 2217139e3d2b12b2ba682e2e1c82243506b9403b..1f6020a3bff313ea077ebe389face43ef0c394cd 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dst.h,v 1.24 2009/10/24 09:46:19 fdupont Exp $ */
+/* $Id: dst.h,v 1.25 2009/10/26 21:18:24 each Exp $ */
 
 #ifndef DST_DST_H
 #define DST_DST_H 1
@@ -100,6 +100,28 @@ typedef struct dst_context         dst_context_t;
 #define DST_NUM_ROLLPERIOD     3
 #define DST_MAX_NUMERIC                3
 
+/*
+ * Current format version number of the private key parser.
+ *
+ * When parsing a key file with the same major number but a higher minor
+ * number, the key parser will ignore any fields it does not recognize.
+ * Thus, DST_MINOR_VERSION should be incremented whenever new
+ * fields are added to the private key file (such as new metadata).
+ *
+ * When rewriting these keys, those fields will be dropped, and the
+ * format version set back to the current one..
+ *
+ * When a key is seen with a higher major number, the key parser will
+ * reject it as invalid.  Thus, DST_MAJOR_VERSION should be incremented
+ * and DST_MINOR_VERSION set to zero whenever there is a format change
+ * which is not backward compatible to previous versions of the dst_key
+ * parser, such as change in the syntax of an existing field, the removal
+ * of a currently mandatory field, or a new field added which would
+ * alter the functioning of the key if it were absent.
+ */
+#define DST_MAJOR_VERSION      1
+#define DST_MINOR_VERSION      3
+
 /***
  *** Functions
  ***/