opensslrsa_link.c revision 433e06a25cdd92d665abda3e64c2c65f4a3f9b21
/*
* Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* 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 ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC 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.
*/
/*
* Principal Author: Brian Wellington
* $Id: opensslrsa_link.c,v 1.38 2011/01/10 05:32:03 marka Exp $
*/
#ifdef OPENSSL
#include <config.h>
#ifndef USE_EVP
#if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA512)
#define USE_EVP 0
#else
#define USE_EVP 1
#endif
#endif
#include "dst_internal.h"
#include "dst_openssl.h"
#include "dst_parse.h"
#if OPENSSL_VERSION_NUMBER > 0x00908000L
#endif
/*
* We don't use configure for windows so enforce the OpenSSL version
* here. Unlike with configure we don't support overriding this test.
*/
#ifdef WIN32
#if !((OPENSSL_VERSION_NUMBER >= 0x009070cfL && \
OPENSSL_VERSION_NUMBER < 0x00908000L) || \
OPENSSL_VERSION_NUMBER >= 0x0090804fL)
#endif
#endif
/*
* XXXMPA Temporarily disable RSA_BLINDING as it requires
* good quality random data that cannot currently be guaranteed.
* XXXMPA Find which versions of openssl use pseudo random data
* and set RSA_FLAG_BLINDING for those.
*/
#if 0
#if OPENSSL_VERSION_NUMBER < 0x0090601fL
do { \
} while (0)
#else
do { \
} while (0)
#endif
#endif
#if OPENSSL_VERSION_NUMBER < 0x0090601fL
do { \
} while (0)
#elif defined(RSA_FLAG_NO_BLINDING)
do { \
} while (0)
#else
do { \
} while (0)
#endif
static isc_result_t
#if USE_EVP
#endif
#if USE_EVP
if (evp_md_ctx == NULL)
return (ISC_R_NOMEMORY);
case DST_ALG_RSAMD5:
break;
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
break;
#ifdef HAVE_EVP_SHA256
case DST_ALG_RSASHA256:
break;
#endif
#ifdef HAVE_EVP_SHA512
case DST_ALG_RSASHA512:
type = EVP_sha512();
break;
#endif
default:
INSIST(0);
}
return (ISC_R_FAILURE);
}
#else
case DST_ALG_RSAMD5:
{
return (ISC_R_NOMEMORY);
}
break;
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
{
return (ISC_R_NOMEMORY);
}
break;
case DST_ALG_RSASHA256:
{
sizeof(isc_sha256_t));
return (ISC_R_NOMEMORY);
}
break;
case DST_ALG_RSASHA512:
{
sizeof(isc_sha512_t));
return (ISC_R_NOMEMORY);
}
break;
default:
INSIST(0);
}
#endif
return (ISC_R_SUCCESS);
}
static void
#if USE_EVP
#endif
#if USE_EVP
if (evp_md_ctx != NULL) {
}
#else
case DST_ALG_RSAMD5:
{
sizeof(isc_md5_t));
}
}
break;
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
{
sizeof(isc_sha1_t));
}
}
break;
case DST_ALG_RSASHA256:
{
sizeof(isc_sha256_t));
}
}
break;
case DST_ALG_RSASHA512:
{
sizeof(isc_sha512_t));
}
}
break;
default:
INSIST(0);
}
#endif
}
static isc_result_t
#if USE_EVP
#endif
#if USE_EVP
return (ISC_R_FAILURE);
}
#else
case DST_ALG_RSAMD5:
{
}
break;
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
{
}
break;
case DST_ALG_RSASHA256:
{
}
break;
case DST_ALG_RSASHA512:
{
}
break;
default:
INSIST(0);
}
#endif
return (ISC_R_SUCCESS);
}
/*
* Digest prefixes from RFC 5702.
*/
static unsigned char sha256_prefix[] =
{ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
static unsigned char sha512_prefix[] =
{ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
#define PREFIXLEN sizeof(sha512_prefix)
#else
#define PREFIXLEN 0
#endif
static isc_result_t
isc_region_t r;
unsigned int siglen = 0;
#if USE_EVP
#else
/* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
int status;
int type = 0;
unsigned int digestlen = 0;
char *message;
unsigned long err;
const char* file;
int line;
#if OPENSSL_VERSION_NUMBER < 0x00908000L
unsigned int prefixlen = 0;
#endif
#endif
#if USE_EVP
return (ISC_R_NOSPACE);
return (ISC_R_FAILURE);
}
#else
return (ISC_R_NOSPACE);
case DST_ALG_RSAMD5:
{
}
break;
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
{
}
break;
case DST_ALG_RSASHA256:
{
#if OPENSSL_VERSION_NUMBER < 0x00908000L
prefixlen = sizeof(sha256_prefix);
#else
type = NID_sha256;
#endif
}
break;
case DST_ALG_RSASHA512:
{
#if OPENSSL_VERSION_NUMBER < 0x00908000L
prefixlen = sizeof(sha512_prefix);
#else
type = NID_sha512;
#endif
}
break;
default:
INSIST(0);
}
#if OPENSSL_VERSION_NUMBER < 0x00908000L
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
break;
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
if (status < 0)
status = 0;
else
break;
default:
INSIST(0);
}
#else
#endif
if (status == 0) {
if (err != 0U) {
}
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
}
#endif
return (ISC_R_SUCCESS);
}
static isc_result_t
int status = 0;
#if USE_EVP
#else
/* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
unsigned char digest[ISC_SHA512_DIGESTLENGTH];
int type = 0;
unsigned int digestlen = 0;
#if OPENSSL_VERSION_NUMBER < 0x00908000L
unsigned int prefixlen = 0;
#endif
#endif
#if USE_EVP
#else
case DST_ALG_RSAMD5:
{
}
break;
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
{
}
break;
case DST_ALG_RSASHA256:
{
#if OPENSSL_VERSION_NUMBER < 0x00908000L
prefixlen = sizeof(sha256_prefix);
#else
type = NID_sha256;
#endif
}
break;
case DST_ALG_RSASHA512:
{
#if OPENSSL_VERSION_NUMBER < 0x00908000L
prefixlen = sizeof(sha512_prefix);
#else
type = NID_sha512;
#endif
}
break;
default:
INSIST(0);
}
return (DST_R_VERIFYFAILURE);
#if OPENSSL_VERSION_NUMBER < 0x00908000L
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
break;
case DST_ALG_RSASHA256:
case DST_ALG_RSASHA512:
{
/*
* 1024 is big enough for all valid RSA bit sizes
* for use with DNSSEC.
*/
return (DST_R_VERIFYFAILURE);
if (status <= 0)
return (DST_R_VERIFYFAILURE);
return (DST_R_VERIFYFAILURE);
return (DST_R_VERIFYFAILURE);
return (DST_R_VERIFYFAILURE);
status = 1;
}
break;
default:
INSIST(0);
}
#else
#endif
#endif
if (status != 1)
return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
return (ISC_R_SUCCESS);
}
static isc_boolean_t
int status;
#if USE_EVP
#endif
#if USE_EVP
/*
* The pkey reference will keep these around after
* the RSA_free() call.
*/
}
}
#else
#endif
return (ISC_TRUE);
return (ISC_FALSE);
if (status != 0)
return (ISC_FALSE);
#if USE_EVP
return (ISC_FALSE);
/*
* Can't compare private parameters, BTW does it make sense?
*/
return (ISC_TRUE);
}
#endif
return (ISC_FALSE);
if (status != 0)
return (ISC_FALSE);
}
return (ISC_TRUE);
}
#if OPENSSL_VERSION_NUMBER > 0x00908000L
static int
{
union {
void *dptr;
void (*fptr)(int);
} u;
UNUSED(n);
u.fptr(p);
return (1);
}
#endif
static isc_result_t
#if OPENSSL_VERSION_NUMBER > 0x00908000L
union {
void *dptr;
void (*fptr)(int);
} u;
#if USE_EVP
#endif
goto err;
#if USE_EVP
goto err;
goto err;
#endif
if (exp == 0) {
/* RSA_F4 0x10001 */
BN_set_bit(e, 0);
BN_set_bit(e, 16);
} else {
/* F5 0x100000001 */
BN_set_bit(e, 0);
BN_set_bit(e, 32);
}
} else {
}
BN_free(e);
#if USE_EVP
#else
#endif
return (ISC_R_SUCCESS);
}
err:
#if USE_EVP
#endif
if (e != NULL)
BN_free(e);
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
#else
unsigned long e;
#if USE_EVP
return (ISC_R_NOMEMORY);
#else
#endif
if (exp == 0)
e = RSA_F4;
else
e = 0x40000003;
#if USE_EVP
#endif
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
}
#if USE_EVP
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
}
#else
#endif
return (ISC_R_SUCCESS);
#endif
}
static isc_boolean_t
#if USE_EVP
/* key->keydata.pkey still has a reference so rsa is still valid. */
#else
#endif
return (ISC_TRUE);
}
static void
#if USE_EVP
#else
#endif
}
static isc_result_t
isc_region_t r;
unsigned int e_bytes;
unsigned int mod_bytes;
#if USE_EVP
#endif
#if USE_EVP
#else
#endif
#if USE_EVP
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
#else
#endif
if (r.length < 1)
isc_region_consume(&r, 1);
} else {
if (r.length < 3)
isc_buffer_putuint8(data, 0);
isc_region_consume(&r, 3);
}
isc_region_consume(&r, e_bytes);
ret = ISC_R_SUCCESS;
err:
#if USE_EVP
#endif
return (ret);
}
static isc_result_t
isc_region_t r;
unsigned int e_bytes;
#if USE_EVP
#endif
if (r.length == 0)
return (ISC_R_SUCCESS);
return (dst__openssl_toresult(ISC_R_NOMEMORY));
if (r.length < 1) {
return (DST_R_INVALIDPUBLICKEY);
}
r.length--;
if (e_bytes == 0) {
if (r.length < 2) {
return (DST_R_INVALIDPUBLICKEY);
}
r.length -= 2;
}
return (DST_R_INVALIDPUBLICKEY);
}
#if USE_EVP
pkey = EVP_PKEY_new();
return (ISC_R_NOMEMORY);
}
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
}
#else
#endif
return (ISC_R_SUCCESS);
}
static isc_result_t
int i;
unsigned char *bufs[8];
#if USE_EVP
return (DST_R_NULLKEY);
return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
#else
return (DST_R_NULLKEY);
#endif
for (i = 0; i < 8; i++) {
goto fail;
}
}
i = 0;
i++;
i++;
i++;
}
i++;
}
i++;
}
i++;
}
i++;
}
i++;
}
i++;
}
i++;
}
fail:
#if USE_EVP
#endif
for (i = 0; i < 8; i++) {
break;
}
return (result);
}
static isc_result_t
{
/* Public parameters should be the same but if they are not set
* copy them from the public key. */
return (DST_R_INVALIDPRIVATEKEY);
} else {
}
return (DST_R_INVALIDPRIVATEKEY);
} else {
}
}
return (DST_R_INVALIDPRIVATEKEY);
return (ISC_R_SUCCESS);
}
static isc_result_t
int i;
#if USE_EVP
#else
}
#endif
/* read private key file */
if (ret != ISC_R_SUCCESS)
return (ret);
case TAG_RSA_ENGINE:
break;
case TAG_RSA_LABEL:
break;
default:
break;
}
}
/*
* Is this key is stored in a HSM?
* See if we can fetch it.
*/
e = dst__openssl_getengine(engine);
if (e == NULL)
/* ERR_print_errors_fp(stderr); */
}
#if USE_EVP
#else
#endif
return (ISC_R_SUCCESS);
}
#if USE_EVP
pkey = EVP_PKEY_new();
#else
#endif
case TAG_RSA_ENGINE:
continue;
case TAG_RSA_LABEL:
continue;
case TAG_RSA_PIN:
continue;
default:
}
case TAG_RSA_MODULUS:
break;
case TAG_RSA_PUBLICEXPONENT:
break;
case TAG_RSA_PRIVATEEXPONENT:
break;
case TAG_RSA_PRIME1:
break;
case TAG_RSA_PRIME2:
break;
case TAG_RSA_EXPONENT1:
break;
case TAG_RSA_EXPONENT2:
break;
case TAG_RSA_COEFFICIENT:
break;
}
}
#if USE_EVP
#endif
return (ISC_R_SUCCESS);
err:
#if USE_EVP
#endif
return (ret);
}
static isc_result_t
const char *pin)
{
char *colon;
e = dst__openssl_getengine(engine);
if (e == NULL)
}
} else {
*colon = '\0';
}
#if USE_EVP
#else
#endif
return (ISC_R_SUCCESS);
err:
return (ret);
}
static dst_func_t opensslrsa_functions = {
NULL, /*%< computesecret */
NULL, /*%< paramcompare */
NULL, /*%< cleanup */
NULL, /*%< dump */
NULL, /*%< restore */
};
switch (algorithm) {
case DST_ALG_RSASHA256:
#if defined(HAVE_EVP_SHA256) || !USE_EVP
#endif
break;
case DST_ALG_RSASHA512:
#if defined(HAVE_EVP_SHA512) || !USE_EVP
#endif
break;
default:
break;
}
}
return (ISC_R_SUCCESS);
}
#else /* OPENSSL */
#endif /* OPENSSL */
/*! \file */