123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #include "config.h"
- #ifdef WITH_TLS
- #include <logging_mosq.h>
- #include <mosquitto_internal.h>
- #include <net_mosq.h>
- #include <openssl/safestack.h>
- #include <openssl/tls1.h>
- #include <openssl/ssl.h>
- #include <openssl/ocsp.h>
- int mosquitto__verify_ocsp_status_cb(SSL * ssl, void *arg)
- {
- struct mosquitto *mosq = (struct mosquitto *)arg;
- int ocsp_status, result2, i;
- unsigned char *p;
- const unsigned char *cp;
- OCSP_RESPONSE *rsp = NULL;
- OCSP_BASICRESP *br = NULL;
- X509_STORE *st = NULL;
- STACK_OF(X509) *ch = NULL;
- long len;
- UNUSED(ssl);
- len = SSL_get_tlsext_status_ocsp_resp(mosq->ssl, &p);
- log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: SSL_get_tlsext_status_ocsp_resp returned %ld bytes", len);
-
- cp = (const unsigned char *)p;
- if (!cp || len <= 0) {
- log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: no response");
- goto end;
- }
- rsp = d2i_OCSP_RESPONSE(NULL, &cp, len);
- if (rsp==NULL) {
- log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: invalid response");
- goto end;
- }
- ocsp_status = OCSP_response_status(rsp);
- if(ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
- log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: invalid status: %s (%d)",
- OCSP_response_status_str(ocsp_status), ocsp_status);
- goto end;
- }
- br = OCSP_response_get1_basic(rsp);
- if (!br) {
- log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: invalid response");
- goto end;
- }
- ch = SSL_get_peer_cert_chain(mosq->ssl);
- if (sk_X509_num(ch) <= 0) {
- log__printf(mosq, MOSQ_LOG_ERR, "OCSP: we did not receive certificates of the server (num: %d)", sk_X509_num(ch));
- goto end;
- }
- st = SSL_CTX_get_cert_store(mosq->ssl_ctx);
-
- if ((result2=OCSP_basic_verify(br, ch, st, 0)) <= 0) {
- log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: response verification failed (error: %d)", result2);
- goto end;
- }
- for(i = 0; i < OCSP_resp_count(br); i++) {
- int cert_status, crl_reason;
- OCSP_SINGLERESP *single = NULL;
- ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
- single = OCSP_resp_get0(br, i);
- if(!single)
- continue;
- cert_status = OCSP_single_get0_status(single, &crl_reason, &rev, &thisupd, &nextupd);
- log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: SSL certificate status: %s (%d)",
- OCSP_cert_status_str(cert_status), cert_status);
- switch(cert_status) {
- case V_OCSP_CERTSTATUS_GOOD:
-
- if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
- log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: OCSP response has expired");
- goto end;
- }
- break;
- case V_OCSP_CERTSTATUS_REVOKED:
- log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: SSL certificate revocation reason: %s (%d)",
- OCSP_crl_reason_str(crl_reason), crl_reason);
- goto end;
- case V_OCSP_CERTSTATUS_UNKNOWN:
- goto end;
- default:
- log__printf(mosq, MOSQ_LOG_DEBUG, "OCSP: SSL certificate revocation status unknown");
- goto end;
- }
- }
- if (br!=NULL) OCSP_BASICRESP_free(br);
- if (rsp!=NULL) OCSP_RESPONSE_free(rsp);
- return 1;
- end:
- if (br!=NULL) OCSP_BASICRESP_free(br);
- if (rsp!=NULL) OCSP_RESPONSE_free(rsp);
- return 0;
- }
- #endif
|