Skip to content
Open
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,24 @@ if(WOLFSSL_CERT_WITH_EXTERN_PSK)
endif()
endif()

# External PSK Importer (RFC 9258)
add_option("WOLFSSL_EXTERNAL_PSK_IMPORTER"
"Enable importing external PSKs for TLS 1.3 per RFC 9258 (default: disabled)"
"no" "yes;no")

if(WOLFSSL_EXTERNAL_PSK_IMPORTER)
if(NOT WOLFSSL_TLS13)
message(WARNING "TLS 1.3 is disabled - disabling psk-importer")
override_cache(WOLFSSL_EXTERNAL_PSK_IMPORTER "no")
elseif(NOT WOLFSSL_PSK)
message(WARNING "PSK is disabled - disabling psk-importer")
override_cache(WOLFSSL_EXTERNAL_PSK_IMPORTER "no")
else()
list(APPEND WOLFSSL_DEFINITIONS
"-DWOLFSSL_EXTERNAL_PSK_IMPORTER")
endif()
endif()

# Hello Retry Request Cookie
add_option("WOLFSSL_HRR_COOKIE"
"Enable the server to send Cookie Extension in HRR with state (default: disabled)"
Expand Down
2 changes: 2 additions & 0 deletions cmake/options.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ extern "C" {
#cmakedefine WOLFSSL_DTLS_CH_FRAG
#undef WOLFSSL_CERT_WITH_EXTERN_PSK
#cmakedefine WOLFSSL_CERT_WITH_EXTERN_PSK
#undef WOLFSSL_EXTERNAL_PSK_IMPORTER
#cmakedefine WOLFSSL_EXTERNAL_PSK_IMPORTER
#undef WOLFSSL_EITHER_SIDE
#cmakedefine WOLFSSL_EITHER_SIDE
#undef WOLFSSL_ENCRYPTED_KEYS
Expand Down
21 changes: 21 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -5298,6 +5298,27 @@ then
fi
fi

# External PSK Importer (RFC 9258)
AC_ARG_ENABLE([psk-importer],
[AS_HELP_STRING([--enable-psk-importer],[Enable importing external PSKs for TLS 1.3 per RFC 9258 (default: disabled)])],
[ ENABLED_PSK_IMPORTER=$enableval ],
[ ENABLED_PSK_IMPORTER=no ]
)
if test "$ENABLED_PSK_IMPORTER" = "yes"
then
if test "$ENABLED_TLS13" = "no"
then
AC_MSG_NOTICE([TLS 1.3 is disabled - disabling psk-importer])
ENABLED_PSK_IMPORTER="no"
elif test "$ENABLED_PSK" = "no"
then
AC_MSG_NOTICE([PSK is disabled - disabling psk-importer])
ENABLED_PSK_IMPORTER="no"
else
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_EXTERNAL_PSK_IMPORTER"
fi
fi

# ERROR STRINGS
AC_ARG_ENABLE([errorstrings],
[AS_HELP_STRING([--enable-errorstrings],[Enable error strings table (default: enabled)])],
Expand Down
112 changes: 112 additions & 0 deletions doc/dox_comments/header_files/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15221,6 +15221,118 @@ void wolfSSL_CTX_set_psk_server_tls13_callback(WOLFSSL_CTX* ctx,
void wolfSSL_set_psk_server_tls13_callback(WOLFSSL* ssl,
wc_psk_server_tls13_callback cb);

/*!
\ingroup Setup

\brief This function sets, on the WOLFSSL_CTX, the client side callback used
to import an external Pre-Shared Key (PSK) for TLS v1.3 connections per
RFC 9258. The callback returns the external identity, an optional context
and the external PSK; wolfSSL derives the ImportedIdentity and the imported
PSK used in the handshake. The identity, context and key are opaque byte
buffers: on entry each length argument holds the buffer capacity and the
callback overwrites it with the actual length. The context is limited to
MAX_PSK_CTX_LEN bytes and the identity to MAX_PSK_ID_LEN bytes. The hashAlgo
argument is the hash associated with the external PSK; it is pre-set to
WC_SHA256 (the RFC 9258 default) and only needs to be changed for an EPSK
associated with a different hash. The callback must be deterministic: it is
invoked more than once per connection (when building the ClientHello and
again while computing the binders) and must return the same identity,
context, key and hash each time. Requires WOLFSSL_EXTERNAL_PSK_IMPORTER.

\param [in,out] ctx a pointer to a WOLFSSL_CTX structure.
\param [in] cb a client PSK importer callback.

_Example_
\code
WOLFSSL_CTX* ctx;
...
wolfSSL_CTX_set_psk_client_importer_callback(ctx, my_psk_importer_cb);
\endcode

\sa wolfSSL_set_psk_client_importer_callback
\sa wolfSSL_CTX_set_psk_server_importer_callback
*/
void wolfSSL_CTX_set_psk_client_importer_callback(WOLFSSL_CTX* ctx,
wc_psk_client_importer_callback cb);

/*!
\ingroup Setup

\brief This function sets, on the WOLFSSL object, the client side callback
used to import an external Pre-Shared Key (PSK) for TLS v1.3 connections per
RFC 9258. Requires WOLFSSL_EXTERNAL_PSK_IMPORTER.

\param [in,out] ssl a pointer to a WOLFSSL structure, created using
wolfSSL_new().
\param [in] cb a client PSK importer callback.

_Example_
\code
WOLFSSL* ssl;
...
wolfSSL_set_psk_client_importer_callback(ssl, my_psk_importer_cb);
\endcode

\sa wolfSSL_CTX_set_psk_client_importer_callback
\sa wolfSSL_set_psk_server_importer_callback
*/
void wolfSSL_set_psk_client_importer_callback(WOLFSSL* ssl,
wc_psk_client_importer_callback cb);

/*!
\ingroup Setup

\brief This function sets, on the WOLFSSL_CTX, the server side callback used
to import an external Pre-Shared Key (PSK) for TLS v1.3 connections per
RFC 9258. Given a received external identity and optional context (each an
opaque buffer with an explicit length), the callback returns the matching
external PSK. The hashAlgo argument is the hash associated with the external
PSK; it is pre-set to WC_SHA256 and must be set to the same value the client
used for that EPSK. The callback must be deterministic: it may be invoked
more than once per connection (once per candidate cipher suite) and must
return the same key and hash each time. Requires
WOLFSSL_EXTERNAL_PSK_IMPORTER.

\param [in,out] ctx a pointer to a WOLFSSL_CTX structure.
\param [in] cb a server PSK importer callback.

_Example_
\code
WOLFSSL_CTX* ctx;
...
wolfSSL_CTX_set_psk_server_importer_callback(ctx, my_psk_importer_cb);
\endcode

\sa wolfSSL_set_psk_server_importer_callback
\sa wolfSSL_CTX_set_psk_client_importer_callback
*/
void wolfSSL_CTX_set_psk_server_importer_callback(WOLFSSL_CTX* ctx,
wc_psk_server_importer_callback cb);

/*!
\ingroup Setup

\brief This function sets, on the WOLFSSL object, the server side callback
used to import an external Pre-Shared Key (PSK) for TLS v1.3 connections per
RFC 9258. Requires WOLFSSL_EXTERNAL_PSK_IMPORTER.

\param [in,out] ssl a pointer to a WOLFSSL structure, created using
wolfSSL_new().
\param [in] cb a server PSK importer callback.

_Example_
\code
WOLFSSL* ssl;
...
wolfSSL_set_psk_server_importer_callback(ssl, my_psk_importer_cb);
\endcode

\sa wolfSSL_CTX_set_psk_server_importer_callback
\sa wolfSSL_set_psk_client_importer_callback
*/
void wolfSSL_set_psk_server_importer_callback(WOLFSSL* ssl,
wc_psk_server_importer_callback cb);

/*!
\ingroup Setup

Expand Down
39 changes: 38 additions & 1 deletion examples/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1466,6 +1466,10 @@ static const char* client_usage_msg[][81] = {
!defined(NO_PSK)
"--psk-with-certs Use TLS 1.3 PSK with certificates\n", /* 74 */
#endif
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER) && \
!defined(NO_PSK)
"--psk-importer Import an external PSK per RFC 9258\n",
#endif
#ifdef HAVE_RPK
"--rpk Use RPK for the defined certificates\n", /* 75 */
#endif
Expand Down Expand Up @@ -1736,6 +1740,10 @@ static const char* client_usage_msg[][81] = {
!defined(NO_PSK)
"--psk-with-certs Use TLS 1.3 PSK with certificates\n", /* 74 */
#endif
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER) && \
!defined(NO_PSK)
"--psk-importer Import an external PSK per RFC 9258\n",
#endif
#ifdef HAVE_RPK
"--rpk Use RPK for the defined certificates\n", /* 75 */
#endif
Expand Down Expand Up @@ -1989,6 +1997,10 @@ static void Usage(void)
!defined(NO_PSK)
printf("%s", msg[++msgid]); /* --psk-with-certs */
#endif
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER) && \
!defined(NO_PSK)
printf("%s", msg[++msgid]); /* --psk-importer */
#endif
#ifdef HAVE_RPK
printf("%s", msg[++msgid]); /* --rpk */
#endif
Expand Down Expand Up @@ -2192,6 +2204,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
!defined(NO_PSK)
{ "psk-with-certs", 0, 272 },
#endif
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER) && \
!defined(NO_PSK)
{ "psk-importer", 0, 273 },
#endif
{ 0, 0, 0 }
};
Expand All @@ -2201,6 +2217,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
int usePsk = 0;
int opensslPsk = 0;
int usePskWithCerts = 0;
int usePskImporter = 0;
int useAnon = 0;
int sendGET = 0;
int benchmark = 0;
Expand Down Expand Up @@ -2441,6 +2458,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
(void)opensslPsk;
(void)fileFormat;
(void)usePskWithCerts;
(void)usePskImporter;
StackTrap();

