bsafe_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"
static const char rcsid[] = "$Header: /proj/cvs/isc/bind8/src/lib/dst/bsafe_link.c,v 1.15 2001/09/25 04:50:28 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 BSAFE library to allow compilation of Bind
* all calls to BSAFE are contained inside this file.
* 2. The glue to connvert RSA KEYS to and from external formats
*/
#include "port_before.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include "dst_internal.h"
# ifdef __STDC__
# define PROTOTYPES 1
# else
# define PROTOTYPES 0
# endif
# ifdef BSAFE
# include <aglobal.h>
# include <bsafe.h>
# else
# include <global.h>
# include <bsafe2.h>
# include <bigmaxes.h>
# endif
#include "port_after.h"
typedef struct bsafekey {
char *rk_signer;
} RSA_Key;
#ifndef MAX_RSA_MODULUS_BITS
#define MAX_RSA_MODULUS_BITS 4096
#endif
{
&AM_MD5,
};
{
0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00,
0x04, 0x10
};
const int out_len);
const int len);
const int buff_len);
const char *buff,
const int buff_len);
static void *dst_bsafe_free_key_structure(void *key);
/*
* dst_bsafe_init() Function to answer set up function pointers for
*/
int
dst_bsafe_init(void)
{
return (1);
return (0);
return (1);
}
/*
* dst_bsafe_sign
* Call BSAFE signing functions to sign a block of data.
* There are three steps to signing, INIT (initialize structures),
* UPDATE (hash (more) data), FINAL (generate a signature). This
* routine performs one or more of these steps.
* Parameters
* dkey structure holds context for a sign done in multiple calls.
* context the context to use for this computation
* data data to be signed.
* len length in bytes of data.
* priv_key key to use for signing.
* signature location to store signature.
* sig_len size in bytes of signature field.
* returns
* N Success on SIG_MODE_FINAL = returns signature length in bytes
* 0 Success on SIG_MODE_INIT and UPDATE
* <0 Failure
*/
static int
{
int status = 0;
int w_bytes = 0;
if (mode & SIG_MODE_INIT) {
return (-1);
return (-1);
}
else if (context)
return (-1);
if (w_bytes < 0)
return (w_bytes);
}
if (mode & SIG_MODE_FINAL) {
int ret = 0;
return (-1);
return (-1);
return (SIGN_FINAL_FAILURE);
NULL_PTR)))
if (ret == 0 &&
if (ret == 0 &&
if (ret == 0 &&
if (ret == 0 &&
if (ret != 0)
return (ret);
}
else {
return (-1);
}
return (sign_len);
}
/*
* Dst_bsafe_verify
* Calls BSAFE verification routines. There are three steps to
* verification, INIT (initialize structures), UPDATE (hash (more) data),
* FINAL (generate a signature). This routine performs one or more of
* these steps.
* Parameters
* dkey structure holds context for a verify done in multiple calls.
* context the context to use for this computation
* data data signed.
* len length in bytes of data.
* pub_key key to use for verify.
* signature signature.
* sig_len length in bytes of signature.
* returns
* 0 Success
* <0 Failure
*/
static int
{
if (mode & SIG_MODE_INIT) {
return (-1);
return (-1);
}
else if (context)
return (-1);
if (w_bytes < 0)
return (-1);
}
if (mode & SIG_MODE_FINAL) {
int ret = 0;
return (-1);
return (-2);
if (rsaEncryptor == NULL_PTR) {
if (ret == 0 &&
NULL_PTR)))
}
if (ret == 0 &&
if (ret == 0 &&
&u_bytes, 0,
if (ret == 0 &&
&u_bytes,
/* skip PKCS#1 header in output from Decrypt function */
if (ret)
return (ret);
if (ret == 0)
return(0);
else
return(VERIFY_FINAL_FAILURE);
}
else {
return (-1);
}
return (0);
}
/*
* dst_bsafe_to_dns_key
* Converts key from RSA to DNS distribution format
* This function gets in a pointer to the public key and a work area
* to write the key into.
* Parameters
* public KEY structure
* out_str buffer to write encoded key into
* out_len size of out_str
* Return
* N >= 0 length of encoded key
* n < 0 error
*/
static int
const int out_len)
{
int n = 0;
return (-1);
if (n != 0)
return (-1);
return (-1);
} else { /* key exponent is > 2040 bits */
return (-1);
*op++ = 0; /* 3 byte length field */
dst_s_put_int16(op, e);
op += sizeof(e);
n = 2;
}
n++;
/*copy exponent */
}
else
n = -1;
return (n);
}
/*
* dst_bsafe_from_dns_key
* Converts from a DNS KEY RR format to an RSA KEY.
* Parameters
* len Length in bytes of DNS key
* key DNS key
* name Key name
* s_key DST structure that will point to the RSA key this routine
* will build.
* Return
* 0 The input key, s_key or name was null.
* 1 Success
*/
static int
{
int bytes;
return (0);
if (len == 0)
return (1);
EREPORT(("dst_bsafe_from_dns_key(): Memory allocation error 1"));
return (0);
}
EREPORT(("dst_bsafe_from_dns_key(): Memory allocation error 3"));
return (0);
}
if (bytes == 0) { /* special case for long exponents */
}
if (bytes > MAX_RSA_MODULUS_LEN) {
return (-1);
}
return (0);
return (0);
if (bytes > MAX_RSA_MODULUS_LEN) {
return (-1);
}
return (0);
return (1);
}
/*
* dst_bsafe_key_to_file_format
* Encodes an RSA Key into the portable file format.
* Parameters
* rkey RSA KEY structure
* buff output buffer
* buff_len size of output buffer
* Return
* 0 Failure - null input rkey
* -1 Failure - not enough space in output area
* N Success - Length of data returned in buff
*/
static int
const int buff_len)
{
char *bp;
return (0);
return (-1); /* no OR not enough space in output area */
/* write file header */
return (-1);
return (-2);
return (-3);
return (-4);
return (-5);
return (-6);
return (-7);
return (-8);
}
/*
* dst_bsafe_key_from_file_format
* Converts contents of a private key file into a private RSA key.
* Parameters
* RSA_Key structure to put key into
* buff buffer containing the encoded key
* buff_len the length of the buffer
* Return
* n >= 0 Foot print of the key converted
* n < 0 Error in conversion
*/
static int
const int buff_len)
{
int status;
char s[RAW_KEY_SIZE];
const char *p = buff;
return (-1);
malloc(sizeof(A_PKCS_RSA_PRIVATE_KEY));
return (-2);
}
if (!dst_s_verify_str(&p, "Modulus: "))
return (-3);
return (-4);
return (-5);
if (dst_s_verify_str(&p, "PublicExponent: ")) {
return (-5);
== NULL)
return (-6);
} else if (dst_s_verify_str(&p, "PrivateExponent: ")) {
return (-6);
== NULL)
return (-7);
len);
} else if (dst_s_verify_str(&p, "Prime1: ")) {
return (-7);
return (-8);
} else if (dst_s_verify_str(&p, "Prime2: ")) {
return (-8);
return (-9);
} else if (dst_s_verify_str(&p, "Exponent1: ")) {
return (-9);
== NULL)
return (-10);
} else if (dst_s_verify_str(&p, "Exponent2: ")) {
return (-10);
== NULL)
return (-11);
} else if (dst_s_verify_str(&p, "Coefficient: ")) {
return (-11);
return (-12);
} else {
EREPORT(("Decode_RSAKey(): Bad keyword %s\n", p));
return (-12);
}
} /* while p */
NULL)
return (-13);
== NULL)
return (-14);
if (status)
return (-1);
if (status)
return (-1);
if (status)
return (-1);
if (status)
return (-1);
return (0);
}
/*
* dst_bsafe_free_key_structure
* Frees all dynamicly allocated structures in RSA_Key.
*/
static void *
dst_bsafe_free_key_structure(void *key)
{
if (r_key->rk_Private_Key)
if (r_key->rk_Public_Key)
}
return (NULL);
}
/*
* dst_bsafe_generate_keypair
* Generates unique keys that are hard to predict.
* Parameters
* key generic Key structure
* exp the public exponent
* Return
* 0 Failure
* 1 Success
*/
static int
{
int i, status;
char exponent[4];
int exponent_len;
int randomSeedLen;
return (0);
EREPORT(("dst_bsafe_generate_keypair: Memory allocation error 3"));
return (0);
}
return (0);
/* exp = 0 or 1 are special (mean 3 or F4) */
if (exp == 0)
exp = 3;
else if (exp == 1)
exp = 65537;
/* Now encode the exponent and its length */
if (exp < 256) {
exponent_len = 1;
exponent_len = 2;
exponent_len = 3;
} else {
exponent_len = 4;
}
== NULL)
return (0);
if ((status = B_SetAlgorithmInfo
return (0);
NULL_SURRENDER)) != 0)
return (0);
return (0);
return (0);
return (0);
NULL_PTR))
!= 0)
return (0);
NULL_SURRENDER)) != 0)
return (0);
randomSeedLen = 256;
return (0);
return (0);
* values if it is not present.
* first fill the buffer with semi random data
* then fill as much as possible with good random data
*/
if (i <= randomSeedLen) {
return(0);
}
randomSeedLen, NULL_SURRENDER)) != 0) {
return (0);
}
!= 0) {
return (0);
}
return (1);
}
/**************************************************************************
* dst_bsafe_compare_keys
* Compare two keys for equality.
* Return
* 0 The keys are equal
* NON-ZERO The keys are not equal
*/
static int
{
return (1);
else
return (0);
}
static int
{
return(0);
return (1);
return (2);
if (rkey1->rk_Public_Key)
if (rkey2->rk_Public_Key)
return (0);
return (1);
if (status)
return (status);
/* if neither or only one is private key consider identical */
return (status);
if (rkey1->rk_Private_Key)
if (rkey2->rk_Private_Key)
return (0);
p2->publicExponent) ||
p2->privateExponent) ||
p2->primeExponent[0])||
return (status);
}
/*
* dst_bsafe_key_size()
* Function to calculate how the size of the key in bits
*/
static int
{
int size;
return (-1);
if (r_key->rk_Private_Key)
else if (r_key->rk_Public_Key)
return (size);
}
/*
* dst_bsafe_md5digest(): function to digest data using MD5 digest function
* if needed
*/
static int
{
int status = 0;
printf("NO digest obj\n");
exit(33);
}
if ((mode & SIG_MODE_INIT) &&
return (SIGN_INIT_FAILURE);
return (SIGN_UPDATE_FAILURE);
if (mode & SIG_MODE_FINAL) {
return (SIGN_FINAL_FAILURE);
return (work_size);
}
return (0);
}
/*
* just use the standard memory functions for bsafe
*/
void
{
}
{
}
int
{
}
void
{
}
void
{
}
void
{
}
{
}
#else /* BSAFE NOT available */
int
{
return (0);
}
#endif /* BSAFE */