Support in SSL for setting a private key id

Works with PKCS #11 to use key on device.
This commit is contained in:
Sean Parkinson 2019-02-08 12:29:19 +10:00
parent dd32df5df1
commit 47922a4d87
5 changed files with 122 additions and 93 deletions

View File

@ -4415,6 +4415,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#endif
ssl->buffers.key = ctx->privateKey;
ssl->buffers.keyType = ctx->privateKeyType;
ssl->buffers.keyId = ctx->privateKeyId;
ssl->buffers.keySz = ctx->privateKeySz;
#endif
#if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \
@ -16927,6 +16928,44 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
ERROR_OUT(NO_PRIVATE_KEY, exit_dpk);
}
#ifdef HAVE_PKCS11
if (ssl->devId != INVALID_DEVID && ssl->buffers.keyId) {
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ret != 0) {
goto exit_dpk;
}
if (ssl->buffers.keyType == rsa_sa_algo) {
ret = wc_InitRsaKey_Id((RsaKey*)ssl->hsKey,
ssl->buffers.key->buffer, ssl->buffers.key->length,
ssl->heap, ssl->devId);
if (ret == 0) {
if (ssl->buffers.keySz < ssl->options.minRsaKeySz) {
WOLFSSL_MSG("RSA key size too small");
ERROR_OUT(RSA_KEY_SIZE_E, exit_dpk);
}
/* Return the maximum signature length. */
*length = (word16)ssl->buffers.keySz;
}
}
else if (ssl->buffers.keyType == ecc_dsa_sa_algo) {
ret = wc_ecc_init_id((ecc_key*)ssl->hsKey, ssl->buffers.key->buffer,
ssl->buffers.key->length, ssl->heap, ssl->devId);
if (ret == 0) {
if (ssl->buffers.keySz < ssl->options.minEccKeySz) {
WOLFSSL_MSG("ECC key size too small");
ERROR_OUT(ECC_KEY_SIZE_E, exit_dpk);
}
/* Return the maximum signature length. */
*length = (word16)ssl->buffers.keySz;
}
}
goto exit_dpk;
}
#endif
#ifndef NO_RSA
if (ssl->buffers.keyType == rsa_sa_algo || ssl->buffers.keyType == 0) {
ssl->hsType = DYNAMIC_TYPE_RSA;
@ -22012,25 +22051,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#endif
case rsa_sa_algo:
{
word32 i = 0;
int keySz;
word16 keySz;
ssl->hsType = DYNAMIC_TYPE_RSA;
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ssl->buffers.keyType == 0)
ssl->buffers.keyType = rsa_sa_algo;
ret = DecodePrivateKey(ssl, &keySz);
if (ret != 0) {
goto exit_sske;
}
ret = wc_RsaPrivateKeyDecode(
ssl->buffers.key->buffer,
&i,
(RsaKey*)ssl->hsKey,
ssl->buffers.key->length);
if (ret != 0) {
goto exit_sske;
}
keySz = wc_RsaEncryptSize((RsaKey*)ssl->hsKey);
if (keySz < 0) { /* test if keySz has error */
ERROR_OUT(keySz, exit_sske);
}
@ -22045,29 +22072,20 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef HAVE_ECC
case ecc_dsa_sa_algo:
{
word32 i = 0;
word16 keySz;
ssl->hsType = DYNAMIC_TYPE_ECC;
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ssl->buffers.keyType == 0)
ssl->buffers.keyType = ecc_dsa_sa_algo;
ret = DecodePrivateKey(ssl, &keySz);
if (ret != 0) {
goto exit_sske;
}
ret = wc_EccPrivateKeyDecode(
ssl->buffers.key->buffer,
&i,
(ecc_key*)ssl->hsKey,
ssl->buffers.key->length);
if (ret != 0) {
goto exit_sske;
ERROR_OUT(keySz, exit_sske);
}
/* worst case estimate */
args->tmpSigSz = wc_ecc_sig_size(
(ecc_key*)ssl->hsKey);
args->tmpSigSz = keySz;
/* check the minimum ECC key size */
if (wc_ecc_size((ecc_key*)ssl->hsKey) <
ssl->options.minEccKeySz) {
if (keySz < ssl->options.minEccKeySz) {
WOLFSSL_MSG("ECC key size too small");
ERROR_OUT(ECC_KEY_SIZE_E, exit_sske);
}
@ -22077,21 +22095,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifdef HAVE_ED25519
case ed25519_sa_algo:
{
word32 i = 0;
word16 keySz;
ssl->hsType = DYNAMIC_TYPE_ED25519;
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ssl->buffers.keyType == 0)
ssl->buffers.keyType = ed25519_sa_algo;
ret = DecodePrivateKey(ssl, &keySz);
if (ret != 0) {
goto exit_sske;
}
ret = wc_Ed25519PrivateKeyDecode(
ssl->buffers.key->buffer,
&i,
(ed25519_key*)ssl->hsKey,
ssl->buffers.key->length);
if (ret != 0) {
goto exit_sske;
ERROR_OUT(keySz, exit_sske);
}
/* worst case estimate */
@ -22307,7 +22318,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
preSigSz = args->length;
if (!ssl->options.usingAnon_cipher) {
int keySz;
word16 keySz;
/* sig length */
args->length += LENGTH_SZ;
@ -22322,22 +22333,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
}
else
{
word32 i = 0;
ssl->hsType = DYNAMIC_TYPE_RSA;
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ssl->buffers.keyType == 0)
ssl->buffers.keyType = rsa_sa_algo;
ret = DecodePrivateKey(ssl, &keySz);
if (ret != 0) {
goto exit_sske;
ERROR_OUT(keySz, exit_sske);
}
ret = wc_RsaPrivateKeyDecode(
ssl->buffers.key->buffer, &i,
(RsaKey*)ssl->hsKey,
ssl->buffers.key->length);
if (ret != 0) {
goto exit_sske;
}
keySz = wc_RsaEncryptSize((RsaKey*)ssl->hsKey);
}
if (keySz <= 0) { /* test if keySz has error */
@ -25014,22 +25016,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifndef NO_RSA
case rsa_kea:
{
word32 i = 0;
int keySz;
word16 keySz;
ssl->hsType = DYNAMIC_TYPE_RSA;
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ssl->buffers.keyType == 0)
ssl->buffers.keyType = rsa_sa_algo;
ret = DecodePrivateKey(ssl, &keySz);
if (ret != 0) {
goto exit_dcke;
}
ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer,
&i, (RsaKey*)ssl->hsKey, ssl->buffers.key->length);
if (ret != 0) {
goto exit_dcke;
}
keySz = wc_RsaEncryptSize((RsaKey*)ssl->hsKey);
if (keySz < 0) { /* test if keySz has error */
ERROR_OUT(keySz, exit_dcke);
}
args->length = (word32)keySz;
@ -25172,27 +25165,20 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* handle static private key */
if (ssl->specs.static_ecdh &&
ssl->ecdhCurveOID != ECC_X25519_OID) {
word32 i = 0;
word16 keySz;
ssl->hsType = DYNAMIC_TYPE_ECC;
ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey);
if (ssl->buffers.keyType == 0)
ssl->buffers.keyType = rsa_sa_algo;
ret = DecodePrivateKey(ssl, &keySz);
if (ret != 0) {
goto exit_dcke;
ERROR_OUT(keySz, exit_dcke);
}
ret = wc_EccPrivateKeyDecode(
ssl->buffers.key->buffer,
&i,
(ecc_key*)ssl->hsKey,
ssl->buffers.key->length);
if (ret == 0) {
private_key = (ecc_key*)ssl->hsKey;
if (wc_ecc_size(private_key) <
ssl->options.minEccKeySz) {
WOLFSSL_MSG("ECC key too small");
ERROR_OUT(ECC_KEY_SIZE_E, exit_dcke);
}
if (keySz < ssl->options.minEccKeySz) {
WOLFSSL_MSG("ECC key too small");
ERROR_OUT(ECC_KEY_SIZE_E, exit_dcke);
}
private_key = (ecc_key*)ssl->hsKey;
}
#endif

View File

@ -11156,6 +11156,24 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
return ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL,NULL,0);
}
#ifdef HAVE_PKCS11
int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX* ctx, const unsigned char* id,
long sz, long keySz)
{
int ret = WOLFSSL_FAILURE;
FreeDer(&ctx->privateKey);
if (AllocDer(&ctx->privateKey, sz, PRIVATEKEY_TYPE, ctx->heap) == 0) {
XMEMCPY(ctx->privateKey->buffer, id, sz);
ctx->privateKeyId = 1;
ctx->privateKeySz = keySz;
ret = WOLFSSL_SUCCESS;
}
return ret;
}
#endif
int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX* ctx,
const unsigned char* in, long sz, int format)
@ -11291,6 +11309,26 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
ssl, NULL, 0);
}
#ifdef HAVE_PKCS11
int wolfSSL_use_PrivateKey_id(WOLFSSL* ssl, const unsigned char* id,
long sz, long keySz)
{
int ret = WOLFSSL_FAILURE;
FreeDer(&ssl->buffers.key);
if (AllocDer(&ssl->buffers.key, sz, PRIVATEKEY_TYPE, ssl->heap) == 0) {
XMEMCPY(ssl->buffers.key->buffer, id, sz);
ssl->buffers.weOwnKey = 1;
ssl->buffers.keyId = 1;
ssl->buffers.keySz = keySz;
ret = WOLFSSL_SUCCESS;
}
return ret;
}
#endif
int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL* ssl,
const unsigned char* in, long sz, int format)
{
@ -12348,7 +12386,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
ret = wolfSSL_EVP_get_hashinfo(md, &hashType, NULL);
if (ret == WOLFSSL_FAILURE)
goto end;
ret = wc_PBKDF1_ex(key, info->keySz, iv, info->ivSz, data, sz, salt,
EVP_SALT_SIZE, count, hashType, NULL);
if (ret == 0)
@ -13055,7 +13093,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
int wolfSSL_EVP_MD_CTX_block_size(const WOLFSSL_EVP_MD_CTX *ctx) {
return(wolfSSL_EVP_MD_block_size(wolfSSL_EVP_MD_CTX_md(ctx)));
}
/* Deep copy of EVP_MD hasher
* return WOLFSSL_SUCCESS on success */
static int wolfSSL_EVP_MD_Copy_Hasher(WOLFSSL_EVP_MD_CTX* des,
@ -13447,7 +13485,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
ctx->enc = enc ? 1 : 0;
if (key) {
ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv,
ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION);
if (ret != 0)
return ret;
}

View File

@ -22900,7 +22900,6 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
#ifndef WC_NO_RNG
static byte seed[] = { 0x00, 0x00, 0x00, 0x01 };
word32 len;
int i;
/* wc_GenerateSeed is a local symbol so we need to fake the entropy. */
while (info->seed.sz > 0) {

View File

@ -2497,7 +2497,8 @@ struct WOLFSSL_CTX {
int certChainCnt;
#endif
DerBuffer* privateKey;
byte privateKeyType;
byte privateKeyType:7;
byte privateKeyId:1;
int privateKeySz;
WOLFSSL_CERT_MANAGER* cm; /* our cert manager, ctx owns SSL will use */
#endif
@ -3078,7 +3079,8 @@ typedef struct Buffers {
#ifndef NO_CERTS
DerBuffer* certificate; /* WOLFSSL_CTX owns, unless we own */
DerBuffer* key; /* WOLFSSL_CTX owns, unless we own */
byte keyType; /* Type of key: RSA, ECC, Ed25519 */
byte keyType:7; /* Type of key: RSA, ECC, Ed25519 */
byte keyId:1; /* Key data is an id not data */
int keySz; /* Size of RSA key */
DerBuffer* certChain; /* WOLFSSL_CTX owns, unless we own */
/* chain after self, in DER, with leading size for each cert */

View File

@ -1733,6 +1733,8 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL*, void* key, unsigned int len,
const unsigned char*, long, int);
WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX*,
const unsigned char*, long, int);
WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX*,
const unsigned char*, long, long);
WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX*,
const unsigned char*, long, int);
WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX*,
@ -1745,6 +1747,8 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL*, void* key, unsigned int len,
int derSz);
WOLFSSL_API int wolfSSL_use_PrivateKey_buffer(WOLFSSL*, const unsigned char*,
long, int);
WOLFSSL_API int wolfSSL_use_PrivateKey_id(WOLFSSL*, const unsigned char*,
long, long);
WOLFSSL_API int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL*,
const unsigned char*, long, int);
WOLFSSL_API int wolfSSL_use_certificate_chain_buffer(WOLFSSL*,