Commit bbc204a2 authored by Mark Andrews's avatar Mark Andrews

2669. [func] Update PKCS#11 support to support Keyper HSM.

                        Update PKCS#11 patch to be against openssl-0.9.8i.
parent 3e1938b7
2669. [func] Update PKCS#11 support to support Keyper HSM.
Update PKCS#11 patch to be against openssl-0.9.8i.
--- 9.7.0a3 released ---
2668. [func] Several improvements to dnssec-* tools, including:
......
......@@ -4,8 +4,9 @@
Prerequisite
The PKCS#11 support needs a PKCS#11 OpenSSL engine based on the Solaris one,
released the 2007-11-21 for OpenSSL 0.9.8g, with a bug fix (call to free)
and some improvements, including user friendly PIN management.
released the 2008-12-02 for OpenSSL 0.9.8i, with back port of key by reference
and some improvements, including user friendly PIN management. You may also
use the original engine code.
Compilation
......@@ -14,7 +15,9 @@ Compilation
PKCS#11 Libraries
Tested with Solaris one with a SCA board and with openCryptoki with the
software token.
software token. Known to work on Linux and Windows 2003 server so
should work on most operating systems. For AEP Keyper or any device used
only for its protected key store, please switch to the sign-only engine.
OpenSSL Engines
......@@ -35,9 +38,13 @@ PKCS#11 tools
The contrib/pkcs11-keygen directory contains a set of experimental tools
to handle keys stored in a Hardware Security Module at the benefit of BIND.
The patch for OpenSSL 0.9.8g is in this directory. Read its README.pkcs11
The patch for OpenSSL 0.9.8i is in this directory. Read its README.pkcs11
for the way to use it (these are the original notes so with the original
path, etc. Define OPENCRYPTOKI to use it with openCryptoki.)
path, etc. Define HAVE_GETPASSPHRASE if you have getpassphrase() on
a operating system which is not Solaris.)
Not all tools are supported on AEP Keyper but genkey and dnssec-keyfromlabel
are functional.
PIN management
......@@ -55,7 +62,33 @@ OpenSSL configuration file (aka. openssl.cnf) by adding in it:
[ pkcs11_section ]
PIN = put__your__pin__value__here
Note
Slot management
The engine tries to use the first best slot but it is recommended
to simply use the slot 0 (usual default, meta-slot on Solaris).
Sign-only engine
openssl.../crypto/engibe/hw_pk11-kp.c and hw_pk11_pub-kp.c contain
a stripped down version of hw_pk11.c and hw_pk11_pub.c files which
has only the useful functions (i.e., signature with a RSA private
key in the device protected key store and key loading).
This engine should be used with a device which provides mainly
a protected store and no acceleration. AEP Keyper is an example
of such a device (BTW with the fully capable engine, key export
must be enabled on this device and this configuration is not yet
supported).
Original engine
If you are using the original engine and getpassphrase() is not defined, add:
#define getpassphrase(x) getpass(x)
in openssl.../crypto/engine/hw_pk11_pub.c
Notes
Some names here are registered trademarks, at least Solaris is a trademark
of Sun Microsystems Inc...
Include files are from RSA Labs., PKCS#11 version is 2.20 amendment 3.
The PKCS#11 support is compatible with the forthcoming FIPS 140-2 support.
......@@ -4,6 +4,8 @@ an id of the keytag in hex.
Run genkey.sh to generate a new key and call the other programs in turn.
Run writekey.sh to load key to the key store from Kxxx.{key,private}.
Run genkey, dnssec-keyfromlabel and optionally set_key_id when you have
no perl or no Net::DNS::SEC perl module.
genkey[.c] uses PKCS11 calls to generate keys.
PEM_write_pubkey[.c] uses OpenSSL to write a public key from the key store
......
......@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
* $Id: dst_api.c,v 1.28 2009/09/02 06:29:01 each Exp $
* $Id: dst_api.c,v 1.29 2009/09/03 04:09:58 marka Exp $
*/
/*! \file */
......@@ -432,7 +432,6 @@ dst_key_fromnamedfile(const char *filename, const char *dirname,
{
isc_result_t result;
dst_key_t *pubkey = NULL, *key = NULL;
dns_keytag_t id;
char *newfilename = NULL;
int newfilenamelen = 0;
isc_lex_t *lex = NULL;
......@@ -489,11 +488,10 @@ dst_key_fromnamedfile(const char *filename, const char *dirname,
key = get_key_struct(pubkey->key_name, pubkey->key_alg,
pubkey->key_flags, pubkey->key_proto, 0,
pubkey->key_class, mctx);
id = pubkey->key_id;
dst_key_free(&pubkey);
if (key == NULL)
if (key == NULL) {
dst_key_free(&pubkey);
return (ISC_R_NOMEMORY);
}
if (key->func->parse == NULL)
RETERR(DST_R_UNSUPPORTEDALG);
......@@ -512,17 +510,20 @@ dst_key_fromnamedfile(const char *filename, const char *dirname,
RETERR(isc_lex_openfile(lex, newfilename));
isc_mem_put(mctx, newfilename, newfilenamelen);
RETERR(key->func->parse(key, lex));
RETERR(key->func->parse(key, lex, pubkey));
isc_lex_destroy(&lex);
RETERR(computeid(key));
if (id != key->key_id)
if (pubkey->key_id != key->key_id)
RETERR(DST_R_INVALIDPRIVATEKEY);
dst_key_free(&pubkey);
*keyp = key;
return (ISC_R_SUCCESS);
out:
if (pubkey != NULL)
dst_key_free(&pubkey);
if (newfilename != NULL)
isc_mem_put(mctx, newfilename, newfilenamelen);
if (lex != NULL)
......@@ -657,7 +658,7 @@ dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer) {
RETERR(isc_lex_create(key->mctx, 1500, &lex));
RETERR(isc_lex_openbuffer(lex, buffer));
RETERR(key->func->parse(key, lex));
RETERR(key->func->parse(key, lex, NULL));
out:
if (lex != NULL)
isc_lex_destroy(&lex);
......
......@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dst_internal.h,v 1.16 2009/09/02 06:29:01 each Exp $ */
/* $Id: dst_internal.h,v 1.17 2009/09/03 04:09:58 marka Exp $ */
#ifndef DST_DST_INTERNAL_H
#define DST_DST_INTERNAL_H 1
......@@ -173,7 +173,9 @@ struct dst_func {
isc_result_t (*todns)(const dst_key_t *key, isc_buffer_t *data);
isc_result_t (*fromdns)(dst_key_t *key, isc_buffer_t *data);
isc_result_t (*tofile)(const dst_key_t *key, const char *directory);
isc_result_t (*parse)(dst_key_t *key, isc_lex_t *lexer);
isc_result_t (*parse)(dst_key_t *key,
isc_lex_t *lexer,
dst_key_t *pub);
/* cleanup */
void (*cleanup)(void);
......
......@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
* $Id: hmac_link.c,v 1.11 2008/04/01 23:47:10 tbox Exp $
* $Id: hmac_link.c,v 1.12 2009/09/03 04:09:58 marka Exp $
*/
#include <config.h>
......@@ -268,13 +268,14 @@ hmacmd5_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer) {
hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx, &priv);
if (result != ISC_R_SUCCESS)
......@@ -537,13 +538,14 @@ hmacsha1_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer) {
hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA1, lexer, mctx,
&priv);
......@@ -807,13 +809,14 @@ hmacsha224_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer) {
hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA224, lexer, mctx,
&priv);
......@@ -1077,13 +1080,14 @@ hmacsha256_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer) {
hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA256, lexer, mctx,
&priv);
......@@ -1347,13 +1351,14 @@ hmacsha384_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer) {
hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA384, lexer, mctx,
&priv);
......@@ -1617,13 +1622,14 @@ hmacsha512_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer) {
hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t result, tresult;
isc_buffer_t b;
isc_mem_t *mctx = key->mctx;
unsigned int i;
UNUSED(pub);
/* read private key file */
result = dst__privstruct_parse(key, DST_ALG_HMACSHA512, lexer, mctx,
&priv);
......
......@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
* $Id: openssl_link.c,v 1.25 2009/02/11 03:04:18 jinmei Exp $
* $Id: openssl_link.c,v 1.26 2009/09/03 04:09:58 marka Exp $
*/
#ifdef OPENSSL
......@@ -223,7 +223,7 @@ dst__openssl_init() {
if (result != ISC_R_SUCCESS)
goto cleanup_rm;
}
#endif /* USE_PKCS11 */
#else /* USE_PKCS11 */
if (engine_id != NULL) {
e = ENGINE_by_id(engine_id);
if (e == NULL) {
......@@ -237,6 +237,8 @@ dst__openssl_init() {
}
ENGINE_set_default(e, ENGINE_METHOD_ALL);
ENGINE_free(e);
if (he == NULL)
he = e;
} else {
ENGINE_register_all_complete();
for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) {
......@@ -251,6 +253,7 @@ dst__openssl_init() {
}
}
}
#endif /* USE_PKCS11 */
re = ENGINE_get_default_RAND();
if (re == NULL) {
re = ENGINE_new();
......@@ -292,10 +295,11 @@ dst__openssl_destroy() {
#endif
EVP_cleanup();
#if defined(USE_ENGINE)
if (e != NULL) {
if (he != NULL)
ENGINE_finish(he);
else if (e != NULL)
ENGINE_finish(e);
e = NULL;
}
he = e = NULL;
#if defined(USE_ENGINE) && OPENSSL_VERSION_NUMBER >= 0x00907000L
ENGINE_cleanup();
#endif
......@@ -345,7 +349,6 @@ dst__openssl_getengine(const char *name) {
UNUSED(name);
#if defined(USE_ENGINE)
return (he);
#else
......
......@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
* $Id: openssldh_link.c,v 1.14 2008/04/01 23:47:10 tbox Exp $
* $Id: openssldh_link.c,v 1.15 2009/09/03 04:09:58 marka Exp $
*/
#ifdef OPENSSL
......@@ -476,7 +476,7 @@ openssldh_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
openssldh_parse(dst_key_t *key, isc_lex_t *lexer) {
openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t ret;
int i;
......@@ -484,6 +484,7 @@ openssldh_parse(dst_key_t *key, isc_lex_t *lexer) {
isc_mem_t *mctx;
#define DST_RET(a) {ret = a; goto err;}
UNUSED(pub);
mctx = key->mctx;
/* read private key file */
......
......@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: openssldsa_link.c,v 1.15 2009/01/14 23:48:00 tbox Exp $ */
/* $Id: openssldsa_link.c,v 1.16 2009/09/03 04:09:58 marka Exp $ */
#ifdef OPENSSL
#ifndef USE_EVP
......@@ -512,7 +512,7 @@ openssldsa_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
openssldsa_parse(dst_key_t *key, isc_lex_t *lexer) {
openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t ret;
int i;
......@@ -520,6 +520,7 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer) {
isc_mem_t *mctx = key->mctx;
#define DST_RET(a) {ret = a; goto err;}
UNUSED(pub);
/* read private key file */
ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv);
if (ret != ISC_R_SUCCESS)
......
......@@ -17,7 +17,7 @@
/*
* Principal Author: Brian Wellington
* $Id: opensslrsa_link.c,v 1.25 2009/08/18 07:45:14 marka Exp $
* $Id: opensslrsa_link.c,v 1.26 2009/09/03 04:09:58 marka Exp $
*/
#ifdef OPENSSL
#ifndef USE_EVP
......@@ -767,16 +767,52 @@ opensslrsa_tofile(const dst_key_t *key, const char *directory) {
}
static isc_result_t
opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
rsa_check(RSA *rsa, RSA *pub)
{
/* Public parameters should be the same but if they are not set
* copy them from the public key. */
if (pub != NULL) {
if (rsa->n != NULL) {
if (BN_cmp(rsa->n, pub->n) != 0)
return (DST_R_INVALIDPRIVATEKEY);
} else {
rsa->n = pub->n;
pub->n = NULL;
}
if (rsa->e != NULL) {
if (BN_cmp(rsa->e, pub->e) != 0)
return (DST_R_INVALIDPRIVATEKEY);
} else {
rsa->e = pub->e;
pub->e = NULL;
}
}
if (rsa->n == NULL || rsa->e == NULL)
return (DST_R_INVALIDPRIVATEKEY);
return (ISC_R_SUCCESS);
}
static isc_result_t
opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t ret;
int i;
RSA *rsa = NULL;
RSA *rsa = NULL, *pubrsa = NULL;
ENGINE *e = NULL;
isc_mem_t *mctx = key->mctx;
const char *name = NULL, *label = NULL;
EVP_PKEY *pkey = NULL;
#if USE_EVP
if (pub != NULL && pub->keydata.pkey != NULL)
pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey);
#else
if (pub != NULL && pub->keydata.rsa != NULL) {
pubrsa = pub->keydata.rsa;
pub->keydata.rsa = NULL;
}
#endif
/* read private key file */
ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
if (ret != ISC_R_SUCCESS)
......@@ -815,16 +851,20 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
key->label = isc_mem_strdup(key->mctx, label);
if (key->label == NULL)
DST_RET(ISC_R_NOMEMORY);
rsa = EVP_PKEY_get1_RSA(pkey);
if (rsa == NULL)
DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
DST_RET(DST_R_INVALIDPRIVATEKEY);
key->key_size = EVP_PKEY_bits(pkey);
#if USE_EVP
key->keydata.pkey = pkey;
#else
key->keydata.rsa = EVP_PKEY_get1_RSA(pkey);
if (rsa == NULL)
DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
key->keydata.rsa = rsa;
EVP_PKEY_free(pkey);
#endif
dst__privstruct_free(&priv, mctx);
memset(&priv, 0, sizeof(priv));
return (ISC_R_SUCCESS);
}
......@@ -889,8 +929,13 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
}
}
dst__privstruct_free(&priv, mctx);
memset(&priv, 0, sizeof(priv));
if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
DST_RET(DST_R_INVALIDPRIVATEKEY);
key->key_size = BN_num_bits(rsa->n);
if (pubrsa != NULL)
RSA_free(pubrsa);
#if USE_EVP
RSA_free(rsa);
#endif
......@@ -904,6 +949,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
#endif
if (rsa != NULL)
RSA_free(rsa);
if (pubrsa != NULL)
RSA_free(pubrsa);
opensslrsa_destroy(key);
dst__privstruct_free(&priv, mctx);
memset(&priv, 0, sizeof(priv));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment