1
0
mirror of https://github.com/wolfSSL/wolfssl.git synced 2026-10-24 04:09:07 +03:00

Merge pull request #11625 from dgarske/cryptonly_nomalloc

wolfCrypt: support zero-malloc cert encoding and clean up CMake/platform defines
This commit is contained in:
philljj
2026-10-07 08:38:22 -05:00
committed by GitHub
23 changed files with 667 additions and 111 deletions

View File

@@ -542,5 +542,29 @@
"--disable-oldtls", "--disable-examples", "CPPFLAGS=-DWOLFSSL_NO_TLS12"]},
{"name": "tls13-sha512-runtime", "minutes": 1.6,
"comment": "--enable-tls13-sha512 with TLS 1.2 left in, so the examples and unit tests build and run with WOLFSSL_HS_HASH_SHA512 set. No cipher suite sets mac_algorithm to sha512_mac, so the sha512_mac arms in src/tls13.c stay unreached; what this entry proves is that the option does not break an otherwise ordinary build, which the two compile-only entries above cannot show.",
"configure": ["--enable-tls13", "--enable-tls13-sha512", "--enable-sha512"]}
"configure": ["--enable-tls13", "--enable-tls13-sha512", "--enable-sha512"]},
{"name": "cryptonly-sha3-keyid", "minutes": 0.8,
"comment": "SHA3 as the only hash family that can derive key identifiers: no SHA-1 and no SHA-256, so HashIdAlg()/CalcHashId_ex() must pick SHA3-256 and KEYID_SIZE must follow it. SHA-512 is kept only because the Hash DRBG needs it. The CERT KEYID subtest checks the SKID/AKID sizes the generator writes against CTC_MAX_SKID_SIZE.",
"configure": ["--enable-cryptonly", "--enable-ecc", "--enable-certgen",
"--enable-certreq", "--enable-certext", "--enable-sha3", "--enable-sha512",
"--disable-sha", "--disable-sha256", "--disable-sha224", "--disable-rsa",
"--disable-dh",
"CPPFLAGS=-DWOLFSSL_DRBG_SHA512 -DUSE_CERT_BUFFERS_256"]},
{"name": "sha3-keyid-ocsp-crl", "minutes": 1.2,
"comment": "The SHA3-only key identifier hash of cryptonly-sha3-keyid, but with the TLS layer left in so src/ocsp.c and the Signer table compile. OCSP_DIGEST and OCSP_RESPONDER_ID_HASH_TYPE must name SHA3-256 and SIGNER_DIGEST_SIZE must match KEYID_SIZE, none of which a cryptonly build reaches. NO_SESSION_CACHE because HashObject() needs MD5, SHA-1 or SHA-256 and this build has none; no cipher suite survives either, so there is no handshake left to check.",
"configure": ["--enable-ocsp", "--enable-crl", "--enable-sha3",
"--enable-certgen", "--enable-certreq", "--enable-certext",
"--disable-sha", "--disable-sha256", "--disable-sha224",
"--disable-examples", "CPPFLAGS=-DNO_SESSION_CACHE"],
"check": false,
"run": [["./wolfcrypt/test/testwolfcrypt"]]},
{"name": "sha3-384-keyid", "minutes": 0.8,
"comment": "WOLFSSL_NOSHA3_256 on top of the SHA3-only key identifier hash, so the selection falls through to SHA3-384 and WC_ASN_KEYID_SZ becomes 48. This is the only entry where the key identifier is larger than the 32-byte floor, so it is what proves CTC_MAX_SKID_SIZE widens and the Cert SKID/AKID buffers still hold what CalcHashId_ex() writes. ML-KEM is off because wc_mlkem_poly.c calls wc_InitSha3_256() unconditionally.",
"configure": ["--enable-cryptonly", "--enable-ecc", "--enable-certgen",
"--enable-certreq", "--enable-certext", "--enable-sha3", "--enable-sha512",
"--disable-sha", "--disable-sha256", "--disable-sha224", "--disable-rsa",
"--disable-dh", "--disable-mlkem",
"CPPFLAGS=-DWOLFSSL_DRBG_SHA512 -DUSE_CERT_BUFFERS_256 -DWOLFSSL_NOSHA3_256"],
"check": false,
"run": [["./wolfcrypt/test/testwolfcrypt"]]}
]

View File

@@ -111,6 +111,67 @@ jobs:
cd ..
rm -rf build
# Option plumbing: a declared option must reach both the library and
# options.h, and a -D that is not an option must reach neither.
- name: Check option to options.h plumbing
run: |
mkdir build
cd build
cmake -DWOLFSSL_CRYPT_ONLY=yes .. 2>&1 | tee cfg.log
grep -q '^#define WOLFCRYPT_ONLY$' wolfssl/options.h
grep -q '^#define NO_TLS$' wolfssl/options.h
# TLS-layer options default off, as with --enable-cryptonly, but the
# TLS 1.3 KDFs stay.
! grep -q '^#define HAVE_SNI$' wolfssl/options.h
! grep -q '^#define WOLFSSL_DTLS$' wolfssl/options.h
grep -q '^#define WOLFSSL_TLS13$' wolfssl/options.h
! grep -q 'is not a wolfSSL build option' cfg.log
cmake --build .
cd ..
rm -rf build
mkdir build
cd build
# Adding cryptonly to a directory configured without it must take the
# TLS layer out too, not leave the previous defaults cached.
cmake .. > /dev/null
grep -q '^#define HAVE_SNI$' wolfssl/options.h
cmake -DWOLFSSL_CRYPT_ONLY=yes .. > /dev/null
! grep -q '^#define HAVE_SNI$' wolfssl/options.h
grep -q '^#define NO_TLS$' wolfssl/options.h
cd ..
rm -rf build
mkdir build
cd build
# Cryptonly wins over a TLS-layer option asked for alongside it.
cmake -DWOLFSSL_CRYPT_ONLY=yes -DWOLFSSL_DTLS=yes .. > /dev/null
! grep -q '^#define WOLFSSL_DTLS$' wolfssl/options.h
cd ..
rm -rf build
mkdir build
cd build
# An option declared with a raw CACHE entry rather than add_option must
# survive the stray-define guard, including across a reconfigure.
cmake -DWOLFSSL_HARDEN_TLS=128 .. 2>&1 | tee cfg.log
grep -q '^#define WOLFSSL_HARDEN_TLS 128$' wolfssl/options.h
! grep -q 'is not a wolfSSL build option' cfg.log
cmake . > /dev/null
grep -q '^#define WOLFSSL_HARDEN_TLS 128$' wolfssl/options.h
cd ..
rm -rf build
mkdir build
cd build
# WOLFSSL_STATICMEMORY is the option; this spelling is not one.
cmake -DWOLFSSL_STATIC_MEMORY=yes .. 2>&1 | tee cfg.log
grep -q 'WOLFSSL_STATIC_MEMORY is not a wolfSSL build option' cfg.log
! grep -q '^#define WOLFSSL_STATIC_MEMORY$' wolfssl/options.h
cd ..
rm -rf build
# CMake build with user_settings.h
- name: Build wolfssl with user_settings.h
run: |

