rsaref_link.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef RSAREF
static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/rsaref_link.c,v 1.10 2001/05/29 05:48:15 marka Exp $";
/*
* Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc.
*
* Permission to use, copy modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THE SOFTWARE.
*/
/*
* This file contains two components
* 1. Interface to the rsaref library to allow compilation when RSAREF is
* not available all calls to RSAREF are contained inside this file.
* 2. The glue to connvert RSA{REF} KEYS to and from external formats
*/
#include "port_before.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include "dst_internal.h"
# ifdef __STDC__
# define PROTOTYPES 1
# else
# define PROTOTYPES 0
# endif
# include <global.h>
# include <rsaref.h>
#include "port_after.h"
typedef struct rsakey {
char *rk_signer;
} RSA_Key;
const int out_len);
const int len);
const int buff_len);
const int buff_len);
static void *dst_rsaref_free_key_structure(void *d_key);
/*
* dst_rsaref_init() Function to answer set up function pointers for RSAREF
* related functions
*/
int
{
return (1);
return (0);
return (1);
}
/*
* dst_rsa_sign
* Call RSAREF signing functions to sign a block of data.
* There are three steps to signing, INIT (initialize structures),
* UPDATE (hash (more) data), FINAL (generate a signature). This
* routine performs one or more of these steps.
* Parameters
* key pointer to a RSA key structure that points to public key
* and context to use.
* data data to be signed.
* len length in bytes of data.
* signature location to store signature.
* sig_len size of the signature storage area
* returns
* N Success on SIG_MODE_FINAL = returns signature length in bytes
* 0 Success on SIG_MODE_INIT and UPDATE
* <0 Failure
*/
static int
{
int sign_len = 0;
if (mode & SIG_MODE_INIT)
else if (context)
return (-1);
return (SIGN_INIT_FAILURE);
/* equivalent of SIG_MODE_UPDATE */
return (SIGN_UPDATE_FAILURE);
if (mode & SIG_MODE_FINAL) {
return (SIGN_FINAL_FAILURE);
return (-1);
return (SIGN_FINAL_FAILURE);
}
else {
return (-1);
}
return (sign_len);
}
/*
* dst_rsaref_verify()
* Calls RSAREF verification routines. There are three steps to
* verification, INIT (initialize structures), UPDATE (hash (more) data),
* FINAL (generate a signature). This routine performs one or more of
* these steps.
* Parameters
* key pointer to a RSA key structure that points to public key
* and context to use.
* data data signed.
* len length in bytes of data.
* signature signature.
* sig_len length in bytes of signature.
* returns
* 0 Success
* <0 Failure
*/
static int
{
if (mode & SIG_MODE_INIT)
else if (context)
return (-1);
return (VERIFY_INIT_FAILURE);
return (VERIFY_UPDATE_FAILURE);
if ((mode & SIG_MODE_FINAL)) {
return (-1);
return (VERIFY_FINAL_FAILURE);
key->rk_Public_Key))
return (VERIFY_FINAL_FAILURE);
}
else {
return (-1);
}
return (0);
}
/*
* dst_rsaref_to_dns_key
* Converts key in RSAREF to DNS distribution format
* This function gets in a pointer to the public key and a work area
* to write the key into.
* Parameters
* public KEY structure
* out_str buffer to write encoded key into
* out_len size of out_str
* Return
* N >= 0 length of encoded key
* n < 0 error
*/
static int
const int out_len)
{
int n, loc;
return (-1);
public = (R_RSA_PUBLIC_KEY *)
return (-1);
/* find first non zero */
n = (MAX_RSA_MODULUS_LEN - n); /* find lenght of exponent */
return (-1);
op += n;
n++; /* include the lenght field in this count */
/* find first non zero */
/*copy exponent */
return (-1);
n += (MAX_RSA_MODULUS_LEN - loc);
return (n);
}
/*
* dst_rsaref_from_dns_key
* Converts from a DNS KEY RR format to an RSA KEY.
* Parameters
* len Length in bytes of DNS key
* key DNS key
* name Key name
* s_key DST structure that will point to the RSA key this routine
* will build.
* Return
* -1 The input key has fields that are larger than this package supports
* 0 The input key, s_key or name was null.
* 1 Success
*/
static int
{
int bytes;
return (0);
}
if (len == 0) /* null key no conversion needed */
return (1);
EREPORT(("dst_rsaref_from_dns_key(): Memory allocation error 1\n"));
return (0);
}
malloc(sizeof(R_RSA_PUBLIC_KEY));
EREPORT(("dst_rsaref_from_dns_key(): Memory allocation error 3\n"));
return (0);
}
if (bytes == 0) { /* special case for long exponents */
}
if (bytes > MAX_RSA_MODULUS_LEN) {
return (-1);
}
if (bytes > MAX_RSA_MODULUS_LEN) {
return (-1);
}
return (1);
}
/*
* dst_rsaref_key_to_file_format
* Encodes an RSA Key into the portable file format.
* Parameters
* rkey RSA KEY structure
* buff output buffer
* buff_len size of output buffer
* Return
* 0 Failure - null input rkey
* -1 Failure - not enough space in output area
* N Success - Length of data returned in buff
*/
static int
const int buff_len)
{
return (-1);
rkey = (R_RSA_PRIVATE_KEY *)
return (0);
return (-1); /* no OR not enough space in output area */
/* write file header */
MAX_RSA_MODULUS_LEN)) <= 0)
return (-1);
MAX_RSA_MODULUS_LEN)) <= 0)
return (-2);
MAX_RSA_MODULUS_LEN)) <= 0)
return (-3);
MAX_RSA_PRIME_LEN)) < 0)
return (-4);
MAX_RSA_PRIME_LEN)) < 0)
return (-5);
rkey->primeExponent[0],
MAX_RSA_PRIME_LEN)) < 0)
return (-6);
MAX_RSA_PRIME_LEN)) < 0)
return (-7);
MAX_RSA_PRIME_LEN)) < 0)
return (-8);
}
/*
* dst_rsaref_key_from_file_format
* Converts contents of a private key file into a private RSA key.
* Parameters
* r_key structure to put key into
* buff buffer containing the encoded key
* buff_len the length of the buffer
* Return
* n >= 0 Foot print of the key converted
* n < 0 Error in conversion
*/
static int
const int buff_len)
{
const char *p = (char *) buff;
int foot = -1;
return (-1);
if (!dst_s_verify_str(&p, "Modulus: "))
return (-3);
return (-4);
if (dst_s_verify_str(&p, "PublicExponent: ")) {
if (!dst_s_conv_bignum_b64_to_u8(&p,
return (-5);
} else if (dst_s_verify_str(&p, "PrivateExponent: ")) {
return (-6);
} else if (dst_s_verify_str(&p, "Prime1: ")) {
return (-7);
} else if (dst_s_verify_str(&p, "Prime2: ")) {
return (-8);
} else if (dst_s_verify_str(&p, "Exponent1: ")) {
if (!dst_s_conv_bignum_b64_to_u8(&p,
key.primeExponent[0],
return (-9);
} else if (dst_s_verify_str(&p, "Exponent2: ")) {
if (!dst_s_conv_bignum_b64_to_u8(&p,
return (-10);
} else if (dst_s_verify_str(&p, "Coefficient: ")) {
return (-11);
} else {
EREPORT(("dst_rsaref_key_from_file_format: Bad keyword %s\n", p));
return (-12);
}
} /* while p */
return (-2);
}
EREPORT(("dst_rsaref_key_from_file_format: Memory allocation error\n"));
return (-13);
}
return (0);
}
/*
* dst_rsaref_compare_keys
* Compare two keys for equality.
* Return
* 0 The keys are equal
* NON-ZERO The keys are not equal
*/
static int
{
return (0); /* same */
return (1);
return (2);
sizeof(R_RSA_PUBLIC_KEY)));
}
/*
* dst_rsaref_generate_keypair
* Generates unique keys that are hard to predict.
* Parameters
* key generic Key structure
* exp the public exponent
* Return
* 0 Failure
* 1 Success
*/
static int
{
int status;
return (0);
EREPORT(("dst_rsaref_generate_keypair: Invalid key size\n"));
return (0); /* these are the limits on key size in RSAREF */
}
/* allocate space */
== NULL) {
EREPORT(("dst_rsaref_generate_keypair: Memory allocation error 1\n"));
return (0);
}
== NULL) {
EREPORT(("dst_rsaref_generate_keypair: Memory allocation error 2\n"));
return (0);
}
EREPORT(("dst_rsaref_generate_keypair: Memory allocation error 3\n"));
return (0);
}
EREPORT(("\ndst_rsaref_generate_keypair: Generating KEY for %s Please wait\n",
key->dk_key_name));
/* set up random seed */
/* generate keys */
if (status) {
EREPORT(("dst_rsaref_generate_keypair: No Key Pair generated %d\n",
status));
return (0);
}
return (1);
}
/*
* dst_rsaref_free_key_structure
* Frees all dynamicly allocated structures in r_key
*/
static void *
{
}
return (NULL);
}
/*
* dst_rsaref_init_random_struct
* A random seed value is used in key generation.
* This routine gets a bunch of system values to randomize the
* randomstruct. A number of system calls are used to get somewhat
* unpredicable values, then a special function dst_s_prandom() is called
* that will do some magic depending on the system used.
* If this function is executed on reasonably busy machine then the values
* that prandom uses are hard to
* 1. Predict
* 2. Regenerate
* 3. Hard to spy on as nothing is stored to disk and data is consumed
* as fast as it is generated.
*/
static void
{
unsigned bytesNeeded;
int n;
/* The runtime of the script is unpredictable within some range
* thus I'm getting the time of day again as this is an hard to guess
* value and the number of characters of the output from the script is
* hard to guess.
* This must be the FIRST CALL
*/
gettimeofday(&tv, 0);
sizeof(struct timeval));
/*
* first find out how many bytes I need
*/
/*
* get a storage area for it addjust the area for the possible
* side effects of digest functions writing out in blocks
*/
* it if not present
* first fill the buffer with semi random data
* then fill as much as possible with good random data
*/
if (n <= bytesNeeded) {
return(0);
}
/* supply the random data (even if it is larger than requested) */
if (bytesNeeded) {
EREPORT(("InitRandomStruct() didn't initialize enough randomness\n"));
exit(33);
}
}
#else
#include "port_before.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include "dst_internal.h"
#include "port_after.h"
int /* rsaref is not available */
{
return (0);
}
#endif /* RSAREF */