]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] rationalize external key handling
authorEvan Hunt <each@isc.org>
Fri, 31 Jan 2014 01:48:10 +0000 (17:48 -0800)
committerEvan Hunt <each@isc.org>
Fri, 31 Jan 2014 01:49:32 +0000 (17:49 -0800)
3723. [cleanup] Imported keys are now handled the same way
regardless of DNSSEC algorithm. [RT #35215]

14 files changed:
CHANGES
lib/dns/dst_result.c
lib/dns/hmac_link.c
lib/dns/include/dst/result.h
lib/dns/openssldh_link.c
lib/dns/openssldsa_link.c
lib/dns/opensslecdsa_link.c
lib/dns/opensslgost_link.c
lib/dns/opensslrsa_link.c
lib/dns/pkcs11dh_link.c
lib/dns/pkcs11dsa_link.c
lib/dns/pkcs11ecdsa_link.c
lib/dns/pkcs11gost_link.c
lib/dns/pkcs11rsa_link.c

diff --git a/CHANGES b/CHANGES
index 369b314ca320c7e01f7a29f953124b7b5f0853a3..6e33aa5a862602940cdb49e12be28fd5f73f3af9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3723.  [cleanup]       Imported keys are now handled the same way
+                       regardless of DNSSEC algorithm. [RT #35215]
+
 3722.  [bug]           Using geoip ACLs in a blackhole statement 
                        could cause a segfault. [RT #35272]
 
index e9f7b06ab2521dd63c61129822c47b9cd6cd025e..078ea38391f8106c56857e1532c711cb256fe099 100644 (file)
@@ -50,7 +50,8 @@ static const char *text[DST_R_NRESULTS] = {
        "failure computing a shared secret",    /*%< 18 */
        "no randomness available",              /*%< 19 */
        "bad key type",                         /*%< 20 */
-       "no engine"                             /*%< 21 */
+       "no engine",                            /*%< 21 */
+       "illegal operation for an external key" /*%< 22 */
 };
 
 #define DST_RESULT_RESULTSET                   2
index d1eb7426114478f84511e2c32fa0ca0cd5775c46..01876d336ab588dcd05b386c712f48c25b243c23 100644 (file)
@@ -250,6 +250,9 @@ hmacmd5_tofile(const dst_key_t *key, const char *directory) {
        if (key->keydata.hmacmd5 == NULL)
                return (DST_R_NULLKEY);
 
+       if (key->external)
+               return (DST_R_EXTERNALKEY);
+
        hkey = key->keydata.hmacmd5;
 
        priv.elements[cnt].tag = TAG_HMACMD5_KEY;
@@ -281,6 +284,9 @@ hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        if (result != ISC_R_SUCCESS)
                return (result);
 
+       if (key->external)
+               result = DST_R_EXTERNALKEY;
+
        key->key_bits = 0;
        for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
                switch (priv.elements[i].tag) {
@@ -527,6 +533,9 @@ hmacsha1_tofile(const dst_key_t *key, const char *directory) {
        if (key->keydata.hmacsha1 == NULL)
                return (DST_R_NULLKEY);
 
+       if (key->external)
+               return (DST_R_EXTERNALKEY);
+
        hkey = key->keydata.hmacsha1;
 
        priv.elements[cnt].tag = TAG_HMACSHA1_KEY;
@@ -558,8 +567,11 @@ hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        if (result != ISC_R_SUCCESS)
                return (result);
 
+       if (key->external)
+               result = DST_R_EXTERNALKEY;
+
        key->key_bits = 0;
-       for (i = 0; i < priv.nelements; i++) {
+       for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
                switch (priv.elements[i].tag) {
                case TAG_HMACSHA1_KEY:
                        isc_buffer_init(&b, priv.elements[i].data,
@@ -806,6 +818,9 @@ hmacsha224_tofile(const dst_key_t *key, const char *directory) {
        if (key->keydata.hmacsha224 == NULL)
                return (DST_R_NULLKEY);
 
+       if (key->external)
+               return (DST_R_EXTERNALKEY);
+
        hkey = key->keydata.hmacsha224;
 
        priv.elements[cnt].tag = TAG_HMACSHA224_KEY;
@@ -837,8 +852,11 @@ hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        if (result != ISC_R_SUCCESS)
                return (result);
 
+       if (key->external)
+               result = DST_R_EXTERNALKEY;
+
        key->key_bits = 0;
-       for (i = 0; i < priv.nelements; i++) {
+       for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
                switch (priv.elements[i].tag) {
                case TAG_HMACSHA224_KEY:
                        isc_buffer_init(&b, priv.elements[i].data,
@@ -1085,6 +1103,9 @@ hmacsha256_tofile(const dst_key_t *key, const char *directory) {
        if (key->keydata.hmacsha256 == NULL)
                return (DST_R_NULLKEY);
 
+       if (key->external)
+               return (DST_R_EXTERNALKEY);
+
        hkey = key->keydata.hmacsha256;
 
        priv.elements[cnt].tag = TAG_HMACSHA256_KEY;
@@ -1116,8 +1137,11 @@ hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        if (result != ISC_R_SUCCESS)
                return (result);
 
+       if (key->external)
+               result = DST_R_EXTERNALKEY;
+
        key->key_bits = 0;
-       for (i = 0; i < priv.nelements; i++) {
+       for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
                switch (priv.elements[i].tag) {
                case TAG_HMACSHA256_KEY:
                        isc_buffer_init(&b, priv.elements[i].data,
@@ -1364,6 +1388,9 @@ hmacsha384_tofile(const dst_key_t *key, const char *directory) {
        if (key->keydata.hmacsha384 == NULL)
                return (DST_R_NULLKEY);
 
+       if (key->external)
+               return (DST_R_EXTERNALKEY);
+
        hkey = key->keydata.hmacsha384;
 
        priv.elements[cnt].tag = TAG_HMACSHA384_KEY;
@@ -1395,8 +1422,11 @@ hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        if (result != ISC_R_SUCCESS)
                return (result);
 
+       if (key->external)
+               result = DST_R_EXTERNALKEY;
+
        key->key_bits = 0;
-       for (i = 0; i < priv.nelements; i++) {
+       for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
                switch (priv.elements[i].tag) {
                case TAG_HMACSHA384_KEY:
                        isc_buffer_init(&b, priv.elements[i].data,
@@ -1643,6 +1673,9 @@ hmacsha512_tofile(const dst_key_t *key, const char *directory) {
        if (key->keydata.hmacsha512 == NULL)
                return (DST_R_NULLKEY);
 
+       if (key->external)
+               return (DST_R_EXTERNALKEY);
+
        hkey = key->keydata.hmacsha512;
 
        priv.elements[cnt].tag = TAG_HMACSHA512_KEY;
@@ -1674,8 +1707,11 @@ hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        if (result != ISC_R_SUCCESS)
                return (result);
 
+       if (key->external)
+               result = DST_R_EXTERNALKEY;
+
        key->key_bits = 0;
-       for (i = 0; i < priv.nelements; i++) {
+       for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
                switch (priv.elements[i].tag) {
                case TAG_HMACSHA512_KEY:
                        isc_buffer_init(&b, priv.elements[i].data,
index 00640a1b1c822be0116d3096c07fe474c3fece2c..cf9428f6bdf4ebda95da87b00cb3ae8f492c3bfb 100644 (file)
@@ -57,8 +57,9 @@
 #define DST_R_NORANDOMNESS             (ISC_RESULTCLASS_DST + 19)
 #define DST_R_BADKEYTYPE               (ISC_RESULTCLASS_DST + 20)
 #define DST_R_NOENGINE                 (ISC_RESULTCLASS_DST + 21)
+#define DST_R_EXTERNALKEY              (ISC_RESULTCLASS_DST + 22)
 
-#define DST_R_NRESULTS                 22      /* Number of results */
+#define DST_R_NRESULTS                 23      /* Number of results */
 
 ISC_LANG_BEGINDECLS
 
index cf49143358228c04bb2b95f7aefe155ef78d321f..6c3f555f8dc71b75d2b7a1bbfcc1eb9fdddd1995 100644 (file)
@@ -463,6 +463,9 @@ openssldh_tofile(const dst_key_t *key, const char *directory) {
        if (key->keydata.dh == NULL)
                return (DST_R_NULLKEY);
 
+       if (key->external)
+               return (DST_R_EXTERNALKEY);
+
        dh = key->keydata.dh;
 
        memset(bufs, 0, sizeof(bufs));
@@ -528,6 +531,9 @@ openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        if (ret != ISC_R_SUCCESS)
                return (ret);
 
+       if (key->external)
+               DST_RET(DST_R_EXTERNALKEY);
+
        dh = DH_new();
        if (dh == NULL)
                DST_RET(ISC_R_NOMEMORY);
index 449c8ac1a7149959cecb11c832e91179f891f079..67b6bbdae3637670867a9538eb66876430ecd2cd 100644 (file)
@@ -578,6 +578,19 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        if (ret != ISC_R_SUCCESS)
                return (ret);
 
+       if (key->external) {
+               if (priv.nelements != 0)
+                       DST_RET(DST_R_INVALIDPRIVATEKEY);
+               if (pub == NULL)
+                       DST_RET(DST_R_INVALIDPRIVATEKEY);
+               key->keydata.pkey = pub->keydata.pkey;
+               pub->keydata.pkey = NULL;
+               key->key_size = pub->key_size;
+               dst__privstruct_free(&priv, mctx);
+               memset(&priv, 0, sizeof(priv));
+               return (ISC_R_SUCCESS);
+       }
+
        dsa = DSA_new();
        if (dsa == NULL)
                DST_RET(ISC_R_NOMEMORY);
@@ -610,22 +623,8 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
                }
        }
        dst__privstruct_free(&priv, mctx);
-
-       if (key->external) {
-               if (pub == NULL)
-                       DST_RET(DST_R_INVALIDPRIVATEKEY);
-               dsa->q = pub->keydata.dsa->q;
-               pub->keydata.dsa->q = NULL;
-               dsa->p = pub->keydata.dsa->p;
-               pub->keydata.dsa->p = NULL;
-               dsa->g = pub->keydata.dsa->g;
-               pub->keydata.dsa->g =  NULL;
-               dsa->pub_key = pub->keydata.dsa->pub_key;
-               pub->keydata.dsa->pub_key = NULL;
-       }
-
+       memset(&priv, 0, sizeof(priv));
        key->key_size = BN_num_bits(dsa->p);
-
        return (ISC_R_SUCCESS);
 
  err:
index c35eb67f29d443484bf318814a8dc4b08b5dfda7..da2b68b6e884a899b9ea805ae68603e117f96641 100644 (file)
@@ -519,9 +519,8 @@ static isc_result_t
 opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        dst_private_t priv;
        isc_result_t ret;
-       EVP_PKEY *pkey, *pubpkey;
-       EC_KEY *eckey = NULL, *pubeckey = NULL;
-       const EC_POINT *pubkey;
+       EVP_PKEY *pkey;
+       EC_KEY *eckey = NULL;
        BIGNUM *privkey = NULL;
        int group_nid;
        isc_mem_t *mctx = key->mctx;
@@ -529,50 +528,41 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
                key->key_alg == DST_ALG_ECDSA384);
 
-       if (key->key_alg == DST_ALG_ECDSA256)
-               group_nid = NID_X9_62_prime256v1;
-       else
-               group_nid = NID_secp384r1;
-
-       eckey = EC_KEY_new_by_curve_name(group_nid);
-       if (eckey == NULL)
-               return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
-
        /* read private key file */
        ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv);
        if (ret != ISC_R_SUCCESS)
                goto err;
 
        if (key->external) {
-               /*
-                * Copy the public key to this new key.
-                */
-               if (pub == NULL)
-                       DST_RET(DST_R_INVALIDPRIVATEKEY);
-               pubpkey = pub->keydata.pkey;
-               pubeckey = EVP_PKEY_get1_EC_KEY(pubpkey);
-               if (pubeckey == NULL)
-                       DST_RET(DST_R_INVALIDPRIVATEKEY);
-               pubkey = EC_KEY_get0_public_key(pubeckey);
-               if (pubkey == NULL)
-                       DST_RET(DST_R_INVALIDPRIVATEKEY);
-               if (EC_KEY_set_public_key(eckey, pubkey) != 1)
-                       DST_RET(DST_R_INVALIDPRIVATEKEY);
-               if (EC_KEY_check_key(eckey) != 1)
+               if (priv.nelements != 0)
                        DST_RET(DST_R_INVALIDPRIVATEKEY);
-       } else {
-               privkey = BN_bin2bn(priv.elements[0].data,
-                                   priv.elements[0].length, NULL);
-               if (privkey == NULL)
-                       DST_RET(ISC_R_NOMEMORY);
-               if (!EC_KEY_set_private_key(eckey, privkey))
-                       DST_RET(ISC_R_NOMEMORY);
-               if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS)
+               if (pub == NULL)
                        DST_RET(DST_R_INVALIDPRIVATEKEY);
+               key->keydata.pkey = pub->keydata.pkey;
+               pub->keydata.pkey = NULL;
                dst__privstruct_free(&priv, mctx);
                memset(&priv, 0, sizeof(priv));
+               return (ISC_R_SUCCESS);
        }
 
+       if (key->key_alg == DST_ALG_ECDSA256)
+               group_nid = NID_X9_62_prime256v1;
+       else
+               group_nid = NID_secp384r1;
+
+       eckey = EC_KEY_new_by_curve_name(group_nid);
+       if (eckey == NULL)
+               return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+
+       privkey = BN_bin2bn(priv.elements[0].data,
+                           priv.elements[0].length, NULL);
+       if (privkey == NULL)
+               DST_RET(ISC_R_NOMEMORY);
+       if (!EC_KEY_set_private_key(eckey, privkey))
+               DST_RET(ISC_R_NOMEMORY);
+       if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS)
+               DST_RET(DST_R_INVALIDPRIVATEKEY);
+
        pkey = EVP_PKEY_new();
        if (pkey == NULL)
                DST_RET (ISC_R_NOMEMORY);
@@ -588,8 +578,6 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
                BN_clear_free(privkey);
        if (eckey != NULL)
                EC_KEY_free(eckey);
-       if (pubeckey != NULL)
-               EC_KEY_free(pubeckey);
        dst__privstruct_free(&priv, mctx);
        memset(&priv, 0, sizeof(priv));
        return (ret);
index e896b0abff966f30985524438b66997a9b078f73..b7c35dca4e80611599c6eb858ada864064e49e52 100644 (file)
@@ -452,69 +452,70 @@ opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        BIGNUM *privkey = NULL;
        const unsigned char *p;
 
-       UNUSED(pub);
-
        /* read private key file */
        ret = dst__privstruct_parse(key, DST_ALG_ECCGOST, lexer, mctx, &priv);
        if (ret != ISC_R_SUCCESS)
                return (ret);
 
        if (key->external) {
-               INSIST(priv.nelements == 0);
+               if (priv.nelements != 0)
+                       DST_RET(DST_R_INVALIDPRIVATEKEY);
                if (pub == NULL)
                        DST_RET(DST_R_INVALIDPRIVATEKEY);
                key->keydata.pkey = pub->keydata.pkey;
                pub->keydata.pkey = NULL;
-       } else {
-               INSIST((priv.elements[0].tag == TAG_GOST_PRIVASN1) ||
-                      (priv.elements[0].tag == TAG_GOST_PRIVRAW));
-
-               if (priv.elements[0].tag == TAG_GOST_PRIVASN1) {
-                       p = priv.elements[0].data;
-                       if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
-                                   (long) priv.elements[0].length) == NULL)
-                               DST_RET(dst__openssl_toresult2(
+               key->key_size = pub->key_size;
+               dst__privstruct_free(&priv, mctx);
+               memset(&priv, 0, sizeof(priv));
+               return (ISC_R_SUCCESS);
+       }
+
+       INSIST((priv.elements[0].tag == TAG_GOST_PRIVASN1) ||
+              (priv.elements[0].tag == TAG_GOST_PRIVRAW));
+
+       if (priv.elements[0].tag == TAG_GOST_PRIVASN1) {
+               p = priv.elements[0].data;
+               if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
+                                  (long) priv.elements[0].length) == NULL)
+                       DST_RET(dst__openssl_toresult2(
                                            "d2i_PrivateKey",
                                            DST_R_INVALIDPRIVATEKEY));
-               } else {
-                       if ((pub != NULL) && (pub->keydata.pkey != NULL)) {
-                               eckey = EVP_PKEY_get0(pub->keydata.pkey);
-                               pubkey = EC_KEY_get0_public_key(eckey);
-                       }
-
-                       privkey = BN_bin2bn(priv.elements[0].data,
-                                           priv.elements[0].length, NULL);
-                       if (privkey == NULL)
-                               DST_RET(ISC_R_NOMEMORY);
-
-                       /* can't create directly the whole key */
-                       p = gost_dummy_key;
-                       if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
-                                   (long) sizeof(gost_dummy_key)) == NULL)
-                               DST_RET(dst__openssl_toresult2(
+       } else {
+               if ((pub != NULL) && (pub->keydata.pkey != NULL)) {
+                       eckey = EVP_PKEY_get0(pub->keydata.pkey);
+                       pubkey = EC_KEY_get0_public_key(eckey);
+               }
+
+               privkey = BN_bin2bn(priv.elements[0].data,
+                                   priv.elements[0].length, NULL);
+               if (privkey == NULL)
+                       DST_RET(ISC_R_NOMEMORY);
+
+               /* can't create directly the whole key */
+               p = gost_dummy_key;
+               if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
+                                  (long) sizeof(gost_dummy_key)) == NULL)
+                       DST_RET(dst__openssl_toresult2(
                                            "d2i_PrivateKey",
                                            DST_R_INVALIDPRIVATEKEY));
 
-                       eckey = EVP_PKEY_get0(pkey);
-                       if (eckey == NULL)
-                               return (dst__openssl_toresult(
-                                           DST_R_OPENSSLFAILURE));
-                       if (!EC_KEY_set_private_key(eckey, privkey))
-                               DST_RET(ISC_R_NOMEMORY);
+               eckey = EVP_PKEY_get0(pkey);
+               if (eckey == NULL)
+                       return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+               if (!EC_KEY_set_private_key(eckey, privkey))
+                       DST_RET(ISC_R_NOMEMORY);
 
-                       /* have to (re)set the public key */
+               /* have to (re)set the public key */
 #ifdef notyet
-                       (void) gost2001_compute_public(eckey);
+               (void) gost2001_compute_public(eckey);
 #else
-                       if ((pubkey != NULL) &&
-                           !EC_KEY_set_public_key(eckey, pubkey))
-                               DST_RET(ISC_R_NOMEMORY);
+               if ((pubkey != NULL) && !EC_KEY_set_public_key(eckey, pubkey))
+                       DST_RET(ISC_R_NOMEMORY);
 #endif
-                       BN_clear_free(privkey);
-                       privkey = NULL;
-               }
-               key->keydata.pkey = pkey;
+               BN_clear_free(privkey);
+               privkey = NULL;
        }
+       key->keydata.pkey = pkey;
        key->key_size = EVP_PKEY_bits(pkey);
        dst__privstruct_free(&priv, mctx);
        memset(&priv, 0, sizeof(priv));
index e3d9be00e0b1db2d1861b33969e2aa14f9a76162..667907a9557fb70ba73fbccc84e63720c79d0193 100644 (file)
@@ -1195,6 +1195,24 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        EVP_PKEY *pkey = NULL;
 #endif
 
+       /* read private key file */
+       ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
+       if (ret != ISC_R_SUCCESS)
+               goto err;
+
+       if (key->external) {
+               if (priv.nelements != 0)
+                       DST_RET(DST_R_INVALIDPRIVATEKEY);
+               if (pub == NULL)
+                       DST_RET(DST_R_INVALIDPRIVATEKEY);
+               key->keydata.pkey = pub->keydata.pkey;
+               pub->keydata.pkey = NULL;
+               key->key_size = pub->key_size;
+               dst__privstruct_free(&priv, mctx);
+               memset(&priv, 0, sizeof(priv));
+               return (ISC_R_SUCCESS);
+       }
+
 #if USE_EVP
        if (pub != NULL && pub->keydata.pkey != NULL)
                pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey);
@@ -1205,14 +1223,6 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        }
 #endif
 
-       /* read private key file */
-       ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
-       if (ret != ISC_R_SUCCESS)
-               goto err;
-
-       if (key->external && priv.nelements != 0)
-               DST_RET(DST_R_INVALIDPRIVATEKEY);
-
        for (i = 0; i < priv.nelements; i++) {
                switch (priv.elements[i].tag) {
                case TAG_RSA_ENGINE:
@@ -1335,10 +1345,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
 
        if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
                DST_RET(DST_R_INVALIDPRIVATEKEY);
-       if (!key->external) {
-               if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS)
-                       DST_RET(ISC_R_RANGE);
-       }
+       if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS)
+               DST_RET(ISC_R_RANGE);
        key->key_size = BN_num_bits(rsa->n);
        if (pubrsa != NULL)
                RSA_free(pubrsa);
index 570ba9efae43f4f2d3ff979d8abed94d321bdda5..b8daba393b01b6b59584edf8ef330ab91dcdf8ab 100644 (file)
@@ -925,6 +925,9 @@ pkcs11dh_tofile(const dst_key_t *key, const char *directory) {
        if (key->keydata.pkey == NULL)
                return (DST_R_NULLKEY);
 
+       if (key->external)
+               return (DST_R_EXTERNALKEY);
+
        dh = key->keydata.pkey;
 
        for (attr = pk11_attribute_first(dh);
@@ -1013,6 +1016,9 @@ pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        if (ret != ISC_R_SUCCESS)
                return (ret);
 
+       if (key->external)
+               DST_RET(DST_R_EXTERNALKEY);
+
        dh = (iscpk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh));
        if (dh == NULL)
                DST_RET(ISC_R_NOMEMORY);
index 84d3e3cec828c4ee489fff7a93ab04a3a501665b..e0ef40b8cded32b03332eea015a96b9cbf29b6aa 100644 (file)
@@ -968,14 +968,26 @@ pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        CK_ATTRIBUTE *attr;
        isc_mem_t *mctx = key->mctx;
 
-       UNUSED(pub);
        /* read private key file */
        ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv);
        if (ret != ISC_R_SUCCESS)
                return (ret);
 
-       if (key->external && priv.nelements != 0)
-               DST_RET(DST_R_INVALIDPRIVATEKEY);
+       if (key->external) {
+               if (priv.nelements != 0)
+                       DST_RET(DST_R_INVALIDPRIVATEKEY);
+               if (pub == NULL)
+                       DST_RET(DST_R_INVALIDPRIVATEKEY);
+
+               key->keydata.pkey = pub->keydata.pkey;
+               pub->keydata.pkey = NULL;
+               key->key_size = pub->key_size;
+
+               dst__privstruct_free(&priv, mctx);
+               memset(&priv, 0, sizeof(priv));
+
+               return (ISC_R_SUCCESS);
+       }
 
        dsa = (iscpk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa));
        if (dsa == NULL)
index a5e111032c3653ce427c645d7b7f6ed10144b8fa..3fe0f2f271c73ef48495f42916525734aef5a5b4 100644 (file)
@@ -918,15 +918,28 @@ pkcs11ecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
 
        REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
                key->key_alg == DST_ALG_ECDSA384);
-       REQUIRE((pub != NULL) && (pub->keydata.pkey != NULL));
+
+       if ((pub == NULL) || (pub->keydata.pkey == NULL))
+               DST_RET(DST_R_INVALIDPRIVATEKEY);
 
        /* read private key file */
        ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv);
        if (ret != ISC_R_SUCCESS)
                return (ret);
 
-       if (key->external && priv.nelements != 0)
-               DST_RET(DST_R_INVALIDPRIVATEKEY);
+       if (key->external) {
+               if (priv.nelements != 0)
+                       DST_RET(DST_R_INVALIDPRIVATEKEY);
+
+               key->keydata.pkey = pub->keydata.pkey;
+               pub->keydata.pkey = NULL;
+               key->key_size = pub->key_size;
+
+               dst__privstruct_free(&priv, mctx);
+               memset(&priv, 0, sizeof(priv));
+
+               return (ISC_R_SUCCESS);
+       }
 
        for (i = 0; i < priv.nelements; i++) {
                switch (priv.elements[i].tag) {
index ab261816b3ad27ec02db610ab4c5018b74616c0d..8e8d501209d31b6ce3d1ee84280152483394f22a 100644 (file)
@@ -744,7 +744,7 @@ pkcs11gost_tofile(const dst_key_t *key, const char *directory) {
                priv.elements[i].length =
                        (unsigned short) attr->ulValueLen + 39;
                memmove(buf, gost_private_der, 39);
-               memmove(buf +39, attr->pValue, attr->ulValueLen);
+               memmove(buf + 39, attr->pValue, attr->ulValueLen);
                adj = (int) attr->ulValueLen - 32;
                if (adj != 0) {
                        buf[1] += adj;
@@ -818,15 +818,27 @@ pkcs11gost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        CK_ATTRIBUTE *attr, *pattr;
        isc_mem_t *mctx = key->mctx;
 
-       REQUIRE((pub != NULL) && (pub->keydata.pkey != NULL));
+       if ((pub == NULL) || (pub->keydata.pkey == NULL))
+               DST_RET(DST_R_INVALIDPRIVATEKEY);
 
        /* read private key file */
        ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv);
        if (ret != ISC_R_SUCCESS)
                return (ret);
 
-       if (key->external && priv.nelements != 0)
-               DST_RET(DST_R_INVALIDPRIVATEKEY);
+       if (key->external) {
+               if (priv.nelements != 0)
+                       DST_RET(DST_R_INVALIDPRIVATEKEY);
+
+               key->keydata.pkey = pub->keydata.pkey;
+               pub->keydata.pkey = NULL;
+               key->key_size = pub->key_size;
+
+               dst__privstruct_free(&priv, mctx);
+               memset(&priv, 0, sizeof(priv));
+
+               return (ISC_R_SUCCESS);
+       }
 
        if (priv.elements[0].tag == TAG_GOST_PRIVASN1) {
                int adj = (int) priv.elements[0].length - (39 + 32);
index 77ba303d510100e5dc6cb253698c285c68c0d808..cfa3da2946a8e008f0d0078202242f55231a75c3 100644 (file)
@@ -1234,8 +1234,21 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
        if (ret != ISC_R_SUCCESS)
                return (ret);
 
-       if (key->external && priv.nelements != 0)
-               DST_RET(DST_R_INVALIDPRIVATEKEY);
+       if (key->external) {
+               if (priv.nelements != 0)
+                       DST_RET(DST_R_INVALIDPRIVATEKEY);
+               if (pub == NULL)
+                       DST_RET(DST_R_INVALIDPRIVATEKEY);
+
+               key->keydata.pkey = pub->keydata.pkey;
+               pub->keydata.pkey = NULL;
+               key->key_size = pub->key_size;
+
+               dst__privstruct_free(&priv, mctx);
+               memset(&priv, 0, sizeof(priv));
+
+               return (ISC_R_SUCCESS);
+       }
 
        for (i = 0; i < priv.nelements; i++) {
                switch (priv.elements[i].tag) {
@@ -1362,8 +1375,7 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
 
        attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT);
        INSIST(attr != NULL);
-       if (!key->external &&
-           pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS)
+       if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS)
                DST_RET(ISC_R_RANGE);
 
        dst__privstruct_free(&priv, mctx);