/* Reinitialize the global myVerifyAction. */
Expand Down Expand Up @@ -3103,6 +3121,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
break;
#endif

#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER) && \
!defined(NO_PSK)
case 273:
/* Import an external PSK per RFC 9258. */
usePskImporter = 1;
usePsk = 1;
break;
#endif

default:
Usage();
XEXIT_T(MY_EX_USAGE);
Expand Down Expand Up @@ -3518,6 +3545,15 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
#ifndef NO_PSK
const char *defaultCipherList = cipherList;

#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER)
if (usePskImporter) {
/* RFC 9258 external PSK importer (TLS 1.3 only). */
wolfSSL_CTX_set_psk_client_importer_callback(ctx,
my_psk_client_importer_cb);
}
else
#endif
{
wolfSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
#ifdef WOLFSSL_TLS13
#if !defined(WOLFSSL_PSK_TLS13_CB) && !defined(WOLFSSL_PSK_ONE_ID)
Expand All @@ -3538,7 +3574,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
}
}
#endif
#endif
#endif /* WOLFSSL_TLS13 */
} /* end of non-importer PSK setup */
if (defaultCipherList == NULL) {
#if defined(HAVE_AESGCM) && !defined(NO_DH)
#ifdef WOLFSSL_TLS13
Expand Down
39 changes: 38 additions & 1 deletion examples/server/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,10 @@ static const char* server_usage_msg[][71] = {
!defined(NO_PSK)
"--psk-with-certs Use TLS 1.3 PSK with certificates\n", /* 65 */
#endif
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER) && \
!defined(NO_PSK)
"--psk-importer Import an external PSK per RFC 9258\n",
#endif
#ifdef WOLFSSL_DUAL_ALG_CERTS
"--altPrivKey <file> Generate alternative signature with this key.\n", /* 66 */
#endif
Expand Down Expand Up @@ -1358,6 +1362,10 @@ static const char* server_usage_msg[][71] = {
!defined(NO_PSK)
"--psk-with-certs Use TLS 1.3 PSK with certificates\n", /* 65 */
#endif
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER) && \
!defined(NO_PSK)
"--psk-importer Import an external PSK per RFC 9258\n",
#endif
#ifdef WOLFSSL_DUAL_ALG_CERTS
"--altPrivKey <file> Generate alternative signature with this key.\n", /* 66 */
#endif
Expand Down Expand Up @@ -1537,6 +1545,10 @@ static void Usage(void)
!defined(NO_PSK)
printf("%s", msg[++msgId]); /* --psk-with-certs */
#endif
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER) && \
!defined(NO_PSK)
printf("%s", msg[++msgId]); /* --psk-importer */
#endif
#ifdef WOLFSSL_DUAL_ALG_CERTS
printf("%s", msg[++msgId]); /* --altPrivKey */
#endif
Expand Down Expand Up @@ -1673,6 +1685,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK) && \
!defined(NO_PSK)
{ "psk-with-certs", 0, 271 },
#endif
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER) && \
!defined(NO_PSK)
{ "psk-importer", 0, 272 },
#endif
{ 0, 0, 0 }
};
Expand All @@ -1691,6 +1707,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
int usePsk = 0;
int usePskPlus = 0;
int usePskWithCerts = 0;
int usePskImporter = 0;
int useAnon = 0;
int doDTLS = 0;
int dtlsUDP = 0;
Expand Down Expand Up @@ -1928,6 +1945,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
(void)usePqc;
(void)altPrivKey;
(void)usePskWithCerts;
(void)usePskImporter;

