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_MAX_MD_SIZE; 48 algorithm->data = hmac_algorithm; 49 algorithm->hmac_create_context = create_context; 50 algorithm->hmac_init_context = init_context; 51 algorithm->hmac_update = update; 52 algorithm->hmac_final = final; 53 tsig_add_algorithm(algorithm); 54 55 return 1; 56 } 57 58 int 59 tsig_openssl_init(region_type *region) 60 { 61 int count = 0; 62 OpenSSL_add_all_digests(); 63 64 count += tsig_openssl_init_algorithm(region, "md5", "hmac-md5","hmac-md5.sig-alg.reg.int."); 65 #ifdef HAVE_EVP_SHA1 66 count += tsig_openssl_init_algorithm(region, "sha1", "hmac-sha1", "hmac-sha1."); 67 #endif /* HAVE_EVP_SHA1 */ 68 69 #ifdef HAVE_EVP_SHA256 70 count += tsig_openssl_init_algorithm(region, "sha256", "hmac-sha256", "hmac-sha256."); 71 #endif /* HAVE_EVP_SHA256 */ 72 return count; 73 } 74 75 static void 76 cleanup_context(void *data) 77 { 78 HMAC_CTX *context = (HMAC_CTX *) data; 79 HMAC_CTX_cleanup(context); 80 } 81 82 static void * 83 create_context(region_type *region) 84 { 85 HMAC_CTX *context 86 = (HMAC_CTX *) region_alloc(region, sizeof(HMAC_CTX)); 87 region_add_cleanup(region, cleanup_context, context); 88 HMAC_CTX_init(context); 89 return context; 90 } 91 92 static void 93 init_context(void *context, 94 tsig_algorithm_type *algorithm, 95 tsig_key_type *key) 96 { 97 HMAC_CTX *ctx = (HMAC_CTX *) context; 98 const EVP_MD *md = (const EVP_MD *) algorithm->data; 99 HMAC_Init_ex(ctx, key->data, key->size, md, NULL); 100 } 101 102 static void 103 update(void *context, const void *data, size_t size) 104 { 105 HMAC_CTX *ctx = (HMAC_CTX *) context; 106 HMAC_Update(ctx, (unsigned char *) data, (int) size); 107 } 108 109 static void 110 final(void *context, uint8_t *digest, size_t *size) 111 { 112 HMAC_CTX *ctx = (HMAC_CTX *) context; 113 unsigned len = (unsigned) *size; 114 HMAC_Final(ctx, digest, &len); 115 *size = (size_t) len; 116 } 117 118 void 119 tsig_openssl_finalize() 120 { 121 EVP_cleanup(); 122 } 123 124 #endif /* defined(HAVE_SSL) */ 125