| 260 | } |
| 261 | |
| 262 | int modssl_verify_ocsp(X509_STORE_CTX *ctx, SSLSrvConfigRec *sc, |
| 263 | server_rec *s, conn_rec *c, apr_pool_t *pool) |
| 264 | { |
| 265 | X509 *cert = X509_STORE_CTX_get_current_cert(ctx); |
| 266 | apr_pool_t *vpool; |
| 267 | int rv; |
| 268 | |
| 269 | if (!cert) { |
| 270 | /* starting with OpenSSL 1.0, X509_STORE_CTX_get_current_cert() |
| 271 | * may yield NULL. Return early, but leave the ctx error as is. */ |
| 272 | ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, |
| 273 | "No cert available to check with OCSP"); |
| 274 | return 1; |
| 275 | } |
| 276 | else if (X509_check_issued(cert,cert) == X509_V_OK) { |
| 277 | /* don't do OCSP checking for valid self-issued certs */ |
| 278 | ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, |
| 279 | "Skipping OCSP check for valid self-issued cert"); |
| 280 | X509_STORE_CTX_set_error(ctx, X509_V_OK); |
| 281 | return 1; |
| 282 | } |
| 283 | |
| 284 | /* Create a temporary pool to constrain memory use (the passed-in |
| 285 | * pool may be e.g. a connection pool). */ |
| 286 | apr_pool_create(&vpool, pool); |
| 287 | apr_pool_tag(vpool, "modssl_verify_ocsp"); |
| 288 | |
| 289 | rv = verify_ocsp_status(cert, ctx, c, sc, s, vpool); |
| 290 | |
| 291 | apr_pool_destroy(vpool); |
| 292 | |
| 293 | /* Propagate the verification status back to the passed-in |
| 294 | * context. */ |
| 295 | switch (rv) { |
| 296 | case V_OCSP_CERTSTATUS_GOOD: |
| 297 | X509_STORE_CTX_set_error(ctx, X509_V_OK); |
| 298 | break; |
| 299 | |
| 300 | case V_OCSP_CERTSTATUS_REVOKED: |
| 301 | X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED); |
| 302 | break; |
| 303 | |
| 304 | case V_OCSP_CERTSTATUS_UNKNOWN: |
| 305 | /* correct error code for application errors? */ |
| 306 | X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION); |
| 307 | break; |
| 308 | } |
| 309 | |
| 310 | return rv == V_OCSP_CERTSTATUS_GOOD; |
| 311 | } |
| 312 | #endif /* HAVE_OCSP */ |
no test coverage detected