From 448cde5a4be0da0ff5fbd121547da9e854a8c0b4 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 10 Jun 2022 18:13:39 +0200 Subject: [PATCH 01/12] Support for new DPP in wpa_supplicant - Add null check to asn template code in MakeCertReq and test - ENABLED_ECCCUSTCURVES can also be "all" --- configure.ac | 26 ++++++++++++++++++++------ wolfcrypt/src/asn.c | 7 ++++--- wolfcrypt/test/test.c | 14 ++++++++++++-- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 12388db48..daf1720cd 100644 --- a/configure.ac +++ b/configure.ac @@ -1234,6 +1234,11 @@ AC_ARG_ENABLE([wpas-dpp], [ ENABLED_WPAS_DPP=no ] ) +if test "$ENABLED_WPAS_DPP" = "yes" +then + ENABLED_WPAS="yes" +fi + # ntp support AC_ARG_ENABLE([ntp], [AS_HELP_STRING([--enable-ntp],[Enable ntp support (default: disabled)])], @@ -1241,11 +1246,6 @@ AC_ARG_ENABLE([ntp], [ ENABLED_NTP=no ] ) -if test "$ENABLED_WPAS_DPP" = "yes" -then - ENABLED_WPAS="yes" -fi - # Fortress build AC_ARG_ENABLE([fortress], [AS_HELP_STRING([--enable-fortress],[Enable SSL fortress build (default: disabled)])], @@ -2677,6 +2677,10 @@ AC_ARG_ENABLE([certreq], [ ENABLED_CERTREQ=no ] ) +if test "$ENABLED_WPAS_DPP" = "yes" +then + ENABLED_CERTREQ="yes" +fi # CERT REQUEST EXTENSION AC_ARG_ENABLE([certext], @@ -2815,6 +2819,11 @@ AC_ARG_ENABLE([ecccustcurves], [ ENABLED_ECCCUSTCURVES=no ] ) +if test "$ENABLED_WPAS_DPP" = "yes" +then + ENABLED_ECCCUSTCURVES="all" +fi + if test "$ENABLED_ECCCUSTCURVES" != "no" then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CUSTOM_CURVES" @@ -4812,6 +4821,11 @@ AC_ARG_ENABLE([pkcs7], [ ENABLED_PKCS7=$enableval ], [ ENABLED_PKCS7=no ] ) + +if test "x$ENABLED_WPAS_DPP" = "xyes" +then + ENABLED_PKCS7=yes +fi # wolfSSH Options AC_ARG_ENABLE([wolfssh], @@ -6450,7 +6464,7 @@ if test "$ENABLED_SP_MATH" = "yes"; then if test "$ENABLED_SP" = "no"; then AC_MSG_ERROR([Must have SP enabled with SP math: --enable-sp]) fi - if test "$ENABLED_ECCCUSTCURVES" = "yes"; then + if test "$ENABLED_ECCCUSTCURVES" != "no"; then AC_MSG_ERROR([Cannot use single precision math and custom curves]) fi if test "$ENABLED_DSA" = "yes"; then diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ea212c2fe..9890c5782 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -26549,7 +26549,7 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, if ((ret == 0) && (sz > (int)derSz)) { ret = BUFFER_E; } - if (ret == 0) { + if (ret == 0 && derBuffer != NULL) { /* Encode certificate request body into buffer. */ SetASN_Items(certReqBodyASN, dataASN, certReqBodyASN_Length, derBuffer); @@ -26565,14 +26565,15 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, &cert->subject, cert->heap); } } - if (ret >= 0) { + if (ret >= 0 && derBuffer != NULL) { /* Encode public key into space in buffer. */ ret = EncodePublicKey(cert->keyType, (byte*)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.data, dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.length, rsaKey, eccKey, ed25519Key, ed448Key, dsaKey); } - if ((ret >= 0) && (!dataASN[CERTREQBODYASN_IDX_EXT_BODY].noOut)) { + if ((ret >= 0 && derBuffer != NULL) && + (!dataASN[CERTREQBODYASN_IDX_EXT_BODY].noOut)) { /* Encode extensions into space in buffer. */ ret = EncodeExtensions(cert, (byte*)dataASN[CERTREQBODYASN_IDX_EXT_BODY].data.buffer.data, diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index de67fc22b..f87102481 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -11995,7 +11995,7 @@ WOLFSSL_TEST_SUBROUTINE int memory_test(void) static const char* certDerFile = CERT_WRITE_TEMP_DIR "cert.der"; static const char* otherCertPemFile = CERT_WRITE_TEMP_DIR "othercert.pem"; static const char* certPemFile = CERT_WRITE_TEMP_DIR "cert.pem"; - #if defined(WOLFSSL_CERT_REQ) && defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + #if defined(WOLFSSL_CERT_REQ) && !defined(WOLFSSL_NO_MALLOC) static const char* certReqDerFile = CERT_WRITE_TEMP_DIR "certreq.der"; static const char* certReqPemFile = CERT_WRITE_TEMP_DIR "certreq.pem"; #endif @@ -15559,10 +15559,13 @@ WOLFSSL_TEST_SUBROUTINE int rsa_test(void) goto exit_rsa; #endif -#if defined(WOLFSSL_CERT_REQ) && defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) +#if defined(WOLFSSL_CERT_REQ) && !defined(WOLFSSL_NO_MALLOC) { Cert *req; int derSz; +#ifndef WOLFSSL_SMALL_STACK + byte* der = NULL; +#endif req = (Cert *)XMALLOC(sizeof *req, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (! req) @@ -15656,6 +15659,13 @@ WOLFSSL_TEST_SUBROUTINE int rsa_test(void) ERROR_OUT(-7974, exit_rsa); } + /* Test getting the size of the buffer without providing the buffer. + * derSz is set to the "largest buffer" we are willing to allocate. */ + derSz = wc_MakeCertReq(req, NULL, 10000, key, NULL); + if (derSz < 0) { + ERROR_OUT(-7975, exit_rsa); + } + XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(req, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); der = NULL; From ee3636f2e76ea5bd673e28eea5d51462d51ab95c Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 13 Jun 2022 17:43:28 +0200 Subject: [PATCH 02/12] wc_EccPublicKeyToDer_ex: exporting the public key in compressed form --- wolfcrypt/src/asn.c | 31 ++++++++++++++++++++----------- wolfcrypt/src/ecc.c | 7 +++++-- wolfcrypt/test/test.c | 11 +++++++++++ wolfssl/wolfcrypt/asn_public.h | 3 +++ 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 9890c5782..ae19b7d64 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -22091,7 +22091,7 @@ enum { * @return MEMORY_E when dynamic memory allocation failed. */ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen, - int with_header) + int with_header, int comp) { #ifndef WOLFSSL_ASN_TEMPLATE int ret, idx = 0, algoSz, curveSz, bitStringSz; @@ -22101,7 +22101,10 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen, /* public size */ pubSz = key->dp ? key->dp->size : MAX_ECC_BYTES; - pubSz = 1 + 2 * pubSz; + if (comp) + pubSz = 1 + pubSz; + else + pubSz = 1 + 2 * pubSz; /* check for buffer overflow */ if (output != NULL && pubSz > (word32)outLen) { @@ -22144,7 +22147,7 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen, /* pub */ if (output) { PRIVATE_KEY_UNLOCK(); - ret = wc_ecc_export_x963(key, output + idx, &pubSz); + ret = wc_ecc_export_x963_ex(key, output + idx, &pubSz, comp); PRIVATE_KEY_LOCK(); if (ret != 0) { return ret; @@ -22168,7 +22171,7 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen, if (ret == 0) { /* Calculate the size of the encoded public point. */ PRIVATE_KEY_UNLOCK(); - ret = wc_ecc_export_x963(key, NULL, &pubSz); + ret = wc_ecc_export_x963_ex(key, NULL, &pubSz, comp); PRIVATE_KEY_LOCK(); /* LENGTH_ONLY_E on success. */ if (ret == LENGTH_ONLY_E) { @@ -22238,7 +22241,7 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen, if ((ret == 0) && (output != NULL)) { /* Encode public point. */ PRIVATE_KEY_UNLOCK(); - ret = wc_ecc_export_x963(key, output, &pubSz); + ret = wc_ecc_export_x963_ex(key, output, &pubSz, comp); PRIVATE_KEY_LOCK(); } if (ret == 0) { @@ -22266,12 +22269,18 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int outLen, int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen, int with_AlgCurve) { - return SetEccPublicKey(output, key, inLen, with_AlgCurve); + return SetEccPublicKey(output, key, inLen, with_AlgCurve, 0); +} + +int wc_EccPublicKeyToDer_ex(ecc_key* key, byte* output, word32 inLen, + int with_AlgCurve, int comp) +{ + return SetEccPublicKey(output, key, inLen, with_AlgCurve, comp); } int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve) { - return SetEccPublicKey(NULL, key, 0, with_AlgCurve); + return SetEccPublicKey(NULL, key, 0, with_AlgCurve, 0); } #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */ @@ -24131,7 +24140,7 @@ static int EncodePublicKey(int keyType, byte* output, int outLen, #endif #ifdef HAVE_ECC case ECC_KEY: - ret = SetEccPublicKey(output, eccKey, outLen, 1); + ret = SetEccPublicKey(output, eccKey, outLen, 1, 0); if (ret <= 0) { ret = PUBLIC_KEY_E; } @@ -24811,7 +24820,7 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, if (eccKey == NULL) return PUBLIC_KEY_E; der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, - sizeof(der->publicKey), 1); + sizeof(der->publicKey), 1, 0); } #endif @@ -26066,7 +26075,7 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, if (eccKey == NULL) return PUBLIC_KEY_E; der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, - sizeof(der->publicKey), 1); + sizeof(der->publicKey), 1, 0); } #endif @@ -26799,7 +26808,7 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, #ifdef HAVE_ECC /* ECC public key */ if (eckey != NULL) - bufferSz = SetEccPublicKey(buf, eckey, MAX_PUBLIC_KEY_SZ, 0); + bufferSz = SetEccPublicKey(buf, eckey, MAX_PUBLIC_KEY_SZ, 0, 0); #endif #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT) /* ED25519 public key */ diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 9397c43bd..95129c825 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -13715,7 +13715,7 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen word32 numlen; int ret = MP_OKAY; - if (key == NULL || out == NULL || outLen == NULL) + if (key == NULL || outLen == NULL) return BAD_FUNC_ARG; if (key->type == ECC_PRIVATEKEY_ONLY) @@ -13729,9 +13729,12 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen if (*outLen < (1 + numlen)) { *outLen = 1 + numlen; - return BUFFER_E; + return LENGTH_ONLY_E; } + if (out == NULL) + return BAD_FUNC_ARG; + /* store first byte */ out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index f87102481..46d8fb390 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -22571,6 +22571,17 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize) ERROR_OUT(-9890, done); } +#ifdef HAVE_COMP_KEY + /* test export of compressed public key */ + derSz = wc_EccPublicKeyToDer_ex(userA, der, ECC_BUFSIZE, 1, 1); + if (derSz < 0) { + ERROR_OUT(derSz, done); + } + if (derSz == 0) { + ERROR_OUT(-9890, done); + } +#endif + ret = SaveDerAndPem(der, derSz, eccPubKeyDerFile, NULL, 0, -8348); if (ret != 0) { goto done; diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index f9351a765..c8b077962 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -657,6 +657,9 @@ WOLFSSL_API int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz); ecc_key* key, word32 inSz); WOLFSSL_API int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen, int with_AlgCurve); + WOLFSSL_API int wc_EccPublicKeyToDer_ex(ecc_key* key, byte* output, + word32 inLen, int with_AlgCurve, + int comp); WOLFSSL_API int wc_EccPublicKeyDerSize(ecc_key* key, int with_AlgCurve); #endif From 5179741ddb07b6e52ce28c8f37ae38ded89869e2 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 13 Jun 2022 20:29:56 +0200 Subject: [PATCH 03/12] wpas: validate ecc points are on the curve --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index daf1720cd..26ff9776b 100644 --- a/configure.ac +++ b/configure.ac @@ -1539,6 +1539,7 @@ then AM_CFLAGS="$AM_CFLAGS -DKEEP_PEER_CERT" AM_CFLAGS="$AM_CFLAGS -DHAVE_KEYING_MATERIAL" AM_CFLAGS="$AM_CFLAGS -DNO_SESSION_CACHE_REF" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_IMPORT" if test "$ENABLED_OPENSSLEXTRA" = "no" then From afaf41823ce75a192b6f4db574d2f2bc3b6977c0 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 14 Jun 2022 16:43:35 +0200 Subject: [PATCH 04/12] wpa_supplicant uses larger challenge passwords for x509 requests --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 26ff9776b..ddef3c78d 100644 --- a/configure.ac +++ b/configure.ac @@ -1540,6 +1540,7 @@ then AM_CFLAGS="$AM_CFLAGS -DHAVE_KEYING_MATERIAL" AM_CFLAGS="$AM_CFLAGS -DNO_SESSION_CACHE_REF" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_ECC_IMPORT" + AM_CFLAGS="$AM_CFLAGS -DWC_CTC_NAME_SIZE=128" if test "$ENABLED_OPENSSLEXTRA" = "no" then From 8e84560f718bef3fd1b8c94153bae1295da96e00 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 14 Jun 2022 17:12:14 +0200 Subject: [PATCH 05/12] CSR: confirm the signature when verify == VERIFY --- tests/api.c | 2 +- wolfcrypt/src/asn.c | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/tests/api.c b/tests/api.c index a19bcf2b1..5a2b904c8 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30576,7 +30576,7 @@ static void test_wc_GetPubKeyDerFromCert(void) XFCLOSE(fp); wc_InitDecodedCert(&decoded, certBuf, certBufSz, NULL); - ret = wc_ParseCert(&decoded, CERTREQ_TYPE, NO_VERIFY, NULL); + ret = wc_ParseCert(&decoded, CERTREQ_TYPE, VERIFY, NULL); AssertIntEQ(ret, 0); /* good test case - RSA DER certificate request */ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ae19b7d64..6a83c6ffd 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -13090,9 +13090,16 @@ int DecodeToKey(DecodedCert* cert, int verify) return ret; /* Determine if self signed */ - cert->selfSigned = XMEMCMP(cert->issuerHash, - cert->subjectHash, - KEYID_SIZE) == 0 ? 1 : 0; +#ifdef WOLFSSL_CERT_REQ + if (cert->isCSR) + cert->selfSigned = 1; + else +#endif + { + cert->selfSigned = XMEMCMP(cert->issuerHash, + cert->subjectHash, + KEYID_SIZE) == 0 ? 1 : 0; + } ret = GetCertKey(cert, cert->source, &cert->srcIdx, cert->maxIdx); if (ret != 0) @@ -18092,8 +18099,15 @@ static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt, } if (ret == 0) { /* Determine if self signed by comparing issuer and subject hashes. */ - cert->selfSigned = XMEMCMP(cert->issuerHash, cert->subjectHash, - KEYID_SIZE) == 0 ? 1 : 0; + #ifdef WOLFSSL_CERT_REQ + if (cert->isCSR) + cert->selfSigned = 1; + else + #endif + { + cert->selfSigned = XMEMCMP(cert->issuerHash, cert->subjectHash, + KEYID_SIZE) == 0 ? 1 : 0; + } if (stopAtPubKey) { /* Return any bad date error through badDateRet and return offset of @@ -19755,6 +19769,22 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) } #endif /* IGNORE_NAME_CONSTRAINTS */ } +#ifdef WOLFSSL_CERT_REQ + else if (type == CERTREQ_TYPE) { + if ((ret = ConfirmSignature(&cert->sigCtx, + cert->source + cert->certBegin, + cert->sigIndex - cert->certBegin, + cert->publicKey, cert->pubKeySize, + cert->keyOID, cert->signature, + cert->sigLength, cert->signatureOID, + sce_tsip_encRsaKeyIdx)) != 0) { + if (ret != WC_PENDING_E) { + WOLFSSL_MSG("Confirm signature failed"); + } + return ret; + } + } +#endif else { /* no signer */ WOLFSSL_MSG("No CA signer to verify with"); From 144f2612e49d84b642b00f0b6be5276c48b43d44 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 15 Jun 2022 18:46:06 +0200 Subject: [PATCH 06/12] wc_ecc_export_x963_ex returns LENGTH_ONLY_E on a NULL output --- tests/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index 5a2b904c8..c8b992c6e 100644 --- a/tests/api.c +++ b/tests/api.c @@ -24713,7 +24713,7 @@ static int test_wc_ecc_export_x963_ex (void) if (ret == BAD_FUNC_ARG) { ret = wc_ecc_export_x963_ex(&key, out, &badOutLen, COMP); } - if (ret == BUFFER_E) { + if (ret == LENGTH_ONLY_E) { key.idx = -4; ret = wc_ecc_export_x963_ex(&key, out, &outlen, COMP); } From fd7bf8d04d32297117fa63d1c916264e4ca32a1c Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 20 Jun 2022 20:32:15 +0200 Subject: [PATCH 07/12] Do resuming check as soon as we get a non-resumption msg --- src/internal.c | 24 ++++++++++++++++++------ src/ssl.c | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/internal.c b/src/internal.c index 98286ba8c..5c69e531a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -14766,6 +14766,24 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, } #endif + if (ssl->options.side == WOLFSSL_CLIENT_END) { + switch (type) { + case certificate: + case server_key_exchange: + case certificate_request: + case server_hello_done: + if (ssl->options.resuming) { + /* This can occur when ssl->sessionSecretCb is set. EAP-FAST + * (RFC 4851) allows for detecting server session resumption + * based on the msg received after the ServerHello. */ + WOLFSSL_MSG("Not resuming as thought"); + ssl->options.resuming = 0; + /* No longer resuming, reset peer authentication state. */ + ssl->options.peerAuthGood = 0; + } + } + } + switch (type) { case hello_request: @@ -14872,12 +14890,6 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, *inOutIdx += MacSize(ssl); #endif } - if (ssl->options.resuming) { - WOLFSSL_MSG("Not resuming as thought"); - ssl->options.resuming = 0; - /* CLIENT: No longer resuming, reset peer authentication state. */ - ssl->options.peerAuthGood = 0; - } break; case finished: diff --git a/src/ssl.c b/src/ssl.c index 3f19647b9..cf53a5a06 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -12148,6 +12148,7 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, /* CLIENT: Fail-safe for Server Authentication. */ if (!ssl->options.peerAuthGood) { WOLFSSL_MSG("Server authentication did not happen"); + ssl->error = NO_PEER_VERIFY; return WOLFSSL_FATAL_ERROR; } From 20e5c98b2cf99a370b72b961428cc2a466c0a306 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 5 Jul 2022 09:42:39 +0200 Subject: [PATCH 08/12] Error out when server indicates resumption but does full handshake --- src/internal.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/internal.c b/src/internal.c index 5c69e531a..785c6db27 100644 --- a/src/internal.c +++ b/src/internal.c @@ -14758,14 +14758,6 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, } } -#ifdef OPENSSL_EXTRA - if (ssl->CBIS != NULL){ - ssl->cbmode = SSL_CB_MODE_READ; - ssl->cbtype = type; - ssl->CBIS(ssl, SSL_CB_ACCEPT_LOOP, SSL_SUCCESS); - } -#endif - if (ssl->options.side == WOLFSSL_CLIENT_END) { switch (type) { case certificate: @@ -14773,6 +14765,7 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, case certificate_request: case server_hello_done: if (ssl->options.resuming) { +#ifdef WOLFSSL_WPAS /* This can occur when ssl->sessionSecretCb is set. EAP-FAST * (RFC 4851) allows for detecting server session resumption * based on the msg received after the ServerHello. */ @@ -14780,10 +14773,25 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, ssl->options.resuming = 0; /* No longer resuming, reset peer authentication state. */ ssl->options.peerAuthGood = 0; +#else + /* Fatal error. Only try to send an alert. RFC 5246 does not + * allow for reverting back to a full handshake after the + * server has indicated the intention to do a resumption. */ + (void)SendAlert(ssl, alert_fatal, unexpected_message); + return OUT_OF_ORDER_E; +#endif } } } +#ifdef OPENSSL_EXTRA + if (ssl->CBIS != NULL){ + ssl->cbmode = SSL_CB_MODE_READ; + ssl->cbtype = type; + ssl->CBIS(ssl, SSL_CB_ACCEPT_LOOP, SSL_SUCCESS); + } +#endif + switch (type) { case hello_request: From 39e53c2b7c29e4ccf1fb01e1c20dce0e04f95058 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 6 Jul 2022 11:59:29 +0200 Subject: [PATCH 09/12] Add wc_EccPublicKeyToDer_ex doxygen entry --- configure.ac | 2 +- doc/dox_comments/header_files/asn_public.h | 44 ++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ddef3c78d..7867a0545 100644 --- a/configure.ac +++ b/configure.ac @@ -4823,7 +4823,7 @@ AC_ARG_ENABLE([pkcs7], [ ENABLED_PKCS7=$enableval ], [ ENABLED_PKCS7=no ] ) - + if test "x$ENABLED_WPAS_DPP" = "xyes" then ENABLED_PKCS7=yes diff --git a/doc/dox_comments/header_files/asn_public.h b/doc/dox_comments/header_files/asn_public.h index 77decc8bc..b493cc4b8 100644 --- a/doc/dox_comments/header_files/asn_public.h +++ b/doc/dox_comments/header_files/asn_public.h @@ -1452,6 +1452,50 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen, int with_AlgCurve); +/*! + \ingroup ASN + + \brief This function converts the ECC public key to DER format. It + returns the size of buffer used. The public ECC key in DER format is stored + in output buffer. with_AlgCurve is a flag for when to include a header that + has the Algorithm and Curve information. The comp parameter + + \return >0 Success, size of buffer used + \return BAD_FUNC_ARG Returned if output or key is null. + \return LENGTH_ONLY_E Error in getting ECC public key size. + \return BUFFER_E Returned when output buffer is too small. + + \param key Pointer to ECC key + \param output Pointer to output buffer to write to. + \param inLen Size of buffer. + \param with_AlgCurve a flag for when to include a header that has the + Algorithm and Curve information. + \param comp Boolean value. If true the ECC public key will be written in + compressed form. If false it will be written in an uncompressed format. + + _Example_ + \code + ecc_key key; + wc_ecc_init(&key); + WC_WC_RNG rng; + wc_InitRng(&rng); + wc_ecc_make_key(&rng, 24, &key); + int derSz = // Some appropriate size for der; + byte der[derSz]; + + // Write out a compressed ECC key + if(wc_EccPublicKeyToDer_ex(&key, der, derSz, 1, 1) < 0) + { + // Error converting ECC public key to der + } + \endcode + + \sa wc_EccKeyToDer + \sa wc_EccPublicKeyDecode +*/ +int wc_EccPublicKeyToDer_ex(ecc_key* key, byte* output, + word32 inLen, int with_AlgCurve, int comp); + /*! \ingroup ASN From 63b4c475d4e637f89d08e1d6954a75c21da86971 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 6 Jul 2022 14:23:08 +0200 Subject: [PATCH 10/12] wolfSSL_set_session_secret_cb: fix for NULL input --- src/ssl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index cf53a5a06..8d45ebd13 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -10476,9 +10476,11 @@ int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx) ssl->sessionSecretCb = cb; ssl->sessionSecretCtx = ctx; - /* If using a pre-set key, assume session resumption. */ - ssl->session->sessionIDSz = 0; - ssl->options.resuming = 1; + if (cb != NULL) { + /* If using a pre-set key, assume session resumption. */ + ssl->session->sessionIDSz = 0; + ssl->options.resuming = 1; + } return WOLFSSL_SUCCESS; } From 9b085a44beb322672f4a6ad2f8a1738443701a96 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 6 Jul 2022 15:06:28 +0200 Subject: [PATCH 11/12] sessionSecretCb should only be called when a ticket is present --- src/internal.c | 14 +++++++++++--- src/tls13.c | 6 +++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/internal.c b/src/internal.c index 785c6db27..85991cff8 100644 --- a/src/internal.c +++ b/src/internal.c @@ -24636,8 +24636,12 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, #ifdef HAVE_SECRET_CALLBACK /* If a session secret callback exists, we are using that - * key instead of the saved session key. */ - ret = ret || (ssl->sessionSecretCb != NULL); + * key instead of the saved session key. Requires a ticket. */ + ret = ret || (ssl->sessionSecretCb != NULL +#ifdef HAVE_SESSION_TICKET + && ssl->session->ticketLen > 0 +#endif + ); #endif #ifdef HAVE_SESSION_TICKET @@ -24984,7 +24988,11 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, } #ifdef HAVE_SECRET_CALLBACK - if (ssl->sessionSecretCb != NULL) { + if (ssl->sessionSecretCb != NULL +#ifdef HAVE_SESSION_TICKET + && ssl->session->ticketLen > 0 +#endif + ) { int secretSz = SECRET_LEN; ret = ssl->sessionSecretCb(ssl, ssl->session->masterSecret, &secretSz, ssl->sessionSecretCtx); diff --git a/src/tls13.c b/src/tls13.c index 431c2e666..8606619c4 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -3921,7 +3921,11 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->options.serverState = SERVER_HELLO_COMPLETE; #ifdef HAVE_SECRET_CALLBACK - if (ssl->sessionSecretCb != NULL) { + if (ssl->sessionSecretCb != NULL +#ifdef HAVE_SESSION_TICKET + && ssl->session->ticketLen > 0 +#endif + ) { int secretSz = SECRET_LEN; ret = ssl->sessionSecretCb(ssl, ssl->session->masterSecret, &secretSz, ssl->sessionSecretCtx); From a171bebba40285de8357933b0f04a85cb97b84fa Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 6 Jul 2022 07:58:18 -0700 Subject: [PATCH 12/12] Fix the `wc_EccPublicKeyToDer_ex` doxy. --- doc/dox_comments/header_files/asn_public.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/doc/dox_comments/header_files/asn_public.h b/doc/dox_comments/header_files/asn_public.h index b493cc4b8..e1f5d8d3d 100644 --- a/doc/dox_comments/header_files/asn_public.h +++ b/doc/dox_comments/header_files/asn_public.h @@ -1416,8 +1416,8 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, \brief This function converts the ECC public key to DER format. It returns the size of buffer used. The public ECC key in DER format is stored - in output buffer. with_AlgCurve is a flag for when to include a header that - has the Algorithm and Curve information. + in output buffer. The with_AlgCurve flag will include a header that + has the Algorithm and Curve information \return >0 Success, size of buffer used \return BAD_FUNC_ARG Returned if output or key is null. @@ -1436,7 +1436,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, wc_ecc_init(&key); WC_WC_RNG rng; wc_InitRng(&rng); - wc_ecc_make_key(&rng, 24, &key); + wc_ecc_make_key(&rng, 32, &key); int derSz = // Some appropriate size for der; byte der[derSz]; @@ -1457,8 +1457,9 @@ int wc_EccPublicKeyToDer(ecc_key* key, byte* output, \brief This function converts the ECC public key to DER format. It returns the size of buffer used. The public ECC key in DER format is stored - in output buffer. with_AlgCurve is a flag for when to include a header that - has the Algorithm and Curve information. The comp parameter + in output buffer. The with_AlgCurve flag will include a header that + has the Algorithm and Curve information. The comp parameter determines if + the public key will be exported as compressed. \return >0 Success, size of buffer used \return BAD_FUNC_ARG Returned if output or key is null. @@ -1470,8 +1471,8 @@ int wc_EccPublicKeyToDer(ecc_key* key, byte* output, \param inLen Size of buffer. \param with_AlgCurve a flag for when to include a header that has the Algorithm and Curve information. - \param comp Boolean value. If true the ECC public key will be written in - compressed form. If false it will be written in an uncompressed format. + \param comp If 1 (non-zero) the ECC public key will be written in + compressed form. If 0 it will be written in an uncompressed format. _Example_ \code @@ -1479,7 +1480,7 @@ int wc_EccPublicKeyToDer(ecc_key* key, byte* output, wc_ecc_init(&key); WC_WC_RNG rng; wc_InitRng(&rng); - wc_ecc_make_key(&rng, 24, &key); + wc_ecc_make_key(&rng, 32, &key); int derSz = // Some appropriate size for der; byte der[derSz];