diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 30e285069..d4b6a0723 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -6202,6 +6202,10 @@ WOLFSSL_API int wolfSSL_SetTmpDH_buffer(WOLFSSL*, const unsigned char* b, long \return SIDE_ERROR if the side member of the Options structure found in the WOLFSSL struct is not the server side. \return SSL_BAD_FILETYPE returns if the certificate fails a set of checks. + \return DH_KEY_SIZE_E returned if the DH parameter's key size is less than + the value of the minDhKeySz member in the WOLFSSL struct. + \return DH_KEY_SIZE_E returned if the DH parameter's key size is greater + than the value of the maxDhKeySz member in the WOLFSSL struct. \return BAD_FUNC_ARG returns if an argument value is NULL that is not permitted such as, the WOLFSSL structure. @@ -6236,8 +6240,10 @@ WOLFSSL_API int wolfSSL_SetTmpDH_file(WOLFSSL*, const char* f, int format); \return SSL_SUCCESS returned if the function and all subroutines return without error. \return BAD_FUNC_ARG returned if the CTX, p or g parameters are NULL. - \return DH_KEY_SIZE_E returned if the minDhKeySz member of the - WOLFSSL_CTX struct is not the correct size. + \return DH_KEY_SIZE_E returned if the DH parameter's key size is less than + the value of the minDhKeySz member of the WOLFSSL_CTX struct. + \return DH_KEY_SIZE_E returned if the DH parameter's key size is greater + than the value of the maxDhKeySz member of the WOLFSSL_CTX struct. \return MEMORY_E returned if the allocation of memory failed in this function or a subroutine. @@ -6335,8 +6341,10 @@ WOLFSSL_API int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX*, const unsigned char* if the a set of checks on the file fail from wolfSSL_SetTmpDH_file_wrapper. \return SSL_BAD_FILETYPE returned if teh format is not PEM or ASN.1 from wolfSSL_SetTmpDH_buffer_wrapper(). - \return DH_KEY_SIZE_E returned from wolfSSL_SetTmpDH() if the ctx - minDhKeySz member exceeds maximum size allowed for DH. + \return DH_KEY_SIZE_E returned if the DH parameter's key size is less than + the value of the minDhKeySz member of the WOLFSSL_CTX struct. + \return DH_KEY_SIZE_E returned if the DH parameter's key size is greater + than the value of the maxDhKeySz member of the WOLFSSL_CTX struct. \return SIDE_ERROR returned in wolfSSL_SetTmpDH() if the side is not the server end. \return SSL_NO_PEM_HEADER returned from PemToDer if there is no PEM header. @@ -6396,7 +6404,8 @@ WOLFSSL_API int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX*, const char* f, \endcode \sa wolfSSL_SetMinDhKey_Sz - \sa CTX_SetMinDhKey_Sz + \sa wolfSSL_CTX_SetMaxDhKey_Sz + \sa wolfSSL_SetMaxDhKey_Sz \sa wolfSSL_GetDhKey_Sz \sa wolfSSL_CTX_SetTMpDH_file */ @@ -6425,10 +6434,68 @@ WOLFSSL_API int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX*, unsigned short); } \endcode + \sa wolfSSL_CTX_SetMinDhKey_Sz \sa wolfSSL_GetDhKey_Sz */ WOLFSSL_API int wolfSSL_SetMinDhKey_Sz(WOLFSSL*, unsigned short); +/*! + \ingroup CertsKeys + + \brief This function sets the maximum size of the Diffie Hellman key size + by accessing the maxDhKeySz member in the WOLFSSL_CTX structure. + + \return SSL_SUCCESS returned if the function completes successfully. + \return BAD_FUNC_ARG returned if the WOLFSSL_CTX struct is NULL or if + the keySz is greater than 16,000 or not divisible by 8. + + \param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). + \param keySz a word16 type used to set the maximum DH key size. The + WOLFSSL_CTX struct holds this information in the maxDhKeySz member. + + _Example_ + \code + public static int CTX_SetMaxDhKey_Sz(IntPtr ctx, short maxDhKey){ + … + return wolfSSL_CTX_SetMaxDhKey_Sz(local_ctx, maxDhKey); + \endcode + + \sa wolfSSL_SetMinDhKey_Sz + \sa wolfSSL_CTX_SetMinDhKey_Sz + \sa wolfSSL_SetMaxDhKey_Sz + \sa wolfSSL_GetDhKey_Sz + \sa wolfSSL_CTX_SetTMpDH_file +*/ +WOLFSSL_API int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX*, unsigned short); + +/*! + \ingroup CertsKeys + + \brief Sets the maximum size for a Diffie-Hellman key in the WOLFSSL + structure in bytes. + + \return SSL_SUCCESS the maximum size was successfully set. + \return BAD_FUNC_ARG the WOLFSSL structure was NULL or the keySz parameter + was greater than the allowable size or not divisible by 8. + + \param ssl a pointer to a WOLFSSL structure, created using wolfSSL_new(). + \param keySz a word16 type representing the bit size of the maximum DH key. + + _Example_ + \code + WOLFSSL* ssl = wolfSSL_new(ctx); + word16 keySz; + ... + if(wolfSSL_SetMaxDhKey(ssl, keySz) != SSL_SUCCESS){ + // Failed to set. + } + \endcode + + \sa wolfSSL_CTX_SetMaxDhKey_Sz + \sa wolfSSL_GetDhKey_Sz +*/ +WOLFSSL_API int wolfSSL_SetMaxDhKey_Sz(WOLFSSL*, unsigned short); + /*! \ingroup CertsKeys diff --git a/src/internal.c b/src/internal.c index 77a09ba6f..e0e505f4c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -754,10 +754,12 @@ static int dtls_export_new(WOLFSSL* ssl, byte* exp, word32 len, byte ver) exp[idx++] = options->downgrade; #ifndef NO_DH c16toa(options->minDhKeySz, exp + idx); idx += OPAQUE16_LEN; + c16toa(options->maxDhKeySz, exp + idx); idx += OPAQUE16_LEN; c16toa(options->dhKeySz, exp + idx); idx += OPAQUE16_LEN; #else c16toa(zero, exp + idx); idx += OPAQUE16_LEN; c16toa(zero, exp + idx); idx += OPAQUE16_LEN; + c16toa(zero, exp + idx); idx += OPAQUE16_LEN; #endif #ifndef NO_RSA c16toa((word16)(options->minRsaKeySz), exp + idx); idx += OPAQUE16_LEN; @@ -917,10 +919,12 @@ static int dtls_export_load(WOLFSSL* ssl, byte* exp, word32 len, byte ver) options->downgrade = exp[idx++]; #ifndef NO_DH ato16(exp + idx, &(options->minDhKeySz)); idx += OPAQUE16_LEN; + ato16(exp + idx, &(options->maxDhKeySz)); idx += OPAQUE16_LEN; ato16(exp + idx, &(options->dhKeySz)); idx += OPAQUE16_LEN; #else idx += OPAQUE16_LEN; idx += OPAQUE16_LEN; + idx += OPAQUE16_LEN; #endif #ifndef NO_RSA ato16(exp + idx, (word16*)&(options->minRsaKeySz)); idx += OPAQUE16_LEN; @@ -1367,6 +1371,7 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #ifndef NO_DH ctx->minDhKeySz = MIN_DHKEY_SZ; + ctx->maxDhKeySz = MAX_DHKEY_SZ; #endif #ifndef NO_RSA ctx->minRsaKeySz = MIN_RSAKEY_SZ; @@ -4163,6 +4168,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #endif #ifndef NO_DH ssl->options.minDhKeySz = ctx->minDhKeySz; + ssl->options.maxDhKeySz = ctx->maxDhKeySz; #endif #ifndef NO_RSA ssl->options.minRsaKeySz = ctx->minRsaKeySz; @@ -17602,6 +17608,11 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, SendAlert(ssl, alert_fatal, handshake_failure); ERROR_OUT(DH_KEY_SIZE_E, exit_dske); } + if (length > ssl->options.maxDhKeySz) { + WOLFSSL_MSG("Server using a DH key that is too big"); + SendAlert(ssl, alert_fatal, handshake_failure); + ERROR_OUT(DH_KEY_SIZE_E, exit_dske); + } ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); @@ -17795,6 +17806,11 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, SendAlert(ssl, alert_fatal, handshake_failure); ERROR_OUT(DH_KEY_SIZE_E, exit_dske); } + if (length > ssl->options.maxDhKeySz) { + WOLFSSL_MSG("Server using a DH key that is too big"); + SendAlert(ssl, alert_fatal, handshake_failure); + ERROR_OUT(DH_KEY_SIZE_E, exit_dske); + } ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(length, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); diff --git a/src/ssl.c b/src/ssl.c index bb5a99ea6..31c2a982d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1461,6 +1461,8 @@ int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz, if (pSz < ssl->options.minDhKeySz) return DH_KEY_SIZE_E; + if (pSz > ssl->options.maxDhKeySz) + return DH_KEY_SIZE_E; if (ssl->options.side != WOLFSSL_SERVER_END) return SIDE_ERROR; @@ -1522,6 +1524,8 @@ int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz, if (pSz < ctx->minDhKeySz) return DH_KEY_SIZE_E; + if (pSz > ctx->maxDhKeySz) + return DH_KEY_SIZE_E; XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY); @@ -1569,6 +1573,26 @@ int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz) } +int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz) +{ + if (ctx == NULL || keySz > 16000 || keySz % 8 != 0) + return BAD_FUNC_ARG; + + ctx->maxDhKeySz = keySz / 8; + return WOLFSSL_SUCCESS; +} + + +int wolfSSL_SetMaxDhKey_Sz(WOLFSSL* ssl, word16 keySz) +{ + if (ssl == NULL || keySz > 16000 || keySz % 8 != 0) + return BAD_FUNC_ARG; + + ssl->options.maxDhKeySz = keySz / 8; + return WOLFSSL_SUCCESS; +} + + int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl) { if (ssl == NULL) diff --git a/tests/api.c b/tests/api.c index 5cb46f15e..7909fcbd9 100644 --- a/tests/api.c +++ b/tests/api.c @@ -772,6 +772,37 @@ static void test_wolfSSL_CTX_SetTmpDH_buffer(void) #endif } +static void test_wolfSSL_CTX_SetMinMaxDhKey_Sz(void) +{ +#if !defined(NO_CERTS) && !defined(NO_DH) && !defined(NO_WOLFSSL_CLIENT) + WOLFSSL_CTX *ctx; + + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMinDhKey_Sz(ctx, 3072)); + + AssertIntEQ(DH_KEY_SIZE_E, wolfSSL_CTX_SetTmpDH_buffer(ctx, dh_key_der_2048, + sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMinDhKey_Sz(ctx, 2048)); + + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx, dh_key_der_2048, + sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMaxDhKey_Sz(ctx, 1024)); + + AssertIntEQ(DH_KEY_SIZE_E, wolfSSL_CTX_SetTmpDH_buffer(ctx, dh_key_der_2048, + sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMaxDhKey_Sz(ctx, 2048)); + + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpDH_buffer(ctx, dh_key_der_2048, + sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + + wolfSSL_CTX_free(ctx); +#endif +} + /*----------------------------------------------------------------------------* | SSL *----------------------------------------------------------------------------*/ @@ -907,6 +938,56 @@ static void test_wolfSSL_SetTmpDH_buffer(void) #endif } +static void test_wolfSSL_SetMinMaxDhKey_Sz(void) +{ +#if !defined(NO_CERTS) && !defined(NO_DH) && !defined(NO_WOLFSSL_CLIENT) + WOLFSSL_CTX *ctx, *ctx2; + WOLFSSL *ssl, *ssl2; + + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())); + AssertTrue(wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048, + sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1)); + AssertTrue(wolfSSL_CTX_use_PrivateKey_buffer(ctx, server_key_der_2048, + sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMinDhKey_Sz(ctx, 3072)); + AssertNotNull(ssl = wolfSSL_new(ctx)); + AssertNotNull(ctx2 = wolfSSL_CTX_new(wolfSSLv23_server_method())); + AssertTrue(wolfSSL_CTX_use_certificate_buffer(ctx2, server_cert_der_2048, + sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1)); + AssertTrue(wolfSSL_CTX_use_PrivateKey_buffer(ctx2, server_key_der_2048, + sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetMaxDhKey_Sz(ctx, 1024)); + AssertNotNull(ssl2 = wolfSSL_new(ctx2)); + + AssertIntEQ(DH_KEY_SIZE_E, wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048, + sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMinDhKey_Sz(ssl, 2048)); + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048, + sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMinDhKey_Sz(ssl, 3072)); + AssertIntEQ(DH_KEY_SIZE_E, wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048, + sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl2, dh_key_der_2048, + sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMaxDhKey_Sz(ssl2, 2048)); + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpDH_buffer(ssl2, dh_key_der_2048, + sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + + AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetMaxDhKey_Sz(ssl2, 1024)); + AssertIntEQ(DH_KEY_SIZE_E, wolfSSL_SetTmpDH_buffer(ssl, dh_key_der_2048, + sizeof_dh_key_der_2048, WOLFSSL_FILETYPE_ASN1)); + + wolfSSL_free(ssl2); + wolfSSL_CTX_free(ctx2); + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); +#endif +} + /* Test function for wolfSSL_SetMinVersion. Sets the minimum downgrade version * allowed. @@ -1814,26 +1895,26 @@ static void test_wolfSSL_read_write(void) defined(WOLFSSL_SESSION_EXPORT) /* canned export of a session using older version 3 */ static unsigned char version_3[] = { - 0xA5, 0xA3, 0x01, 0x87, 0x00, 0x39, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xA5, 0xA3, 0x01, 0x87, 0x00, 0x3b, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x30, 0x05, + 0x09, 0x0A, 0x01, 0x01, 0x00, 0x0D, 0x05, 0xFE, + 0xFD, 0x01, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xC0, 0x30, 0x05, 0x09, 0x0A, - 0x01, 0x01, 0x00, 0x0D, 0x05, 0xFE, 0xFD, 0x01, - 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, - 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x30, 0x00, - 0x00, 0x00, 0x10, 0x01, 0x01, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x10, 0x01, 0x01, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1845,25 +1926,25 @@ static unsigned char version_3[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, 0x05, 0x12, 0xCF, 0x22, - 0xA1, 0x9F, 0x1C, 0x39, 0x1D, 0x31, 0x11, 0x12, - 0x1D, 0x11, 0x18, 0x0D, 0x0B, 0xF3, 0xE1, 0x4D, - 0xDC, 0xB1, 0xF1, 0x39, 0x98, 0x91, 0x6C, 0x48, - 0xE5, 0xED, 0x11, 0x12, 0xA0, 0x00, 0xF2, 0x25, - 0x4C, 0x09, 0x26, 0xD1, 0x74, 0xDF, 0x23, 0x40, - 0x15, 0x6A, 0x42, 0x2A, 0x26, 0xA5, 0xAC, 0x56, - 0xD5, 0x4A, 0x20, 0xB7, 0xE9, 0xEF, 0xEB, 0xAF, - 0xA8, 0x1E, 0x23, 0x7C, 0x04, 0xAA, 0xA1, 0x6D, - 0x92, 0x79, 0x7B, 0xFA, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x79, 0x7B, - 0xFA, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xAA, 0xA1, 0x6D, 0x92, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x10, - 0x08, 0x02, 0x05, 0x08, 0x01, 0x30, 0x28, 0x00, - 0x00, 0x0F, 0x00, 0x02, 0x00, 0x09, 0x31, 0x32, - 0x37, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x31, 0xED, - 0x4F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x05, 0x12, + 0xCF, 0x22, 0xA1, 0x9F, 0x1C, 0x39, 0x1D, 0x31, + 0x11, 0x12, 0x1D, 0x11, 0x18, 0x0D, 0x0B, 0xF3, + 0xE1, 0x4D, 0xDC, 0xB1, 0xF1, 0x39, 0x98, 0x91, + 0x6C, 0x48, 0xE5, 0xED, 0x11, 0x12, 0xA0, 0x00, + 0xF2, 0x25, 0x4C, 0x09, 0x26, 0xD1, 0x74, 0xDF, + 0x23, 0x40, 0x15, 0x6A, 0x42, 0x2A, 0x26, 0xA5, + 0xAC, 0x56, 0xD5, 0x4A, 0x20, 0xB7, 0xE9, 0xEF, + 0xEB, 0xAF, 0xA8, 0x1E, 0x23, 0x7C, 0x04, 0xAA, + 0xA1, 0x6D, 0x92, 0x79, 0x7B, 0xFA, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, + 0x79, 0x7B, 0xFA, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA1, 0x6D, 0x92, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, + 0x00, 0x10, 0x08, 0x02, 0x05, 0x08, 0x01, 0x30, + 0x28, 0x00, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x09, + 0x31, 0x32, 0x37, 0x2E, 0x30, 0x2E, 0x30, 0x2E, + 0x31, 0xED, 0x4F }; #endif /* defined(HAVE_IO_TESTS_DEPENDENCIES) && defined(WOLFSSL_DTLS) && \ defined(WOLFSSL_SESSION_EXPORT) */ @@ -19899,10 +19980,12 @@ void ApiTest(void) test_wolfSSL_CTX_trust_peer_cert(); test_wolfSSL_CTX_SetTmpDH_file(); test_wolfSSL_CTX_SetTmpDH_buffer(); + test_wolfSSL_CTX_SetMinMaxDhKey_Sz(); test_server_wolfSSL_new(); test_client_wolfSSL_new(); test_wolfSSL_SetTmpDH_file(); test_wolfSSL_SetTmpDH_buffer(); + test_wolfSSL_SetMinMaxDhKey_Sz(); #if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) test_wolfSSL_read_write(); #endif diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 93a3ba4a0..a80010dad 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1032,6 +1032,38 @@ enum { #endif /* WOLFSSL_MAX_MTU */ +/* set minimum DH key size allowed */ +#ifndef WOLFSSL_MIN_DHKEY_BITS + #ifdef WOLFSSL_MAX_STRENGTH + #define WOLFSSL_MIN_DHKEY_BITS 2048 + #else + #define WOLFSSL_MIN_DHKEY_BITS 1024 + #endif +#endif +#if (WOLFSSL_MIN_DHKEY_BITS % 8) + #error DH minimum bit size must be multiple of 8 +#endif +#if (WOLFSSL_MIN_DHKEY_BITS > 16000) + #error DH minimum bit size must not be greater than 16000 +#endif +#define MIN_DHKEY_SZ (WOLFSSL_MIN_DHKEY_BITS / 8) +/* set maximum DH key size allowed */ +#ifndef WOLFSSL_MAX_DHKEY_BITS + #ifdef WOLFSSL_MAX_STRENGTH + #define WOLFSSL_MAX_DHKEY_BITS 3072 + #else + #define WOLFSSL_MAX_DHKEY_BITS 2048 + #endif +#endif +#if (WOLFSSL_MAX_DHKEY_BITS % 8) + #error DH maximum bit size must be multiple of 8 +#endif +#if (WOLFSSL_MAX_DHKEY_BITS > 16000) + #error DH maximum bit size must not be greater than 16000 +#endif +#define MAX_DHKEY_SZ (WOLFSSL_MAX_DHKEY_BITS / 8) + + enum Misc { CIPHER_BYTE = 0x00, /* Default ciphers */ @@ -1089,7 +1121,8 @@ enum Misc { MAX_COMP_EXTRA = 1024, /* max compression extra */ MAX_MTU = WOLFSSL_MAX_MTU, /* max expected MTU */ MAX_UDP_SIZE = 8192 - 100, /* was MAX_MTU - 100 */ - MAX_DH_SZ = 1036, /* 4096 p, pub, g + 2 byte size for each */ + MAX_DH_SZ = (MAX_DHKEY_SZ * 2) + 12, + /* 4096 p, pub, g + 2 byte size for each */ MAX_STR_VERSION = 8, /* string rep of protocol version */ PAD_MD5 = 48, /* pad length for finished */ @@ -1103,7 +1136,8 @@ enum Misc { VERIFY_HEADER = 2, /* always use 2 bytes */ EXTS_SZ = 2, /* always use 2 bytes */ EXT_ID_SZ = 2, /* always use 2 bytes */ - MAX_DH_SIZE = 513, /* 4096 bit plus possible leading 0 */ + MAX_DH_SIZE = MAX_DHKEY_SZ+1, + /* Max size plus possible leading 0 */ NAMED_DH_MASK = 0x100, /* Named group mask for DH parameters */ SESSION_HINT_SZ = 4, /* session timeout hint */ SESSION_ADD_SZ = 4, /* session age add */ @@ -1151,9 +1185,9 @@ enum Misc { DTLS_POOL_SZ = 255,/* allowed number of list items in TX pool */ DTLS_EXPORT_PRO = 165,/* wolfSSL protocol for serialized session */ DTLS_EXPORT_VERSION = 4, /* wolfSSL version for serialized session */ - DTLS_EXPORT_OPT_SZ = 58, /* amount of bytes used from Options */ + DTLS_EXPORT_OPT_SZ = 60, /* amount of bytes used from Options */ DTLS_EXPORT_VERSION_3 = 3, /* wolfSSL version before TLS 1.3 addition */ - DTLS_EXPORT_OPT_SZ_3 = 57, /* amount of bytes used from Options */ + DTLS_EXPORT_OPT_SZ_3 = 59, /* amount of bytes used from Options */ DTLS_EXPORT_KEY_SZ = 325 + (DTLS_SEQ_SZ * 2), /* max amount of bytes used from Keys */ DTLS_EXPORT_MIN_KEY_SZ = 78 + (DTLS_SEQ_SZ * 2), @@ -1352,23 +1386,6 @@ enum Misc { #endif #define MIN_RSAKEY_SZ (WOLFSSL_MIN_RSA_BITS / 8) -/* set minimum DH key size allowed */ -#ifndef WOLFSSL_MIN_DHKEY_BITS - #ifdef WOLFSSL_MAX_STRENGTH - #define WOLFSSL_MIN_DHKEY_BITS 2048 - #else - #define WOLFSSL_MIN_DHKEY_BITS 1024 - #endif -#endif -#if (WOLFSSL_MIN_DHKEY_BITS % 8) - #error DH minimum bit size must be multiple of 8 -#endif -#if (WOLFSSL_MIN_DHKEY_BITS > 16000) - #error DH minimum bit size must not be greater than 16000 -#endif -#define MIN_DHKEY_SZ (WOLFSSL_MIN_DHKEY_BITS / 8) - - #ifdef SESSION_INDEX /* Shift values for making a session index */ #define SESSIDX_ROW_SHIFT 4 @@ -2438,6 +2455,7 @@ struct WOLFSSL_CTX { #endif #ifndef NO_DH word16 minDhKeySz; /* minimum DH key size */ + word16 maxDhKeySz; /* maximum DH key size */ #endif #ifndef NO_RSA short minRsaKeySz; /* minimum RSA key size */ @@ -3137,6 +3155,7 @@ typedef struct Options { #endif #ifndef NO_DH word16 minDhKeySz; /* minimum DH key size */ + word16 maxDhKeySz; /* minimum DH key size */ word16 dhKeySz; /* actual DH key size */ #endif #ifndef NO_RSA diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 4bfa335d4..b3705b9b4 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1604,6 +1604,8 @@ WOLFSSL_API int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX*, const unsigned char* WOLFSSL_API int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX*, unsigned short); WOLFSSL_API int wolfSSL_SetMinDhKey_Sz(WOLFSSL*, unsigned short); +WOLFSSL_API int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX*, unsigned short); +WOLFSSL_API int wolfSSL_SetMaxDhKey_Sz(WOLFSSL*, unsigned short); WOLFSSL_API int wolfSSL_GetDhKey_Sz(WOLFSSL*); #endif /* NO_DH */ diff --git a/wolfssl/test.h b/wolfssl/test.h index 20feefa9c..db21f0023 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -238,8 +238,10 @@ #define CLIENT_DOWNGRADE_VERSION (-98) #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH) #define DEFAULT_MIN_DHKEY_BITS 2048 + #define DEFAULT_MAX_DHKEY_BITS 3072 #else #define DEFAULT_MIN_DHKEY_BITS 1024 + #define DEFAULT_MAX_DHKEY_BITS 2048 #endif #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_MAX_STRENGTH) #define DEFAULT_MIN_RSAKEY_BITS 2048