Home | History | Annotate | Line # | Download | only in dist
tsig-openssl.c revision 1.1
      1  1.1  christos /*
      2  1.1  christos  * tsig-openssl.h -- Interface to OpenSSL for TSIG support.
      3  1.1  christos  *
      4  1.1  christos  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
      5  1.1  christos  *
      6  1.1  christos  * See LICENSE for the license.
      7  1.1  christos  *
      8  1.1  christos  */
      9  1.1  christos 
     10  1.1  christos #include "config.h"
     11  1.1  christos 
     12  1.1  christos #if defined(HAVE_SSL)
     13  1.1  christos 
     14  1.1  christos #include "tsig-openssl.h"
     15  1.1  christos #include "tsig.h"
     16  1.1  christos #include "util.h"
     17  1.1  christos 
     18  1.1  christos static void *create_context(region_type *region);
     19  1.1  christos static void init_context(void *context,
     20  1.1  christos 			 tsig_algorithm_type *algorithm,
     21  1.1  christos 			 tsig_key_type *key);
     22  1.1  christos static void update(void *context, const void *data, size_t size);
     23  1.1  christos static void final(void *context, uint8_t *digest, size_t *size);
     24  1.1  christos 
     25  1.1  christos static int
     26  1.1  christos tsig_openssl_init_algorithm(region_type* region,
     27  1.1  christos 	const char* digest, const char* name, const char* wireformat)
     28  1.1  christos {
     29  1.1  christos 	tsig_algorithm_type* algorithm;
     30  1.1  christos 	const EVP_MD *hmac_algorithm;
     31  1.1  christos 
     32  1.1  christos 	hmac_algorithm = EVP_get_digestbyname(digest);
     33  1.1  christos 	if (!hmac_algorithm) {
     34  1.1  christos 		/* skip but don't error */
     35  1.1  christos 		return 0;
     36  1.1  christos 	}
     37  1.1  christos 
     38  1.1  christos 	algorithm = (tsig_algorithm_type *) region_alloc(
     39  1.1  christos 		region, sizeof(tsig_algorithm_type));
     40  1.1  christos 	algorithm->short_name = name;
     41  1.1  christos 	algorithm->wireformat_name
     42  1.1  christos 		= dname_parse(region, wireformat);
     43  1.1  christos 	if (!algorithm->wireformat_name) {
     44  1.1  christos 		log_msg(LOG_ERR, "cannot parse %s algorithm", wireformat);
     45  1.1  christos 		return 0;
     46  1.1  christos 	}
     47  1.1  christos 	algorithm->maximum_digest_size = EVP_MD_size(hmac_algorithm);
     48  1.1  christos 	if(algorithm->maximum_digest_size < 20)
     49  1.1  christos 		algorithm->maximum_digest_size = EVP_MAX_MD_SIZE;
     50  1.1  christos 	algorithm->data = hmac_algorithm;
     51  1.1  christos 	algorithm->hmac_create_context = create_context;
     52  1.1  christos 	algorithm->hmac_init_context = init_context;
     53  1.1  christos 	algorithm->hmac_update = update;
     54  1.1  christos 	algorithm->hmac_final = final;
     55  1.1  christos 	tsig_add_algorithm(algorithm);
     56  1.1  christos 
     57  1.1  christos 	return 1;
     58  1.1  christos }
     59  1.1  christos 
     60  1.1  christos int
     61  1.1  christos tsig_openssl_init(region_type *region)
     62  1.1  christos {
     63  1.1  christos 	int count = 0;
     64  1.1  christos #if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
     65  1.1  christos 	OpenSSL_add_all_digests();
     66  1.1  christos #else
     67  1.1  christos 	OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
     68  1.1  christos #endif
     69  1.1  christos 
     70  1.1  christos 	count += tsig_openssl_init_algorithm(region,
     71  1.1  christos 	    "md5", "hmac-md5","hmac-md5.sig-alg.reg.int.");
     72  1.1  christos 	count += tsig_openssl_init_algorithm(region,
     73  1.1  christos 	    "sha1", "hmac-sha1", "hmac-sha1.");
     74  1.1  christos 	count += tsig_openssl_init_algorithm(region,
     75  1.1  christos 	    "sha224", "hmac-sha224", "hmac-sha224.");
     76  1.1  christos 	count += tsig_openssl_init_algorithm(region,
     77  1.1  christos 	    "sha256", "hmac-sha256", "hmac-sha256.");
     78  1.1  christos 	count += tsig_openssl_init_algorithm(region,
     79  1.1  christos 	    "sha384", "hmac-sha384", "hmac-sha384.");
     80  1.1  christos 	count += tsig_openssl_init_algorithm(region,
     81  1.1  christos 	    "sha512", "hmac-sha512", "hmac-sha512.");
     82  1.1  christos 
     83  1.1  christos 	return count;
     84  1.1  christos }
     85  1.1  christos 
     86  1.1  christos static void
     87  1.1  christos cleanup_context(void *data)
     88  1.1  christos {
     89  1.1  christos 	HMAC_CTX *context = (HMAC_CTX *) data;
     90  1.1  christos #ifdef HAVE_HMAC_CTX_NEW
     91  1.1  christos 	HMAC_CTX_free(context);
     92  1.1  christos #else
     93  1.1  christos 	HMAC_CTX_cleanup(context);
     94  1.1  christos 	free(context);
     95  1.1  christos #endif
     96  1.1  christos }
     97  1.1  christos 
     98  1.1  christos static void *
     99  1.1  christos create_context(region_type *region)
    100  1.1  christos {
    101  1.1  christos #ifdef HAVE_HMAC_CTX_NEW
    102  1.1  christos 	HMAC_CTX *context = HMAC_CTX_new();
    103  1.1  christos #else
    104  1.1  christos 	HMAC_CTX *context = (HMAC_CTX *) malloc(sizeof(HMAC_CTX));
    105  1.1  christos #endif
    106  1.1  christos 	region_add_cleanup(region, cleanup_context, context);
    107  1.1  christos #ifdef HAVE_HMAC_CTX_RESET
    108  1.1  christos 	HMAC_CTX_reset(context);
    109  1.1  christos #else
    110  1.1  christos 	HMAC_CTX_init(context);
    111  1.1  christos #endif
    112  1.1  christos 	return context;
    113  1.1  christos }
    114  1.1  christos 
    115  1.1  christos static void
    116  1.1  christos init_context(void *context,
    117  1.1  christos 			  tsig_algorithm_type *algorithm,
    118  1.1  christos 			  tsig_key_type *key)
    119  1.1  christos {
    120  1.1  christos 	HMAC_CTX *ctx = (HMAC_CTX *) context;
    121  1.1  christos 	const EVP_MD *md = (const EVP_MD *) algorithm->data;
    122  1.1  christos 	HMAC_Init_ex(ctx, key->data, key->size, md, NULL);
    123  1.1  christos }
    124  1.1  christos 
    125  1.1  christos static void
    126  1.1  christos update(void *context, const void *data, size_t size)
    127  1.1  christos {
    128  1.1  christos 	HMAC_CTX *ctx = (HMAC_CTX *) context;
    129  1.1  christos 	HMAC_Update(ctx, (unsigned char *) data, (int) size);
    130  1.1  christos }
    131  1.1  christos 
    132  1.1  christos static void
    133  1.1  christos final(void *context, uint8_t *digest, size_t *size)
    134  1.1  christos {
    135  1.1  christos 	HMAC_CTX *ctx = (HMAC_CTX *) context;
    136  1.1  christos 	unsigned len = (unsigned) *size;
    137  1.1  christos 	HMAC_Final(ctx, digest, &len);
    138  1.1  christos 	*size = (size_t) len;
    139  1.1  christos }
    140  1.1  christos 
    141  1.1  christos void
    142  1.1  christos tsig_openssl_finalize()
    143  1.1  christos {
    144  1.1  christos #ifdef HAVE_EVP_CLEANUP
    145  1.1  christos 	EVP_cleanup();
    146  1.1  christos #endif
    147  1.1  christos }
    148  1.1  christos 
    149  1.1  christos #endif /* defined(HAVE_SSL) */
    150