|
19 | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
20 | 20 | */ |
21 | 21 |
|
22 | | -/* This is a test program and should not be used as an example. */ |
| 22 | +/* Example OCSP responder used for interoperability and stapling testing. |
| 23 | + * This code is for demonstration/testing only and is not hardened for |
| 24 | + * secure or production use. Do not use this as a reference implementation |
| 25 | + * for deploying an OCSP responder in production. |
| 26 | + */ |
23 | 27 |
|
24 | 28 | #ifdef HAVE_CONFIG_H |
25 | 29 | #include <config.h> |
@@ -515,15 +519,43 @@ static int ParseHttpRequest(const byte* httpReq, int httpReqSz, |
515 | 519 | } |
516 | 520 | if (contentLen) { |
517 | 521 | *bodySz = atoi(contentLen + 15); |
| 522 | + /* Reject obviously invalid or unreasonably large Content-Length */ |
| 523 | + if (*bodySz < 0 || *bodySz > MAX_REQUEST_SIZE) { |
| 524 | + LOG_ERROR("Invalid or too large Content-Length: %d\n", *bodySz); |
| 525 | + *body = NULL; |
| 526 | + *bodySz = 0; |
| 527 | + return -1; |
| 528 | + } |
518 | 529 | } |
519 | 530 |
|
520 | 531 | /* Find body (after \r\n\r\n) */ |
521 | 532 | *body = (const byte*)XSTRSTR((char*)httpReq, "\r\n\r\n"); |
522 | 533 | if (*body) { |
| 534 | + int offset; |
| 535 | + |
523 | 536 | *body += 4; |
| 537 | + offset = (int)(*body - httpReq); |
| 538 | + |
| 539 | + /* Validate that the body pointer is within the received buffer */ |
| 540 | + if (offset < 0 || offset > httpReqSz) { |
| 541 | + LOG_ERROR("Invalid HTTP body offset\n"); |
| 542 | + *body = NULL; |
| 543 | + *bodySz = 0; |
| 544 | + return -1; |
| 545 | + } |
| 546 | + |
524 | 547 | /* Use Content-Length if available, otherwise use remaining data */ |
525 | 548 | if (*bodySz == 0) { |
526 | | - *bodySz = httpReqSz - (int)(*body - httpReq); |
| 549 | + *bodySz = httpReqSz - offset; |
| 550 | + } |
| 551 | + |
| 552 | + /* Ensure that the claimed body length fits in the received data */ |
| 553 | + if (offset + *bodySz > httpReqSz) { |
| 554 | + LOG_ERROR("Incomplete HTTP body: expected %d bytes, have %d\n", |
| 555 | + *bodySz, httpReqSz - offset); |
| 556 | + *body = NULL; |
| 557 | + *bodySz = 0; |
| 558 | + return -1; |
527 | 559 | } |
528 | 560 | return 0; |
529 | 561 | } |
@@ -554,17 +586,31 @@ static int SendHttpResponse(SOCKET_T clientfd, const byte* ocspResp, int ocspRes |
554 | 586 | "\r\n", ocspRespSz); |
555 | 587 |
|
556 | 588 | /* Send header */ |
557 | | - sent = (int)send(clientfd, header, (size_t)headerLen, 0); |
558 | | - if (sent != headerLen) { |
559 | | - LOG_ERROR("Failed to send HTTP header\n"); |
560 | | - return -1; |
| 589 | + { |
| 590 | + int totalSent = 0; |
| 591 | + while (totalSent < headerLen) { |
| 592 | + sent = (int)send(clientfd, header + totalSent, |
| 593 | + (size_t)(headerLen - totalSent), 0); |
| 594 | + if (sent <= 0) { |
| 595 | + LOG_ERROR("Failed to send HTTP header\n"); |
| 596 | + return -1; |
| 597 | + } |
| 598 | + totalSent += sent; |
| 599 | + } |
561 | 600 | } |
562 | 601 |
|
563 | 602 | /* Send body */ |
564 | | - sent = (int)send(clientfd, (const char*)ocspResp, (size_t)ocspRespSz, 0); |
565 | | - if (sent != ocspRespSz) { |
566 | | - LOG_ERROR("Failed to send OCSP response\n"); |
567 | | - return -1; |
| 603 | + { |
| 604 | + int totalSent = 0; |
| 605 | + while (totalSent < ocspRespSz) { |
| 606 | + sent = (int)send(clientfd, (const char*)ocspResp + totalSent, |
| 607 | + (size_t)(ocspRespSz - totalSent), 0); |
| 608 | + if (sent <= 0) { |
| 609 | + LOG_ERROR("Failed to send OCSP response\n"); |
| 610 | + return -1; |
| 611 | + } |
| 612 | + totalSent += sent; |
| 613 | + } |
568 | 614 | } |
569 | 615 |
|
570 | 616 | return 0; |
@@ -815,9 +861,9 @@ THREAD_RETURN WOLFSSL_THREAD ocsp_responder_test(void* args) |
815 | 861 | /* Write ready file if requested */ |
816 | 862 | if (opts.readyFile != NULL) { |
817 | 863 | XFILE rf = XFOPEN(opts.readyFile, "w"); |
818 | | - if (rf != NULL) { |
| 864 | + if (rf != XBADFILE) { |
819 | 865 | fprintf(rf, "%d\n", (int)opts.port); |
820 | | - fclose(rf); |
| 866 | + XFCLOSE(rf); |
821 | 867 | if (opts.verbose) { |
822 | 868 | LOG_MSG("Ready file created: %s\n", opts.readyFile); |
823 | 869 | } |
|
0 commit comments