blob: 5b46afbd65fa1dcaca58192e1171cca853e27e72 [file] [log] [blame]
Support for OCSP Verification in Serf
=====================================
Serf trunk currently supports OCSP stapling for verifying server
certificates. The purpose of this branch is to add minimal support
for issuing OCSP requests to responders from the client application.
The idea is that the application decides when and where to send OCSP
requests and how to verify responses, and Serf provides some basic
utility functions for constructing the requests and parsing the
responses.
These are the proposed changes:
1. serf_ssl_cert_certificate()
Extract the OCSP responder locations from the certificate's x509v3
extension field authorityInfoAccess:OCSP;URI and, if it is present,
insert the array into the returned hash table with key "OCSP".
2. serf_ssl_cert_import()
Add a new function that is the inverse of serf_ssl_cert_export():
serf_ssl_certificate_t *serf_ssl_cert_import(
const char *encoded_cert,
apr_pool_t *pool);
Docstring:
Imports certificate from a base64-encoded, zero-terminated
string. The returned certificate is allocated in @a pool.
Returns NULL on failure.
Discussion:
In order to create an OCSP request, the application needs both
the server certificate and its issuer certtificate. An
application may have to issue OCSP requests independently and
asynchronously of any other processing, so it's nice if it can
store the certificates in a form that's independent of pool
lifetimes. We provide this form with serf_ssl_cert_export(), but
there's no easy way to consume the exported form in existing Serf
APIs (writing it to a file in PEM format and reading it back
through serf_ssl_load_cert_file() is neither easy nor sane).
3. serf_ssl_ocsp_request_create()
Add a new function that can be used from within a request setup
handler to create an OCSP request:
apr_status_t serf_ssl_ocsp_request_create(
const serf_ssl_certificate_t *server_cert,
const serf_ssl_certificate_t *issuer_cert,
const void **ocsp_request,
apr_size_t *ocsp_request_size,
const void **nonce,
apr_size_t *nonce_size,
apr_pool_t *pool);
Docstring:
Constructs an OCSP verification request for @a server_cert with
issuer certificate @a issuer_cert, Retyurns the DER encoded
request in @a ocsp_request and its size in @a ocsp_request_size.
If @a nonce is not @c NULL, the request will contain a randomly
generated nonce, which will be returned in @a *nonce and its
size in @a nonce_size. If @a nonce is @c NULL, @a nonce_size
is ignored.
The request and nonce will be allocated from @a pool.
Discussion:
HTTP OCSP requests can be sent using eithe the GET or POST
methods; see https://www.ietf.org/rfc/rfc2560.txt section A.1.1.
It's up to the application to decide which method to use, so we
don't provide a function to create the request body or set
request headers.
4. serf_ssl_ocsp_response_verify()
Add a new function that can be used from within a response handler
to verify an OCSP response:
apr_status_t serf_ssl_ocsp_response_verify(
const void *ocsp_response,
apr_size_t ocsp_response_size,
const serf_ssl_certificate_t *server_cert,
const serf_ssl_certificate_t *issuer_cert,
const void *nonce,
apr_size_t nonce_size,
apr_time_t *this_update,
apr_time_t *next_update,
apr_time_t *produced_at,
apr_pool_t *pool);
Docstring:
Check if the given @a ocsp_response of size @a ocsp_response_size
is valid for the given @a server_cert, @a issuer_cert and @a nonce.
If @a nonce is @c NULL, the response _must not_ contain a nonce.
Otherwise, it must contain an identical nonce with size @a nonce_size.
The @a this_update, @a next_update and @a produced_at output arguments
are described in RFC 2560, section 2.4 and, when not @c NULL, will be
set from the parsed response. Any of these times that are not present
in the response will be set to the epoch, i.e., @c APR_TIME_C(0).
Uses @a pool for temporary allocations.
Discussion:
Parses and verifies the OCSP response received in the HTTP response
body as per RFC 2560, section 3.2.
5. New error codes and macros
#define SERF_ERROR_SSL_OCSP_RESPONSE_CERT_REVOKED
#define SERF_ERROR_SSL_OCSP_RESPONSE_CERT_UNKNOWN
#define SERF_ERROR_SSL_OCSP_RESPONSE_INVALID
#define SERF_OCSP_UNGOOD_ERROR(status)
Discussion:
These error codes are returned from serf_ssl_ocsp_response_verify().
The SERF_OCSP_UNGOOD_ERROR() macro combines the _CERT_REVOKED
and _CERT_UNKNOWN error codes..