@@ -1444,8 +1444,119 @@ static void test_wolfSSH_SFTP_SendReadPacket(void)
14441444 ThreadJoin (serThread );
14451445}
14461446
1447+ static void sftp_rekey_test (int nonBlock )
1448+ {
1449+ func_args ser ;
1450+ tcp_ready ready ;
1451+ int argsCount ;
1452+ int err ;
1453+ WS_SOCKET_T clientFd ;
1454+ WS_SFTPNAME * ls ;
1455+ int i ;
1456+
1457+ const char * args [10 ];
1458+ WOLFSSH_CTX * ctx = NULL ;
1459+ WOLFSSH * ssh = NULL ;
1460+
1461+ THREAD_TYPE serThread ;
1462+
1463+ WMEMSET (& ser , 0 , sizeof (func_args ));
1464+
1465+ argsCount = 0 ;
1466+ args [argsCount ++ ] = "." ;
1467+ args [argsCount ++ ] = "-1" ;
1468+ #ifndef USE_WINDOWS_API
1469+ args [argsCount ++ ] = "-p" ;
1470+ args [argsCount ++ ] = "0" ;
1471+ #endif
1472+ ser .argv = (char * * )args ;
1473+ ser .argc = argsCount ;
1474+ ser .signal = & ready ;
1475+ InitTcpReady (ser .signal );
1476+ ThreadStart (echoserver_test , (void * )& ser , & serThread );
1477+ WaitTcpReady (& ready );
1478+
1479+ sftp_client_connect (& ctx , & ssh , ready .port );
1480+ AssertNotNull (ctx );
1481+ AssertNotNull (ssh );
1482+
1483+ /* Handshake completed in blocking mode; switch to non-blocking so the
1484+ * LS/rekey phase exercises the WS_WANT_READ/WS_WANT_WRITE early-return
1485+ * path in buffer_send/buffer_read. */
1486+ clientFd = wolfSSH_get_fd (ssh );
1487+ if (nonBlock ) {
1488+ tcp_set_nonblocking (& clientFd );
1489+ }
1490+
1491+ /* Low threshold forces a rekey mid-SFTP-operation. In blocking mode the
1492+ * buffer_read/buffer_send fixes drive the rekey internally; in non-blocking
1493+ * mode the retry loop below advances it on
1494+ * WS_WANT_READ/WS_WANT_WRITE/WS_REKEYING. */
1495+ wolfSSH_SetHighwater (ssh , 256 );
1496+
1497+ ls = NULL ;
1498+ for (i = 0 ; i < 3 ; i ++ ) {
1499+ /* Retry loop is a single pass in blocking mode; for non-blocking it
1500+ * drives the rekey forward while LS reports a want/rekey status. */
1501+ do {
1502+ ls = wolfSSH_SFTP_LS (ssh , (char * )"." );
1503+ err = wolfSSH_get_error (ssh );
1504+ if (ls == NULL && (err == WS_WANT_READ || err == WS_WANT_WRITE
1505+ || err == WS_REKEYING )) {
1506+ tcp_select (clientFd , 1 );
1507+ }
1508+ } while (ls == NULL && (err == WS_WANT_READ || err == WS_WANT_WRITE
1509+ || err == WS_REKEYING ));
1510+ AssertNotNull (ls );
1511+ wolfSSH_SFTPNAME_list_free (ls );
1512+ ls = NULL ;
1513+ }
1514+
1515+ do {
1516+ argsCount = wolfSSH_shutdown (ssh );
1517+ err = wolfSSH_get_error (ssh );
1518+ if (argsCount != WS_SUCCESS && (err == WS_WANT_READ
1519+ || err == WS_WANT_WRITE || err == WS_REKEYING )) {
1520+ tcp_select (clientFd , 1 );
1521+ }
1522+ } while (argsCount != WS_SUCCESS && (err == WS_WANT_READ
1523+ || err == WS_WANT_WRITE || err == WS_REKEYING ));
1524+ if (argsCount == WS_SOCKET_ERROR_E ) {
1525+ argsCount = WS_SUCCESS ;
1526+ }
1527+ #if DEFAULT_HIGHWATER_MARK < 8000
1528+ if (argsCount == WS_REKEYING ) {
1529+ /* in cases where highwater mark is really small a re-key could happen */
1530+ argsCount = WS_SUCCESS ;
1531+ }
1532+ #endif
1533+ AssertIntEQ (argsCount , WS_SUCCESS );
1534+
1535+ clientFd = wolfSSH_get_fd (ssh );
1536+ WCLOSESOCKET (clientFd );
1537+
1538+ wolfSSH_free (ssh );
1539+ wolfSSH_CTX_free (ctx );
1540+ #ifdef WOLFSSH_ZEPHYR
1541+ k_sleep (Z_TIMEOUT_TICKS (100 ));
1542+ #endif
1543+ ThreadJoin (serThread );
1544+ }
1545+
1546+ static void test_wolfSSH_SFTP_ReKey (void )
1547+ {
1548+ sftp_rekey_test (0 );
1549+ }
1550+
1551+ static void test_wolfSSH_SFTP_ReKey_NonBlock (void )
1552+ {
1553+ sftp_rekey_test (1 );
1554+ }
1555+
14471556#else /* WOLFSSH_SFTP && !NO_WOLFSSH_CLIENT && !SINGLE_THREADED */
14481557static void test_wolfSSH_SFTP_SendReadPacket (void ) { ; }
1558+ static void test_wolfSSH_SFTP_ReKey (void ) { ; }
1559+ static void test_wolfSSH_SFTP_ReKey_NonBlock (void ) { ; }
14491560#endif /* WOLFSSH_SFTP && !NO_WOLFSSH_CLIENT && !SINGLE_THREADED */
14501561
14511562
@@ -2159,6 +2270,8 @@ int wolfSSH_ApiTest(int argc, char** argv)
21592270
21602271 /* SFTP tests */
21612272 test_wolfSSH_SFTP_SendReadPacket ();
2273+ test_wolfSSH_SFTP_ReKey ();
2274+ test_wolfSSH_SFTP_ReKey_NonBlock ();
21622275
21632276 /* Either SCP or SFTP */
21642277 test_wolfSSH_RealPath ();
0 commit comments