From 797a89a15aff6af1a3bb458987cce7fbddef1ff0 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sat, 21 Jun 2014 20:13:37 +0100 Subject: [PATCH] Add some OCSP documentation. Reviewed-by: Matt Caswell --- doc/crypto/OCSP_REQUEST_new.pod | 107 +++++++++++++++++++++ doc/crypto/OCSP_cert_to_id.pod | 78 ++++++++++++++++ doc/crypto/OCSP_request_add1_nonce.pod | 73 +++++++++++++++ doc/crypto/OCSP_response_find_status.pod | 104 +++++++++++++++++++++ doc/crypto/OCSP_response_status.pod | 57 ++++++++++++ doc/crypto/OCSP_sendreq_new.pod | 113 +++++++++++++++++++++++ 6 files changed, 532 insertions(+) create mode 100644 doc/crypto/OCSP_REQUEST_new.pod create mode 100644 doc/crypto/OCSP_cert_to_id.pod create mode 100644 doc/crypto/OCSP_request_add1_nonce.pod create mode 100644 doc/crypto/OCSP_response_find_status.pod create mode 100644 doc/crypto/OCSP_response_status.pod create mode 100644 doc/crypto/OCSP_sendreq_new.pod diff --git a/doc/crypto/OCSP_REQUEST_new.pod b/doc/crypto/OCSP_REQUEST_new.pod new file mode 100644 index 0000000000..563fed3c12 --- /dev/null +++ b/doc/crypto/OCSP_REQUEST_new.pod @@ -0,0 +1,107 @@ +=pod + +OCSP_REQUEST_new, OCSP_REQUEST_free, OCSP_request_add0_id, OCSP_request_sign, +OCSP_request_add1_cert, OCSP_request_onereq_count, +OCSP_request_onereq_get0 - OCSP request functions. + +=head1 SYNOPSIS + + #include + + OCSP_REQUEST *OCSP_REQUEST_new(void); + void OCSP_REQUEST_free(OCSP_REQUEST *req); + + OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); + + int OCSP_request_sign(OCSP_REQUEST *req, + X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); + + int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); + + int OCSP_request_onereq_count(OCSP_REQUEST *req); + OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); + +=head1 DESCRIPTION + +OCSP_REQUEST_new() allocates and returns an empty B structure. + +OCSP_REQUEST_free() frees up the request structure B. + +OCSP_request_add0_id() adds certificate ID B to B. It returns +the B structure added so an application can add additional +extensions to the request. The B parameter B be freed up after +the operation. + +OCSP_request_sign() signs OCSP request B using certificate +B, private key B, digest B and additional certificates +B. If the B option B is set then no certificates +will be included in the request. + +OCSP_request_add1_cert() adds certificate B to request B. The +application is responsible for freeing up B after use. + +OCSP_request_onereq_count() returns the total number of B +structures in B. + +OCSP_request_onereq_get0() returns an internal pointer to the B +contained in B of index B. The index value B runs from 0 to +OCSP_request_onereq_count(req) - 1. + +=head1 RETURN VALUES + +OCSP_REQUEST_new() returns an empty B structure or B if +an error occurred. + +OCSP_request_add0_id() returns the B structure containing B +or B if an error occurred. + +OCSP_request_sign() and OCSP_request_add1_cert() return 1 for success and 0 +for failure. + +OCSP_request_onereq_count() returns the total number of B +structures in B. + +OCSP_request_onereq_get0() returns a pointer to an B structure +or B if the index value is out or range. + +=head1 NOTES + +An OCSP request structure contains one or more B structures +corresponding to each certificate. + +OCSP_request_onereq_count() and OCSP_request_onereq_get0() are mainly used by +OCSP responders. + +=head1 EXAMPLE + +Create an B structure for certificate B with issuer +B: + + OCSP_REQUEST *req; + OCSP_ID *cid; + + req = OCSP_REQUEST_new(); + if (req == NULL) + /* error */ + cid = OCSP_cert_to_id(EVP_sha1(), cert, issuer); + if (cid == NULL) + /* error */ + + if (OCSP_REQUEST_add0_id(req, cid) == NULL) + /* error */ + + /* Do something with req, e.g. query responder */ + + OCSP_REQUEST_free(req); + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=cut diff --git a/doc/crypto/OCSP_cert_to_id.pod b/doc/crypto/OCSP_cert_to_id.pod new file mode 100644 index 0000000000..2eab1d3825 --- /dev/null +++ b/doc/crypto/OCSP_cert_to_id.pod @@ -0,0 +1,78 @@ +=pod + +OCSP_cert_to_id, OCSP_cert_id_new, OCSP_CERTID_free, OCSP_id_issuer_cmp, +OCSP_id_cmp, OCSP_id_get0_info - OCSP certificate ID utility functions. + +=head1 SYNOPSIS + + #include + + OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, + X509 *subject, X509 *issuer); + + OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, + X509_NAME *issuerName, + ASN1_BIT_STRING *issuerKey, + ASN1_INTEGER *serialNumber); + + void OCSP_CERTID_free(OCSP_CERTID *id); + + int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b); + int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b); + + int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, + ASN1_INTEGER **pserial, OCSP_CERTID *cid); + + +=head1 DESCRIPTION + +OCSP_cert_to_id() creates and returns a new B structure using +message digest B for certificate B with issuer B. If +B is B then SHA1 is used. + +OCSP_cert_id_new() creates and returns a new B using B and +issuer name B, issuer key hash B and serial number +B. + +OCSP_CERTID_free() frees up B. + +OCSP_id_cmp() compares B B and B. + +OCSP_id_issuer_cmp() compares only the issuer name of B B and B. + +OCSP_id_get0_info() returns the issuer name hash, hash OID, issuer key hash and +serial number contained in B. If any of the values are not required the +corresponding parameter can be set to B. + +=head1 RETURN VALUES + +OCSP_cert_to_id() and OCSP_cert_id_new() return either a pointer to a valid +B structure or B if an error occurred. + +OCSP_id_cmp() and OCSP_id_issuer_cmp() returns zero for a match and non-zero +otherwise. + +OCSP_CERTID_free() does not return a value. + +OCSP_id_get0_info() returns 1 for sucess and 0 for failure. + +=head1 NOTES + +OCSP clients will typically only use OCSP_cert_to_id() or OCSP_cert_id_new(): +the other functions are used by responder applications. + +The values returned by OCSP_id_get0_info() are internal pointers and B be freed up by an application: they will be freed when the corresponding +B structure is freed. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=cut diff --git a/doc/crypto/OCSP_request_add1_nonce.pod b/doc/crypto/OCSP_request_add1_nonce.pod new file mode 100644 index 0000000000..8fe319706a --- /dev/null +++ b/doc/crypto/OCSP_request_add1_nonce.pod @@ -0,0 +1,73 @@ +=pod + +OCSP_request_add1_nonce, OCSP_basic_add1_nonce, OCSP_check_nonce, OCSP_copy_nonce - OCSP nonce functions. + +=head1 SYNOPSIS + + #include + + int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); + int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); + int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); + int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *resp); + +=head1 DESCRIPTION + +OCSP_request_add1_nonce() adds a nonce of value B and length B to +OCSP request B. If B is B a random nonce is used. If B +is zero or negative a default length will be used (currently 16 bytes). + +OCSP_basic_add1_nonce() is identical to OCSP_request_add1_nonce() except +it adds a nonce to OCSP basic response B. + +OCSP_check_nonce() compares the nonce value in B and B. + +OCSP_copy_nonce() copys any nonce value present in B to B. + +=head1 RETURN VALUES + +OCSP_request_add1_nonce() and OCSP_basic_add1_nonce() return 1 for success +and 0 for failure. + +OCSP_copy_nonce() returns 1 if a nonce was successfully copied, 2 if no nonce +was present in B and 0 if an error occurred. + +OCSP_check_nonce() returns the result of the nonce comparison between B +and B. The return value indicates the result of the comparison. If +nonces are present and equal 1 is returned. If the nonces are absent 2 is +returned. If a nonce is present in the response only 3 is returned. If nonces +are present and unequal 0 is returned. If the nonce is present in the request +only then -1 is returned. + +=head1 NOTES + +For most purposes the nonce value in a request is set to a random value so +the B parameter in OCSP_request_add1_nonce() is usually NULL. + +An OCSP nonce is typically added to an OCSP request to thwart replay attacks +by checking the same nonce value appears in the response. + +Some responders may include a nonce in all responses even if one is not +supplied. + +Some responders cache OCSP responses and do not sign each response for +performance reasons. As a result they do not support nonces. + +The return values of OCSP_check_nonce() can be checked to cover each case. A +positive return value effectively indicates success: nonces are both present +and match, both absent or present in the response only. A non-zero return +additionally covers the case where the nonce is present in the request only: +this will happen if the responder doesn't support nonces. A zero return value +indicates present and mismatched nonces: this should be treated as an error +condition. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=cut diff --git a/doc/crypto/OCSP_response_find_status.pod b/doc/crypto/OCSP_response_find_status.pod new file mode 100644 index 0000000000..1f4666a8fb --- /dev/null +++ b/doc/crypto/OCSP_response_find_status.pod @@ -0,0 +1,104 @@ +=pod + +OCSP_resp_find_status, OCSP_resp_count, OCSP_resp_get0, OCSP_resp_find, OCSP_single_get0_status, OCSP_check_validity - OCSP reponse utility functions. + +=head1 SYNOPSIS + + #include + + int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); + + int OCSP_resp_count(OCSP_BASICRESP *bs); + OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); + int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); + int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); + + int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, + long sec, long maxsec); + +=head1 DESCRIPTION + +OCSP_resp_find_status() searches B for an OCSP response for B. If it is +successful the fields of the response are returned in B<*status>, B<*reason>, +B<*revtime>, B<*thisupd> and B<*nextupd>. The B<*status> value will be one of +B, B or +B. The B<*reason> and B<*revtime> fields are only +set if the status is B. If set the B<*reason> field +will be set to the revocation reason which will be one of +B, B, +B, B, +B, B, +B, +B or B. + +OCSP_resp_count() returns the number of B structures in B. + +OCSP_resp_get0() returns the B structure in B +corresponding to index B. Where B runs from 0 to +OCSP_resp_count(bs) - 1. + +OCSP_resp_find() searches B for B and returns the index of the first +matching entry after B or starting from the beginning if B is -1. + +OCSP_single_get0_status() extracts the fields of B in B<*reason>, +B<*revtime>, B<*thisupd> and B<*nextupd>. + +OCSP_check_validity() checks the validity of B and B values +which will be typically obtained from OCSP_resp_find_status() or +OCSP_single_get0_status(). If B is non-zero it indicates how many seconds +leeway should be allowed in the check. If B is positive it indicates +the maximum age of B in seconds. + +=head1 RETURN VALUES + +OCSP_resp_find_status() returns 1 if B is found in B and 0 otherwise. + +OCSP_resp_count() returns the total number of B fields in +B. + +OCSP_resp_get0() returns a pointer to an B structure or +B if B is out of range. + +OCSP_resp_find() returns the index of B in B (which may be 0) or -1 if +B was not found. + +OCSP_single_get0_status() returns the status of B or -1 if an error +occurred. + +=head1 NOTES + +Applications will typically call OCSP_resp_find_status() using the certificate +ID of interest and then check its validity using OCSP_check_validity(). They +can then take appropriate action based on the status of the certificate. + +An OCSP response for a certificate contains B and B +fields. Normally the current time should be between these two values. To +account for clock skew the B field can be set to non-zero in +OCSP_check_validity(). Some responders do not set the B field, this +would otherwise mean an ancient response would be considered valid: the +B parameter to OCSP_check_validity() can be used to limit the permitted +age of responses. + +The values written to B<*revtime>, B<*thisupd> and B<*nextupd> by +OCSP_resp_find_status() and OCSP_single_get0_status() are internal pointers +which B be freed up by the calling application. Any or all of these +parameters can be set to NULL if their value is not required. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=cut diff --git a/doc/crypto/OCSP_response_status.pod b/doc/crypto/OCSP_response_status.pod new file mode 100644 index 0000000000..7121872f23 --- /dev/null +++ b/doc/crypto/OCSP_response_status.pod @@ -0,0 +1,57 @@ +=pod + +OCSP_response_status, OCSP_response_get1_basic, OCSP_response_create, +OCSP_RESPONSE_free - OCSP response functions. + +=head1 SYNOPSIS + + #include + + int OCSP_response_status(OCSP_RESPONSE *resp); + OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); + OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); + void OCSP_RESPONSE_free(OCSP_RESPONSE *resp); + +=head1 DESCRIPTION + +OCSP_response_status() returns the OCSP response status of B. It returns +one of the values: B, +B, +B, B +B, or B. + +OCSP_response_get1_basic() decodes and returns the B structure +contained in B. + +OCSP_response_create() creates and returns an B structure for +B and optionally including basic response B. + +OCSP_RESPONSE_free() frees up OCSP reponse B. + +=head1 RETURN VALUES + +OCSP_RESPONSE_status() returns a status value. + +OCSP_response_get1_basic() returns an B structure pointer or +B if an error occurred. + +OCSP_response_create() returns an B structure pointer or B +if an error occurred. + +OCSP_RESPONSE_free() does not return a value. + +=head1 NOTES + +OCSP_response_get1_basic() is only called if the status of a response is +B. + +=head1 SEE ALSO + +L +L +L +L +L +L + +=cut diff --git a/doc/crypto/OCSP_sendreq_new.pod b/doc/crypto/OCSP_sendreq_new.pod new file mode 100644 index 0000000000..cab11f71c5 --- /dev/null +++ b/doc/crypto/OCSP_sendreq_new.pod @@ -0,0 +1,113 @@ +=pod + +=head1 NAME + +OCSP_sendreq_new, OCSP_sendreq_nbio, OCSP_REQ_CTX_free, +OCSP_set_max_response_length, OCSP_REQ_CTX_add1_header, +OCSP_REQ_CTX_set1_req, OCSP_sendreq_bio - OCSP responder query functions + +=head1 SYNOPSIS + + #include + + OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline); + + int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); + + void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); + + void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len); + + int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value); + + int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); + + OCSP_RESPONSE *OCSP_sendreq_bio(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline); + +=head1 DESCRIPTION + +The function OCSP_sendreq_new() returns an B structure using the +responder B, the URL path B, the OCSP request B and with a +response header maximum line length of B. If B is zero a +default value of 4k is used. The OCSP request B may be set to B +and provided later if required. + +OCSP_sendreq_nbio() performs non-blocking I/O on the OCSP request context +B. When the operation is complete it returns the response in B<*presp>. + +OCSP_REQ_CTX_free() frees up the OCSP context B. + +OCSP_set_max_response_length() sets the maximum reponse length for B +to B. If the response exceeds this length an error occurs. If not +set a default value of 100k is used. + +OCSP_REQ_CTX_add1_header() adds header B with value B to the +context B. It can be called more than once to add multiple headers. +It B be called before any calls to OCSP_sendreq_nbio(). The B +parameter in the initial to OCSP_sendreq_new() call MUST be set to B if +additional headers are set. + +OCSP_REQ_CTX_set1_req() sets the OCSP request in B to B. This +function should be called after any calls to OCSP_REQ_CTX_add1_header(). + +OCSP_sendreq_bio() performs an OCSP request using the responder B, the URL +path B, the OCSP request B and with a response header maximum line +length of B. If B is zero a default value of 4k is used. + +=head1 RETURN VALUES + +OCSP_sendreq_new() returns a valid B structure or B if +an error occurred. + +OCSP_sendreq_nbio() returns B<1> if the operation was completed successfully, +B<-1> if the operation should be retried and B<0> if an error occurred. + +OCSP_REQ_CTX_add1_header() and OCSP_REQ_CTX_set1_req() return B<1> for success +and B<0> for failure. + +OCSP_sendreq_bio() returns the B structure sent by the +responder or B if an error occurred. + +OCSP_REQ_CTX_free() and OCSP_set_max_response_length() do not return values. + +=head1 NOTES + +These functions only perform a minimal HTTP query to a responder. If an +application wishes to support more advanced features it should use an +alternative more complete HTTP library. + +Currently only HTTP POST queries to responders are supported. + +The arguments to OCSP_sendreq_new() correspond to the components of the URL. +For example if the responder URL is B the BIO +B should be connected to host B on port 80 and B +should be set to B<"/ocspreq"> + +The headers added with OCSP_REQ_CTX_add1_header() are of the form +"B: B" or just "B" if B is B. So to add +a Host header for B you would call: + + OCSP_REQ_CTX_add1_header(ctx, "Host", "ocsp.com"); + +If OCSP_sendreq_nbio() indicates an operation should be retried the +corresponding BIO can be examined to determine which operation (read or +write) should be retried and appropriate action taken (for example a select() +call on the underlying socket). + +OCSP_sendreq_bio() does not support retries and so cannot handle non-blocking +I/O efficiently. It is retained for compatibility and its use in new +applications is not recommended. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=cut -- 2.40.0