forked from wolfSSL/wolfssl
Merge pull request #390 from JacobBarthelmeh/ECC-min
minimum ECC key size check at TLS/SSL level
This commit is contained in:
@@ -278,6 +278,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
|||||||
int throughput = 0;
|
int throughput = 0;
|
||||||
int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS;
|
int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS;
|
||||||
int minRsaKeyBits = DEFAULT_MIN_RSAKEY_BITS;
|
int minRsaKeyBits = DEFAULT_MIN_RSAKEY_BITS;
|
||||||
|
short minEccKeyBits = DEFAULT_MIN_ECCKEY_BITS;
|
||||||
int doListen = 1;
|
int doListen = 1;
|
||||||
int crlFlags = 0;
|
int crlFlags = 0;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -329,6 +330,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
|||||||
(void)doCliCertCheck;
|
(void)doCliCertCheck;
|
||||||
(void)minDhKeyBits;
|
(void)minDhKeyBits;
|
||||||
(void)minRsaKeyBits;
|
(void)minRsaKeyBits;
|
||||||
|
(void)minEccKeyBits;
|
||||||
(void)alpnList;
|
(void)alpnList;
|
||||||
(void)alpn_opt;
|
(void)alpn_opt;
|
||||||
(void)crlFlags;
|
(void)crlFlags;
|
||||||
@@ -649,6 +651,11 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
|||||||
err_sys("Error setting minimum RSA key size");
|
err_sys("Error setting minimum RSA key size");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
if (wolfSSL_CTX_SetMinEccKey_Sz(ctx, minEccKeyBits) != SSL_SUCCESS){
|
||||||
|
err_sys("Error setting minimum ECC key size");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_NTRU
|
#ifdef HAVE_NTRU
|
||||||
if (useNtruKey) {
|
if (useNtruKey) {
|
||||||
|
@@ -554,8 +554,8 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method)
|
|||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
ctx->minRsaKeySz = MIN_RSAKEY_SZ;
|
ctx->minRsaKeySz = MIN_RSAKEY_SZ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
|
ctx->minEccKeySz = MIN_ECCKEY_SZ;
|
||||||
ctx->eccTempKeySz = ECDHE_SIZE;
|
ctx->eccTempKeySz = ECDHE_SIZE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2240,6 +2240,9 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
|
|||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
ssl->options.minRsaKeySz = ctx->minRsaKeySz;
|
ssl->options.minRsaKeySz = ctx->minRsaKeySz;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
ssl->options.minEccKeySz = ctx->minEccKeySz;
|
||||||
|
#endif
|
||||||
|
|
||||||
ssl->options.sessionCacheOff = ctx->sessionCacheOff;
|
ssl->options.sessionCacheOff = ctx->sessionCacheOff;
|
||||||
ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
|
ssl->options.sessionCacheFlushOff = ctx->sessionCacheFlushOff;
|
||||||
@@ -5148,6 +5151,15 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* !NO_RSA */
|
#endif /* !NO_RSA */
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
case ECDSAk:
|
||||||
|
if (ssl->options.minEccKeySz < 0 ||
|
||||||
|
dCert->pubKeySize < (word16)ssl->options.minEccKeySz) {
|
||||||
|
WOLFSSL_MSG("ECC key size in cert chain error");
|
||||||
|
ret = ECC_KEY_SIZE_E;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WOLFSSL_MSG("Key size not checked");
|
WOLFSSL_MSG("Key size not checked");
|
||||||
@@ -5534,6 +5546,16 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
#endif /* HAVE_ECC */
|
#endif /* HAVE_ECC */
|
||||||
#endif /*HAVE_PK_CALLBACKS */
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check size of peer ECC key */
|
||||||
|
if (ret == 0 && ssl->peerEccDsaKeyPresent &&
|
||||||
|
!ssl->options.verifyNone &&
|
||||||
|
wc_ecc_size(ssl->peerEccDsaKey)
|
||||||
|
< ssl->options.minEccKeySz) {
|
||||||
|
ret = ECC_KEY_SIZE_E;
|
||||||
|
WOLFSSL_MSG("Peer ECC key is too small");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_ECC */
|
#endif /* HAVE_ECC */
|
||||||
@@ -10168,6 +10190,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
|
|||||||
case RSA_KEY_SIZE_E:
|
case RSA_KEY_SIZE_E:
|
||||||
return "RSA key too small";
|
return "RSA key too small";
|
||||||
|
|
||||||
|
case ECC_KEY_SIZE_E:
|
||||||
|
return "ECC key too small";
|
||||||
|
|
||||||
default :
|
default :
|
||||||
return "unknown error number";
|
return "unknown error number";
|
||||||
}
|
}
|
||||||
@@ -13982,6 +14007,12 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer)
|
|||||||
WOLFSSL_MSG("Using ECC client cert");
|
WOLFSSL_MSG("Using ECC client cert");
|
||||||
usingEcc = 1;
|
usingEcc = 1;
|
||||||
sigOutSz = MAX_ENCODED_SIG_SZ;
|
sigOutSz = MAX_ENCODED_SIG_SZ;
|
||||||
|
|
||||||
|
/* check minimum size of ECC key */
|
||||||
|
if (wc_ecc_size(&eccKey) < ssl->options.minEccKeySz) {
|
||||||
|
WOLFSSL_MSG("ECC key size too small");
|
||||||
|
return ECC_KEY_SIZE_E;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WOLFSSL_MSG("Bad client cert type");
|
WOLFSSL_MSG("Bad client cert type");
|
||||||
@@ -14937,6 +14968,14 @@ int DoSessionTicket(WOLFSSL* ssl,
|
|||||||
goto exit_sske;
|
goto exit_sske;
|
||||||
}
|
}
|
||||||
sigSz = wc_ecc_sig_size((ecc_key*)ssl->sigKey); /* worst case estimate */
|
sigSz = wc_ecc_sig_size((ecc_key*)ssl->sigKey); /* worst case estimate */
|
||||||
|
|
||||||
|
/* check the minimum ECC key size */
|
||||||
|
if (wc_ecc_size((ecc_key*)ssl->sigKey) <
|
||||||
|
ssl->options.minEccKeySz) {
|
||||||
|
WOLFSSL_MSG("ECC key size too small");
|
||||||
|
ret = ECC_KEY_SIZE_E;
|
||||||
|
goto exit_sske;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -17219,6 +17258,11 @@ int DoSessionTicket(WOLFSSL* ssl,
|
|||||||
ssl->buffers.key->length);
|
ssl->buffers.key->length);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
private_key = (ecc_key*)ssl->sigKey;
|
private_key = (ecc_key*)ssl->sigKey;
|
||||||
|
if (wc_ecc_size(private_key) <
|
||||||
|
ssl->options.minEccKeySz) {
|
||||||
|
WOLFSSL_MSG("ECC key too small");
|
||||||
|
ERROR_OUT(ECC_KEY_SIZE_E, exit_dcke);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ssl->eccTempKeyPresent == 0) {
|
else if (ssl->eccTempKeyPresent == 0) {
|
||||||
|
72
src/ssl.c
72
src/ssl.c
@@ -483,6 +483,31 @@ int wolfSSL_GetObjectSize(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
|
||||||
|
{
|
||||||
|
if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
|
||||||
|
WOLFSSL_MSG("Key size must be divisable by 8 or ctx was null");
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->minEccKeySz = keySz / 8;
|
||||||
|
ctx->cm->minEccKeySz = keySz / 8;
|
||||||
|
return SSL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
|
||||||
|
{
|
||||||
|
if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
|
||||||
|
WOLFSSL_MSG("Key size must be divisable by 8 or ssl was null");
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl->options.minEccKeySz = keySz / 8;
|
||||||
|
return SSL_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* !NO_RSA */
|
||||||
|
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, word16 keySz)
|
int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, word16 keySz)
|
||||||
@@ -1762,6 +1787,9 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
|
|||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
cm->minRsaKeySz = MIN_RSAKEY_SZ;
|
cm->minRsaKeySz = MIN_RSAKEY_SZ;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
cm->minEccKeySz = MIN_ECCKEY_SZ;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return cm;
|
return cm;
|
||||||
@@ -2603,6 +2631,15 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* !NO_RSA */
|
#endif /* !NO_RSA */
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
case ECDSAk:
|
||||||
|
if (cm->minEccKeySz < 0 ||
|
||||||
|
cert->pubKeySize < (word16)cm->minEccKeySz) {
|
||||||
|
ret = ECC_KEY_SIZE_E;
|
||||||
|
WOLFSSL_MSG(" CA ECC key size error");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WOLFSSL_MSG(" No key size check done on CA");
|
WOLFSSL_MSG(" No key size check done on CA");
|
||||||
@@ -3524,6 +3561,23 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||||||
wc_ecc_free(&key);
|
wc_ecc_free(&key);
|
||||||
return SSL_BAD_FILE;
|
return SSL_BAD_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check for minimum ECC key size and then free */
|
||||||
|
if (ssl) {
|
||||||
|
if (wc_ecc_size(&key) < ssl->options.minEccKeySz) {
|
||||||
|
wc_ecc_free(&key);
|
||||||
|
WOLFSSL_MSG("ECC private key too small");
|
||||||
|
return ECC_KEY_SIZE_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ctx) {
|
||||||
|
if (wc_ecc_size(&key) < ctx->minEccKeySz) {
|
||||||
|
wc_ecc_free(&key);
|
||||||
|
WOLFSSL_MSG("ECC private key too small");
|
||||||
|
return ECC_KEY_SIZE_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wc_ecc_free(&key);
|
wc_ecc_free(&key);
|
||||||
eccKey = 1;
|
eccKey = 1;
|
||||||
if (ctx)
|
if (ctx)
|
||||||
@@ -3614,6 +3668,24 @@ static int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* !NO_RSA */
|
#endif /* !NO_RSA */
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
case ECDSAk:
|
||||||
|
if (ssl && !ssl->options.verifyNone) {
|
||||||
|
if (ssl->options.minEccKeySz < 0 ||
|
||||||
|
cert->pubKeySize < (word16)ssl->options.minEccKeySz) {
|
||||||
|
ret = ECC_KEY_SIZE_E;
|
||||||
|
WOLFSSL_MSG("Certificate ECC key size error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ctx && !ctx->verifyNone) {
|
||||||
|
if (ctx->minEccKeySz < 0 ||
|
||||||
|
cert->pubKeySize < (word16)ctx->minEccKeySz) {
|
||||||
|
ret = ECC_KEY_SIZE_E;
|
||||||
|
WOLFSSL_MSG("Certificate ECC key size error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WOLFSSL_MSG("No key size check done on certificate");
|
WOLFSSL_MSG("No key size check done on certificate");
|
||||||
|
@@ -145,6 +145,7 @@ enum wolfSSL_ErrorCodes {
|
|||||||
ASYNC_NOT_PENDING = -408, /* Async operation not pending */
|
ASYNC_NOT_PENDING = -408, /* Async operation not pending */
|
||||||
|
|
||||||
RSA_KEY_SIZE_E = -409, /* RSA key too small */
|
RSA_KEY_SIZE_E = -409, /* RSA key too small */
|
||||||
|
ECC_KEY_SIZE_E = -410, /* ECC key too small */
|
||||||
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
|
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
|
||||||
|
|
||||||
/* begin negotiation parameter errors */
|
/* begin negotiation parameter errors */
|
||||||
|
@@ -1063,6 +1063,24 @@ enum Misc {
|
|||||||
/* 150 suites for now! */
|
/* 150 suites for now! */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* set minimum ECC key size allowed */
|
||||||
|
#ifndef WOLFSSL_MIN_ECC_BITS
|
||||||
|
#ifdef WOLFSSL_MAX_STRENGTH
|
||||||
|
#define WOLFSSL_MIN_ECC_BITS 256
|
||||||
|
#else
|
||||||
|
#define WOLFSSL_MIN_ECC_BITS 224
|
||||||
|
#endif
|
||||||
|
#endif /* WOLFSSL_MIN_ECC_BITS */
|
||||||
|
#if (WOLFSSL_MIN_ECC_BITS % 8)
|
||||||
|
/* Some ECC keys are not divisable by 8 such as prime239v1 or sect131r1.
|
||||||
|
In these cases round down to the nearest value divisable by 8. The
|
||||||
|
restriction of being divisable by 8 is in place to match wc_ecc_size
|
||||||
|
function from wolfSSL.
|
||||||
|
*/
|
||||||
|
#error ECC minimum bit size must be a multiple of 8
|
||||||
|
#endif
|
||||||
|
#define MIN_ECCKEY_SZ (WOLFSSL_MIN_ECC_BITS / 8)
|
||||||
|
|
||||||
/* set minimum RSA key size allowed */
|
/* set minimum RSA key size allowed */
|
||||||
#ifndef WOLFSSL_MIN_RSA_BITS
|
#ifndef WOLFSSL_MIN_RSA_BITS
|
||||||
#ifdef WOLFSSL_MAX_STRENGTH
|
#ifdef WOLFSSL_MAX_STRENGTH
|
||||||
@@ -1500,6 +1518,9 @@ struct WOLFSSL_CERT_MANAGER {
|
|||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
word16 minRsaKeySz; /* minimum allowed RSA key size */
|
word16 minRsaKeySz; /* minimum allowed RSA key size */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
short minEccKeySz; /* minimum allowed ECC key size */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER*, const char*);
|
WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER*, const char*);
|
||||||
@@ -1898,6 +1919,9 @@ struct WOLFSSL_CTX {
|
|||||||
#endif
|
#endif
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
word16 minRsaKeySz; /* minimum RSA key size */
|
word16 minRsaKeySz; /* minimum RSA key size */
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
short minEccKeySz; /* minimum ECC key size */
|
||||||
#endif
|
#endif
|
||||||
CallbackIORecv CBIORecv;
|
CallbackIORecv CBIORecv;
|
||||||
CallbackIOSend CBIOSend;
|
CallbackIOSend CBIOSend;
|
||||||
@@ -2366,6 +2390,9 @@ typedef struct Options {
|
|||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
word16 minRsaKeySz; /* minimum RSA key size */
|
word16 minRsaKeySz; /* minimum RSA key size */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
short minEccKeySz; /* minimum ECC key size */
|
||||||
|
#endif
|
||||||
|
|
||||||
} Options;
|
} Options;
|
||||||
|
|
||||||
|
@@ -943,6 +943,11 @@ WOLFSSL_API int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX*, unsigned short);
|
|||||||
WOLFSSL_API int wolfSSL_SetMinRsaKey_Sz(WOLFSSL*, unsigned short);
|
WOLFSSL_API int wolfSSL_SetMinRsaKey_Sz(WOLFSSL*, unsigned short);
|
||||||
#endif /* NO_RSA */
|
#endif /* NO_RSA */
|
||||||
|
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
WOLFSSL_API int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX*, short);
|
||||||
|
WOLFSSL_API int wolfSSL_SetMinEccKey_Sz(WOLFSSL*, short);
|
||||||
|
#endif /* NO_RSA */
|
||||||
|
|
||||||
WOLFSSL_API int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL*, unsigned short);
|
WOLFSSL_API int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL*, unsigned short);
|
||||||
WOLFSSL_API int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX*, unsigned short);
|
WOLFSSL_API int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX*, unsigned short);
|
||||||
|
|
||||||
|
@@ -236,6 +236,11 @@
|
|||||||
#else
|
#else
|
||||||
#define DEFAULT_MIN_RSAKEY_BITS 1024
|
#define DEFAULT_MIN_RSAKEY_BITS 1024
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH)
|
||||||
|
#define DEFAULT_MIN_ECCKEY_BITS 256
|
||||||
|
#else
|
||||||
|
#define DEFAULT_MIN_ECCKEY_BITS 224
|
||||||
|
#endif
|
||||||
|
|
||||||
/* all certs relative to wolfSSL home directory now */
|
/* all certs relative to wolfSSL home directory now */
|
||||||
#if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL)
|
#if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL)
|
||||||
|
Reference in New Issue
Block a user