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