openssl_link.c revision 364a82f7c25b62967678027043425201a5e5171a
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews#if defined(OPENSSL)
7d32c065c7bb56f281651ae3dd2888f32ce4f1d9Bob Halley
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence/*
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * Portions Copyright (c) 1995-1998 by Network Associates, Inc.
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews *
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * Permission to use, copy modify, and distribute this software for any
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * purpose with or without fee is hereby granted, provided that the above
15a44745412679c30a6d022733925af70a38b715David Lawrence * copyright notice and this permission notice appear in all copies.
15a44745412679c30a6d022733925af70a38b715David Lawrence *
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES
15a44745412679c30a6d022733925af70a38b715David Lawrence * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
15a44745412679c30a6d022733925af70a38b715David Lawrence * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews */
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson/*
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson * Principal Author: Brian Wellington
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson * $Id: openssl_link.c,v 1.17 2000/04/28 01:10:48 halley Exp $
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews */
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews#include <config.h>
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff#include <stdio.h>
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff#include <unistd.h>
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff#include <stdlib.h>
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#include <string.h>
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews#include <memory.h>
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0bd044c2afee944d93879a7de82cd2ccc0635798David Lawrence#include <isc/assertions.h>
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews#include <isc/buffer.h>
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews#include <isc/int.h>
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff#include <isc/region.h>
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews#include <isc/util.h>
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson#include "dst_internal.h"
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews#include "dst_parse.h"
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews#include <openssl/crypto.h>
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson#include <openssl/bn.h>
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews#include <openssl/dsa.h>
34b394b43e2207e8f8f3703f0402422121455638David Lawrence#include <openssl/sha.h>
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrencestatic struct dst_func openssl_functions;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
542deb20c44666a870855bf755a100d254db074dAndreas Gustafssonstatic isc_result_t dst_openssl_sign(const unsigned int mode,
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff dst_key_t *key,
0bd044c2afee944d93879a7de82cd2ccc0635798David Lawrence void **context, isc_region_t *data,
0bd044c2afee944d93879a7de82cd2ccc0635798David Lawrence isc_buffer_t *sig, isc_mem_t *mctx);
34b394b43e2207e8f8f3703f0402422121455638David Lawrencestatic isc_result_t dst_openssl_verify(const unsigned int mode,
5d15501996f597d9bbb734d88d4549828e28000bMark Andrews dst_key_t *key,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews void **context, isc_region_t *data,
0bd044c2afee944d93879a7de82cd2ccc0635798David Lawrence isc_region_t *sig, isc_mem_t *mctx);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic isc_boolean_t dst_openssl_compare(const dst_key_t *key1,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews const dst_key_t *key2);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic isc_result_t dst_openssl_generate(dst_key_t *key, int unused,
34b394b43e2207e8f8f3703f0402422121455638David Lawrence isc_mem_t *mctx);
34b394b43e2207e8f8f3703f0402422121455638David Lawrencestatic isc_boolean_t dst_openssl_isprivate(const dst_key_t *key);
34b394b43e2207e8f8f3703f0402422121455638David Lawrencestatic void dst_openssl_destroy(void *key, isc_mem_t *mctx);
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafssonstatic isc_result_t dst_openssl_to_dns(const dst_key_t *in_key,
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson isc_buffer_t *data);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic isc_result_t dst_openssl_from_dns(dst_key_t *key, isc_buffer_t *data,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_mem_t *mctx);
34b394b43e2207e8f8f3703f0402422121455638David Lawrencestatic isc_result_t dst_openssl_to_file(const dst_key_t *key);
34b394b43e2207e8f8f3703f0402422121455638David Lawrencestatic isc_result_t dst_openssl_from_file(dst_key_t *key,
34b394b43e2207e8f8f3703f0402422121455638David Lawrence const isc_uint16_t id,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_mem_t *mctx);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
34b394b43e2207e8f8f3703f0402422121455638David Lawrencestatic int BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf,
ea8651059209b96fa005e06a0b9b33ae5a8eacd4David Lawrence int size);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
34b394b43e2207e8f8f3703f0402422121455638David Lawrence/*
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * dst_s_openssldsa_init()
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * Sets up function pointers for OpenSSL related functions
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews */
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsvoid
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsdst_s_openssldsa_init() {
34b394b43e2207e8f8f3703f0402422121455638David Lawrence REQUIRE(dst_t_func[DST_ALG_DSA] == NULL);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence dst_t_func[DST_ALG_DSA] = &openssl_functions;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence memset(&openssl_functions, 0, sizeof(struct dst_func));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews openssl_functions.sign = dst_openssl_sign;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson openssl_functions.verify = dst_openssl_verify;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson openssl_functions.computesecret = NULL;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews openssl_functions.compare = dst_openssl_compare;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence openssl_functions.paramcompare = NULL; /* is this useful for DSA? */
34b394b43e2207e8f8f3703f0402422121455638David Lawrence openssl_functions.generate = dst_openssl_generate;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence openssl_functions.isprivate = dst_openssl_isprivate;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews openssl_functions.destroy = dst_openssl_destroy;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson openssl_functions.to_dns = dst_openssl_to_dns;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson openssl_functions.from_dns = dst_openssl_from_dns;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews openssl_functions.to_file = dst_openssl_to_file;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence openssl_functions.from_file = dst_openssl_from_file;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence CRYPTO_set_mem_functions(dst_mem_alloc, dst_mem_realloc, dst_mem_free);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence}
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews/*
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * dst_openssl_sign
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * Call OpenSSL signing functions to sign a block of data.
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * There are three steps to signing, INIT (initialize structures),
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * UPDATE (hash (more) data), FINAL (generate a signature). This
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * routine performs one or more of these steps.
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * Parameters
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL}
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * key key to use for signing
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * context the context to use for this computation
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * data data to be signed
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * signature buffer to store signature
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * mctx memory context for temporary allocations
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * Returns
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington * ISC_R_SUCCESS Success
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * !ISC_R_SUCCESS Failure
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews */
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedst_openssl_sign(const unsigned int mode, dst_key_t *key, void **context,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_region_t *data, isc_buffer_t *sig, isc_mem_t *mctx)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews{
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_region_t r;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews SHA_CTX *ctx = NULL;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (mode & DST_SIGMODE_INIT) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews ctx = (SHA_CTX *) isc_mem_get(mctx, sizeof(SHA_CTX));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (ctx == NULL)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (ISC_R_NOMEMORY);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews }
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews else if (context != NULL)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews ctx = (SHA_CTX *) *context;
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews REQUIRE (ctx != NULL);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (mode & DST_SIGMODE_INIT)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews SHA1_Init(ctx);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence if ((mode & DST_SIGMODE_UPDATE))
34b394b43e2207e8f8f3703f0402422121455638David Lawrence SHA1_Update(ctx, data->base, data->length);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (mode & DST_SIGMODE_FINAL) {
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson DSA *dsa;
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson DSA_SIG *dsasig;
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson unsigned char digest[SHA_DIGEST_LENGTH];
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson isc_buffer_availableregion(sig, &r);
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson if (r.length < SHA_DIGEST_LENGTH * 2 + 1)
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson return (ISC_R_NOSPACE);
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson dsa = key->opaque;
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson SHA1_Final(digest, ctx);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_mem_put(mctx, ctx, sizeof(SHA_CTX));
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
34b394b43e2207e8f8f3703f0402422121455638David Lawrence dsasig = DSA_do_sign(digest, SHA_DIGEST_LENGTH, dsa);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence if (dsasig == NULL)
34b394b43e2207e8f8f3703f0402422121455638David Lawrence return (DST_R_SIGNFINALFAILURE);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews *r.base++ = (key->key_size - 512)/64;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews BN_bn2bin_fixed(dsasig->r, r.base, SHA_DIGEST_LENGTH);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews r.base += SHA_DIGEST_LENGTH;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews BN_bn2bin_fixed(dsasig->s, r.base, SHA_DIGEST_LENGTH);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence r.base += SHA_DIGEST_LENGTH;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence DSA_SIG_free(dsasig);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence isc_buffer_add(sig, SHA_DIGEST_LENGTH * 2 + 1);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews }
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews else
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews *context = ctx;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (ISC_R_SUCCESS);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence}
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews/*
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * dst_openssl_verify
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Calls OpenSSL verification routines. There are three steps to
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * verification, INIT (initialize structures), UPDATE (hash (more) data),
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * FINAL (generate a signature). This routine performs one or more of
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * these steps.
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * Parameters
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL}
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * key key to use for verifying
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * context the context to use for this computation
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * data signed data
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * signature signature
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * mctx memory context for temporary allocations
fad44a20eede1bbc66716241dede225500c91caaAndreas Gustafsson * Returns
fad44a20eede1bbc66716241dede225500c91caaAndreas Gustafsson * ISC_R_SUCCESS Success
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * !ISC_R_SUCCESS Failure
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson */
34b394b43e2207e8f8f3703f0402422121455638David Lawrencestatic isc_result_t
34b394b43e2207e8f8f3703f0402422121455638David Lawrencedst_openssl_verify(const unsigned int mode, dst_key_t *key, void **context,
34b394b43e2207e8f8f3703f0402422121455638David Lawrence isc_region_t *data, isc_region_t *sig, isc_mem_t *mctx)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews{
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews int status = 0;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson SHA_CTX *ctx = NULL;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (mode & DST_SIGMODE_INIT) {
34b394b43e2207e8f8f3703f0402422121455638David Lawrence ctx = (SHA_CTX *) isc_mem_get(mctx, sizeof(SHA_CTX));
34b394b43e2207e8f8f3703f0402422121455638David Lawrence if (ctx == NULL)
34b394b43e2207e8f8f3703f0402422121455638David Lawrence return (ISC_R_NOMEMORY);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews }
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews else if (context != NULL)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence ctx = (SHA_CTX *) *context;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews REQUIRE (ctx != NULL);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (mode & DST_SIGMODE_INIT)
34b394b43e2207e8f8f3703f0402422121455638David Lawrence SHA1_Init(ctx);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence if ((mode & DST_SIGMODE_UPDATE))
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews SHA1_Update(ctx, data->base, data->length);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (mode & DST_SIGMODE_FINAL) {
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews DSA *dsa;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson DSA_SIG *dsasig;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews unsigned char digest[SHA_DIGEST_LENGTH];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews unsigned char *cp = sig->base;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence dsa = key->opaque;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson SHA1_Final(digest, ctx);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_mem_put(mctx, ctx, sizeof(SHA_CTX));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
fad44a20eede1bbc66716241dede225500c91caaAndreas Gustafsson if (sig->length < 2 * SHA_DIGEST_LENGTH + 1)
fad44a20eede1bbc66716241dede225500c91caaAndreas Gustafsson return (DST_R_VERIFYFINALFAILURE);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff cp++; /* Skip T */
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dsasig = DSA_SIG_new();
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dsasig->r = BN_bin2bn(cp, SHA_DIGEST_LENGTH, NULL);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff cp += SHA_DIGEST_LENGTH;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence dsasig->s = BN_bin2bn(cp, SHA_DIGEST_LENGTH, NULL);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews cp += SHA_DIGEST_LENGTH;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews status = DSA_do_verify(digest, SHA_DIGEST_LENGTH, dsasig, dsa);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews DSA_SIG_free(dsasig);
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews if (status == 0)
94a08e09db3dc844b6ee4841c368a2d7074a9c3fAndreas Gustafsson return (DST_R_VERIFYFINALFAILURE);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence }
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson else
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews *context = ctx;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (ISC_R_SUCCESS);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews}
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews/*
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * dst_openssl_isprivate
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * Is this a private key?
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * Parameters
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * key DST KEY structure
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * Returns
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * ISC_TRUE
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * ISC_FALSE
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews */
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrewsstatic isc_boolean_t
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsdst_openssl_isprivate(const dst_key_t *key) {
34b394b43e2207e8f8f3703f0402422121455638David Lawrence DSA *dsa = (DSA *) key->opaque;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence return (ISC_TF(dsa != NULL && dsa->priv_key != NULL));
34b394b43e2207e8f8f3703f0402422121455638David Lawrence}
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews/*
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * dst_openssl_to_dns
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * Converts key from DSA to DNS distribution format
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * Parameters
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence * key DST KEY structure
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews * data output data
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson * Returns
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * ISC_R_SUCCESS Success
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * !ISC_R_SUCCESS Failure
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff */
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic isc_result_t
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsdst_openssl_to_dns(const dst_key_t *key, isc_buffer_t *data) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews DSA *dsa;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_region_t r;
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews int dnslen;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews unsigned int t, p_bytes;
94a08e09db3dc844b6ee4841c368a2d7074a9c3fAndreas Gustafsson
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews REQUIRE(key->opaque != NULL);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dsa = (DSA *) key->opaque;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_buffer_availableregion(data, &r);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews t = (BN_num_bytes(dsa->p) - 64) / 8;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (t > 8)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (DST_R_INVALIDPUBLICKEY);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews p_bytes = 64 + 8 * t;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dnslen = 1 + (key->key_size * 3)/8 + SHA_DIGEST_LENGTH;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (r.length < (unsigned int) dnslen)
34b394b43e2207e8f8f3703f0402422121455638David Lawrence return (ISC_R_NOSPACE);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence *r.base++ = t;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews BN_bn2bin_fixed(dsa->q, r.base, SHA_DIGEST_LENGTH);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews r.base += SHA_DIGEST_LENGTH;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews r.base += p_bytes;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence r.base += p_bytes;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence r.base += p_bytes;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_buffer_add(data, dnslen);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
4529cdaedaf1a0a5f8ff89aeca510b7a4475446cBob Halley return (ISC_R_SUCCESS);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence}
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews/*
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * dst_openssl_from_dns
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson * Converts from a DNS KEY RR format to a DSA KEY.
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * Parameters
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * key Partially filled key structure
d981ca645597116d227a48bf37cc5edc061c854dBob Halley * data Buffer containing key in DNS format
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * Return
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews * ISC_R_SUCCESS Success
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews * !ISC_R_SUCCESS Failure
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews */
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic isc_result_t
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsdst_openssl_from_dns(dst_key_t *key, isc_buffer_t *data, isc_mem_t *mctx) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews DSA *dsa;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews isc_region_t r;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews unsigned int t, p_bytes;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews mctx = mctx; /* make the compiler happy */
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson isc_buffer_remainingregion(data, &r);
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson if (r.length == 0)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (ISC_R_SUCCESS);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dsa = DSA_new();
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (dsa == NULL)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (ISC_R_NOMEMORY);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews t = (unsigned int) *r.base++;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (t > 8) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews DSA_free(dsa);
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson return (DST_R_INVALIDPUBLICKEY);
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson }
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson p_bytes = 64 + 8 * t;
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (r.length < 1 + SHA_DIGEST_LENGTH + 3 * p_bytes) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews DSA_free(dsa);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews return (DST_R_INVALIDPUBLICKEY);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews }
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dsa->q = BN_bin2bn(r.base, SHA_DIGEST_LENGTH, NULL);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff r.base += SHA_DIGEST_LENGTH;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews dsa->p = BN_bin2bn(r.base, p_bytes, NULL);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews r.base += p_bytes;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews dsa->g = BN_bin2bn(r.base, p_bytes, NULL);
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews r.base += p_bytes;
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL);
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews r.base += p_bytes;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence isc_buffer_remainingregion(data, &r);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence key->key_id = dst_s_id_calc(r.base,
34b394b43e2207e8f8f3703f0402422121455638David Lawrence 1 + SHA_DIGEST_LENGTH + 3 * p_bytes);
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington key->key_size = p_bytes * 8;
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington
34b394b43e2207e8f8f3703f0402422121455638David Lawrence isc_buffer_forward(data, 1 + SHA_DIGEST_LENGTH + 3 * p_bytes);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence key->opaque = (void *) dsa;
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington return (ISC_R_SUCCESS);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence}
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington/*
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * dst_openssl_to_file
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * Encodes a DSA Key into the portable file format.
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * Parameters
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * key DST KEY structure
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * Returns
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * ISC_R_SUCCESS Success
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * !ISC_R_SUCCESS Failure
34b394b43e2207e8f8f3703f0402422121455638David Lawrence */
34b394b43e2207e8f8f3703f0402422121455638David Lawrencestatic isc_result_t
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellingtondst_openssl_to_file(const dst_key_t *key) {
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington int cnt = 0;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence DSA *dsa;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence dst_private_t priv;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence unsigned char bufs[5][128];
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington if (key->opaque == NULL)
34b394b43e2207e8f8f3703f0402422121455638David Lawrence return (DST_R_NULLKEY);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence dsa = (DSA *) key->opaque;
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington priv.elements[cnt].tag = TAG_DSA_PRIME;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence priv.elements[cnt].length = BN_num_bytes(dsa->p);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence BN_bn2bin(dsa->p, bufs[cnt]);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence priv.elements[cnt].data = bufs[cnt];
5466ce3f279d9fa83ce826bcdc9482bc591152aeAndreas Gustafsson cnt++;
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington
34b394b43e2207e8f8f3703f0402422121455638David Lawrence priv.elements[cnt].tag = TAG_DSA_SUBPRIME;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence priv.elements[cnt].length = BN_num_bytes(dsa->q);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence BN_bn2bin(dsa->q, bufs[cnt]);
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews priv.elements[cnt].data = bufs[cnt];
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews cnt++;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff priv.elements[cnt].tag = TAG_DSA_BASE;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence priv.elements[cnt].length = BN_num_bytes(dsa->g);
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington BN_bn2bin(dsa->g, bufs[cnt]);
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews priv.elements[cnt].data = bufs[cnt];
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington cnt++;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews priv.elements[cnt].tag = TAG_DSA_PRIVATE;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews priv.elements[cnt].length = BN_num_bytes(dsa->priv_key);
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews BN_bn2bin(dsa->priv_key, bufs[cnt]);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence priv.elements[cnt].data = bufs[cnt];
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington cnt++;
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington priv.elements[cnt].tag = TAG_DSA_PUBLIC;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews priv.elements[cnt].length = BN_num_bytes(dsa->pub_key);
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington BN_bn2bin(dsa->pub_key, bufs[cnt]);
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington priv.elements[cnt].data = bufs[cnt];
34b394b43e2207e8f8f3703f0402422121455638David Lawrence cnt++;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence priv.nelements = cnt;
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington return (dst_s_write_private_key_file(key->key_name, key->key_alg,
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington key->key_id, &priv));
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington}
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence/*
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * dst_openssl_from_file
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * Converts contents of a private key file into a private DSA key.
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * Parameters
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * key Partially filled DSA KEY structure
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * id The key id
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * path The directory that the file will be read from
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * Return
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * ISC_R_SUCCESS Success
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * !ISC_R_SUCCESS Failure
34b394b43e2207e8f8f3703f0402422121455638David Lawrence */
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrencestatic isc_result_t
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellingtondst_openssl_from_file(dst_key_t *key, const isc_uint16_t id, isc_mem_t *mctx) {
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington dst_private_t priv;
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington isc_result_t ret;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence isc_buffer_t dns;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence isc_region_t r;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence unsigned char dns_array[1024];
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington int i;
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington DSA *dsa = NULL;
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington#define DST_RET(a) {ret = a; goto err;}
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence /* read private key file */
34b394b43e2207e8f8f3703f0402422121455638David Lawrence ret = dst_s_parse_private_key_file(key->key_name, key->key_alg,
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington id, &priv, mctx);
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington if (ret != ISC_R_SUCCESS)
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington return (ret);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence dsa = DSA_new();
34b394b43e2207e8f8f3703f0402422121455638David Lawrence if (dsa == NULL)
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington DST_RET(ISC_R_NOMEMORY);
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington key->opaque = dsa;
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington for (i=0; i < priv.nelements; i++) {
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington BIGNUM *bn;
cf3f14106d082e4676431c10c54b60b9a0e9b127Brian Wellington bn = BN_bin2bn(priv.elements[i].data,
1bb227b988b8170cbb1a2fcf43b19a3ec57423adMark Andrews priv.elements[i].length, NULL);
cf3f14106d082e4676431c10c54b60b9a0e9b127Brian Wellington if (bn == NULL)
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington DST_RET(ISC_R_NOMEMORY);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence
34b394b43e2207e8f8f3703f0402422121455638David Lawrence switch (priv.elements[i].tag) {
34b394b43e2207e8f8f3703f0402422121455638David Lawrence case TAG_DSA_PRIME:
b5da378f2987a115491c291d062252f3152d8db8Brian Wellington dsa->p = bn;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews break;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews case TAG_DSA_SUBPRIME:
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews dsa->q = bn;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews break;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews case TAG_DSA_BASE:
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews dsa->g = bn;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews break;
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington case TAG_DSA_PRIVATE:
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews dsa->priv_key = bn;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff break;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews case TAG_DSA_PUBLIC:
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews dsa->pub_key = bn;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews break;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews }
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews }
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dst_s_free_private_structure_fields(&priv, mctx);
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews
4529cdaedaf1a0a5f8ff89aeca510b7a4475446cBob Halley key->key_size = BN_num_bits(dsa->p);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence isc_buffer_init(&dns, dns_array, sizeof(dns_array));
b8dd48ecf83142f6ee7238cbd68fec455e527fc8Mark Andrews ret = dst_openssl_to_dns(key, &dns);
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington if (ret != ISC_R_SUCCESS)
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews DST_RET(ret);
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington isc_buffer_usedregion(&dns, &r);
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington key->key_id = dst_s_id_calc(r.base, r.length);
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews if (key->key_id != id)
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews DST_RET(DST_R_INVALIDPRIVATEKEY);
cf3f14106d082e4676431c10c54b60b9a0e9b127Brian Wellington
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson return (ISC_R_SUCCESS);
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews err:
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews key->opaque = NULL;
d981ca645597116d227a48bf37cc5edc061c854dBob Halley dst_openssl_destroy(dsa, mctx);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff dst_s_free_private_structure_fields(&priv, mctx);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence memset(&priv, 0, sizeof(priv));
d981ca645597116d227a48bf37cc5edc061c854dBob Halley return (ret);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley}
82ca33427bdd4f3bc4ed3431e86bd810fe751674Andreas Gustafsson
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson/*
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson * dst_openssl_destroy
d981ca645597116d227a48bf37cc5edc061c854dBob Halley * Frees all dynamically allocated structures in key.
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff */
d981ca645597116d227a48bf37cc5edc061c854dBob Halleystatic void
d981ca645597116d227a48bf37cc5edc061c854dBob Halleydst_openssl_destroy(void *key, isc_mem_t *mctx) {
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff DSA *dsa = (DSA *) key;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence if (dsa == NULL)
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley return;
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley mctx = mctx; /* make the compiler happy */
82ca33427bdd4f3bc4ed3431e86bd810fe751674Andreas Gustafsson
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson DSA_free(dsa);
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson}
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley/*
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * dst_openssl_generate
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * Generates unique keys that are hard to predict.
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * Parameters
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * key DST Key structure
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * unused algorithm specific data, unused for DSA.
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * mctx memory context to allocate key
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * Return
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * ISC_R_SUCCESS Success
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * !ISC_R_SUCCESS Failure
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley */
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halleystatic isc_result_t
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halleydst_openssl_generate(dst_key_t *key, int unused, isc_mem_t *mctx) {
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley DSA *dsa;
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews unsigned char dns_array[1024];
unsigned char rand_array[SHA_DIGEST_LENGTH];
isc_buffer_t dns, rand;
isc_result_t ret;
isc_region_t r;
unused = unused; /* make the compiler happy */
mctx = mctx; /* make the compiler happy */
isc_buffer_init(&rand, rand_array, sizeof(rand_array));
ret = dst_random_get(SHA_DIGEST_LENGTH, &rand);
if (ret != ISC_R_SUCCESS)
return (ret);
dsa = DSA_generate_parameters(key->key_size, rand_array,
SHA_DIGEST_LENGTH, NULL, NULL,
NULL, NULL);
if (dsa == NULL)
return (ISC_R_NOMEMORY);
if (DSA_generate_key(dsa) == 0)
return (ISC_R_NOMEMORY);
key->opaque = dsa;
isc_buffer_init(&dns, dns_array, sizeof(dns_array));
dst_openssl_to_dns(key, &dns);
isc_buffer_usedregion(&dns, &r);
key->key_id = dst_s_id_calc(r.base, r.length);
return (ISC_R_SUCCESS);
}
/**************************************************************************
* dst_openssl_compare
* Compare two keys for equality.
* Return
* ISC_TRUE The keys are equal
* ISC_FALSE The keys are not equal
*/
static isc_boolean_t
dst_openssl_compare(const dst_key_t *key1, const dst_key_t *key2) {
int status;
DSA *dsa1, *dsa2;
dsa1 = (DSA *) key1->opaque;
dsa2 = (DSA *) key2->opaque;
if (dsa1 == NULL && dsa2 == NULL)
return (ISC_TRUE);
else if (dsa1 == NULL || dsa2 == NULL)
return (ISC_FALSE);
status = BN_cmp(dsa1->p, dsa2->p) ||
BN_cmp(dsa1->q, dsa2->q) ||
BN_cmp(dsa1->g, dsa2->g) ||
BN_cmp(dsa1->pub_key, dsa2->pub_key);
if (status != 0)
return (ISC_FALSE);
if (dsa1->priv_key != NULL || dsa2->priv_key != NULL) {
if (dsa1->priv_key == NULL || dsa2->priv_key == NULL)
return (ISC_FALSE);
if (BN_cmp(dsa1->priv_key, dsa2->priv_key))
return (ISC_FALSE);
}
return (ISC_TRUE);
}
static int
BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
int bytes = size - BN_num_bytes(bn);
while (bytes-- > 0)
*buf++ = 0;
BN_bn2bin(bn, buf);
return (size);
}
#endif