diff options
Diffstat (limited to 'contrib/bind/lib/dst')
-rw-r--r-- | contrib/bind/lib/dst/Makefile | 98 | ||||
-rw-r--r-- | contrib/bind/lib/dst/README | 27 | ||||
-rw-r--r-- | contrib/bind/lib/dst/bsafe_link.c | 1125 | ||||
-rw-r--r-- | contrib/bind/lib/dst/cylink_link.c | 676 | ||||
-rw-r--r-- | contrib/bind/lib/dst/dst_api.c | 1068 | ||||
-rw-r--r-- | contrib/bind/lib/dst/dst_internal.h | 163 | ||||
-rw-r--r-- | contrib/bind/lib/dst/eay_dss_link.c | 624 | ||||
-rw-r--r-- | contrib/bind/lib/dst/hmac_link.c | 493 | ||||
-rw-r--r-- | contrib/bind/lib/dst/md5.h | 101 | ||||
-rw-r--r-- | contrib/bind/lib/dst/md5_dgst.c | 368 | ||||
-rw-r--r-- | contrib/bind/lib/dst/md5_locl.h | 190 | ||||
-rw-r--r-- | contrib/bind/lib/dst/prandom.c | 853 | ||||
-rw-r--r-- | contrib/bind/lib/dst/rsaref_link.c | 755 | ||||
-rw-r--r-- | contrib/bind/lib/dst/support.c | 461 |
14 files changed, 0 insertions, 7002 deletions
diff --git a/contrib/bind/lib/dst/Makefile b/contrib/bind/lib/dst/Makefile deleted file mode 100644 index ffd9b17f8b06c..0000000000000 --- a/contrib/bind/lib/dst/Makefile +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (c) 1996,1999 by Internet Software Consortium -# -# 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS -# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE -# CONSORTIUM 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 THIS -# SOFTWARE. - -# $Id: Makefile,v 1.17 2000/07/11 06:41:39 vixie Exp $ - -# these are only appropriate for BSD 4.4 or derivatives, and are used in -# development. normal builds will be done in the top level directory and -# this Makefile will be invoked with a lot of overrides for the following: -SYSTYPE= bsdos -DESTDIR = -DESTLIB = /usr/local/lib -O=o -A=a -CC= cc -LD= ld -SHELL= /bin/sh -CDEBUG= -g -TOP= ../.. -INCL = ${TOP}/include -PORTINCL = ${TOP}/port/${SYSTYPE}/include -LIBBIND = ${TOP}/lib/libbind.${A} -LIBBINDR = ../${TOP}/lib/libbind_r.${A} -CFLAGS= ${CDEBUG} -CPPFLAGS= -I${PORTINCL} -I${INCL} -LD_LIBFLAGS= -x -r -AR= ar cru -RANLIB= ranlib -INSTALL= install -INSTALL_EXEC= -INSTALL_LIB=-o bin -g bin -THREADED= threaded - -HDRS= md5.h md5_locl.h - -SRCS= dst_api.c prandom.c rsaref_link.c support.c bsafe_link.c \ - cylink_link.c hmac_link.c md5_dgst.c eay_dss_link.c - -OBJS= dst_api.${O} prandom.${O} rsaref_link.${O} support.${O} \ - bsafe_link.${O} cylink_link.${O} hmac_link.${O} md5_dgst.${O} \ - eay_dss_link.${O} - -CRYPTINCL= -I../cylink -I../dnssafe -CRYPTFLAGS= -DCYLINK_DSS -DHMAC_MD5 -DUSE_MD5 -DDNSSAFE - -all: ${LIBBIND} - -${LIBBIND}: ${OBJS} - ( cd ${THREADED} ; \ - ${AR} ${LIBBINDR} ${ARPREF} ${OBJS} ${ARSUFF} ; \ - ${RANLIB} ${LIBBINDR} ) - ${AR} ${LIBBIND} ${ARPREF} ${OBJS} ${ARSUFF} - ${RANLIB} ${LIBBIND} - -.c.${O}: - if test ! -d ${THREADED} ; then mkdir ${THREADED} ; else true ; fi - ${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} ${CRYPTINCL} ${CRYPTFLAGS} -c $*.c -o ${THREADED}/$*.${O} - -${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} \ - -o ${THREADED}/$*.out && \ - ${LDS} mv ${THREADED}/$*.out ${THREADED}/$*.${O} - ${CC} ${CPPFLAGS} ${CFLAGS} ${CRYPTINCL} ${CRYPTFLAGS} -c $*.c - -${LDS} ${LD} ${LD_LIBFLAGS} $*.${O} -o $*.out && \ - ${LDS} mv $*.out $*.${O} - -$(SRCS):: $(HDRS) - -distclean: clean - -clean: FRC - rm -f .depend a.out core ${LIB} tags - rm -f *.${O} *.BAK *.CKP *~ - rm -f prand_conf.h - rm -f ${THREADED}/*.${O} - -if test -d ${THREADED} ; then rmdir ${THREADED}; else true; fi - -depend: FRC - mkdep -I${INCL} -I${PORTINCL} ${CPPFLAGS} ${SRCS} - -links: FRC - @set -e; ln -s SRC/*.[ch] SRC/*.pl . - -install: - -FRC: - -# DO NOT DELETE THIS LINE -- mkdep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. diff --git a/contrib/bind/lib/dst/README b/contrib/bind/lib/dst/README deleted file mode 100644 index 6283e589b6e10..0000000000000 --- a/contrib/bind/lib/dst/README +++ /dev/null @@ -1,27 +0,0 @@ -This directory in BIND contains the Domain Signature Tools (dst) -library. It was written by Trusted Information Systems, Inc. and -integrated into BIND by John Gilmore. It is used as a generic -crypto library interface by the DNS Security code in BIND. - - Installing Domain Signature Tools Library - dst - -1. Assess available crypto libraries: - - if you have DNSSAFE (the default) - CRYPTFLAGS must include -DDNSSAFE - CRYPTINCL must include -I../dnssafe - - if you have RSAREF - CRYPTFLAGS must include -DRSAREF - CRYPTINCL must include -I<path to rsa include files> - - if you have BSAFE - CRYPTFLAGS must include -DBSAFE - CRYPTINCL must include -I<path to bsafe include files> - - if you want HMAC-MD5 support - CRYPTFLAGs must include -DHMAC - -2. Building BIND as usual will include the dst library routines into - libbind.a, and link them into the BIND programs that use crypto - support. diff --git a/contrib/bind/lib/dst/bsafe_link.c b/contrib/bind/lib/dst/bsafe_link.c deleted file mode 100644 index 8b24d99fb971e..0000000000000 --- a/contrib/bind/lib/dst/bsafe_link.c +++ /dev/null @@ -1,1125 +0,0 @@ -#if defined(BSAFE) || defined(DNSSAFE) -static const char rcsid[] = "$Header: /proj/cvs/isc/bind/src/lib/dst/bsafe_link.c,v 1.11 1999/10/13 16:39:22 vixie Exp $"; - -/* - * Portions Copyright (c) 1995-1998 by Trusted Information Systems, 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 TRUSTED INFORMATION SYSTEMS - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * TRUSTED INFORMATION SYSTEMS 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. - */ -/* - * This file contains two components - * 1. Interface to the BSAFE library to allow compilation of Bind - * with TIS/DNSSEC when BSAFE is not available - * all calls to BSAFE are contained inside this file. - * 2. The glue to connvert RSA KEYS to and from external formats - */ -#include "port_before.h" - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <memory.h> -#include <sys/param.h> -#include <sys/time.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include "dst_internal.h" - -# ifdef __STDC__ -# define PROTOTYPES 1 -# else -# define PROTOTYPES 0 -# endif - -# ifdef BSAFE -# include <aglobal.h> -# include <bsafe.h> -# else -# include <global.h> -# include <bsafe2.h> -# include <bigmaxes.h> -# endif - -#include "port_after.h" - -typedef struct bsafekey { - char *rk_signer; - B_KEY_OBJ rk_Private_Key; - B_KEY_OBJ rk_Public_Key; -} RSA_Key; - -#ifndef MAX_RSA_MODULUS_BITS -#define MAX_RSA_MODULUS_BITS 4096 -#define MAX_RSA_MODULUS_LEN (MAX_RSA_MODULUS_BITS/8) -#define MAX_RSA_PRIME_LEN (MAX_RSA_MODULUS_LEN/2) -#endif - -#define NULL_SURRENDER (A_SURRENDER_CTX *)NULL_PTR -#define NULL_RANDOM (B_ALGORITHM_OBJ)NULL_PTR - -B_ALGORITHM_METHOD *CHOOSER[] = -{ - &AM_MD5, - &AM_MD5_RANDOM, - &AM_RSA_KEY_GEN, - &AM_RSA_ENCRYPT, - &AM_RSA_DECRYPT, - &AM_RSA_CRT_ENCRYPT, - &AM_RSA_CRT_DECRYPT, - (B_ALGORITHM_METHOD *) NULL_PTR -}; - -static u_char pkcs1[] = -{ - 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, - 0x04, 0x10 -}; - -static int dst_bsafe_md5digest(const int mode, B_ALGORITHM_OBJ *digest_obj, - const u_char *data, const int len, - u_char *digest, const int digest_len); - -static int dst_bsafe_key_size(RSA_Key *r_key); - -static int dst_bsafe_sign(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - u_char *signature, const int sig_len); -static int dst_bsafe_verify(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - const u_char *signature, const int sig_len); -static int dst_bsafe_to_dns_key(const DST_KEY *in_key, u_char *out_str, - const int out_len); -static int dst_bsafe_from_dns_key(DST_KEY *s_key, const u_char *key, - const int len); -static int dst_bsafe_key_to_file_format(const DST_KEY *key, char *buff, - const int buff_len); -static int dst_bsafe_key_from_file_format(DST_KEY *d_key, - const char *buff, - const int buff_len); -static int dst_bsafe_generate_keypair(DST_KEY *key, int exp); -static int dst_bsafe_compare_keys(const DST_KEY *key1, const DST_KEY *key2); -static void *dst_bsafe_free_key_structure(void *key); - -/* - * dst_bsafe_init() Function to answer set up function pointers for - * BSAFE/DNSSAFE related functions - */ -int -dst_bsafe_init() -{ - if (dst_t_func[KEY_RSA] != NULL) - return (1); - dst_t_func[KEY_RSA] = malloc(sizeof(struct dst_func)); - if (dst_t_func[KEY_RSA] == NULL) - return (0); - memset(dst_t_func[KEY_RSA], 0, sizeof(struct dst_func)); - dst_t_func[KEY_RSA]->sign = dst_bsafe_sign; - dst_t_func[KEY_RSA]->verify = dst_bsafe_verify; - dst_t_func[KEY_RSA]->compare = dst_bsafe_compare_keys; - dst_t_func[KEY_RSA]->generate = dst_bsafe_generate_keypair; - dst_t_func[KEY_RSA]->destroy = dst_bsafe_free_key_structure; - dst_t_func[KEY_RSA]->from_dns_key = dst_bsafe_from_dns_key; - dst_t_func[KEY_RSA]->to_dns_key = dst_bsafe_to_dns_key; - dst_t_func[KEY_RSA]->from_file_fmt = dst_bsafe_key_from_file_format; - dst_t_func[KEY_RSA]->to_file_fmt = dst_bsafe_key_to_file_format; - return (1); -} - -/* - * dst_bsafe_sign - * Call BSAFE signing functions to sign a block of data. - * There are three steps to signing, INIT (initialize structures), - * UPDATE (hash (more) data), FINAL (generate a signature). This - * routine performs one or more of these steps. - * Parameters - * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL. - * dkey structure holds context for a sign done in multiple calls. - * context the context to use for this computation - * data data to be signed. - * len length in bytes of data. - * priv_key key to use for signing. - * signature location to store signature. - * sig_len size in bytes of signature field. - * returns - * N Success on SIG_MODE_FINAL = returns signature length in bytes - * 0 Success on SIG_MODE_INIT and UPDATE - * <0 Failure - */ - -static int -dst_bsafe_sign(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - u_char *signature, const int sig_len) -{ - u_int sign_len = 0; - int status = 0; - B_ALGORITHM_OBJ *md5_ctx = NULL; - int w_bytes = 0; - u_int u_bytes = 0; - u_char work_area[NS_MD5RSA_MAX_SIZE]; - - if (mode & SIG_MODE_INIT) { - md5_ctx = (B_ALGORITHM_OBJ *) malloc(sizeof(B_ALGORITHM_OBJ)); - if ((status = B_CreateAlgorithmObject(md5_ctx))) - return (-1); - if ((status = B_SetAlgorithmInfo(*md5_ctx, AI_MD5, NULL))) - return (-1); - } - else if (context) - md5_ctx = (B_ALGORITHM_OBJ *) *context; - if (md5_ctx == NULL) - return (-1); - - w_bytes = dst_bsafe_md5digest(mode, md5_ctx, - data, len,work_area, sizeof(work_area)); - if (w_bytes < 0 || (mode & SIG_MODE_FINAL)) { - B_DestroyAlgorithmObject(md5_ctx); - SAFE_FREE(md5_ctx); - if (w_bytes < 0) - return (w_bytes); - } - - if (mode & SIG_MODE_FINAL) { - RSA_Key *key; - int ret = 0; - B_ALGORITHM_OBJ rsaEncryptor = (B_ALGORITHM_OBJ) NULL_PTR; - - if (dkey == NULL || dkey->dk_KEY_struct == NULL) - return (-1); - key = (RSA_Key *) dkey->dk_KEY_struct; - if (key == NULL || key->rk_Private_Key == NULL) - return (-1); - - if ((status = B_CreateAlgorithmObject(&rsaEncryptor))) - return (SIGN_FINAL_FAILURE); - if ((status = B_SetAlgorithmInfo(rsaEncryptor, - AI_PKCS_RSAPrivate, - NULL_PTR))) - - ret = SIGN_FINAL_FAILURE; - if (ret == 0 && - (status = B_EncryptInit(rsaEncryptor, - key->rk_Private_Key, - CHOOSER, NULL_SURRENDER))) - ret = SIGN_FINAL_FAILURE; - if (ret == 0 && - (status = B_EncryptUpdate(rsaEncryptor, signature, - &u_bytes, sig_len, pkcs1, - sizeof(pkcs1), NULL_PTR, - NULL_SURRENDER))) - ret = SIGN_FINAL_FAILURE; - if (ret == 0 && - (status = B_EncryptUpdate(rsaEncryptor, signature, - &u_bytes, sig_len, work_area, - w_bytes, NULL_PTR, - NULL_SURRENDER))) - ret = SIGN_FINAL_FAILURE; - - if (ret == 0 && - (status = B_EncryptFinal(rsaEncryptor, signature + u_bytes, - &sign_len, sig_len - u_bytes, - NULL_PTR, NULL_SURRENDER))) - ret = SIGN_FINAL_FAILURE; - B_DestroyAlgorithmObject(&rsaEncryptor); - if (ret != 0) - return (ret); - - } - else { - if (context == NULL) - return (-1); - *context = (void *) md5_ctx; - } - return (sign_len); -} - - -/* - * Dst_bsafe_verify - * Calls BSAFE verification routines. There are three steps to - * verification, INIT (initialize structures), UPDATE (hash (more) data), - * FINAL (generate a signature). This routine performs one or more of - * these steps. - * Parameters - * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL. - * dkey structure holds context for a verify done in multiple calls. - * context the context to use for this computation - * data data signed. - * len length in bytes of data. - * pub_key key to use for verify. - * signature signature. - * sig_len length in bytes of signature. - * returns - * 0 Success - * <0 Failure - */ - -static int -dst_bsafe_verify(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - const u_char *signature, const int sig_len) -{ - B_ALGORITHM_OBJ *md5_ctx = NULL; - u_char digest[DST_HASH_SIZE]; - u_char work_area[DST_HASH_SIZE + sizeof(pkcs1)]; - int status = 0, w_bytes = 0; - u_int u_bytes = 0; - - if (mode & SIG_MODE_INIT) { - md5_ctx = (B_ALGORITHM_OBJ *) malloc(sizeof(B_ALGORITHM_OBJ)); - if ((status = B_CreateAlgorithmObject(md5_ctx))) - return (-1); - if ((status = B_SetAlgorithmInfo(*md5_ctx, AI_MD5, NULL))) - return (-1); - } - else if (context) - md5_ctx = (B_ALGORITHM_OBJ *) *context; - if (md5_ctx == NULL) - return (-1); - - w_bytes = dst_bsafe_md5digest(mode, md5_ctx, data, len, - digest, sizeof(digest)); - - if (w_bytes < 0 || (mode & SIG_MODE_FINAL)) { - B_DestroyAlgorithmObject(md5_ctx); - SAFE_FREE(md5_ctx); - if (w_bytes < 0) - return (-1); - } - - if (mode & SIG_MODE_FINAL) { - RSA_Key *key; - int ret = 0; - B_ALGORITHM_OBJ rsaEncryptor = (B_ALGORITHM_OBJ) NULL_PTR; - - if (dkey == NULL || dkey->dk_KEY_struct == NULL) - return (-1); - key = (RSA_Key *) dkey->dk_KEY_struct; - if (key->rk_Public_Key == NULL) - return (-2); - if (rsaEncryptor == NULL_PTR) { - if ((status = B_CreateAlgorithmObject(&rsaEncryptor))) - ret = SIGN_FINAL_FAILURE; - if (ret == 0 && - (status = B_SetAlgorithmInfo(rsaEncryptor, - AI_PKCS_RSAPublic, - NULL_PTR))) - ret = VERIFY_FINAL_FAILURE; - } - if (ret == 0 && - (status = B_DecryptInit(rsaEncryptor, key->rk_Public_Key, - CHOOSER, NULL_SURRENDER))) - ret = VERIFY_FINAL_FAILURE; - - if (ret == 0 && - (status = B_DecryptUpdate(rsaEncryptor, work_area, - &u_bytes, 0, - (u_char *) signature, sig_len, - NULL_PTR, NULL_SURRENDER))) - ret = VERIFY_FINAL_FAILURE; - - if (ret == 0 && - (status = B_DecryptFinal(rsaEncryptor, work_area + u_bytes, - &u_bytes, - sizeof(work_area) - u_bytes, - NULL_PTR, NULL_SURRENDER))) - ret = VERIFY_FINAL_FAILURE; - B_DestroyAlgorithmObject(&rsaEncryptor); - /* skip PKCS#1 header in output from Decrypt function */ - if (ret) - return (ret); - ret = memcmp(digest, &work_area[sizeof(pkcs1)], w_bytes); - if (ret == 0) - return(0); - else - return(VERIFY_FINAL_FAILURE); - } - else { - if (context == NULL) - return (-1); - *context = (void *) md5_ctx; - } - return (0); -} - - -/* - * dst_bsafe_to_dns_key - * Converts key from RSA to DNS distribution format - * This function gets in a pointer to the public key and a work area - * to write the key into. - * Parameters - * public KEY structure - * out_str buffer to write encoded key into - * out_len size of out_str - * Return - * N >= 0 length of encoded key - * n < 0 error - */ - -static int -dst_bsafe_to_dns_key(const DST_KEY *in_key, u_char *out_str, - const int out_len) -{ - B_KEY_OBJ public; - A_RSA_KEY *pub = NULL; - u_char *op = out_str; - int n = 0; - - if (in_key == NULL || in_key->dk_KEY_struct == NULL || - out_len <= 0 || out_str == NULL) - return (-1); - public = (B_KEY_OBJ)((RSA_Key *) in_key->dk_KEY_struct)->rk_Public_Key; - - n = B_GetKeyInfo((POINTER *) &pub, public, KI_RSAPublic); - - if (out_len < pub->exponent.len) /* not enough space */ - return (-1); - if (pub->exponent.len < 256) /* key exponent is <= 2040 bits */ - *op++ = (u_int8_t) pub->exponent.len; - else { /* key exponent is > 2040 bits */ - u_int16_t e = (u_int16_t) pub->exponent.len; - *op++ = 0; /* 3 byte lenght field */ - dst_s_put_int16(op, e); - op += sizeof(e); - n = 2; - } - n += pub->exponent.len; - memcpy(op, pub->exponent.data, n); - op += n; - n++; - - if ((out_len - n) > pub->modulus.len) { - /*copy exponent */ - memcpy(op, pub->modulus.data, pub->modulus.len); - n += pub->modulus.len; - } - else - n = -1; - return (n); -} - - -/* - * dst_bsafe_from_dns_key - * Converts from a DNS KEY RR format to an RSA KEY. - * Parameters - * len Length in bytes of DNS key - * key DNS key - * name Key name - * s_key DST structure that will point to the RSA key this routine - * will build. - * Return - * 0 The input key, s_key or name was null. - * 1 Success - */ -static int -dst_bsafe_from_dns_key(DST_KEY *s_key, const u_char *key, const int len) -{ - int bytes; - const u_char *key_ptr; - RSA_Key *r_key; - A_RSA_KEY *public; - - if (s_key == NULL || len < 0 || key == NULL) - return (0); - - r_key = (RSA_Key *) s_key->dk_KEY_struct; - if (r_key != NULL) /* do not reuse */ - s_key->dk_func->destroy(r_key); - - if (len == 0) - return (1); - - if ((r_key = (RSA_Key *) malloc(sizeof(RSA_Key))) == NULL) { - EREPORT(("dst_bsafe_from_dns_key(): Memory allocation error 1")); - return (0); - } - memset(r_key, 0, sizeof(RSA_Key)); - s_key->dk_KEY_struct = (void *) r_key; - r_key->rk_signer = strdup(s_key->dk_key_name); - - if (B_CreateKeyObject(&r_key->rk_Public_Key) != 0) { - EREPORT(("dst_bsafe_from_dns_key(): Memory allocation error 3")); - s_key->dk_func->destroy(r_key); - return (0); - } - key_ptr = key; - bytes = (int) *key_ptr++; /* length of exponent in bytes */ - if (bytes == 0) { /* special case for long exponents */ - bytes = (int) dst_s_get_int16(key_ptr); - key_ptr += sizeof(u_int16_t); - } - if (bytes > MAX_RSA_MODULUS_LEN) { - dst_bsafe_free_key_structure(r_key); - return (-1); - } - if ((public = (A_RSA_KEY *) malloc(sizeof(A_RSA_KEY))) == NULL) - return (0); - memset(public, 0, sizeof(*public)); - public->exponent.len = bytes; - if ((public->exponent.data = (u_char *) malloc(bytes)) == NULL) - return (0); - memcpy(public->exponent.data, key_ptr, bytes); - - key_ptr += bytes; /* beginning of modulus */ - bytes = len - bytes - 1; /* length of modulus */ - - if (bytes > MAX_RSA_MODULUS_LEN) { - dst_bsafe_free_key_structure(r_key); - return (-1); - } - public->modulus.len = bytes; - if ((public->modulus.data = (u_char *) malloc(bytes)) == NULL) - return (0); - memcpy(public->modulus.data, key_ptr, bytes); - - B_SetKeyInfo(r_key->rk_Public_Key, KI_RSAPublic, (POINTER) public); - - s_key->dk_id = (u_int16_t) - dst_s_get_int16(&public->modulus.data[public->modulus.len - 3]); - s_key->dk_key_size = dst_bsafe_key_size(r_key); - SAFE_FREE(public->modulus.data); - SAFE_FREE(public->exponent.data); - SAFE_FREE(public); - return (1); -} - - -/* - * dst_bsafe_key_to_file_format - * Encodes an RSA Key into the portable file format. - * Parameters - * rkey RSA KEY structure - * buff output buffer - * buff_len size of output buffer - * Return - * 0 Failure - null input rkey - * -1 Failure - not enough space in output area - * N Success - Length of data returned in buff - */ - -static int -dst_bsafe_key_to_file_format(const DST_KEY *key, char *buff, - const int buff_len) -{ - char *bp; - int len, b_len; - B_KEY_OBJ rkey; - A_PKCS_RSA_PRIVATE_KEY *private = NULL; - - if (key == NULL || key->dk_KEY_struct == NULL) /* no output */ - return (0); - if (buff == NULL || buff_len <= (int) strlen(key_file_fmt_str)) - return (-1); /* no OR not enough space in output area */ - - rkey = (B_KEY_OBJ)((RSA_Key *) key->dk_KEY_struct)->rk_Private_Key; - - B_GetKeyInfo((POINTER *) &private, rkey, KI_PKCS_RSAPrivate); - - memset(buff, 0, buff_len); /* just in case */ - /* write file header */ - sprintf(buff, key_file_fmt_str, KEY_FILE_FORMAT, KEY_RSA, "RSA"); - - bp = strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Modulus: ", - private->modulus.data, - private->modulus.len)) <= 0) - return (-1); - - bp += len; - b_len -= len; - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "PublicExponent: ", - private->publicExponent.data, - private->publicExponent.len)) <= 0) - return (-2); - - bp += len; - b_len -= len; - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "PrivateExponent: ", - private->privateExponent.data, - private->privateExponent.len)) <= 0) - return (-3); - bp += len; - b_len -= len; - - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Prime1: ", - private->prime[0].data, - private->prime[0].len)) < 0) - return (-4); - bp += len; - b_len -= len; - - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Prime2: ", - private->prime[1].data, - private->prime[1].len)) < 0) - return (-5); - bp += len; - b_len -= len; - - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Exponent1: ", - private->primeExponent[0].data, - private->primeExponent[0].len)) < 0) - return (-6); - bp += len; - b_len -= len; - - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Exponent2: ", - private->primeExponent[1].data, - private->primeExponent[1].len)) < 0) - return (-7); - bp += len; - b_len -= len; - - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Coefficient: ", - private->coefficient.data, - private->coefficient.len)) < 0) - return (-8); - bp += len; - b_len -= len; - return (buff_len - b_len); -} - - -/* - * dst_bsafe_key_from_file_format - * Converts contents of a private key file into a private RSA key. - * Parameters - * RSA_Key structure to put key into - * buff buffer containing the encoded key - * buff_len the length of the buffer - * Return - * n >= 0 Foot print of the key converted - * n < 0 Error in conversion - */ - -static int -dst_bsafe_key_from_file_format(DST_KEY *d_key, const char *buff, - const int buff_len) -{ - int status; - char s[RAW_KEY_SIZE]; - int len, s_len = sizeof(s); - int tag = -1; - const char *p = buff; - RSA_Key *b_key; - A_RSA_KEY *public; - A_PKCS_RSA_PRIVATE_KEY *private; - - if (d_key == NULL || buff == NULL || buff_len <= 0) - return (-1); - - b_key = (RSA_Key *) malloc(sizeof(RSA_Key)); - public = (A_RSA_KEY *) malloc(sizeof(A_RSA_KEY)); - private = (A_PKCS_RSA_PRIVATE_KEY *) - malloc(sizeof(A_PKCS_RSA_PRIVATE_KEY)); - if (b_key == NULL || private == NULL || public == NULL) { - SAFE_FREE(b_key); - SAFE_FREE(public); - SAFE_FREE(private); - return (-2); - } - memset(b_key, 0, sizeof(*b_key)); - memset(public, 0, sizeof(A_RSA_KEY)); - memset(private, 0, sizeof(A_PKCS_RSA_PRIVATE_KEY)); - d_key->dk_KEY_struct = (void *) b_key; - if (!dst_s_verify_str(&p, "Modulus: ")) - return (-3); - memset(s, 0, s_len); - if ((len = dst_s_conv_bignum_b64_to_u8(&p, (u_char *)s, s_len)) == 0) - return (-4); - - private->modulus.len = len; - if ((private->modulus.data = malloc(len)) == NULL) - return (-5); - memcpy(private->modulus.data, s + s_len - len, len); - - while (*(++p) && p < (const char *) &buff[buff_len]) { - if (dst_s_verify_str(&p, "PublicExponent: ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, (u_char *)s, s_len))) - return (-5); - private->publicExponent.len = len; - if ((private->publicExponent.data = malloc(len)) - == NULL) - return (-6); - memcpy(private->publicExponent.data, - s + s_len - len, len); - } else if (dst_s_verify_str(&p, "PrivateExponent: ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, (u_char *)s, s_len))) - return (-6); - private->privateExponent.len = len; - if ((private->privateExponent.data = malloc(len)) - == NULL) - return (-7); - memcpy(private->privateExponent.data, s + s_len - len, - len); - } else if (dst_s_verify_str(&p, "Prime1: ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, (u_char *)s, - MAX_RSA_PRIME_LEN))) - return (-7); - private->prime[0].len = len; - if ((private->prime[0].data = malloc(len)) == NULL) - return (-8); - memcpy(private->prime[0].data, - s + MAX_RSA_PRIME_LEN - len, len); - } else if (dst_s_verify_str(&p, "Prime2: ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, (u_char *)s, - MAX_RSA_PRIME_LEN))) - return (-8); - private->prime[1].len = len; - if ((private->prime[1].data = malloc(len)) == NULL) - return (-9); - memcpy(private->prime[1].data, - s + MAX_RSA_PRIME_LEN - len, len); - } else if (dst_s_verify_str(&p, "Exponent1: ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, (u_char *)s, - MAX_RSA_PRIME_LEN))) - return (-9); - private->primeExponent[0].len = len; - if ((private->primeExponent[0].data = malloc(len)) - == NULL) - return (-10); - memcpy(private->primeExponent[0].data, - s + MAX_RSA_PRIME_LEN - len, len); - } else if (dst_s_verify_str(&p, "Exponent2: ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, (u_char *)s, - MAX_RSA_PRIME_LEN))) - return (-10); - private->primeExponent[1].len = len; - if ((private->primeExponent[1].data = malloc(len)) - == NULL) - return (-11); - memcpy(private->primeExponent[1].data, - s + MAX_RSA_PRIME_LEN - len, len); - } else if (dst_s_verify_str(&p, "Coefficient: ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, (u_char *)s, - MAX_RSA_PRIME_LEN))) - return (-11); - private->coefficient.len = len; - if ((private->coefficient.data = malloc(len)) == NULL) - return (-12); - memcpy(private->coefficient.data, - s + MAX_RSA_PRIME_LEN - len, len); - } else { - EREPORT(("Decode_RSAKey(): Bad keyword %s\n", p)); - return (-12); - } - } /* while p */ - - public->modulus.len = private->modulus.len; - if ((public->modulus.data = (u_char *) malloc(public->modulus.len)) == - NULL) - return (-13); - memcpy(public->modulus.data, private->modulus.data, - private->modulus.len); - - public->exponent.len = private->publicExponent.len; - if ((public->exponent.data = (u_char *) malloc(public->exponent.len)) - == NULL) - return (-14); - memcpy(public->exponent.data, private->publicExponent.data, - private->publicExponent.len); - - status = B_CreateKeyObject(&(b_key->rk_Public_Key)); - if (status) - return (-1); - status = B_SetKeyInfo(b_key->rk_Public_Key, KI_RSAPublic, - (POINTER) public); - if (status) - return (-1); - - status = B_CreateKeyObject(&b_key->rk_Private_Key); - if (status) - return (-1); - status = B_SetKeyInfo(b_key->rk_Private_Key, KI_PKCS_RSAPrivate, - (POINTER) private); - if (status) - return (-1); - - tag = (int)(u_int16_t) - dst_s_get_int16(&public->modulus.data[public->modulus.len - 3]); - d_key->dk_key_size = dst_bsafe_key_size(b_key); - - SAFE_FREE(private->modulus.data); - SAFE_FREE(private->publicExponent.data); - SAFE_FREE(private->privateExponent.data); - SAFE_FREE(private->prime[0].data); - SAFE_FREE(private->prime[1].data); - SAFE_FREE(private->primeExponent[0].data); - SAFE_FREE(private->primeExponent[1].data); - SAFE_FREE(private->coefficient.data); - SAFE_FREE(private); /* is this the right thing to do ??? XXXX */ - SAFE_FREE(public->modulus.data); - SAFE_FREE(public->exponent.data); - SAFE_FREE(public); - return (tag); -} - - -/* - * dst_bsafe_free_key_structure - * Frees all dynamicly allocated structures in RSA_Key. - */ - -static void * -dst_bsafe_free_key_structure(void *key) -{ - RSA_Key *r_key = (RSA_Key *) key; - if (r_key != NULL) { - if (r_key->rk_Private_Key) - B_DestroyKeyObject(&r_key->rk_Private_Key); - if (r_key->rk_Public_Key) - B_DestroyKeyObject(&r_key->rk_Public_Key); - SAFE_FREE2(r_key->rk_signer, strlen(r_key->rk_signer)); - SAFE_FREE(r_key); - } - return (NULL); -} - - -/* - * dst_bsafe_generate_keypair - * Generates unique keys that are hard to predict. - * Parameters - * key generic Key structure - * exp the public exponent - * Return - * 0 Failure - * 1 Success - */ - -static int -dst_bsafe_generate_keypair(DST_KEY *key, int exp) -{ - int i, status; - B_KEY_OBJ private; - B_KEY_OBJ public; - B_ALGORITHM_OBJ keypairGenerator; - B_ALGORITHM_OBJ randomAlgorithm; - A_RSA_KEY_GEN_PARAMS keygenParams; - char exponent[4]; - int exponent_len; - RSA_Key *rsa; - POINTER randomSeed = NULL_PTR; - int randomSeedLen; - A_RSA_KEY *pk_access = NULL; - - if (key == NULL || key->dk_alg != KEY_RSA) - return (0); - - if ((rsa = (RSA_Key *) malloc(sizeof(RSA_Key))) == NULL) { - EREPORT(("dst_bsafe_generate_keypair: Memory allocation error 3")); - return (0); - } - memset(rsa, 0, sizeof(*rsa)); - - if ((status = B_CreateAlgorithmObject(&keypairGenerator)) != 0) - return (0); - - keygenParams.modulusBits = key->dk_key_size; - - /* exp = 0 or 1 are special (mean 3 or F4) */ - if (exp == 0) - exp = 3; - else if (exp == 1) - exp = 65537; - - /* Now encode the exponent and its length */ - if (exp < 256) { - exponent_len = 1; - exponent[0] = exp; - } else if (exp < (1 << 16)) { - exponent_len = 2; - exponent[0] = exp >> 8; - exponent[1] = exp; - } else if (exp < (1 << 24)) { - exponent_len = 3; - exponent[0] = exp >> 16; - exponent[1] = exp >> 8; - exponent[2] = exp; - } else { - exponent_len = 4; - exponent[0] = exp >> 24; - exponent[1] = exp >> 16; - exponent[2] = exp >> 8; - exponent[3] = exp; - } - - if ((keygenParams.publicExponent.data = (u_char *) malloc(exponent_len)) - == NULL) - return (0); - memcpy(keygenParams.publicExponent.data, exponent, exponent_len); - keygenParams.publicExponent.len = exponent_len; - if ((status = B_SetAlgorithmInfo - (keypairGenerator, AI_RSAKeyGen, (POINTER) &keygenParams)) != 0) - return (0); - - if ((status = B_GenerateInit(keypairGenerator, CHOOSER, - NULL_SURRENDER)) != 0) - return (0); - - if ((status = B_CreateKeyObject(&public)) != 0) - return (0); - - if ((status = B_CreateKeyObject(&private)) != 0) - return (0); - - if ((status = B_CreateAlgorithmObject(&randomAlgorithm)) != 0) - return (0); - - if ((status = B_SetAlgorithmInfo(randomAlgorithm, AI_MD5Random, - NULL_PTR)) - != 0) - return (0); - - if ((status = B_RandomInit(randomAlgorithm, CHOOSER, - NULL_SURRENDER)) != 0) - return (0); - - randomSeedLen = 256; - if ((randomSeed = malloc(randomSeedLen)) == NULL) - return (0); - if ((status = (randomSeed == NULL_PTR)) != 0) - return (0); - - /* gets random seed from /dev/random if present, generates random - * values if it is not present. - * first fill the buffer with semi random data - * then fill as much as possible with good random data - */ - i = dst_random(DST_RAND_SEMI, randomSeedLen, randomSeed); - i += dst_random(DST_RAND_KEY, randomSeedLen, randomSeed); - - if (i <= randomSeedLen) { - SAFE_FREE(rsa); - return(0); - } - if ((status = B_RandomUpdate(randomAlgorithm, randomSeed, - randomSeedLen, NULL_SURRENDER)) != 0) { - SAFE_FREE(rsa); - return (0); - } - SAFE_FREE2(randomSeed, randomSeedLen); - if ((status = B_GenerateKeypair(keypairGenerator, public, private, - randomAlgorithm, NULL_SURRENDER)) - != 0) { - SAFE_FREE(rsa); - return (0); - } - rsa->rk_signer = strdup(key->dk_key_name); - rsa->rk_Private_Key = private; - rsa->rk_Public_Key = public; - key->dk_KEY_struct = (void *) rsa; - - /* fill in the footprint on generate key */ - B_GetKeyInfo((POINTER *) &pk_access, public, KI_RSAPublic); - key->dk_id = (u_int16_t) - dst_s_get_int16(&pk_access->modulus.data[pk_access->modulus.len - 3]); - return (1); -} - - -/************************************************************************** - * dst_bsafe_compare_keys - * Compare two keys for equality. - * Return - * 0 The keys are equal - * NON-ZERO The keys are not equal - */ - -static int -dst_s_bsafe_itemcmp(ITEM i1, ITEM i2) -{ - if (i1.len != i2.len || memcmp (i1.data, i2.data, i1.len)) - return (1); - else - return (0); -} - -static int -dst_bsafe_compare_keys(const DST_KEY *key1, const DST_KEY *key2) -{ - int status, s1 = 0, s2 = 0; - RSA_Key *rkey1 = (RSA_Key *) key1->dk_KEY_struct; - RSA_Key *rkey2 = (RSA_Key *) key2->dk_KEY_struct; - A_RSA_KEY *public1 = NULL, *public2 = NULL; - A_PKCS_RSA_PRIVATE_KEY *p1 = NULL, *p2 = NULL; - - if (rkey1 == NULL && rkey2 == NULL) - return(0); - else if (rkey1 == NULL) - return (1); - else if (rkey2 == NULL) - return (2); - - if (rkey1->rk_Public_Key) - B_GetKeyInfo((POINTER *) &public1, rkey1->rk_Public_Key, - KI_RSAPublic); - if (rkey2->rk_Public_Key) - B_GetKeyInfo((POINTER *) &public2, rkey2->rk_Public_Key, - KI_RSAPublic); - if (public1 == NULL && public2 == NULL) - return (0); - else if (public1 == NULL || public2 == NULL) - return (1); - - status = dst_s_bsafe_itemcmp(public1->modulus, public2->modulus) || - dst_s_bsafe_itemcmp(public1->exponent, public2->exponent); - - if (status) - return (status); - - if (rkey1->rk_Private_Key == NULL || rkey2->rk_Private_Key == NULL) - /* if neither or only one is private key consider identical */ - return (status); - if (rkey1->rk_Private_Key) - s1 = B_GetKeyInfo((POINTER *) &p1, rkey1->rk_Private_Key, - KI_PKCS_RSAPrivate); - if (rkey2->rk_Private_Key) - s2 = B_GetKeyInfo((POINTER *) &p2, rkey2->rk_Private_Key, - KI_PKCS_RSAPrivate); - if (p1 == NULL || p2 == NULL) - return (0); - - status = dst_s_bsafe_itemcmp(p1->modulus, p2->modulus) || - dst_s_bsafe_itemcmp (p1->publicExponent, - p2->publicExponent) || - dst_s_bsafe_itemcmp (p1->privateExponent, - p2->privateExponent) || - dst_s_bsafe_itemcmp (p1->prime[0], p2->prime[0]) || - dst_s_bsafe_itemcmp (p1->prime[1], p2->prime[1]) || - dst_s_bsafe_itemcmp (p1->primeExponent[0], - p2->primeExponent[0])|| - dst_s_bsafe_itemcmp (p1->primeExponent[1], - p2->primeExponent[1])|| - dst_s_bsafe_itemcmp (p1->coefficient, p2->coefficient); - return (status); -} - - -/* - * dst_bsafe_key_size() - * Function to calculate how the size of the key in bits - */ -static int -dst_bsafe_key_size(RSA_Key *r_key) -{ - int size; - A_PKCS_RSA_PRIVATE_KEY *private = NULL; - - if (r_key == NULL) - return (-1); - if (r_key->rk_Private_Key) - B_GetKeyInfo((POINTER *) &private, r_key->rk_Private_Key, - KI_PKCS_RSAPrivate); - else if (r_key->rk_Public_Key) - B_GetKeyInfo((POINTER *) &private, r_key->rk_Public_Key, - KI_RSAPublic); - size = dst_s_calculate_bits(private->modulus.data, - private->modulus.len * 8); - return (size); -} - -/* - * dst_bsafe_md5digest(): function to digest data using MD5 digest function - * if needed - */ -static int -dst_bsafe_md5digest(const int mode, B_ALGORITHM_OBJ *digest_obj, - const u_char *data, const int len, - u_char *digest, const int digest_len) -{ - int status = 0; - u_int work_size = 0; - - if (digest_obj == NULL || *digest_obj == NULL) { - printf("NO digest obj\n"); - exit(-33); - } - - if ((mode & SIG_MODE_INIT) && - (status = B_DigestInit(*digest_obj, (B_KEY_OBJ) NULL, - CHOOSER, NULL_SURRENDER))) - return (SIGN_INIT_FAILURE); - - if ((mode & SIG_MODE_UPDATE) && data && (len > 0) && - (status = B_DigestUpdate(*digest_obj, (u_char *) data, len, - NULL_SURRENDER))) - return (SIGN_UPDATE_FAILURE); - - if (mode & SIG_MODE_FINAL) { - if (digest == NULL || - (status = B_DigestFinal(*digest_obj, digest, &work_size, - digest_len, NULL_SURRENDER))) - return (SIGN_FINAL_FAILURE); - return (work_size); - } - return (0); -} - -/* - * just use the standard memory functions for bsafe - */ -void -T_free(POINTER block) -{ - free(block); -} - -POINTER -T_malloc(unsigned int len) -{ - return (malloc(len)); -} - -int -T_memcmp(POINTER firstBlock, POINTER secondBlock, unsigned int len) -{ - return (memcmp(firstBlock, secondBlock, len)); -} - -void -T_memcpy(POINTER output, POINTER input, unsigned int len) -{ - memcpy(output, input, len); -} - -void -T_memmove(POINTER output, POINTER input, unsigned int len) -{ - memmove(output, input, len); -} - -void -T_memset(POINTER output, int value, unsigned int len) -{ - memset(output, value, len); -} - -POINTER -T_realloc(POINTER block, unsigned int len) -{ - return (realloc(block, len)); -} - -#else /* BSAFE NOT available */ -int -dst_bsafe_init() -{ - return (0); -} -#endif /* BSAFE */ diff --git a/contrib/bind/lib/dst/cylink_link.c b/contrib/bind/lib/dst/cylink_link.c deleted file mode 100644 index c7cb2767410b6..0000000000000 --- a/contrib/bind/lib/dst/cylink_link.c +++ /dev/null @@ -1,676 +0,0 @@ -#ifdef CYLINK_DSS -static const char rcsid[] = "$Header: /proj/cvs/isc/bind/src/lib/dst/cylink_link.c,v 1.7 1999/10/13 16:39:22 vixie Exp $"; - -/* - * Portions Copyright (c) 1995-1998 by Trusted Information Systems, 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 TRUSTED INFORMATION SYSTEMS - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * TRUSTED INFORMATION SYSTEMS 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. - */ -/* - * This file contains two components - * 1. Interface to the CYLINK library to allow compilation of Bind - * with TIS/DNSSEC when CYLINK is not available - * all calls to CYLINK are contained inside this file. - * 2. The glue to connvert DSA KEYS to and from external formats - */ -#include "port_before.h" - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <memory.h> -#include <sys/param.h> -#include <sys/time.h> -#include <netinet/in.h> - -#include "dst_internal.h" -#include <toolkit.h> - -#include "port_after.h" - -typedef struct cylinkkey { - char *dk_signer; - uchar *dk_p; - uchar *dk_q; - uchar *dk_g; - uchar *dk_x; - uchar *dk_y; - ushort dk_p_bytes; -} DSA_Key; - -#define NULL_PRIV_KEY(k)(k == NULL || k->dk_p == NULL || k->dk_q == NULL || \ - k->dk_g == NULL || k->dk_x == NULL) -#define NULL_PUB_KEY(k)(k == NULL || k->dk_p == NULL || k->dk_q == NULL || \ - k->dk_g == NULL || k->dk_y == NULL) - -static int dst_cylink_sign(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - u_char *signature, const int sig_len); - -static int dst_cylink_verify(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - const u_char *signature, const int sig_len); - -static int dst_cylink_to_dns_key(const DST_KEY *in_key, u_char *out_str, - const int out_len); -static int dst_cylink_from_dns_key(DST_KEY *s_key, const u_char *key, - const int len); -static int dst_cylink_key_to_file_format(const DST_KEY *key, char *buff, - const int buff_len); -static int dst_cylink_key_from_file_format(DST_KEY *d_key, - const char *buff, - const int buff_len); -static void *dst_cylink_free_key_structure(void *key); - -static int dst_cylink_generate_keypair(DST_KEY *key, int exp); -static int dst_cylink_compare_keys(const DST_KEY *key1, const DST_KEY *key2); - -static void *memcpyend(void *dest, const void *src, size_t n, size_t size); - -/* - * dst_cylink_init() Function to answer set up function pointers for - * CYLINK related functions - */ -int -dst_cylink_init() -{ - if (dst_t_func[KEY_DSA] != NULL) - return (1); - dst_t_func[KEY_DSA] = malloc(sizeof(struct dst_func)); - if (dst_t_func[KEY_DSA] == NULL) - return (0); - memset(dst_t_func[KEY_DSA], 0, sizeof(struct dst_func)); - dst_t_func[KEY_DSA]->sign = dst_cylink_sign; - dst_t_func[KEY_DSA]->verify = dst_cylink_verify; - dst_t_func[KEY_DSA]->compare = dst_cylink_compare_keys; - dst_t_func[KEY_DSA]->generate = dst_cylink_generate_keypair; - dst_t_func[KEY_DSA]->destroy = dst_cylink_free_key_structure; - dst_t_func[KEY_DSA]->from_dns_key = dst_cylink_from_dns_key; - dst_t_func[KEY_DSA]->to_dns_key = dst_cylink_to_dns_key; - dst_t_func[KEY_DSA]->from_file_fmt = dst_cylink_key_from_file_format; - dst_t_func[KEY_DSA]->to_file_fmt = dst_cylink_key_to_file_format; - SetDataOrder(1); - return (1); -} - -/* - * dst_cylink_sign - * Call CYLINK signing functions to sign a block of data. - * There are three steps to signing, INIT (initialize structures), - * UPDATE (hash (more) data), FINAL (generate a signature). This - * routine performs one or more of these steps. - * Parameters - * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL. - * algobj structure holds context for a sign done in multiple calls. - * context the context to use for this computation - * data data to be signed. - * len length in bytes of data. - * priv_key key to use for signing. - * signature location to store signature. - * sig_len size in bytes of signature field. - * returns - * N Success on SIG_MODE_FINAL = returns signature length in bytes - * N is 41 for DNS - * 0 Success on SIG_MODE_INIT and UPDATE - * <0 Failure - */ - -static int -dst_cylink_sign(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - u_char *signature, const int sig_len) -{ - int sign_len = 0; - int status; - SHA_context *ctx = NULL; - - if (mode & SIG_MODE_INIT) - ctx = (SHA_context *) malloc(sizeof(SHA_context)); - else if (context) - ctx = (SHA_context *) *context; - if (ctx == NULL) - return (-1); - - if (mode & SIG_MODE_INIT) - SHAInit(ctx); - - if ((mode & SIG_MODE_UPDATE) && (data && len > 0)) { - status = SHAUpdate(ctx, (u_char *) data, len); - if (status != SUCCESS) - return (SIGN_UPDATE_FAILURE); - } - if (mode & SIG_MODE_FINAL) { - DSA_Key *key; - uchar digest[SHA_LENGTH]; - uchar rand[SHA_LENGTH]; - uchar r[SHA_LENGTH], s[SHA_LENGTH]; - - if (signature == NULL || sig_len < 2 * SHA_LENGTH) - return (SIGN_FINAL_FAILURE); - if ((status = SHAFinal(ctx, digest)) != SUCCESS) - return (SIGN_FINAL_FAILURE); - SAFE_FREE(ctx); - if (dkey == NULL || dkey->dk_KEY_struct == NULL) - return (-1); - key = (DSA_Key *) dkey->dk_KEY_struct; - if (NULL_PRIV_KEY(key)) - return (-2); - dst_random(DST_RAND_STD, sizeof(rand), rand); - status = GenDSSSignature(key->dk_p_bytes, key->dk_p, - key->dk_q, key->dk_g, key->dk_x, - rand, r, s, digest); - if (status != SUCCESS) - return (SIGN_FINAL_FAILURE); - *signature = (dkey->dk_key_size - 512)/64; - sign_len = 1; - memcpy(signature + sign_len, r, SHA_LENGTH); - sign_len += SHA_LENGTH; - memcpy(signature + sign_len, s, SHA_LENGTH); - sign_len += SHA_LENGTH; - } - else { - if (context == NULL) - return (-1); - *context = (void *) ctx; - } - return (sign_len); -} - - -/* - * Dst_cylink_verify - * Calls CYLINK verification routines. There are three steps to - * verification, INIT (initialize structures), UPDATE (hash (more) data), - * FINAL (generate a signature). This routine performs one or more of - * these steps. - * Parameters - * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL. - * dkey structure holds context for a verify done in multiple calls. - * context algorithm specific context for the current context processing - * data data signed. - * len length in bytes of data. - * pub_key key to use for verify. - * signature signature. - * sig_len length in bytes of signature. - * returns - * 0 Success - * <0 Failure - */ - -static int -dst_cylink_verify(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - const u_char *signature, const int sig_len) -{ - int status; - SHA_context *ctx = NULL; - - if (mode & SIG_MODE_INIT) - ctx = (SHA_context *) malloc(sizeof(SHA_context)); - else if (context) - ctx = (SHA_context *) *context; - if (ctx == NULL) - return (-1); - - if (mode & SIG_MODE_INIT) - SHAInit(ctx); - - if ((mode & SIG_MODE_UPDATE) && (data && len > 0)) { - status = SHAUpdate(ctx, (u_char *) data, len); - if (status != SUCCESS) - return (VERIFY_UPDATE_FAILURE); - } - if (mode & SIG_MODE_FINAL) { - DSA_Key *key; - uchar digest[SHA_LENGTH]; - uchar r[SHA_LENGTH], s[SHA_LENGTH]; - - if (dkey == NULL || dkey->dk_KEY_struct == NULL) - return (-1); - key = (DSA_Key *) dkey->dk_KEY_struct; - if (NULL_PUB_KEY(key)) - return (-2); - if (signature == NULL || sig_len != (2 * SHA_LENGTH +1)) - return (SIGN_FINAL_FAILURE); - status = SHAFinal(ctx, digest); - SAFE_FREE(ctx); - if (status != SUCCESS) - return (SIGN_FINAL_FAILURE); - if (((int)*signature) != ((key->dk_p_bytes -64)/8)) - return(VERIFY_FINAL_FAILURE); - - memcpy(r, signature +1, SHA_LENGTH); - memcpy(s, signature + SHA_LENGTH +1, SHA_LENGTH); - status = VerDSSSignature(key->dk_p_bytes, key->dk_p, - key->dk_q, key->dk_g, key->dk_y, - r, s, digest); - if (status != SUCCESS) - return (VERIFY_FINAL_FAILURE); - } - else { - if (context == NULL) - return (-1); - *context = (void *) ctx; - } - return (0); -} - - -/* - * dst_cylink_to_dns_key - * Converts key from DSA to DNS distribution format - * This function gets in a pointer to the public key and a work area - * to write the key into. - * Parameters - * public KEY structure - * out_str buffer to write encoded key into - * out_len size of out_str - * Return - * N >= 0 length of encoded key - * n < 0 error - */ - -static int -dst_cylink_to_dns_key(const DST_KEY *in_key, u_char *out_str, - const int out_len) -{ - u_char *op = out_str; - int t; - DSA_Key *key; - - if (in_key == NULL || in_key->dk_KEY_struct == NULL || - out_len <= 0 || out_str == NULL) - return (-1); - key = (DSA_Key *) in_key->dk_KEY_struct; - - t = (key->dk_p_bytes - 64) / 8; - - *op++ = t; - memcpy(op, key->dk_q, SHA_LENGTH); - op += SHA_LENGTH; - memcpy(op, key->dk_p, key->dk_p_bytes); - op += key->dk_p_bytes; - memcpy(op, key->dk_g, key->dk_p_bytes); - op += key->dk_p_bytes; - memcpy(op, key->dk_y, key->dk_p_bytes); - op += key->dk_p_bytes; - - return (op - out_str); -} - - -/* - * dst_cylink_from_dns_key - * Converts from a DNS KEY RR format to an RSA KEY. - * Parameters - * len Length in bytes of DNS key - * key DNS key - * name Key name - * s_key DST structure that will point to the RSA key this routine - * will build. - * Return - * 0 The input key, s_key or name was null. - * 1 Success - */ -static int -dst_cylink_from_dns_key(DST_KEY *s_key, const u_char *key, const int len) -{ - int t; - const u_char *key_ptr = key; - DSA_Key *d_key; - - if (s_key == NULL || len < 0 || key == NULL) - return (0); - - if (len == 0) /* process null key */ - return (1); - - if (key_ptr == NULL) - return (0); - t = (int) *key_ptr++; /* length of exponent in bytes */ - - if ((3 * (t * 8 + 64) + SHA_LENGTH + 1) != len) - return (0); - - if ((d_key = (DSA_Key *) malloc(sizeof(DSA_Key))) == NULL) { - EREPORT(("dst_cylink_from_dns_key(): Memory allocation error 1")); - return (0); - } - memset(d_key, 0, sizeof(DSA_Key)); - s_key->dk_KEY_struct = (void *) d_key; - d_key->dk_signer = strdup(s_key->dk_key_name); - d_key->dk_p_bytes = 64 + 8 * t; - - if ((d_key->dk_q = (uchar *) malloc(SHA_LENGTH)) == NULL) - return (0); - memcpy(d_key->dk_q, key_ptr, SHA_LENGTH); - key_ptr += SHA_LENGTH; - - if ((d_key->dk_p = (uchar *) malloc(d_key->dk_p_bytes)) == NULL) - return (0); - memcpy(d_key->dk_p, key_ptr, d_key->dk_p_bytes); - key_ptr += d_key->dk_p_bytes; - - if ((d_key->dk_g = (uchar *) malloc(d_key->dk_p_bytes)) == NULL) - return (0); - memcpy(d_key->dk_g, key_ptr, d_key->dk_p_bytes); - key_ptr += d_key->dk_p_bytes; - - if ((d_key->dk_y = (uchar *) malloc(d_key->dk_p_bytes)) == NULL) - return (0); - memcpy(d_key->dk_y, key_ptr, d_key->dk_p_bytes); - key_ptr += d_key->dk_p_bytes; - - s_key->dk_id = dst_s_id_calc(key, len); - s_key->dk_key_size = d_key->dk_p_bytes * 8; - return (1); -} - - -/************************************************************************** - * dst_cylink_key_to_file_format - * Encodes an DSA Key into the portable file format. - * Parameters - * key DSA KEY structure - * buff output buffer - * buff_len size of output buffer - * Return - * 0 Failure - null input rkey - * -1 Failure - not enough space in output area - * N Success - Length of data returned in buff - */ - -static int -dst_cylink_key_to_file_format(const DST_KEY *key, char *buff, - const int buff_len) -{ - char *bp; - int len, b_len; - DSA_Key *dkey; - u_char num[256]; /* More than long enough for DSA keys */ - - if (key == NULL || key->dk_KEY_struct == NULL) /* no output */ - return (0); - if (buff == NULL || buff_len <= (int) strlen(key_file_fmt_str)) - return (-1); /* no OR not enough space in output area */ - - dkey = (DSA_Key *) key->dk_KEY_struct; - - memset(buff, 0, buff_len); /* just in case */ - /* write file header */ - sprintf(buff, key_file_fmt_str, KEY_FILE_FORMAT, KEY_DSA, "DSA"); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - memcpy(num, dkey->dk_p, dkey->dk_p_bytes); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Prime(p): ", - num, dkey->dk_p_bytes)) <= 0) - return (-1); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - memcpy(num, dkey->dk_q, dkey->dk_p_bytes); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Subprime(q): ", - num, SHA_LENGTH)) <= 0) - return (-2); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - memcpy(num, dkey->dk_g, dkey->dk_p_bytes); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Base(g): ", - num, dkey->dk_p_bytes)) <= 0) - return (-3); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - memcpy(num, dkey->dk_x, dkey->dk_p_bytes); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Private_value(x): ", - num, SHA_LENGTH)) <= 0) - return (-4); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - memcpy(num, dkey->dk_y, dkey->dk_p_bytes); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Public_value(y): ", - num, dkey->dk_p_bytes)) <= 0) - return (-4); - - bp += len; - b_len -= len; - return (buff_len - b_len); -} - - -/************************************************************************** - * dst_cylink_key_from_file_format - * Converts contents of a private key file into a private DSA key. - * Parameters - * DSA_Key structure to put key into - * buff buffer containing the encoded key - * buff_len the length of the buffer - * Return - * n >= 0 Foot print of the key converted - * n < 0 Error in conversion - */ - -static int -dst_cylink_key_from_file_format(DST_KEY *d_key, const char *buff, - const int buff_len) -{ - u_char s[DSS_LENGTH_MAX]; - u_char dns[1024]; - int len, s_len = sizeof(s); - int foot = -1, dnslen; - const char *p = buff; - DSA_Key *dsa_key; - - if (d_key == NULL || buff == NULL || buff_len <= 0) - return (-1); - - dsa_key = (DSA_Key *) malloc(sizeof(DSA_Key)); - if (dsa_key == NULL) { - return (-2); - } - memset(dsa_key, 0, sizeof(*dsa_key)); - d_key->dk_KEY_struct = (void *) dsa_key; - - if (!dst_s_verify_str(&p, "Prime(p): ")) - return (-3); - memset(s, 0, s_len); - if ((len = dst_s_conv_bignum_b64_to_u8(&p, s, s_len)) == 0) - return (-4); - dsa_key->dk_p_bytes = len; - if ((dsa_key->dk_p = malloc(len)) == NULL) - return (-5); - memcpy(dsa_key->dk_p, s + s_len - len, len); - - while (*++p && p < (const char *) &buff[buff_len]) { - if (dst_s_verify_str(&p, "Subprime(q): ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, s, s_len))) - return (-6); - if ((dsa_key->dk_q = malloc(SHA_LENGTH)) == NULL) - return (-7); - memcpyend(dsa_key->dk_q, s + s_len - len, len, - SHA_LENGTH); - } else if (dst_s_verify_str(&p, "Base(g): ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, s, s_len))) - return (-8); - if ((dsa_key->dk_g = malloc(dsa_key->dk_p_bytes)) - == NULL) - return (-9); - memcpyend(dsa_key->dk_g, s + s_len - len, len, - dsa_key->dk_p_bytes); - } else if (dst_s_verify_str(&p, "Private_value(x): ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, s, s_len))) - return (-10); - if ((dsa_key->dk_x = malloc(SHA_LENGTH)) == NULL) - return (-11); - memcpyend(dsa_key->dk_x, s + s_len - len, len, - SHA_LENGTH); - } else if (dst_s_verify_str(&p, "Public_value(y): ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, s, s_len))) - return (-10); - if ((dsa_key->dk_y = malloc(dsa_key->dk_p_bytes)) - == NULL) - return (-11); - memcpyend(dsa_key->dk_y, s + s_len - len, len, - dsa_key->dk_p_bytes); - } else { - EREPORT(("Decode_DSAKey(): Bad keyword %s\n", p)); - return (-12); - } - } /* while p */ - - d_key->dk_key_size = dsa_key->dk_p_bytes * 8; - dnslen = d_key->dk_func->to_dns_key(d_key, dns, sizeof(dns)); - foot = dst_s_id_calc(dns, dnslen); - - return (foot); -} - - -/************************************************************************** - * dst_cylink_free_key_structure - * Frees all dynamicly allocated structures in DSA_Key. - */ - -static void * -dst_cylink_free_key_structure(void *key) -{ - DSA_Key *d_key = (DSA_Key *) key; - if (d_key != NULL) { - SAFE_FREE(d_key->dk_signer); - SAFE_FREE(d_key->dk_p); - SAFE_FREE(d_key->dk_q); - SAFE_FREE(d_key->dk_g); - SAFE_FREE(d_key->dk_x); - SAFE_FREE(d_key->dk_y); - SAFE_FREE(d_key); - } - return (NULL); -} - - -/************************************************************************** - * dst_cylink_generate_keypair - * Generates unique keys that are hard to predict. - * Parameters - * key generic Key structure - * exp the public exponent - * Return - * 0 Failure - * 1 Success - */ - -static int -dst_cylink_generate_keypair(DST_KEY *key, int nothing) -{ - int status, dnslen, n; - DSA_Key *dsa; - u_char rand[SHA_LENGTH]; - u_char dns[1024]; - - if (key == NULL || key->dk_alg != KEY_DSA) - return (0); - - if ((dsa = (DSA_Key *) malloc(sizeof(DSA_Key))) == NULL) { - EREPORT(("dst_cylink_generate_keypair: Memory allocation error 3")); - return (0); - } - memset(dsa, 0, sizeof(*dsa)); - - dsa->dk_p_bytes = key->dk_key_size / 8; - dsa->dk_p = (uchar *) malloc(dsa->dk_p_bytes); - dsa->dk_q = (uchar *) malloc(SHA_LENGTH); - dsa->dk_g = (uchar *) malloc(dsa->dk_p_bytes); - dsa->dk_x = (uchar *) malloc(SHA_LENGTH); - dsa->dk_y = (uchar *) malloc(dsa->dk_p_bytes); - if (!dsa->dk_p || !dsa->dk_q || !dsa->dk_g || !dsa->dk_x || !dsa->dk_y) { - EREPORT(("dst_cylink_generate_keypair: Memory allocation error 4")); - return (0); - } - n = dst_random(DST_RAND_KEY, sizeof(rand), rand); - if (n != sizeof(rand)) - return (0); - status = GenDSSParameters(dsa->dk_p_bytes, dsa->dk_p, dsa->dk_q, - dsa->dk_g, rand, NULL); - if (status != SUCCESS) - return (0); - - status = GenDSSKey(dsa->dk_p_bytes, dsa->dk_p, dsa->dk_q, dsa->dk_g, - dsa->dk_x, dsa->dk_y, rand); - if (status != SUCCESS) - return (0); - memset(rand, 0, sizeof(rand)); - key->dk_KEY_struct = (void *) dsa; - dnslen = key->dk_func->to_dns_key(key, dns, sizeof(dns)); - key->dk_id = dst_s_id_calc(dns, dnslen); - return (1); -} - - -/* - * dst_cylink_compare_keys - * Compare two keys for equality. - * Return - * 0 The keys are equal - * NON-ZERO The keys are not equal - */ - -static int -dst_cylink_compare_keys(const DST_KEY *key1, const DST_KEY *key2) -{ - int status; - DSA_Key *dkey1 = (DSA_Key *) key1->dk_KEY_struct; - DSA_Key *dkey2 = (DSA_Key *) key2->dk_KEY_struct; - - if (dkey1 == NULL && dkey2 == NULL) - return (0); - else if (dkey1 == NULL) - return (2); - else if (dkey2 == NULL) - return(1); - - if (dkey1->dk_p_bytes != dkey2->dk_p_bytes) - return (201); - status = memcmp(dkey1->dk_p, dkey2->dk_p, dkey1->dk_p_bytes) || - memcmp(dkey1->dk_q, dkey2->dk_q, SHA_LENGTH) || - memcmp(dkey1->dk_g, dkey2->dk_g, dkey1->dk_p_bytes) || - memcmp(dkey1->dk_y, dkey2->dk_y, dkey1->dk_p_bytes); - if (status) - return (status); - if (dkey1->dk_x || dkey2->dk_x) { - if (dkey1->dk_x == NULL || dkey2->dk_x == NULL) - return (202); - return (memcmp(dkey1->dk_x, dkey2->dk_x, dkey1->dk_p_bytes)); - } else - return (0); -} - -static void * -memcpyend(void *dest, const void *src, size_t n, size_t size) { - if (n < size) - memset(dest, 0, size - n); - memcpy((char *)dest + size - n, src, n); - return dest; -} - -#else -int -dst_cylink_init() -{ - return (0); -} -#endif /* CYLINK */ diff --git a/contrib/bind/lib/dst/dst_api.c b/contrib/bind/lib/dst/dst_api.c deleted file mode 100644 index f25438ed6ef9e..0000000000000 --- a/contrib/bind/lib/dst/dst_api.c +++ /dev/null @@ -1,1068 +0,0 @@ -#ifndef LINT -static const char rcsid[] = "$Header: /proj/cvs/isc/bind/src/lib/dst/dst_api.c,v 1.14 2000/02/28 07:51:50 vixie Exp $"; -#endif - -/* - * Portions Copyright (c) 1995-1998 by Trusted Information Systems, 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 TRUSTED INFORMATION SYSTEMS - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * TRUSTED INFORMATION SYSTEMS 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. - */ -/* - * This file contains the interface between the DST API and the crypto API. - * This is the only file that needs to be changed if the crypto system is - * changed. Exported functions are: - * void dst_init() Initialize the toolkit - * int dst_check_algorithm() Function to determines if alg is suppored. - * int dst_compare_keys() Function to compare two keys for equality. - * int dst_sign_data() Incremental signing routine. - * int dst_verify_data() Incremental verify routine. - * int dst_generate_key() Function to generate new KEY - * DST_KEY *dst_read_key() Function to retrieve private/public KEY. - * void dst_write_key() Function to write out a key. - * DST_KEY *dst_dnskey_to_key() Function to convert DNS KEY RR to a DST - * KEY structure. - * int dst_key_to_dnskey() Function to return a public key in DNS - * format binary - * DST_KEY *dst_buffer_to_key() Converst a data in buffer to KEY - * int *dst_key_to_buffer() Writes out DST_KEY key matterial in buffer - * void dst_free_key() Releases all memory referenced by key structure - */ - -#include "port_before.h" -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <memory.h> -#include <ctype.h> -#include <time.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <resolv.h> - -#include "dst_internal.h" -#include "port_after.h" - -/* static variables */ -static int done_init = 0; -dst_func *dst_t_func[DST_MAX_ALGS]; -char *key_file_fmt_str = "Private-key-format: v%s\nAlgorithm: %d (%s)\n"; -char *dst_path = ""; - -/* internal I/O functions */ -static DST_KEY *dst_s_read_public_key(const char *in_name, - const u_int16_t in_id, int in_alg); -static int dst_s_read_private_key_file(char *name, DST_KEY *pk_key, - u_int16_t in_id, int in_alg); -static int dst_s_write_public_key(const DST_KEY *key); -static int dst_s_write_private_key(const DST_KEY *key); - -/* internal function to set up data structure */ -static DST_KEY *dst_s_get_key_struct(const char *name, const int alg, - const int flags, const int protocol, - const int bits); - -/* - * dst_init - * This function initializes the Digital Signature Toolkit. - * Right now, it just checks the DSTKEYPATH environment variable. - * Parameters - * none - * Returns - * none - */ -void -dst_init() -{ - char *s; - int len; - - if (done_init != 0) - return; - done_init = 1; - - s = getenv("DSTKEYPATH"); - len = 0; - if (s) { - struct stat statbuf; - - len = strlen(s); - if (len > PATH_MAX) { - EREPORT(("%s is longer than %d characters, ignoring\n", - s, PATH_MAX)); - } else if (stat(s, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) { - EREPORT(("%s is not a valid directory\n", s)); - } else { - dst_path = (char *) malloc(len + 2); - memcpy(dst_path, s, len + 1); - if (dst_path[strlen(dst_path) - 1] != '/') { - dst_path[strlen(dst_path) + 1] = 0; - dst_path[strlen(dst_path)] = '/'; - } - } - } - memset(dst_t_func, 0, sizeof(dst_t_func)); - /* first one is selected */ - dst_bsafe_init(); - dst_rsaref_init(); - dst_hmac_md5_init(); - dst_eay_dss_init(); - dst_cylink_init(); -} - -/* - * dst_check_algorithm - * This function determines if the crypto system for the specified - * algorithm is present. - * Parameters - * alg 1 KEY_RSA - * 3 KEY_DSA - * 157 KEY_HMAC_MD5 - * future algorithms TBD and registered with IANA. - * Returns - * 1 - The algorithm is available. - * 0 - The algorithm is not available. - */ -int -dst_check_algorithm(const int alg) -{ - return (dst_t_func[alg] != NULL); -} - -/* - * dst_s_get_key_struct - * This function allocates key structure and fills in some of the - * fields of the structure. - * Parameters: - * name: the name of the key - * alg: the algorithm number - * flags: the dns flags of the key - * protocol: the dns protocol of the key - * bits: the size of the key - * Returns: - * NULL if error - * valid pointer otherwise - */ -static DST_KEY * -dst_s_get_key_struct(const char *name, const int alg, const int flags, - const int protocol, const int bits) -{ - DST_KEY *new_key = NULL; - - if (dst_check_algorithm(alg)) /* make sure alg is available */ - new_key = (DST_KEY *) malloc(sizeof(*new_key)); - if (new_key == NULL) - return (NULL); - - memset(new_key, 0, sizeof(*new_key)); - new_key->dk_key_name = strdup(name); - new_key->dk_alg = alg; - new_key->dk_flags = flags; - new_key->dk_proto = protocol; - new_key->dk_KEY_struct = NULL; - new_key->dk_key_size = bits; - new_key->dk_func = dst_t_func[alg]; - return (new_key); -} - -/* - * dst_compare_keys - * Compares two keys for equality. - * Parameters - * key1, key2 Two keys to be compared. - * Returns - * 0 The keys are equal. - * non-zero The keys are not equal. - */ - -int -dst_compare_keys(const DST_KEY *key1, const DST_KEY *key2) -{ - if (key1 == key2) - return (0); - if (key1 == NULL || key2 == NULL) - return (4); - if (key1->dk_alg != key2->dk_alg) - return (1); - if (key1->dk_key_size != key2->dk_key_size) - return (2); - if (key1->dk_id != key2->dk_id) - return (3); - return (key1->dk_func->compare(key1, key2)); -} - - -/* - * dst_sign_data - * An incremental signing function. Data is signed in steps. - * First the context must be initialized (SIG_MODE_INIT). - * Then data is hashed (SIG_MODE_UPDATE). Finally the signature - * itself is created (SIG_MODE_FINAL). This function can be called - * once with INIT, UPDATE and FINAL modes all set, or it can be - - * called separately with a different mode set for each step. The - * UPDATE step can be repeated. - * Parameters - * mode A bit mask used to specify operation(s) to be performed. - * SIG_MODE_INIT 1 Initialize digest - * SIG_MODE_UPDATE 2 Add data to digest - * SIG_MODE_FINAL 4 Generate signature - * from signature - * SIG_MODE_ALL (SIG_MODE_INIT,SIG_MODE_UPDATE,SIG_MODE_FINAL - * data Data to be signed. - * len The length in bytes of data to be signed. - * in_key Contains a private key to sign with. - * KEY structures should be handled (created, converted, - * compared, stored, freed) by the DST. - * signature - * The location to which the signature will be written. - * sig_len Length of the signature field in bytes. - * Return - * 0 Successfull INIT or Update operation - * >0 success FINAL (sign) operation - * <0 failure - */ - -int -dst_sign_data(const int mode, DST_KEY *in_key, void **context, - const u_char *data, const int len, - u_char *signature, const int sig_len) -{ - DUMP(data, mode, len, "dst_sign_data()"); - - if (mode & SIG_MODE_FINAL && - (in_key->dk_KEY_struct == NULL || signature == NULL)) - return (MISSING_KEY_OR_SIGNATURE); - - if (in_key->dk_func && in_key->dk_func->sign) - return (in_key->dk_func->sign(mode, in_key, context, data, len, - signature, sig_len)); - return (UNKNOWN_KEYALG); -} - - -/* - * dst_verify_data - * An incremental verify function. Data is verified in steps. - * First the context must be initialized (SIG_MODE_INIT). - * Then data is hashed (SIG_MODE_UPDATE). Finally the signature - * is verified (SIG_MODE_FINAL). This function can be called - * once with INIT, UPDATE and FINAL modes all set, or it can be - * called separately with a different mode set for each step. The - * UPDATE step can be repeated. - * Parameters - * mode Operations to perform this time. - * SIG_MODE_INIT 1 Initialize digest - * SIG_MODE_UPDATE 2 add data to digest - * SIG_MODE_FINAL 4 verify signature - * SIG_MODE_ALL - * (SIG_MODE_INIT,SIG_MODE_UPDATE,SIG_MODE_FINAL) - * data Data to pass through the hash function. - * len Length of the data in bytes. - * in_key Key for verification. - * signature Location of signature. - * sig_len Length of the signature in bytes. - * Returns - * 0 Verify success - * Non-Zero Verify Failure - */ - -int -dst_verify_data(const int mode, DST_KEY *in_key, void **context, - const u_char *data, const int len, - const u_char *signature, const int sig_len) -{ - DUMP(data, mode, len, "dst_verify_data()"); - if (mode & SIG_MODE_FINAL && - (in_key->dk_KEY_struct == NULL || signature == NULL)) - return (MISSING_KEY_OR_SIGNATURE); - - if (in_key->dk_func == NULL || in_key->dk_func->verify == NULL) - return (UNSUPPORTED_KEYALG); - return (in_key->dk_func->verify(mode, in_key, context, data, len, - signature, sig_len)); -} - - -/* - * dst_read_private_key - * Access a private key. First the list of private keys that have - * already been read in is searched, then the key accessed on disk. - * If the private key can be found, it is returned. If the key cannot - * be found, a null pointer is returned. The options specify required - * key characteristics. If the private key requested does not have - * these characteristics, it will not be read. - * Parameters - * in_keyname The private key name. - * in_id The id of the private key. - * options DST_FORCE_READ Read from disk - don't use a previously - * read key. - * DST_CAN_SIGN The key must be useable for signing. - * DST_NO_AUTHEN The key must be useable for authentication. - * DST_STANDARD Return any key - * Returns - * NULL If there is no key found in the current directory or - * this key has not been loaded before. - * !NULL Success - KEY structure returned. - */ - -DST_KEY * -dst_read_key(const char *in_keyname, const u_int16_t in_id, - const int in_alg, const int type) -{ - char keyname[PATH_MAX]; - DST_KEY *dg_key = NULL, *pubkey = NULL; - - if (!dst_check_algorithm(in_alg)) { /* make sure alg is available */ - EREPORT(("dst_read_private_key(): Algorithm %d not suppored\n", - in_alg)); - return (NULL); - } - if ((type & (DST_PUBLIC | DST_PRIVATE)) == 0) - return (NULL); - if (in_keyname == NULL) { - EREPORT(("dst_read_private_key(): Null key name passed in\n")); - return (NULL); - } else - strcpy(keyname, in_keyname); - - /* before I read in the public key, check if it is allowed to sign */ - if ((pubkey = dst_s_read_public_key(keyname, in_id, in_alg)) == NULL) - return (NULL); - - if (type == DST_PUBLIC) - return pubkey; - - if (!(dg_key = dst_s_get_key_struct(keyname, pubkey->dk_alg, - pubkey->dk_flags, pubkey->dk_proto, - 0))) - return (dg_key); - /* Fill in private key and some fields in the general key structure */ - if (dst_s_read_private_key_file(keyname, dg_key, pubkey->dk_id, - pubkey->dk_alg) == 0) - dg_key = dst_free_key(dg_key); - - pubkey = dst_free_key(pubkey); - return (dg_key); -} - -int -dst_write_key(const DST_KEY *key, const int type) -{ - int pub = 0, priv = 0; - - if (key == NULL) - return (0); - if (!dst_check_algorithm(key->dk_alg)) { /* make sure alg is available */ - EREPORT(("dst_write_key(): Algorithm %d not suppored\n", - key->dk_alg)); - return (UNSUPPORTED_KEYALG); - } - if ((type & (DST_PRIVATE|DST_PUBLIC)) == 0) - return (0); - - if (type & DST_PUBLIC) - if ((pub = dst_s_write_public_key(key)) < 0) - return (pub); - if (type & DST_PRIVATE) - if ((priv = dst_s_write_private_key(key)) < 0) - return (priv); - return (priv+pub); -} - -/* - * dst_write_private_key - * Write a private key to disk. The filename will be of the form: - * K<key->dk_name>+<key->dk_alg>+<key->dk_id>.<private key suffix>. - * If there is already a file with this name, an error is returned. - * - * Parameters - * key A DST managed key structure that contains - * all information needed about a key. - * Return - * >= 0 Correct behavior. Returns length of encoded key value - * written to disk. - * < 0 error. - */ - -static int -dst_s_write_private_key(const DST_KEY *key) -{ - u_char encoded_block[RAW_KEY_SIZE]; - char file[PATH_MAX]; - int len; - FILE *fp; - - /* First encode the key into the portable key format */ - if (key == NULL) - return (-1); - if (key->dk_KEY_struct == NULL) - return (0); /* null key has no private key */ - - if (key->dk_func == NULL || key->dk_func->to_file_fmt == NULL) { - EREPORT(("dst_write_private_key(): Unsupported operation %d\n", - key->dk_alg)); - return (-5); - } else if ((len = key->dk_func->to_file_fmt(key, (char *)encoded_block, - sizeof(encoded_block))) <= 0) { - EREPORT(("dst_write_private_key(): Failed encoding private RSA bsafe key %d\n", len)); - return (-8); - } - /* Now I can create the file I want to use */ - dst_s_build_filename(file, key->dk_key_name, key->dk_id, key->dk_alg, - PRIVATE_KEY, PATH_MAX); - - /* Do not overwrite an existing file */ - if ((fp = dst_s_fopen(file, "w", 0600)) != NULL) { - int nn; - if ((nn = fwrite(encoded_block, 1, len, fp)) != len) { - EREPORT(("dst_write_private_key(): Write failure on %s %d != %d errno=%d\n", - file, out_len, nn, errno)); - return (-5); - } - fclose(fp); - } else { - EREPORT(("dst_write_private_key(): Can not create file %s\n" - ,file)); - return (-6); - } - memset(encoded_block, 0, len); - return (len); -} - -/* -* - * dst_read_public_key - * Read a public key from disk and store in a DST key structure. - * Parameters - * in_name K<in_name><in_id>.<public key suffix> is the - * filename of the key file to be read. - * Returns - * NULL If the key does not exist or no name is supplied. - * NON-NULL Initalized key structure if the key exists. - */ - -static DST_KEY * -dst_s_read_public_key(const char *in_name, const u_int16_t in_id, int in_alg) -{ - int flags, proto, alg, len, dlen; - int c; - char name[PATH_MAX], enckey[RAW_KEY_SIZE], *notspace; - u_char deckey[RAW_KEY_SIZE]; - FILE *fp; - - if (in_name == NULL) { - EREPORT(("dst_read_public_key(): No key name given\n")); - return (NULL); - } - if (dst_s_build_filename(name, in_name, in_id, in_alg, PUBLIC_KEY, - PATH_MAX) == -1) { - EREPORT(("dst_read_public_key(): Cannot make filename from %s, %d, and %s\n", - in_name, in_id, PUBLIC_KEY)); - return (NULL); - } - /* - * Open the file and read it's formatted contents up to key - * File format: - * domain.name [ttl] [IN] KEY <flags> <protocol> <algorithm> <key> - * flags, proto, alg stored as decimal (or hex numbers FIXME). - * (FIXME: handle parentheses for line continuation.) - */ - if ((fp = dst_s_fopen(name, "r", 0)) == NULL) { - EREPORT(("dst_read_public_key(): Public Key not found %s\n", - name)); - return (NULL); - } - /* Skip domain name, which ends at first blank */ - while ((c = getc(fp)) != EOF) - if (isspace(c)) - break; - /* Skip blank to get to next field */ - while ((c = getc(fp)) != EOF) - if (!isspace(c)) - break; - - /* Skip optional TTL -- if initial digit, skip whole word. */ - if (isdigit(c)) { - while ((c = getc(fp)) != EOF) - if (isspace(c)) - break; - while ((c = getc(fp)) != EOF) - if (!isspace(c)) - break; - } - /* Skip optional "IN" */ - if (c == 'I' || c == 'i') { - while ((c = getc(fp)) != EOF) - if (isspace(c)) - break; - while ((c = getc(fp)) != EOF) - if (!isspace(c)) - break; - } - /* Locate and skip "KEY" */ - if (c != 'K' && c != 'k') { - EREPORT(("\"KEY\" doesn't appear in file: %s", name)); - return NULL; - } - while ((c = getc(fp)) != EOF) - if (isspace(c)) - break; - while ((c = getc(fp)) != EOF) - if (!isspace(c)) - break; - ungetc(c, fp); /* return the charcter to the input field */ - /* Handle hex!! FIXME. */ - - if (fscanf(fp, "%d %d %d", &flags, &proto, &alg) != 3) { - EREPORT(("dst_read_public_key(): Can not read flag/proto/alg field from %s\n" - ,name)); - return (NULL); - } - /* read in the key string */ - fgets(enckey, sizeof(enckey), fp); - - /* If we aren't at end-of-file, something is wrong. */ - while ((c = getc(fp)) != EOF) - if (!isspace(c)) - break; - if (!feof(fp)) { - EREPORT(("Key too long in file: %s", name)); - return NULL; - } - fclose(fp); - - if ((len = strlen(enckey)) <= 0) - return (NULL); - - /* discard \n */ - enckey[--len] = '\0'; - - /* remove leading spaces */ - for (notspace = (char *) enckey; isspace(*notspace); len--) - notspace++; - - dlen = b64_pton(notspace, deckey, sizeof(deckey)); - if (dlen < 0) { - EREPORT(("dst_read_public_key: bad return from b64_pton = %d", - dlen)); - return (NULL); - } - /* store key and info in a key structure that is returned */ -/* return dst_store_public_key(in_name, alg, proto, 666, flags, deckey, - dlen);*/ - return dst_buffer_to_key(in_name, alg, flags, proto, deckey, dlen); -} - - -/* - * dst_write_public_key - * Write a key to disk in DNS format. - * Parameters - * key Pointer to a DST key structure. - * Returns - * 0 Failure - * 1 Success - */ - -static int -dst_s_write_public_key(const DST_KEY *key) -{ - FILE *fp; - char filename[PATH_MAX]; - u_char out_key[RAW_KEY_SIZE]; - char enc_key[RAW_KEY_SIZE]; - int len = 0; - - memset(out_key, 0, sizeof(out_key)); - if (key == NULL) { - EREPORT(("dst_write_public_key(): No key specified \n")); - return (0); - } else if ((len = dst_key_to_dnskey(key, out_key, sizeof(out_key)))< 0) - return (0); - - /* Make the filename */ - if (dst_s_build_filename(filename, key->dk_key_name, key->dk_id, - key->dk_alg, PUBLIC_KEY, PATH_MAX) == -1) { - EREPORT(("dst_write_public_key(): Cannot make filename from %s, %d, and %s\n", - key->dk_key_name, key->dk_id, PUBLIC_KEY)); - return (0); - } - /* create public key file */ - if ((fp = dst_s_fopen(filename, "w+", 0644)) == NULL) { - EREPORT(("DST_write_public_key: open of file:%s failed (errno=%d)\n", - filename, errno)); - return (0); - } - /*write out key first base64 the key data */ - if (key->dk_flags & DST_EXTEND_FLAG) - b64_ntop(&out_key[6], len - 6, enc_key, sizeof(enc_key)); - else - b64_ntop(&out_key[4], len - 4, enc_key, sizeof(enc_key)); - fprintf(fp, "%s IN KEY %d %d %d %s\n", - key->dk_key_name, - key->dk_flags, key->dk_proto, key->dk_alg, enc_key); - fclose(fp); - return (1); -} - - -/* - * dst_dnskey_to_public_key - * This function converts the contents of a DNS KEY RR into a DST - * key structure. - * Paramters - * len Length of the RDATA of the KEY RR RDATA - * rdata A pointer to the the KEY RR RDATA. - * in_name Key name to be stored in key structure. - * Returns - * NULL Failure - * NON-NULL Success. Pointer to key structure. - * Caller's responsibility to free() it. - */ - -DST_KEY * -dst_dnskey_to_key(const char *in_name, const u_char *rdata, const int len) -{ - DST_KEY *key_st; - int alg ; - int start = DST_KEY_START; - - if (rdata == NULL || len <= DST_KEY_ALG) /* no data */ - return (NULL); - alg = (u_int8_t) rdata[DST_KEY_ALG]; - if (!dst_check_algorithm(alg)) { /* make sure alg is available */ - EREPORT(("dst_dnskey_to_key(): Algorithm %d not suppored\n", - alg)); - return (NULL); - } - if ((key_st = dst_s_get_key_struct(in_name, alg, 0, 0, 0)) == NULL) - return (NULL); - - if (in_name == NULL) - return (NULL); - key_st->dk_flags = dst_s_get_int16(rdata); - key_st->dk_proto = (u_int16_t) rdata[DST_KEY_PROT]; - if (key_st->dk_flags & DST_EXTEND_FLAG) { - u_int32_t ext_flags; - ext_flags = (u_int32_t) dst_s_get_int16(&rdata[DST_EXT_FLAG]); - key_st->dk_flags = key_st->dk_flags | (ext_flags << 16); - start += 2; - } - /* - * now point to the begining of the data representing the encoding - * of the key - */ - if (key_st->dk_func && key_st->dk_func->from_dns_key) { - if (key_st->dk_func->from_dns_key(key_st, &rdata[start], - len - start) > 0) - return (key_st); - } else - EREPORT(("dst_dnskey_to_public_key(): unsuppored alg %d\n", - alg)); - - SAFE_FREE(key_st); - return (key_st); -} - - -/* - * dst_public_key_to_dnskey - * Function to encode a public key into DNS KEY wire format - * Parameters - * key Key structure to encode. - * out_storage Location to write the encoded key to. - * out_len Size of the output array. - * Returns - * <0 Failure - * >=0 Number of bytes written to out_storage - */ - -int -dst_key_to_dnskey(const DST_KEY *key, u_char *out_storage, - const int out_len) -{ - u_int16_t val; - int loc = 0; - int enc_len = 0; - if (key == NULL) - return (-1); - - if (!dst_check_algorithm(key->dk_alg)) { /* make sure alg is available */ - EREPORT(("dst_key_to_dnskey(): Algorithm %d not suppored\n", - key->dk_alg)); - return (UNSUPPORTED_KEYALG); - } - memset(out_storage, 0, out_len); - val = (u_int16_t)(key->dk_flags & 0xffff); - dst_s_put_int16(out_storage, val); - loc += 2; - - out_storage[loc++] = (u_char) key->dk_proto; - out_storage[loc++] = (u_char) key->dk_alg; - - if (key->dk_flags > 0xffff) { /* Extended flags */ - val = (u_int16_t)((key->dk_flags >> 16) & 0xffff); - dst_s_put_int16(&out_storage[loc], val); - loc += 2; - } - if (key->dk_KEY_struct == NULL) - return (loc); - if (key->dk_func && key->dk_func->to_dns_key) { - enc_len = key->dk_func->to_dns_key(key, - (u_char *) &out_storage[loc], - out_len - loc); - if (enc_len > 0) - return (enc_len + loc); - else - return (-1); - } else - EREPORT(("dst_key_to_dnskey(): Unsupported ALG %d\n", - key->dk_alg)); - return (-1); -} - - -/* - * dst_buffer_to_key - * Function to encode a string of raw data into a DST key - * Parameters - * alg The algorithm (HMAC only) - * key A pointer to the data - * keylen The length of the data - * Returns - * NULL an error occurred - * NON-NULL the DST key - */ -DST_KEY * -dst_buffer_to_key(const char *key_name, /* name of the key */ - const int alg, /* algorithm */ - const int flags, /* dns flags */ - const int protocol, /* dns protocol */ - const u_char *key_buf, /* key in dns wire fmt */ - const int key_len) /* size of key */ -{ - - DST_KEY *dkey = NULL; - - if (!dst_check_algorithm(alg)) { /* make sure alg is available */ - EREPORT(("dst_buffer_to_key(): Algorithm %d not suppored\n", alg)); - return (NULL); - } - - dkey = dst_s_get_key_struct(key_name, alg, flags, - protocol, -1); - - if (dkey == NULL) - return (NULL); - if (dkey->dk_func != NULL && - dkey->dk_func->from_dns_key != NULL) { - if (dkey->dk_func->from_dns_key(dkey, key_buf, key_len) < 0) { - EREPORT(("dst_buffer_to_key(): dst_buffer_to_hmac failed\n")); - return (dst_free_key(dkey)); - } - return (dkey); - } - return (NULL); -} - -int -dst_key_to_buffer(DST_KEY *key, u_char *out_buff, int buf_len) -{ - int len; - /* this function will extrac the secret of HMAC into a buffer */ - if(key == NULL) - return (0); - if(key->dk_func != NULL && key->dk_func != NULL) { - len = key->dk_func->to_dns_key(key, out_buff, buf_len); - if (len < 0) - return (0); - return (len); - } - return (0); -} - - -/* - * dst_s_read_private_key_file - * Function reads in private key from a file. - * Fills out the KEY structure. - * Parameters - * name Name of the key to be read. - * pk_key Structure that the key is returned in. - * in_id Key identifier (tag) - * Return - * 1 if everthing works - * 0 if there is any problem - */ - -static int -dst_s_read_private_key_file(char *name, DST_KEY *pk_key, u_int16_t in_id, - int in_alg) -{ - int cnt, alg, len, major, minor, file_major, file_minor; - int id; - char filename[PATH_MAX]; - u_char in_buff[RAW_KEY_SIZE], *p; - FILE *fp; - - if (name == NULL || pk_key == NULL) { - EREPORT(("dst_read_private_key_file(): No key name given\n")); - return (0); - } - /* Make the filename */ - if (dst_s_build_filename(filename, name, in_id, in_alg, PRIVATE_KEY, - PATH_MAX) == -1) { - EREPORT(("dst_read_private_key(): Cannot make filename from %s, %d, and %s\n", - name, in_id, PRIVATE_KEY)); - return (0); - } - /* first check if we can find the key file */ - if ((fp = dst_s_fopen(filename, "r", 0)) == NULL) { - EREPORT(("dst_s_read_private_key_file: Could not open file %s in directory %s\n", - filename, dst_path[0] ? dst_path : - (char *) getcwd(NULL, PATH_MAX - 1))); - return (0); - } - /* now read the header info from the file */ - if ((cnt = fread(in_buff, 1, sizeof(in_buff), fp)) < 5) { - fclose(fp); - EREPORT(("dst_s_read_private_key_file: error reading file %s (empty file)\n", - filename)); - return (0); - } - /* decrypt key */ - fclose(fp); - if (memcmp(in_buff, "Private-key-format: v", 20) != 0) - goto fail; - len = cnt; - p = in_buff; - - if (!dst_s_verify_str((const char **) &p, "Private-key-format: v")) { - EREPORT(("dst_s_read_private_key_file(): Not a Key file/Decrypt failed %s\n", name)); - goto fail; - } - /* read in file format */ - sscanf((char *)p, "%d.%d", &file_major, &file_minor); - sscanf(KEY_FILE_FORMAT, "%d.%d", &major, &minor); - if (file_major < 1) { - EREPORT(("dst_s_read_private_key_file(): Unknown keyfile %d.%d version for %s\n", - file_major, file_minor, name)); - goto fail; - } else if (file_major > major || file_minor > minor) - EREPORT(( - "dst_s_read_private_key_file(): Keyfile %s version higher than mine %d.%d MAY FAIL\n", - name, file_major, file_minor)); - - while (*p++ != '\n') ; /* skip to end of line */ - - if (!dst_s_verify_str((const char **) &p, "Algorithm: ")) - goto fail; - - if (sscanf((char *)p, "%d", &alg) != 1) - goto fail; - while (*p++ != '\n') ; /* skip to end of line */ - - if (pk_key->dk_key_name && !strcmp(pk_key->dk_key_name, name)) - SAFE_FREE2(pk_key->dk_key_name, strlen(pk_key->dk_key_name)); - pk_key->dk_key_name = (char *) strdup(name); - - /* allocate and fill in key structure */ - if (pk_key->dk_func == NULL || pk_key->dk_func->from_file_fmt == NULL) - goto fail; - - id = pk_key->dk_func->from_file_fmt(pk_key, (char *)p, &in_buff[len] - p); - if (id < 0) - goto fail; - - /* Make sure the actual key tag matches the input tag used in the filename - */ - if (id != in_id) { - EREPORT(("dst_s_read_private_key_file(): actual tag of key read %d != input tag used to build filename %d.\n", id, in_id)); - goto fail; - } - pk_key->dk_id = (u_int16_t) id; - pk_key->dk_alg = alg; - memset(in_buff, 0, cnt); - return (1); - - fail: - memset(in_buff, 0, cnt); - return (0); -} - - -/* - * dst_generate_key - * Generate and store a public/private keypair. - * Keys will be stored in formatted files. - * Parameters - * name Name of the new key. Used to create key files - * K<name>+<alg>+<id>.public and K<name>+<alg>+<id>.private. - * bits Size of the new key in bits. - * exp What exponent to use: - * 0 use exponent 3 - * non-zero use Fermant4 - * flags The default value of the DNS Key flags. - * The DNS Key RR Flag field is defined in RFC 2065, - * section 3.3. The field has 16 bits. - * protocol - * Default value of the DNS Key protocol field. - * The DNS Key protocol field is defined in RFC 2065, - * section 3.4. The field has 8 bits. - * alg What algorithm to use. Currently defined: - * KEY_RSA 1 - * KEY_DSA 3 - * KEY_HMAC 157 - * out_id The key tag is returned. - * - * Return - * NULL Failure - * non-NULL the generated key pair - * Caller frees the result, and its dk_name pointer. - */ -DST_KEY * -dst_generate_key(const char *name, const int bits, const int exp, - const int flags, const int protocol, const int alg) -{ - DST_KEY *new_key = NULL; - int res; - if (name == NULL) - return (NULL); - - if (!dst_check_algorithm(alg)) { /* make sure alg is available */ - EREPORT(("dst_generate_key(): Algorithm %d not suppored\n", alg)); - return (NULL); - } - - new_key = dst_s_get_key_struct(name, alg, flags, protocol, bits); - if (new_key == NULL) - return (NULL); - if (bits == 0) /* null key we are done */ - return (new_key); - if (new_key->dk_func == NULL || new_key->dk_func->generate == NULL) { - EREPORT(("dst_generate_key_pair():Unsupported algorithm %d\n", - alg)); - return (dst_free_key(new_key)); - } - if ((res = new_key->dk_func->generate(new_key, exp)) <= 0) { - EREPORT(("dst_generate_key_pair(): Key generation failure %s %d %d %d\n", - new_key->dk_key_name, new_key->dk_alg, - new_key->dk_key_size, exp)); - return (dst_free_key(new_key)); - } - return (new_key); -} - - -/* - * dst_free_key - * Release all data structures pointed to by a key structure. - * Parameters - * f_key Key structure to be freed. - */ - -DST_KEY * -dst_free_key(DST_KEY *f_key) -{ - - if (f_key == NULL) - return (f_key); - if (f_key->dk_func && f_key->dk_func->destroy) - f_key->dk_KEY_struct = - f_key->dk_func->destroy(f_key->dk_KEY_struct); - else { - EREPORT(("dst_free_key(): Unknown key alg %d\n", - f_key->dk_alg)); - free(f_key->dk_KEY_struct); /* SHOULD NOT happen */ - } - if (f_key->dk_KEY_struct) { - free(f_key->dk_KEY_struct); - f_key->dk_KEY_struct = NULL; - } - if (f_key->dk_key_name) - SAFE_FREE(f_key->dk_key_name); - SAFE_FREE(f_key); - return (NULL); -} - -/* - * dst_sig_size - * Return the maximim size of signature from the key specified in bytes - * Parameters - * key - * Returns - * bytes - */ -int -dst_sig_size(DST_KEY *key) { - switch (key->dk_alg) { - case KEY_HMAC_MD5: - return (16); - case KEY_HMAC_SHA1: - return (20); - case KEY_RSA: - return (key->dk_key_size + 7) / 8; - case KEY_DSA: - return (40); - default: - EREPORT(("dst_sig_size(): Unknown key alg %d\n", key->dk_alg)); - return -1; - } -} - -/* - * dst_random - * function that multiplexes number of random number generators - * Parameters - * mode: select the random number generator - * wanted is how many bytes of random data are requested - * outran is a buffer of size at least wanted for the output data - * - * Returns - * number of bytes written to outran - */ -int -dst_random(const int mode, int wanted, u_char *outran) -{ - u_int32_t *buff = NULL, *bp = NULL; - int i; - if (wanted <= 0 || outran == NULL) - return (0); - - switch (mode) { - case DST_RAND_SEMI: - bp = buff = (u_int32_t *) malloc(wanted+sizeof(u_int32_t)); - for (i = 0; i < wanted; i+= sizeof(u_int32_t), bp++) { - *bp = dst_s_quick_random(i); - } - memcpy(outran, buff, wanted); - SAFE_FREE(buff); - return (wanted); - case DST_RAND_STD: - return (dst_s_semi_random(outran, wanted)); - case DST_RAND_KEY: - return (dst_s_random(outran, wanted)); - case DST_RAND_DSS: - default: - /* need error case here XXX OG */ - return (0); - } -} - diff --git a/contrib/bind/lib/dst/dst_internal.h b/contrib/bind/lib/dst/dst_internal.h deleted file mode 100644 index 66bfed4066a95..0000000000000 --- a/contrib/bind/lib/dst/dst_internal.h +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef DST_INTERNAL_H -#define DST_INTERNAL_H - -/* - * Portions Copyright (c) 1995-1998 by Trusted Information Systems, 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 TRUSTED INFORMATION SYSTEMS - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * TRUSTED INFORMATION SYSTEMS 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. - */ -#include <limits.h> -#include <sys/param.h> -#if (!defined(BSD)) || (BSD < 199306) -# include <sys/bitypes.h> -#else -# include <sys/types.h> -#endif - -#ifndef PATH_MAX -# ifdef POSIX_PATH_MAX -# define PATH_MAX POSIX_PATH_MAX -# else -# define PATH_MAX 255 /* this is the value of POSIX_PATH_MAX */ -# endif -#endif - -typedef struct dst_key { - char *dk_key_name; /* name of the key */ - int dk_key_size; /* this is the size of the key in bits */ - int dk_proto; /* what protocols this key can be used for */ - int dk_alg; /* algorithm number from key record */ - u_int32_t dk_flags; /* and the flags of the public key */ - u_int16_t dk_id; /* identifier of the key */ - void *dk_KEY_struct; /* pointer to key in crypto pkg fmt */ - struct dst_func *dk_func; /* point to cryptto pgk specific function table */ -} DST_KEY; -#define HAS_DST_KEY - -#include <isc/dst.h> -/* - * define what crypto systems are supported for RSA, - * BSAFE is prefered over RSAREF; only one can be set at any time - */ -#if defined(BSAFE) && defined(RSAREF) -# error "Cannot have both BSAFE and RSAREF defined" -#endif - -/* Declare dst_lib specific constants */ -#define KEY_FILE_FORMAT "1.2" - -/* suffixes for key file names */ -#define PRIVATE_KEY "private" -#define PUBLIC_KEY "key" - -/* error handling */ -#ifdef REPORT_ERRORS -#define EREPORT(str) printf str -#else -#define EREPORT(str) -#endif - -/* use our own special macro to FRRE memory */ - -#ifndef SAFE_FREE -#define SAFE_FREE(a) if(a != NULL){memset(a,0, sizeof(*a)); free(a); a=NULL;} -#define SAFE_FREE2(a,s) if (a != NULL && s > 0){memset(a,0, s);free(a); a=NULL;} -#endif - -typedef struct dst_func { - int (*sign)(const int mode, DST_KEY *key, void **context, - const u_int8_t *data, const int len, - u_int8_t *signature, const int sig_len); - int (*verify)(const int mode, DST_KEY *key, void **context, - const u_int8_t *data, const int len, - const u_int8_t *signature, const int sig_len); - int (*compare)(const DST_KEY *key1, const DST_KEY *key2); - int (*generate)(DST_KEY *key, int parms); - void *(*destroy)(void *key); - /* conversion functions */ - int (*to_dns_key)(const DST_KEY *key, u_int8_t *out, - const int out_len); - int (*from_dns_key)(DST_KEY *key, const u_int8_t *str, - const int str_len); - int (*to_file_fmt)(const DST_KEY *key, char *out, - const int out_len); - int (*from_file_fmt)(DST_KEY *key, const char *out, - const int out_len); - -} dst_func; - -extern dst_func *dst_t_func[DST_MAX_ALGS]; -extern char *key_file_fmt_str; -extern char *dst_path; - -#ifndef DST_HASH_SIZE -#define DST_HASH_SIZE 20 /* RIPEMD160 and SHA-1 are 20 bytes MD5 is 16 */ -#endif - -int dst_bsafe_init(); - -int dst_rsaref_init(); - -int dst_hmac_md5_init(); - -int dst_cylink_init(); - -int dst_eay_dss_init(); - -/* support functions */ -/* base64 to bignum conversion routines */ -int dst_s_conv_bignum_u8_to_b64( char *out_buf, const int out_len, - const char *header, - const u_int8_t *bin_data, - const int bin_len); -int dst_s_conv_bignum_b64_to_u8( const char **buf, u_int8_t *loc, - const int loclen) ; -/* from higher level support routines */ -int dst_s_calculate_bits( const u_int8_t *str, const int max_bits); -int dst_s_verify_str( const char **buf, const char *str); - - -/* conversion between dns names and key file names */ -size_t dst_s_filename_length( const char *name, const char *suffix); -int dst_s_build_filename( char *filename, const char *name, - u_int16_t id, int alg, const char *suffix, - size_t filename_length); - -FILE *dst_s_fopen (const char *filename, const char *mode, int perm); - -/* from file prandom.c */ -int dst_s_random( u_int8_t *output, int size); -int dst_s_semi_random( u_int8_t *output, int size); -u_int32_t dst_s_quick_random( int inc); -void dst_s_quick_random_set( u_int32_t val, u_int32_t cnt); - -/* - * read and write network byte order into u_int?_t - * all of these should be retired - */ -u_int16_t dst_s_get_int16( const u_int8_t *buf); -void dst_s_put_int16( u_int8_t *buf, const u_int16_t val); - -u_int32_t dst_s_get_int32( const u_int8_t *buf); -void dst_s_put_int32( u_int8_t *buf, const u_int32_t val); - -#ifdef DUMP -# undef DUMP -# define DUMP(a,b,c,d) dst_s_dump(a,b,c,d) -#else -# define DUMP(a,b,c,d) -#endif - - -#endif /* DST_INTERNAL_H */ diff --git a/contrib/bind/lib/dst/eay_dss_link.c b/contrib/bind/lib/dst/eay_dss_link.c deleted file mode 100644 index b060bf0368632..0000000000000 --- a/contrib/bind/lib/dst/eay_dss_link.c +++ /dev/null @@ -1,624 +0,0 @@ -#ifdef EAY_DSS -static const char rcsid[] = "$Header: /proj/cvs/isc/bind/src/lib/dst/eay_dss_link.c,v 1.4 1999/10/13 16:39:23 vixie Exp $"; - -/* - * Portions Copyright (c) 1995-1998 by Trusted Information Systems, 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 TRUSTED INFORMATION SYSTEMS - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * TRUSTED INFORMATION SYSTEMS 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. - */ -/* - * This file contains two components - * 1. Interface to the EAY libcrypto library to allow compilation of Bind - * with TIS/DNSSEC when EAY libcrypto is not available - * all calls to libcrypto are contained inside this file. - * 2. The glue to connvert DSA KEYS to and from external formats - */ -#include "port_before.h" - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <memory.h> -#include <sys/param.h> -#include <sys/time.h> -#include <netinet/in.h> - -#include "dst_internal.h" - -#include "crypto.h" -#include "bn.h" -#include "dsa.h" -#include "sha.h" - -#include "port_after.h" - -static int dst_eay_dss_sign(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - u_char *signature, const int sig_len); - -static int dst_eay_dss_verify(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - const u_char *signature, const int sig_len); - -static int dst_eay_dss_to_dns_key(const DST_KEY *in_key, u_char *out_str, - const int out_len); -static int dst_eay_dss_from_dns_key(DST_KEY *s_key, const u_char *key, - const int len); -static int dst_eay_dss_key_to_file_format(const DST_KEY *key, u_char *buff, - const int buff_len); -static int dst_eay_dss_key_from_file_format(DST_KEY *d_key, - const u_char *buff, - const int buff_len); -static void *dst_eay_dss_free_key_structure(void *key); - -static int dst_eay_dss_generate_keypair(DST_KEY *key, int exp); -static int dst_eay_dss_compare_keys(const DST_KEY *key1, const DST_KEY *key2); - -/* - * dst_eay_dss_init() Function to answer set up function pointers for - * EAY DSS related functions - */ -int -dst_eay_dss_init() -{ - if (dst_t_func[KEY_DSA] != NULL) - return (1); - dst_t_func[KEY_DSA] = malloc(sizeof(struct dst_func)); - if (dst_t_func[KEY_DSA] == NULL) - return (0); - memset(dst_t_func[KEY_DSA], 0, sizeof(struct dst_func)); - dst_t_func[KEY_DSA]->sign = dst_eay_dss_sign; - dst_t_func[KEY_DSA]->verify = dst_eay_dss_verify; - dst_t_func[KEY_DSA]->compare = dst_eay_dss_compare_keys; - dst_t_func[KEY_DSA]->generate = dst_eay_dss_generate_keypair; - dst_t_func[KEY_DSA]->destroy = dst_eay_dss_free_key_structure; - dst_t_func[KEY_DSA]->from_dns_key = dst_eay_dss_from_dns_key; - dst_t_func[KEY_DSA]->to_dns_key = dst_eay_dss_to_dns_key; - dst_t_func[KEY_DSA]->from_file_fmt = dst_eay_dss_key_from_file_format; - dst_t_func[KEY_DSA]->to_file_fmt = dst_eay_dss_key_to_file_format; - return (1); -} - -/* - * dst_eay_dss_sign - * Call EAY DSS signing functions to sign a block of data. - * There are three steps to signing, INIT (initialize structures), - * UPDATE (hash (more) data), FINAL (generate a signature). This - * routine performs one or more of these steps. - * Parameters - * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL. - * algobj structure holds context for a sign done in multiple calls. - * context the context to use for this computation - * data data to be signed. - * len length in bytes of data. - * priv_key key to use for signing. - * signature location to store signature. - * sig_len size in bytes of signature field. - * returns - * N Success on SIG_MODE_FINAL = returns signature length in bytes - * N is 41 for DNS - * 0 Success on SIG_MODE_INIT and UPDATE - * <0 Failure - */ - -static int -dst_eay_dss_sign(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - u_char *signature, const int sig_len) -{ - int sign_len = 0; - int status; - SHA_CTX *ctx = NULL; - - if (mode & SIG_MODE_INIT) - ctx = (SHA_CTX *) malloc(sizeof(SHA_CTX)); - else if (context) - ctx = (SHA_CTX *) *context; - if (ctx == NULL) - return (-1); - - if (mode & SIG_MODE_INIT) - SHA1_Init(ctx); - - if ((mode & SIG_MODE_UPDATE) && (data && len > 0)) { - SHA1_Update(ctx, (u_char *) data, len); - } - if (mode & SIG_MODE_FINAL) { - DSA *key; - u_char digest[SHA_DIGEST_LENGTH]; - u_char rand[SHA_DIGEST_LENGTH]; - u_char r[SHA_DIGEST_LENGTH], s[SHA_DIGEST_LENGTH]; - - if (dkey == NULL || dkey->dk_KEY_struct == NULL) - return (-1); - key = dkey->dk_KEY_struct; - if (key == NULL) - return(-2); - SHA1_Final(digest, ctx); - status = DSA_sign(0, digest, SHA_DIGEST_LENGTH, - signature, &sign_len, key); - if (status != 0) - return (SIGN_FINAL_FAILURE); - - *signature = (dkey->dk_key_size - 512)/64; - sign_len = 1; - memcpy(signature + sign_len, r, SHA_DIGEST_LENGTH); - sign_len += SHA_DIGEST_LENGTH; - memcpy(signature + sign_len, s, SHA_DIGEST_LENGTH); - sign_len += SHA_DIGEST_LENGTH; - } - else { - if (context == NULL) - return (-1); - *context = (void *) ctx; - } - return (sign_len); -} - - -/* - * dst_eay_dss_verify - * Calls EAY DSS verification routines. There are three steps to - * verification, INIT (initialize structures), UPDATE (hash (more) data), - * FINAL (generate a signature). This routine performs one or more of - * these steps. - * Parameters - * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL. - * dkey structure holds context for a verify done in multiple calls. - * context algorithm specific context for the current context processing - * data data signed. - * len length in bytes of data. - * pub_key key to use for verify. - * signature signature. - * sig_len length in bytes of signature. - * returns - * 0 Success - * <0 Failure - */ - -static int -dst_eay_dss_verify(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - const u_char *signature, const int sig_len) -{ - int status; - SHA_CTX *ctx = NULL; - - if (mode & SIG_MODE_INIT) - ctx = (SHA_CTX *) malloc(sizeof(SHA_CTX)); - else if (context) - ctx = (SHA_CTX *) *context; - if (ctx == NULL) - return (-1); - - if (mode & SIG_MODE_INIT) - SHA1_Init(ctx); - - if ((mode & SIG_MODE_UPDATE) && (data && len > 0)) { - SHA1_Update(ctx, (u_char *) data, len); - } - if (mode & SIG_MODE_FINAL) { - DSA *key; - u_char digest[SHA_DIGEST_LENGTH]; - u_char r[SHA_DIGEST_LENGTH], s[SHA_DIGEST_LENGTH]; - - if (dkey == NULL || dkey->dk_KEY_struct == NULL) - return (-1); - key = (DSA *) dkey->dk_KEY_struct; - if (key = NULL) - return (-2); - if (signature == NULL || sig_len != (2 * SHA_DIGEST_LENGTH +1)) - return (SIGN_FINAL_FAILURE); - SHA1_Final(digest, ctx); - SAFE_FREE(ctx); - if (status != 0) - return (SIGN_FINAL_FAILURE); - if (((int)*signature) != ((BN_num_bytes(key->p) -64)/8)) - return(VERIFY_FINAL_FAILURE); - - memcpy(r, signature +1, SHA_DIGEST_LENGTH); - memcpy(s, signature + SHA_DIGEST_LENGTH +1, SHA_DIGEST_LENGTH); - status = DSA_verify(0, digest, SHA_DIGEST_LENGTH, - (u_char *)signature, sig_len, key); - if (status != 0) - return (VERIFY_FINAL_FAILURE); - } - else { - if (context == NULL) - return (-1); - *context = (void *) ctx; - } - return (0); -} - - -/* - * dst_eay_dss_to_dns_key - * Converts key from DSA to DNS distribution format - * This function gets in a pointer to the public key and a work area - * to write the key into. - * Parameters - * public KEY structure - * out_str buffer to write encoded key into - * out_len size of out_str - * Return - * N >= 0 length of encoded key - * n < 0 error - */ - -static int -dst_eay_dss_to_dns_key(const DST_KEY *in_key, u_char *out_str, - const int out_len) -{ - u_char *op = out_str; - int t; - DSA *key; - - if (in_key == NULL || in_key->dk_KEY_struct == NULL || - out_len <= 0 || out_str == NULL) - return (-1); - key = (DSA *) in_key->dk_KEY_struct; - - t = (BN_num_bytes(key->p) - 64) / 8; - - *op++ = t; - BN_bn2bin(key->q, op); - op += BN_num_bytes(key->q); - BN_bn2bin(key->p, op); - op += BN_num_bytes(key->p); - BN_bn2bin(key->g, op); - op += BN_num_bytes(key->g); - BN_bn2bin(key->pub_key, op); - op += BN_num_bytes(key->pub_key); - - return (op - out_str); -} - - -/* - * dst_eay_dss_from_dns_key - * Converts from a DNS KEY RR format to an RSA KEY. - * Parameters - * len Length in bytes of DNS key - * key DNS key - * name Key name - * s_key DST structure that will point to the RSA key this routine - * will build. - * Return - * 0 The input key, s_key or name was null. - * 1 Success - */ -static int -dst_eay_dss_from_dns_key(DST_KEY *s_key, const u_char *key, const int len) -{ - int t; - u_char *key_ptr = (u_char *)key; - DSA *d_key; - int p_bytes; - - if (s_key == NULL || len < 0 || key == NULL) - return (0); - - if (len == 0) /* process null key */ - return (1); - - if (key_ptr == NULL) - return (0); - t = (int) *key_ptr++; /* length of exponent in bytes */ - p_bytes = 64 + 8 * t; - - if ((3 * (t * 8 + 64) + SHA_DIGEST_LENGTH + 1) != len) - return (0); - - if ((d_key = (DSA *) malloc(sizeof(DSA))) == NULL) { - EREPORT(("dst_eay_dss_from_dns_key(): Memory allocation error 1")); - return (0); - } - memset(d_key, 0, sizeof(DSA)); - s_key->dk_KEY_struct = (void *) d_key; - - d_key->q = BN_bin2bn(key_ptr, SHA_DIGEST_LENGTH, NULL); - key_ptr += SHA_DIGEST_LENGTH; - - d_key->p = BN_bin2bn(key_ptr, p_bytes, NULL); - key_ptr += p_bytes; - - d_key->g = BN_bin2bn(key_ptr, p_bytes, NULL); - key_ptr += p_bytes; - - d_key->pub_key = BN_bin2bn(key_ptr, p_bytes, NULL); - key_ptr += p_bytes; - - s_key->dk_id = dst_s_id_calc(key, len); - s_key->dk_key_size = p_bytes * 8; - return (1); -} - - -/************************************************************************** - * dst_eay_dss_key_to_file_format - * Encodes an DSA Key into the portable file format. - * Parameters - * key DSA KEY structure - * buff output buffer - * buff_len size of output buffer - * Return - * 0 Failure - null input rkey - * -1 Failure - not enough space in output area - * N Success - Length of data returned in buff - */ - -static int -dst_eay_dss_key_to_file_format(const DST_KEY *key, u_char *buff, - const int buff_len) -{ - u_char *bp; - int len, b_len; - DSA *dkey; - char num[256]; /* More than long enough for DSA keys */ - - if (key == NULL || key->dk_KEY_struct == NULL) /* no output */ - return (0); - if (buff == NULL || buff_len <= (int) strlen(key_file_fmt_str)) - return (-1); /* no OR not enough space in output area */ - - dkey = (DSA *) key->dk_KEY_struct; - - memset(buff, 0, buff_len); /* just in case */ - /* write file header */ - sprintf(buff, key_file_fmt_str, KEY_FILE_FORMAT, KEY_DSA, "DSA"); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - memcpy(num, dkey->p, BN_num_bytes(dkey->p)); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Prime(p): ", num, - BN_num_bytes(dkey->p))) <= 0) - return (-1); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - memcpy(num, dkey->q, BN_num_bytes(dkey->q)); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Subprime(q): ", num, - BN_num_bytes(dkey->q))) <= 0) - return (-2); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - memcpy(num, dkey->g, BN_num_bytes(dkey->g)); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Base(g): ", num, - BN_num_bytes(dkey->g))) <= 0) - return (-3); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - memcpy(num, dkey->priv_key, BN_num_bytes(dkey->priv_key)); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Private_value(x): ", - num, - BN_num_bytes(dkey->priv_key))) - <= 0) - return (-4); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - memcpy(num, dkey->pub_key, BN_num_bytes(dkey->pub_key)); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Public_value(y): ", - num, - BN_num_bytes(dkey->pub_key))) - <= 0) - return (-5); - - bp += len; - b_len -= len; - return (buff_len - b_len); -} - - -/************************************************************************** - * dst_eay_dss_key_from_file_format - * Converts contents of a private key file into a private DSA key. - * Parameters - * d_key structure to put key into - * buff buffer containing the encoded key - * buff_len the length of the buffer - * Return - * n >= 0 Foot print of the key converted - * n < 0 Error in conversion - */ - -static int -dst_eay_dss_key_from_file_format(DST_KEY *d_key, const u_char *buff, - const int buff_len) -{ - char s[128]; - char dns[1024]; - int len, s_len = sizeof(s); - int foot = -1, dnslen; - const char *p = buff; - DSA *dsa_key; - - if (d_key == NULL || buff == NULL || buff_len <= 0) - return (-1); - - dsa_key = (DSA *) malloc(sizeof(DSA)); - if (dsa_key == NULL) { - return (-2); - } - memset(dsa_key, 0, sizeof(*dsa_key)); - d_key->dk_KEY_struct = (void *) dsa_key; - - if (!dst_s_verify_str(&p, "Prime(p): ")) - return (-3); - memset(s, 0, s_len); - if ((len = dst_s_conv_bignum_b64_to_u8(&p, s, s_len)) == 0) - return (-4); - dsa_key->p = BN_bin2bn (s, len, NULL); - if (dsa_key->p == NULL) - return(-5); - - while (*++p && p < (const char *) &buff[buff_len]) { - if (dst_s_verify_str(&p, "Subprime(q): ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, s, s_len))) - return (-6); - dsa_key->q = BN_bin2bn (s, len, NULL); - if (dsa_key->q == NULL) - return (-7); - } else if (dst_s_verify_str(&p, "Base(g): ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, s, s_len))) - return (-8); - dsa_key->g = BN_bin2bn (s, len, NULL); - if (dsa_key->g == NULL) - return (-9); - } else if (dst_s_verify_str(&p, "Private_value(x): ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, s, s_len))) - return (-10); - dsa_key->priv_key = BN_bin2bn (s, len, NULL); - if (dsa_key->priv_key == NULL) - return (-11); - } else if (dst_s_verify_str(&p, "Public_value(y): ")) { - if (!(len = dst_s_conv_bignum_b64_to_u8(&p, s, s_len))) - return (-12); - dsa_key->pub_key = BN_bin2bn (s, len, NULL); - if (dsa_key->pub_key == NULL) - return (-13); - } else { - EREPORT(("Decode_DSAKey(): Bad keyword %s\n", p)); - return (-14); - } - } /* while p */ - - d_key->dk_key_size = BN_num_bytes(dsa_key->p); - dnslen = d_key->dk_func->to_dns_key(d_key, dns, sizeof(dns)); - foot = dst_s_id_calc(dns, dnslen); - - return (foot); -} - - -/************************************************************************** - * dst_eay_dss_free_key_structure - * Frees all dynamicly allocated structures in DSA. - */ - -static void * -dst_eay_dss_free_key_structure(void *key) -{ - DSA *d_key = (DSA *) key; - if (d_key != NULL) { - BN_free(d_key->p); - BN_free(d_key->q); - BN_free(d_key->g); - if (d_key->pub_key) - BN_free(d_key->pub_key); - if (d_key->priv_key) - BN_free(d_key->priv_key); - SAFE_FREE(d_key); - } - return (NULL); -} - - -/************************************************************************** - * dst_eay_dss_generate_keypair - * Generates unique keys that are hard to predict. - * Parameters - * key generic Key structure - * exp the public exponent - * Return - * 0 Failure - * 1 Success - */ - -static int -dst_eay_dss_generate_keypair(DST_KEY *key, int nothing) -{ - int status, dnslen, n; - DSA *dsa; - u_char rand[SHA_DIGEST_LENGTH]; - char dns[1024]; - - if (key == NULL || key->dk_alg != KEY_DSA) - return (0); - - if ((dsa = (DSA *) malloc(sizeof(DSA))) == NULL) { - EREPORT(("dst_eay_dss_generate_keypair: Memory allocation error 3")); - return (0); - } - memset(dsa, 0, sizeof(*dsa)); - - n = dst_random(DST_RAND_KEY, sizeof(rand), rand); - if (n != sizeof(rand)) - return (0); - dsa = DSA_generate_parameters(key->dk_key_size, rand, 20, NULL, NULL, - NULL, NULL); - - if (!dsa) { - EREPORT(("dst_eay_dss_generate_keypair: Generate Parameters failed")); - return (0); - } - if (DSA_generate_key(dsa) == 0) { - EREPORT(("dst_eay_dss_generate_keypair: Generate Key failed")); - return(0); - } - key->dk_KEY_struct = (void *) dsa; - dnslen = key->dk_func->to_dns_key(key, dns, sizeof(dns)); - key->dk_id = dst_s_id_calc(dns, dnslen); - return (1); -} - - -/* - * dst_eay_dss_compare_keys - * Compare two keys for equality. - * Return - * 0 The keys are equal - * NON-ZERO The keys are not equal - */ - -static int -dst_eay_dss_compare_keys(const DST_KEY *key1, const DST_KEY *key2) -{ - int status; - DSA *dkey1 = (DSA *) key1->dk_KEY_struct; - DSA *dkey2 = (DSA *) key2->dk_KEY_struct; - - if (dkey1 == NULL && dkey2 == NULL) - return (0); - else if (dkey1 == NULL) - return (2); - else if (dkey2 == NULL) - return(1); - - status = BN_cmp(dkey1->p, dkey2->p) || - BN_cmp(dkey1->q, dkey2->q) || - BN_cmp(dkey1->g, dkey2->g) || - BN_cmp(dkey1->pub_key, dkey2->pub_key); - - if (status) - return (status); - - if (dkey1->priv_key || dkey2->priv_key) { - if (dkey1->priv_key == NULL || dkey2->priv_key == NULL) - return (202); - return (BN_cmp(dkey1->priv_key, dkey2->priv_key)); - } else - return (0); -} -#else -int -dst_eay_dss_init() -{ - return (0); -} -#endif /* EAY_DSS */ diff --git a/contrib/bind/lib/dst/hmac_link.c b/contrib/bind/lib/dst/hmac_link.c deleted file mode 100644 index 1f96bcab4245e..0000000000000 --- a/contrib/bind/lib/dst/hmac_link.c +++ /dev/null @@ -1,493 +0,0 @@ -#ifdef HMAC_MD5 -#ifndef LINT -static const char rcsid[] = "$Header: /proj/cvs/isc/bind/src/lib/dst/hmac_link.c,v 1.8 1999/10/15 21:30:07 vixie Exp $"; -#endif -/* - * Portions Copyright (c) 1995-1998 by Trusted Information Systems, 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 TRUSTED INFORMATION SYSTEMS - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * TRUSTED INFORMATION SYSTEMS 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. - */ - -/* - * This file contains an implementation of the HMAC-MD5 algorithm. - */ -#include "port_before.h" - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <memory.h> -#include <sys/param.h> -#include <sys/time.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <resolv.h> - -#include "dst_internal.h" -#ifdef USE_MD5 -# include "md5.h" -# ifndef _MD5_H_ -# define _MD5_H_ 1 /* make sure we do not include rsaref md5.h file */ -# endif -#endif - -#include "port_after.h" - - -#define HMAC_LEN 64 -#define HMAC_IPAD 0x36 -#define HMAC_OPAD 0x5c -#define MD5_LEN 16 - - -typedef struct hmackey { - u_char hk_ipad[64], hk_opad[64]; -} HMAC_Key; - - -/************************************************************************** - * dst_hmac_md5_sign - * Call HMAC signing functions to sign a block of data. - * There are three steps to signing, INIT (initialize structures), - * UPDATE (hash (more) data), FINAL (generate a signature). This - * routine performs one or more of these steps. - * Parameters - * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL. - * priv_key key to use for signing. - * context the context to be used in this digest - * data data to be signed. - * len length in bytes of data. - * signature location to store signature. - * sig_len size of the signature location - * returns - * N Success on SIG_MODE_FINAL = returns signature length in bytes - * 0 Success on SIG_MODE_INIT and UPDATE - * <0 Failure - */ - -static int -dst_hmac_md5_sign(const int mode, DST_KEY *d_key, void **context, - const u_char *data, const int len, - u_char *signature, const int sig_len) -{ - HMAC_Key *key; - int sign_len = 0; - MD5_CTX *ctx = NULL; - - if (mode & SIG_MODE_INIT) - ctx = (MD5_CTX *) malloc(sizeof(*ctx)); - else if (context) - ctx = (MD5_CTX *) *context; - if (ctx == NULL) - return (-1); - - if (d_key == NULL || d_key->dk_KEY_struct == NULL) - return (-1); - key = (HMAC_Key *) d_key->dk_KEY_struct; - - if (mode & SIG_MODE_INIT) { - MD5Init(ctx); - MD5Update(ctx, key->hk_ipad, HMAC_LEN); - } - - if ((mode & SIG_MODE_UPDATE) && (data && len > 0)) - MD5Update(ctx, (u_char *)data, len); - - if (mode & SIG_MODE_FINAL) { - if (signature == NULL || sig_len < MD5_LEN) - return (SIGN_FINAL_FAILURE); - MD5Final(signature, ctx); - - /* perform outer MD5 */ - MD5Init(ctx); - MD5Update(ctx, key->hk_opad, HMAC_LEN); - MD5Update(ctx, signature, MD5_LEN); - MD5Final(signature, ctx); - sign_len = MD5_LEN; - SAFE_FREE(ctx); - } - else { - if (context == NULL) - return (-1); - *context = (void *) ctx; - } - return (sign_len); -} - - -/************************************************************************** - * dst_hmac_md5_verify() - * Calls HMAC verification routines. There are three steps to - * verification, INIT (initialize structures), UPDATE (hash (more) data), - * FINAL (generate a signature). This routine performs one or more of - * these steps. - * Parameters - * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL. - * dkey key to use for verify. - * data data signed. - * len length in bytes of data. - * signature signature. - * sig_len length in bytes of signature. - * returns - * 0 Success - * <0 Failure - */ - -static int -dst_hmac_md5_verify(const int mode, DST_KEY *d_key, void **context, - const u_char *data, const int len, - const u_char *signature, const int sig_len) -{ - HMAC_Key *key; - MD5_CTX *ctx = NULL; - - if (mode & SIG_MODE_INIT) - ctx = (MD5_CTX *) malloc(sizeof(*ctx)); - else if (context) - ctx = (MD5_CTX *) *context; - if (ctx == NULL) - return (-1); - - if (d_key == NULL || d_key->dk_KEY_struct == NULL) - return (-1); - - key = (HMAC_Key *) d_key->dk_KEY_struct; - if (mode & SIG_MODE_INIT) { - MD5Init(ctx); - MD5Update(ctx, key->hk_ipad, HMAC_LEN); - } - if ((mode & SIG_MODE_UPDATE) && (data && len > 0)) - MD5Update(ctx, (u_char *)data, len); - - if (mode & SIG_MODE_FINAL) { - u_char digest[MD5_LEN]; - if (signature == NULL || key == NULL || sig_len != MD5_LEN) - return (VERIFY_FINAL_FAILURE); - MD5Final(digest, ctx); - - /* perform outer MD5 */ - MD5Init(ctx); - MD5Update(ctx, key->hk_opad, HMAC_LEN); - MD5Update(ctx, digest, MD5_LEN); - MD5Final(digest, ctx); - - SAFE_FREE(ctx); - if (memcmp(digest, signature, MD5_LEN) != 0) - return (VERIFY_FINAL_FAILURE); - } - else { - if (context == NULL) - return (-1); - *context = (void *) ctx; - } - return (0); -} - - -/************************************************************************** - * dst_buffer_to_hmac_md5 - * Converts key from raw data to an HMAC Key - * This function gets in a pointer to the data - * Parameters - * hkey the HMAC key to be filled in - * key the key in raw format - * keylen the length of the key - * Return - * 0 Success - * <0 Failure - */ -static int -dst_buffer_to_hmac_md5(DST_KEY *dkey, const u_char *key, const int keylen) -{ - int i; - HMAC_Key *hkey = NULL; - MD5_CTX ctx; - int local_keylen = keylen; - - if (dkey == NULL || key == NULL || keylen < 0) - return (-1); - - if ((hkey = (HMAC_Key *) malloc(sizeof(HMAC_Key))) == NULL) - return (-2); - - memset(hkey->hk_ipad, 0, sizeof(hkey->hk_ipad)); - memset(hkey->hk_opad, 0, sizeof(hkey->hk_opad)); - - /* if key is longer than HMAC_LEN bytes reset it to key=MD5(key) */ - if (keylen > HMAC_LEN) { - u_char tk[MD5_LEN]; - MD5Init(&ctx); - MD5Update(&ctx, (u_char *)key, keylen); - MD5Final(tk, &ctx); - memset((void *) &ctx, 0, sizeof(ctx)); - key = tk; - local_keylen = MD5_LEN; - } - /* start out by storing key in pads */ - memcpy(hkey->hk_ipad, key, local_keylen); - memcpy(hkey->hk_opad, key, local_keylen); - - /* XOR key with hk_ipad and opad values */ - for (i = 0; i < HMAC_LEN; i++) { - hkey->hk_ipad[i] ^= HMAC_IPAD; - hkey->hk_opad[i] ^= HMAC_OPAD; - } - dkey->dk_key_size = local_keylen; - dkey->dk_KEY_struct = (void *) hkey; - return (1); -} - - -/************************************************************************** - * dst_hmac_md5_key_to_file_format - * Encodes an HMAC Key into the portable file format. - * Parameters - * hkey HMAC KEY structure - * buff output buffer - * buff_len size of output buffer - * Return - * 0 Failure - null input hkey - * -1 Failure - not enough space in output area - * N Success - Length of data returned in buff - */ - -static int -dst_hmac_md5_key_to_file_format(const DST_KEY *dkey, char *buff, - const int buff_len) -{ - char *bp; - int len, b_len, i, key_len; - u_char key[HMAC_LEN]; - HMAC_Key *hkey; - - if (dkey == NULL || dkey->dk_KEY_struct == NULL) - return (0); - if (buff == NULL || buff_len <= (int) strlen(key_file_fmt_str)) - return (-1); /* no OR not enough space in output area */ - - hkey = (HMAC_Key *) dkey->dk_KEY_struct; - memset(buff, 0, buff_len); /* just in case */ - /* write file header */ - sprintf(buff, key_file_fmt_str, KEY_FILE_FORMAT, KEY_HMAC_MD5, "HMAC"); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - - memset(key, 0, HMAC_LEN); - for (i = 0; i < HMAC_LEN; i++) - key[i] = hkey->hk_ipad[i] ^ HMAC_IPAD; - for (i = HMAC_LEN - 1; i >= 0; i--) - if (key[i] != 0) - break; - key_len = i + 1; - - strcat(bp, "Key: "); - bp += strlen("Key: "); - b_len = buff_len - (bp - buff); - - len = b64_ntop(key, key_len, bp, b_len); - if (len < 0) - return (-1); - bp += len; - *(bp++) = '\n'; - *bp = '\0'; - b_len = buff_len - (bp - buff); - - return (buff_len - b_len); -} - - -/************************************************************************** - * dst_hmac_md5_key_from_file_format - * Converts contents of a key file into an HMAC key. - * Parameters - * hkey structure to put key into - * buff buffer containing the encoded key - * buff_len the length of the buffer - * Return - * n >= 0 Foot print of the key converted - * n < 0 Error in conversion - */ - -static int -dst_hmac_md5_key_from_file_format(DST_KEY *dkey, const char *buff, - const int buff_len) -{ - const char *p = buff, *eol; - u_char key[HMAC_LEN+1]; /* b64_pton needs more than 64 bytes do decode - * it should probably be fixed rather than doing - * this - */ - u_char *tmp; - int key_len, len; - - if (dkey == NULL) - return (-2); - if (buff == NULL || buff_len < 0) - return (-1); - - memset(key, 0, sizeof(key)); - - if (!dst_s_verify_str(&p, "Key: ")) - return (-3); - - eol = strchr(p, '\n'); - if (eol == NULL) - return (-4); - len = eol - p; - tmp = malloc(len + 2); - memcpy(tmp, p, len); - *(tmp + len) = 0x0; - key_len = b64_pton((char *)tmp, key, HMAC_LEN+1); /* see above */ - SAFE_FREE2(tmp, len + 2); - - if (dst_buffer_to_hmac_md5(dkey, key, key_len) < 0) { - return (-6); - } - return (0); -} - -/* - * dst_hmac_md5_to_dns_key() - * function to extract hmac key from DST_KEY structure - * intput: - * in_key: HMAC-MD5 key - * output: - * out_str: buffer to write ot - * out_len: size of output buffer - * returns: - * number of bytes written to output buffer - */ -static int -dst_hmac_md5_to_dns_key(const DST_KEY *in_key, u_char *out_str, - const int out_len) -{ - - HMAC_Key *hkey; - int i; - - if (in_key == NULL || in_key->dk_KEY_struct == NULL || - out_len <= in_key->dk_key_size || out_str == NULL) - return (-1); - - hkey = (HMAC_Key *) in_key->dk_KEY_struct; - for (i = 0; i < in_key->dk_key_size; i++) - out_str[i] = hkey->hk_ipad[i] ^ HMAC_IPAD; - return (i); -} - -/************************************************************************** - * dst_hmac_md5_compare_keys - * Compare two keys for equality. - * Return - * 0 The keys are equal - * NON-ZERO The keys are not equal - */ - -static int -dst_hmac_md5_compare_keys(const DST_KEY *key1, const DST_KEY *key2) -{ - HMAC_Key *hkey1 = (HMAC_Key *) key1->dk_KEY_struct; - HMAC_Key *hkey2 = (HMAC_Key *) key2->dk_KEY_struct; - return memcmp(hkey1->hk_ipad, hkey2->hk_ipad, HMAC_LEN); -} - -/************************************************************************** - * dst_hmac_md5_free_key_structure - * Frees all (none) dynamically allocated structures in hkey - */ - -static void * -dst_hmac_md5_free_key_structure(void *key) -{ - HMAC_Key *hkey = key; - SAFE_FREE(hkey); - return (NULL); -} - - -/*************************************************************************** - * dst_hmac_md5_generate_key - * Creates a HMAC key of size size with a maximum size of 63 bytes - * generating a HMAC key larger than 63 bytes makes no sense as that key - * is digested before use. - */ - -static int -dst_hmac_md5_generate_key(DST_KEY *key, const int nothing) -{ - u_char *buff; - int i, n, size; - - if (key == NULL || key->dk_alg != KEY_HMAC_MD5) - return (0); - size = (key->dk_key_size + 7) / 8; /* convert to bytes */ - if (size <= 0) - return(0); - - i = size > 64 ? 64 : size; - buff = malloc(i+8); - - n = dst_random(DST_RAND_SEMI, i, buff); - n += dst_random(DST_RAND_KEY, i, buff); - if (n <= i) { /* failed getting anything */ - SAFE_FREE2(buff, i); - return (-1); - } - n = dst_buffer_to_hmac_md5(key, buff, i); - SAFE_FREE2(buff, i); - if (n <= 0) - return (n); - return (1); -} - -/* - * dst_hmac_md5_init() Function to answer set up function pointers for HMAC - * related functions - */ -int -dst_hmac_md5_init() -{ - if (dst_t_func[KEY_HMAC_MD5] != NULL) - return (1); - dst_t_func[KEY_HMAC_MD5] = malloc(sizeof(struct dst_func)); - if (dst_t_func[KEY_HMAC_MD5] == NULL) - return (0); - memset(dst_t_func[KEY_HMAC_MD5], 0, sizeof(struct dst_func)); - dst_t_func[KEY_HMAC_MD5]->sign = dst_hmac_md5_sign; - dst_t_func[KEY_HMAC_MD5]->verify = dst_hmac_md5_verify; - dst_t_func[KEY_HMAC_MD5]->compare = dst_hmac_md5_compare_keys; - dst_t_func[KEY_HMAC_MD5]->generate = dst_hmac_md5_generate_key; - dst_t_func[KEY_HMAC_MD5]->destroy = dst_hmac_md5_free_key_structure; - dst_t_func[KEY_HMAC_MD5]->to_dns_key = dst_hmac_md5_to_dns_key; - dst_t_func[KEY_HMAC_MD5]->from_dns_key = dst_buffer_to_hmac_md5; - dst_t_func[KEY_HMAC_MD5]->to_file_fmt = dst_hmac_md5_key_to_file_format; - dst_t_func[KEY_HMAC_MD5]->from_file_fmt = dst_hmac_md5_key_from_file_format; - return (1); -} - -#else -int -dst_hmac_md5_init(){ - return (0); -} -#endif - - - - - - - diff --git a/contrib/bind/lib/dst/md5.h b/contrib/bind/lib/dst/md5.h deleted file mode 100644 index c8b1580364b22..0000000000000 --- a/contrib/bind/lib/dst/md5.h +++ /dev/null @@ -1,101 +0,0 @@ -/* crypto/md/md5.h */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_MD5_H -#define HEADER_MD5_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define MD5_CBLOCK 64 -#define MD5_LBLOCK 16 -#define MD5_BLOCK 16 -#define MD5_LAST_BLOCK 56 -#define MD5_LENGTH_BLOCK 8 -#define MD5_DIGEST_LENGTH 16 - -typedef struct MD5state_st - { - unsigned long A,B,C,D; - unsigned long Nl,Nh; - unsigned long data[MD5_LBLOCK]; - int num; - } MD5_CTX; - -#ifndef NOPROTO -void MD5_Init(MD5_CTX *c); -void MD5_Update(MD5_CTX *c, unsigned char *data, unsigned long len); -void MD5_Final(unsigned char *md, MD5_CTX *c); -unsigned char *MD5(unsigned char *d, unsigned long n, unsigned char *md); -#else -void MD5_Init(); -void MD5_Update(); -void MD5_Final(); -unsigned char *MD5(); -#endif - -/* to provide backward compatabilty to RSAREF calls ogud@tis.com 1997/11/14 */ -#define MD5Init(c) MD5_Init(c) -#define MD5Update(c,data, len) MD5_Update(c,data,len) -#define MD5Final(md, c) MD5_Final(md, c) -#ifdef __cplusplus -} -#endif - -#endif diff --git a/contrib/bind/lib/dst/md5_dgst.c b/contrib/bind/lib/dst/md5_dgst.c deleted file mode 100644 index 82e5a3829a0c7..0000000000000 --- a/contrib/bind/lib/dst/md5_dgst.c +++ /dev/null @@ -1,368 +0,0 @@ -/* crypto/md/md5_dgst.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdio.h> -#ifdef USE_MD5 /* Added by ogud@tis.com 1998/1/26 */ -#include "md5_locl.h" - -char *MD5_version="MD5 part of SSLeay 0.8.1 19-Jul-1997"; - -/* Implemented from RFC1321 The MD5 Message-Digest Algorithm - */ - -#define INIT_DATA_A (unsigned long)0x67452301L -#define INIT_DATA_B (unsigned long)0xefcdab89L -#define INIT_DATA_C (unsigned long)0x98badcfeL -#define INIT_DATA_D (unsigned long)0x10325476L - -#ifndef NOPROTO -static void md5_block(MD5_CTX *c, unsigned long *p); -#else -static void md5_block(); -#endif - -void MD5_Init(c) -MD5_CTX *c; - { - c->A=INIT_DATA_A; - c->B=INIT_DATA_B; - c->C=INIT_DATA_C; - c->D=INIT_DATA_D; - c->Nl=0; - c->Nh=0; - c->num=0; - } - -void MD5_Update(c, data, len) -MD5_CTX *c; -register unsigned char *data; -unsigned long len; - { - register ULONG *p; - int sw,sc; - ULONG l; - - if (len == 0) return; - - l=(c->Nl+(len<<3))&0xffffffffL; - /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to - * Wei Dai <weidai@eskimo.com> for pointing it out. */ - if (l < c->Nl) /* overflow */ - c->Nh++; - c->Nh+=(len>>29); - c->Nl=l; - - if (c->num != 0) - { - p=c->data; - sw=c->num>>2; - sc=c->num&0x03; - - if ((c->num+len) >= MD5_CBLOCK) - { - l= p[sw]; - p_c2l(data,l,sc); - p[sw++]=l; - for (; sw<MD5_LBLOCK; sw++) - { - c2l(data,l); - p[sw]=l; - } - len-=(MD5_CBLOCK-c->num); - - md5_block(c,p); - c->num=0; - /* drop through and do the rest */ - } - else - { - int ew,ec; - - c->num+=(int)len; - if ((sc+len) < 4) /* ugly, add char's to a word */ - { - l= p[sw]; - p_c2l_p(data,l,sc,len); - p[sw]=l; - } - else - { - ew=(c->num>>2); - ec=(c->num&0x03); - l= p[sw]; - p_c2l(data,l,sc); - p[sw++]=l; - for (; sw < ew; sw++) - { c2l(data,l); p[sw]=l; } - if (ec) - { - c2l_p(data,l,ec); - p[sw]=l; - } - } - return; - } - } - /* we now can process the input data in blocks of MD5_CBLOCK - * chars and save the leftovers to c->data. */ - p=c->data; - while (len >= MD5_CBLOCK) - { -#if defined(L_ENDIAN) || defined(B_ENDIAN) - memcpy(p,data,MD5_CBLOCK); - data+=MD5_CBLOCK; -#ifdef B_ENDIAN - for (sw=(MD5_LBLOCK/4); sw; sw--) - { - Endian_Reverse32(p[0]); - Endian_Reverse32(p[1]); - Endian_Reverse32(p[2]); - Endian_Reverse32(p[3]); - p+=4; - } -#endif -#else - for (sw=(MD5_LBLOCK/4); sw; sw--) - { - c2l(data,l); *(p++)=l; - c2l(data,l); *(p++)=l; - c2l(data,l); *(p++)=l; - c2l(data,l); *(p++)=l; - } -#endif - p=c->data; - md5_block(c,p); - len-=MD5_CBLOCK; - } - sc=(int)len; - c->num=sc; - if (sc) - { - sw=sc>>2; /* words to copy */ -#ifdef L_ENDIAN - p[sw]=0; - memcpy(p,data,sc); -#else - sc&=0x03; - for ( ; sw; sw--) - { c2l(data,l); *(p++)=l; } - c2l_p(data,l,sc); - *p=l; -#endif - } - } - -static void md5_block(c, X) -MD5_CTX *c; -register ULONG *X; - { - register ULONG A,B,C,D; - - A=c->A; - B=c->B; - C=c->C; - D=c->D; - - /* Round 0 */ - R0(A,B,C,D,X[ 0], 7,0xd76aa478L); - R0(D,A,B,C,X[ 1],12,0xe8c7b756L); - R0(C,D,A,B,X[ 2],17,0x242070dbL); - R0(B,C,D,A,X[ 3],22,0xc1bdceeeL); - R0(A,B,C,D,X[ 4], 7,0xf57c0fafL); - R0(D,A,B,C,X[ 5],12,0x4787c62aL); - R0(C,D,A,B,X[ 6],17,0xa8304613L); - R0(B,C,D,A,X[ 7],22,0xfd469501L); - R0(A,B,C,D,X[ 8], 7,0x698098d8L); - R0(D,A,B,C,X[ 9],12,0x8b44f7afL); - R0(C,D,A,B,X[10],17,0xffff5bb1L); - R0(B,C,D,A,X[11],22,0x895cd7beL); - R0(A,B,C,D,X[12], 7,0x6b901122L); - R0(D,A,B,C,X[13],12,0xfd987193L); - R0(C,D,A,B,X[14],17,0xa679438eL); - R0(B,C,D,A,X[15],22,0x49b40821L); - /* Round 1 */ - R1(A,B,C,D,X[ 1], 5,0xf61e2562L); - R1(D,A,B,C,X[ 6], 9,0xc040b340L); - R1(C,D,A,B,X[11],14,0x265e5a51L); - R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL); - R1(A,B,C,D,X[ 5], 5,0xd62f105dL); - R1(D,A,B,C,X[10], 9,0x02441453L); - R1(C,D,A,B,X[15],14,0xd8a1e681L); - R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L); - R1(A,B,C,D,X[ 9], 5,0x21e1cde6L); - R1(D,A,B,C,X[14], 9,0xc33707d6L); - R1(C,D,A,B,X[ 3],14,0xf4d50d87L); - R1(B,C,D,A,X[ 8],20,0x455a14edL); - R1(A,B,C,D,X[13], 5,0xa9e3e905L); - R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L); - R1(C,D,A,B,X[ 7],14,0x676f02d9L); - R1(B,C,D,A,X[12],20,0x8d2a4c8aL); - /* Round 2 */ - R2(A,B,C,D,X[ 5], 4,0xfffa3942L); - R2(D,A,B,C,X[ 8],11,0x8771f681L); - R2(C,D,A,B,X[11],16,0x6d9d6122L); - R2(B,C,D,A,X[14],23,0xfde5380cL); - R2(A,B,C,D,X[ 1], 4,0xa4beea44L); - R2(D,A,B,C,X[ 4],11,0x4bdecfa9L); - R2(C,D,A,B,X[ 7],16,0xf6bb4b60L); - R2(B,C,D,A,X[10],23,0xbebfbc70L); - R2(A,B,C,D,X[13], 4,0x289b7ec6L); - R2(D,A,B,C,X[ 0],11,0xeaa127faL); - R2(C,D,A,B,X[ 3],16,0xd4ef3085L); - R2(B,C,D,A,X[ 6],23,0x04881d05L); - R2(A,B,C,D,X[ 9], 4,0xd9d4d039L); - R2(D,A,B,C,X[12],11,0xe6db99e5L); - R2(C,D,A,B,X[15],16,0x1fa27cf8L); - R2(B,C,D,A,X[ 2],23,0xc4ac5665L); - /* Round 3 */ - R3(A,B,C,D,X[ 0], 6,0xf4292244L); - R3(D,A,B,C,X[ 7],10,0x432aff97L); - R3(C,D,A,B,X[14],15,0xab9423a7L); - R3(B,C,D,A,X[ 5],21,0xfc93a039L); - R3(A,B,C,D,X[12], 6,0x655b59c3L); - R3(D,A,B,C,X[ 3],10,0x8f0ccc92L); - R3(C,D,A,B,X[10],15,0xffeff47dL); - R3(B,C,D,A,X[ 1],21,0x85845dd1L); - R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL); - R3(D,A,B,C,X[15],10,0xfe2ce6e0L); - R3(C,D,A,B,X[ 6],15,0xa3014314L); - R3(B,C,D,A,X[13],21,0x4e0811a1L); - R3(A,B,C,D,X[ 4], 6,0xf7537e82L); - R3(D,A,B,C,X[11],10,0xbd3af235L); - R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL); - R3(B,C,D,A,X[ 9],21,0xeb86d391L); - - c->A+=A&0xffffffffL; - c->B+=B&0xffffffffL; - c->C+=C&0xffffffffL; - c->D+=D&0xffffffffL; - } - -void MD5_Final(md, c) -unsigned char *md; -MD5_CTX *c; - { - register int i,j; - register ULONG l; - register ULONG *p; - static unsigned char end[4]={0x80,0x00,0x00,0x00}; - unsigned char *cp=end; - - /* c->num should definitly have room for at least one more byte. */ - p=c->data; - j=c->num; - i=j>>2; - - /* purify often complains about the following line as an - * Uninitialized Memory Read. While this can be true, the - * following p_c2l macro will reset l when that case is true. - * This is because j&0x03 contains the number of 'valid' bytes - * already in p[i]. If and only if j&0x03 == 0, the UMR will - * occur but this is also the only time p_c2l will do - * l= *(cp++) instead of l|= *(cp++) - * Many thanks to Alex Tang <altitude@cic.net> for pickup this - * 'potential bug' */ -#ifdef PURIFY - if ((j&0x03) == 0) p[i]=0; -#endif - l=p[i]; - p_c2l(cp,l,j&0x03); - p[i]=l; - i++; - /* i is the next 'undefined word' */ - if (c->num >= MD5_LAST_BLOCK) - { - for (; i<MD5_LBLOCK; i++) - p[i]=0; - md5_block(c,p); - i=0; - } - for (; i<(MD5_LBLOCK-2); i++) - p[i]=0; - p[MD5_LBLOCK-2]=c->Nl; - p[MD5_LBLOCK-1]=c->Nh; - md5_block(c,p); - cp=md; - l=c->A; l2c(l,cp); - l=c->B; l2c(l,cp); - l=c->C; l2c(l,cp); - l=c->D; l2c(l,cp); - - /* clear stuff, md5_block may be leaving some stuff on the stack - * but I'm not worried :-) */ - c->num=0; -/* memset((char *)&c,0,sizeof(c));*/ - } - -#ifdef undef -int printit(l) -unsigned long *l; - { - int i,ii; - - for (i=0; i<2; i++) - { - for (ii=0; ii<8; ii++) - { - fprintf(stderr,"%08lx ",l[i*8+ii]); - } - fprintf(stderr,"\n"); - } - } -#endif -#endif /* USE_MD5 */ diff --git a/contrib/bind/lib/dst/md5_locl.h b/contrib/bind/lib/dst/md5_locl.h deleted file mode 100644 index b2f0028fbd368..0000000000000 --- a/contrib/bind/lib/dst/md5_locl.h +++ /dev/null @@ -1,190 +0,0 @@ -/* crypto/md/md5_locl.h */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include <stdlib.h> -#include <string.h> -#include "md5.h" - -#define ULONG unsigned long -#define UCHAR unsigned char -#define UINT unsigned int - -#if defined(NOCONST) -#define const -#endif - -#undef c2l -#define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \ - l|=(((unsigned long)(*((c)++)))<< 8), \ - l|=(((unsigned long)(*((c)++)))<<16), \ - l|=(((unsigned long)(*((c)++)))<<24)) - -#undef p_c2l -#define p_c2l(c,l,n) { \ - switch (n) { \ - case 0: l =((unsigned long)(*((c)++))); \ - case 1: l|=((unsigned long)(*((c)++)))<< 8; \ - case 2: l|=((unsigned long)(*((c)++)))<<16; \ - case 3: l|=((unsigned long)(*((c)++)))<<24; \ - } \ - } - -/* NOTE the pointer is not incremented at the end of this */ -#undef c2l_p -#define c2l_p(c,l,n) { \ - l=0; \ - (c)+=n; \ - switch (n) { \ - case 3: l =((unsigned long)(*(--(c))))<<16; \ - case 2: l|=((unsigned long)(*(--(c))))<< 8; \ - case 1: l|=((unsigned long)(*(--(c)))) ; \ - } \ - } - -#undef p_c2l_p -#define p_c2l_p(c,l,sc,len) { \ - switch (sc) \ - { \ - case 0: l =((unsigned long)(*((c)++))); \ - if (--len == 0) break; \ - case 1: l|=((unsigned long)(*((c)++)))<< 8; \ - if (--len == 0) break; \ - case 2: l|=((unsigned long)(*((c)++)))<<16; \ - } \ - } - -#undef l2c -#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff)) - -/* NOTE - c is not incremented as per l2c */ -#undef l2cn -#define l2cn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ - } \ - } - -/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */ -#if defined(WIN32) -/* 5 instructions with rotate instruction, else 9 */ -#define Endian_Reverse32(a) \ - { \ - unsigned long l=(a); \ - (a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \ - } -#else -/* 6 instructions with rotate instruction, else 8 */ -#define Endian_Reverse32(a) \ - { \ - unsigned long l=(a); \ - l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \ - (a)=ROTATE(l,16L); \ - } -#endif -/* -#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) -#define G(x,y,z) (((x) & (z)) | ((y) & (~(z)))) -*/ - -/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be - * simplified to the code below. Wei attributes these optimisations - * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. - */ -#define F(x,y,z) ((((y) ^ (z)) & (x)) ^ (z)) -#define G(x,y,z) ((((x) ^ (y)) & (z)) ^ (y)) -#define H(x,y,z) ((x) ^ (y) ^ (z)) -#define I(x,y,z) (((x) | (~(z))) ^ (y)) - -#undef ROTATE -#if defined(WIN32) -#define ROTATE(a,n) _lrotl(a,n) -#else -#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) -#endif - - -#define R0(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+F((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; };\ - -#define R1(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+G((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; }; - -#define R2(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+H((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; }; - -#define R3(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+I((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; }; diff --git a/contrib/bind/lib/dst/prandom.c b/contrib/bind/lib/dst/prandom.c deleted file mode 100644 index dcd53435f0e6a..0000000000000 --- a/contrib/bind/lib/dst/prandom.c +++ /dev/null @@ -1,853 +0,0 @@ -#ifndef LINT -static const char rcsid[] = "$Header: /proj/cvs/isc/bind/src/lib/dst/prandom.c,v 1.9 2000/07/17 07:36:53 vixie Exp $"; -#endif -/* - * Portions Copyright (c) 1995-1998 by Trusted Information Systems, 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 TRUSTED INFORMATION SYSTEMS - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * TRUSTED INFORMATION SYSTEMS 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. - */ - -#include "port_before.h" - -#include <assert.h> -#include <stdio.h> -#include <sys/types.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <time.h> -#include <dirent.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/time.h> - -#include "dst_internal.h" -#include "prand_conf.h" - -#include "port_after.h" - -#ifndef DST_NUM_HASHES -#define DST_NUM_HASHES 4 -#endif -#ifndef DST_NUMBER_OF_COUNTERS -#define DST_NUMBER_OF_COUNTERS 5 /* 32 * 5 == 160 == SHA(1) > MD5 */ -#endif - -/* - * the constant below is a prime number to make fixed data structues like - * stat and time wrap over blocks. This adds certain uncertanty to what is - * in each digested block. - * The prime number 2879 has the special property that when - * divided by 2,4 and 6 the result is also a prime numbers - */ - -#ifndef DST_RANDOM_BLOCK_SIZE -#define DST_RANDOM_BLOCK_SIZE 2879 -#endif - -/* - * This constant dictatates how many bits we shift to the right before using a - */ -#ifndef DST_SHIFT -#define DST_SHIFT 9 -#endif - -/* - * An initalizer that is as bad as any other with half the bits set - */ -#ifndef DST_RANDOM_PATTERN -#define DST_RANDOM_PATTERN 0x8765CA93 -#endif -/* - * things must have changed in the last 3600 seconds to be used - */ -#define MAX_OLD 3600 - - -/* - * these two data structure are used to process input data into digests, - * - * The first structure is containts a pointer to a DST HMAC key - * the variables accompanying are used for - * step : select every step byte from input data for the hash - * block: number of data elements going into each hash - * digested: number of data elements digested so far - * curr: offset into the next input data for the first byte. - */ -typedef struct hash { - DST_KEY *key; - void *ctx; - int digested, block, step, curr; -} prand_hash; - -/* - * This data structure controlls number of hashes and keeps track of - * overall progress in generating correct number of bytes of output. - * output : array to store the output data in - * needed : how many bytes of output are needed - * filled : number of bytes in output so far. - * bytes : total number of bytes processed by this structure - * file_digest : the HMAC key used to digest files. - */ -typedef struct work { - int needed, filled, bytes; - u_char *output; - prand_hash *hash[DST_NUM_HASHES]; - DST_KEY *file_digest; -} dst_work; - - -/* - * forward function declarations - */ -static int get_dev_random(u_char *output, int size); -static int do_time(dst_work *work); -static int do_ls(dst_work *work); -static int unix_cmd(dst_work *work); -static int digest_file(dst_work *work); - -static void force_hash(dst_work *work, prand_hash *hash); -static int do_hash(dst_work *work, prand_hash *hash, u_char *input, - int size); -static int my_digest(dst_work *tmp, u_char *input, int size); -static prand_hash *get_hmac_key(int step, int block); - -static int own_random(dst_work *work); - - -/* - * variables used in the quick random number generator - */ -static u_int32_t ran_val = DST_RANDOM_PATTERN; -static u_int32_t ran_cnt = (DST_RANDOM_PATTERN >> 10); - -/* - * setting the quick_random generator to particular values or if both - * input parameters are 0 then set it to initial vlaues - */ - -void -dst_s_quick_random_set(u_int32_t val, u_int32_t cnt) -{ - ran_val = (val == 0) ? DST_RANDOM_PATTERN : val; - ran_cnt = (cnt == 0) ? (DST_RANDOM_PATTERN >> 10) : cnt; -} - -/* - * this is a quick and random number generator that seems to generate quite - * good distribution of data - */ -u_int32_t -dst_s_quick_random(int inc) -{ - ran_val = ((ran_val >> 13) ^ (ran_val << 19)) ^ - ((ran_val >> 7) ^ (ran_val << 25)); - if (inc > 0) /* only increasing values accepted */ - ran_cnt += inc; - ran_val += ran_cnt++; - return (ran_val); -} - -/* - * get_dev_random: Function to read /dev/random reliably - * this function returns how many bytes where read from the device. - * port_after.h should set the control variable HAVE_DEV_RANDOM - */ -static int -get_dev_random(u_char *output, int size) -{ -#ifdef HAVE_DEV_RANDOM - struct stat st; - int n = 0, fd = -1, s; - - s = stat("/dev/random", &st); - if (s == 0 && S_ISCHR(st.st_mode)) { - if ((fd = open("/dev/random", O_RDONLY | O_NONBLOCK)) != -1) { - if ((n = read(fd, output, size)) < 0) - n = 0; - close(fd); - } - return (n); - } -#endif - return (0); -} - -/* - * Portable way of getting the time values if gettimeofday is missing - * then compile with -DMISSING_GETTIMEOFDAY time() is POSIX compliant but - * gettimeofday() is not. - * Time of day is predictable, we are looking for the randomness that comes - * the last few bits in the microseconds in the timer are hard to predict when - * this is invoked at the end of other operations - */ -struct timeval *mtime; -static int -do_time(dst_work *work) -{ - int cnt = 0; - static u_char tmp[sizeof(struct timeval) + sizeof(struct timezone)]; - struct timezone *zone; - - zone = (struct timezone *) tmp; - mtime = (struct timeval *)(tmp + sizeof(struct timezone)); - gettimeofday(mtime, zone); - assert(mtime->tv_usec >= 0 && mtime->tv_usec < 1000000); - cnt = sizeof(tmp); - my_digest(work, tmp, sizeof(tmp)); - - return (cnt); -} - -/* - * this function simulates the ls command, but it uses stat which gives more - * information and is harder to guess - * Each call to this function will visit the next directory on the list of - * directories, in a circular manner. - * return value is the number of bytes added to the temp buffer - * - * do_ls() does not visit subdirectories - * if attacker has access to machine it can guess most of the values seen - * thus it is important to only visit directories that are freqently updated - * Attacker that has access to the network can see network traffic - * when NFS mounted directories are accessed and know exactly the data used - * but may not know exactly in what order data is used. - * Returns the number of bytes that where returned in stat structures - */ -static int -do_ls(dst_work *work) -{ - struct dir_info { - uid_t uid; - gid_t gid; - off_t size; - time_t atime, mtime, ctime; - }; - static struct dir_info dir_info; - struct stat buf; - struct dirent *entry; - static int i = 0; - static unsigned long d_round = 0; - struct timeval tv; - int n = 0, dir_len, tb_i = 0, out = 0; - - char file_name[1024]; - u_char tmp_buff[1024]; - DIR *dir = NULL; - - if (dirs[i] == NULL) /* if at the end of the list start over */ - i = 0; - if (stat(dirs[i++], &buf)) /* directory does not exist */ - return (0); - - gettimeofday(&tv,NULL); - if (d_round == 0) - d_round = tv.tv_sec - MAX_OLD; - else if (i==1) /* if starting a new round cut what we accept */ - d_round += (tv.tv_sec - d_round)/2; - - if (buf.st_atime < d_round) - return (0); - - EREPORT(("do_ls i %d filled %4d in_temp %4d\n", - i-1, work->filled, work->in_temp)); - memcpy(tmp_buff, &buf, sizeof(buf)); - tb_i += sizeof(buf); - - - if ((dir = opendir(dirs[i-1])) == NULL)/* open it for read */ - return (0); - strcpy(file_name, dirs[i-1]); - dir_len = strlen(file_name); - file_name[dir_len++] = '/'; - while ((entry = readdir(dir))) { - int len = strlen(entry->d_name); - out += len; - if (my_digest(work, (u_char *)entry->d_name, len)) - break; - - memcpy(&file_name[dir_len], entry->d_name, len); - file_name[dir_len + len] = 0x0; - /* for all entries in dir get the stats */ - if (stat(file_name, &buf) == 0) { - n++; /* count successfull stat calls */ - /* copy non static fields */ - dir_info.uid += buf.st_uid; - dir_info.gid += buf.st_gid; - dir_info.size += buf.st_size; - dir_info.atime += buf.st_atime; - dir_info.mtime += buf.st_mtime; - dir_info.ctime += buf.st_ctime; - out += sizeof(dir_info); - if(my_digest(work, (u_char *)&dir_info, - sizeof(dir_info))) - break; - } - } - closedir(dir); /* done */ - out += do_time(work); /* add a time stamp */ - return (out); -} - - -/* - * unix_cmd() - * this function executes the a command from the cmds[] list of unix commands - * configured in the prand_conf.h file - * return value is the number of bytes added to the randomness temp buffer - * - * it returns the number of bytes that where read in - * if more data is needed at the end time is added to the data. - * This function maintains a state to selects the next command to run - * returns the number of bytes read in from the command - */ -static int -unix_cmd(dst_work *work) -{ - static int cmd_index = 0; - int cnt = 0, n; - FILE *pipe; - u_char buffer[4096]; - - if (cmds[cmd_index] == NULL) - cmd_index = 0; - EREPORT(("unix_cmd() i %d filled %4d in_temp %4d\n", - cmd_index, work->filled, work->in_temp)); - pipe = popen(cmds[cmd_index++], "r"); /* execute the command */ - - while ((n = fread(buffer, sizeof(char), sizeof(buffer), pipe)) > 0) { - cnt += n; /* process the output */ - if (my_digest(work, buffer, n)) - break; - /* this adds some randomness to the output */ - cnt += do_time(work); - } - while ((n = fread(buffer, sizeof(char), sizeof(buffer), pipe)) > 0) - NULL; /* drain the pipe */ - pclose(pipe); - return (cnt); /* read how many bytes where read in */ -} - -/* - * digest_file() This function will read a file and run hash over it - * input is a file name - */ -static int -digest_file(dst_work *work) -{ - static int f_cnt = 0; - static unsigned long f_round = 0; - FILE *fp; - void *ctx; - const char *name; - int no, i; - struct stat st; - struct timeval tv; - u_char buf[1024]; - - if (f_round == 0 || files[f_cnt] == NULL || work->file_digest == NULL) - if (gettimeofday(&tv, NULL)) /* only do this if needed */ - return (0); - if (f_round == 0) /* first time called set to one hour ago */ - f_round = (tv.tv_sec - MAX_OLD); - name = files[f_cnt++]; - if (files[f_cnt] == NULL) { /* end of list of files */ - if(f_cnt <= 1) /* list is too short */ - return (0); - f_cnt = 0; /* start again on list */ - f_round += (tv.tv_sec - f_round)/2; /* set new cutoff */ - work->file_digest = dst_free_key(work->file_digest); - } - if (work->file_digest == NULL) { - work->file_digest = dst_buffer_to_key("", KEY_HMAC_MD5, 0, 0, - (u_char *)&tv, sizeof(tv)); - if (work->file_digest == NULL) - return (0); - } - if (access(name, R_OK) || stat(name, &st)) - return (0); /* no such file or not allowed to read it */ - if (strncmp(name, "/proc/", 6) && st.st_mtime < f_round) - return(0); /* file has not changed recently enough */ - if (dst_sign_data(SIG_MODE_INIT, work->file_digest, &ctx, - NULL, 0, NULL, 0)) { - work->file_digest = dst_free_key(work->file_digest); - return (0); - } - if ((fp = fopen(name, "r")) == NULL) - return (0); - for (no = 0; (i = fread(buf, sizeof(*buf), sizeof(buf), fp)) > 0; - no += i) - dst_sign_data(SIG_MODE_UPDATE, work->file_digest, &ctx, - buf, i, NULL, 0); - - fclose(fp); - if (no >= 64) { - i = dst_sign_data(SIG_MODE_FINAL, work->file_digest, &ctx, - NULL, 0, &work->output[work->filled], - DST_HASH_SIZE); - if (i > 0) - work->filled += i; - } - else if (i > 0) - my_digest(work, buf, i); - my_digest(work, (u_char *)name, strlen(name)); - return (no + strlen(name)); -} - -/* - * function to perform the FINAL and INIT operation on a hash if allowed - */ -static void -force_hash(dst_work *work, prand_hash *hash) -{ - int i = 0; - - /* - * if more than half a block then add data to output - * otherwise adde the digest to the next hash - */ - if ((hash->digested * 2) > hash->block) { - i = dst_sign_data(SIG_MODE_FINAL, hash->key, &hash->ctx, - NULL, 0, &work->output[work->filled], - DST_HASH_SIZE); - - hash->digested = 0; - dst_sign_data(SIG_MODE_INIT, hash->key, &hash->ctx, - NULL, 0, NULL, 0); - if (i > 0) - work->filled += i; - } - return; -} - -/* - * This function takes the input data does the selection of data specified - * by the hash control block. - * The step varialbe in the work sturcture determines which 1/step bytes - * are used, - * - */ -static int -do_hash(dst_work *work, prand_hash *hash, u_char *input, int size) -{ - u_char *tmp = input, *tp; - int i, cnt = size, n, needed, avail, dig, tmp_size = 0; - - if (cnt <= 0 || input == NULL) - return (0); - - if (hash->step > 1) { /* if using subset of input data */ - tmp_size = size / hash->step + 2; - tp = tmp = malloc(tmp_size); - for (cnt = 0, i = hash->curr; i < size; i += hash->step, cnt++) - *(tp++) = input[i]; - /* calcutate the starting point in the next input set */ - hash->curr = (hash->step - (i - size)) % hash->step; - } - /* digest the data in block sizes */ - for (n = 0; n < cnt; n += needed) { - avail = (cnt - n); - needed = hash->block - hash->digested; - dig = (avail < needed) ? avail : needed; - dst_sign_data(SIG_MODE_UPDATE, hash->key, &hash->ctx, - &tmp[n], dig, NULL, 0); - hash->digested += dig; - if (hash->digested >= hash->block) - force_hash(work, hash); - if (work->needed < work->filled) { - if (tmp != input) - SAFE_FREE2(tmp, tmp_size); - return (1); - } - } - if (tmp_size > 0) - SAFE_FREE2(tmp, tmp_size); - return (0); -} - -/* - * Copy data from INPUT for length SIZE into the work-block TMP. - * If we fill the work-block, digest it; then, - * if work-block needs more data, keep filling with the rest of the input. - */ -static int -my_digest(dst_work *work, u_char *input, int size) -{ - - int i, full = 0; - static unsigned counter; - - counter += size; - /* first do each one of the hashes */ - for (i = 0; i < DST_NUM_HASHES && full == 0; i++) - full = do_hash(work, work->hash[i], input, size) + - do_hash(work, work->hash[i], (u_char *) &counter, - sizeof(counter)); -/* - * if enough data has be generated do final operation on all hashes - * that have enough date for that - */ - for (i = 0; full && (i < DST_NUM_HASHES); i++) - force_hash(work, work->hash[i]); - - return (full); -} - -/* - * this function gets some semi random data and sets that as an HMAC key - * If we get a valid key this function returns that key initalized - * otherwise it returns NULL; - */ -static prand_hash * -get_hmac_key(int step, int block) -{ - - u_char *buff; - int temp = 0, n = 0, size = 70; - DST_KEY *new_key = NULL; - prand_hash *new = NULL; - - /* use key that is larger than digest algorithms (64) for key size */ - buff = malloc(size); - if (buff == NULL) - return (NULL); - /* do not memset the allocated memory to get random bytes there */ - /* time of day is somewhat random expecialy in the last bytes */ - gettimeofday((struct timeval *) &buff[n], NULL); - n += sizeof(struct timeval); - -/* get some semi random stuff in here stir it with micro seconds */ - if (n < size) { - temp = dst_s_quick_random((int) buff[n - 1]); - memcpy(&buff[n], &temp, sizeof(temp)); - n += sizeof(temp); - } -/* get the pid of this process and its parent */ - if (n < size) { - temp = (int) getpid(); - memcpy(&buff[n], &temp, sizeof(temp)); - n += sizeof(temp); - } - if (n < size) { - temp = (int) getppid(); - memcpy(&buff[n], &temp, sizeof(temp)); - n += sizeof(temp); - } -/* get the user ID */ - if (n < size) { - temp = (int) getuid(); - memcpy(&buff[n], &temp, sizeof(temp)); - n += sizeof(temp); - } -#ifndef GET_HOST_ID_MISSING - if (n < size) { - temp = (int) gethostid(); - memcpy(&buff[n], &temp, sizeof(temp)); - n += sizeof(temp); - } -#endif -/* get some more random data */ - if (n < size) { - temp = dst_s_quick_random((int) buff[n - 1]); - memcpy(&buff[n], &temp, sizeof(temp)); - n += sizeof(temp); - } -/* covert this into a HMAC key */ - new_key = dst_buffer_to_key("", KEY_HMAC_MD5, 0, 0, buff, size); - SAFE_FREE(buff); - -/* get the control structure */ - if ((new = malloc(sizeof(prand_hash))) == NULL) - return (NULL); - new->digested = new->curr = 0; - new->step = step; - new->block = block; - new->key = new_key; - if (dst_sign_data(SIG_MODE_INIT, new_key, &new->ctx, NULL, 0, NULL, 0)) - return (NULL); - - return (new); -} - -/* - * own_random() - * This function goes out and from various sources tries to generate enough - * semi random data that a hash function can generate a random data. - * This function will iterate between the two main random source sources, - * information from programs and directores in random order. - * This function return the number of bytes added to the random output buffer. - */ -static int -own_random(dst_work *work) -{ - int dir = 0, b; - int bytes, n, cmd = 0, dig = 0; - int start =0; -/* - * now get the initial seed to put into the quick random function from - * the address of the work structure - */ - bytes = (int) getpid(); -/* - * proceed while needed - */ - while (work->filled < work->needed) { - EREPORT(("own_random r %08x b %6d t %6d f %6d\n", - ran_val, bytes, work->in_temp, work->filled)); -/* pick a random number in the range of 0..7 based on that random number - * perform some operations that yield random data - */ - start = work->filled; - n = (dst_s_quick_random(bytes) >> DST_SHIFT) & 0x07; - switch (n) { - case 0: - case 3: - if (sizeof(cmds) > 2 *sizeof(*cmds)) { - b = unix_cmd(work); - cmd += b; - } - break; - - case 1: - case 7: - if (sizeof(dirs) > 2 *sizeof(*dirs)) { - b = do_ls(work); - dir += b; - } - break; - - case 4: - case 5: - /* retry getting data from /dev/random */ - b = get_dev_random(&work->output[work->filled], - work->needed - work->filled); - if (b > 0) - work->filled += b; - break; - - case 6: - if (sizeof(files) > 2 * sizeof(*files)) { - b = digest_file(work); - dig += b; - } - break; - - case 2: - default: /* to make sure we make some progress */ - work->output[work->filled++] = 0xff & - dst_s_quick_random(bytes); - b = 1; - break; - } - if (b > 0) - bytes += b; - } - return (work->filled); -} - - -/* - * dst_s_random() This function will return the requested number of bytes - * of randomness to the caller it will use the best available sources of - * randomness. - * The current order is to use /dev/random, precalculated randomness, and - * finaly use some system calls and programs to generate semi random data that - * is then digested to generate randomness. - * This function is thread safe as each thread uses its own context, but - * concurrent treads will affect each other as they update shared state - * information. - * It is strongly recommended that this function be called requesting a size - * that is not a multiple of the output of the hash function used. - * - * If /dev/random is not available this function is not suitable to generate - * large ammounts of data, rather it is suitable to seed a pseudo-random - * generator - * Returns the number of bytes put in the output buffer - */ -int -dst_s_random(u_char *output, int size) -{ - int n = 0, s, i; - static u_char old_unused[DST_HASH_SIZE * DST_NUM_HASHES]; - static int unused = 0; - - if (size <= 0 || output == NULL) - return (0); - - if (size >= 2048) - return (-1); - /* - * Read from /dev/random - */ - n = get_dev_random(output, size); - /* - * If old data is available and needed use it - */ - if (n < size && unused > 0) { - int need = size - n; - if (unused <= need) { - memcpy(output, old_unused, unused); - n += unused; - unused = 0; - } else { - memcpy(output, old_unused, need); - n += need; - unused -= need; - memcpy(old_unused, &old_unused[need], unused); - } - } - /* - * If we need more use the simulated randomness here. - */ - if (n < size) { - dst_work *my_work = (dst_work *) malloc(sizeof(dst_work)); - if (my_work == NULL) - return (n); - my_work->needed = size - n; - my_work->filled = 0; - my_work->output = (u_char *) malloc(my_work->needed + - DST_HASH_SIZE * - DST_NUM_HASHES); - my_work->file_digest = NULL; - if (my_work->output == NULL) - return (n); - memset(my_work->output, 0x0, my_work->needed); -/* allocate upto 4 different HMAC hash functions out of order */ -#if DST_NUM_HASHES >= 3 - my_work->hash[2] = get_hmac_key(3, DST_RANDOM_BLOCK_SIZE / 2); -#endif -#if DST_NUM_HASHES >= 2 - my_work->hash[1] = get_hmac_key(7, DST_RANDOM_BLOCK_SIZE / 6); -#endif -#if DST_NUM_HASHES >= 4 - my_work->hash[3] = get_hmac_key(5, DST_RANDOM_BLOCK_SIZE / 4); -#endif - my_work->hash[0] = get_hmac_key(1, DST_RANDOM_BLOCK_SIZE); - if (my_work->hash[0] == NULL) /* if failure bail out */ - return (n); - s = own_random(my_work); -/* if more generated than needed store it for future use */ - if (s >= my_work->needed) { - EREPORT(("dst_s_random(): More than needed %d >= %d\n", - s, my_work->needed)); - memcpy(&output[n], my_work->output, my_work->needed); - n += my_work->needed; - /* saving unused data for next time */ - unused = s - my_work->needed; - memcpy(old_unused, &my_work->output[my_work->needed], - unused); - } else { - /* XXXX This should not happen */ - EREPORT(("Not enough %d >= %d\n", s, my_work->needed)); - memcpy(&output[n], my_work->output, s); - n += my_work->needed; - } - -/* delete the allocated work area */ - for (i = 0; i < DST_NUM_HASHES; i++) { - dst_free_key(my_work->hash[i]->key); - SAFE_FREE(my_work->hash[i]); - } - SAFE_FREE(my_work->output); - SAFE_FREE(my_work); - } - return (n); -} - -/* - * A random number generator that is fast and strong - * this random number generator is based on HASHing data, - * the input to the digest function is a collection of <NUMBER_OF_COUNTERS> - * counters that is incremented between digest operations - * each increment operation amortizes to 2 bits changed in that value - * for 5 counters thus the input will amortize to have 10 bits changed - * The counters are initaly set using the strong random function above - * the HMAC key is selected by the same methold as the HMAC keys for the - * strong random function. - * Each set of counters is used for 2^25 operations - * - * returns the number of bytes written to the output buffer - * or negative number in case of error - */ -int -dst_s_semi_random(u_char *output, int size) -{ - static u_int32_t counter[DST_NUMBER_OF_COUNTERS]; - static u_char semi_old[DST_HASH_SIZE]; - static int semi_loc = 0, cnt = 0, hb_size = 0; - static DST_KEY *my_key = NULL; - prand_hash *hash; - int out = 0, i, n; - - if (output == NULL || size <= 0) - return (-2); - -/* check if we need a new key */ - if (my_key == NULL || cnt > (1 << 25)) { /* get HMAC KEY */ - if (my_key) - my_key->dk_func->destroy(my_key); - if ((hash = get_hmac_key(1, DST_RANDOM_BLOCK_SIZE)) == NULL) - return (0); - my_key = hash->key; -/* check if the key works stir the new key using some old random data */ - hb_size = dst_sign_data(SIG_MODE_ALL, my_key, NULL, - (u_char *) counter, sizeof(counter), - semi_old, sizeof(semi_old)); - if (hb_size <= 0) { - EREPORT(("dst_s_semi_random() Sign of alg %d failed %d\n", - my_key->dk_alg, hb_size)); - return (-1); - } -/* new set the counters to random values */ - dst_s_random((u_char *) counter, sizeof(counter)); - cnt = 0; - } -/* if old data around use it first */ - if (semi_loc < hb_size) { - if (size <= hb_size - semi_loc) { /* need less */ - memcpy(output, &semi_old[semi_loc], size); - semi_loc += size; - return (size); /* DONE */ - } else { - out = hb_size - semi_loc; - memcpy(output, &semi_old[semi_loc], out); - semi_loc += out; - } - } -/* generate more randome stuff */ - while (out < size) { - /* - * modify at least one bit by incrementing at least one counter - * based on the last bit of the last counter updated update - * the next one. - * minimaly this operation will modify at least 1 bit, - * amortized 2 bits - */ - for (n = 0; n < DST_NUMBER_OF_COUNTERS; n++) - i = (int) counter[n]++; - - i = dst_sign_data(SIG_MODE_ALL, my_key, NULL, - (u_char *) counter, hb_size, - semi_old, sizeof(semi_old)); - if (i != hb_size) - EREPORT(("HMAC SIGNATURE FAILURE %d\n", i)); - cnt++; - if (size - out < i) /* Not all data is needed */ - semi_loc = i = size - out; - memcpy(&output[out], semi_old, i); - out += i; - } - return (out); -} diff --git a/contrib/bind/lib/dst/rsaref_link.c b/contrib/bind/lib/dst/rsaref_link.c deleted file mode 100644 index 2ccd96ec36b82..0000000000000 --- a/contrib/bind/lib/dst/rsaref_link.c +++ /dev/null @@ -1,755 +0,0 @@ -#ifdef RSAREF -static const char rcsid[] = "$Header: /proj/cvs/isc/bind/src/lib/dst/rsaref_link.c,v 1.7 2000/07/17 07:36:53 vixie Exp $"; - -/* - * Portions Copyright (c) 1995-1998 by Trusted Information Systems, 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 TRUSTED INFORMATION SYSTEMS - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * TRUSTED INFORMATION SYSTEMS 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. - */ - -/* - * This file contains two components - * 1. Interface to the rsaref library to allow compilation when RSAREF is - * not available all calls to RSAREF are contained inside this file. - * 2. The glue to connvert RSA{REF} KEYS to and from external formats - */ -#include "port_before.h" - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <memory.h> -#include <sys/param.h> -#include <sys/time.h> -#include <netinet/in.h> - -#include "dst_internal.h" - -# ifdef __STDC__ -# define PROTOTYPES 1 -# else -# define PROTOTYPES 0 -# endif - -# include <global.h> -# include <rsaref.h> - -#include "port_after.h" - - -typedef struct rsakey { - char *rk_signer; - R_RSA_PRIVATE_KEY *rk_Private_Key; - R_RSA_PUBLIC_KEY *rk_Public_Key; -} RSA_Key; - - -static int dst_rsaref_sign(const int mode, DST_KEY *key, void **context, - const u_char *data, const int len, - u_char *signature, const int sig_len); -static int dst_rsaref_verify(const int mode, DST_KEY *key, void **context, - const u_char *data, const int len, - const u_char *signature, const int sig_len); - -static int dst_rsaref_to_dns_key(const DST_KEY *public, u_char *out_str, - const int out_len); -static int dst_rsaref_from_dns_key(DST_KEY *s_key, const u_char *key, - const int len); - -static int dst_rsaref_key_to_file_format(const DST_KEY *dkey, - u_char *buff, - const int buff_len); -static int dst_rsaref_key_from_file_format(DST_KEY *dkey, - const u_char *buff, - const int buff_len); - -static int dst_rsaref_compare_keys(const DST_KEY *rkey1, - const DST_KEY *rkey2); -static void *dst_rsaref_free_key_structure(void *d_key); - -static int dst_rsaref_generate_keypair(DST_KEY *key, const int exp); - -static void dst_rsaref_init_random_struct(R_RANDOM_STRUCT * randomstruct); - -/* - * dst_rsaref_init() Function to answer set up function pointers for RSAREF - * related functions - */ -int -dst_rsaref_init() -{ - if (dst_t_func[KEY_RSA] != NULL) - return (1); - dst_t_func[KEY_RSA] = malloc(sizeof(struct dst_func)); - if (dst_t_func[KEY_RSA] == NULL) - return (0); - memset(dst_t_func[KEY_RSA], 0, sizeof(struct dst_func)); - dst_t_func[KEY_RSA]->sign = dst_rsaref_sign; - dst_t_func[KEY_RSA]->verify = dst_rsaref_verify; - dst_t_func[KEY_RSA]->compare = dst_rsaref_compare_keys; - dst_t_func[KEY_RSA]->generate = dst_rsaref_generate_keypair; - dst_t_func[KEY_RSA]->destroy = dst_rsaref_free_key_structure; - dst_t_func[KEY_RSA]->to_dns_key = dst_rsaref_to_dns_key; - dst_t_func[KEY_RSA]->from_dns_key = dst_rsaref_from_dns_key; - dst_t_func[KEY_RSA]->to_file_fmt = dst_rsaref_key_to_file_format; - dst_t_func[KEY_RSA]->from_file_fmt = dst_rsaref_key_from_file_format; - return (1); -} - -/* - * dst_rsa_sign - * Call RSAREF signing functions to sign a block of data. - * There are three steps to signing, INIT (initialize structures), - * UPDATE (hash (more) data), FINAL (generate a signature). This - * routine performs one or more of these steps. - * Parameters - * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL. - * key pointer to a RSA key structure that points to public key - * and context to use. - * data data to be signed. - * len length in bytes of data. - * signature location to store signature. - * sig_len size of the signature storage area - * returns - * N Success on SIG_MODE_FINAL = returns signature length in bytes - * 0 Success on SIG_MODE_INIT and UPDATE - * <0 Failure - */ - - -static int -dst_rsaref_sign(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - u_char *signature, const int sig_len) -{ - int sign_len = 0; - R_SIGNATURE_CTX *ctx = NULL; - - if (mode & SIG_MODE_INIT) - ctx = malloc(sizeof(*ctx)); - else if (context) - ctx = (R_SIGNATURE_CTX *) *context; - if (ctx == NULL) - return (-1); - - if ((mode & SIG_MODE_INIT) && R_SignInit(ctx, DA_MD5)) - return (SIGN_INIT_FAILURE); - - /* equivalent of SIG_MODE_UPDATE */ - if ((mode & SIG_MODE_UPDATE) && (data && len > 0) && - R_SignUpdate(ctx, (u_char *) data, len)) - return (SIGN_UPDATE_FAILURE); - - if (mode & SIG_MODE_FINAL) { - RSA_Key *key = (RSA_Key *) dkey->dk_KEY_struct; - if (signature == NULL || - sig_len < (int)(key->rk_Public_Key->bits + 7) / 8) - return (SIGN_FINAL_FAILURE); - if(key == NULL || key->rk_Private_Key == NULL) - return (-1); - if (R_SignFinal(ctx, signature, &sign_len, - key->rk_Private_Key)) - return (SIGN_FINAL_FAILURE); - SAFE_FREE(ctx); - } - else { - if (context == NULL) - return (-1); - *context = (void *) ctx; - } - return (sign_len); -} - - -/* - * dst_rsaref_verify() - * Calls RSAREF verification routines. There are three steps to - * verification, INIT (initialize structures), UPDATE (hash (more) data), - * FINAL (generate a signature). This routine performs one or more of - * these steps. - * Parameters - * mode SIG_MODE_INIT, SIG_MODE_UPDATE and/or SIG_MODE_FINAL. - * key pointer to a RSA key structure that points to public key - * and context to use. - * data data signed. - * len length in bytes of data. - * signature signature. - * sig_len length in bytes of signature. - * returns - * 0 Success - * <0 Failure - */ - -static int -dst_rsaref_verify(const int mode, DST_KEY *dkey, void **context, - const u_char *data, const int len, - const u_char *signature, const int sig_len) -{ - R_SIGNATURE_CTX *ctx = NULL; - - if (mode & SIG_MODE_INIT) - ctx = malloc(sizeof(*ctx)); - else if (context) - ctx = (R_SIGNATURE_CTX *) *context; - if (ctx == NULL) - return (-1); - - if ((mode & SIG_MODE_INIT) && R_VerifyInit(ctx, DA_MD5)) - return (VERIFY_INIT_FAILURE); - - if ((mode & SIG_MODE_UPDATE) && (data && len > 0) && - R_VerifyUpdate(ctx, (u_char *) data, len)) - return (VERIFY_UPDATE_FAILURE); - - if ((mode & SIG_MODE_FINAL)) { - RSA_Key *key = (RSA_Key *) dkey->dk_KEY_struct; - - if (key == NULL || key->rk_Public_Key == NULL) - return (-1); - if (signature == NULL || sig_len <= 0) - return (VERIFY_FINAL_FAILURE); - if (R_VerifyFinal(ctx, (u_char *) signature, sig_len, - key->rk_Public_Key)) - return (VERIFY_FINAL_FAILURE); - } - else { - if (context == NULL) - return (-1); - *context = (void *) ctx; - } - - return (0); -} - - -/* - * dst_rsaref_to_dns_key - * Converts key in RSAREF to DNS distribution format - * This function gets in a pointer to the public key and a work area - * to write the key into. - * Parameters - * public KEY structure - * out_str buffer to write encoded key into - * out_len size of out_str - * Return - * N >= 0 length of encoded key - * n < 0 error - */ - -static int -dst_rsaref_to_dns_key(const DST_KEY *in_key, u_char *out_str, - const int out_len) -{ - int n, loc; - R_RSA_PUBLIC_KEY *public; - u_char *op = (u_char *) out_str; - - if (in_key == NULL || in_key->dk_KEY_struct == NULL || - out_len <= 0 || out_str == NULL) - return (-1); - public = (R_RSA_PUBLIC_KEY *) - ((RSA_Key *) in_key->dk_KEY_struct)->rk_Public_Key; - if (public == NULL) - return (-1); - - memset(op, 0, out_len); - - /* find first non zero */ - for (n = 0; public->exponent[n] == 0x0; n++) ; - - n = (MAX_RSA_MODULUS_LEN - n); /* find lenght of exponent */ - *op++ = (u_int8_t) n; - - if (n > (out_len - (op-out_str))) - return (-1); - memcpy(op, &public->exponent[MAX_RSA_MODULUS_LEN - n], n); - op += n; - n++; /* include the lenght field in this count */ - - /* find first non zero */ - for (loc = 0; public->modulus[loc] == 0x0; loc++) ; - - /*copy exponent */ - if ((MAX_RSA_MODULUS_LEN - loc) > (out_len - (op-out_str))) - return (-1); - memcpy(op, &public->modulus[loc], MAX_RSA_MODULUS_LEN - loc); - n += (MAX_RSA_MODULUS_LEN - loc); - return (n); -} - - -/* - * dst_rsaref_from_dns_key - * Converts from a DNS KEY RR format to an RSA KEY. - * Parameters - * len Length in bytes of DNS key - * key DNS key - * name Key name - * s_key DST structure that will point to the RSA key this routine - * will build. - * Return - * -1 The input key has fields that are larger than this package supports - * 0 The input key, s_key or name was null. - * 1 Success - */ -static int -dst_rsaref_from_dns_key(DST_KEY *s_key, const u_char *key, const int len) -{ - int bytes; - u_char *key_ptr; - RSA_Key *r_key; - - if (key == NULL || s_key == NULL || len < 0) - return (0); - - if (s_key->dk_KEY_struct) { /* do not reuse */ - dst_rsaref_free_key_structure(s_key->dk_KEY_struct); - s_key->dk_KEY_struct = NULL; - } - if (len == 0) /* null key no conversion needed */ - return (1); - - if ((r_key = (RSA_Key *) malloc(sizeof(RSA_Key))) == NULL) { - EREPORT(("dst_rsaref_from_dns_key(): Memory allocation error 1\n")); - return (0); - } - memset(r_key, 0, sizeof(RSA_Key)); - s_key->dk_KEY_struct = (void *) r_key; - r_key->rk_signer = strdup(s_key->dk_key_name); - r_key->rk_Public_Key = (R_RSA_PUBLIC_KEY *) - malloc(sizeof(R_RSA_PUBLIC_KEY)); - if (r_key->rk_Public_Key == NULL) { - EREPORT(("dst_rsaref_from_dns_key(): Memory allocation error 3\n")); - return (0); - } - memset(r_key->rk_Public_Key, 0, sizeof(R_RSA_PUBLIC_KEY)); - key_ptr = (u_char *) key; - bytes = (int) *key_ptr++; /* length of exponent in bytes */ - if (bytes == 0) { /* special case for long exponents */ - bytes = (int) dst_s_get_int16(key_ptr); - key_ptr += sizeof(u_int16_t); - } - if (bytes > MAX_RSA_MODULUS_LEN) { - dst_rsaref_free_key_structure(r_key); - return (-1); - } - memcpy(&r_key->rk_Public_Key->exponent[MAX_RSA_MODULUS_LEN - bytes], - key_ptr, bytes); - - key_ptr += bytes; /* beginning of modulus */ - bytes = len - bytes - 1; /* length of modulus */ - if (bytes > MAX_RSA_MODULUS_LEN) { - dst_rsaref_free_key_structure(r_key); - return (-1); - } - memcpy(&r_key->rk_Public_Key->modulus[MAX_RSA_MODULUS_LEN - bytes], - key_ptr, bytes); - r_key->rk_Public_Key->bits = bytes * 8; - s_key->dk_id = (u_int16_t) dst_s_get_int16((u_char *) - &r_key->rk_Public_Key->modulus[MAX_RSA_MODULUS_LEN - 3]); - s_key->dk_key_size = r_key->rk_Public_Key->bits; - - return (1); -} - - -/* - * dst_rsaref_key_to_file_format - * Encodes an RSA Key into the portable file format. - * Parameters - * rkey RSA KEY structure - * buff output buffer - * buff_len size of output buffer - * Return - * 0 Failure - null input rkey - * -1 Failure - not enough space in output area - * N Success - Length of data returned in buff - */ - -static int -dst_rsaref_key_to_file_format(const DST_KEY *in_key, u_char *buff, - const int buff_len) -{ - u_char *bp; - int len, b_len; - R_RSA_PRIVATE_KEY *rkey; - - if (in_key == NULL || in_key->dk_KEY_struct == NULL) - return (-1); - rkey = (R_RSA_PRIVATE_KEY *) - ((RSA_Key *) in_key->dk_KEY_struct)->rk_Private_Key; - if (rkey == NULL) /* no output */ - return (0); - if (buff == NULL || buff_len <= (int) strlen(key_file_fmt_str)) - return (-1); /* no OR not enough space in output area */ - - memset(buff, 0, buff_len); /* just in case */ - /* write file header */ - sprintf(buff, key_file_fmt_str, KEY_FILE_FORMAT, KEY_RSA, "RSA"); - - bp = (char *) strchr(buff, '\0'); - b_len = buff_len - (bp - buff); - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Modulus: ", - rkey->modulus, - MAX_RSA_MODULUS_LEN)) <= 0) - return (-1); - - bp += len; - b_len -= len; - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "PublicExponent: ", - rkey->publicExponent, - MAX_RSA_MODULUS_LEN)) <= 0) - return (-2); - bp += len; - b_len -= len; - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "PrivateExponent: ", - rkey->exponent, - MAX_RSA_MODULUS_LEN)) <= 0) - return (-3); - bp += len; - b_len -= len; - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Prime1: ", - rkey->prime[0], - MAX_RSA_PRIME_LEN)) < 0) - return (-4); - bp += len; - b_len -= len; - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Prime2: ", - rkey->prime[1], - MAX_RSA_PRIME_LEN)) < 0) - return (-5); - bp += len; - b_len -= len; - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Exponent1: ", - rkey->primeExponent[0], - MAX_RSA_PRIME_LEN)) < 0) - return (-6); - bp += len; - b_len -= len; - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Exponent2: ", - rkey->primeExponent[1], - MAX_RSA_PRIME_LEN)) < 0) - return (-7); - bp += len; - b_len -= len; - if ((len = dst_s_conv_bignum_u8_to_b64(bp, b_len, "Coefficient: ", - rkey->coefficient, - MAX_RSA_PRIME_LEN)) < 0) - return (-8); - bp += len; - b_len -= len; - return (buff_len - b_len); -} - - -/* - * dst_rsaref_key_from_file_format - * Converts contents of a private key file into a private RSA key. - * Parameters - * r_key structure to put key into - * buff buffer containing the encoded key - * buff_len the length of the buffer - * Return - * n >= 0 Foot print of the key converted - * n < 0 Error in conversion - */ - -static int -dst_rsaref_key_from_file_format(DST_KEY *d_key, const u_char *buff, - const int buff_len) -{ - const char *p = (char *) buff; - R_RSA_PRIVATE_KEY key; - int foot = -1; - RSA_Key *r_key; - - if (d_key == NULL || buff == NULL || buff_len < 0) - return (-1); - - memset(&key, 0, sizeof(key)); - - if (!dst_s_verify_str(&p, "Modulus: ")) - return (-3); - - if (!dst_s_conv_bignum_b64_to_u8(&p, key.modulus, MAX_RSA_MODULUS_LEN)) - return (-4); - - key.bits = dst_s_calculate_bits(key.modulus, MAX_RSA_MODULUS_BITS); - - while (*++p && p < (char *) &buff[buff_len]) { - if (dst_s_verify_str(&p, "PublicExponent: ")) { - if (!dst_s_conv_bignum_b64_to_u8(&p, - key.publicExponent, - MAX_RSA_MODULUS_LEN)) - return (-5); - } else if (dst_s_verify_str(&p, "PrivateExponent: ")) { - if (!dst_s_conv_bignum_b64_to_u8(&p, key.exponent, - MAX_RSA_MODULUS_LEN)) - return (-6); - } else if (dst_s_verify_str(&p, "Prime1: ")) { - if (!dst_s_conv_bignum_b64_to_u8(&p, key.prime[0], - MAX_RSA_PRIME_LEN)) - return (-7); - } else if (dst_s_verify_str(&p, "Prime2: ")) { - if (!dst_s_conv_bignum_b64_to_u8(&p, key.prime[1], - MAX_RSA_PRIME_LEN)) - return (-8); - } else if (dst_s_verify_str(&p, "Exponent1: ")) { - if (!dst_s_conv_bignum_b64_to_u8(&p, - key.primeExponent[0], - MAX_RSA_PRIME_LEN)) - return (-9); - } else if (dst_s_verify_str(&p, "Exponent2: ")) { - if (!dst_s_conv_bignum_b64_to_u8(&p, - key.primeExponent[1], - MAX_RSA_PRIME_LEN)) - return (-10); - } else if (dst_s_verify_str(&p, "Coefficient: ")) { - if (!dst_s_conv_bignum_b64_to_u8(&p, key.coefficient, - MAX_RSA_PRIME_LEN)) - return (-11); - } else { - EREPORT(("dst_rsaref_key_from_file_format: Bad keyword %s\n", p)); - return (-12); - } - } /* while p */ - - r_key = (RSA_Key *) malloc(sizeof(RSA_Key)); - if (r_key == NULL) { - return (-2); - } - memset(r_key, 0, sizeof(*r_key)); - - r_key->rk_Private_Key = - (R_RSA_PRIVATE_KEY *) malloc(sizeof(R_RSA_PRIVATE_KEY)); - if (r_key->rk_Private_Key == NULL) { - EREPORT(("dst_rsaref_key_from_file_format: Memory allocation error\n")); - return (-13); - } - r_key->rk_Public_Key = (R_RSA_PUBLIC_KEY *) r_key->rk_Private_Key; - memcpy(r_key->rk_Private_Key, &key, sizeof(R_RSA_PRIVATE_KEY)); - - r_key->rk_signer = strdup(d_key->dk_key_name); - d_key->dk_KEY_struct = (void *) r_key; - d_key->dk_key_size = r_key->rk_Private_Key->bits; - d_key->dk_id = (u_int16_t) dst_s_get_int16((u_char *) - &r_key->rk_Public_Key->modulus[MAX_RSA_MODULUS_LEN - 3]); - foot = (int) d_key->dk_id; - return (foot); -} - - - -/* - * dst_rsaref_compare_keys - * Compare two keys for equality. - * Return - * 0 The keys are equal - * NON-ZERO The keys are not equal - */ - -static int -dst_rsaref_compare_keys(const DST_KEY *dkey1, const DST_KEY *dkey2) -{ - RSA_Key *rkey1 = (RSA_Key *) dkey1->dk_KEY_struct; - RSA_Key *rkey2 = (RSA_Key *) dkey2->dk_KEY_struct; - - if (rkey1 == NULL && rkey2 == NULL) - return (0); /* same */ - else if (rkey1 == NULL) - return (1); - else if (rkey2 == NULL) - return (2); - return (memcmp(rkey1->rk_Public_Key, rkey2->rk_Public_Key, - sizeof(R_RSA_PUBLIC_KEY))); -} - -/* - * dst_rsaref_generate_keypair - * Generates unique keys that are hard to predict. - * Parameters - * key generic Key structure - * exp the public exponent - * Return - * 0 Failure - * 1 Success - */ - -static int -dst_rsaref_generate_keypair(DST_KEY *key, const int exp) -{ - R_RSA_PUBLIC_KEY *public; - R_RSA_PRIVATE_KEY *private; - R_RSA_PROTO_KEY proto; - R_RANDOM_STRUCT randomStruct; - RSA_Key *rsa; - int status; - - if (key == NULL || key->dk_alg != KEY_RSA) - return (0); - if (key->dk_key_size < MIN_RSA_MODULUS_BITS || - key->dk_key_size > MAX_RSA_MODULUS_BITS) { - EREPORT(("dst_rsaref_generate_keypair: Invalid key size\n")); - return (0); /* these are the limits on key size in RSAREF */ - } - /* allocate space */ - if ((public = (R_RSA_PUBLIC_KEY *) malloc(sizeof(R_RSA_PUBLIC_KEY))) - == NULL) { - EREPORT(("dst_rsaref_generate_keypair: Memory allocation error 1\n")); - return (0); - } - if ((private = (R_RSA_PRIVATE_KEY *) malloc(sizeof(R_RSA_PRIVATE_KEY))) - == NULL) { - EREPORT(("dst_rsaref_generate_keypair: Memory allocation error 2\n")); - return (0); - } - if ((rsa = (RSA_Key *) malloc(sizeof(RSA_Key))) == NULL) { - EREPORT(("dst_rsaref_generate_keypair: Memory allocation error 3\n")); - return (0); - } - memset(public, 0, sizeof(*public)); - memset(private, 0, sizeof(*private)); - - proto.bits = key->dk_key_size; - proto.useFermat4 = exp ? 0x1 : 0x0; /* 1 for f4=65537, 0 for f0=3 */ - EREPORT(("\ndst_rsaref_generate_keypair: Generating KEY for %s Please wait\n", - key->dk_key_name)); - - /* set up random seed */ - dst_rsaref_init_random_struct(&randomStruct); - - /* generate keys */ - status = R_GeneratePEMKeys(public, private, &proto, &randomStruct); - if (status) { - EREPORT(("dst_rsaref_generate_keypair: No Key Pair generated %d\n", - status)); - SAFE_FREE(public); - SAFE_FREE(private); - SAFE_FREE(rsa); - return (0); - } - memset(rsa, 0, sizeof(*rsa)); - rsa->rk_signer = key->dk_key_name; - rsa->rk_Private_Key = private; - rsa->rk_Public_Key = public; - key->dk_KEY_struct = (void *) rsa; - - key->dk_id = (u_int16_t) dst_s_get_int16((u_char *) - &rsa->rk_Public_Key->modulus[MAX_RSA_MODULUS_LEN - 3]); - return (1); -} - - -/* - * dst_rsaref_free_key_structure - * Frees all dynamicly allocated structures in r_key - */ - -static void * -dst_rsaref_free_key_structure(void *v_key) -{ - RSA_Key *r_key = (RSA_Key *) v_key; - - if (r_key != NULL) { - if ((void *) r_key->rk_Private_Key == (void *) r_key->rk_Public_Key) - r_key->rk_Public_Key = NULL; - SAFE_FREE(r_key->rk_Private_Key); - SAFE_FREE(r_key->rk_Public_Key); - SAFE_FREE(r_key->rk_signer); - SAFE_FREE(r_key); - } - return (NULL); -} - - -/* - * dst_rsaref_init_random_struct - * A random seed value is used in key generation. - * This routine gets a bunch of system values to randomize the - * randomstruct. A number of system calls are used to get somewhat - * unpredicable values, then a special function dst_s_prandom() is called - * that will do some magic depending on the system used. - * If this function is executed on reasonably busy machine then the values - * that prandom uses are hard to - * 1. Predict - * 2. Regenerate - * 3. Hard to spy on as nothing is stored to disk and data is consumed - * as fast as it is generated. - */ - -static void -dst_rsaref_init_random_struct(R_RANDOM_STRUCT * randomstruct) -{ - unsigned bytesNeeded; - struct timeval tv; - u_char *array; - int n; - - R_RandomInit(randomstruct); - - /* The runtime of the script is unpredictable within some range - * thus I'm getting the time of day again as this is an hard to guess - * value and the number of characters of the output from the script is - * hard to guess. - * This must be the FIRST CALL - */ - gettimeofday(&tv, 0); - assert(tv.tv_usec >= 0 && tv.tv_usec < 1000000); - R_RandomUpdate(randomstruct, (u_char *) &tv, - sizeof(struct timeval)); - - /* - * first find out how many bytes I need - */ - R_GetRandomBytesNeeded(&bytesNeeded, randomstruct); - - /* - * get a storage area for it addjust the area for the possible - * side effects of digest functions writing out in blocks - */ - array = (u_char *) malloc(bytesNeeded); - - /* extract the random data from /dev/random if present, generate - * it if not present - * first fill the buffer with semi random data - * then fill as much as possible with good random data - */ - n = dst_random(DST_RAND_SEMI, bytesNeeded, array); - n += dst_random(DST_RAND_KEY, bytesNeeded, array); - if (n <= bytesNeeded) { - SAFE_FREE(array); - return(0); - } - - /* supply the random data (even if it is larger than requested) */ - R_RandomUpdate(randomstruct, array, bytesNeeded); - - SAFE_FREE(array); - - R_GetRandomBytesNeeded(&bytesNeeded, randomstruct); - if (bytesNeeded) { - EREPORT(("InitRandomStruct() didn't initialize enough randomness\n")); - exit(33); - } -} - - -#else -int /* rsaref is not available */ -dst_rsaref_init() -{ - return (0); -} -#endif /* RSAREF */ diff --git a/contrib/bind/lib/dst/support.c b/contrib/bind/lib/dst/support.c deleted file mode 100644 index d50aa075ac8b0..0000000000000 --- a/contrib/bind/lib/dst/support.c +++ /dev/null @@ -1,461 +0,0 @@ -static const char rcsid[] = "$Header: /proj/cvs/isc/bind/src/lib/dst/support.c,v 1.8 1999/10/13 16:39:24 vixie Exp $"; - - -/* - * Portions Copyright (c) 1995-1998 by Trusted Information Systems, 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 TRUSTED INFORMATION SYSTEMS - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * TRUSTED INFORMATION SYSTEMS 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. - */ - -#include "port_before.h" - -#include <stdio.h> -#include <unistd.h> -#include <memory.h> -#include <string.h> -#include <errno.h> -#include <sys/stat.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <resolv.h> - -#include "dst_internal.h" - -#include "port_after.h" -/* - * dst_s_conv_bignum_u8_to_b64 - * This function converts binary data stored as a u_char[] to a - * base-64 string. Leading zeroes are discarded. If a header is - * supplied, it is prefixed to the input prior to encoding. The - * output is \n\0 terminated (the \0 is not included in output length). - * Parameters - * out_buf binary data to convert - * header character string to prefix to the output (label) - * bin_data binary data - * bin_len size of binary data - * Return - * -1 not enough space in output work area - * 0 no output - * >0 number of bytes written to output work area - */ - -int -dst_s_conv_bignum_u8_to_b64(char *out_buf, const int out_len, - const char *header, const u_char *bin_data, - const int bin_len) -{ - const u_char *bp = bin_data; - char *op = out_buf; - int lenh = 0, len64 = 0; - int local_in_len = bin_len; - int local_out_len = out_len; - - if (bin_data == NULL || bin_len <= 0) /* no data no */ - return (0); - - if (out_buf == NULL || out_len <= 0) /* no output_work area */ - return (-1); - - /* suppress leading \0 */ - for (; (*bp == 0x0) && (local_in_len > 0); local_in_len--) - bp++; - - if (header) { /* add header to output string */ - lenh = strlen(header); - if (lenh < out_len) - memcpy(op, header, lenh); - else - return (-1); - local_out_len -= lenh; - op += lenh; - } - len64 = b64_ntop(bp, local_in_len, op, local_out_len - 2); - if (len64 < 0) - return (-1); - op += len64++; - *(op++) = '\n'; /* put CR in the output */ - *op = '\0'; /* make sure output is 0 terminated */ - return (lenh + len64); -} - - -/* - * dst_s_verify_str() - * Validate that the input string(*str) is at the head of the input - * buffer(**buf). If so, move the buffer head pointer (*buf) to - * the first byte of data following the string(*str). - * Parameters - * buf Input buffer. - * str Input string. - * Return - * 0 *str is not the head of **buff - * 1 *str is the head of **buff, *buf is is advanced to - * the tail of **buf. - */ - -int -dst_s_verify_str(const char **buf, const char *str) -{ - int b, s; - if (*buf == NULL) /* error checks */ - return (0); - if (str == NULL || *str == '\0') - return (1); - - b = strlen(*buf); /* get length of strings */ - s = strlen(str); - if (s > b || strncmp(*buf, str, s)) /* check if same */ - return (0); /* not a match */ - (*buf) += s; /* advance pointer */ - return (1); -} - - -/* - * dst_s_conv_bignum_b64_to_u8 - * Read a line of base-64 encoded string from the input buffer, - * convert it to binary, and store it in an output area. The - * input buffer is read until reaching a newline marker or the - * end of the buffer. The binary data is stored in the last X - * number of bytes of the output area where X is the size of the - * binary output. If the operation is successful, the input buffer - * pointer is advanced. This procedure does not do network to host - * byte order conversion. - * Parameters - * buf Pointer to encoded input string. Pointer is updated if - * function is successfull. - * loc Output area. - * loclen Size in bytes of output area. - * Return - * >0 Return = number of bytes of binary data stored in loc. - * 0 Failure. - */ - -int -dst_s_conv_bignum_b64_to_u8(const char **buf, u_char *loc, const int loclen) -{ - int blen; - char *bp; - u_char bstr[RAW_KEY_SIZE]; - - if (buf == NULL || *buf == NULL) { /* error checks */ - EREPORT(("dst_s_conv_bignum_b64_to_u8: null input buffer.\n")); - return (0); - } - bp = strchr(*buf, '\n'); /* find length of input line */ - if (bp != NULL) - *bp = (u_char) NULL; - - blen = b64_pton(*buf, bstr, sizeof(bstr)); - if (blen <= 0) { - EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is null.\n")); - return (0); - } - else if (loclen < blen) { - EREPORT(("dst_s_conv_bignum_b64_to_u8: decoded value is longer than output buffer.\n")); - return (0); - } - if (bp) - *buf = bp; /* advancing buffer past \n */ - memset(loc, 0, loclen - blen); /* clearing unused output area */ - memcpy(loc + loclen - blen, bstr, blen); /* write last blen bytes */ - return (blen); -} - - -/* - * dst_s_calculate_bits - * Given a binary number represented in a u_char[], determine - * the number of significant bits used. - * Parameters - * str An input character string containing a binary number. - * max_bits The maximum possible significant bits. - * Return - * N The number of significant bits in str. - */ - -int -dst_s_calculate_bits(const u_char *str, const int max_bits) -{ - const u_char *p = str; - u_char i, j = 0x80; - int bits; - for (bits = max_bits; *p == 0x00 && bits > 0; p++) - bits -= 8; - for (i = *p; (i & j) != j; j >>= 1) - bits--; - return (bits); -} - - -/* - * calculates a checksum used in kmt for a id. - * takes an array of bytes and a length. - * returns a 16 bit checksum. - */ -u_int16_t -dst_s_id_calc(const u_char *key, const int keysize) -{ - u_int32_t ac; - const u_char *kp = key; - int size = keysize; - - if (!key || (keysize <= 0)) - return (-1); - - for (ac = 0; size > 1; size -= 2, kp += 2) - ac += ((*kp) << 8) + *(kp + 1); - - if (size > 0) - ac += ((*kp) << 8); - ac += (ac >> 16) & 0xffff; - - return (ac & 0xffff); -} - -/* - * dst_s_dns_key_id() Function to calculated DNSSEC footprint from KEY reocrd - * rdata (all of record) - * Input: - * dns_key_rdata: the raw data in wire format - * rdata_len: the size of the input data - * Output: - * the key footprint/id calcuated from the key data - */ -u_int16_t -dst_s_dns_key_id(const u_char *dns_key_rdata, const int rdata_len) -{ - int key_data = 4; - - if (!dns_key_rdata || (rdata_len < key_data)) - return 0; - - /* check the extended parameters bit in the DNS Key RR flags */ - if (dst_s_get_int16(dns_key_rdata) & DST_EXTEND_FLAG) - key_data += 2; - - /* compute id */ - if (dns_key_rdata[3] == KEY_RSA) /* Algorithm RSA */ - return dst_s_get_int16((u_char *) - &dns_key_rdata[rdata_len - 3]); - else - /* compute a checksum on the key part of the key rr */ - return dst_s_id_calc(&dns_key_rdata[key_data], - (rdata_len - key_data)); -} - -/* - * dst_s_get_int16 - * This routine extracts a 16 bit integer from a two byte character - * string. The character string is assumed to be in network byte - * order and may be unaligned. The number returned is in host order. - * Parameter - * buf A two byte character string. - * Return - * The converted integer value. - */ - -u_int16_t -dst_s_get_int16(const u_char *buf) -{ - register u_int16_t a = 0; - a = ((u_int16_t)(buf[0] << 8)) | ((u_int16_t)(buf[1])); - return (a); -} - - -/* - * dst_s_get_int32 - * This routine extracts a 32 bit integer from a four byte character - * string. The character string is assumed to be in network byte - * order and may be unaligned. The number returned is in host order. - * Parameter - * buf A four byte character string. - * Return - * The converted integer value. - */ - -u_int32_t -dst_s_get_int32(const u_char *buf) -{ - register u_int32_t a = 0; - a = ((u_int32_t)(buf[0] << 24)) | ((u_int32_t)(buf[1] << 16)) | - ((u_int32_t)(buf[2] << 8)) | ((u_int32_t)(buf[3])); - return (a); -} - - -/* - * dst_s_put_int16 - * Take a 16 bit integer and store the value in a two byte - * character string. The integer is assumed to be in network - * order and the string is returned in host order. - * - * Parameters - * buf Storage for a two byte character string. - * val 16 bit integer. - */ - -void -dst_s_put_int16(u_int8_t *buf, const u_int16_t val) -{ - buf[0] = (u_int8_t)(val >> 8); - buf[1] = (u_int8_t)(val); -} - - -/* - * dst_s_put_int32 - * Take a 32 bit integer and store the value in a four byte - * character string. The integer is assumed to be in network - * order and the string is returned in host order. - * - * Parameters - * buf Storage for a four byte character string. - * val 32 bit integer. - */ - -void -dst_s_put_int32(u_int8_t *buf, const u_int32_t val) -{ - buf[0] = (u_int8_t)(val >> 24); - buf[1] = (u_int8_t)(val >> 16); - buf[2] = (u_int8_t)(val >> 8); - buf[3] = (u_int8_t)(val); -} - - -/* - * dst_s_filename_length - * - * This function returns the number of bytes needed to hold the - * filename for a key file. '/', '\' and ':' are not allowed. - * form: K<keyname>+<alg>+<id>.<suffix> - * - * Returns 0 if the filename would contain either '\', '/' or ':' - */ -size_t -dst_s_filename_length(const char *name, const char *suffix) -{ - if (name == NULL) - return (0); - if (strrchr(name, '\\')) - return (0); - if (strrchr(name, '/')) - return (0); - if (strrchr(name, ':')) - return (0); - if (suffix == NULL) - return (0); - if (strrchr(suffix, '\\')) - return (0); - if (strrchr(suffix, '/')) - return (0); - if (strrchr(suffix, ':')) - return (0); - return (1 + strlen(name) + 6 + strlen(suffix)); -} - - -/* - * dst_s_build_filename () - * Builds a key filename from the key name, it's id, and a - * suffix. '\', '/' and ':' are not allowed. fA filename is of the - * form: K<keyname><id>.<suffix> - * form: K<keyname>+<alg>+<id>.<suffix> - * - * Returns -1 if the conversion fails: - * if the filename would be too long for space allotted - * if the filename would contain a '\', '/' or ':' - * Returns 0 on success - */ - -int -dst_s_build_filename(char *filename, const char *name, u_int16_t id, - int alg, const char *suffix, size_t filename_length) -{ - u_int32_t my_id; - if (filename == NULL) - return (-1); - memset(filename, 0, filename_length); - if (name == NULL) - return (-1); - if (suffix == NULL) - return (-1); - if (filename_length < 1 + strlen(name) + 4 + 6 + 1 + strlen(suffix)) - return (-1); - my_id = id; - sprintf(filename, "K%s+%03d+%05d.%s", name, alg, my_id, - (char *) suffix); - if (strrchr(filename, '/')) - return (-1); - if (strrchr(filename, '\\')) - return (-1); - if (strrchr(filename, ':')) - return (-1); - return (0); -} - -/* - * dst_s_fopen () - * Open a file in the dst_path directory. If perm is specified, the - * file is checked for existence first, and not opened if it exists. - * Parameters - * filename File to open - * mode Mode to open the file (passed directly to fopen) - * perm File permission, if creating a new file. - * Returns - * NULL Failure - * NON-NULL (FILE *) of opened file. - */ -FILE * -dst_s_fopen(const char *filename, const char *mode, int perm) -{ - FILE *fp; - char pathname[PATH_MAX]; - int plen = sizeof(pathname); - - if (*dst_path != '\0') { - strcpy(pathname, dst_path); - plen -= strlen(pathname); - } - else - pathname[0] = '\0'; - - if (plen > strlen(filename)) - strncpy(&pathname[PATH_MAX - plen], filename, plen-1); - else - return (NULL); - - fp = fopen(pathname, mode); - if (perm) - chmod(pathname, perm); - return (fp); -} - -void -dst_s_dump(const int mode, const u_char *data, const int size, - const char *msg) -{ - if (size > 0) { -#ifdef LONG_TEST - static u_char scratch[1000]; - int n ; - n = b64_ntop(data, scratch, size, sizeof(scratch)); - printf("%s: %x %d %s\n", msg, mode, n, scratch); -#else - printf("%s,%x %d\n", msg, mode, size); -#endif - } -} |