Skip to content

Commit e0390b6

Browse files
committed
Refactor OCSP responder error handling and improve HTTP response sending logic; add wolfCLU_SendAll function for reliable socket writes
1 parent ee60365 commit e0390b6

6 files changed

Lines changed: 89 additions & 55 deletions

File tree

src/ocsp/clu_ocsp.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -818,15 +818,13 @@ static int ocspResponder(OcspResponderConfig* config)
818818

819819
/* Accept connection */
820820
clientfd = wolfCLU_ServerAccept(sockfd);
821-
if (clientfd == INVALID_SOCKET) {
822-
continue;
823-
}
821+
if (clientfd == INVALID_SOCKET)
822+
goto continue_loop;
824823

825824
/* Read request from transport layer */
826825
ret = transportReadRequest(clientfd, transportType, &ocspReq, &ocspReqSz);
827-
if (ret != WOLFCLU_SUCCESS) {
828-
break;
829-
}
826+
if (ret != WOLFCLU_SUCCESS)
827+
goto continue_loop;
830828

831829
/* Process OCSP request and generate response */
832830
respSz = sizeof(respBuffer);
@@ -862,14 +860,13 @@ static int ocspResponder(OcspResponderConfig* config)
862860
if (ret != 0) {
863861
/* If we can't encode an error response, send HTTP/SCGI error */
864862
transportSendError(clientfd, transportType, 500, "Internal Server Error");
865-
break;
863+
goto continue_loop;
866864
}
867865
}
868866

869867
/* Send response via transport layer */
870-
if (transportSendResponse(clientfd, transportType, respBuffer, (int)respSz) != 0) {
871-
break;
872-
}
868+
if (transportSendResponse(clientfd, transportType, respBuffer, (int)respSz) != 0)
869+
goto continue_loop;
873870

874871
requestsProcessed++;
875872

@@ -878,7 +875,9 @@ static int ocspResponder(OcspResponderConfig* config)
878875
break;
879876
}
880877

881-
wolfCLU_ServerClose(clientfd);
878+
continue_loop:
879+
if (clientfd != INVALID_SOCKET)
880+
wolfCLU_ServerClose(clientfd);
882881
clientfd = INVALID_SOCKET;
883882
}
884883

src/tools/clu_http.c

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,25 @@ int wolfCLU_HttpServerRecv(SOCKET_T clientfd, byte* buffer, int bufferSz)
295295
return totalLen;
296296
}
297297

