[email protected] wrote on Sun, Dec 11, 2016 at 12:32:57 -0000:
> Author: brane
> Date: Sun Dec 11 12:32:57 2016
> New Revision: 1773567
>
> URL: http://svn.apache.org/viewvc?rev=1773567&view=rev
> Log:
> On the ocsp-verification branch: Prepare prototypes and error codes
> for OCSP response creation and verification.
>
> * BRANCH-README: Update branch docs.
>
> * serf.h
> (SERF_ERROR_SSL_OCSP_RESPONSE_CERT_REVOKED,
> SERF_ERROR_SSL_OCSP_RESPONSE_CERT_UNKNOWN,
> SERF_ERROR_SSL_OCSP_RESPONSE_INVALID): New error codes.
> (SERF_OCSP_UNGOOD_ERROR): New error-checking utility macro.
>
> * serf_bucket_types.h
> (serf_ssl_ocsp_request_create,
> serf_ssl_ocsp_response_verify): New prototypes.
>
> * src/context.c
> (serf_error_string): Add error strings for the new error codes.
>
> +++ serf/branches/ocsp-verification/serf.h Sun Dec 11 12:32:57 2016
> @@ -143,6 +143,19 @@ typedef struct serf_config_t serf_config
> +#define SERF_OCSP_UNGOOD_ERROR(status) ((status) \
> + && ((SERF_ERROR_SSL_OCSP_CERT_REVOKED == (status)) \
> + ||(SERF_ERROR_SSL_OCSP_CERT_UNKNOWN == (status))))
The "(status) &&" conjunct is redundant. I assume the optimizer would
just remove the nonzero-p check unless __builtin_expect were used, but
I haven't checked the generated code.
> +++ serf/branches/ocsp-verification/serf_bucket_types.h Sun Dec 11 12:32:57
> 2016
> @@ -769,6 +769,53 @@ apr_status_t
> serf_ssl_check_cert_status_request(serf_ssl_context_t *ssl_ctx, int enabled);
>
> /**
> + * Constructs an OCSP verification request for @a server_cert with
> + * issuer certificate @a issuer_cert, Retyurns the DER encoded
Typo s/y//
> + * request in @a ocsp_request and its size in @a ocsp_request_size.
> + *
Maybe use a counted-string type to make the coupling explicit?
struct serf_string_t { const void *data; apr_size_t length; }
struct serf_string_t *ocsp_request,
> + * 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.
What is the caller expected to do with the nonce? Why is it exposed in
the API? I'd consider making the nonce opaque (i.e.: hide its length
from the caller), to remove the opportunity for the caller to handle the
nonce wrongly.
For that matter, I wouldn't try to write code that generates or compares
nonces, either; I'd leave that to openssl. (Haven't looked at the
implementation.)
> + * The request and nonce will be allocated from @a pool.
Rename the argument to result_pool, then? (And add scratch_pool if needed)
> + */
> +apr_status_t serf_ssl_ocsp_request_create(
> + const serf_ssl_certificate_t *server_cert,
> + const serf_ssl_certificate_t *issuer_cert,
What will happen if an API caller passes these two parameters in the
wrong order?
> + const void **ocsp_request,
> + apr_size_t *ocsp_request_size,
> + const void **nonce,
> + apr_size_t *nonce_size,
> + apr_pool_t *pool);
> +
> +/**
> + * 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.
> + *
Use doxygen bold/italic markup instead of underscores?
> + * 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.
What error code is returned for an invalid response?
> + */
> +apr_status_t serf_ssl_ocsp_response_verify(
> + const void *ocsp_response,
> + apr_size_t ocsp_response_size,
Another opportunity to use the aforementioned counted-length string type.
> + const serf_ssl_certificate_t *server_cert,
> + const serf_ssl_certificate_t *issuer_cert,
Same ordering question as above.
> + 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);
Cheers,
Daniel