@@ -2922,6 +2922,108 @@ int test_tls13_duplicate_extension(void)
29222922}
29232923
29242924
2925+ #if defined(WOLFSSL_TLS13 ) && defined(HAVE_ECH ) && \
2926+ !defined(NO_WOLFSSL_SERVER ) && !defined(NO_FILESYSTEM ) && \
2927+ (!defined(NO_RSA ) || defined(HAVE_ECC ))
2928+ static int DupEchSend (WOLFSSL * ssl , char * buf , int sz , void * ctx )
2929+ {
2930+ (void )ssl ;
2931+ (void )buf ;
2932+ (void )sz ;
2933+ (void )ctx ;
2934+
2935+ return sz ;
2936+ }
2937+ static int DupEchRecv (WOLFSSL * ssl , char * buf , int sz , void * ctx )
2938+ {
2939+ WOLFSSL_BUFFER_INFO * msg = (WOLFSSL_BUFFER_INFO * )ctx ;
2940+ int len = (int )msg -> length ;
2941+
2942+ (void )ssl ;
2943+ (void )sz ;
2944+
2945+ if (len > sz )
2946+ len = sz ;
2947+ XMEMCPY (buf , msg -> buffer , len );
2948+ msg -> buffer += len ;
2949+ msg -> length -= len ;
2950+
2951+ return len ;
2952+ }
2953+ #endif
2954+
2955+ /* Test detection of duplicate ECH extension (type 0xfe0d) in ClientHello.
2956+ * ECH has a semaphore mapping in TLSX_ToSemaphore() and needs to be included
2957+ * in the duplicate-detection gate in TLSX_Parse(). RFC 8446 section 4.2
2958+ * requires rejecting messages with duplicate extensions.
2959+ */
2960+ int test_tls13_duplicate_ech_extension (void )
2961+ {
2962+ EXPECT_DECLS ;
2963+ #if defined(WOLFSSL_TLS13 ) && defined(HAVE_ECH ) && \
2964+ !defined(NO_WOLFSSL_SERVER ) && !defined(NO_FILESYSTEM ) && \
2965+ (!defined(NO_RSA ) || defined(HAVE_ECC ))
2966+ /* TLS 1.3 ClientHello with two ECH extensions (type 0xfe0d).
2967+ * Extensions block contains: supported_versions + ECH + ECH (dup). */
2968+ const unsigned char clientHelloDupEch [] = {
2969+ 0x16 , 0x03 , 0x03 , 0x00 , 0x40 , 0x01 , 0x00 , 0x00 ,
2970+ 0x3c , 0x03 , 0x03 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 ,
2971+ 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 ,
2972+ 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 ,
2973+ 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 ,
2974+ 0x01 , 0x01 , 0x01 , 0x00 , 0x00 , 0x02 , 0x13 , 0x01 ,
2975+ 0x01 , 0x00 , 0x00 , 0x11 , 0x00 , 0x2b , 0x00 , 0x03 ,
2976+ 0x02 , 0x03 , 0x04 , 0xfe , 0x0d , 0x00 , 0x01 , 0x00 ,
2977+ 0xfe , 0x0d , 0x00 , 0x01 , 0x00
2978+ };
2979+ WOLFSSL_BUFFER_INFO msg ;
2980+ const char * testCertFile ;
2981+ const char * testKeyFile ;
2982+ WOLFSSL_CTX * ctx = NULL ;
2983+ WOLFSSL * ssl = NULL ;
2984+
2985+ #ifndef NO_RSA
2986+ testCertFile = svrCertFile ;
2987+ testKeyFile = svrKeyFile ;
2988+ #elif defined(HAVE_ECC )
2989+ testCertFile = eccCertFile ;
2990+ testKeyFile = eccKeyFile ;
2991+ #endif
2992+
2993+ ExpectNotNull (ctx = wolfSSL_CTX_new (wolfTLSv1_3_server_method ()));
2994+
2995+ ExpectTrue (wolfSSL_CTX_use_certificate_file (ctx , testCertFile ,
2996+ CERT_FILETYPE ));
2997+ ExpectTrue (wolfSSL_CTX_use_PrivateKey_file (ctx , testKeyFile ,
2998+ CERT_FILETYPE ));
2999+
3000+ /* Read from 'msg'. */
3001+ wolfSSL_SetIORecv (ctx , DupEchRecv );
3002+ /* No where to send to - dummy sender. */
3003+ wolfSSL_SetIOSend (ctx , DupEchSend );
3004+
3005+ ssl = wolfSSL_new (ctx );
3006+ ExpectNotNull (ssl );
3007+
3008+ msg .buffer = (unsigned char * )clientHelloDupEch ;
3009+ msg .length = (unsigned int )sizeof (clientHelloDupEch );
3010+ wolfSSL_SetIOReadCtx (ssl , & msg );
3011+
3012+ ExpectIntNE (wolfSSL_accept (ssl ), WOLFSSL_SUCCESS );
3013+ /* Can return duplicate ext error or socket error if the peer closed
3014+ * down while sending alert. */
3015+ if (wolfSSL_get_error (ssl , 0 ) != WC_NO_ERR_TRACE (SOCKET_ERROR_E )) {
3016+ ExpectIntEQ (wolfSSL_get_error (ssl , 0 ),
3017+ WC_NO_ERR_TRACE (DUPLICATE_TLS_EXT_E ));
3018+ }
3019+
3020+ wolfSSL_free (ssl );
3021+ wolfSSL_CTX_free (ctx );
3022+ #endif
3023+ return EXPECT_RESULT ();
3024+ }
3025+
3026+
29253027int test_key_share_mismatch (void )
29263028{
29273029 EXPECT_DECLS ;
0 commit comments