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 OpenSSL_add_all_digests(); 65 66 count += tsig_openssl_init_algorithm(region, 67 "md5", "hmac-md5","hmac-md5.sig-alg.reg.int."); 68 count += tsig_openssl_init_algorithm(region, 69 "sha1", "hmac-sha1", "hmac-sha1."); 70 count += tsig_openssl_init_algorithm(region, 71 "sha224", "hmac-sha224", "hmac-sha224."); 72 count += tsig_openssl_init_algorithm(region, 73 "sha256", "hmac-sha256", "hmac-sha256."); 74 count += tsig_openssl_init_algorithm(region, 75 "sha384", "hmac-sha384", "hmac-sha384."); 76 count += tsig_openssl_init_algorithm(region, 77 "sha512", "hmac-sha512", "hmac-sha512."); 78 79 return count; 80 } 81 82 static void 83 cleanup_context(void *data) 84 { 85 HMAC_CTX *context = (HMAC_CTX *) data; 86 #ifdef HAVE_HMAC_CTX_NEW 87 HMAC_CTX_free(context); 88 #else 89 HMAC_CTX_cleanup(context); 90 free(context); 91 #endif 92 } 93 94 static void * 95 create_context(region_type *region) 96 { 97 #ifdef HAVE_HMAC_CTX_NEW 98 HMAC_CTX *context = HMAC_CTX_new(); 99 #else 100 HMAC_CTX *context = (HMAC_CTX *) malloc(sizeof(HMAC_CTX)); 101 #endif 102 region_add_cleanup(region, cleanup_context, context); 103 #ifdef HAVE_HMAC_CTX_RESET 104 HMAC_CTX_reset(context); 105 #else 106 HMAC_CTX_init(context); 107 #endif 108 return context; 109 } 110 111 static void 112 init_context(void *context, 113 tsig_algorithm_type *algorithm, 114 tsig_key_type *key) 115 { 116 HMAC_CTX *ctx = (HMAC_CTX *) context; 117 const EVP_MD *md = (const EVP_MD *) algorithm->data; 118 HMAC_Init_ex(ctx, key->data, key->size, md, NULL); 119 } 120 121 static void 122 update(void *context, const void *data, size_t size) 123 { 124 HMAC_CTX *ctx = (HMAC_CTX *) context; 125 HMAC_Update(ctx, (unsigned char *) data, (int) size); 126 } 127 128 static void 129 final(void *context, uint8_t *digest, size_t *size) 130 { 131 HMAC_CTX *ctx = (HMAC_CTX *) context; 132 unsigned len = (unsigned) *size; 133 HMAC_Final(ctx, digest, &len); 134 *size = (size_t) len; 135 } 136 137 void 138 tsig_openssl_finalize() 139 { 140 EVP_cleanup(); 141 } 142 143 #endif /* defined(HAVE_SSL) */ 144