diff options
Diffstat (limited to 'lib/dns/opensslecdsa_link.c')
| -rw-r--r-- | lib/dns/opensslecdsa_link.c | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c index c3f5061b75467..40081c2df856e 100644 --- a/lib/dns/opensslecdsa_link.c +++ b/lib/dns/opensslecdsa_link.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -371,7 +371,7 @@ opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) { cp = buf; if (!i2o_ECPublicKey(eckey, &cp)) DST_RET (dst__openssl_toresult(ISC_R_FAILURE)); - memcpy(r.base, buf + 1, len); + memmove(r.base, buf + 1, len); isc_buffer_add(data, len); ret = ISC_R_SUCCESS; @@ -414,7 +414,7 @@ opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); buf[0] = POINT_CONVERSION_UNCOMPRESSED; - memcpy(buf + 1, r.base, len); + memmove(buf + 1, r.base, len); cp = buf; if (o2i_ECPublicKey(&eckey, (const unsigned char **) &cp, @@ -453,6 +453,11 @@ opensslecdsa_tofile(const dst_key_t *key, const char *directory) { if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); + if (key->external) { + priv.nelements = 0; + return (dst__privstruct_writefile(key, &priv, directory)); + } + pkey = key->keydata.pkey; eckey = EVP_PKEY_get1_EC_KEY(pkey); if (eckey == NULL) @@ -514,8 +519,9 @@ 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; - EC_KEY *eckey = NULL; + EVP_PKEY *pkey, *pubpkey; + EC_KEY *eckey = NULL, *pubeckey = NULL; + const EC_POINT *pubkey; BIGNUM *privkey; int group_nid; isc_mem_t *mctx = key->mctx; @@ -537,16 +543,35 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (ret != ISC_R_SUCCESS) goto err; - 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); - dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + 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) + 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) + DST_RET(DST_R_INVALIDPRIVATEKEY); + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + } pkey = EVP_PKEY_new(); if (pkey == NULL) @@ -561,6 +586,8 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { err: 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); |
