summaryrefslogtreecommitdiff
path: root/minires
diff options
context:
space:
mode:
authorTed Lemon <source@isc.org>2001-02-22 07:22:09 +0000
committerTed Lemon <source@isc.org>2001-02-22 07:22:09 +0000
commit246f7f725a95a69bebf29a43a5a69b4c7d3ce4bb (patch)
treede5af02f8536eef46a14f53b23f63d2edc63e1d0 /minires
parent9560d30a7fbf21b140e2a3be52bca3dc299716b8 (diff)
downloadisc-dhcp-246f7f725a95a69bebf29a43a5a69b4c7d3ce4bb.tar.gz
Move dst API into its own subdirectory.
Diffstat (limited to 'minires')
-rw-r--r--minires/base64.c319
-rw-r--r--minires/dst_api.c1081
-rw-r--r--minires/hmac_link.c494
-rw-r--r--minires/md5.h101
-rw-r--r--minires/md5_locl.h190
-rw-r--r--minires/prandom.c862
-rw-r--r--minires/support.c462
7 files changed, 0 insertions, 3509 deletions
diff --git a/minires/base64.c b/minires/base64.c
deleted file mode 100644
index 65ea65d5..00000000
--- a/minires/base64.c
+++ /dev/null
@@ -1,319 +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.
- */
-
-/*
- * Portions Copyright (c) 1995 by International Business Machines, Inc.
- *
- * International Business Machines, Inc. (hereinafter called IBM) grants
- * permission under its copyrights to use, copy, modify, and distribute this
- * Software with or without fee, provided that the above copyright notice and
- * all paragraphs of this notice appear in all copies, and that the name of IBM
- * not be used in connection with the marketing of any product incorporating
- * the Software or modifications thereof, without specific, written prior
- * permission.
- *
- * To the extent it has a right to do so, IBM grants an immunity from suit
- * under its patents, if any, for the use, sale or manufacture of products to
- * the extent that such products are used for performing Domain Name System
- * dynamic updates in TCP/IP networks by means of the Software. No immunity is
- * granted for any product per se or for any other function of any product.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
- * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
- * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
- */
-
-#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: base64.c,v 1.2 2000/02/02 19:59:15 mellon Exp $";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/socket.h>
-
-#include "minires/minires.h"
-#include "arpa/nameser.h"
-
-#define Assert(Cond) if (!(Cond)) abort()
-
-static const char Base64[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-static const char Pad64 = '=';
-
-/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
- The following encoding technique is taken from RFC 1521 by Borenstein
- and Freed. It is reproduced here in a slightly edited form for
- convenience.
-
- A 65-character subset of US-ASCII is used, enabling 6 bits to be
- represented per printable character. (The extra 65th character, "=",
- is used to signify a special processing function.)
-
- The encoding process represents 24-bit groups of input bits as output
- strings of 4 encoded characters. Proceeding from left to right, a
- 24-bit input group is formed by concatenating 3 8-bit input groups.
- These 24 bits are then treated as 4 concatenated 6-bit groups, each
- of which is translated into a single digit in the base64 alphabet.
-
- Each 6-bit group is used as an index into an array of 64 printable
- characters. The character referenced by the index is placed in the
- output string.
-
- Table 1: The Base64 Alphabet
-
- Value Encoding Value Encoding Value Encoding Value Encoding
- 0 A 17 R 34 i 51 z
- 1 B 18 S 35 j 52 0
- 2 C 19 T 36 k 53 1
- 3 D 20 U 37 l 54 2
- 4 E 21 V 38 m 55 3
- 5 F 22 W 39 n 56 4
- 6 G 23 X 40 o 57 5
- 7 H 24 Y 41 p 58 6
- 8 I 25 Z 42 q 59 7
- 9 J 26 a 43 r 60 8
- 10 K 27 b 44 s 61 9
- 11 L 28 c 45 t 62 +
- 12 M 29 d 46 u 63 /
- 13 N 30 e 47 v
- 14 O 31 f 48 w (pad) =
- 15 P 32 g 49 x
- 16 Q 33 h 50 y
-
- Special processing is performed if fewer than 24 bits are available
- at the end of the data being encoded. A full encoding quantum is
- always completed at the end of a quantity. When fewer than 24 input
- bits are available in an input group, zero bits are added (on the
- right) to form an integral number of 6-bit groups. Padding at the
- end of the data is performed using the '=' character.
-
- Since all base64 input is an integral number of octets, only the
- -------------------------------------------------
- following cases can arise:
-
- (1) the final quantum of encoding input is an integral
- multiple of 24 bits; here, the final unit of encoded
- output will be an integral multiple of 4 characters
- with no "=" padding,
- (2) the final quantum of encoding input is exactly 8 bits;
- here, the final unit of encoded output will be two
- characters followed by two "=" padding characters, or
- (3) the final quantum of encoding input is exactly 16 bits;
- here, the final unit of encoded output will be three
- characters followed by one "=" padding character.
- */
-
-int
-b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
- size_t datalength = 0;
- u_char input[3];
- u_char output[4];
- size_t i;
-
- while (2 < srclength) {
- input[0] = *src++;
- input[1] = *src++;
- input[2] = *src++;
- srclength -= 3;
-
- output[0] = input[0] >> 2;
- output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
- output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
- output[3] = input[2] & 0x3f;
- Assert(output[0] < 64);
- Assert(output[1] < 64);
- Assert(output[2] < 64);
- Assert(output[3] < 64);
-
- if (datalength + 4 > targsize)
- return (-1);
- target[datalength++] = Base64[output[0]];
- target[datalength++] = Base64[output[1]];
- target[datalength++] = Base64[output[2]];
- target[datalength++] = Base64[output[3]];
- }
-
- /* Now we worry about padding. */
- if (0 != srclength) {
- /* Get what's left. */
- input[0] = input[1] = input[2] = '\0';
- for (i = 0; i < srclength; i++)
- input[i] = *src++;
-
- output[0] = input[0] >> 2;
- output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
- output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
- Assert(output[0] < 64);
- Assert(output[1] < 64);
- Assert(output[2] < 64);
-
- if (datalength + 4 > targsize)
- return (-1);
- target[datalength++] = Base64[output[0]];
- target[datalength++] = Base64[output[1]];
- if (srclength == 1)
- target[datalength++] = Pad64;
- else
- target[datalength++] = Base64[output[2]];
- target[datalength++] = Pad64;
- }
- if (datalength >= targsize)
- return (-1);
- target[datalength] = '\0'; /* Returned value doesn't count \0. */
- return (datalength);
-}
-
-/* skips all whitespace anywhere.
- converts characters, four at a time, starting at (or after)
- src from base - 64 numbers into three 8 bit bytes in the target area.
- it returns the number of data bytes stored at the target, or -1 on error.
- */
-
-int
-b64_pton(src, target, targsize)
- char const *src;
- u_char *target;
- size_t targsize;
-{
- int tarindex, state, ch;
- char *pos;
-
- state = 0;
- tarindex = 0;
-
- while ((ch = *src++) != '\0') {
- if (isspace(ch)) /* Skip whitespace anywhere. */
- continue;
-
- if (ch == Pad64)
- break;
-
- pos = strchr(Base64, ch);
- if (pos == 0) /* A non-base64 character. */
- return (-1);
-
- switch (state) {
- case 0:
- if (target) {
- if ((size_t)tarindex >= targsize)
- return (-1);
- target[tarindex] = (pos - Base64) << 2;
- }
- state = 1;
- break;
- case 1:
- if (target) {
- if ((size_t)tarindex + 1 >= targsize)
- return (-1);
- target[tarindex] |= (pos - Base64) >> 4;
- target[tarindex+1] = ((pos - Base64) & 0x0f)
- << 4 ;
- }
- tarindex++;
- state = 2;
- break;
- case 2:
- if (target) {
- if ((size_t)tarindex + 1 >= targsize)
- return (-1);
- target[tarindex] |= (pos - Base64) >> 2;
- target[tarindex+1] = ((pos - Base64) & 0x03)
- << 6;
- }
- tarindex++;
- state = 3;
- break;
- case 3:
- if (target) {
- if ((size_t)tarindex >= targsize)
- return (-1);
- target[tarindex] |= (pos - Base64);
- }
- tarindex++;
- state = 0;
- break;
- default:
- abort();
- }
- }
-
- /*
- * We are done decoding Base-64 chars. Let's see if we ended
- * on a byte boundary, and/or with erroneous trailing characters.
- */
-
- if (ch == Pad64) { /* We got a pad char. */
- ch = *src++; /* Skip it, get next. */
- switch (state) {
- case 0: /* Invalid = in first position */
- case 1: /* Invalid = in second position */
- return (-1);
-
- case 2: /* Valid, means one byte of info */
- /* Skip any number of spaces. */
- for ((void)NULL; ch != '\0'; ch = *src++)
- if (!isspace(ch))
- break;
- /* Make sure there is another trailing = sign. */
- if (ch != Pad64)
- return (-1);
- ch = *src++; /* Skip the = */
- /* Fall through to "single trailing =" case. */
- /* FALLTHROUGH */
-
- case 3: /* Valid, means two bytes of info */
- /*
- * We know this char is an =. Is there anything but
- * whitespace after it?
- */
- for ((void)NULL; ch != '\0'; ch = *src++)
- if (!isspace(ch))
- return (-1);
-
- /*
- * Now make sure for cases 2 and 3 that the "extra"
- * bits that slopped past the last full byte were
- * zeros. If we don't check them, they become a
- * subliminal channel.
- */
- if (target && target[tarindex] != 0)
- return (-1);
- }
- } else {
- /*
- * We ended by seeing the end of the string. Make sure we
- * have no partial bytes lying around.
- */
- if (state != 0)
- return (-1);
- }
-
- return (tarindex);
-}
diff --git a/minires/dst_api.c b/minires/dst_api.c
deleted file mode 100644
index 69e68815..00000000
--- a/minires/dst_api.c
+++ /dev/null
@@ -1,1081 +0,0 @@
-#ifndef LINT
-static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/minires/Attic/dst_api.c,v 1.3 2000/08/03 21:00:05 neild 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 <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 "minires/minires.h"
-#include "arpa/nameser.h"
-
-#include "dst_internal.h"
-
-/* static variables */
-static int done_init = 0;
-dst_func *dst_t_func[DST_MAX_ALGS];
-const char *key_file_fmt_str = "Private-key-format: v%s\nAlgorithm: %d (%s)\n";
-const char *dst_path = "";
-
-/* internal I/O functions */
-static DST_KEY *dst_s_read_public_key(const char *in_name,
- const unsigned in_id, int in_alg);
-static int dst_s_read_private_key_file(char *name, DST_KEY *pk_key,
- unsigned 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 u_int32_t 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;
- unsigned 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 {
- char *dp = (char *) malloc(len + 2);
- int l;
- memcpy(dp, s, len + 1);
- l = strlen (dp);
- if (dp[l - 1] != '/') {
- dp[l + 1] = 0;
- dp[l] = '/';
- }
- dst_path = dp;
- }
- }
- memset(dst_t_func, 0, sizeof(dst_t_func));
- /* first one is selected */
-#if 0
- dst_bsafe_init();
- dst_rsaref_init();
-#endif
- dst_hmac_md5_init();
-#if 0
- dst_eay_dss_init();
- dst_cylink_init();
-#endif
-}
-
-/*
- * 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 u_int32_t 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 unsigned len,
- u_char *signature, const unsigned 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 unsigned len,
- const u_char *signature, const unsigned 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 unsigned 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];
- unsigned 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 unsigned in_id, int in_alg)
-{
- unsigned flags, len;
- int proto, alg, 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, (unsigned)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],
- (unsigned)(len - 6), enc_key, sizeof(enc_key));
- else
- b64_ntop(&out_key[4],
- (unsigned)(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 unsigned 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 unsigned 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);
- out_storage[0] = (val >> 8) & 0xff;
- out_storage[1] = val & 0xff;
- 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);
- out_storage[loc] = (val >> 8) & 0xff;
- out_storage[loc+1] = val & 0xff;
- 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 unsigned flags, /* dns flags */
- const int protocol, /* dns protocol */
- const u_char *key_buf, /* key in dns wire fmt */
- const unsigned 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, unsigned 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, unsigned 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,
- (unsigned)(&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, (unsigned)cnt);
- return (1);
-
- fail:
- memset(in_buff, 0, (unsigned)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 unsigned 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, unsigned 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, (unsigned)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/minires/hmac_link.c b/minires/hmac_link.c
deleted file mode 100644
index e37c0b45..00000000
--- a/minires/hmac_link.c
+++ /dev/null
@@ -1,494 +0,0 @@
-#ifdef HMAC_MD5
-#ifndef LINT
-static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/minires/Attic/hmac_link.c,v 1.3 2000/02/02 19:59:15 mellon 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 <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 <sys/socket.h>
-
-#include "minires/minires.h"
-#include "arpa/nameser.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
-
-#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 unsigned len,
- u_char *signature, const unsigned 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, (const unsigned 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 unsigned len,
- const u_char *signature, const unsigned 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, (const unsigned 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 unsigned keylen)
-{
- int i;
- HMAC_Key *hkey = NULL;
- MD5_CTX ctx;
- unsigned 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, (const unsigned 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 unsigned buff_len)
-{
- char *bp;
- int i;
- unsigned len, b_len, 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 unsigned 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;
- unsigned key_len, len;
-
- if (dkey == NULL)
- return (-2);
- if (buff == NULL)
- 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 unsigned 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 n;
- unsigned size, len;
-
- 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);
-
- len = size > 64 ? 64 : size;
- buff = malloc(len+8);
-
- n = dst_random(DST_RAND_SEMI, len, buff);
- n += dst_random(DST_RAND_KEY, len, buff);
- if (n <= len) { /* failed getting anything */
- SAFE_FREE2(buff, len);
- return (-1);
- }
- n = dst_buffer_to_hmac_md5(key, buff, len);
- SAFE_FREE2(buff, len);
- 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/minires/md5.h b/minires/md5.h
deleted file mode 100644
index c886d17b..00000000
--- a/minires/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, const 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/minires/md5_locl.h b/minires/md5_locl.h
deleted file mode 100644
index b2f0028f..00000000
--- a/minires/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/minires/prandom.c b/minires/prandom.c
deleted file mode 100644
index b3581086..00000000
--- a/minires/prandom.c
+++ /dev/null
@@ -1,862 +0,0 @@
-#ifndef LINT
-static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/minires/Attic/prandom.c,v 1.2 2000/02/02 19:59:16 mellon 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 <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 <netinet/in.h>
-#include <sys/socket.h>
-#define NEED_PRAND_CONF
-#include "minires/minires.h"
-#include "dst_internal.h"
-#include "arpa/nameser.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 {
- unsigned 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, unsigned 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, const u_char *input,
- unsigned size);
-static int my_digest(dst_work *tmp, const u_char *input, unsigned size);
-static prand_hash *get_hmac_key(int step, int block);
-
-static unsigned 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, unsigned 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);
- 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, tb_i = 0, out = 0;
- unsigned dir_len;
-
- 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))) {
- unsigned 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, (unsigned)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, (unsigned)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, (unsigned)i);
- my_digest(work, (const 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, const u_char *input, unsigned size)
-{
- const u_char *tmp = input;
- u_char *tp, *abuf = (u_char *)0;
- int i, n;
- unsigned needed, avail, dig, cnt = size;
- unsigned 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;
- abuf = tp = malloc(tmp_size);
- tmp = tp;
- 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 (abuf)
- SAFE_FREE2(abuf, tmp_size);
- return (1);
- }
- }
- if (tmp_size > 0)
- SAFE_FREE2(abuf, 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, const u_char *input, unsigned 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;
- unsigned 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 unsigned
-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, unsigned size)
-{
- int n = 0, i;
- unsigned s;
- static u_char old_unused[DST_HASH_SIZE * DST_NUM_HASHES];
- static unsigned 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) {
- unsigned 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, unsigned 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;
- static unsigned hb_size = 0;
- static DST_KEY *my_key = NULL;
- prand_hash *hash;
- unsigned out = 0;
- unsigned i;
- int 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/minires/support.c b/minires/support.c
deleted file mode 100644
index 9b681ab7..00000000
--- a/minires/support.c
+++ /dev/null
@@ -1,462 +0,0 @@
-static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/minires/Attic/support.c,v 1.2 2000/02/02 19:59:16 mellon 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 <stdio.h>
-#include <unistd.h>
-#include <memory.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include "minires/minires.h"
-#include "arpa/nameser.h"
-
-#include "dst_internal.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 unsigned out_len,
- const char *header, const u_char *bin_data,
- const unsigned bin_len)
-{
- const u_char *bp = bin_data;
- char *op = out_buf;
- unsigned lenh = 0, len64 = 0;
- unsigned local_in_len = bin_len;
- unsigned local_out_len = out_len;
-
- if (bin_data == NULL) /* 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)
-{
- unsigned 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 unsigned loclen)
-{
- unsigned 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 unsigned keysize)
-{
- u_int32_t ac;
- const u_char *kp = key;
- unsigned size = keysize;
-
- if (!key)
- return 0;
-
- 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 unsigned rdata_len)
-{
- unsigned 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((const 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, unsigned id,
- int alg, const char *suffix, size_t filename_length)
-{
- unsigned 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,
- (const 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, unsigned perm)
-{
- FILE *fp;
- char pathname[PATH_MAX];
- unsigned 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);
-}
-
-#if 0
-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
- }
-}
-#endif