View File

@@ -99,7 +99,8 @@ jobs:
"run": [["./wolfcrypt/test/testwolfcrypt"]]},
{"name": "no-heap-cert", "minutes": 0.8,
"configure": ["--enable-rsa", "--enable-keygen", "--enable-ecc",
"--enable-acert", "--disable-dh", "--disable-filesystem",
"--enable-acert", "--enable-certgen", "--enable-certreq",
"--enable-certext", "--disable-dh", "--disable-filesystem",
"CFLAGS=-DWOLFSSL_NO_MALLOC -DNO_WOLFSSL_MEMORY -DRSA_MIN_SIZE=1024 -DWOLFSSL_TEST_CERT -DUSE_CERT_BUFFERS_2048 -DUSE_CERT_BUFFERS_256 -pedantic -Wdeclaration-after-statement -Wnull-dereference -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE"],
"check": false,
"run": [["./wolfcrypt/test/testwolfcrypt"]]}

View File

@@ -500,14 +500,6 @@ if(WOLFSSL_SCEP)
list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_AES_KEYWRAP" "-DHAVE_X963_KDF" "-DWOLFSSL_AES_DIRECT" "-DWOLFSSL_CERT_EXT" "-DWOLFSSL_CERT_GEN" "-DWOLFSSL_CERT_REQ" "-DWOLFSSL_HAVE_WOLFSCEP" "-DWOLFSSL_KEY_GEN")
endif()
add_option("WOLFSSL_MCAST" "Enable DTLS multicast support (default: disabled)" "no" "yes;no")
if(WOLFSSL_MCAST)
foreach(_o WOLFSSL_DTLS)
force_option(${_o} "yes")
endforeach()
list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_NULL_CIPHER" "-DWOLFSSL_MULTICAST")
endif()
add_option("WOLFSSL_WPAS_DPP" "Enable wpa_supplicant DPP support (default: disabled)" "no" "yes;no")
if(WOLFSSL_WPAS_DPP)
foreach(_o WOLFSSL_AES WOLFSSL_ARC4 WOLFSSL_CRL WOLFSSL_DES3 WOLFSSL_DSA WOLFSSL_MD4 WOLFSSL_MD5 WOLFSSL_OCSP WOLFSSL_OCSPSTAPLING WOLFSSL_OCSPSTAPLING_V2 WOLFSSL_PKCS7)
@@ -632,6 +624,39 @@ if(WOLFSSL_DEBUG)
endif()
# wolfCrypt only (no TLS). Declared ahead of the TLS-layer options so the
# forces below land before their add_option() calls.
add_option("WOLFSSL_CRYPT_ONLY"
"Enable wolfCrypt Only build (default: disabled)"
"no" "yes;no")
if(WOLFSSL_CRYPT_ONLY)
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFCRYPT_ONLY")
# Mirror --enable-cryptonly so options.h describes the library built.
# Forced, not defaulted: a reconfigure cannot tell a cache entry from an
# explicit setting. WOLFSSL_TLS carries -DNO_TLS and the TLS-version
# checks read it. TLS 1.2 and 1.3 stay on for their wolfCrypt-layer KDFs.
foreach(_o WOLFSSL_TLS
WOLFSSL_ALPN WOLFSSL_CRL_MONITOR WOLFSSL_DTLS WOLFSSL_DTLS13
WOLFSSL_DTLS_CH_FRAG WOLFSSL_DTLS_CID WOLFSSL_DTLS_MTU
WOLFSSL_EARLYDATA WOLFSSL_ECH WOLFSSL_MCAST WOLFSSL_OCSP
WOLFSSL_OCSPSTAPLING WOLFSSL_OCSPSTAPLING_V2
WOLFSSL_PKCALLBACKS WOLFSSL_QUIC
WOLFSSL_RENEGOTIATION_INDICATION WOLFSSL_SECURE_RENEGOTIATION
WOLFSSL_SNI WOLFSSL_SRTP WOLFSSL_TLSX)
force_option(${_o} "no")
endforeach()
message(STATUS "WOLFSSL_CRYPT_ONLY: TLS layer off, including its options")
endif()
add_option("WOLFSSL_MCAST" "Enable DTLS multicast support (default: disabled)" "no" "yes;no")
if(WOLFSSL_MCAST)
foreach(_o WOLFSSL_DTLS)
force_option(${_o} "yes")
endforeach()
list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_NULL_CIPHER" "-DWOLFSSL_MULTICAST")
endif()
# Single threaded
add_option("WOLFSSL_SINGLE_THREADED"
"Enable wolfSSL single threaded (default: disabled)"
@@ -4628,6 +4653,58 @@ endforeach()
# both emitting the same feature define).
list(REMOVE_DUPLICATES WOLFSSL_DEFINITIONS)
# Matches configure.ac: cryptonly and opensslall are mutually incompatible.
# The application bundles (nginx, haproxy, ...) each append -DOPENSSL_ALL
# directly, which forcing their leaf options off does not retract, so test the
# definition list as well as the option.
if(WOLFSSL_CRYPT_ONLY)
if(WOLFSSL_OPENSSLALL OR "-DOPENSSL_ALL" IN_LIST WOLFSSL_DEFINITIONS)
message(FATAL_ERROR
"cryptonly and opensslall are mutually incompatible.")
endif()
endif()
# A -D that is not a build option still satisfies the matching #cmakedefine
# below, so options.h would claim features the library lacks (for example
# WOLFSSL_STATIC_MEMORY for the WOLFSSL_STATICMEMORY option). Drop those.
get_property(WOLFSSL_DECLARED_OPTIONS GLOBAL PROPERTY WOLFSSL_DECLARED_OPTIONS)
get_cmake_property(WOLFSSL_CACHE_VARS CACHE_VARIABLES)
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/options.h.in" OPTIONS_H_LINES
REGEX "^#cmakedefine[ \t]+[A-Za-z_]")
foreach(LINE IN LISTS OPTIONS_H_LINES)
string(REGEX REPLACE "^#cmakedefine[ \t]+([A-Za-z_][A-Za-z0-9_]*).*$" "\\1"
MACRO_NAME "${LINE}")
# wolfSSL's namespace only; the rest are system probes we set ourselves.
if(NOT MACRO_NAME MATCHES "^WOLF")
continue()
endif()
if(MACRO_NAME IN_LIST WOLFSSL_DECLARED_OPTIONS)
continue()
endif()
if(NOT MACRO_NAME IN_LIST WOLFSSL_CACHE_VARS)
continue()
endif()
# Already compiled in, so a real option however its cache entry was made
# (WOLFSSL_HARDEN_TLS uses a raw CACHE STRING to keep a bad value).
set(MACRO_IN_DEFS FALSE)
foreach(DEF IN LISTS WOLFSSL_DEFINITIONS)
if(DEF MATCHES "^-D${MACRO_NAME}(=.*)?$")
set(MACRO_IN_DEFS TRUE)
break()
endif()
endforeach()
if(MACRO_IN_DEFS)
continue()
endif()
if(${MACRO_NAME})
message(WARNING "${MACRO_NAME} is not a wolfSSL build option; ignoring "
"it so that wolfssl/options.h matches the library. Run "
"`cmake -LH` for the option list.")
unset(${MACRO_NAME})
unset(${MACRO_NAME} CACHE)
endif()
endforeach()
foreach(DEF IN LISTS WOLFSSL_DEFINITIONS)
string(REGEX MATCH "^(-D)?([^=]+)(=(.*))?$" DEF_MATCH ${DEF})
if (NOT "${CMAKE_MATCH_4}" STREQUAL "")

