| 596 | } md_ocsp_update_t; |
| 597 | |
| 598 | static apr_status_t ostat_on_resp(const md_http_response_t *resp, void *baton) |
| 599 | { |
| 600 | md_ocsp_update_t *update = baton; |
| 601 | md_ocsp_status_t *ostat = update->ostat; |
| 602 | md_http_request_t *req = resp->req; |
| 603 | OCSP_RESPONSE *ocsp_resp = NULL; |
| 604 | OCSP_BASICRESP *basic_resp = NULL; |
| 605 | OCSP_SINGLERESP *single_resp; |
| 606 | apr_status_t rv = APR_SUCCESS; |
| 607 | int n, breason = 0, bstatus; |
| 608 | ASN1_GENERALIZEDTIME *bup = NULL, *bnextup = NULL; |
| 609 | md_data_t der, new_der; |
| 610 | md_timeperiod_t valid; |
| 611 | md_ocsp_cert_stat_t nstat; |
| 612 | |
| 613 | der.data = new_der.data = NULL; |
| 614 | der.len = new_der.len = 0; |
| 615 | |
| 616 | md_result_activity_printf(update->result, "status of certid %s, reading response", |
| 617 | ostat->hexid); |
| 618 | if (APR_SUCCESS != (rv = apr_brigade_pflatten(resp->body, (char**)&der.data, |
| 619 | &der.len, req->pool))) { |
| 620 | goto cleanup; |
| 621 | } |
| 622 | if (NULL == (ocsp_resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char**)&der.data, |
| 623 | (long)der.len))) { |
| 624 | rv = APR_EINVAL; |
| 625 | |
| 626 | md_result_set(update->result, rv, |
| 627 | apr_psprintf(req->pool, "req[%d] response body does not parse as " |
| 628 | "OCSP response, status=%d, body brigade length=%ld", |
| 629 | resp->req->id, resp->status, (long)der.len)); |
| 630 | md_result_log(update->result, MD_LOG_DEBUG); |
| 631 | goto cleanup; |
| 632 | } |
| 633 | /* got a response! but what does it say? */ |
| 634 | n = OCSP_response_status(ocsp_resp); |
| 635 | if (OCSP_RESPONSE_STATUS_SUCCESSFUL != n) { |
| 636 | rv = APR_EINVAL; |
| 637 | md_result_printf(update->result, rv, "OCSP response status is, unsuccessfully, %d", n); |
| 638 | md_result_log(update->result, MD_LOG_DEBUG); |
| 639 | goto cleanup; |
| 640 | } |
| 641 | basic_resp = OCSP_response_get1_basic(ocsp_resp); |
| 642 | if (!basic_resp) { |
| 643 | rv = APR_EINVAL; |
| 644 | md_result_set(update->result, rv, "OCSP response has no basicresponse"); |
| 645 | md_result_log(update->result, MD_LOG_DEBUG); |
| 646 | goto cleanup; |
| 647 | } |
| 648 | /* The notion of nonce enabled freshness in OCSP responses, e.g. that the response |
| 649 | * contains the signed nonce we sent to the responder, does not scale well. Responders |
| 650 | * like to return cached response bytes and therefore do not add a nonce to it. |
| 651 | * So, in reality, we can only detect a mismatch when present and otherwise have |
| 652 | * to accept it. */ |
| 653 | switch ((n = OCSP_check_nonce(ostat->ocsp_req, basic_resp))) { |
| 654 | case 1: |
| 655 | md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, req->pool, |
nothing calls this directly
no test coverage detected