opensslrsa_link.c revision 1f821c10583d9cddbaf3626a96ff8cf10cdb645b
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/*
d7201de09b85929a86b157f4b2d91667c68c6b52Automatic Updater * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
fcb54ce0a4f7377486df5bec83b3aa4711bf4131Mark Andrews * Copyright (C) 2000-2003 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * Permission to use, copy, modify, and/or distribute this software for any
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * purpose with or without fee is hereby granted, provided that the above
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews/*
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * Principal Author: Brian Wellington
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * $Id: opensslrsa_link.c,v 1.27 2009/09/07 12:54:59 fdupont Exp $
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff */
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff#ifdef OPENSSL
de153390f5a1f6d4fa86af91d4cae772d9846ca0Mark Andrews#ifndef USE_EVP
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff#define USE_EVP 1
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington#endif
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington#if USE_EVP
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#define USE_EVP_RSA 1
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#endif
242bba8991b030b7764f0bdca3922d75c34ea51eAndreas Gustafsson
25a66b4e41e2b0a2af4840749bac80ae78c678bfMark Andrews#include <config.h>
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
21f1794606dce19928cf455029e173321f166380Mark Andrews#include <isc/entropy.h>
973a19342597823f111fce6a8cd5adfd0e2e7c0dMark Andrews#include <isc/md5.h>
0c310d16b05ee94743d33f6920907edee6084fc8Michael Graff#include <isc/sha1.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/mem.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/string.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/util.h>
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrews
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <dst/result.h>
21825a8d005ccc2dfaf12889bf9eef3413555277Brian Wellington
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉#include "dst_internal.h"
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include "dst_openssl.h"
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include "dst_parse.h"
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <openssl/err.h>
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews#include <openssl/objects.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <openssl/rsa.h>
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews#if OPENSSL_VERSION_NUMBER > 0x00908000L
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson#include <openssl/bn.h>
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#endif
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#include <openssl/engine.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews/*
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews * We don't use configure for windows so enforce the OpenSSL version
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews * here. Unlike with configure we don't support overriding this test.
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews */
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews#ifdef WIN32
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews#if !((OPENSSL_VERSION_NUMBER >= 0x009070cfL && \
c46f10e4a1702191b003cf8f8fc5059c15d29c48Mark Andrews OPENSSL_VERSION_NUMBER < 0x00908000L) || \
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews OPENSSL_VERSION_NUMBER >= 0x0090804fL)
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews#error Please upgrade OpenSSL to 0.9.8d/0.9.7l or greater.
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews#endif
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews#endif
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrews /*
eb6bd543c7d072efdca509eb17f8f301c1467b53Mark Andrews * XXXMPA Temporarily disable RSA_BLINDING as it requires
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews * good quality random data that cannot currently be guaranteed.
c46f10e4a1702191b003cf8f8fc5059c15d29c48Mark Andrews * XXXMPA Find which versions of openssl use pseudo random data
c46f10e4a1702191b003cf8f8fc5059c15d29c48Mark Andrews * and set RSA_FLAG_BLINDING for those.
0b056755b2f423ba5f6adac8f7851d78f7d11437David Lawrence */
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#if 0
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews#if OPENSSL_VERSION_NUMBER < 0x0090601fL
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define SET_FLAGS(rsa) \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence do { \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence (rsa)->flags |= RSA_FLAG_BLINDING; \
0b056755b2f423ba5f6adac8f7851d78f7d11437David Lawrence } while (0)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#else
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#define SET_FLAGS(rsa) \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence do { \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence (rsa)->flags |= RSA_FLAG_BLINDING; \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence } while (0)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#endif
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#endif
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
0b056755b2f423ba5f6adac8f7851d78f7d11437David Lawrence#if OPENSSL_VERSION_NUMBER < 0x0090601fL
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define SET_FLAGS(rsa) \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence do { \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence (rsa)->flags &= ~RSA_FLAG_BLINDING; \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence } while (0)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#elif defined(RSA_FLAG_NO_BLINDING)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define SET_FLAGS(rsa) \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence do { \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence (rsa)->flags &= ~RSA_FLAG_BLINDING; \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence (rsa)->flags |= RSA_FLAG_NO_BLINDING; \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence } while (0)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#else
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#define SET_FLAGS(rsa) \
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews do { \
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews (rsa)->flags &= ~RSA_FLAG_BLINDING; \
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews } while (0)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#endif
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence#define DST_RET(a) {ret = a; goto err;}
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafssonstatic isc_result_t opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafssonstatic isc_result_t
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeinopensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#if USE_EVP
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein EVP_MD_CTX *evp_md_ctx;
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater const EVP_MD *type;
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson#endif
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence UNUSED(key);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence dctx->key->key_alg == DST_ALG_RSASHA1 ||
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence#if USE_EVP
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence evp_md_ctx = EVP_MD_CTX_create();
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (evp_md_ctx == NULL)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence return (ISC_R_NOMEMORY);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (dctx->key->key_alg == DST_ALG_RSAMD5)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence type = EVP_md5(); /* MD5 + RSA */
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence else
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence type = EVP_sha1(); /* SHA1 + RSA */
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence EVP_MD_CTX_destroy(evp_md_ctx);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence return (ISC_R_FAILURE);
330705066b03f6ce0bc08a4bbfc5d2418038c68dBrian Wellington }
330705066b03f6ce0bc08a4bbfc5d2418038c68dBrian Wellington dctx->ctxdata.evp_md_ctx = evp_md_ctx;
330705066b03f6ce0bc08a4bbfc5d2418038c68dBrian Wellington#else
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (dctx->key->key_alg == DST_ALG_RSAMD5) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence isc_md5_t *md5ctx;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t));
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (md5ctx == NULL)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence return (ISC_R_NOMEMORY);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence isc_md5_init(md5ctx);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence dctx->ctxdata.md5ctx = md5ctx;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence } else {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence isc_sha1_t *sha1ctx;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (sha1ctx == NULL)
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence return (ISC_R_NOMEMORY);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence isc_sha1_init(sha1ctx);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence dctx->ctxdata.sha1ctx = sha1ctx;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence }
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence#endif
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence return (ISC_R_SUCCESS);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence}
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencestatic void
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrenceopensslrsa_destroyctx(dst_context_t *dctx) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence#if USE_EVP
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence#endif
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dctx->key->key_alg == DST_ALG_RSASHA1 ||
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence#if USE_EVP
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (evp_md_ctx != NULL) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence EVP_MD_CTX_destroy(evp_md_ctx);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence dctx->ctxdata.evp_md_ctx = NULL;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence }
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence#else
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (dctx->key->key_alg == DST_ALG_RSAMD5) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (md5ctx != NULL) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence isc_md5_invalidate(md5ctx);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence isc_mem_put(dctx->mctx, md5ctx, sizeof(isc_md5_t));
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence dctx->ctxdata.md5ctx = NULL;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence }
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson } else {
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (sha1ctx != NULL) {
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence isc_sha1_invalidate(sha1ctx);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence dctx->ctxdata.sha1ctx = NULL;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence }
fd4810861c0c0ccb9aebde94e9d289442b2630dbMark Andrews }
fd4810861c0c0ccb9aebde94e9d289442b2630dbMark Andrews#endif
fd4810861c0c0ccb9aebde94e9d289442b2630dbMark Andrews}
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencestatic isc_result_t
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrenceopensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson#if USE_EVP
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#endif
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews dctx->key->key_alg == DST_ALG_RSASHA1 ||
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews
c5223c9cb7c22620d5ee6611228673e95b48a270Mark Andrews#if USE_EVP
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_FAILURE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews#else
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews if (dctx->key->key_alg == DST_ALG_RSAMD5) {
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews isc_md5_update(md5ctx, data->base, data->length);
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews } else {
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews isc_sha1_update(sha1ctx, data->base, data->length);
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews }
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews#endif
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews return (ISC_R_SUCCESS);
23cb957a81a51a9656917ea98d0ae56b7abdcaccMark Andrews}
b6a0341bcb113e93bd0bc41a9f9a1fc117444da6Mark Andrews
b6a0341bcb113e93bd0bc41a9f9a1fc117444da6Mark Andrewsstatic isc_result_t
aa05bbdef7f7827dde158dcc913f4dade84c8511Brian Wellingtonopensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
23cb957a81a51a9656917ea98d0ae56b7abdcaccMark Andrews dst_key_t *key = dctx->key;
23cb957a81a51a9656917ea98d0ae56b7abdcaccMark Andrews isc_region_t r;
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews unsigned int siglen = 0;
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews#if USE_EVP
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews EVP_PKEY *pkey = key->keydata.pkey;
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews#else
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews RSA *rsa = key->keydata.rsa;
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews unsigned char digest[ISC_SHA1_DIGESTLENGTH];
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington int status;
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews int type;
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews unsigned int digestlen;
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews char *message;
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews unsigned long err;
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews const char* file;
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews int line;
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews#endif
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews dctx->key->key_alg == DST_ALG_RSASHA1 ||
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews isc_buffer_availableregion(sig, &r);
f6407f9a0b890bebbfd5f738d9c4aef3d3315fe9Michael Graff
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews#if USE_EVP
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews if (r.length < (unsigned int) EVP_PKEY_size(pkey))
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews return (ISC_R_NOSPACE);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_FAILURE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#else
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews if (r.length < (unsigned int) RSA_size(rsa))
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews return (ISC_R_NOSPACE);
bed8e84810a80dad3d37870be927d1dfd015f480Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (dctx->key->key_alg == DST_ALG_RSAMD5) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_md5_final(md5ctx, digest);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews type = NID_md5;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews digestlen = ISC_MD5_DIGESTLENGTH;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews } else {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_sha1_final(sha1ctx, digest);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews type = NID_sha1;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews digestlen = ISC_SHA1_DIGESTLENGTH;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
d981ca645597116d227a48bf37cc5edc061c854dBob Halley
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa);
e6bd97dded968f82e26b270842b789bff7bca422Mark Andrews if (status == 0) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews err = ERR_peek_error_line(&file, &line);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (err != 0U) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews message = ERR_error_string(err, NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews }
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews#endif
cabaeca9ae5b98c80586b91e89cf552e17a75a9bBrian Wellington
cabaeca9ae5b98c80586b91e89cf552e17a75a9bBrian Wellington isc_buffer_add(sig, siglen);
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews return (ISC_R_SUCCESS);
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews}
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrewsstatic isc_result_t
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrewsopensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews dst_key_t *key = dctx->key;
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews int status = 0;
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews#if USE_EVP
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews EVP_PKEY *pkey = key->keydata.pkey;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews#else
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews unsigned char digest[ISC_SHA1_DIGESTLENGTH];
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews int type;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews unsigned int digestlen;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews RSA *rsa = key->keydata.rsa;
cabaeca9ae5b98c80586b91e89cf552e17a75a9bBrian Wellington#endif
cabaeca9ae5b98c80586b91e89cf552e17a75a9bBrian Wellington
cabaeca9ae5b98c80586b91e89cf552e17a75a9bBrian Wellington REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
f1cae4bcb7ee3060d893f5ab3ba55c1820bf3e4aBrian Wellington dctx->key->key_alg == DST_ALG_RSASHA1 ||
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews#if USE_EVP
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews#else
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews if (dctx->key->key_alg == DST_ALG_RSAMD5) {
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews isc_md5_final(md5ctx, digest);
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews type = NID_md5;
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews digestlen = ISC_MD5_DIGESTLENGTH;
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews } else {
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_sha1_final(sha1ctx, digest);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews type = NID_sha1;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews digestlen = ISC_SHA1_DIGESTLENGTH;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence if (sig->length < (unsigned int) RSA_size(rsa))
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews return (DST_R_VERIFYFAILURE);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews status = RSA_verify(type, digest, digestlen, sig->base,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RSA_size(rsa), rsa);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#endif
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (status != 1)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews return (ISC_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
d981ca645597116d227a48bf37cc5edc061c854dBob Halley
d981ca645597116d227a48bf37cc5edc061c854dBob Halleystatic isc_boolean_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsopensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews int status;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RSA *rsa1 = NULL, *rsa2 = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#if USE_EVP
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews EVP_PKEY *pkey1, *pkey2;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#endif
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews#if USE_EVP
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews pkey1 = key1->keydata.pkey;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews pkey2 = key2->keydata.pkey;
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews /*
44a966dff66061ac3f266c6b451a70733eb78e82Mark Andrews * The pkey reference will keep these around after
90e303b114e56db5809fdd19805243457fa43cd9Olafur Gudmundsson * the RSA_free() call.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (pkey1 != NULL) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rsa1 = EVP_PKEY_get1_RSA(pkey1);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RSA_free(rsa1);
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews }
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews if (pkey2 != NULL) {
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews rsa2 = EVP_PKEY_get1_RSA(pkey2);
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews RSA_free(rsa2);
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews }
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews#else
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews rsa1 = key1->keydata.rsa;
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews rsa2 = key2->keydata.rsa;
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews#endif
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews if (rsa1 == NULL && rsa2 == NULL)
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews return (ISC_TRUE);
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews else if (rsa1 == NULL || rsa2 == NULL)
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews return (ISC_FALSE);
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews status = BN_cmp(rsa1->n, rsa2->n) ||
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews BN_cmp(rsa1->e, rsa2->e);
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews if (status != 0)
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews return (ISC_FALSE);
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews#if USE_EVP
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews if ((rsa1->flags & RSA_FLAG_EXT_PKEY) != 0 ||
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews (rsa2->flags & RSA_FLAG_EXT_PKEY) != 0) {
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews if ((rsa1->flags & RSA_FLAG_EXT_PKEY) == 0 ||
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews (rsa2->flags & RSA_FLAG_EXT_PKEY) == 0)
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews return (ISC_FALSE);
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews /*
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews * Can't compare private parameters, BTW does it make sense?
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews */
3d17a3ba61a303d5c4d9867068d0fbe9f24d2988Mark Andrews return (ISC_TRUE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#endif
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rsa1->d != NULL || rsa2->d != NULL) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rsa1->d == NULL || rsa2->d == NULL)
d981ca645597116d227a48bf37cc5edc061c854dBob Halley return (ISC_FALSE);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews status = BN_cmp(rsa1->d, rsa2->d) ||
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews BN_cmp(rsa1->p, rsa2->p) ||
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence BN_cmp(rsa1->q, rsa2->q);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews
f1cae4bcb7ee3060d893f5ab3ba55c1820bf3e4aBrian Wellington if (status != 0)
19d365e4448f1782611280b020987988b7ac3210Mark Andrews return (ISC_FALSE);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews }
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews return (ISC_TRUE);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic isc_result_t
d981ca645597116d227a48bf37cc5edc061c854dBob Halleyopensslrsa_generate(dst_key_t *key, int exp) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#if OPENSSL_VERSION_NUMBER > 0x00908000L
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews BN_GENCB cb;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RSA *rsa = RSA_new();
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews BIGNUM *e = BN_new();
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#if USE_EVP
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence EVP_PKEY *pkey = EVP_PKEY_new();
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#endif
19d365e4448f1782611280b020987988b7ac3210Mark Andrews
19d365e4448f1782611280b020987988b7ac3210Mark Andrews if (rsa == NULL || e == NULL)
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews goto err;
19d365e4448f1782611280b020987988b7ac3210Mark Andrews#if USE_EVP
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (pkey == NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto err;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (!EVP_PKEY_set1_RSA(pkey, rsa))
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews goto err;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff#endif
d981ca645597116d227a48bf37cc5edc061c854dBob Halley
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews if (exp == 0) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews /* RSA_F4 0x10001 */
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews BN_set_bit(e, 0);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews BN_set_bit(e, 16);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff } else {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* F5 0x100000001 */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews BN_set_bit(e, 0);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews BN_set_bit(e, 32);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews }
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews BN_GENCB_set_old(&cb, NULL, NULL);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (RSA_generate_key_ex(rsa, key->key_size, e, &cb)) {
f1cae4bcb7ee3060d893f5ab3ba55c1820bf3e4aBrian Wellington BN_free(e);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews SET_FLAGS(rsa);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews#if USE_EVP
19d365e4448f1782611280b020987988b7ac3210Mark Andrews key->keydata.pkey = pkey;
6bebabb376b93e7d12f53a253b197a3fc0e0b001Andreas Gustafsson
6bebabb376b93e7d12f53a253b197a3fc0e0b001Andreas Gustafsson RSA_free(rsa);
6bebabb376b93e7d12f53a253b197a3fc0e0b001Andreas Gustafsson#else
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews key->keydata.rsa = rsa;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#endif
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_SUCCESS);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews }
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrewserr:
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#if USE_EVP
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (pkey != NULL)
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews EVP_PKEY_free(pkey);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews#endif
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews if (e != NULL)
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews BN_free(e);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews if (rsa != NULL)
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews RSA_free(rsa);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews#else
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews RSA *rsa;
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews unsigned long e;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#if USE_EVP
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence EVP_PKEY *pkey = EVP_PKEY_new();
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (pkey == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews#endif
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
ad7209ea70d346527ffdcda335153831341d9dcfAndreas Gustafsson if (exp == 0)
7d8cdd869ed2162a5befda7cc1600136110f54d6Mark Andrews e = RSA_F4;
7d8cdd869ed2162a5befda7cc1600136110f54d6Mark Andrews else
7d8cdd869ed2162a5befda7cc1600136110f54d6Mark Andrews e = 0x40000003;
d981ca645597116d227a48bf37cc5edc061c854dBob Halley rsa = RSA_generate_key(key->key_size, e, NULL, NULL);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rsa == NULL) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#if USE_EVP
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff EVP_PKEY_free(pkey);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#endif
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews SET_FLAGS(rsa);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#if USE_EVP
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (!EVP_PKEY_set1_RSA(pkey, rsa)) {
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff EVP_PKEY_free(pkey);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RSA_free(rsa);
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff key->keydata.pkey = pkey;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews RSA_free(rsa);
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley#else
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews key->keydata.rsa = rsa;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#endif
19d365e4448f1782611280b020987988b7ac3210Mark Andrews
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews return (ISC_R_SUCCESS);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence#endif
693ddf84daa745a0ea8ca311a8154dfa03eabc43Andreas Gustafsson}
693ddf84daa745a0ea8ca311a8154dfa03eabc43Andreas Gustafsson
693ddf84daa745a0ea8ca311a8154dfa03eabc43Andreas Gustafssonstatic isc_boolean_t
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrewsopensslrsa_isprivate(const dst_key_t *key) {
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews#if USE_EVP
693ddf84daa745a0ea8ca311a8154dfa03eabc43Andreas Gustafsson RSA *rsa = EVP_PKEY_get1_RSA(key->keydata.pkey);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews INSIST(rsa != NULL);
693ddf84daa745a0ea8ca311a8154dfa03eabc43Andreas Gustafsson RSA_free(rsa);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews /* key->keydata.pkey still has a reference so rsa is still valid. */
19d365e4448f1782611280b020987988b7ac3210Mark Andrews#else
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RSA *rsa = key->keydata.rsa;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence#endif
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (rsa != NULL && (rsa->flags & RSA_FLAG_EXT_PKEY) != 0)
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence return (ISC_TRUE);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence return (ISC_TF(rsa != NULL && rsa->d != NULL));
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff}
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halley
f0a5bb8f86631ce638cb2b6c65bbb9bcf9b0cdc0Bob Halleystatic void
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffopensslrsa_destroy(dst_key_t *key) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#if USE_EVP
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff EVP_PKEY *pkey = key->keydata.pkey;
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews EVP_PKEY_free(pkey);
7c0378745269fe49a05904935afc42b85528f53aDavid Lawrence key->keydata.pkey = NULL;
7c0378745269fe49a05904935afc42b85528f53aDavid Lawrence#else
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews RSA *rsa = key->keydata.rsa;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RSA_free(rsa);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews key->keydata.rsa = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#endif
7e4cda9965e2edf2ec43c57967eec8eff7061ab0Andreas Gustafsson}
7e4cda9965e2edf2ec43c57967eec8eff7061ab0Andreas Gustafsson
7e4cda9965e2edf2ec43c57967eec8eff7061ab0Andreas Gustafsson
7e4cda9965e2edf2ec43c57967eec8eff7061ab0Andreas Gustafssonstatic isc_result_t
7e4cda9965e2edf2ec43c57967eec8eff7061ab0Andreas Gustafssonopensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) {
3a16668468060842e847ea6556e80e1405d35cd6Brian Wellington isc_region_t r;
7e4cda9965e2edf2ec43c57967eec8eff7061ab0Andreas Gustafsson unsigned int e_bytes;
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington unsigned int mod_bytes;
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews isc_result_t ret;
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington RSA *rsa;
7d8cdd869ed2162a5befda7cc1600136110f54d6Mark Andrews#if USE_EVP
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington EVP_PKEY *pkey;
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington#endif
942d1a339b1fe617f7d17d66cb5fccce798d15aeBrian Wellington
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington#if USE_EVP
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington REQUIRE(key->keydata.pkey != NULL);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#else
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington REQUIRE(key->keydata.rsa != NULL);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews#endif
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews#if USE_EVP
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews pkey = key->keydata.pkey;
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington rsa = EVP_PKEY_get1_RSA(pkey);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington if (rsa == NULL)
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington#else
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington rsa = key->keydata.rsa;
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington#endif
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington isc_buffer_availableregion(data, &r);
de5247ae1683ce145662180ee50272d2214a0232Andreas Gustafsson
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington e_bytes = BN_num_bytes(rsa->e);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington mod_bytes = BN_num_bytes(rsa->n);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington if (e_bytes < 256) { /*%< key exponent is <= 2040 bits */
5eb91bd90e3ad3426e5e3213031556a737cf3809Mark Andrews if (r.length < 1)
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington DST_RET(ISC_R_NOSPACE);
f16495732753175e4a9fc144323a12fdcc29b561Brian Wellington isc_buffer_putuint8(data, (isc_uint8_t) e_bytes);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington } else {
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington if (r.length < 3)
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater DST_RET(ISC_R_NOSPACE);
e086935752b6e2f51ef2985fee21ccfff617b115David Lawrence isc_buffer_putuint8(data, 0);
e086935752b6e2f51ef2985fee21ccfff617b115David Lawrence isc_buffer_putuint16(data, (isc_uint16_t) e_bytes);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington }
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington if (r.length < e_bytes + mod_bytes)
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington return (ISC_R_NOSPACE);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington isc_buffer_availableregion(data, &r);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington BN_bn2bin(rsa->e, r.base);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington r.base += e_bytes;
7e4cda9965e2edf2ec43c57967eec8eff7061ab0Andreas Gustafsson BN_bn2bin(rsa->n, r.base);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington isc_buffer_add(data, e_bytes + mod_bytes);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington ret = ISC_R_SUCCESS;
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington err:
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington#if USE_EVP
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington if (rsa != NULL)
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington RSA_free(rsa);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington#endif
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington return (ret);
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington}
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellingtonstatic isc_result_t
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellingtonopensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington RSA *rsa;
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington isc_region_t r;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff unsigned int e_bytes;
d981ca645597116d227a48bf37cc5edc061c854dBob Halley#if USE_EVP
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews EVP_PKEY *pkey;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#endif
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews isc_buffer_remainingregion(data, &r);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (r.length == 0)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews rsa = RSA_new();
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (rsa == NULL)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (dst__openssl_toresult(ISC_R_NOMEMORY));
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews SET_FLAGS(rsa);
20b20b23948b90cb2f7d7f402da99d09f837efd0David Lawrence
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence if (r.length < 1) {
8dd5237a27e2e824d18f835dc711573aeb23a173Mark Andrews RSA_free(rsa);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DST_R_INVALIDPUBLICKEY);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence }
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews e_bytes = *r.base++;
f1cae4bcb7ee3060d893f5ab3ba55c1820bf3e4aBrian Wellington r.length--;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (e_bytes == 0) {
23cb957a81a51a9656917ea98d0ae56b7abdcaccMark Andrews if (r.length < 2) {
23cb957a81a51a9656917ea98d0ae56b7abdcaccMark Andrews RSA_free(rsa);
23cb957a81a51a9656917ea98d0ae56b7abdcaccMark Andrews return (DST_R_INVALIDPUBLICKEY);
23cb957a81a51a9656917ea98d0ae56b7abdcaccMark Andrews }
19d365e4448f1782611280b020987988b7ac3210Mark Andrews e_bytes = ((*r.base++) << 8);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews e_bytes += *r.base++;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews r.length -= 2;
23cb957a81a51a9656917ea98d0ae56b7abdcaccMark Andrews }
228c679d7a269423019f7c528db92e855f08240bMark Andrews
b6a0341bcb113e93bd0bc41a9f9a1fc117444da6Mark Andrews if (r.length < e_bytes) {
228c679d7a269423019f7c528db92e855f08240bMark Andrews RSA_free(rsa);
228c679d7a269423019f7c528db92e855f08240bMark Andrews return (DST_R_INVALIDPUBLICKEY);
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington }
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington rsa->e = BN_bin2bn(r.base, e_bytes, NULL);
228c679d7a269423019f7c528db92e855f08240bMark Andrews r.base += e_bytes;
228c679d7a269423019f7c528db92e855f08240bMark Andrews r.length -= e_bytes;
228c679d7a269423019f7c528db92e855f08240bMark Andrews
228c679d7a269423019f7c528db92e855f08240bMark Andrews rsa->n = BN_bin2bn(r.base, r.length, NULL);
228c679d7a269423019f7c528db92e855f08240bMark Andrews
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington key->key_size = BN_num_bits(rsa->n);
228c679d7a269423019f7c528db92e855f08240bMark Andrews
228c679d7a269423019f7c528db92e855f08240bMark Andrews isc_buffer_forward(data, r.length);
c46f10e4a1702191b003cf8f8fc5059c15d29c48Mark Andrews
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington#if USE_EVP
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington pkey = EVP_PKEY_new();
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington if (pkey == NULL) {
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington RSA_free(rsa);
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington return (ISC_R_NOMEMORY);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews }
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (!EVP_PKEY_set1_RSA(pkey, rsa)) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews EVP_PKEY_free(pkey);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews RSA_free(rsa);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews }
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews key->keydata.pkey = pkey;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews RSA_free(rsa);
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews#else
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews key->keydata.rsa = rsa;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#endif
8dd5237a27e2e824d18f835dc711573aeb23a173Mark Andrews
8dd5237a27e2e824d18f835dc711573aeb23a173Mark Andrews return (ISC_R_SUCCESS);
8dd5237a27e2e824d18f835dc711573aeb23a173Mark Andrews}
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrewsstatic isc_result_t
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrewsopensslrsa_tofile(const dst_key_t *key, const char *directory) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews int i;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews RSA *rsa;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews dst_private_t priv;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff unsigned char *bufs[8];
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_result_t result;
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews#if USE_EVP
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews if (key->keydata.pkey == NULL)
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews return (DST_R_NULLKEY);
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews rsa = EVP_PKEY_get1_RSA(key->keydata.pkey);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (rsa == NULL)
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews#else
82d05588933a3c765aa8518fe455d6477d640b99Mark Andrews if (key->keydata.rsa == NULL)
fd4810861c0c0ccb9aebde94e9d289442b2630dbMark Andrews return (DST_R_NULLKEY);
fd4810861c0c0ccb9aebde94e9d289442b2630dbMark Andrews rsa = key->keydata.rsa;
fd4810861c0c0ccb9aebde94e9d289442b2630dbMark Andrews#endif
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
fd4810861c0c0ccb9aebde94e9d289442b2630dbMark Andrews for (i = 0; i < 8; i++) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (bufs[i] == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOMEMORY;
7d8cdd869ed2162a5befda7cc1600136110f54d6Mark Andrews goto fail;
7d8cdd869ed2162a5befda7cc1600136110f54d6Mark Andrews }
7d8cdd869ed2162a5befda7cc1600136110f54d6Mark Andrews }
d981ca645597116d227a48bf37cc5edc061c854dBob Halley
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews i = 0;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews priv.elements[i].tag = TAG_RSA_MODULUS;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews priv.elements[i].length = BN_num_bytes(rsa->n);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews BN_bn2bin(rsa->n, bufs[i]);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews priv.elements[i].data = bufs[i];
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews i++;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley priv.elements[i].length = BN_num_bytes(rsa->e);
19d365e4448f1782611280b020987988b7ac3210Mark Andrews BN_bn2bin(rsa->e, bufs[i]);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff priv.elements[i].data = bufs[i];
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews i++;
471e0563c7965c556c759775882cd3448dae78eaMark Andrews
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews if (rsa->d != NULL) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
19d365e4448f1782611280b020987988b7ac3210Mark Andrews priv.elements[i].length = BN_num_bytes(rsa->d);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence BN_bn2bin(rsa->d, bufs[i]);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence priv.elements[i].data = bufs[i];
19d365e4448f1782611280b020987988b7ac3210Mark Andrews i++;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence }
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (rsa->p != NULL) {
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews priv.elements[i].tag = TAG_RSA_PRIME1;
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews priv.elements[i].length = BN_num_bytes(rsa->p);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff BN_bn2bin(rsa->p, bufs[i]);
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews priv.elements[i].data = bufs[i];
f8aae502686e2448c48f56697c212a50e2a1cbaeAndreas Gustafsson i++;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews if (rsa->q != NULL) {
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews priv.elements[i].tag = TAG_RSA_PRIME2;
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington priv.elements[i].length = BN_num_bytes(rsa->q);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews BN_bn2bin(rsa->q, bufs[i]);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews priv.elements[i].data = bufs[i];
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews i++;
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews }
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews if (rsa->dmp1 != NULL) {
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews priv.elements[i].tag = TAG_RSA_EXPONENT1;
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews priv.elements[i].length = BN_num_bytes(rsa->dmp1);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews BN_bn2bin(rsa->dmp1, bufs[i]);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews priv.elements[i].data = bufs[i];
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington i++;
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington }
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews if (rsa->dmq1 != NULL) {
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews priv.elements[i].tag = TAG_RSA_EXPONENT2;
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews priv.elements[i].length = BN_num_bytes(rsa->dmq1);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews BN_bn2bin(rsa->dmq1, bufs[i]);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews priv.elements[i].data = bufs[i];
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews i++;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rsa->iqmp != NULL) {
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff priv.elements[i].tag = TAG_RSA_COEFFICIENT;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence priv.elements[i].length = BN_num_bytes(rsa->iqmp);
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson BN_bn2bin(rsa->iqmp, bufs[i]);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews priv.elements[i].data = bufs[i];
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews i++;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews }
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (key->engine != NULL) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence priv.elements[i].tag = TAG_RSA_ENGINE;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence priv.elements[i].length = strlen(key->engine) + 1;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson priv.elements[i].data = (unsigned char *)key->engine;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson i++;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson }
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley if (key->label != NULL) {
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson priv.elements[i].tag = TAG_RSA_LABEL;
7ab0e69f61e61e81d489c95c7ebd981e74e7ef16Andreas Gustafsson priv.elements[i].length = strlen(key->label) + 1;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff priv.elements[i].data = (unsigned char *)key->label;
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson i++;
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson }
a5746c4ec14e5dbcb6a2431aa86cc86c21387e6bMark Andrews
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews priv.nelements = i;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews result = dst__privstruct_writefile(key, &priv, directory);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews fail:
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews#if USE_EVP
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence RSA_free(rsa);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence#endif
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence for (i = 0; i < 8; i++) {
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson if (bufs[i] == NULL)
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson break;
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson isc_mem_put(key->mctx, bufs[i], BN_num_bytes(rsa->n));
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson }
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson return (result);
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson}
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafssonstatic isc_result_t
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafssonrsa_check(RSA *rsa, RSA *pub)
ae70d32b67cf30e06553c01479e71c87b21d984cBob Halley{
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson /* Public parameters should be the same but if they are not set
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson * copy them from the public key. */
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff if (pub != NULL) {
d981ca645597116d227a48bf37cc5edc061c854dBob Halley if (rsa->n != NULL) {
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews if (BN_cmp(rsa->n, pub->n) != 0)
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews return (DST_R_INVALIDPRIVATEKEY);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews } else {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff rsa->n = pub->n;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews pub->n = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (rsa->e != NULL) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (BN_cmp(rsa->e, pub->e) != 0)
19d365e4448f1782611280b020987988b7ac3210Mark Andrews return (DST_R_INVALIDPRIVATEKEY);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews } else {
f1cae4bcb7ee3060d893f5ab3ba55c1820bf3e4aBrian Wellington rsa->e = pub->e;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews pub->e = NULL;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews }
19d365e4448f1782611280b020987988b7ac3210Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rsa->n == NULL || rsa->e == NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (DST_R_INVALIDPRIVATEKEY);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrewsstatic isc_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsopensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff dst_private_t priv;
7d8cdd869ed2162a5befda7cc1600136110f54d6Mark Andrews isc_result_t ret;
7d8cdd869ed2162a5befda7cc1600136110f54d6Mark Andrews int i;
7d8cdd869ed2162a5befda7cc1600136110f54d6Mark Andrews RSA *rsa = NULL, *pubrsa = NULL;
d981ca645597116d227a48bf37cc5edc061c854dBob Halley ENGINE *e = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_mem_t *mctx = key->mctx;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff const char *engine = NULL, *label = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews EVP_PKEY *pkey = NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#if USE_EVP
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (pub != NULL && pub->keydata.pkey != NULL)
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey);
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews#else
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (pub != NULL && pub->keydata.rsa != NULL) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews pubrsa = pub->keydata.rsa;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews pub->keydata.rsa = NULL;
19d365e4448f1782611280b020987988b7ac3210Mark Andrews }
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews#endif
19d365e4448f1782611280b020987988b7ac3210Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* read private key file */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews if (ret != ISC_R_SUCCESS)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews return (ret);
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews for (i = 0; i < priv.nelements; i++) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews switch (priv.elements[i].tag) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews case TAG_RSA_ENGINE:
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews engine = (char *)priv.elements[i].data;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews break;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews case TAG_RSA_LABEL:
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews label = (char *)priv.elements[i].data;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews break;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews default:
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews break;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews }
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff }
d981ca645597116d227a48bf37cc5edc061c854dBob Halley /*
d981ca645597116d227a48bf37cc5edc061c854dBob Halley * Is this key is stored in a HSM?
d981ca645597116d227a48bf37cc5edc061c854dBob Halley * See if we can fetch it.
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff */
d981ca645597116d227a48bf37cc5edc061c854dBob Halley if (label != NULL) {
d981ca645597116d227a48bf37cc5edc061c854dBob Halley if (engine == NULL)
d981ca645597116d227a48bf37cc5edc061c854dBob Halley DST_RET(DST_R_NOENGINE);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley e = dst__openssl_getengine(engine);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley if (e == NULL)
d981ca645597116d227a48bf37cc5edc061c854dBob Halley DST_RET(DST_R_NOENGINE);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley pkey = ENGINE_load_private_key(e, label, NULL, NULL);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley if (pkey == NULL) {
d981ca645597116d227a48bf37cc5edc061c854dBob Halley /* ERR_print_errors_fp(stderr); */
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews DST_RET(ISC_R_NOTFOUND);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley }
d981ca645597116d227a48bf37cc5edc061c854dBob Halley key->engine = isc_mem_strdup(key->mctx, engine);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley if (key->engine == NULL)
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews DST_RET(ISC_R_NOMEMORY);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley key->label = isc_mem_strdup(key->mctx, label);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews if (key->label == NULL)
d981ca645597116d227a48bf37cc5edc061c854dBob Halley DST_RET(ISC_R_NOMEMORY);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley rsa = EVP_PKEY_get1_RSA(pkey);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley if (rsa == NULL)
d981ca645597116d227a48bf37cc5edc061c854dBob Halley DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley DST_RET(DST_R_INVALIDPRIVATEKEY);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (pubrsa != NULL)
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley RSA_free(pubrsa);
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews key->key_size = EVP_PKEY_bits(pkey);
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley#if USE_EVP
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley key->keydata.pkey = pkey;
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley RSA_free(rsa);
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley#else
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley key->keydata.rsa = rsa;
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley EVP_PKEY_free(pkey);
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley#endif
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dst__privstruct_free(&priv, mctx);
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley memset(&priv, 0, sizeof(priv));
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley return (ISC_R_SUCCESS);
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley }
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews rsa = RSA_new();
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews if (rsa == NULL)
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews DST_RET(ISC_R_NOMEMORY);
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley SET_FLAGS(rsa);
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley#if USE_EVP
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley pkey = EVP_PKEY_new();
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (pkey == NULL)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews DST_RET(ISC_R_NOMEMORY);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (!EVP_PKEY_set1_RSA(pkey, rsa))
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews DST_RET(ISC_R_FAILURE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews key->keydata.pkey = pkey;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#else
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews key->keydata.rsa = rsa;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#endif
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews for (i = 0; i < priv.nelements; i++) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews BIGNUM *bn;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews switch (priv.elements[i].tag) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews case TAG_RSA_ENGINE:
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews continue;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews case TAG_RSA_LABEL:
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews continue;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews case TAG_RSA_PIN:
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews continue;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews default:
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff bn = BN_bin2bn(priv.elements[i].data,
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff priv.elements[i].length, NULL);
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff if (bn == NULL)
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrews DST_RET(ISC_R_NOMEMORY);
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrews }
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrews
471e0563c7965c556c759775882cd3448dae78eaMark Andrews switch (priv.elements[i].tag) {
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff case TAG_RSA_MODULUS:
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff rsa->n = bn;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff break;
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence case TAG_RSA_PUBLICEXPONENT:
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff rsa->e = bn;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews break;
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff case TAG_RSA_PRIVATEEXPONENT:
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff rsa->d = bn;
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff break;
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff case TAG_RSA_PRIME1:
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff rsa->p = bn;
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff break;
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff case TAG_RSA_PRIME2:
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence rsa->q = bn;
47b26abe77184f9bedc68e36bdad03332cf67570David Lawrence break;
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff case TAG_RSA_EXPONENT1:
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff rsa->dmp1 = bn;
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff break;
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff case TAG_RSA_EXPONENT2:
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews rsa->dmq1 = bn;
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff break;
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff case TAG_RSA_COEFFICIENT:
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graff rsa->iqmp = bn;
8695d7b357789bedff63e5b19c5ab25cd58fcd4bMark Andrews break;
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews }
8695d7b357789bedff63e5b19c5ab25cd58fcd4bMark Andrews }
8695d7b357789bedff63e5b19c5ab25cd58fcd4bMark Andrews dst__privstruct_free(&priv, mctx);
8695d7b357789bedff63e5b19c5ab25cd58fcd4bMark Andrews memset(&priv, 0, sizeof(priv));
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington
9be230cfca126bea6b666f506a230ffcdfba60dbMark Andrews if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
8695d7b357789bedff63e5b19c5ab25cd58fcd4bMark Andrews DST_RET(DST_R_INVALIDPRIVATEKEY);
beed6a0e226fbd0c18c19a3e341a2003cba020a5Mark Andrews key->key_size = BN_num_bits(rsa->n);
beed6a0e226fbd0c18c19a3e341a2003cba020a5Mark Andrews if (pubrsa != NULL)
beed6a0e226fbd0c18c19a3e341a2003cba020a5Mark Andrews RSA_free(pubrsa);
9be230cfca126bea6b666f506a230ffcdfba60dbMark Andrews#if USE_EVP
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington RSA_free(rsa);
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington#endif
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington return (ISC_R_SUCCESS);
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews err:
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews#if USE_EVP
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews if (pkey != NULL)
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff EVP_PKEY_free(pkey);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence#endif
471e0563c7965c556c759775882cd3448dae78eaMark Andrews if (rsa != NULL)
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff RSA_free(rsa);
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrews if (pubrsa != NULL)
cc083bb7031c04d57cbad41b2f5a796a4fd1865cMark Andrews RSA_free(pubrsa);
471e0563c7965c556c759775882cd3448dae78eaMark Andrews opensslrsa_destroy(key);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews dst__privstruct_free(&priv, mctx);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews memset(&priv, 0, sizeof(priv));
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson return (ret);
8c962eba3d6faebc008806ebb6bb9d08089118e9Andreas Gustafsson}
8c962eba3d6faebc008806ebb6bb9d08089118e9Andreas Gustafsson
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafssonstatic isc_result_t
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafssonopensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson const char *pin)
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson{
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson ENGINE *e = NULL;
8c962eba3d6faebc008806ebb6bb9d08089118e9Andreas Gustafsson isc_result_t ret;
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson EVP_PKEY *pkey = NULL;
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson RSA *rsa = NULL, *pubrsa = NULL;
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson char *colon;
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson UNUSED(pin);
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson e = dst__openssl_getengine(engine);
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson if (e == NULL)
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson DST_RET(DST_R_NOENGINE);
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson pkey = ENGINE_load_public_key(e, label, NULL, NULL);
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson if (pkey != NULL) {
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson pubrsa = EVP_PKEY_get1_RSA(pkey);
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson EVP_PKEY_free(pkey);
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson if (pubrsa == NULL)
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence }
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence pkey = ENGINE_load_private_key(e, label, NULL, NULL);
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence if (pkey == NULL)
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews DST_RET(ISC_R_NOTFOUND);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (engine != NULL) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews key->engine = isc_mem_strdup(key->mctx, engine);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (key->engine == NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews DST_RET(ISC_R_NOMEMORY);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews } else {
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff key->engine = isc_mem_strdup(key->mctx, label);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (key->engine == NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews DST_RET(ISC_R_NOMEMORY);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews colon = strchr(key->engine, ':');
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (colon != NULL)
fe47f41b13620bfafc4f8cf65d5df24f1e568764Bob Halley *colon = '\0';
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews key->label = isc_mem_strdup(key->mctx, label);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence if (key->label == NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews DST_RET(ISC_R_NOMEMORY);
fe47f41b13620bfafc4f8cf65d5df24f1e568764Bob Halley rsa = EVP_PKEY_get1_RSA(pkey);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rsa == NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews DST_RET(DST_R_INVALIDPRIVATEKEY);
0e8cf9a887c70f96ac448b06c069d90b830215ccMark Andrews if (pubrsa != NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RSA_free(pubrsa);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews key->key_size = EVP_PKEY_bits(pkey);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff#if USE_EVP
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews key->keydata.pkey = pkey;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RSA_free(rsa);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#else
ca2912424b1d7c348186a325dd2078a37bb8d818Andreas Gustafsson key->keydata.rsa = rsa;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews EVP_PKEY_free(pkey);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff#endif
7755f5932a3e59d0c6a2506cc94519de92b91ca6Mark Andrews return (ISC_R_SUCCESS);
7755f5932a3e59d0c6a2506cc94519de92b91ca6Mark Andrews
7755f5932a3e59d0c6a2506cc94519de92b91ca6Mark Andrews err:
7755f5932a3e59d0c6a2506cc94519de92b91ca6Mark Andrews if (rsa != NULL)
c2b217ea1135f070da3856d3276895b3026e932aMark Andrews RSA_free(rsa);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (pubrsa != NULL)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews RSA_free(pubrsa);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (pkey != NULL)
7755f5932a3e59d0c6a2506cc94519de92b91ca6Mark Andrews EVP_PKEY_free(pkey);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ret);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic dst_func_t opensslrsa_functions = {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews opensslrsa_createctx,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews opensslrsa_destroyctx,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews opensslrsa_adddata,
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff opensslrsa_sign,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews opensslrsa_verify,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews NULL, /*%< computesecret */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews opensslrsa_compare,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews NULL, /*%< paramcompare */
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff opensslrsa_generate,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews opensslrsa_isprivate,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews opensslrsa_destroy,
fe47f41b13620bfafc4f8cf65d5df24f1e568764Bob Halley opensslrsa_todns,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews opensslrsa_fromdns,
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff opensslrsa_tofile,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews opensslrsa_parse,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews NULL, /*%< cleanup */
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff opensslrsa_fromlabel,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews};
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrewsisc_result_t
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrewsdst__opensslrsa_init(dst_func_t **funcp) {
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews REQUIRE(funcp != NULL);
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews if (*funcp == NULL)
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews *funcp = &opensslrsa_functions;
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews return (ISC_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews#else /* OPENSSL */
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews
f0ff273b530afa730025e1c5ad311950f7ff4328Mark Andrews#include <isc/util.h>
f0ff273b530afa730025e1c5ad311950f7ff4328Mark Andrews
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark AndrewsEMPTY_TRANSLATION_UNIT
7d62ddffbb4d1cc97b8d80b7ee4944554a57523eMark Andrews
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff#endif /* OPENSSL */
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence/*! \file */
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence