mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 03:07:29 +02:00
Merge pull request #3697 from julek-wolfssl/openvpn-2.5-missing-stuff
OpenVPN master additions
This commit is contained in:
17
configure.ac
17
configure.ac
@ -3544,6 +3544,18 @@ then
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_FALLBACK_SCSV"
|
||||
fi
|
||||
|
||||
# Exporting Keying Material
|
||||
AC_ARG_ENABLE([keying-material],
|
||||
[AS_HELP_STRING([--enable-keying-material],[Enable Keying Material Exporters (default: disabled)])],
|
||||
[ ENABLED_KEYING_MATERIAL=$enableval ],
|
||||
[ ENABLED_KEYING_MATERIAL=no ]
|
||||
)
|
||||
|
||||
if test "x$ENABLED_KEYING_MATERIAL" = "xyes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_KEYING_MATERIAL"
|
||||
fi
|
||||
|
||||
# Supported Elliptic Curves Extensions
|
||||
AC_ARG_ENABLE([supportedcurves],
|
||||
[AS_HELP_STRING([--enable-supportedcurves],[Enable Supported Elliptic Curves (default: enabled)])],
|
||||
@ -4077,7 +4089,9 @@ fi
|
||||
|
||||
if test "$ENABLED_OPENVPN" = "yes"
|
||||
then
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DES_ECB -DHAVE_EX_DATA -DWOLFSSL_KEY_GEN -DWOLFSSL_OPENVPN"
|
||||
ENABLED_SUPPORTED_CURVES="yes"
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_OPENVPN -DHAVE_KEYING_MATERIAL"
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DES_ECB -DHAVE_EX_DATA -DWOLFSSL_KEY_GEN"
|
||||
fi
|
||||
|
||||
|
||||
@ -6467,6 +6481,7 @@ echo " * Extended Master Secret: $ENABLED_EXTENDED_MASTER"
|
||||
echo " * Renegotiation Indication: $ENABLED_RENEGOTIATION_INDICATION"
|
||||
echo " * Secure Renegotiation: $ENABLED_SECURE_RENEGOTIATION"
|
||||
echo " * Fallback SCSV: $ENABLED_FALLBACK_SCSV"
|
||||
echo " * Keying Material Exporter: $ENABLED_KEYING_MATERIAL"
|
||||
echo " * All TLS Extensions: $ENABLED_TLSX"
|
||||
echo " * PKCS#7 $ENABLED_PKCS7"
|
||||
echo " * S/MIME $ENABLED_SMIME"
|
||||
|
@ -1107,7 +1107,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
WOLFSSL_MEM_STATS mem_stats;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_TLS13
|
||||
#if defined(WOLFSSL_TLS13)
|
||||
int onlyKeyShare = 0;
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET)
|
||||
|
@ -5381,6 +5381,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
|
||||
ssl->pkCurveOID = ctx->pkCurveOID;
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_EXTRA
|
||||
ssl->CBIS = ctx->CBIS;
|
||||
#endif
|
||||
@ -5506,6 +5507,13 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||
}
|
||||
} /* writeDup check */
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
|
||||
if (ctx->mask != 0 && wolfSSL_set_options(ssl, ctx->mask) == 0) {
|
||||
WOLFSSL_MSG("wolfSSL_set_options error");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SESSION_EXPORT
|
||||
#ifdef WOLFSSL_DTLS
|
||||
ssl->dtls_export = ctx->dtls_export; /* export function for session */
|
||||
@ -5801,6 +5809,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_OPENVPN) && defined(HAVE_KEYING_MATERIAL)
|
||||
/* Save arrays by default for OpenVPN */
|
||||
ssl->options.saveArrays = 1;
|
||||
#endif
|
||||
|
||||
ssl->cipher.ssl = ssl;
|
||||
|
||||
|
710
src/ssl.c
710
src/ssl.c
@ -133,6 +133,7 @@
|
||||
int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi);
|
||||
int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi);
|
||||
int oid2nid(word32 oid, int grp);
|
||||
word32 nid2oid(int nid, int grp);
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_QT)
|
||||
@ -2375,13 +2376,10 @@ int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx, byte status_type,
|
||||
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
|
||||
|
||||
/* Elliptic Curves */
|
||||
#if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT)
|
||||
#if defined(HAVE_SUPPORTED_CURVES)
|
||||
|
||||
int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
|
||||
static int isValidCurveGroup(word16 name)
|
||||
{
|
||||
if (ssl == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
switch (name) {
|
||||
case WOLFSSL_ECC_SECP160K1:
|
||||
case WOLFSSL_ECC_SECP160R1:
|
||||
@ -2405,11 +2403,17 @@ int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
|
||||
case WOLFSSL_FFDHE_4096:
|
||||
case WOLFSSL_FFDHE_6144:
|
||||
case WOLFSSL_FFDHE_8192:
|
||||
break;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
|
||||
{
|
||||
if (ssl == NULL || !isValidCurveGroup(name))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
ssl->options.userCurves = 1;
|
||||
|
||||
@ -2419,43 +2423,87 @@ int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
|
||||
|
||||
int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
if (ctx == NULL || !isValidCurveGroup(name))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
switch (name) {
|
||||
case WOLFSSL_ECC_SECP160K1:
|
||||
case WOLFSSL_ECC_SECP160R1:
|
||||
case WOLFSSL_ECC_SECP160R2:
|
||||
case WOLFSSL_ECC_SECP192K1:
|
||||
case WOLFSSL_ECC_SECP192R1:
|
||||
case WOLFSSL_ECC_SECP224K1:
|
||||
case WOLFSSL_ECC_SECP224R1:
|
||||
case WOLFSSL_ECC_SECP256K1:
|
||||
case WOLFSSL_ECC_SECP256R1:
|
||||
case WOLFSSL_ECC_SECP384R1:
|
||||
case WOLFSSL_ECC_SECP521R1:
|
||||
case WOLFSSL_ECC_BRAINPOOLP256R1:
|
||||
case WOLFSSL_ECC_BRAINPOOLP384R1:
|
||||
case WOLFSSL_ECC_BRAINPOOLP512R1:
|
||||
case WOLFSSL_ECC_X25519:
|
||||
case WOLFSSL_ECC_X448:
|
||||
case WOLFSSL_FFDHE_2048:
|
||||
case WOLFSSL_FFDHE_3072:
|
||||
case WOLFSSL_FFDHE_4096:
|
||||
case WOLFSSL_FFDHE_6144:
|
||||
case WOLFSSL_FFDHE_8192:
|
||||
break;
|
||||
|
||||
default:
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
ctx->userCurves = 1;
|
||||
|
||||
return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap);
|
||||
}
|
||||
|
||||
#endif /* HAVE_SUPPORTED_CURVES && !NO_WOLFSSL_CLIENT */
|
||||
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13)
|
||||
int wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups,
|
||||
int count)
|
||||
{
|
||||
int i;
|
||||
int _groups[WOLFSSL_MAX_GROUP_COUNT];
|
||||
WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
|
||||
if (count == 0) {
|
||||
WOLFSSL_MSG("Group count is zero");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
if (isValidCurveGroup((word16)groups[i])) {
|
||||
_groups[i] = groups[i];
|
||||
}
|
||||
#ifdef HAVE_ECC
|
||||
else {
|
||||
/* groups may be populated with curve NIDs */
|
||||
int oid = nid2oid(groups[i], oidCurveType);
|
||||
int name = (int)GetCurveByOID(oid);
|
||||
if (name == 0) {
|
||||
WOLFSSL_MSG("Invalid group name");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
_groups[i] = name;
|
||||
}
|
||||
#else
|
||||
else {
|
||||
WOLFSSL_MSG("Invalid group name");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return wolfSSL_CTX_set_groups(ctx, _groups, count) == WOLFSSL_SUCCESS ?
|
||||
WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
int wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count)
|
||||
{
|
||||
int i;
|
||||
int _groups[WOLFSSL_MAX_GROUP_COUNT];
|
||||
WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
|
||||
if (count == 0) {
|
||||
WOLFSSL_MSG("Group count is zero");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
if (isValidCurveGroup((word16)groups[i])) {
|
||||
_groups[i] = groups[i];
|
||||
}
|
||||
#ifdef HAVE_ECC
|
||||
else {
|
||||
/* groups may be populated with curve NIDs */
|
||||
int oid = nid2oid(groups[i], oidCurveType);
|
||||
int name = (int)GetCurveByOID(oid);
|
||||
if (name == 0) {
|
||||
WOLFSSL_MSG("Invalid group name");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
_groups[i] = name;
|
||||
}
|
||||
#else
|
||||
else {
|
||||
WOLFSSL_MSG("Invalid group name");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return wolfSSL_set_groups(ssl, _groups, count) == WOLFSSL_SUCCESS ?
|
||||
WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA && WOLFSSL_TLS13 */
|
||||
#endif /* HAVE_SUPPORTED_CURVES */
|
||||
|
||||
/* QSH quantum safe handshake */
|
||||
#ifdef HAVE_QSH
|
||||
@ -3163,15 +3211,17 @@ int wolfSSL_want_write(WOLFSSL* ssl)
|
||||
|
||||
char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
|
||||
{
|
||||
static wcchar msg = "Please supply a buffer for error string";
|
||||
static char tmp[WOLFSSL_MAX_ERROR_SZ] = {0};
|
||||
|
||||
WOLFSSL_ENTER("ERR_error_string");
|
||||
if (data) {
|
||||
SetErrorString((int)errNumber, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
return (char*)msg;
|
||||
else {
|
||||
SetErrorString((int)errNumber, tmp);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7662,6 +7712,9 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out,
|
||||
|
||||
return pkey;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("RSA wolfSSL_EVP_PKEY_new error");
|
||||
}
|
||||
}
|
||||
wc_FreeRsaKey(&rsa);
|
||||
}
|
||||
@ -7706,6 +7759,9 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out,
|
||||
|
||||
return pkey;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("ECC wolfSSL_EVP_PKEY_new error");
|
||||
}
|
||||
}
|
||||
wc_ecc_free(&ecc);
|
||||
}
|
||||
@ -7753,6 +7809,9 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out,
|
||||
|
||||
return pkey;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("DSA wolfSSL_EVP_PKEY_new error");
|
||||
}
|
||||
}
|
||||
wc_FreeDsaKey(&dsa);
|
||||
}
|
||||
@ -7801,12 +7860,19 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out,
|
||||
|
||||
return pkey;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("DH wolfSSL_EVP_PKEY_new error");
|
||||
}
|
||||
}
|
||||
wc_FreeDhKey(&dh);
|
||||
}
|
||||
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
|
||||
#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
|
||||
|
||||
if (pkey == NULL) {
|
||||
WOLFSSL_MSG("wolfSSL_d2i_PUBKEY couldn't determine key type");
|
||||
}
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
@ -11860,6 +11926,117 @@ int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_KEYING_MATERIAL
|
||||
|
||||
#define TLS_PRF_LABEL_CLIENT_FINISHED "client finished"
|
||||
#define TLS_PRF_LABEL_SERVER_FINISHED "server finished"
|
||||
#define TLS_PRF_LABEL_MASTER_SECRET "master secret"
|
||||
#define TLS_PRF_LABEL_EXT_MASTER_SECRET "extended master secret"
|
||||
#define TLS_PRF_LABEL_KEY_EXPANSION "key expansion"
|
||||
|
||||
static const struct ForbiddenLabels {
|
||||
const char* label;
|
||||
size_t labelLen;
|
||||
} forbiddenLabels[] = {
|
||||
{TLS_PRF_LABEL_CLIENT_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_CLIENT_FINISHED)},
|
||||
{TLS_PRF_LABEL_SERVER_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_SERVER_FINISHED)},
|
||||
{TLS_PRF_LABEL_MASTER_SECRET, XSTR_SIZEOF(TLS_PRF_LABEL_MASTER_SECRET)},
|
||||
{TLS_PRF_LABEL_EXT_MASTER_SECRET, XSTR_SIZEOF(TLS_PRF_LABEL_EXT_MASTER_SECRET)},
|
||||
{TLS_PRF_LABEL_KEY_EXPANSION, XSTR_SIZEOF(TLS_PRF_LABEL_KEY_EXPANSION)},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
/**
|
||||
* Implement RFC 5705
|
||||
* TLS 1.3 uses a different exporter definition (section 7.5 of RFC 8446)
|
||||
* @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
|
||||
*/
|
||||
int wolfSSL_export_keying_material(WOLFSSL *ssl,
|
||||
unsigned char *out, size_t outLen,
|
||||
const char *label, size_t labelLen,
|
||||
const unsigned char *context, size_t contextLen,
|
||||
int use_context)
|
||||
{
|
||||
byte* seed = NULL;
|
||||
/* clientRandom + serverRandom
|
||||
* OR
|
||||
* clientRandom + serverRandom + ctx len encoding + ctx */
|
||||
word32 seedLen = !use_context ? SEED_LEN : SEED_LEN + 2 + (word32)contextLen;
|
||||
const struct ForbiddenLabels* fl;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_export_keying_material");
|
||||
|
||||
if (ssl == NULL || out == NULL || label == NULL ||
|
||||
(use_context && contextLen && context == NULL)) {
|
||||
WOLFSSL_MSG("Bad argument");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
|
||||
WOLFSSL_MSG("To export keying material wolfSSL needs to keep handshake "
|
||||
"data. Call wolfSSL_KeepArrays before attempting to "
|
||||
"export keyig material.");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
/* check forbidden labels */
|
||||
for (fl = &forbiddenLabels[0]; fl->label != NULL; fl++) {
|
||||
if (labelLen >= fl->labelLen &&
|
||||
XMEMCMP(label, fl->label, fl->labelLen) == 0) {
|
||||
WOLFSSL_MSG("Forbidden label");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if (IsAtLeastTLSv1_3(ssl->version)) {
|
||||
/* Path for TLS 1.3 */
|
||||
if (!use_context) {
|
||||
contextLen = 0;
|
||||
context = (byte*)""; /* Give valid pointer for 0 length memcpy */
|
||||
}
|
||||
|
||||
if (Tls13_Exporter(ssl, out, (word32)outLen, label, labelLen,
|
||||
context, contextLen) != 0) {
|
||||
WOLFSSL_MSG("Tls13_Exporter error");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Path for <=TLS 1.2 */
|
||||
seed = (byte*)XMALLOC(seedLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (seed == NULL) {
|
||||
WOLFSSL_MSG("malloc error");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
|
||||
XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
|
||||
|
||||
if (use_context) {
|
||||
/* Encode len in big endian */
|
||||
seed[SEED_LEN ] = (contextLen >> 8) & 0xFF;
|
||||
seed[SEED_LEN + 1] = (contextLen) & 0xFF;
|
||||
if (contextLen) {
|
||||
/* 0 length context is allowed */
|
||||
XMEMCPY(seed + SEED_LEN + 2, context, contextLen);
|
||||
}
|
||||
}
|
||||
|
||||
if (wc_PRF_TLS(out, (word32)outLen, ssl->arrays->masterSecret, SECRET_LEN,
|
||||
(byte*)label, (word32)labelLen, seed, seedLen, IsAtLeastTLSv1_2(ssl),
|
||||
ssl->specs.mac_algorithm, ssl->heap, ssl->devId) != 0) {
|
||||
WOLFSSL_MSG("wc_PRF_TLS error");
|
||||
XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#endif /* HAVE_KEYING_MATERIAL */
|
||||
|
||||
int wolfSSL_dtls_get_using_nonblock(WOLFSSL* ssl)
|
||||
{
|
||||
@ -16341,18 +16518,15 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
switch (version) {
|
||||
#ifndef NO_TLS
|
||||
case TLS1_3_VERSION:
|
||||
#ifdef WOLFSSL_TLS13
|
||||
wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
|
||||
FALL_THROUGH;
|
||||
#else
|
||||
WOLFSSL_MSG("wolfSSL TLS1.3 support not compiled in");
|
||||
return WOLFSSL_FAILURE;
|
||||
#endif
|
||||
case TLS1_2_VERSION:
|
||||
wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
|
||||
FALL_THROUGH;
|
||||
@ -16361,11 +16535,13 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
|
||||
FALL_THROUGH;
|
||||
case TLS1_VERSION:
|
||||
wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_SSLv3);
|
||||
FALL_THROUGH;
|
||||
break;
|
||||
#endif
|
||||
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
|
||||
case SSL3_VERSION:
|
||||
FALL_THROUGH;
|
||||
case SSL2_VERSION:
|
||||
/* Nothing to do here */
|
||||
#endif
|
||||
break;
|
||||
#ifdef WOLFSSL_DTLS
|
||||
#ifndef NO_OLD_TLS
|
||||
@ -16375,7 +16551,7 @@ int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
WOLFSSL_MSG("Unrecognized protocol version");
|
||||
WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
@ -16395,6 +16571,7 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver)
|
||||
case SSL2_VERSION:
|
||||
WOLFSSL_MSG("wolfSSL does not support SSLv2");
|
||||
return WOLFSSL_FAILURE;
|
||||
#if (defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)) || !defined(NO_TLS)
|
||||
case SSL3_VERSION:
|
||||
wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
|
||||
FALL_THROUGH;
|
||||
@ -16406,12 +16583,11 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver)
|
||||
FALL_THROUGH;
|
||||
case TLS1_2_VERSION:
|
||||
wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_3);
|
||||
#ifdef WOLFSSL_TLS13
|
||||
FALL_THROUGH;
|
||||
case TLS1_3_VERSION:
|
||||
/* Nothing to do here */
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_DTLS
|
||||
#ifndef NO_OLD_TLS
|
||||
case DTLS1_VERSION:
|
||||
@ -16420,7 +16596,7 @@ int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int ver)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
WOLFSSL_MSG("Unrecognized protocol version");
|
||||
WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
@ -20838,6 +21014,26 @@ WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WOLFSSL_X509* wolfSSL_CTX_get0_certificate(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
if (ctx) {
|
||||
if (ctx->ourCert == NULL) {
|
||||
if (ctx->certificate == NULL) {
|
||||
WOLFSSL_MSG("Ctx Certificate buffer not set!");
|
||||
return NULL;
|
||||
}
|
||||
#ifndef WOLFSSL_X509_STORE_CERTS
|
||||
ctx->ourCert = wolfSSL_X509_d2i(NULL,
|
||||
ctx->certificate->buffer,
|
||||
ctx->certificate->length);
|
||||
#endif
|
||||
ctx->ownOurCert = 1;
|
||||
}
|
||||
return ctx->ourCert;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA && KEEP_OUR_CERT */
|
||||
#endif /* NO_CERTS */
|
||||
|
||||
@ -27313,10 +27509,11 @@ long wolfSSL_set_options(WOLFSSL* ssl, long op)
|
||||
keySz = ssl->buffers.keySz;
|
||||
#endif
|
||||
|
||||
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
|
||||
ssl->options.haveDH, ssl->options.haveNTRU,
|
||||
ssl->options.haveECDSAsig, ssl->options.haveECC,
|
||||
ssl->options.haveStaticECC, ssl->options.side);
|
||||
if (ssl->suites != NULL && ssl->options.side != WOLFSSL_NEITHER_END)
|
||||
InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
|
||||
ssl->options.haveDH, ssl->options.haveNTRU,
|
||||
ssl->options.haveECDSAsig, ssl->options.haveECC,
|
||||
ssl->options.haveStaticECC, ssl->options.side);
|
||||
|
||||
return ssl->options.mask;
|
||||
}
|
||||
@ -28291,16 +28488,11 @@ WOLFSSL_API int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str,
|
||||
}
|
||||
#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
|
||||
|
||||
#ifndef NO_WOLFSSL_STUB
|
||||
/*** TBD ***/
|
||||
WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(void *ciphers, int idx)
|
||||
WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(WOLFSSL_STACK* sk, int i)
|
||||
{
|
||||
(void)ciphers;
|
||||
(void)idx;
|
||||
WOLFSSL_STUB("wolfSSL_sk_SSL_CIPHER_value");
|
||||
return NULL;
|
||||
WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_value");
|
||||
return (WOLFSSL_CIPHER*)wolfSSL_sk_value(sk, i);
|
||||
}
|
||||
#endif
|
||||
|
||||
WOLFSSL_API void ERR_load_SSL_strings(void)
|
||||
{
|
||||
@ -30523,6 +30715,12 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = {
|
||||
#ifndef NO_DH
|
||||
{ NID_dhKeyAgreement, DHk, oidKeyType, "dhKeyAgreement", "dhKeyAgreement"},
|
||||
#endif
|
||||
#ifdef HAVE_ED448
|
||||
{ NID_ED448, ED448k, oidKeyType, "ED448", "ED448"},
|
||||
#endif
|
||||
#ifdef HAVE_ED25519
|
||||
{ NID_ED25519, ED25519k, oidKeyType, "ED25519", "ED25519"},
|
||||
#endif
|
||||
|
||||
/* oidCurveType */
|
||||
#ifdef HAVE_ECC
|
||||
@ -35098,8 +35296,7 @@ int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, char *list)
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
return wolfSSL_CTX_set_groups(ctx, groups, count) == WOLFSSL_SUCCESS ?
|
||||
WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
|
||||
return wolfSSL_CTX_set1_groups(ctx, groups, count);
|
||||
}
|
||||
|
||||
int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list)
|
||||
@ -35116,8 +35313,7 @@ int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list)
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
return wolfSSL_set_groups(ssl, groups, count) == WOLFSSL_SUCCESS ?
|
||||
WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
|
||||
return wolfSSL_set1_groups(ssl, groups, count);
|
||||
}
|
||||
#endif /* WOLFSSL_TLS13 */
|
||||
|
||||
@ -46733,6 +46929,44 @@ static WC_INLINE int SCSV_Check(byte suite0, byte suite)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static WC_INLINE int sslCipherMinMaxCheck(const WOLFSSL *ssl, byte suite0,
|
||||
byte suite)
|
||||
{
|
||||
const CipherSuiteInfo* cipher_names = GetCipherNames();
|
||||
int cipherSz = GetCipherNamesSize();
|
||||
int i;
|
||||
for (i = 0; i < cipherSz; i++)
|
||||
if (cipher_names[i].cipherSuite0 == suite0 &&
|
||||
cipher_names[i].cipherSuite == suite)
|
||||
break;
|
||||
if (i == cipherSz)
|
||||
return 1;
|
||||
/* Check min version */
|
||||
if (cipher_names[i].minor < ssl->options.minDowngrade) {
|
||||
if (ssl->options.minDowngrade <= TLSv1_2_MINOR &&
|
||||
cipher_names[i].minor >= TLSv1_MINOR)
|
||||
/* 1.0 ciphersuites are in general available in 1.1 and
|
||||
* 1.1 ciphersuites are in general available in 1.2 */
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
/* Check max version */
|
||||
switch (cipher_names[i].minor) {
|
||||
case SSLv3_MINOR :
|
||||
return ssl->options.mask & WOLFSSL_OP_NO_SSLv3;
|
||||
case TLSv1_MINOR :
|
||||
return ssl->options.mask & WOLFSSL_OP_NO_TLSv1;
|
||||
case TLSv1_1_MINOR :
|
||||
return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1;
|
||||
case TLSv1_2_MINOR :
|
||||
return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2;
|
||||
case TLSv1_3_MINOR :
|
||||
return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3;
|
||||
default:
|
||||
WOLFSSL_MSG("Unrecognized minor version");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* returns a pointer to internal cipher suite list. Should not be free'd by
|
||||
* caller.
|
||||
@ -46752,6 +46986,11 @@ WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl)
|
||||
}
|
||||
|
||||
if (ssl->suites != NULL) {
|
||||
if (ssl->suites->suiteSz == 0 &&
|
||||
InitSSL_Suites((WOLFSSL*)ssl) != WOLFSSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Suite initialization failure");
|
||||
return NULL;
|
||||
}
|
||||
suites = ssl->suites;
|
||||
}
|
||||
else {
|
||||
@ -46769,7 +47008,9 @@ WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl)
|
||||
|
||||
/* A couple of suites are placeholders for special options,
|
||||
* skip those. */
|
||||
if (SCSV_Check(suites->suites[i], suites->suites[i+1])) {
|
||||
if (SCSV_Check(suites->suites[i], suites->suites[i+1])
|
||||
|| sslCipherMinMaxCheck(ssl, suites->suites[i],
|
||||
suites->suites[i+1])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -48192,6 +48433,339 @@ int wolfSSL_set_alpn_protos(WOLFSSL* ssl,
|
||||
#include "src/bio.c"
|
||||
#endif
|
||||
|
||||
word32 nid2oid(int nid, int grp)
|
||||
{
|
||||
/* get OID type */
|
||||
switch (grp) {
|
||||
/* oidHashType */
|
||||
case oidHashType:
|
||||
switch (nid) {
|
||||
#ifdef WOLFSSL_MD2
|
||||
case NID_md2:
|
||||
return MD2h;
|
||||
#endif
|
||||
#ifndef NO_MD5
|
||||
case NID_md5:
|
||||
return MD5h;
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
case NID_sha1:
|
||||
return SHAh;
|
||||
#endif
|
||||
case NID_sha224:
|
||||
return SHA224h;
|
||||
#ifndef NO_SHA256
|
||||
case NID_sha256:
|
||||
return SHA256h;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case NID_sha384:
|
||||
return SHA384h;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case NID_sha512:
|
||||
return SHA512h;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
/* oidSigType */
|
||||
case oidSigType:
|
||||
switch (nid) {
|
||||
#ifndef NO_DSA
|
||||
case CTC_SHAwDSA:
|
||||
return CTC_SHAwDSA;
|
||||
#endif /* NO_DSA */
|
||||
#ifndef NO_RSA
|
||||
case CTC_MD2wRSA:
|
||||
return CTC_MD2wRSA;
|
||||
case CTC_MD5wRSA:
|
||||
return CTC_MD5wRSA;
|
||||
case CTC_SHAwRSA:
|
||||
return CTC_SHAwRSA;
|
||||
case CTC_SHA224wRSA:
|
||||
return CTC_SHA224wRSA;
|
||||
case CTC_SHA256wRSA:
|
||||
return CTC_SHA256wRSA;
|
||||
case CTC_SHA384wRSA:
|
||||
return CTC_SHA384wRSA;
|
||||
case CTC_SHA512wRSA:
|
||||
return CTC_SHA512wRSA;
|
||||
#endif /* NO_RSA */
|
||||
#ifdef HAVE_ECC
|
||||
case CTC_SHAwECDSA:
|
||||
return CTC_SHAwECDSA;
|
||||
case CTC_SHA224wECDSA:
|
||||
return CTC_SHA224wECDSA;
|
||||
case CTC_SHA256wECDSA:
|
||||
return CTC_SHA256wECDSA;
|
||||
case CTC_SHA384wECDSA:
|
||||
return CTC_SHA384wECDSA;
|
||||
case CTC_SHA512wECDSA:
|
||||
return CTC_SHA512wECDSA;
|
||||
#endif /* HAVE_ECC */
|
||||
}
|
||||
break;
|
||||
|
||||
/* oidKeyType */
|
||||
case oidKeyType:
|
||||
switch (nid) {
|
||||
#ifndef NO_DSA
|
||||
case DSAk:
|
||||
return DSAk;
|
||||
#endif /* NO_DSA */
|
||||
#ifndef NO_RSA
|
||||
case RSAk:
|
||||
return RSAk;
|
||||
#endif /* NO_RSA */
|
||||
#ifdef HAVE_NTRU
|
||||
case NTRUk:
|
||||
return NTRUk;
|
||||
#endif /* HAVE_NTRU */
|
||||
#ifdef HAVE_ECC
|
||||
case ECDSAk:
|
||||
return ECDSAk;
|
||||
#endif /* HAVE_ECC */
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
case oidCurveType:
|
||||
switch (nid) {
|
||||
case NID_X9_62_prime192v1:
|
||||
return ECC_SECP192R1_OID;
|
||||
case NID_X9_62_prime192v2:
|
||||
return ECC_PRIME192V2_OID;
|
||||
case NID_X9_62_prime192v3:
|
||||
return ECC_PRIME192V3_OID;
|
||||
case NID_X9_62_prime239v1:
|
||||
return ECC_PRIME239V1_OID;
|
||||
case NID_X9_62_prime239v2:
|
||||
return ECC_PRIME239V2_OID;
|
||||
case NID_X9_62_prime239v3:
|
||||
return ECC_PRIME239V3_OID;
|
||||
case NID_X9_62_prime256v1:
|
||||
return ECC_SECP256R1_OID;
|
||||
case NID_secp112r1:
|
||||
return ECC_SECP112R1_OID;
|
||||
case NID_secp112r2:
|
||||
return ECC_SECP112R2_OID;
|
||||
case NID_secp128r1:
|
||||
return ECC_SECP128R1_OID;
|
||||
case NID_secp128r2:
|
||||
return ECC_SECP128R2_OID;
|
||||
case NID_secp160r1:
|
||||
return ECC_SECP160R1_OID;
|
||||
case NID_secp160r2:
|
||||
return ECC_SECP160R2_OID;
|
||||
case NID_secp224r1:
|
||||
return ECC_SECP224R1_OID;
|
||||
case NID_secp384r1:
|
||||
return ECC_SECP384R1_OID;
|
||||
case NID_secp521r1:
|
||||
return ECC_SECP521R1_OID;
|
||||
case NID_secp160k1:
|
||||
return ECC_SECP160K1_OID;
|
||||
case NID_secp192k1:
|
||||
return ECC_SECP192K1_OID;
|
||||
case NID_secp224k1:
|
||||
return ECC_SECP224K1_OID;
|
||||
case NID_secp256k1:
|
||||
return ECC_SECP256K1_OID;
|
||||
case NID_brainpoolP160r1:
|
||||
return ECC_BRAINPOOLP160R1_OID;
|
||||
case NID_brainpoolP192r1:
|
||||
return ECC_BRAINPOOLP192R1_OID;
|
||||
case NID_brainpoolP224r1:
|
||||
return ECC_BRAINPOOLP224R1_OID;
|
||||
case NID_brainpoolP256r1:
|
||||
return ECC_BRAINPOOLP256R1_OID;
|
||||
case NID_brainpoolP320r1:
|
||||
return ECC_BRAINPOOLP320R1_OID;
|
||||
case NID_brainpoolP384r1:
|
||||
return ECC_BRAINPOOLP384R1_OID;
|
||||
case NID_brainpoolP512r1:
|
||||
return ECC_BRAINPOOLP512R1_OID;
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
/* oidBlkType */
|
||||
case oidBlkType:
|
||||
switch (nid) {
|
||||
#ifdef WOLFSSL_AES_128
|
||||
case AES128CBCb:
|
||||
return AES128CBCb;
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_192
|
||||
case AES192CBCb:
|
||||
return AES192CBCb;
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_256
|
||||
case AES256CBCb:
|
||||
return AES256CBCb;
|
||||
#endif
|
||||
#ifndef NO_DES3
|
||||
case NID_des:
|
||||
return DESb;
|
||||
case NID_des3:
|
||||
return DES3b;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
case oidOcspType:
|
||||
switch (nid) {
|
||||
case NID_id_pkix_OCSP_basic:
|
||||
return OCSP_BASIC_OID;
|
||||
case OCSP_NONCE_OID:
|
||||
return OCSP_NONCE_OID;
|
||||
}
|
||||
break;
|
||||
#endif /* HAVE_OCSP */
|
||||
|
||||
/* oidCertExtType */
|
||||
case oidCertExtType:
|
||||
switch (nid) {
|
||||
case BASIC_CA_OID:
|
||||
return BASIC_CA_OID;
|
||||
case ALT_NAMES_OID:
|
||||
return ALT_NAMES_OID;
|
||||
case CRL_DIST_OID:
|
||||
return CRL_DIST_OID;
|
||||
case AUTH_INFO_OID:
|
||||
return AUTH_INFO_OID;
|
||||
case AUTH_KEY_OID:
|
||||
return AUTH_KEY_OID;
|
||||
case SUBJ_KEY_OID:
|
||||
return SUBJ_KEY_OID;
|
||||
case INHIBIT_ANY_OID:
|
||||
return INHIBIT_ANY_OID;
|
||||
case NID_key_usage:
|
||||
return KEY_USAGE_OID;
|
||||
case NID_name_constraints:
|
||||
return NAME_CONS_OID;
|
||||
case NID_certificate_policies:
|
||||
return CERT_POLICY_OID;
|
||||
}
|
||||
break;
|
||||
|
||||
/* oidCertAuthInfoType */
|
||||
case oidCertAuthInfoType:
|
||||
switch (nid) {
|
||||
case AIA_OCSP_OID:
|
||||
return AIA_OCSP_OID;
|
||||
case AIA_CA_ISSUER_OID:
|
||||
return AIA_CA_ISSUER_OID;
|
||||
}
|
||||
break;
|
||||
|
||||
/* oidCertPolicyType */
|
||||
case oidCertPolicyType:
|
||||
switch (nid) {
|
||||
case NID_any_policy:
|
||||
return CP_ANY_OID;
|
||||
}
|
||||
break;
|
||||
|
||||
/* oidCertAltNameType */
|
||||
case oidCertAltNameType:
|
||||
switch (nid) {
|
||||
case NID_hw_name_oid:
|
||||
return HW_NAME_OID;
|
||||
}
|
||||
break;
|
||||
|
||||
/* oidCertKeyUseType */
|
||||
case oidCertKeyUseType:
|
||||
switch (nid) {
|
||||
case NID_anyExtendedKeyUsage:
|
||||
return EKU_ANY_OID;
|
||||
case EKU_SERVER_AUTH_OID:
|
||||
return EKU_SERVER_AUTH_OID;
|
||||
case EKU_CLIENT_AUTH_OID:
|
||||
return EKU_CLIENT_AUTH_OID;
|
||||
case EKU_OCSP_SIGN_OID:
|
||||
return EKU_OCSP_SIGN_OID;
|
||||
}
|
||||
break;
|
||||
|
||||
/* oidKdfType */
|
||||
case oidKdfType:
|
||||
switch (nid) {
|
||||
case PBKDF2_OID:
|
||||
return PBKDF2_OID;
|
||||
}
|
||||
break;
|
||||
|
||||
/* oidPBEType */
|
||||
case oidPBEType:
|
||||
switch (nid) {
|
||||
case PBE_SHA1_RC4_128:
|
||||
return PBE_SHA1_RC4_128;
|
||||
case PBE_SHA1_DES:
|
||||
return PBE_SHA1_DES;
|
||||
case PBE_SHA1_DES3:
|
||||
return PBE_SHA1_DES3;
|
||||
}
|
||||
break;
|
||||
|
||||
/* oidKeyWrapType */
|
||||
case oidKeyWrapType:
|
||||
switch (nid) {
|
||||
#ifdef WOLFSSL_AES_128
|
||||
case AES128_WRAP:
|
||||
return AES128_WRAP;
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_192
|
||||
case AES192_WRAP:
|
||||
return AES192_WRAP;
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_256
|
||||
case AES256_WRAP:
|
||||
return AES256_WRAP;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
/* oidCmsKeyAgreeType */
|
||||
case oidCmsKeyAgreeType:
|
||||
switch (nid) {
|
||||
#ifndef NO_SHA
|
||||
case dhSinglePass_stdDH_sha1kdf_scheme:
|
||||
return dhSinglePass_stdDH_sha1kdf_scheme;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case dhSinglePass_stdDH_sha224kdf_scheme:
|
||||
return dhSinglePass_stdDH_sha224kdf_scheme;
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case dhSinglePass_stdDH_sha256kdf_scheme:
|
||||
return dhSinglePass_stdDH_sha256kdf_scheme;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case dhSinglePass_stdDH_sha384kdf_scheme:
|
||||
return dhSinglePass_stdDH_sha384kdf_scheme;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case dhSinglePass_stdDH_sha512kdf_scheme:
|
||||
return dhSinglePass_stdDH_sha512kdf_scheme;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("NID not in table");
|
||||
/* MSVC warns without the cast */
|
||||
return (word32)-1;
|
||||
}
|
||||
|
||||
/* MSVC warns without the cast */
|
||||
return (word32)-1;
|
||||
}
|
||||
|
||||
int oid2nid(word32 oid, int grp)
|
||||
{
|
||||
size_t i;
|
||||
|
178
src/tls13.c
178
src/tls13.c
@ -29,9 +29,8 @@
|
||||
* Enables session tickets - required for TLS 1.3 resumption.
|
||||
* NO_PSK
|
||||
* Do not enable Pre-Shared Keys.
|
||||
* TLS13_SUPPORTS_EXPORTERS
|
||||
* Guard to compile out any code for exporter keys.
|
||||
* Feature not supported yet.
|
||||
* HAVE_KEYING_MATERIAL
|
||||
* Enables exporting keying material based on section 7.5 of RFC 8446.
|
||||
* WOLFSSL_ASYNC_CRYPT
|
||||
* Enables the use of asynchronous cryptographic operations.
|
||||
* This is available for ciphers and certificates.
|
||||
@ -515,7 +514,7 @@ static int DeriveEarlyTrafficSecret(WOLFSSL* ssl, byte* key)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef TLS13_SUPPORTS_EXPORTERS
|
||||
#ifdef HAVE_KEYING_MATERIAL
|
||||
/* The length of the early exporter label. */
|
||||
#define EARLY_EXPORTER_LABEL_SZ 12
|
||||
/* The early exporter label. */
|
||||
@ -688,7 +687,7 @@ static int DeriveServerTrafficSecret(WOLFSSL* ssl, byte* key)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef TLS13_SUPPORTS_EXPORTERS
|
||||
#ifdef HAVE_KEYING_MATERIAL
|
||||
/* The length of the exporter master secret label. */
|
||||
#define EXPORTER_MASTER_LABEL_SZ 10
|
||||
/* The exporter master secret label. */
|
||||
@ -704,7 +703,7 @@ static const byte exporterMasterLabel[EXPORTER_MASTER_LABEL_SZ + 1] =
|
||||
static int DeriveExporterSecret(WOLFSSL* ssl, byte* key)
|
||||
{
|
||||
int ret;
|
||||
WOLFSSL_MSG("Derive Exporter Secret");
|
||||
WOLFSSL_ENTER("Derive Exporter Secret");
|
||||
if (ssl == NULL || ssl->arrays == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
@ -722,6 +721,104 @@ static int DeriveExporterSecret(WOLFSSL* ssl, byte* key)
|
||||
#endif /* HAVE_SECRET_CALLBACK */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The length of the exporter label. */
|
||||
#define EXPORTER_LABEL_SZ 8
|
||||
/* The exporter label. */
|
||||
static const byte exporterLabel[EXPORTER_LABEL_SZ + 1] =
|
||||
"exporter";
|
||||
/* Hash("") */
|
||||
#ifndef NO_SHA256
|
||||
static const byte emptySHA256Hash[] = {
|
||||
0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8,
|
||||
0x99, 0x6F, 0xB9, 0x24, 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C,
|
||||
0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55
|
||||
};
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
static const byte emptySHA384Hash[] = {
|
||||
0x38, 0xB0, 0x60, 0xA7, 0x51, 0xAC, 0x96, 0x38, 0x4C, 0xD9, 0x32, 0x7E,
|
||||
0xB1, 0xB1, 0xE3, 0x6A, 0x21, 0xFD, 0xB7, 0x11, 0x14, 0xBE, 0x07, 0x43,
|
||||
0x4C, 0x0C, 0xC7, 0xBF, 0x63, 0xF6, 0xE1, 0xDA, 0x27, 0x4E, 0xDE, 0xBF,
|
||||
0xE7, 0x6F, 0x65, 0xFB, 0xD5, 0x1A, 0xD2, 0xF1, 0x48, 0x98, 0xB9, 0x5B
|
||||
};
|
||||
#endif
|
||||
#ifdef WOLFSSL_TLS13_SHA512
|
||||
static const byte emptySHA512Hash[] = {
|
||||
0xCF, 0x83, 0xE1, 0x35, 0x7E, 0xEF, 0xB8, 0xBD, 0xF1, 0x54, 0x28, 0x50,
|
||||
0xD6, 0x6D, 0x80, 0x07, 0xD6, 0x20, 0xE4, 0x05, 0x0B, 0x57, 0x15, 0xDC,
|
||||
0x83, 0xF4, 0xA9, 0x21, 0xD3, 0x6C, 0xE9, 0xCE, 0x47, 0xD0, 0xD1, 0x3C,
|
||||
0x5D, 0x85, 0xF2, 0xB0, 0xFF, 0x83, 0x18, 0xD2, 0x87, 0x7E, 0xEC, 0x2F,
|
||||
0x63, 0xB9, 0x31, 0xBD, 0x47, 0x41, 0x7A, 0x81, 0xA5, 0x38, 0x32, 0x7A,
|
||||
0xF9, 0x27, 0xDA, 0x3E
|
||||
};
|
||||
#endif
|
||||
/**
|
||||
* Implement section 7.5 of RFC 8446
|
||||
* @return 0 on success
|
||||
* <0 on failure
|
||||
*/
|
||||
int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen,
|
||||
const char *label, size_t labelLen,
|
||||
const unsigned char *context, size_t contextLen)
|
||||
{
|
||||
int ret;
|
||||
enum wc_HashType hashType = WC_HASH_TYPE_NONE;
|
||||
int hashLen = 0;
|
||||
byte hashOut[WC_MAX_DIGEST_SIZE];
|
||||
const byte* emptyHash = NULL;
|
||||
byte firstExpand[WC_MAX_DIGEST_SIZE];
|
||||
const byte* protocol = tls13ProtocolLabel;
|
||||
word32 protocolLen = TLS13_PROTOCOL_LABEL_SZ;
|
||||
|
||||
if (ssl->version.minor != TLSv1_3_MINOR)
|
||||
return VERSION_ERROR;
|
||||
|
||||
switch (ssl->specs.mac_algorithm) {
|
||||
#ifndef NO_SHA256
|
||||
case sha256_mac:
|
||||
hashType = WC_SHA256;
|
||||
hashLen = WC_SHA256_DIGEST_SIZE;
|
||||
emptyHash = emptySHA256Hash;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case sha384_mac:
|
||||
hashType = WC_SHA384;
|
||||
hashLen = WC_SHA384_DIGEST_SIZE;
|
||||
emptyHash = emptySHA384Hash;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13_SHA512
|
||||
case sha512_mac:
|
||||
hashType = WC_SHA512;
|
||||
hashLen = WC_SHA512_DIGEST_SIZE;
|
||||
emptyHash = emptySHA512Hash;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Derive-Secret(Secret, label, "") */
|
||||
ret = HKDF_Expand_Label(firstExpand, hashLen,
|
||||
ssl->arrays->exporterSecret, hashLen,
|
||||
protocol, protocolLen, (byte*)label, (word32)labelLen,
|
||||
emptyHash, hashLen, hashType);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* Hash(context_value) */
|
||||
ret = wc_Hash(hashType, context, (word32)contextLen, hashOut, WC_MAX_DIGEST_SIZE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = HKDF_Expand_Label(out, (word32)outLen, firstExpand, hashLen,
|
||||
protocol, protocolLen, exporterLabel, EXPORTER_LABEL_SZ,
|
||||
hashOut, hashLen, hashType);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
@ -862,9 +959,19 @@ int DeriveMasterSecret(WOLFSSL* ssl)
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return Tls13_HKDF_Extract(ssl->arrays->masterSecret,
|
||||
ret = Tls13_HKDF_Extract(ssl->arrays->masterSecret,
|
||||
key, ssl->specs.hash_size,
|
||||
ssl->arrays->masterSecret, 0, ssl->specs.mac_algorithm);
|
||||
|
||||
#ifdef HAVE_KEYING_MATERIAL
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
/* Calculate exporter secret only when saving arrays */
|
||||
if (ssl->options.saveArrays)
|
||||
ret = DeriveExporterSecret(ssl, ssl->arrays->exporterSecret);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(HAVE_SESSION_TICKET)
|
||||
@ -7477,6 +7584,15 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||
}
|
||||
}
|
||||
|
||||
if (!ssl->options.tls1_3) {
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
if (ssl->options.downgrade)
|
||||
return wolfSSL_connect(ssl);
|
||||
#endif
|
||||
WOLFSSL_MSG("Client using higher version, fatal error");
|
||||
return VERSION_ERROR;
|
||||
}
|
||||
|
||||
ssl->options.connectState = HELLO_AGAIN;
|
||||
WOLFSSL_MSG("connect state: HELLO_AGAIN");
|
||||
FALL_THROUGH;
|
||||
@ -7485,16 +7601,6 @@ int wolfSSL_connect_TLSv13(WOLFSSL* ssl)
|
||||
if (ssl->options.certOnly)
|
||||
return WOLFSSL_SUCCESS;
|
||||
|
||||
if (!ssl->options.tls1_3) {
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
if (ssl->options.downgrade)
|
||||
return wolfSSL_connect(ssl);
|
||||
#endif
|
||||
|
||||
WOLFSSL_MSG("Client using higher version, fatal error");
|
||||
return VERSION_ERROR;
|
||||
}
|
||||
|
||||
if (ssl->options.serverState ==
|
||||
SERVER_HELLO_RETRY_REQUEST_COMPLETE) {
|
||||
#if defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT)
|
||||
@ -7964,7 +8070,7 @@ int wolfSSL_preferred_group(WOLFSSL* ssl)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
#if defined(HAVE_SUPPORTED_CURVES)
|
||||
/* Sets the key exchange groups in rank order on a context.
|
||||
*
|
||||
* ctx SSL/TLS context object.
|
||||
@ -7975,15 +8081,26 @@ int wolfSSL_preferred_group(WOLFSSL* ssl)
|
||||
*/
|
||||
int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups, int count)
|
||||
{
|
||||
int i;
|
||||
int ret, i;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_CTX_set_groups");
|
||||
if (ctx == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
|
||||
return BAD_FUNC_ARG;
|
||||
if (!IsAtLeastTLSv1_3(ctx->method->version))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
ctx->group[i] = (word16)groups[i];
|
||||
ctx->numGroups = 0;
|
||||
TLSX_Remove(&ctx->extensions, TLSX_SUPPORTED_GROUPS, ctx->heap);
|
||||
for (i = 0; i < count; i++) {
|
||||
/* Call to wolfSSL_CTX_UseSupportedCurve also checks if input groups
|
||||
* are valid */
|
||||
if ((ret = wolfSSL_CTX_UseSupportedCurve(ctx, groups[i]))
|
||||
!= WOLFSSL_SUCCESS) {
|
||||
TLSX_Remove(&ctx->extensions, TLSX_SUPPORTED_GROUPS, ctx->heap);
|
||||
return ret;
|
||||
}
|
||||
ctx->group[i] = groups[i];
|
||||
}
|
||||
ctx->numGroups = (byte)count;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
@ -7999,20 +8116,31 @@ int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups, int count)
|
||||
*/
|
||||
int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count)
|
||||
{
|
||||
int i;
|
||||
int ret, i;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_set_groups");
|
||||
if (ssl == NULL || groups == NULL || count > WOLFSSL_MAX_GROUP_COUNT)
|
||||
return BAD_FUNC_ARG;
|
||||
if (!IsAtLeastTLSv1_3(ssl->version))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
ssl->group[i] = (word16)groups[i];
|
||||
ssl->numGroups = 0;
|
||||
TLSX_Remove(&ssl->extensions, TLSX_SUPPORTED_GROUPS, ssl->heap);
|
||||
for (i = 0; i < count; i++) {
|
||||
/* Call to wolfSSL_UseSupportedCurve also checks if input groups
|
||||
* are valid */
|
||||
if ((ret = wolfSSL_UseSupportedCurve(ssl, groups[i]))
|
||||
!= WOLFSSL_SUCCESS) {
|
||||
TLSX_Remove(&ssl->extensions, TLSX_SUPPORTED_GROUPS, ssl->heap);
|
||||
return ret;
|
||||
}
|
||||
ssl->group[i] = groups[i];
|
||||
}
|
||||
ssl->numGroups = (byte)count;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_SUPPORTED_CURVES */
|
||||
|
||||
#ifndef NO_PSK
|
||||
void wolfSSL_CTX_set_psk_client_tls13_callback(WOLFSSL_CTX* ctx,
|
||||
|
115
tests/api.c
115
tests/api.c
@ -5030,6 +5030,7 @@ static void test_wolfSSL_PKCS12(void)
|
||||
AssertNotNull(tmp_ca);
|
||||
AssertIntEQ(sk_X509_num(tmp_ca), sk_X509_num(ca));
|
||||
/* Check that the main cert is also set */
|
||||
AssertNotNull(SSL_CTX_get0_certificate(ctx));
|
||||
AssertNotNull(ssl = SSL_new(ctx));
|
||||
AssertNotNull(SSL_get_certificate(ssl));
|
||||
SSL_free(ssl);
|
||||
@ -27071,6 +27072,12 @@ static void test_wolfSSL_EVP_MD_size(void)
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA_BLOCK_SIZE);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
|
||||
|
||||
wolfSSL_EVP_MD_CTX_init(&mdCtx);
|
||||
|
||||
AssertIntEQ(wolfSSL_EVP_DigestInit(&mdCtx, "SHA1"), 1);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_size(&mdCtx), WC_SHA_DIGEST_SIZE);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_block_size(&mdCtx), WC_SHA_BLOCK_SIZE);
|
||||
AssertIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);
|
||||
#endif
|
||||
/* error case */
|
||||
wolfSSL_EVP_MD_CTX_init(&mdCtx);
|
||||
@ -37414,12 +37421,24 @@ static int test_tls13_apis(void)
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
int outSz;
|
||||
#endif
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
|
||||
int groups[2] = { WOLFSSL_ECC_X25519, WOLFSSL_ECC_X448 };
|
||||
int numGroups = 2;
|
||||
#endif
|
||||
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
|
||||
char groupList[] = "P-521:P-384:P-256";
|
||||
char groupList[] =
|
||||
#ifndef NO_ECC_SECP
|
||||
#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
|
||||
"P-521:"
|
||||
#endif
|
||||
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
|
||||
"P-384:"
|
||||
#endif
|
||||
#if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
|
||||
"P-256"
|
||||
#endif
|
||||
"";
|
||||
#endif /* !defined(NO_ECC_SECP) */
|
||||
#endif /* defined(OPENSSL_EXTRA) && defined(HAVE_ECC) */
|
||||
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
@ -37626,6 +37645,7 @@ static int test_tls13_apis(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
#ifndef WOLFSSL_NO_SERVER_GROUPS_EXT
|
||||
AssertIntEQ(wolfSSL_preferred_group(NULL), BAD_FUNC_ARG);
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
@ -37681,7 +37701,7 @@ static int test_tls13_apis(void)
|
||||
WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
|
||||
#ifdef OPENSSL_EXTRA
|
||||
AssertIntEQ(wolfSSL_CTX_set1_groups_list(NULL, NULL), WOLFSSL_FAILURE);
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
AssertIntEQ(wolfSSL_CTX_set1_groups_list(clientCtx, NULL), WOLFSSL_FAILURE);
|
||||
@ -37717,8 +37737,9 @@ static int test_tls13_apis(void)
|
||||
AssertIntEQ(wolfSSL_set1_groups_list(serverSsl, groupList),
|
||||
WOLFSSL_SUCCESS);
|
||||
#endif
|
||||
#endif /* defined(OPENSSL_EXTRA) && defined(HAVE_ECC) */
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
#endif /* HAVE_SUPPORTED_CURVES */
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
#ifdef WOLFSSL_EARLY_DATA
|
||||
AssertIntEQ(wolfSSL_CTX_set_max_early_data(NULL, 0), BAD_FUNC_ARG);
|
||||
@ -40147,6 +40168,86 @@ static int test_various_pathlen_chains(void)
|
||||
}
|
||||
#endif /* !NO_RSA && !NO_SHA && !NO_FILESYSTEM && !NO_CERTS */
|
||||
|
||||
#ifdef HAVE_KEYING_MATERIAL
|
||||
static int test_export_keying_material_cb(WOLFSSL_CTX *ctx, WOLFSSL *ssl)
|
||||
{
|
||||
byte ekm[100] = {0};
|
||||
|
||||
(void)ctx;
|
||||
|
||||
/* Succes Cases */
|
||||
AssertIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"Test label", XSTR_SIZEOF("Test label"), NULL, 0, 0), 1);
|
||||
AssertIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"Test label", XSTR_SIZEOF("Test label"), NULL, 0, 1), 1);
|
||||
/* Use some random context */
|
||||
AssertIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"Test label", XSTR_SIZEOF("Test label"), ekm, 10, 1), 1);
|
||||
/* Failure cases */
|
||||
AssertIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"client finished", XSTR_SIZEOF("client finished"), NULL, 0, 0), 0);
|
||||
AssertIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"server finished", XSTR_SIZEOF("server finished"), NULL, 0, 0), 0);
|
||||
AssertIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"master secret", XSTR_SIZEOF("master secret"), NULL, 0, 0), 0);
|
||||
AssertIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"extended master secret", XSTR_SIZEOF("extended master secret"), NULL, 0, 0), 0);
|
||||
AssertIntEQ(wolfSSL_export_keying_material(ssl, ekm, sizeof(ekm),
|
||||
"key expansion", XSTR_SIZEOF("key expansion"), NULL, 0, 0), 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_export_keying_material_ssl_cb(WOLFSSL* ssl)
|
||||
{
|
||||
wolfSSL_KeepArrays(ssl);
|
||||
}
|
||||
|
||||
static void test_export_keying_material(void)
|
||||
{
|
||||
#ifndef SINGLE_THREADED
|
||||
tcp_ready ready;
|
||||
callback_functions clientCb;
|
||||
func_args client_args;
|
||||
func_args server_args;
|
||||
THREAD_TYPE serverThread;
|
||||
|
||||
XMEMSET(&client_args, 0, sizeof(func_args));
|
||||
XMEMSET(&server_args, 0, sizeof(func_args));
|
||||
XMEMSET(&clientCb, 0, sizeof(callback_functions));
|
||||
#ifdef WOLFSSL_TIRTOS
|
||||
fdOpenSession(Task_self());
|
||||
#endif
|
||||
|
||||
StartTCP();
|
||||
InitTcpReady(&ready);
|
||||
|
||||
#if defined(USE_WINDOWS_API)
|
||||
/* use RNG to get random port if using windows */
|
||||
ready.port = GetRandomPort();
|
||||
#endif
|
||||
|
||||
server_args.signal = &ready;
|
||||
client_args.signal = &ready;
|
||||
clientCb.ssl_ready = test_export_keying_material_ssl_cb;
|
||||
client_args.callbacks = &clientCb;
|
||||
|
||||
start_thread(test_server_nofail, &server_args, &serverThread);
|
||||
wait_tcp_ready(&server_args);
|
||||
test_client_nofail(&client_args, test_export_keying_material_cb);
|
||||
join_thread(serverThread);
|
||||
|
||||
AssertTrue(client_args.return_code);
|
||||
AssertTrue(server_args.return_code);
|
||||
|
||||
FreeTcpReady(&ready);
|
||||
|
||||
#ifdef WOLFSSL_TIRTOS
|
||||
fdOpenSession(Task_self());
|
||||
#endif
|
||||
#endif /* !SINGLE_THREADED */
|
||||
}
|
||||
#endif /* HAVE_KEYING_MATERIAL */
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
| Main
|
||||
*----------------------------------------------------------------------------*/
|
||||
@ -40556,6 +40657,11 @@ void ApiTest(void)
|
||||
test_DhCallbacks();
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_KEYING_MATERIAL
|
||||
test_export_keying_material();
|
||||
#endif /* HAVE_KEYING_MATERIAL */
|
||||
|
||||
/*wolfcrypt */
|
||||
printf("\n-----------------wolfcrypt unit tests------------------\n");
|
||||
AssertFalse(test_wolfCrypt_Init());
|
||||
@ -40858,7 +40964,6 @@ void ApiTest(void)
|
||||
test_wc_PKCS7_SetOriDecryptCtx();
|
||||
test_wc_PKCS7_DecodeCompressedData();
|
||||
|
||||
|
||||
test_wc_i2d_PKCS12();
|
||||
|
||||
test_wolfSSL_CTX_LoadCRL();
|
||||
|
@ -5603,9 +5603,10 @@ int wc_OBJ_sn2nid(const char *sn)
|
||||
{WOLFSSL_ORGUNIT_NAME, NID_organizationalUnitName},
|
||||
{WOLFSSL_EMAIL_ADDR, NID_emailAddress},
|
||||
{NULL, -1}};
|
||||
|
||||
int i;
|
||||
#ifdef HAVE_ECC
|
||||
char curveName[16]; /* Same as MAX_CURVE_NAME_SZ but can't include that
|
||||
* symbol in this file */
|
||||
int eccEnum;
|
||||
#endif
|
||||
WOLFSSL_ENTER("OBJ_sn2nid");
|
||||
@ -5618,8 +5619,11 @@ int wc_OBJ_sn2nid(const char *sn)
|
||||
/* Nginx uses this OpenSSL string. */
|
||||
if (XSTRNCMP(sn, "prime256v1", 10) == 0)
|
||||
sn = "SECP256R1";
|
||||
if (XSTRNCMP(sn, "secp384r1", 10) == 0)
|
||||
sn = "SECP384R1";
|
||||
/* OpenSSL allows lowercase curve names */
|
||||
for (i = 0; i < (int)(sizeof(curveName) - 1) && *sn; i++) {
|
||||
curveName[i] = (char)XTOUPPER(*sn++);
|
||||
}
|
||||
curveName[i] = '\0';
|
||||
/* find based on name and return NID */
|
||||
for (i = 0;
|
||||
#ifndef WOLFSSL_ECC_CURVE_STATIC
|
||||
@ -5628,7 +5632,7 @@ int wc_OBJ_sn2nid(const char *sn)
|
||||
ecc_sets[i].size != 0;
|
||||
#endif
|
||||
i++) {
|
||||
if (XSTRNCMP(sn, ecc_sets[i].name, ECC_MAXNAME) == 0) {
|
||||
if (XSTRNCMP(curveName, ecc_sets[i].name, ECC_MAXNAME) == 0) {
|
||||
eccEnum = ecc_sets[i].id;
|
||||
/* Convert enum value in ecc_curve_id to OpenSSL NID */
|
||||
return EccEnumToNID(eccEnum);
|
||||
|
@ -772,39 +772,16 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
||||
case AES_256_GCM_TYPE:
|
||||
if ((ctx->gcmBuffer && ctx->gcmBufferLen > 0)
|
||||
|| (ctx->gcmBufferLen == 0)) {
|
||||
ret = 0;
|
||||
if (ctx->gcmAuthIn) {
|
||||
/* authenticated, non-confidential data*/
|
||||
if (ctx->enc) {
|
||||
XMEMSET(ctx->authTag, 0, ctx->authTagSz);
|
||||
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, NULL, NULL, 0,
|
||||
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
||||
ctx->gcmAuthIn, ctx->gcmAuthInSz);
|
||||
}
|
||||
else {
|
||||
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, NULL, NULL, 0,
|
||||
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
||||
ctx->gcmAuthIn, ctx->gcmAuthInSz);
|
||||
/* Reset partial authTag error for AAD*/
|
||||
if (ret == AES_GCM_AUTH_E)
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (ctx->enc)
|
||||
/* encrypt confidential data*/
|
||||
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out,
|
||||
ctx->gcmBuffer, ctx->gcmBufferLen,
|
||||
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
||||
NULL, 0);
|
||||
else
|
||||
/* decrypt confidential data*/
|
||||
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, out,
|
||||
ctx->gcmBuffer, ctx->gcmBufferLen,
|
||||
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
||||
NULL, 0);
|
||||
}
|
||||
if (ctx->enc)
|
||||
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out,
|
||||
ctx->gcmBuffer, ctx->gcmBufferLen,
|
||||
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
||||
ctx->gcmAuthIn, ctx->gcmAuthInSz);
|
||||
else
|
||||
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, out,
|
||||
ctx->gcmBuffer, ctx->gcmBufferLen,
|
||||
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
|
||||
ctx->gcmAuthIn, ctx->gcmAuthInSz);
|
||||
|
||||
if (ret == 0) {
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
@ -1229,7 +1206,8 @@ unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher)
|
||||
case AES_128_GCM_TYPE:
|
||||
case AES_192_GCM_TYPE:
|
||||
case AES_256_GCM_TYPE:
|
||||
return WOLFSSL_EVP_CIPH_GCM_MODE;
|
||||
return WOLFSSL_EVP_CIPH_GCM_MODE &
|
||||
WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
|
||||
#endif
|
||||
#if defined(WOLFSSL_AES_COUNTER)
|
||||
case AES_128_CTR_TYPE:
|
||||
@ -2105,7 +2083,8 @@ static const struct s_ent {
|
||||
#endif /* NO_MD5 */
|
||||
|
||||
#ifndef NO_SHA
|
||||
{WC_HASH_TYPE_SHA, NID_sha1, "SHA"},
|
||||
{WC_HASH_TYPE_SHA, NID_sha1, "SHA1"},
|
||||
{WC_HASH_TYPE_SHA, NID_sha1, "SHA"}, /* Leave for backwards compatibility */
|
||||
#endif /* NO_SHA */
|
||||
|
||||
#ifdef WOLFSSL_SHA224
|
||||
@ -3278,8 +3257,8 @@ const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name)
|
||||
{
|
||||
{"MD4", "ssl3-md4"},
|
||||
{"MD5", "ssl3-md5"},
|
||||
{"SHA", "ssl3-sha1"},
|
||||
{"SHA", "SHA1"},
|
||||
{"SHA1", "ssl3-sha1"},
|
||||
{"SHA1", "SHA"},
|
||||
{ NULL, NULL}
|
||||
};
|
||||
char nameUpper[15]; /* 15 bytes should be enough for any name */
|
||||
@ -3357,7 +3336,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
||||
const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void)
|
||||
{
|
||||
WOLFSSL_ENTER("EVP_sha1");
|
||||
return EVP_get_digestbyname("SHA");
|
||||
return EVP_get_digestbyname("SHA1");
|
||||
}
|
||||
#endif /* NO_SHA */
|
||||
|
||||
@ -4387,7 +4366,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
||||
WOLFSSL_MSG("EVP_AES_128_GCM");
|
||||
ctx->cipherType = AES_128_GCM_TYPE;
|
||||
ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
|
||||
ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE;
|
||||
ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE |
|
||||
WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
|
||||
ctx->keyLen = 16;
|
||||
ctx->block_size = AES_BLOCK_SIZE;
|
||||
ctx->authTagSz = AES_BLOCK_SIZE;
|
||||
@ -4411,7 +4391,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
||||
WOLFSSL_MSG("EVP_AES_192_GCM");
|
||||
ctx->cipherType = AES_192_GCM_TYPE;
|
||||
ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
|
||||
ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE;
|
||||
ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE |
|
||||
WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
|
||||
ctx->keyLen = 24;
|
||||
ctx->block_size = AES_BLOCK_SIZE;
|
||||
ctx->authTagSz = AES_BLOCK_SIZE;
|
||||
@ -4435,7 +4416,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
||||
WOLFSSL_MSG("EVP_AES_256_GCM");
|
||||
ctx->cipherType = AES_256_GCM_TYPE;
|
||||
ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
|
||||
ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE;
|
||||
ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE |
|
||||
WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
|
||||
ctx->keyLen = 32;
|
||||
ctx->block_size = AES_BLOCK_SIZE;
|
||||
ctx->authTagSz = AES_BLOCK_SIZE;
|
||||
@ -5284,39 +5266,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
|
||||
ret = wolfSSL_EVP_CipherUpdate_GCM_AAD(ctx, src, len);
|
||||
}
|
||||
else {
|
||||
ret = 0;
|
||||
if (ctx->gcmAuthIn) {
|
||||
/* authenticated, non-confidential data*/
|
||||
if (ctx->enc) {
|
||||
XMEMSET(ctx->authTag, 0, ctx->authTagSz);
|
||||
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, NULL,
|
||||
NULL, 0, ctx->iv, ctx->ivSz, ctx->authTag,
|
||||
ctx->authTagSz, ctx->gcmAuthIn,
|
||||
ctx->gcmAuthInSz);
|
||||
}
|
||||
else {
|
||||
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, NULL,
|
||||
NULL, 0, ctx->iv, ctx->ivSz, ctx->authTag,
|
||||
ctx->authTagSz, ctx->gcmAuthIn,
|
||||
ctx->gcmAuthInSz);
|
||||
/* Reset partial authTag error for AAD*/
|
||||
if (ret == AES_GCM_AUTH_E)
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (ctx->enc)
|
||||
/* encrypt confidential data*/
|
||||
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, dst, src,
|
||||
len, ctx->iv, ctx->ivSz, ctx->authTag,
|
||||
ctx->authTagSz, NULL, 0);
|
||||
else
|
||||
/* decrypt confidential data*/
|
||||
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, dst, src,
|
||||
len, ctx->iv, ctx->ivSz, ctx->authTag,
|
||||
ctx->authTagSz, NULL, 0);
|
||||
}
|
||||
if (ctx->enc)
|
||||
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, dst, src,
|
||||
len, ctx->iv, ctx->ivSz, ctx->authTag,
|
||||
ctx->authTagSz, ctx->gcmAuthIn, ctx->gcmAuthInSz);
|
||||
else
|
||||
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, dst, src,
|
||||
len, ctx->iv, ctx->ivSz, ctx->authTag,
|
||||
ctx->authTagSz, ctx->gcmAuthIn, ctx->gcmAuthInSz);
|
||||
}
|
||||
if (ret == 0)
|
||||
ret = len;
|
||||
@ -6879,7 +6836,10 @@ int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (XSTRNCMP("SHA1", evp, 4) == 0) {
|
||||
hash = WC_HASH_TYPE_SHA;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("Unknown SHA hash");
|
||||
}
|
||||
}
|
||||
|
@ -2676,6 +2676,10 @@ WOLFSSL_LOCAL int DeriveMasterSecret(WOLFSSL* ssl);
|
||||
WOLFSSL_LOCAL int DeriveResumptionPSK(WOLFSSL* ssl, byte* nonce, byte nonceLen, byte* secret);
|
||||
WOLFSSL_LOCAL int DeriveResumptionSecret(WOLFSSL* ssl, byte* key);
|
||||
|
||||
WOLFSSL_LOCAL int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen,
|
||||
const char *label, size_t labelLen,
|
||||
const unsigned char *context, size_t contextLen);
|
||||
|
||||
/* The key update request values for KeyUpdate message. */
|
||||
enum KeyUpdateRequest {
|
||||
update_not_requested,
|
||||
@ -3645,6 +3649,9 @@ typedef struct Arrays {
|
||||
byte sessionIDSz;
|
||||
#ifdef WOLFSSL_TLS13
|
||||
byte secret[SECRET_LEN];
|
||||
#endif
|
||||
#ifdef HAVE_KEYING_MATERIAL
|
||||
byte exporterSecret[WC_MAX_DIGEST_SIZE];
|
||||
#endif
|
||||
byte masterSecret[SECRET_LEN];
|
||||
#if defined(WOLFSSL_RENESAS_TSIP_TLS) && \
|
||||
|
@ -25,6 +25,7 @@
|
||||
#define WOLFSSL_EC_H_
|
||||
|
||||
#include <wolfssl/openssl/bn.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -68,6 +69,13 @@ enum {
|
||||
NID_brainpoolP512r1 = 933,
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ED448
|
||||
NID_ED448 = ED448k,
|
||||
#endif
|
||||
#ifdef HAVE_ED25519
|
||||
NID_ED25519 = ED25519k,
|
||||
#endif
|
||||
|
||||
OPENSSL_EC_NAMED_CURVE = 0x001
|
||||
};
|
||||
|
||||
|
@ -645,6 +645,8 @@ WOLFSSL_LOCAL int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp,
|
||||
#define EVP_CIPH_CCM_MODE WOLFSSL_EVP_CIPH_CCM_MODE
|
||||
#define EVP_CIPH_XTS_MODE WOLFSSL_EVP_CIPH_XTS_MODE
|
||||
|
||||
#define EVP_CIPH_FLAG_AEAD_CIPHER WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER
|
||||
|
||||
#define WOLFSSL_EVP_CIPH_MODE 0x0007
|
||||
#define WOLFSSL_EVP_CIPH_STREAM_CIPHER 0x0
|
||||
#define WOLFSSL_EVP_CIPH_ECB_MODE 0x1
|
||||
@ -655,6 +657,7 @@ WOLFSSL_LOCAL int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp,
|
||||
#define WOLFSSL_EVP_CIPH_GCM_MODE 0x6
|
||||
#define WOLFSSL_EVP_CIPH_CCM_MODE 0x7
|
||||
#define WOLFSSL_EVP_CIPH_XTS_MODE 0x10
|
||||
#define WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER 0x20
|
||||
#define WOLFSSL_EVP_CIPH_NO_PADDING 0x100
|
||||
#define EVP_CIPH_VARIABLE_LENGTH 0x200
|
||||
#define WOLFSSL_EVP_CIPH_TYPE_INIT 0xff
|
||||
|
@ -183,6 +183,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
|
||||
#define SSL_CTX_get_verify_mode wolfSSL_CTX_get_verify_mode
|
||||
#define SSL_CTX_get_verify_depth wolfSSL_CTX_get_verify_depth
|
||||
#define SSL_get_certificate wolfSSL_get_certificate
|
||||
#define SSL_CTX_get0_certificate wolfSSL_CTX_get0_certificate
|
||||
#define SSL_use_certificate wolfSSL_use_certificate
|
||||
#define SSL_use_certificate_ASN1 wolfSSL_use_certificate_ASN1
|
||||
#define d2i_PKCS8_PRIV_KEY_INFO_bio wolfSSL_d2i_PKCS8_PKEY_bio
|
||||
@ -305,7 +306,10 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
|
||||
/* wolfSSL does not support security levels */
|
||||
#define SSL_CTX_set_security_level(...)
|
||||
/* wolfSSL does not support exporting keying material */
|
||||
#define SSL_export_keying_material(...) 0
|
||||
#define SSL_export_keying_material wolfSSL_export_keying_material
|
||||
|
||||
#define SSL_CTX_set1_groups wolfSSL_CTX_set1_groups
|
||||
#define SSL_set1_groups wolfSSL_set1_groups
|
||||
|
||||
#define SSL_CTX_set1_groups_list wolfSSL_CTX_set1_groups_list
|
||||
#define SSL_set1_groups_list wolfSSL_set1_groups_list
|
||||
@ -1261,6 +1265,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
|
||||
#define OPENSSL_cleanse wolfSSL_OPENSSL_cleanse
|
||||
#define SSL_CTX_get_timeout wolfSSL_SSL_CTX_get_timeout
|
||||
#define SSL_CTX_set_tmp_ecdh wolfSSL_SSL_CTX_set_tmp_ecdh
|
||||
#define SSL_CTX_set_ecdh_auto(...)
|
||||
#define SSL_CTX_remove_session wolfSSL_SSL_CTX_remove_session
|
||||
#define SSL_get_rbio wolfSSL_SSL_get_rbio
|
||||
#define SSL_get_wbio wolfSSL_SSL_get_wbio
|
||||
|
@ -926,6 +926,12 @@ WOLFSSL_API int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups,
|
||||
int count);
|
||||
WOLFSSL_API int wolfSSL_set_groups(WOLFSSL* ssl, int* groups, int count);
|
||||
|
||||
#ifdef OPENSSL_EXTRA
|
||||
WOLFSSL_API int wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups,
|
||||
int count);
|
||||
WOLFSSL_API int wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count);
|
||||
#endif
|
||||
|
||||
WOLFSSL_API int wolfSSL_connect_TLSv13(WOLFSSL*);
|
||||
WOLFSSL_API int wolfSSL_accept_TLSv13(WOLFSSL*);
|
||||
|
||||
@ -1062,6 +1068,15 @@ WOLFSSL_API int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX*);
|
||||
WOLFSSL_API int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX*, const char*);
|
||||
WOLFSSL_API int wolfSSL_set_cipher_list(WOLFSSL*, const char*);
|
||||
|
||||
#ifdef HAVE_KEYING_MATERIAL
|
||||
/* Keying Material Exporter for TLS */
|
||||
WOLFSSL_API int wolfSSL_export_keying_material(WOLFSSL *ssl,
|
||||
unsigned char *out, size_t outLen,
|
||||
const char *label, size_t labelLen,
|
||||
const unsigned char *context, size_t contextLen,
|
||||
int use_context);
|
||||
#endif /* HAVE_KEYING_MATERIAL */
|
||||
|
||||
/* Nonblocking DTLS helper functions */
|
||||
WOLFSSL_API void wolfSSL_dtls_set_using_nonblock(WOLFSSL*, int);
|
||||
WOLFSSL_API int wolfSSL_dtls_get_using_nonblock(WOLFSSL*);
|
||||
@ -2416,6 +2431,7 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL*, void* key, unsigned int len,
|
||||
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
|
||||
defined(KEEP_OUR_CERT)
|
||||
WOLFSSL_API WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl);
|
||||
WOLFSSL_API WOLFSSL_X509* wolfSSL_CTX_get0_certificate(WOLFSSL_CTX* ctx);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -3163,13 +3179,9 @@ enum {
|
||||
};
|
||||
|
||||
#ifdef HAVE_SUPPORTED_CURVES
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
|
||||
WOLFSSL_API int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name);
|
||||
WOLFSSL_API int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx,
|
||||
word16 name);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13
|
||||
@ -4086,7 +4098,7 @@ WOLFSSL_API int wolfSSL_sk_SSL_CIPHER_find(
|
||||
WOLFSSL_API void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk);
|
||||
WOLFSSL_API int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* st);
|
||||
WOLFSSL_API int wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF(WOLFSSL_COMP)* sk);
|
||||
WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(void *ciphers, int idx);
|
||||
WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(WOLFSSL_STACK* sk, int i);
|
||||
WOLFSSL_API void ERR_load_SSL_strings(void);
|
||||
WOLFSSL_API void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p);
|
||||
|
||||
|
Reference in New Issue
Block a user