openssl_link.c revision 364a82f7c25b62967678027043425201a5e5171a
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * Portions Copyright (c) 1995-1998 by Network Associates, Inc.
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 * 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.
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson * Principal Author: Brian Wellington
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson * $Id: openssl_link.c,v 1.17 2000/04/28 01:10:48 halley Exp $
542deb20c44666a870855bf755a100d254db074dAndreas Gustafssonstatic isc_result_t dst_openssl_sign(const unsigned int mode,
34b394b43e2207e8f8f3703f0402422121455638David Lawrencestatic isc_result_t dst_openssl_verify(const unsigned int mode,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic isc_boolean_t dst_openssl_compare(const dst_key_t *key1,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic isc_result_t dst_openssl_generate(dst_key_t *key, int unused,
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,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsstatic isc_result_t dst_openssl_from_dns(dst_key_t *key, isc_buffer_t *data,
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 Lawrencestatic int BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf,
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * dst_s_openssldsa_init()
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * Sets up function pointers for OpenSSL related functions
34b394b43e2207e8f8f3703f0402422121455638David Lawrence dst_t_func[DST_ALG_DSA] = &openssl_functions;
34b394b43e2207e8f8f3703f0402422121455638David Lawrence memset(&openssl_functions, 0, sizeof(struct dst_func));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson openssl_functions.verify = dst_openssl_verify;
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);
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
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington * ISC_R_SUCCESS Success
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * !ISC_R_SUCCESS Failure
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 ctx = (SHA_CTX *) isc_mem_get(mctx, sizeof(SHA_CTX));
1ac4b2a1da88e574319b374bc733eccf8ac45327Andreas Gustafsson if (r.length < SHA_DIGEST_LENGTH * 2 + 1)
34b394b43e2207e8f8f3703f0402422121455638David Lawrence dsasig = DSA_do_sign(digest, SHA_DIGEST_LENGTH, dsa);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews BN_bn2bin_fixed(dsasig->r, r.base, SHA_DIGEST_LENGTH);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews BN_bn2bin_fixed(dsasig->s, r.base, SHA_DIGEST_LENGTH);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence isc_buffer_add(sig, SHA_DIGEST_LENGTH * 2 + 1);
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 * 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 * ISC_R_SUCCESS Success
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * !ISC_R_SUCCESS Failure
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)
34b394b43e2207e8f8f3703f0402422121455638David Lawrence ctx = (SHA_CTX *) isc_mem_get(mctx, sizeof(SHA_CTX));
fad44a20eede1bbc66716241dede225500c91caaAndreas Gustafsson if (sig->length < 2 * SHA_DIGEST_LENGTH + 1)
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dsasig->r = BN_bin2bn(cp, SHA_DIGEST_LENGTH, NULL);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence dsasig->s = BN_bin2bn(cp, SHA_DIGEST_LENGTH, NULL);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews status = DSA_do_verify(digest, SHA_DIGEST_LENGTH, dsasig, dsa);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * dst_openssl_isprivate
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * Is this a private key?
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * Parameters
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * key DST KEY structure
34b394b43e2207e8f8f3703f0402422121455638David Lawrence return (ISC_TF(dsa != NULL && dsa->priv_key != NULL));
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * dst_openssl_to_dns
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * Converts key from DSA to DNS distribution format
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence * key DST KEY structure
2bc0da0cd874b15593d65338ba96e90ceed13072Mark Andrews * data output data
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * ISC_R_SUCCESS Success
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews * !ISC_R_SUCCESS Failure
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsdst_openssl_to_dns(const dst_key_t *key, isc_buffer_t *data) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews unsigned int t, p_bytes;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dnslen = 1 + (key->key_size * 3)/8 + SHA_DIGEST_LENGTH;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews BN_bn2bin_fixed(dsa->q, r.base, SHA_DIGEST_LENGTH);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8);
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8);
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
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews * ISC_R_SUCCESS Success
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews * !ISC_R_SUCCESS Failure
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrewsdst_openssl_from_dns(dst_key_t *key, isc_buffer_t *data, isc_mem_t *mctx) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews unsigned int t, p_bytes;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews t = (unsigned int) *r.base++;
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (t > 8) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (r.length < 1 + SHA_DIGEST_LENGTH + 3 * p_bytes) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dsa->q = BN_bin2bn(r.base, SHA_DIGEST_LENGTH, NULL);
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence isc_buffer_forward(data, 1 + SHA_DIGEST_LENGTH + 3 * p_bytes);
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * dst_openssl_to_file
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * Encodes a DSA Key into the portable file format.
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * key DST KEY structure
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * ISC_R_SUCCESS Success
34b394b43e2207e8f8f3703f0402422121455638David Lawrence * !ISC_R_SUCCESS Failure
34b394b43e2207e8f8f3703f0402422121455638David Lawrence priv.elements[cnt].length = BN_num_bytes(dsa->p);
34b394b43e2207e8f8f3703f0402422121455638David Lawrence priv.elements[cnt].length = BN_num_bytes(dsa->q);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence priv.elements[cnt].length = BN_num_bytes(dsa->g);
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews priv.elements[cnt].length = BN_num_bytes(dsa->priv_key);
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews priv.elements[cnt].length = BN_num_bytes(dsa->pub_key);
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington return (dst_s_write_private_key_file(key->key_name, key->key_alg,
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * dst_openssl_from_file
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * Converts contents of a private key file into a private DSA key.
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 * ISC_R_SUCCESS Success
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington * !ISC_R_SUCCESS Failure
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellingtondst_openssl_from_file(dst_key_t *key, const isc_uint16_t id, isc_mem_t *mctx) {
34b394b43e2207e8f8f3703f0402422121455638David Lawrence /* read private key file */
34b394b43e2207e8f8f3703f0402422121455638David Lawrence ret = dst_s_parse_private_key_file(key->key_name, key->key_alg,
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews dst_s_free_private_structure_fields(&priv, mctx);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence isc_buffer_init(&dns, dns_array, sizeof(dns_array));
d8813e2ceee2f4adaf697931c2491de265ce5eb9Brian Wellington key->key_id = dst_s_id_calc(r.base, r.length);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff dst_s_free_private_structure_fields(&priv, mctx);
542deb20c44666a870855bf755a100d254db074dAndreas Gustafsson * dst_openssl_destroy
d981ca645597116d227a48bf37cc5edc061c854dBob Halley * Frees all dynamically allocated structures in key.
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 * ISC_R_SUCCESS Success
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * !ISC_R_SUCCESS Failure
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halleydst_openssl_generate(dst_key_t *key, int unused, isc_mem_t *mctx) {
isc_region_t r;
return (ret);
return (ISC_R_NOMEMORY);
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
static isc_boolean_t
int status;
return (ISC_TRUE);
return (ISC_FALSE);
if (status != 0)
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
while (bytes-- > 0)
*buf++ = 0;
return (size);