298+
/* Send all bytes, looping on partial writes and EINTR */
299+
int wolfCLU_SendAll(SOCKET_T sockfd, const char* buf, int len)
300+
{
301+
int sent = 0;
302+
while (sent < len) {
303+
int n = (int)send(sockfd, buf + sent, (size_t)(len - sent), 0);
304+
if (n < 0) {
305+
#ifndef _WIN32
306+
if (errno == EINTR) continue;
307+
#endif
308+
return -1;
309+
}
310+
if (n == 0)
311+
return -1;
312+
sent += n;
313+
}
314+
return sent;
315+
}
316+
298317
/**
299318
* @brief Send an HTTP response with OCSP content
300319
* @param clientfd client socket descriptor
@@ -307,7 +326,6 @@ int wolfCLU_HttpServerSendOcspResponse(SOCKET_T clientfd, const byte* body,
307326
{
308327
char header[512];
309328
int headerLen;
310-
int sent;
311329

312330
headerLen = XSNPRINTF(header, sizeof(header),
313331
"HTTP/1.0 200 OK\r\n"
@@ -321,15 +339,13 @@ int wolfCLU_HttpServerSendOcspResponse(SOCKET_T clientfd, const byte* body,
321339
}
322340

323341
/* Send header */
324-
sent = (int)send(clientfd, header, (size_t)headerLen, 0);
325-
if (sent != headerLen) {
342+
if (wolfCLU_SendAll(clientfd, header, headerLen) != headerLen) {
326343
return -1;
327344
}
328345

329346
/* Send body */
330347
if (bodySz > 0) {
331-
sent = (int)send(clientfd, (const char*)body, (size_t)bodySz, 0);
332-
if (sent != bodySz) {
348+
if (wolfCLU_SendAll(clientfd, (const char*)body, bodySz) != bodySz) {
333349
return -1;
334350
}
335351
}
@@ -390,12 +406,18 @@ int wolfCLU_HttpServerParseRequest(const byte* httpReq, int httpReqSz,
390406
{
391407
const char* contentLen;
392408
const char* bodyStart;
409+
int bodyAvail;
393410

394411
*body = NULL;
395412
*bodySz = 0;
396413

414+
if (httpReqSz < (int)XSTR_SIZEOF("POST ")) {
415+
return -1;
416+
}
417+
397418
/* Check for POST method */
398-
if (XSTRNCMP((char*)httpReq, "POST ", 5) != 0) {
419+
if (XSTRNCMP((char*)httpReq, "POST ",
420+
XSTR_SIZEOF("POST ")) != 0) {
399421
return -1;
400422
}
401423

@@ -405,22 +427,26 @@ int wolfCLU_HttpServerParseRequest(const byte* httpReq, int httpReqSz,
405427
contentLen = XSTRSTR((char*)httpReq, "content-length:");
406428
}
407429
if (contentLen) {
408-
*bodySz = XATOI(contentLen + 15);
409-
if (*bodySz < 0) {
430+
*bodySz = XATOI(contentLen + XSTR_SIZEOF("Content-Length:"));
431+
if (*bodySz <= 0) {
410432
return -1;
411433
}
412434
}
413435

414-
/* Find body (after \r\n\r\n) */
415-
bodyStart = XSTRSTR((char*)httpReq, "\r\n\r\n");
416-
if (bodyStart) {
417-
*body = (const byte*)(bodyStart + 4);
418-
/* Use Content-Length if available, otherwise use remaining data */
419-
if (*bodySz == 0) {
420-
*bodySz = httpReqSz - (int)(*body - httpReq);
421-
}
422-
return 0;
436+
/* Find body (has to appear after headers) */
437+
bodyStart = XSTRSTR((char*)contentLen, "\r\n\r\n");
438+
if (!bodyStart)
439+
return -1;
440+
bodyAvail = (int)(((char*)httpReq + httpReqSz) -
441+
(bodyStart + XSTR_SIZEOF("\r\n\r\n")));
442+
/* Use Content-Length if available, otherwise use
443+
* remaining data. Verify how much body we have. */
444+
if (*bodySz == 0) {
445+
*bodySz = bodyAvail;
423446
}
424-
425-
return -1;
447+
else if (*bodySz > bodyAvail) {
448+
return -1;
449+
}
450+
*body = (const byte*)(bodyStart + XSTR_SIZEOF("\r\n\r\n"));
451+
return 0;
426452
}

src/tools/clu_pem_der.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static int loadFileToDer(const char* filename, byte** der, word32* derSz, int pe
5555
return -1;
5656
}
5757

58-
buf = (byte*)XMALLOC(bufSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
58+
buf = (byte*)XMALLOC(bufSz + 1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
5959
if (buf == NULL) {
6060
wolfSSL_BIO_free(bio);
6161
return -1;
@@ -68,6 +68,7 @@ static int loadFileToDer(const char* filename, byte** der, word32* derSz, int pe
6868
return -1;
6969
}
7070
wolfSSL_BIO_free(bio);
71+
buf[bufSz] = '\0';
7172

7273
/* Check if PEM format */
7374
isPem = (XSTRSTR((char*)buf, "-----BEGIN") != NULL) ? 1 : 0;

src/tools/clu_scgi.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,31 @@ static int parseHeaders(const byte* headers, int headerLen, ScgiRequest* req)
118118

119119
while (pos < headerLen) {
120120
const char* key = (const char*)(headers + pos);
121-
int keyLen = (int)XSTRLEN(key);
121+
const char* keyEnd;
122122
const char* value;
123+
const char* valueEnd;
124+
int keyLen;
123125
int valueLen;
124-
125-
if (pos + keyLen >= headerLen) {
126+
127+
/* Find NUL terminator for key within remaining bounds */
128+
keyEnd = (const char*)memchr(key, '\0', (size_t)(headerLen - pos));
129+
if (keyEnd == NULL) {
126130
break;
127131
}
128-
132+
keyLen = (int)(keyEnd - key);
129133
pos += keyLen + 1;
134+
135+
if (pos >= headerLen) {
136+
break;
137+
}
138+
139+
/* Find NUL terminator for value within remaining bounds */
130140
value = (const char*)(headers + pos);
131-
valueLen = (int)XSTRLEN(value);
132-
133-
if (pos + valueLen >= headerLen) {
141+
valueEnd = (const char*)memchr(value, '\0', (size_t)(headerLen - pos));
142+
if (valueEnd == NULL) {
134143
break;
135144
}
145+
valueLen = (int)(valueEnd - value);
136146

137147
if (XSTRCMP(key, "CONTENT_LENGTH") == 0) {
138148
req->contentLength = XATOI(value);
@@ -235,7 +245,6 @@ int wolfCLU_ScgiSendResponse(SOCKET_T sockfd, int statusCode,
235245
{
236246
char header[512];
237247
int headerLen;
238-
int sent;
239248

240249
headerLen = XSNPRINTF(header, sizeof(header),
241250
"Status: %d %s\r\n"
@@ -248,14 +257,12 @@ int wolfCLU_ScgiSendResponse(SOCKET_T sockfd, int statusCode,
248257
return -1;
249258
}
250259

251-
sent = (int)send(sockfd, header, headerLen, 0);
252-
if (sent != headerLen) {
260+
if (wolfCLU_SendAll(sockfd, header, headerLen) != headerLen) {
253261
return -1;
254262
}
255263

256264
if (bodyLen > 0 && body != NULL) {
257-
sent = (int)send(sockfd, (const char*)body, bodyLen, 0);
258-
if (sent != bodyLen) {
265+
if (wolfCLU_SendAll(sockfd, (const char*)body, bodyLen) != bodyLen) {
259266
return -1;
260267
}
261268
}

tests/ocsp-scgi/ocsp-scgi-test.sh

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -276,21 +276,13 @@ run_test() {
276276
-CAfile "$CERTS_DIR/ca-cert.pem" \
277277
-url http://localhost:8080/ocsp 2>&1)
278278

279-
OCSP_EXIT_CODE=$?
280-
281279
echo "$OCSP_OUTPUT"
282280

283-
# Check if the request was successful
284-
if [ $OCSP_EXIT_CODE -eq 0 ]; then
285-
if echo "$OCSP_OUTPUT" | grep -q "$expected_status"; then
286-
echo "✓ Test PASSED: Found expected status '$expected_status'"
287-
return $EXIT_SUCCESS
288-
else
289-
echo "✗ Test FAILED: Expected '$expected_status' but got different status"
290-
return $EXIT_FAILURE
291-
fi
281+
if echo "$OCSP_OUTPUT" | grep -q "$expected_status"; then
282+
echo "✓ Test PASSED: Found expected status '$expected_status'"
283+
return $EXIT_SUCCESS
292284
else
293-
echo "✗ Test FAILED: OCSP request failed with exit code $OCSP_EXIT_CODE"
285+
echo "✗ Test FAILED: Expected '$expected_status' but got different status"
294286
return $EXIT_FAILURE
295287
fi
296288
}

wolfclu/clu_header_main.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,15 @@ int wolfCLU_HttpServerSendError(SOCKET_T clientfd, int statusCode,
712712
*/
713713
void wolfCLU_ServerClose(SOCKET_T sockfd);
714714

715+
/**
716+
* @brief Send all bytes on a socket, looping on partial writes and EINTR
717+
* @param sockfd socket descriptor
718+
* @param buf data to send
719+
* @param len number of bytes to send
720+
* @return number of bytes sent on success, negative on error
721+
*/
722+
int wolfCLU_SendAll(SOCKET_T sockfd, const char* buf, int len);
723+
715724
/**
716725
* @brief Parse HTTP POST request to extract OCSP request body
717726
* @param httpReq HTTP request buffer

0 commit comments

Comments
 (0)