1 /* 2 * tsig-openssl.h -- Interface to OpenSSL for TSIG support. 3 * 4 * Copyright (c) 2001-2011, 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 log_msg(LOG_ERR, "%s digest not available", digest); 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 OpenSSL_add_all_digests(); 62 63 /* TODO: walk lookup supported algorithms table */ 64 if (!tsig_openssl_init_algorithm(region, "md5", "hmac-md5","hmac-md5.sig-alg.reg.int.")) 65 return 0; 66 #ifdef HAVE_EVP_SHA1 67 if (!tsig_openssl_init_algorithm(region, "sha1", "hmac-sha1", "hmac-sha1.")) 68 return 0; 69 #endif /* HAVE_EVP_SHA1 */ 70 71 #ifdef HAVE_EVP_SHA256 72 if (!tsig_openssl_init_algorithm(region, "sha256", "hmac-sha256", "hmac-sha256.")) 73 return 0; 74 #endif /* HAVE_EVP_SHA256 */ 75 return 1; 76 } 77 78 static void 79 cleanup_context(void *data) 80 { 81 HMAC_CTX *context = (HMAC_CTX *) data; 82 HMAC_CTX_cleanup(context); 83 } 84 85 static void * 86 create_context(region_type *region) 87 { 88 HMAC_CTX *context 89 = (HMAC_CTX *) region_alloc(region, sizeof(HMAC_CTX)); 90 region_add_cleanup(region, cleanup_context, context); 91 HMAC_CTX_init(context); 92 return context; 93 } 94 95 static void 96 init_context(void *context, 97 tsig_algorithm_type *algorithm, 98 tsig_key_type *key) 99 { 100 HMAC_CTX *ctx = (HMAC_CTX *) context; 101 const EVP_MD *md = (const EVP_MD *) algorithm->data; 102 HMAC_Init_ex(ctx, key->data, key->size, md, NULL); 103 } 104 105 static void 106 update(void *context, const void *data, size_t size) 107 { 108 HMAC_CTX *ctx = (HMAC_CTX *) context; 109 HMAC_Update(ctx, (unsigned char *) data, (int) size); 110 } 111 112 static void 113 final(void *context, uint8_t *digest, size_t *size) 114 { 115 HMAC_CTX *ctx = (HMAC_CTX *) context; 116 unsigned len = (unsigned) *size; 117 HMAC_Final(ctx, digest, &len); 118 *size = (size_t) len; 119 } 120 121 void 122 tsig_openssl_finalize() 123 { 124 EVP_cleanup(); 125 } 126 127 #endif /* defined(HAVE_SSL) */ 128