View File

@@ -537,6 +537,9 @@ extern unsigned int my_rng_seed_gen(void);
#define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
#define XSNPRINTF snprintf
#include <stdlib.h>
#define XATOI(s) atoi((s))
#endif

View File

@@ -454,6 +454,9 @@ extern "C" {
#define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
#define XSNPRINTF snprintf
#include <stdlib.h>
#define XATOI(s) atoi((s))
#endif

View File

@@ -531,6 +531,9 @@ extern unsigned int my_rng_seed_gen(void);
#define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
#define XSNPRINTF snprintf
#include <stdlib.h>
#define XATOI(s) atoi((s))
#endif

View File

@@ -662,6 +662,9 @@ C149F3285397DFBD0C6720E14818475C3A50B10880EF9619463173A6D5ED15E7
#define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
#define XSNPRINTF snprintf
#include <stdlib.h>
#define XATOI(s) atoi((s))
#endif

View File

@@ -528,6 +528,9 @@ extern "C" {
#define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
#define XSNPRINTF snprintf
#include <stdlib.h>
#define XATOI(s) atoi((s))
#endif

View File

@@ -539,6 +539,9 @@ extern "C" {
#define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
#define XSNPRINTF snprintf
#include <stdlib.h>
#define XATOI(s) atoi((s))
#endif

View File

@@ -540,6 +540,9 @@ extern "C" {
#define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
#define XSNPRINTF snprintf
#include <stdlib.h>
#define XATOI(s) atoi((s))
#endif

View File

@@ -621,6 +621,9 @@ extern "C" {
#define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
#define XSNPRINTF snprintf
#include <stdlib.h>
#define XATOI(s) atoi((s))
#endif

View File

@@ -681,6 +681,9 @@ extern "C" {
#define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
#define XSNPRINTF snprintf
#include <stdlib.h>
#define XATOI(s) atoi((s))
#endif

View File

@@ -17,9 +17,8 @@ endfunction()
# explicit rather than relying on cross-file cache-precedence side effects.
function(force_option NAME VALUE)
set_property(GLOBAL PROPERTY "WOLFSSL_FORCE_${NAME}" "${VALUE}")
# Track pending forces so an unconsumed one (no matching add_option) can be
# reported by wolfssl_warn_unconsumed_forces() -- a force on an option that
# is not declared via add_option() would otherwise be silently ignored.
# Track pending forces so wolfssl_warn_unconsumed_forces() can report one
# with no matching add_option(), which would otherwise be ignored.
set_property(GLOBAL APPEND PROPERTY WOLFSSL_FORCE_PENDING "${NAME}")
endfunction()
@@ -39,6 +38,9 @@ function(wolfssl_warn_unconsumed_forces)
endfunction()
function(add_option NAME HELP_STRING DEFAULT VALUES)
# Record the name for the options.h.in guard in CMakeLists.txt.
set_property(GLOBAL APPEND PROPERTY WOLFSSL_DECLARED_OPTIONS "${NAME}")
if(VALUES STREQUAL "yes;no")
# Set the default value for the option.
set(${NAME} ${DEFAULT} CACHE BOOL ${HELP_STRING})
@@ -49,10 +51,8 @@ function(add_option NAME HELP_STRING DEFAULT VALUES)
set_property(CACHE ${NAME} PROPERTY STRINGS ${VALUES})
endif()
# Apply any dependency force recorded via force_option(). Done after the
# cache entry is created (so its BOOL/STRING type and help are preserved)
# and before the reduction below, so the forced value drives this option's
# own define/source emission just as an explicit setting would.
# Apply any force_option(), after the cache entry exists so its type and
# help survive, and before the reduction below.
get_property(_wolfssl_forced GLOBAL PROPERTY "WOLFSSL_FORCE_${NAME}" SET)
if(_wolfssl_forced)
get_property(_wolfssl_force_val GLOBAL PROPERTY "WOLFSSL_FORCE_${NAME}")

View File

@@ -709,6 +709,8 @@ extern "C" {
#cmakedefine WOLFSSL_STATIC_MEMORY_LEAN
#undef WOLFSSL_STATIC_MEMORY_DEBUG_CALLBACK
#cmakedefine WOLFSSL_STATIC_MEMORY_DEBUG_CALLBACK
#undef WOLFCRYPT_ONLY
#cmakedefine WOLFCRYPT_ONLY
#undef NO_TLS
#cmakedefine NO_TLS
#undef NO_SHA256

View File

@@ -487,6 +487,9 @@ extern "C" {
#define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
#define XSNPRINTF snprintf
#include <stdlib.h>
#define XATOI(s) atoi((s))
#endif

View File

@@ -110,6 +110,7 @@ ASN Options:
cost of taking up more memory. Adds initials, givenname, dnQualifer for
example.
* WC_ASN_HASH_SHA256: Force use of SHA2-256 for the internal hash ID calcs.
An OCSP CertID carries those hashes, so this selects its hash too.
* WOLFSSL_ALLOW_ENCODING_CA_FALSE: Allow encoding BasicConstraints CA:FALSE
* which is discouraged by X.690 specification - default values shall not
* be encoded.
@@ -194,10 +195,11 @@ ASN Options:
* WOLFSSL_X509_TINY: Minimal-extension profile. Compiles out optional
X.509 extension decoders behind per-feature WOLFSSL_X509_TINY_<F> add-back
macros. Requires WOLFSSL_ASN_TEMPLATE (enforced with #error).
* WC_ASN_NO_HEAP: Zero-allocation cert parse: reference key/alt-name
data in the source DER instead of heap copies, so the source buffer must
outlive the DecodedCert. Auto-defined when WOLFSSL_NO_MALLOC and
NO_WOLFSSL_MEMORY are set without XMALLOC_USER or WOLFSSL_STATIC_MEMORY.
* WC_ASN_NO_HEAP: Zero-allocation cert parse and encode. Parsing
references key/alt-name data in the source DER instead of heap copies, so
the source buffer must outlive the DecodedCert; encoding works from the
stack. Auto-defined when WOLFSSL_NO_MALLOC and NO_WOLFSSL_MEMORY are set
without XMALLOC_USER or WOLFSSL_STATIC_MEMORY.
Limitation: IP and registeredID SAN entries need a parsed string form that
has no in-place source, so such certs are rejected with ASN_PARSE_E. SAN
DNS_entry.name is NOT NUL-terminated in this mode; only .len is authoritative.
@@ -277,6 +279,7 @@ ASN Options:
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/hash.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
@@ -14399,6 +14402,12 @@ static int GetCertKey(DecodedCert* cert, const byte* source, word32* inOutIdx,
}
#endif
#ifdef WOLFSSL_CERT_EXT
/* Cert key identifier buffers must hold what CalcHashId_ex() writes. */
wc_static_assert((int)KEYID_SIZE <= (int)CTC_MAX_SKID_SIZE);
wc_static_assert((int)KEYID_SIZE <= (int)CTC_MAX_AKID_SIZE);
#endif
/* Return the hash algorithm to use with the signature algorithm.
*
* @param [in] oidSum Signature id.
@@ -14416,11 +14425,7 @@ int HashIdAlg(word32 oidSum)
return WC_SM3;
}
#endif
#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256))
return WC_SHA256;
#else
return WC_SHA;
#endif
return WC_ASN_KEYID_HASH_TYPE;
}
/* Calculate hash of the id using the SHA-1 or SHA-256.
@@ -14434,13 +14439,7 @@ int HashIdAlg(word32 oidSum)
int CalcHashId(const byte* data, word32 len, byte* hash)
{
/* Use default hash algorithm. */
return CalcHashId_ex(data, len, hash,
#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256))
WC_SHA256
#else
WC_SHA
#endif
);
return CalcHashId_ex(data, len, hash, WC_ASN_KEYID_HASH_TYPE);
}
/* Calculate hash of the id using the SHA-1 or SHA-256.
@@ -14451,41 +14450,103 @@ int CalcHashId(const byte* data, word32 len, byte* hash)
* @return 0 on success.
* @return MEMORY_E when dynamic memory allocation fails.
*/
/* Fit a digest into the caller's KEYID_SIZE buffer: refuse one that is too
* long and zero the tail a shorter one leaves. Both operands are constants,
* so the arms fold away where the sizes match. */
#define WC_ASN_KEYID_FIT(hash, digestSz, ret) \
do { \
if ((int)KEYID_SIZE < (int)(digestSz)) { \
(ret) = BUFFER_E; \
} \
else { \
if ((int)KEYID_SIZE > (int)(digestSz)) { \
XMEMSET((hash) + (digestSz), 0, \
(size_t)((int)KEYID_SIZE - (int)(digestSz))); \
} \
(ret) = 0; \
} \
} while (0)
int CalcHashId_ex(const byte* data, word32 len, byte* hash, int hashAlg)
{
int ret;
switch (hashAlg) {
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
if (hashAlg == WC_SM3) {
ret = wc_Sm3Hash(data, len, hash);
}
else
case WC_SM3:
WC_ASN_KEYID_FIT(hash, WC_SM3_DIGEST_SIZE, ret);
if (ret == 0) {
ret = wc_Sm3Hash(data, len, hash);
}
break;
#endif
#if defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256))
if (hashAlg == WC_SHA256) {
ret = wc_Sha256Hash(data, len, hash);
}
else
#elif !defined(NO_SHA)
if (hashAlg == WC_SHA) {
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
XMEMSET(hash + WC_SHA_DIGEST_SIZE, 0, KEYID_SIZE - WC_SHA_DIGEST_SIZE);
#endif
ret = wc_ShaHash(data, len, hash);
}
else
#else
(void)data;
(void)len;
(void)hash;
#ifndef NO_SHA
case WC_SHA:
WC_ASN_KEYID_FIT(hash, WC_SHA_DIGEST_SIZE, ret);
if (ret == 0) {
ret = wc_ShaHash(data, len, hash);
}
break;
#endif
#ifndef NO_SHA256
case WC_SHA256:
WC_ASN_KEYID_FIT(hash, WC_SHA256_DIGEST_SIZE, ret);
if (ret == 0) {
ret = wc_Sha256Hash(data, len, hash);
}
break;
#endif
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
case WC_SHA3_256:
{
wc_Sha3 sha3[1]; /* on the stack: this path must not allocate */
WC_ASN_KEYID_FIT(hash, WC_SHA3_256_DIGEST_SIZE, ret);
if (ret == 0) {
ret = wc_InitSha3_256(sha3, NULL, INVALID_DEVID);
}
if (ret == 0) {
ret = wc_Sha3_256_Update(sha3, data, len);
if (ret == 0) {
ret = wc_Sha3_256_Final(sha3, hash);
}
wc_Sha3_256_Free(sha3);
}
break;
}
#endif
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
case WC_SHA3_384:
{
wc_Sha3 sha3[1]; /* on the stack: this path must not allocate */
WC_ASN_KEYID_FIT(hash, WC_SHA3_384_DIGEST_SIZE, ret);
if (ret == 0) {
ret = wc_InitSha3_384(sha3, NULL, INVALID_DEVID);
}
if (ret == 0) {
ret = wc_Sha3_384_Update(sha3, data, len);
if (ret == 0) {
ret = wc_Sha3_384_Final(sha3, hash);
}
wc_Sha3_384_Free(sha3);
}
break;
}
#endif
default:
(void)data;
(void)len;
(void)hash;
ret = NOT_COMPILED_IN;
break;
}
return ret;
}
#undef WC_ASN_KEYID_FIT
#ifndef NO_CERTS
/* Get the hash of the id using the SHA-1 or SHA-256.
*
@@ -28766,6 +28827,12 @@ static int wc_SetCert_LoadDer(Cert* cert, const byte* der, word32 derSz,
#endif /* WOLFSSL_CERT_GEN */
/* Bound for wc_SetExtKeyUsage()'s value. Every known usage name, comma
* separated, is 78 bytes today. */
#ifndef WC_ASN_EKU_STR_MAX
#define WC_ASN_EKU_STR_MAX 128
#endif
#ifdef WOLFSSL_CERT_GEN
#ifndef NO_ASN_TIME
@@ -29001,6 +29068,15 @@ struct {
#define EKU_OID_LO 1
#define EKU_OID_HI 6
#ifdef WC_ASN_NO_HEAP
/* EKU template items: the SEQUENCE, one per known usage, plus OID slots. */
#ifdef WOLFSSL_EKU_OID
#define WC_ASN_EKU_MAX_ITEMS (1 + EKU_OID_HI + CTC_MAX_EKU_NB)
#else
#define WC_ASN_EKU_MAX_ITEMS (1 + EKU_OID_HI)
#endif
#endif
#endif /* WOLFSSL_ASN_TEMPLATE */
/* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
@@ -29009,6 +29085,11 @@ static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
{
/* TODO: consider calculating size of OBJECT_IDs, setting length into
* SEQUENCE, encode SEQUENCE, encode OBJECT_IDs into buffer. */
#ifdef WC_ASN_NO_HEAP
/* cnt below is a compile-time bound, so these fit on the stack. */
ASNSetData dataASNbuf[WC_ASN_EKU_MAX_ITEMS];
ASNItem extKuASNbuf[WC_ASN_EKU_MAX_ITEMS];
#endif
ASNSetData* dataASN;
ASNItem* extKuASN = NULL;
int asnIdx = 1;
@@ -29021,6 +29102,10 @@ static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
cnt += CTC_MAX_EKU_NB;
#endif
#ifdef WC_ASN_NO_HEAP
dataASN = dataASNbuf;
extKuASN = extKuASNbuf;
#else
/* Allocate memory for dynamic data items. */
dataASN = (ASNSetData*)XMALLOC(cnt * sizeof(ASNSetData), cert->heap,
DYNAMIC_TYPE_TMP_BUFFER);
@@ -29035,6 +29120,7 @@ static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
ret = MEMORY_E;
}
}
#endif
if (ret == 0) {
/* Copy Sequence into dynamic ASN.1 template. */
@@ -29103,9 +29189,11 @@ static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
ret = (int)sz;
}
#ifndef WC_ASN_NO_HEAP
/* Dispose of allocated data. */
XFREE(extKuASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(dataASN, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
@@ -29474,24 +29562,38 @@ int ParseExtKeyUsageStr(const char* value, byte* extKeyUsage, void* heap)
char *token, *str, *ptr;
word32 len = 0;
byte usage = 0;
#ifdef WC_ASN_NO_HEAP
char strBuf[WC_ASN_EKU_STR_MAX + 1];
#endif
if (value == NULL || extKeyUsage == NULL) {
return BAD_FUNC_ARG;
}
/* duplicate string (including terminator) */
/* duplicate string (including terminator); XSTRTOK writes into it */
len = (word32)XSTRLEN(value);
#ifdef WC_ASN_NO_HEAP
(void)heap;
if (len > WC_ASN_EKU_STR_MAX) {
return BUFFER_E;
}
str = strBuf;
#else
str = (char*)XMALLOC(len + 1, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (str == NULL) {
return MEMORY_E;
}
#endif
XMEMCPY(str, value, len + 1);
/* parse value, and set corresponding Key Usage value */
if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
#ifndef WC_ASN_NO_HEAP
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return EXTKEYUSAGE_E;
}
/* Adding a usage name here may need WC_ASN_EKU_STR_MAX raised. */
while (token != NULL) {
if (!XSTRCASECMP(token, "any"))
usage |= EXTKEYUSE_ANY;
@@ -29515,7 +29617,9 @@ int ParseExtKeyUsageStr(const char* value, byte* extKeyUsage, void* heap)
token = XSTRTOK(NULL, ",", &ptr);
}
#ifndef WC_ASN_NO_HEAP
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
if (ret == 0) {
*extKeyUsage = usage;
@@ -29583,6 +29687,20 @@ enum {
/* Number of items in ASN.1 template for the SEQUENCE around the RDNs. */
#define nameASN_Length (sizeof(nameASN) / sizeof(ASNItem))
#ifdef WC_ASN_NO_HEAP
/* Name components per certificate name. Lower to trade components for
* stack; SetNameEx() returns BUFFER_E when a name needs more. */
#ifndef WC_ASN_MAX_NAME_ENTRIES
#ifdef WOLFSSL_MULTI_ATTRIB
#define WC_ASN_MAX_NAME_ENTRIES (NAME_ENTRIES + CTC_MAX_ATTRIB)
#else
#define WC_ASN_MAX_NAME_ENTRIES NAME_ENTRIES
#endif
#endif
#define WC_ASN_NAME_MAX_ITEMS \
(nameASN_Length + rdnASN_Length * (word32)WC_ASN_MAX_NAME_ENTRIES)
#endif
static int SetNameRdnItems(ASNSetData* dataASN, ASNItem* namesASN,
int maxIdx, CertName* name)
{
@@ -29714,11 +29832,16 @@ int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap)
{
/* TODO: consider calculating size of entries, putting length into
* SEQUENCE, encode SEQUENCE, encode entries into buffer. */
ASNSetData* dataASN = NULL; /* Can't use DECL_ASNSETDATA. Always dynamic. */
/* Can't use DECL_ASNSETDATA: item count is only known at run time. */
ASNSetData* dataASN = NULL;
ASNItem* namesASN = NULL;
word32 items = 0;
int ret = 0;
word32 sz = 0;
#ifdef WC_ASN_NO_HEAP
ASNSetData dataASNbuf[WC_ASN_NAME_MAX_ITEMS];
ASNItem namesASNbuf[WC_ASN_NAME_MAX_ITEMS];
#endif
/* Calculate length of name entries and size for allocating. */
ret = SetNameRdnItems(NULL, NULL, 0, name);
@@ -29734,6 +29857,14 @@ int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap)
return 0;
}
#ifdef WC_ASN_NO_HEAP
if (items > WC_ASN_NAME_MAX_ITEMS) {
WOLFSSL_MSG("Name needs more entries than WC_ASN_MAX_NAME_ENTRIES");
return BUFFER_E;
}
dataASN = dataASNbuf;
namesASN = namesASNbuf;
#else
/* Allocate dynamic data items. */
dataASN = (ASNSetData*)XMALLOC(items * sizeof(ASNSetData), heap,
DYNAMIC_TYPE_TMP_BUFFER);
@@ -29748,6 +29879,7 @@ int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap)
ret = MEMORY_E;
}
}
#endif
if (ret == 0) {
/* Clear the dynamic data. */
@@ -29782,8 +29914,10 @@ int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap)
}
}
#ifndef WC_ASN_NO_HEAP
XFREE(namesASN, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(dataASN, heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
(void)heap;
return ret;
}
@@ -32964,6 +33098,9 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
void* mlKemKey,
int kid_type)
{
#ifdef WC_ASN_NO_HEAP
byte bufOnStack[MAX_PUBLIC_KEY_SZ];
#endif
byte *buf;
int bufferSz, ret;
word32 bufSz = MAX_PUBLIC_KEY_SZ;
@@ -32987,9 +33124,17 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
bufSz = MLKEM_MAX_PUB_KEY_DER_SIZE;
}
#endif
#ifdef WC_ASN_NO_HEAP
if (bufSz > (word32)sizeof(bufOnStack)) {
/* The PQC keys above ask for more than the stack buffer holds. */
return NOT_COMPILED_IN;
}
buf = bufOnStack;
#else
buf = (byte *)XMALLOC(bufSz, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (buf == NULL)
return MEMORY_E;
#endif
/* Public Key */
bufferSz = -1;
@@ -33047,7 +33192,9 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
#endif
if (bufferSz <= 0) {
#ifndef WC_ASN_NO_HEAP
XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return PUBLIC_KEY_E;
}
@@ -33071,7 +33218,9 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
#endif
}
#ifndef WC_ASN_NO_HEAP
XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
@@ -34074,17 +34223,29 @@ int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
word32 idx = 0, nb_val;
char *token, *str, *ptr;
word32 len;
/* NULL when str is the stack buffer, so XFREE below is then a no-op */
char *strAlloc = NULL;
#ifdef WC_ASN_NO_HEAP
char strBuf[CTC_MAX_CERTPOL_SZ];
#endif
(void)heap;
if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL)
return BAD_FUNC_ARG;
/* duplicate string (including terminator) */
/* duplicate string (including terminator); XSTRTOK writes into it */
len = (word32)XSTRLEN(in);
str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (str == NULL)
#ifdef WC_ASN_NO_HEAP
if (len >= sizeof(strBuf))
return BUFFER_E;
str = strBuf;
#else
strAlloc = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (strAlloc == NULL)
return MEMORY_E;
str = strAlloc;
#endif
XMEMCPY(str, in, len+1);
nb_val = 0;
@@ -34097,7 +34258,7 @@ int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
if (nb_val == 0) {
if (val > 2) {
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(strAlloc, heap, DYNAMIC_TYPE_TMP_BUFFER);
return ASN_OBJECT_ID_E;
}
@@ -34105,12 +34266,12 @@ int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
}
else if (nb_val == 1) {
if (val > 127) {
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(strAlloc, heap, DYNAMIC_TYPE_TMP_BUFFER);
return ASN_OBJECT_ID_E;
}
if (idx > *outSz) {
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(strAlloc, heap, DYNAMIC_TYPE_TMP_BUFFER);
return BUFFER_E;
}
@@ -34129,7 +34290,7 @@ int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
}
if ((idx+(word32)i) >= *outSz) {
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(strAlloc, heap, DYNAMIC_TYPE_TMP_BUFFER);
return BUFFER_E;
}
@@ -34146,7 +34307,7 @@ int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
*outSz = idx;
XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(strAlloc, heap, DYNAMIC_TYPE_TMP_BUFFER);
return 0;
}
#endif /* WOLFSSL_CERT_EXT || OPENSSL_EXTRA */
@@ -38071,13 +38232,13 @@ int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
XMEMSET(req, 0, sizeof(OcspRequest));
req->heap = heap;
#ifdef NO_SHA
req->hashAlg = SHA256h;
#else
req->hashAlg = SHAh;
#endif
req->hashAlg = wc_HashGetOID(OCSP_DIGEST);
if (cert) {
/* CertID.hashAlgorithm names the hash the issuer hashes were made
* with (RFC 6960 4.1.1), which is per certificate in an SM build. */
req->hashAlg = wc_HashGetOID(
wc_HashTypeConvert(HashIdAlg(cert->signatureOID)));
XMEMCPY(req->issuerHash, cert->issuerHash, KEYID_SIZE);
XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);

View File

@@ -1133,6 +1133,8 @@ static WARN_UNUSED_RESULT int Hash_DRBG_Reseed(WC_RNG* rng, const byte* seed,
WOLFSSL_ATOMIC_STORE(rng->nextStirLen,
WC_DRBG_NEXT_SEED_EMPTY);
}
#else
(void)in_bracketed_consume;
#endif
ret = Hash512_DRBG_Reseed(drbg512, seed, seedSz,

View File

@@ -1250,6 +1250,18 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes_cts_test(void);
#endif /* !WC_TEST_EXPORT_SUBTESTS */
/* Declared here too: WC_TEST_EXPORT_SUBTESTS drops the block above. */
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
defined(WOLFSSL_CERT_EXT) && defined(HAVE_ECC) && \
defined(USE_CERT_BUFFERS_256) && !defined(NO_SHA256)
static wc_test_ret_t certreq_no_malloc_test(void);
#endif
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && \
defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) && \
defined(WC_ASN_KEYID_HASH)
static wc_test_ret_t keyid_test(void);
#endif
/* General big buffer size for many tests. */
#define FOURK_BUF 4096
@@ -3430,6 +3442,24 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
TEST_PASS("CERT NOMALLOC test passed!\n");
#endif
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
defined(WOLFSSL_CERT_EXT) && defined(HAVE_ECC) && \
defined(USE_CERT_BUFFERS_256) && !defined(NO_SHA256)
if ( (ret = certreq_no_malloc_test()) != 0)
TEST_FAIL("CERTREQ NOMALLOC test failed!\n", ret);
else
TEST_PASS("CERTREQ NOMALLOC test passed!\n");
#endif
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && \
defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) && \
defined(WC_ASN_KEYID_HASH)
if ( (ret = keyid_test()) != 0)
TEST_FAIL("CERT KEYID test failed!\n", ret);
else
TEST_PASS("CERT KEYID test passed!\n");
#endif
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(WOLFSSL_GEN_CERT)
if ( (ret = certext_test()) != 0)
@@ -39101,6 +39131,148 @@ exit_rsa:
#endif /* !NO_RSA */
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
defined(WOLFSSL_CERT_EXT) && defined(HAVE_ECC) && \
defined(USE_CERT_BUFFERS_256) && !defined(NO_SHA256)
/* Certificate request generation with the Cert on the stack. */
static wc_test_ret_t certreq_no_malloc_test(void)
{
/* Too large for one stack frame (linuxkm caps them at 4kB), and only
* ever one in flight. */
static Cert req;
static ecc_key key;
static byte der[1024];
word32 idx = 0;
int derSz;
wc_test_ret_t ret;
WOLFSSL_ENTER("certreq_no_malloc_test");
ret = wc_ecc_init_ex(&key, HEAP_HINT, devId);
if (ret != 0)
return WC_TEST_RET_ENC_EC(ret);
ret = wc_EccPrivateKeyDecode(ecc_key_der_256, &idx, &key,
(word32)sizeof_ecc_key_der_256);
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
if (ret == 0) {
ret = wc_InitCert_ex(&req, HEAP_HINT, devId);
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
}
if (ret == 0) {
XSTRNCPY(req.subject.country, "US", CTC_NAME_SIZE);
XSTRNCPY(req.subject.org, "wolfSSL", CTC_NAME_SIZE);
XSTRNCPY(req.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
req.version = 0;
req.sigType = CTC_SHA256wECDSA;
/* Covers the EKU string parser and encoder. */
ret = wc_SetExtKeyUsage(&req, "clientAuth,codeSigning");
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
}
if (ret == 0) {
derSz = wc_MakeCertReq_ex(&req, der, (word32)sizeof(der), ECC_TYPE,
&key);
if (derSz <= 0)
ret = WC_TEST_RET_ENC_EC(derSz);
}
#if !defined(NO_ASN_TIME) && !defined(WC_NO_RNG)
/* Policies encode only for a certificate, so EncodePolicyOID() needs
* wc_MakeCert(). */
if (ret == 0) {
static WC_RNG rng;
ret = wc_InitRng_ex(&rng, HEAP_HINT, devId);
if (ret != 0) {
ret = WC_TEST_RET_ENC_EC(ret);
}
else {
XMEMCPY(&req.issuer, &req.subject, sizeof(CertName));
req.selfSigned = 1;
XSTRNCPY(req.certPolicies[0], "2.16.840.1.101.3.4.1.42",
CTC_MAX_CERTPOL_SZ);
req.certPoliciesNb = 1;
derSz = wc_MakeCert(&req, der, (word32)sizeof(der), NULL, &key,
&rng);
if (derSz <= 0)
ret = WC_TEST_RET_ENC_EC(derSz);
wc_FreeRng(&rng);
}
}
#endif
wc_ecc_free(&key);
return ret;
}
#endif /* WOLFSSL_CERT_GEN && WOLFSSL_CERT_REQ && WOLFSSL_CERT_EXT &&
* HAVE_ECC && USE_CERT_BUFFERS_256 && !NO_SHA256 */
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_EXT) && \
defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) && \
defined(WC_ASN_KEYID_HASH)
/* Cert SKID and AKID buffers are sized for the selected key identifier
* hash. */
static wc_test_ret_t keyid_test(void)
{
static Cert cert;
static ecc_key key;
word32 idx = 0;
wc_test_ret_t ret;
WOLFSSL_ENTER("keyid_test");
ret = wc_ecc_init_ex(&key, HEAP_HINT, devId);
if (ret != 0)
return WC_TEST_RET_ENC_EC(ret);
ret = wc_EccPrivateKeyDecode(ecc_key_der_256, &idx, &key,
(word32)sizeof_ecc_key_der_256);
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
if (ret == 0) {
ret = wc_InitCert_ex(&cert, HEAP_HINT, devId);
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
}
if (ret == 0) {
ret = wc_SetSubjectKeyIdFromPublicKey(&cert, NULL, &key);
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
}
if ((ret == 0) && ((cert.skidSz <= 0) ||
(cert.skidSz > (int)CTC_MAX_SKID_SIZE))) {
ret = WC_TEST_RET_ENC_NC;
}
#if !defined(WOLFSSL_SM2) || !defined(WOLFSSL_SM3)
/* SM builds size KEYID_SIZE for SM3 but may use another hash, so only
* check equality in the plain case. */
if ((ret == 0) && (cert.skidSz != (int)KEYID_SIZE))
ret = WC_TEST_RET_ENC_NC;
#endif
if (ret == 0) {
ret = wc_SetAuthKeyIdFromPublicKey(&cert, NULL, &key);
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
}
if ((ret == 0) && ((cert.akidSz <= 0) ||
(cert.akidSz > (int)CTC_MAX_AKID_SIZE))) {
ret = WC_TEST_RET_ENC_NC;
}
if ((ret == 0) && (cert.akidSz != cert.skidSz))
ret = WC_TEST_RET_ENC_NC;
wc_ecc_free(&key);
return ret;
}
#endif /* WOLFSSL_CERT_GEN && WOLFSSL_CERT_EXT && HAVE_ECC &&
* USE_CERT_BUFFERS_256 && WC_ASN_KEYID_HASH */
#if defined(WOLFSSL_TEST_CERT) && defined(HAVE_ECC) && \
!defined(NO_ECC256) && !defined(NO_ECC_SECP)
/* Self-signed P-256 cert with a critical extension of unrecognized OID
@@ -44551,9 +44723,8 @@ static wc_test_ret_t hkdf_test(void)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
#endif
{
wc_test_ret_t ret = 0;
#if !defined(NO_SHA) || !defined(NO_SHA256)
wc_test_ret_t ret = 0;
int L;
byte prk[WC_MAX_DIGEST_SIZE];
byte okm1[42];

View File

@@ -2663,13 +2663,8 @@ struct WOLFSSL_OCSP {
typedef struct CRL_Entry CRL_Entry;
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
#define CRL_DIGEST_SIZE WC_SM3_DIGEST_SIZE
#elif defined(NO_SHA)
#define CRL_DIGEST_SIZE WC_SHA256_DIGEST_SIZE
#else
#define CRL_DIGEST_SIZE WC_SHA_DIGEST_SIZE
#endif
/* DecodeCRL() fills issuerHash with CalcHashId_ex(), the same as a Signer. */
#define CRL_DIGEST_SIZE KEYID_SIZE
#ifdef NO_ASN
typedef struct RevokedCert RevokedCert;

View File

@@ -1365,11 +1365,12 @@ enum Misc_ASN {
ASN_ECC_HEADER_SZ = 2, /* String type + 1 byte len */
ASN_ECC_CONTEXT_SZ = 2, /* Content specific type + 1 byte len */
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
KEYID_SIZE = WC_SM3_DIGEST_SIZE,
#elif defined(NO_SHA) || (!defined(NO_SHA256) && defined(WC_ASN_HASH_SHA256))
KEYID_SIZE = WC_SHA256_DIGEST_SIZE,
/* SM builds use the fallback hash for non-SM signatures; hold the
* larger. */
KEYID_SIZE = (WC_SM3_DIGEST_SIZE > WC_ASN_KEYID_SZ) ?
WC_SM3_DIGEST_SIZE : WC_ASN_KEYID_SZ,
#else
KEYID_SIZE = WC_SHA_DIGEST_SIZE,
KEYID_SIZE = WC_ASN_KEYID_SZ,
#endif
RSA_INTS = 2 /* RSA ints in private key */
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
@@ -1554,7 +1555,8 @@ enum KeyIdType {
#define WOLFSSL_IP6_ADDR_LEN 16
#endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
/* No allocator: reference key/alt-name data in the source DER, not copies. */
/* No allocator: parse by referencing key/alt-name data in the source DER
* rather than copies, and encode from the stack. */
#if defined(WOLFSSL_NO_MALLOC) && defined(NO_WOLFSSL_MEMORY) && \
!defined(XMALLOC_USER) && !defined(WOLFSSL_STATIC_MEMORY)
#define WC_ASN_NO_HEAP
@@ -2320,13 +2322,8 @@ struct DecodedCert {
#endif
};
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
#define SIGNER_DIGEST_SIZE WC_SM3_DIGEST_SIZE
#elif defined(NO_SHA)
#define SIGNER_DIGEST_SIZE WC_SHA256_DIGEST_SIZE
#else
#define SIGNER_DIGEST_SIZE WC_SHA_DIGEST_SIZE
#endif
/* Signer and CRL hashes come from CalcHashId*(). */
#define SIGNER_DIGEST_SIZE KEYID_SIZE
/* CA Signers */
/* if change layout change PERSIST_CERT_CACHE functions too */
@@ -3040,21 +3037,13 @@ struct CertStatus {
typedef struct OcspEntry OcspEntry;
/* A CertID carries cert->issuerHash and issuerKeyHash, so name their hash. */
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
#define OCSP_DIGEST WC_HASH_TYPE_SM3
#elif defined(NO_SHA)
#define OCSP_DIGEST WC_HASH_TYPE_SHA256
#define OCSP_DIGEST WC_HASH_TYPE_SM3
#else
#define OCSP_DIGEST WC_HASH_TYPE_SHA
#endif
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
#define OCSP_DIGEST_SIZE WC_SM3_DIGEST_SIZE
#elif defined(NO_SHA)
#define OCSP_DIGEST_SIZE WC_SHA256_DIGEST_SIZE
#else
#define OCSP_DIGEST_SIZE WC_SHA_DIGEST_SIZE
#define OCSP_DIGEST WC_ASN_KEYID_HASH_TYPE
#endif
#define OCSP_DIGEST_SIZE KEYID_SIZE
struct OcspEntry
{
@@ -3074,11 +3063,8 @@ struct OcspEntry
};
#define OCSP_RESPONDER_ID_KEY_SZ 20
#if !defined(NO_SHA)
#define OCSP_RESPONDER_ID_HASH_TYPE WC_SHA
#else
#define OCSP_RESPONDER_ID_HASH_TYPE WC_SHA256
#endif
/* Passed to CalcHashId_ex() for a responder name. */
#define OCSP_RESPONDER_ID_HASH_TYPE WC_ASN_KEYID_HASH_TYPE
enum responderIdType {
OCSP_RESPONDER_ID_INVALID = 0,
OCSP_RESPONDER_ID_NAME = 1,

View File

@@ -128,6 +128,40 @@ enum EncPkcs8Types {
ENC_PKCS8_ALG_DES3 = 652
};
/* Hash for key identifiers (SKID, AKID, internal name and key hashes), as
* CalcHashId_ex() takes it. SHA-1 for interoperability while it is in the
* build, then SHA-256, then a SHA-3 size. */
#if !defined(NO_SHA256) && (defined(NO_SHA) || defined(WC_ASN_HASH_SHA256))
#define WC_ASN_KEYID_HASH_TYPE WC_HASH_TYPE_SHA256
#define WC_ASN_KEYID_SZ 32 /* WC_SHA256_DIGEST_SIZE */
#elif !defined(NO_SHA)
#define WC_ASN_KEYID_HASH_TYPE WC_HASH_TYPE_SHA
#define WC_ASN_KEYID_SZ 20 /* WC_SHA_DIGEST_SIZE */
#elif defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
#define WC_ASN_KEYID_HASH_TYPE WC_HASH_TYPE_SHA3_256
#define WC_ASN_KEYID_SZ 32 /* WC_SHA3_256_DIGEST_SIZE */
#elif defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
#define WC_ASN_KEYID_HASH_TYPE WC_HASH_TYPE_SHA3_384
#define WC_ASN_KEYID_SZ 48 /* WC_SHA3_384_DIGEST_SIZE */
#else
/* No hash available; the size is only a buffer floor. */
#define WC_ASN_KEYID_HASH_TYPE WC_HASH_TYPE_NONE
#define WC_ASN_KEYID_SZ 32
#endif
/* Set when a key identifier hash is available. */
#if !defined(NO_SHA) || !defined(NO_SHA256) || (defined(WOLFSSL_SHA3) && \
(!defined(WOLFSSL_NOSHA3_256) || !defined(WOLFSSL_NOSHA3_384)))
#define WC_ASN_KEYID_HASH
#endif
/* Cert key identifier buffers: 32-byte floor, widened for a larger hash. */
#if WC_ASN_KEYID_SZ > 32
#define WC_CTC_MAX_KEYID_SIZE WC_ASN_KEYID_SZ
#else
#define WC_CTC_MAX_KEYID_SIZE 32
#endif
/* Certificate file Type */
enum CertType {
CERT_TYPE = 0,
@@ -224,12 +258,12 @@ enum Ctc_Misc {
CTC_FILETYPE_ASN1 = 2,
CTC_FILETYPE_PEM = 1,
CTC_FILETYPE_DEFAULT = 2,
CTC_MAX_CERTPOL_SZ = 200, /* RFC 5280 Section 4.2.1.4 */
#ifdef WOLFSSL_CERT_EXT
/* AKID could contains: hash + (Option) AuthCertIssuer,AuthCertSerialNum
* We support only hash */
CTC_MAX_SKID_SIZE = 32, /* SHA256_DIGEST_SIZE */
CTC_MAX_AKID_SIZE = 32, /* SHA256_DIGEST_SIZE */
CTC_MAX_CERTPOL_SZ = 200, /* RFC 5280 Section 4.2.1.4 */
CTC_MAX_SKID_SIZE = WC_CTC_MAX_KEYID_SIZE,
CTC_MAX_AKID_SIZE = WC_CTC_MAX_KEYID_SIZE,
CTC_MAX_CERTPOL_NB = 2, /* Max number of Certificate Policy */
CTC_MAX_CRLINFO_SZ = WC_CTC_MAX_CRLINFO_SZ, /* Arbitrary size that should be
* enough for at least two

View File

@@ -1305,7 +1305,6 @@ binding for XSNPRINTF
#define XSTRTOK(s1,d,ptr) strtok_r((s1),(d),(ptr))
#endif
#endif
#if defined(WOLFSSL_CERT_EXT) || defined(HAVE_OCSP) || \
defined(HAVE_CRL_IO) || defined(HAVE_HTTP_CLIENT) || \
!defined(NO_CRYPT_BENCHMARK) || defined(OPENSSL_EXTRA)
@@ -1317,6 +1316,19 @@ binding for XSNPRINTF
#endif
#endif /* STRING_USER */
/* The STRING_USER platform templates override the string and memory macros
* but not XATOI, which the certificate policy OID parser and the benchmark
* need. Same features as the case above, so a platform that set STRING_USER
* to keep the standard library out only reaches <stdlib.h> through one that
* cannot work without XATOI, and one that supplies its own still wins. */
#if defined(STRING_USER) && !defined(XATOI) && \
(defined(WOLFSSL_CERT_EXT) || defined(HAVE_OCSP) || \
defined(HAVE_CRL_IO) || defined(HAVE_HTTP_CLIENT) || \
!defined(NO_CRYPT_BENCHMARK) || defined(OPENSSL_EXTRA))
#include <stdlib.h>
#define XATOI(s) atoi((s))
#endif
#ifdef WOLFSSL_WIDE_BYTE
/* Packed octet stream -> one octet per byte cell. All sizes are in byte cells;
* out needs octetSz, in needs WC_PACKED_CELLS(octetSz), and they must not