Fixes for allowing server to have a public key set when using external key with PK callbacks.

This commit is contained in:
David Garske
2022-03-18 11:27:45 -07:00
parent c213c725d7
commit 59665a44b5
6 changed files with 128 additions and 62 deletions

View File

@@ -5775,18 +5775,24 @@ int InitSSL_Suites(WOLFSSL* ssl)
return NO_PRIVATE_KEY; return NO_PRIVATE_KEY;
} }
/* allow no private key if using PK callbacks and CB is set */ if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
/* allow no private key if using existing key */
#ifdef WOLF_PRIVATE_KEY_ID
if (ssl->devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) { || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
WOLFSSL_MSG("Using PK for server private key"); #endif
) {
WOLFSSL_MSG("Allowing no server private key (external)");
} }
else else
#endif #endif
if (!ssl->buffers.key || !ssl->buffers.key->buffer) { {
WOLFSSL_MSG("Server missing private key"); WOLFSSL_MSG("Server missing private key");
return NO_PRIVATE_KEY; return NO_PRIVATE_KEY;
} }
} }
}
#endif #endif
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
@@ -22380,20 +22386,25 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
int keySz; int keySz;
word32 idx; word32 idx;
/* make sure private key exists */
if (ssl->buffers.key == NULL || ssl->buffers.key->buffer == NULL) {
/* allow no private key if using external */
#ifdef WOLF_PRIVATE_KEY_ID
if (ssl->devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
/* allow no private key if using PK callbacks and CB is set */ || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
if (wolfSSL_IsPrivatePkSet(ssl)) { #endif
) {
*length = GetPrivateKeySigSize(ssl); *length = GetPrivateKeySigSize(ssl);
return 0; return 0;
} }
else else
#endif #endif
{
/* make sure private key exists */
if (ssl->buffers.key == NULL || ssl->buffers.key->buffer == NULL) {
WOLFSSL_MSG("Private key missing!"); WOLFSSL_MSG("Private key missing!");
ERROR_OUT(NO_PRIVATE_KEY, exit_dpk); ERROR_OUT(NO_PRIVATE_KEY, exit_dpk);
} }
}
#ifdef WOLF_PRIVATE_KEY_ID #ifdef WOLF_PRIVATE_KEY_ID
if (ssl->buffers.keyDevId != INVALID_DEVID && (ssl->buffers.keyId || if (ssl->buffers.keyDevId != INVALID_DEVID && (ssl->buffers.keyId ||
@@ -22479,8 +22490,12 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &idx, ret = wc_RsaPrivateKeyDecode(ssl->buffers.key->buffer, &idx,
(RsaKey*)ssl->hsKey, ssl->buffers.key->length); (RsaKey*)ssl->hsKey, ssl->buffers.key->length);
#ifdef WOLF_PRIVATE_KEY_ID #ifdef WOLF_PRIVATE_KEY_ID
/* if using crypto or PK callbacks allow using a public key */ /* if using external key then allow using a public key */
if (ret != 0 && ssl->devId != INVALID_DEVID) { if (ret != 0 && (ssl->devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
#endif
)) {
WOLFSSL_MSG("Trying RSA public key with crypto callbacks"); WOLFSSL_MSG("Trying RSA public key with crypto callbacks");
idx = 0; idx = 0;
ret = wc_RsaPublicKeyDecode(ssl->buffers.key->buffer, &idx, ret = wc_RsaPublicKeyDecode(ssl->buffers.key->buffer, &idx,
@@ -22534,8 +22549,12 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
(ecc_key*)ssl->hsKey, (ecc_key*)ssl->hsKey,
ssl->buffers.key->length); ssl->buffers.key->length);
#ifdef WOLF_PRIVATE_KEY_ID #ifdef WOLF_PRIVATE_KEY_ID
/* if using crypto or PK callbacks allow using a public key */ /* if using external key then allow using a public key */
if (ret != 0 && ssl->devId != INVALID_DEVID) { if (ret != 0 && (ssl->devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
#endif
)) {
WOLFSSL_MSG("Trying ECC public key with crypto callbacks"); WOLFSSL_MSG("Trying ECC public key with crypto callbacks");
idx = 0; idx = 0;
ret = wc_EccPublicKeyDecode(ssl->buffers.key->buffer, &idx, ret = wc_EccPublicKeyDecode(ssl->buffers.key->buffer, &idx,
@@ -22587,8 +22606,12 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
(ed25519_key*)ssl->hsKey, (ed25519_key*)ssl->hsKey,
ssl->buffers.key->length); ssl->buffers.key->length);
#ifdef WOLF_PRIVATE_KEY_ID #ifdef WOLF_PRIVATE_KEY_ID
/* if using crypto or PK callbacks allow using a public key */ /* if using external key then allow using a public key */
if (ret != 0 && ssl->devId != INVALID_DEVID) { if (ret != 0 && (ssl->devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
#endif
)) {
WOLFSSL_MSG("Trying ED25519 public key with crypto callbacks"); WOLFSSL_MSG("Trying ED25519 public key with crypto callbacks");
idx = 0; idx = 0;
ret = wc_Ed25519PublicKeyDecode(ssl->buffers.key->buffer, &idx, ret = wc_Ed25519PublicKeyDecode(ssl->buffers.key->buffer, &idx,
@@ -22640,6 +22663,20 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length)
ret = wc_Ed448PrivateKeyDecode(ssl->buffers.key->buffer, &idx, ret = wc_Ed448PrivateKeyDecode(ssl->buffers.key->buffer, &idx,
(ed448_key*)ssl->hsKey, (ed448_key*)ssl->hsKey,
ssl->buffers.key->length); ssl->buffers.key->length);
#ifdef WOLF_PRIVATE_KEY_ID
/* if using external key then allow using a public key */
if (ret != 0 && (ssl->devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
#endif
)) {
WOLFSSL_MSG("Trying ED25519 public key with crypto callbacks");
idx = 0;
ret = wc_Ed448PublicKeyDecode(ssl->buffers.key->buffer, &idx,
(ed448_key*)ssl->hsKey,
ssl->buffers.key->length);
}
#endif
if (ret == 0) { if (ret == 0) {
WOLFSSL_MSG("Using ED448 private key"); WOLFSSL_MSG("Using ED448 private key");
@@ -26876,7 +26913,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
#ifndef NO_CERTS #ifndef NO_CERTS
#ifdef HAVE_PK_CALLBACKS #ifdef WOLF_PRIVATE_KEY_ID
int GetPrivateKeySigSize(WOLFSSL* ssl) int GetPrivateKeySigSize(WOLFSSL* ssl)
{ {
int sigSz = 0; int sigSz = 0;

View File

@@ -5697,7 +5697,11 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
*idx = 0; *idx = 0;
ret = wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length); ret = wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID #ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && devId != INVALID_DEVID) { if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */ /* if using crypto or PK callbacks, try public key decode */
*idx = 0; *idx = 0;
ret = wc_RsaPublicKeyDecode(der->buffer, idx, key, der->length); ret = wc_RsaPublicKeyDecode(der->buffer, idx, key, der->length);
@@ -5769,7 +5773,11 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
*idx = 0; *idx = 0;
ret = wc_EccPrivateKeyDecode(der->buffer, idx, key, der->length); ret = wc_EccPrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID #ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && devId != INVALID_DEVID) { if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */ /* if using crypto or PK callbacks, try public key decode */
*idx = 0; *idx = 0;
ret = wc_EccPublicKeyDecode(der->buffer, idx, key, der->length); ret = wc_EccPublicKeyDecode(der->buffer, idx, key, der->length);
@@ -5836,7 +5844,11 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
*idx = 0; *idx = 0;
ret = wc_Ed25519PrivateKeyDecode(der->buffer, idx, key, der->length); ret = wc_Ed25519PrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID #ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && devId != INVALID_DEVID) { if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */ /* if using crypto or PK callbacks, try public key decode */
*idx = 0; *idx = 0;
ret = wc_Ed25519PublicKeyDecode(der->buffer, idx, key, der->length); ret = wc_Ed25519PublicKeyDecode(der->buffer, idx, key, der->length);
@@ -5905,6 +5917,17 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
if (ret == 0) { if (ret == 0) {
*idx = 0; *idx = 0;
ret = wc_Ed448PrivateKeyDecode(der->buffer, idx, key, der->length); ret = wc_Ed448PrivateKeyDecode(der->buffer, idx, key, der->length);
#ifdef WOLF_PRIVATE_KEY_ID
if (ret != 0 && (devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS
|| wolfSSL_CTX_IsPrivatePkSet(ctx)
#endif
)) {
/* if using crypto or PK callbacks, try public key decode */
*idx = 0;
ret = wc_Ed448PublicKeyDecode(der->buffer, idx, key, der->length);
}
#endif
if (ret == 0) { if (ret == 0) {
/* check for minimum key size and then free */ /* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minEccKeySz : int minKeySz = ssl ? ssl->options.minEccKeySz :
@@ -14823,7 +14846,6 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
#ifndef NO_CERTS #ifndef NO_CERTS
/* in case used set_accept_state after init */ /* in case used set_accept_state after init */
/* allow no private key if using PK callbacks and CB is set */
if (!havePSK && !haveAnon && !haveMcast) { if (!havePSK && !haveAnon && !haveMcast) {
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
if (ssl->ctx->certSetupCb != NULL) { if (ssl->ctx->certSetupCb != NULL) {
@@ -14842,20 +14864,26 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
} }
if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
/* allow no private key if using existing key */
#ifdef WOLF_PRIVATE_KEY_ID
if (ssl->devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) { || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
WOLFSSL_MSG("Using PK for server private key"); #endif
) {
WOLFSSL_MSG("Allowing no server private key (external)");
} }
else else
#endif #endif
if (!ssl->buffers.key || !ssl->buffers.key->buffer) { {
WOLFSSL_MSG("accept error: server key required"); WOLFSSL_MSG("accept error: server key required");
ssl->error = NO_PRIVATE_KEY; WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
WOLFSSL_ERROR(ssl->error);
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
} }
} }
} }
}
#endif #endif
#ifdef WOLFSSL_DTLS #ifdef WOLFSSL_DTLS

View File

@@ -9520,7 +9520,6 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */ #endif /* WOLFSSL_WOLFSENTRY_HOOKS */
#ifndef NO_CERTS #ifndef NO_CERTS
/* allow no private key if using PK callbacks and CB is set */
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
if (!havePSK) if (!havePSK)
#endif #endif
@@ -9542,19 +9541,26 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
} }
if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
/* allow no private key if using existing key */
#ifdef WOLF_PRIVATE_KEY_ID
if (ssl->devId != INVALID_DEVID
#ifdef HAVE_PK_CALLBACKS #ifdef HAVE_PK_CALLBACKS
if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) { || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
WOLFSSL_MSG("Using PK for server private key"); #endif
) {
WOLFSSL_MSG("Allowing no server private key (external)");
} }
else else
#endif #endif
if (!ssl->buffers.key || !ssl->buffers.key->buffer) { {
WOLFSSL_MSG("accept error: server key required"); WOLFSSL_MSG("accept error: server key required");
WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY); WOLFSSL_ERROR(ssl->error = NO_PRIVATE_KEY);
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
} }
} }
} }
}
#endif /* NO_CERTS */ #endif /* NO_CERTS */
if (ssl->buffers.outputBuffer.length > 0 if (ssl->buffers.outputBuffer.length > 0

View File

@@ -19802,7 +19802,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
} }
#endif #endif
else { else {
#if defined(WOLF_CRYPTO_CB) || defined(HAVE_PK_CALLBACKS) #ifdef WOLF_PRIVATE_KEY_ID
/* allow loading a public key for use with crypto or PK callbacks */ /* allow loading a public key for use with crypto or PK callbacks */
type = PUBLICKEY_TYPE; type = PUBLICKEY_TYPE;
header = BEGIN_PUB_KEY; header = BEGIN_PUB_KEY;
@@ -19926,7 +19926,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
*keyFormat = DSAk; *keyFormat = DSAk;
#endif #endif
} }
#if defined(WOLF_CRYPTO_CB) || defined(HAVE_PK_CALLBACKS) #ifdef WOLF_PRIVATE_KEY_ID
else if (type == PUBLICKEY_TYPE) { else if (type == PUBLICKEY_TYPE) {
#ifndef NO_RSA #ifndef NO_RSA
if (header == BEGIN_RSA_PUB) if (header == BEGIN_RSA_PUB)

View File

@@ -1735,7 +1735,7 @@ WOLFSSL_LOCAL int CreateDevPrivateKey(void** pkey, byte* data, word32 length,
void* heap, int devId); void* heap, int devId);
#endif #endif
WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word16* length); WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word16* length);
#ifdef HAVE_PK_CALLBACKS #ifdef WOLF_PRIVATE_KEY_ID
WOLFSSL_LOCAL int GetPrivateKeySigSize(WOLFSSL* ssl); WOLFSSL_LOCAL int GetPrivateKeySigSize(WOLFSSL* ssl);
#ifndef NO_ASN #ifndef NO_ASN
WOLFSSL_LOCAL int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx); WOLFSSL_LOCAL int InitSigPkCb(WOLFSSL* ssl, SignatureCtx* sigCtx);

View File

@@ -3729,14 +3729,9 @@ typedef struct PkCbInfo {
#ifdef TEST_PK_PRIVKEY #ifdef TEST_PK_PRIVKEY
union { union {
#ifdef HAVE_ECC #ifdef HAVE_ECC
/* only ECC PK callback with TLS v1.2 needs this */
ecc_key ecc; ecc_key ecc;
#endif #endif
#ifdef HAVE_CURVE25519
curve25519_key curve;
#endif
#ifdef HAVE_CURVE448
curve448_key curve;
#endif
} keyGen; } keyGen;
int hasKeyGen; int hasKeyGen;
#endif #endif