#ifdef WOLFSSL_TIRTOS
fdOpenSession(Task_self());
Expand Down Expand Up @@ -2625,6 +2643,15 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
break;
#endif

#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER) && \
!defined(NO_PSK)
case 272:
/* Import an external PSK per RFC 9258. */
usePskImporter = 1;
usePsk = 1;
break;
#endif

case -1:
default:
Usage();
Expand Down Expand Up @@ -3057,6 +3084,15 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
#ifndef NO_PSK
const char *defaultCipherList = cipherList;

#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EXTERNAL_PSK_IMPORTER)
if (usePskImporter) {
/* RFC 9258 external PSK importer (TLS 1.3 only). */
wolfSSL_CTX_set_psk_server_importer_callback(ctx,
my_psk_server_importer_cb);
}
else
#endif
{
wolfSSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
#ifdef WOLFSSL_TLS13
wolfSSL_CTX_set_psk_server_tls13_callback(ctx, my_psk_server_tls13_cb);
Expand All @@ -3068,7 +3104,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
}
}
#endif
#endif
#endif /* WOLFSSL_TLS13 */
} /* end of non-importer PSK setup */
if (sendPskIdentityHint == 1)
wolfSSL_CTX_use_psk_identity_hint(ctx, "cyassl server");

Expand Down
4 changes: 4 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -7234,7 +7234,11 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
ssl->options.client_psk_cs_cb = ctx->client_psk_cs_cb;
ssl->options.client_psk_tls13_cb = ctx->client_psk_tls13_cb;
ssl->options.server_psk_tls13_cb = ctx->server_psk_tls13_cb;
#ifdef WOLFSSL_EXTERNAL_PSK_IMPORTER
ssl->options.client_psk_importer_cb = ctx->client_psk_importer_cb;
ssl->options.server_psk_importer_cb = ctx->server_psk_importer_cb;
#endif
#endif /* WOLFSSL_TLS13 */
#endif /* NO_PSK */
#ifdef WOLFSSL_EARLY_DATA
if (ssl->options.side == WOLFSSL_SERVER_END)
Expand Down
Loading
Loading