@@ -119,4 +119,202 @@ int copy_file(const char* in, const char* out)
119119}
120120#endif /* !NO_FILESYSTEM */
121121
122+ #if !defined(NO_FILESYSTEM ) && !defined(NO_CERTS ) && !defined(NO_RSA ) && \
123+ !defined(NO_WOLFSSL_SERVER ) && !defined(NO_WOLFSSL_CLIENT )
124+
125+ /* This set of memio functions allows for more fine tuned control of the TLS
126+ * connection operations. For new tests, try to use ssl_memio first. */
127+
128+ #define HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES
129+
130+ #define TEST_MEMIO_BUF_SZ (64 * 1024)
131+ struct test_memio_ctx
132+ {
133+ byte c_buff [TEST_MEMIO_BUF_SZ ];
134+ int c_len ;
135+ const char * c_ciphers ;
136+ byte s_buff [TEST_MEMIO_BUF_SZ ];
137+ int s_len ;
138+ const char * s_ciphers ;
139+ };
140+
141+ int test_memio_do_handshake (WOLFSSL * ssl_c , WOLFSSL * ssl_s ,
142+ int max_rounds , int * rounds );
143+ int test_memio_setup (struct test_memio_ctx * ctx ,
144+ WOLFSSL_CTX * * ctx_c , WOLFSSL_CTX * * ctx_s , WOLFSSL * * ssl_c , WOLFSSL * * ssl_s ,
145+ method_provider method_c , method_provider method_s );
146+
147+ static WC_INLINE int test_memio_write_cb (WOLFSSL * ssl , char * data , int sz ,
148+ void * ctx )
149+ {
150+ struct test_memio_ctx * test_ctx ;
151+ byte * buf ;
152+ int * len ;
153+
154+ test_ctx = (struct test_memio_ctx * )ctx ;
155+
156+ if (wolfSSL_GetSide (ssl ) == WOLFSSL_SERVER_END ) {
157+ buf = test_ctx -> c_buff ;
158+ len = & test_ctx -> c_len ;
159+ }
160+ else {
161+ buf = test_ctx -> s_buff ;
162+ len = & test_ctx -> s_len ;
163+ }
164+
165+ if ((unsigned )(* len + sz ) > TEST_MEMIO_BUF_SZ )
166+ return WOLFSSL_CBIO_ERR_WANT_READ ;
167+
168+ XMEMCPY (buf + * len , data , sz );
169+ * len += sz ;
170+
171+ return sz ;
172+ }
173+
174+ static WC_INLINE int test_memio_read_cb (WOLFSSL * ssl , char * data , int sz ,
175+ void * ctx )
176+ {
177+ struct test_memio_ctx * test_ctx ;
178+ int read_sz ;
179+ byte * buf ;
180+ int * len ;
181+
182+ test_ctx = (struct test_memio_ctx * )ctx ;
183+
184+ if (wolfSSL_GetSide (ssl ) == WOLFSSL_SERVER_END ) {
185+ buf = test_ctx -> s_buff ;
186+ len = & test_ctx -> s_len ;
187+ }
188+ else {
189+ buf = test_ctx -> c_buff ;
190+ len = & test_ctx -> c_len ;
191+ }
192+
193+ if (* len == 0 )
194+ return WOLFSSL_CBIO_ERR_WANT_READ ;
195+
196+ read_sz = sz < * len ? sz : * len ;
197+
198+ XMEMCPY (data , buf , read_sz );
199+ XMEMMOVE (buf , buf + read_sz , * len - read_sz );
200+
201+ * len -= read_sz ;
202+
203+ return read_sz ;
204+ }
205+
206+ int test_memio_do_handshake (WOLFSSL * ssl_c , WOLFSSL * ssl_s ,
207+ int max_rounds , int * rounds )
208+ {
209+ byte handshake_complete = 0 , hs_c = 0 , hs_s = 0 ;
210+ int ret , err ;
211+
212+ if (rounds != NULL )
213+ * rounds = 0 ;
214+ while (!handshake_complete && max_rounds > 0 ) {
215+ if (!hs_c ) {
216+ ret = wolfSSL_connect (ssl_c );
217+ if (ret == WOLFSSL_SUCCESS ) {
218+ hs_c = 1 ;
219+ }
220+ else {
221+ err = wolfSSL_get_error (ssl_c , ret );
222+ if (err != WOLFSSL_ERROR_WANT_READ &&
223+ err != WOLFSSL_ERROR_WANT_WRITE )
224+ return -1 ;
225+ }
226+ }
227+ if (!hs_s ) {
228+ ret = wolfSSL_accept (ssl_s );
229+ if (ret == WOLFSSL_SUCCESS ) {
230+ hs_s = 1 ;
231+ }
232+ else {
233+ err = wolfSSL_get_error (ssl_s , ret );
234+ if (err != WOLFSSL_ERROR_WANT_READ &&
235+ err != WOLFSSL_ERROR_WANT_WRITE )
236+ return -1 ;
237+ }
238+ }
239+ handshake_complete = hs_c && hs_s ;
240+ max_rounds -- ;
241+ if (rounds != NULL )
242+ * rounds = * rounds + 1 ;
243+ }
244+
245+ if (!handshake_complete )
246+ return -1 ;
247+
248+ return 0 ;
249+ }
250+
251+ int test_memio_setup (struct test_memio_ctx * ctx ,
252+ WOLFSSL_CTX * * ctx_c , WOLFSSL_CTX * * ctx_s , WOLFSSL * * ssl_c , WOLFSSL * * ssl_s ,
253+ method_provider method_c , method_provider method_s )
254+ {
255+ int ret ;
256+
257+ if (ctx_c != NULL && * ctx_c == NULL ) {
258+ * ctx_c = wolfSSL_CTX_new (method_c ());
259+ if (* ctx_c == NULL )
260+ return -1 ;
261+ #ifndef NO_CERTS
262+ ret = wolfSSL_CTX_load_verify_locations (* ctx_c , caCertFile , 0 );
263+ if (ret != WOLFSSL_SUCCESS )
264+ return -1 ;
265+ #endif /* NO_CERTS */
266+ wolfSSL_SetIORecv (* ctx_c , test_memio_read_cb );
267+ wolfSSL_SetIOSend (* ctx_c , test_memio_write_cb );
268+ if (ctx -> c_ciphers != NULL ) {
269+ ret = wolfSSL_CTX_set_cipher_list (* ctx_c , ctx -> c_ciphers );
270+ if (ret != WOLFSSL_SUCCESS )
271+ return -1 ;
272+ }
273+ }
274+
275+ if (ctx_s != NULL && * ctx_s == NULL ) {
276+ * ctx_s = wolfSSL_CTX_new (method_s ());
277+ if (* ctx_s == NULL )
278+ return -1 ;
279+ #ifndef NO_CERTS
280+ ret = wolfSSL_CTX_use_PrivateKey_file (* ctx_s , svrKeyFile ,
281+ WOLFSSL_FILETYPE_PEM );
282+ if (ret != WOLFSSL_SUCCESS )
283+ return - -1 ;
284+ ret = wolfSSL_CTX_use_certificate_file (* ctx_s , svrCertFile ,
285+ WOLFSSL_FILETYPE_PEM );
286+ if (ret != WOLFSSL_SUCCESS )
287+ return -1 ;
288+ #endif
289+ wolfSSL_SetIORecv (* ctx_s , test_memio_read_cb );
290+ wolfSSL_SetIOSend (* ctx_s , test_memio_write_cb );
291+ if (ctx -> s_ciphers != NULL ) {
292+ ret = wolfSSL_CTX_set_cipher_list (* ctx_s , ctx -> s_ciphers );
293+ if (ret != WOLFSSL_SUCCESS )
294+ return -1 ;
295+ }
296+ }
297+
298+ if (ctx_c != NULL && ssl_c != NULL ) {
299+ * ssl_c = wolfSSL_new (* ctx_c );
300+ if (* ssl_c == NULL )
301+ return -1 ;
302+ wolfSSL_SetIOWriteCtx (* ssl_c , ctx );
303+ wolfSSL_SetIOReadCtx (* ssl_c , ctx );
304+ }
305+ if (ctx_s != NULL && ssl_s != NULL ) {
306+ * ssl_s = wolfSSL_new (* ctx_s );
307+ if (* ssl_s == NULL )
308+ return -1 ;
309+ wolfSSL_SetIOWriteCtx (* ssl_s , ctx );
310+ wolfSSL_SetIOReadCtx (* ssl_s , ctx );
311+ #if !defined(NO_DH )
312+ SetDH (* ssl_s );
313+ #endif
314+ }
315+
316+ return 0 ;
317+ }
318+ #endif
319+
122320#endif /* WOLFSSL_TEST_UTILS_INCLUDED */
0 commit comments