Commit 25811a89 authored by Brian Wellington's avatar Brian Wellington
Browse files

Added dst_digest (a wrapper around digest functions), and dst_s_md5 (an

internal wrapper around MD5).  Modified hmac-md5 code to use dst_s_md5.
parent b500110b
......@@ -43,8 +43,8 @@ CONFOBJS = config/confacl.@O@ config/confcache.@O@ config/confcommon.@O@ \
DSTOBJS = sec/dst/bsafe_link.@O@ sec/dst/dst_api.@O@ \
sec/dst/dst_parse.@O@ sec/dst/hmac_link.@O@ \
sec/dst/openssl_link.@O@ sec/dst/openssldh_link.@O@ \
sec/dst/dst_result.@O@ sec/dst/dst_support.@O@ \
sec/dst/dst_lib.@O@
sec/dst/opensslmd5_link.@O@ sec/dst/dst_result.@O@ \
sec/dst/dst_support.@O@ sec/dst/dst_lib.@O@
OPENSSLOBJS = sec/openssl/bn_add.@O@ sec/openssl/bn_asm.@O@ \
sec/openssl/bn_comba.@O@ sec/openssl/bn_div.@O@ \
......@@ -122,7 +122,7 @@ OBJS = a6.@O@ address.@O@ callbacks.@O@ compress.@O@ \
rbt.@O@ rbtdb.@O@ rbtdb64.@O@ rdata.@O@ rdatalist.@O@ \
rdataset.@O@ rdatasetiter.@O@ rdataslab.@O@ resolver.@O@ \
result.@O@ \
tcpmsg.@O@ time.@O@ tsig.@O@ ttl.@O@ \
tcpmsg.@O@ time.@O@ tkey.@O@ tsig.@O@ ttl.@O@ \
version.@O@ view.@O@ zone.@O@ zt.@O@ \
${DSTOBJS} ${OPENSSLOBJS} ${DNSSAFEOBJS} ${CONFOBJS}
......@@ -135,7 +135,7 @@ SRCS = a6.c address.c callbacks.c compress.c \
rbt.c rbtdb.c rbtdb64.c rdata.c rdatalist.c \
rdataset.c rdatasetiter.c rdataslab.c resolver.c \
result.c \
tcpmsg.c time.c tsig.c ttl.c \
tcpmsg.c time.c tkey.c tsig.c ttl.c \
version.c view.c zone.c zt.c
SUBDIRS = include sec config
......
......@@ -31,12 +31,12 @@ LIBS = @LIBS@
# Alphabetically
OBJS = bsafe_link.@O@ dst_api.@O@ dst_parse.@O@ hmac_link.@O@ \
openssl_link.@O@ openssldh_link.@O@ dst_result.@O@ \
dst_support.@O@ dst_lib.@O@
openssl_link.@O@ openssldh_link.@O@ opensslmd5_link.@O@ \
dst_result.@O@ dst_support.@O@ dst_lib.@O@
SRCS = bsafe_link.c dst_api.c dst_parse.c hmac_link.c \
openssl_link.c openssldh_link.c dst_result.c dst_support.c \
dst_lib.c
openssl_link.c openssldh_link.c opensslmd5_link.c \
dst_result.c dst_support.c dst_lib.c
SUBDIRS = include
TARGETS = ${OBJS}
......
......@@ -17,7 +17,7 @@
/*
* Principal Author: Brian Wellington
* $Id: dst_api.c,v 1.14 1999/10/14 18:32:49 bwelling Exp $
* $Id: dst_api.c,v 1.15 1999/10/18 21:35:46 bwelling Exp $
*/
#include <config.h>
......@@ -180,6 +180,48 @@ dst_verify(const unsigned int mode, dst_key_t *key, dst_context_t *context,
key->mctx));
}
/*
* dst_digest
* An incremental digest function. Data is digested in steps.
* First the context must be initialized (DST_SIGMODE_INIT).
* Then data is hashed (DST_SIGMODE_UPDATE). Finally the digest
* is generated (DST_SIGMODE_FINAL). This function can be called
* once with DST_SIGMODE_ALL set, or it can be called separately
* for each step. The UPDATE step may be repeated.
* Parameters
* mode A bit mask specifying operation(s) to be performed.
* DST_SIGMODE_INIT Initialize digest
* DST_SIGMODE_UPDATE Add data to digest
* DST_SIGMODE_FINAL Complete digest
* DST_SIGMODE_ALL Perform all operations
* alg The digest algorithm to use
* context The state of the operation
* data The data to be digested.
* sig The sdigest.
* Returns
* ISC_R_SUCCESS Success
* !ISC_R_SUCCESS Failure
*/
dst_result_t
dst_digest(const unsigned int mode, const unsigned int alg,
dst_context_t *context, isc_region_t *data, isc_buffer_t *digest)
{
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
REQUIRE((mode & DST_SIGMODE_ALL) != 0);
if ((mode & DST_SIGMODE_UPDATE) != 0)
REQUIRE(data != NULL && data->base != NULL);
if ((mode & DST_SIGMODE_FINAL) != 0)
REQUIRE(digest != NULL);
if (alg != DST_DIGEST_MD5)
return (DST_R_UNSUPPORTEDALG);
return (dst_s_md5(mode, context, data, digest, dst_memory_pool));
}
/*
* dst_computesecret
* A function to compute a shared secret from two (Diffie-Hellman) keys.
......
......@@ -105,6 +105,13 @@ int dst_s_build_filename(char *filename, const char *name,
const char *suffix,
size_t filename_length);
/* digest functions */
dst_result_t dst_s_md5(const unsigned int mode, void **context,
isc_region_t *data, isc_buffer_t *digest,
isc_mem_t *mctx);
/* memory allocators using the DST memory pool */
void * dst_mem_alloc(size_t size);
void dst_mem_free(void *ptr);
......
......@@ -17,7 +17,7 @@
/*
* Principal Author: Brian Wellington
* $Id: hmac_link.c,v 1.9 1999/10/08 13:08:56 bwelling Exp $
* $Id: hmac_link.c,v 1.10 1999/10/18 21:35:46 bwelling Exp $
*/
#include <config.h>
......@@ -41,12 +41,17 @@
#define HMAC_LEN 64
#define HMAC_IPAD 0x36
#define HMAC_OPAD 0x5c
#define MD5_LEN 16
#define MD5Init MD5_Init
#define MD5Update MD5_Update
#define MD5Final MD5_Final
#define RETERR(x) { \
ret = (x); \
if (ret != ISC_R_SUCCESS) \
return (ret); \
} while (0)
typedef struct hmackey {
unsigned char ipad[64], opad[64];
} HMAC_Key;
......@@ -122,47 +127,38 @@ dst_hmacmd5_sign(const unsigned int mode, dst_key_t *key, void **context,
isc_region_t *data, isc_buffer_t *sig, isc_mem_t *mctx)
{
isc_region_t r;
MD5_CTX *ctx = NULL;
isc_result_t ret;
if (mode & DST_SIGMODE_INIT) {
ctx = (MD5_CTX *) isc_mem_get(mctx, sizeof(MD5_CTX));
if (ctx == NULL)
return (DST_R_NOMEMORY);
}
else if (context != NULL)
ctx = (MD5_CTX *) *context;
REQUIRE (ctx != NULL);
if (mode & DST_SIGMODE_INIT) {
HMAC_Key *hkey = key->opaque;
MD5Init(ctx);
MD5Update(ctx, hkey->ipad, HMAC_LEN);
r.base = hkey->ipad;
r.length = HMAC_LEN;
RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx));
RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
}
if (mode & DST_SIGMODE_UPDATE) {
RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, data, NULL,
mctx));
}
if ((mode & DST_SIGMODE_UPDATE))
MD5Update(ctx, data->base, data->length);
if (mode & DST_SIGMODE_FINAL) {
HMAC_Key *hkey = key->opaque;
unsigned char digest[MD5_DIGEST_LENGTH];
isc_buffer_t b;
isc_buffer_available(sig, &r);
if (r.length < MD5_LEN)
return DST_R_NOSPACE;
MD5Final(r.base, ctx);
isc_buffer_init(&b, digest, sizeof(digest),
ISC_BUFFERTYPE_BINARY);
/* perform outer MD5 */
MD5Init(ctx);
MD5Update(ctx, hkey->opad, HMAC_LEN);
MD5Update(ctx, r.base, MD5_LEN);
MD5Final(r.base, ctx);
isc_buffer_add(sig, MD5_LEN);
RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, &b, mctx));
isc_mem_put(mctx, ctx, sizeof(MD5_CTX));
RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx));
r.base = hkey->opad;
r.length = HMAC_LEN;
RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
isc_buffer_used(&b, &r);
RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, sig, mctx));
}
else
*context = ctx;
return (DST_R_SUCCESS);
}
......@@ -189,49 +185,43 @@ static dst_result_t
dst_hmacmd5_verify(const unsigned int mode, dst_key_t *key, void **context,
isc_region_t *data, isc_region_t *sig, isc_mem_t *mctx)
{
MD5_CTX *ctx = NULL;
isc_region_t r;
isc_result_t ret;
if (mode & DST_SIGMODE_INIT) {
ctx = (MD5_CTX *) isc_mem_get(mctx, sizeof(MD5_CTX));
if (ctx == NULL)
return (DST_R_NOMEMORY);
}
else if (context != NULL)
ctx = (MD5_CTX *) *context;
REQUIRE (ctx != NULL);
if (mode & DST_SIGMODE_INIT) {
HMAC_Key *hkey = key->opaque;
MD5Init(ctx);
MD5Update(ctx, hkey->ipad, HMAC_LEN);
r.base = hkey->ipad;
r.length = HMAC_LEN;
RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx));
RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
}
if (mode & DST_SIGMODE_UPDATE) {
RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, data, NULL,
mctx));
}
if ((mode & DST_SIGMODE_UPDATE))
MD5Update(ctx, data->base, data->length);
if (mode & DST_SIGMODE_FINAL) {
u_char digest[MD5_LEN];
HMAC_Key *hkey = key->opaque;
unsigned char digest[MD5_DIGEST_LENGTH];
isc_buffer_t b;
if (sig->length < MD5_LEN)
return (DST_R_VERIFYFINALFAILURE);
MD5Final(digest, ctx);
isc_buffer_init(&b, digest, sizeof(digest),
ISC_BUFFERTYPE_BINARY);
/* perform outer MD5 */
MD5Init(ctx);
MD5Update(ctx, hkey->opad, HMAC_LEN);
MD5Update(ctx, digest, MD5_LEN);
MD5Final(digest, ctx);
RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, &b, mctx));
isc_mem_put(mctx, ctx, sizeof(MD5_CTX));
RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx));
r.base = hkey->opad;
r.length = HMAC_LEN;
RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
isc_buffer_used(&b, &r);
RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx));
isc_buffer_clear(&b);
RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, &b, mctx));
if (memcmp(digest, sig->base, MD5_LEN) != 0)
if (memcmp(digest, sig->base, MD5_DIGEST_LENGTH) != 0)
return (DST_R_VERIFYFINALFAILURE);
}
else
*context = ctx;
return (DST_R_SUCCESS);
}
......@@ -317,14 +307,14 @@ dst_hmacmd5_from_dns(dst_key_t *key, isc_buffer_t *data, isc_mem_t *mctx) {
if (r.length > HMAC_LEN) {
MD5_CTX ctx;
unsigned char digest[MD5_LEN];
unsigned char digest[MD5_DIGEST_LENGTH];
MD5Init(&ctx);
MD5Update(&ctx, r.base, r.length);
MD5Final(digest, &ctx);
memcpy(hkey->ipad, digest, MD5_LEN);
memcpy(hkey->opad, digest, MD5_LEN);
keylen = MD5_LEN;
memcpy(hkey->ipad, digest, MD5_DIGEST_LENGTH);
memcpy(hkey->opad, digest, MD5_DIGEST_LENGTH);
keylen = MD5_DIGEST_LENGTH;
}
else {
memcpy(hkey->ipad, r.base, r.length);
......
......@@ -36,6 +36,10 @@ typedef void * dst_context_t;
#define DST_ALG_EXPAND 255
#define DST_MAX_ALGS DST_ALG_HMACSHA1
/* DST algorithm codes */
#define DST_DIGEST_MD5 258
#define DST_DIGEST_SHA1 259
/* 'Mode' passed into dst_sign() and dst_verify() */
#define DST_SIGMODE_INIT 1 /* initialize digest */
#define DST_SIGMODE_UPDATE 2 /* add data to digest */
......@@ -96,6 +100,24 @@ dst_result_t
dst_verify(const unsigned int mode, dst_key_t *key, dst_context_t *context,
isc_region_t *data, isc_region_t *sig);
/* Digest a block of data.
*
* Requires:
* "mode" is some combination of DST_SIGMODE_INIT, DST_SIGMODE_UPDATE,
* and DST_SIGMODE_FINAL.
* "alg" is a valid digest algorithm
* "context" contains a value appropriate for the value of "mode".
* "data" is a valid region.
* "digest" is a valid buffer.
*
* Ensures:
* All allocated memory will be freed after the FINAL call. "digest"
* will contain a digest if all operations completed successfully.
*/
dst_result_t
dst_digest(const unsigned int mode, const unsigned int alg,
dst_context_t *context, isc_region_t *data, isc_buffer_t *digest);
/*
* dst_computesecret
* A function to compute a shared secret from two (Diffie-Hellman) keys.
......
#if defined(OPENSSL)
/*
* Portions Copyright (c) 1995-1998 by Network Associates, Inc.
*
* Permission to use, copy modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
*/
/*
* Principal Author: Brian Wellington
* $Id: opensslmd5_link.c,v 1.1 1999/10/18 21:35:46 bwelling Exp $
*/
#include <config.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <isc/assertions.h>
#include <isc/buffer.h>
#include <isc/int.h>
#include <isc/region.h>
#include "dst_internal.h"
#include "dst_parse.h"
#include <openssl/crypto.h>
#include <openssl/bn.h>
#include <openssl/md5.h>
#define MD5Init MD5_Init
#define MD5Update MD5_Update
#define MD5Final MD5_Final
/*
* dst_s_md5
* Call MD5 functions to digest a block of data.
* There are three steps to signing, INIT (initialize structures),
* UPDATE (hash (more) data), FINAL (generate a digest). This
* routine performs one or more of these steps.
* Parameters
* mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL}
* context the context to use for this computation
* data data to be signed
* digest buffer to store digest
* mctx memory context for temporary allocations
* Returns
* DST_R_SUCCESS Success
* !DST_R_SUCCESS Failure
*/
dst_result_t
dst_s_md5(const unsigned int mode, void **context, isc_region_t *data,
isc_buffer_t *digest, isc_mem_t *mctx)
{
isc_region_t r;
MD5_CTX *ctx = NULL;
if (mode & DST_SIGMODE_INIT) {
ctx = (MD5_CTX *) isc_mem_get(mctx, sizeof(MD5_CTX));
if (ctx == NULL)
return (DST_R_NOMEMORY);
}
else if (context != NULL)
ctx = (MD5_CTX *) *context;
REQUIRE (ctx != NULL);
if (mode & DST_SIGMODE_INIT)
MD5Init(ctx);
if (mode & DST_SIGMODE_UPDATE)
MD5Update(ctx, data->base, data->length);
if (mode & DST_SIGMODE_FINAL) {
isc_buffer_available(digest, &r);
if (r.length < MD5_DIGEST_LENGTH)
return DST_R_NOSPACE;
MD5Final(r.base, ctx);
isc_buffer_add(digest, MD5_DIGEST_LENGTH);
isc_mem_put(mctx, ctx, sizeof(MD5_CTX));
}
else
*context = ctx;
return (DST_R_SUCCESS);
}
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment