4343
4444
4545#ifndef WOLFHSM_CFG_NO_CRYPTO
46+
4647/* returns 1 (true) if the error passed in is a notice for non blocking
4748 * 0 if the error is a fatal error */
4849static int NonBlockingError (int err )
@@ -63,40 +64,26 @@ int posixTransportTls_InitConnect(void* context, const void* config,
6364 (posixTransportTlsClientContext * )context ;
6465 posixTransportTlsConfig * cfg = (posixTransportTlsConfig * )config ;
6566 int rc ;
67+ WOLFSSL_CTX * ssl_ctx ;
6668
6769 if (!ctx || !cfg ) {
6870 return WH_ERROR_BADARGS ;
6971 }
7072
73+ /* Save configured WOLFSSL_CTX and clear rest of the context struct */
74+ ssl_ctx = ctx -> ssl_ctx ;
75+ memset (ctx , 0 , sizeof (posixTransportTlsClientContext ));
76+ ctx -> ssl_ctx = ssl_ctx ;
77+
7178 /* Setup underlying TCP transport */
7279 rc = posixTransportTcp_InitConnect ((void * )& ctx -> tcpCtx , cfg , connectcb ,
7380 connectcb_arg );
7481 if (rc != WH_ERROR_OK ) {
7582 return rc ;
7683 }
7784
78- /* Create SSL object if not already created */
79- if (ctx -> ssl == NULL ) {
80- if (posixTransportTcp_GetConnectFd (
81- (void * )& ctx -> tcpCtx , & ctx -> connect_fd_p1 ) != WH_ERROR_OK ) {
82- return WH_ERROR_NOTREADY ;
83- }
84-
85- ctx -> ssl = wolfSSL_new (ctx -> ssl_ctx );
86- if (!ctx -> ssl ) {
87- posixTransportTcp_CleanupConnect ((void * )& ctx -> tcpCtx );
88- return WH_ERROR_ABORTED ;
89- }
90-
91- /* Set the socket file descriptor */
92- rc = wolfSSL_set_fd (ctx -> ssl , ctx -> connect_fd_p1 );
93- if (rc != WOLFSSL_SUCCESS ) {
94- wolfSSL_free (ctx -> ssl );
95- ctx -> ssl = NULL ;
96- posixTransportTcp_CleanupConnect ((void * )& ctx -> tcpCtx );
97- return WH_ERROR_ABORTED ;
98- }
99- }
85+ /* At the point of the TCP claiming to be connected, the TLS handshake will
86+ * happen during send/recv calls */
10087 if (ctx -> connectcb != NULL ) {
10188 ctx -> connectcb (ctx -> connectcb_arg , WH_COMM_CONNECTED );
10289 }
@@ -119,7 +106,7 @@ int posixTransportTls_SendRequest(void* context, uint16_t size,
119106 posixTransportTlsClientContext * ctx =
120107 (posixTransportTlsClientContext * )context ;
121108 int err ;
122- int rc ;
109+ int rc = 0 ;
123110
124111 if (!ctx || !data || size == 0 ) {
125112 return WH_ERROR_BADARGS ;
@@ -131,13 +118,61 @@ int posixTransportTls_SendRequest(void* context, uint16_t size,
131118 return WH_ERROR_NOTREADY ;
132119 }
133120
121+ /* Create SSL object if not already created
122+ * (posixTransportTcp_HandleConnect can change the socket used if server
123+ * is not listening yet, thats why we need to wait to set the fd in
124+ * wolfSSL until after the connect() has completed) */
125+ if (ctx -> ssl == NULL ) {
126+ if (posixTransportTcp_GetConnectFd (
127+ (void * )& ctx -> tcpCtx , & ctx -> connect_fd_p1 ) != WH_ERROR_OK ) {
128+ return WH_ERROR_NOTREADY ;
129+ }
130+
131+ ctx -> ssl = wolfSSL_new (ctx -> ssl_ctx );
132+ if (!ctx -> ssl ) {
133+ posixTransportTcp_CleanupConnect ((void * )& ctx -> tcpCtx );
134+ return WH_ERROR_ABORTED ;
135+ }
136+
137+ /* Set the current socket file descriptor */
138+ rc = wolfSSL_set_fd (ctx -> ssl , ctx -> connect_fd_p1 );
139+ if (rc != WOLFSSL_SUCCESS ) {
140+ wolfSSL_free (ctx -> ssl );
141+ ctx -> ssl = NULL ;
142+ posixTransportTcp_CleanupConnect ((void * )& ctx -> tcpCtx );
143+ return WH_ERROR_ABORTED ;
144+ }
145+ }
146+
134147 rc = wolfSSL_connect (ctx -> ssl );
135148 err = wolfSSL_get_error (ctx -> ssl , rc );
136149 if (rc != WOLFSSL_SUCCESS ) {
137150 if (NonBlockingError (err )) {
138151 return WH_ERROR_NOTREADY ;
139152 }
140153 else {
154+ if (err == SOCKET_ERROR_E ) {
155+ /* There is a case where TCP connect() returned successfully
156+ * but the server has not called accept() and the pending
157+ * send was in the TCP backlog waiting on the server. But
158+ * if the server closes down the listen port then RST gets
159+ * returned. Retry the TCP connect() */
160+ wolfSSL_free (ctx -> ssl );
161+ ctx -> ssl = NULL ;
162+
163+ /* Close the failed socket fd and set state for retry */
164+ if (ctx -> tcpCtx .connect_fd_p1 != 0 ) {
165+ close (ctx -> tcpCtx .connect_fd_p1 - 1 );
166+ ctx -> tcpCtx .connect_fd_p1 = 0 ;
167+ }
168+ ctx -> tcpCtx .state = PTT_STATE_UNCONNECTED ;
169+ return WH_ERROR_NOTREADY ;
170+
171+ }
172+
173+ if (ctx -> connectcb != NULL ) {
174+ ctx -> connectcb (ctx -> connectcb_arg , WH_COMM_DISCONNECTED );
175+ }
141176 return WH_ERROR_ABORTED ;
142177 }
143178 }
@@ -218,6 +253,8 @@ int posixTransportTls_CleanupConnect(void* context)
218253 wolfSSL_free (ctx -> ssl );
219254 }
220255 ctx -> ssl = NULL ;
256+ ctx -> state = PTTLS_STATE_UNCONNECTED ;
257+ ctx -> connect_fd_p1 = 0 ;
221258 posixTransportTcp_CleanupConnect ((void * )& ctx -> tcpCtx );
222259 return WH_ERROR_OK ;
223260#else
@@ -237,28 +274,29 @@ int posixTransportTls_InitListen(void* context, const void* config,
237274 (posixTransportTlsServerContext * )context ;
238275 posixTransportTlsConfig * cfg = (posixTransportTlsConfig * )config ;
239276 int rc ;
277+ WOLFSSL_CTX * ssl_ctx ;
240278
241279 if (!ctx || !cfg ) {
242280 return WH_ERROR_BADARGS ;
243281 }
244282
283+ /* Save configured WOLFSSL_CTX and clear rest of the context struct */
284+ ssl_ctx = ctx -> ssl_ctx ;
285+ memset (ctx , 0 , sizeof (posixTransportTlsServerContext ));
286+ ctx -> ssl_ctx = ssl_ctx ;
287+
245288 /* Initialize TCP server context */
246289 rc = posixTransportTcp_InitListen (& ctx -> tcpCtx , cfg , connectcb ,
247290 connectcb_arg );
248291 if (rc != WH_ERROR_OK ) {
249292 return rc ;
250293 }
251294
252- /* Copy TCP context fields to TLS context for compatibility */
253295 ctx -> connectcb = connectcb ;
254296 ctx -> connectcb_arg = connectcb_arg ;
255297 ctx -> server_addr = ctx -> tcpCtx .server_addr ;
256298 ctx -> listen_fd_p1 = ctx -> tcpCtx .listen_fd_p1 ;
257299
258-
259- /* Load private key and certificate */
260-
261- /* Connecting is handled internally so we need server to call recv */
262300 if (ctx -> connectcb != NULL ) {
263301 ctx -> connectcb (ctx -> connectcb_arg , WH_COMM_CONNECTED );
264302 }
@@ -409,6 +447,8 @@ int posixTransportTls_CleanupListen(void* context)
409447 }
410448
411449 if (ctx -> ssl ) {
450+ /* Give a quick shutdown signal to the client but do not wait for a
451+ * response from the client before tearing down the transport. */
412452 (void )wolfSSL_shutdown (ctx -> ssl );
413453 wolfSSL_free (ctx -> ssl );
414454 ctx -> ssl = NULL ;
0 commit comments