aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-12-17 21:49:07 -0500
committerJack Lloyd <[email protected]>2016-12-17 21:49:07 -0500
commit7397a773c80a6f3d273b2aa80c6e54aa7ebdcc46 (patch)
tree29aa6fd1c9cbe1fa16baff3d8adf2c8d3b959229
parent0a3487433ccbf89df2c0e99b533e59f273759c49 (diff)
Update OCSP manual, and inline to main X.509 doc
[ci skip]
-rw-r--r--doc/manual/contents.rst1
-rw-r--r--doc/manual/ocsp.rst47
-rw-r--r--doc/manual/x509.rst116
3 files changed, 116 insertions, 48 deletions
diff --git a/doc/manual/contents.rst b/doc/manual/contents.rst
index 5d84c1727..2a1136f79 100644
--- a/doc/manual/contents.rst
+++ b/doc/manual/contents.rst
@@ -17,7 +17,6 @@ Contents
pubkey
mceliece
x509
- ocsp
tls
credentials_manager
bigint
diff --git a/doc/manual/ocsp.rst b/doc/manual/ocsp.rst
deleted file mode 100644
index 45858dfeb..000000000
--- a/doc/manual/ocsp.rst
+++ /dev/null
@@ -1,47 +0,0 @@
-OCSP
-========================================
-
-A client makes an OCSP request to what is termed an 'OCSP responder'.
-This responder returns a signed response attesting that the
-certificate in question has not been revoked. One common way of making
-OCSP requests is via HTTP, see :rfc:`2560` Appendix A for details.
-
-.. cpp:class:: OCSP::Request
-
- .. cpp:function:: OCSP::Request(const X509_Certificate& issuer_cert, \
- const X509_Certificate& subject_cert)
-
- Create a new OCSP request
-
- .. cpp:function:: std::vector<byte> BER_encode() const
-
- Encode the current OCSP request as a binary string.
-
- .. cpp:function:: std::string base64_encode() const
-
- Encode the current OCSP request as a base64 string.
-
-.. cpp:class:: OCSP::Response
-
- .. cpp:function:: OCSP::Response(const Certificate_Store& trusted_roots, \
- const std::vector<byte>& response)
-
- Deserializes *response* sent by a responder, and checks that it
- was signed by a certificate associated with one of the CAs
- stored in *trusted_roots*.
-
- .. cpp:function:: bool affirmative_response_for(const X509_Certificate& issuer, \
- const X509_Certificate& subject) const
-
- Returns true if and only if this OCSP response is not an error,
- is signed correctly, and the response indicates that *subject*
- is not currently revoked.
-
-
-.. cpp:function:: OCSP::Response online_check(const X509_Certificate& issuer, \
- const X509_Certificate& subject, \
- const Certificate_Store* trusted_roots)
-
- Attempts to contact the OCSP responder specified in the subject certificate
- and
-
diff --git a/doc/manual/x509.rst b/doc/manual/x509.rst
index 4c06a8709..9ec8112ea 100644
--- a/doc/manual/x509.rst
+++ b/doc/manual/x509.rst
@@ -675,3 +675,119 @@ Note that extensions added this way will be overwritten by an
``X509_CA`` if also added by the ``X509_CA`` itself. This currently
includes the Basic Constraints, Key Usage, Authority Key ID, Subject
Key ID, Subject Alternative Name and Extended Key Usage extension.
+
+OCSP Requests
+----------------------------------------
+
+A client makes an OCSP request to what is termed an 'OCSP responder'. This
+responder returns a signed response attesting that the certificate in question
+has not been revoked. The most recent OCSP specification is as of this
+writing :rfc:`6960`.
+
+Normally OCSP validation happens automatically as part of X.509 certificate
+validation, as long as OCSP is enabled (by setting a non-zero ``ocsp_timeout``
+in the call to ``x509_path_validate``, or for TLS by implementing the related
+``tls_verify_cert_chain_ocsp_timeout`` callback and returning a non-zero value
+from that). So most applications should not need to directly manipulate OCSP
+request and response objects.
+
+For those that do, the primary ocsp interface is in ``ocsp.h``. First a request
+must be formed, using information contained in the subject certificate and in
+the subject's issuing certificate.
+
+.. cpp:class:: OCSP::Request
+
+ .. cpp:function:: OCSP::Request(const X509_Certificate& issuer_cert, \
+ const X509_Certificate& subject_cert)
+
+ Create a new OCSP request
+
+ .. cpp:function:: std::vector<byte> BER_encode() const
+
+ Encode the current OCSP request as a binary string.
+
+ .. cpp:function:: std::string base64_encode() const
+
+ Encode the current OCSP request as a base64 string.
+
+Then the response is parsed and validated, and if valid, can be consulted
+for certificate status information.
+
+.. cpp:class:: OCSP::Response
+
+ .. cpp:function:: OCSP::Response(const uint8_t response_bits[], size_t response_bits_len)
+
+ Attempts to parse ``response_bits`` as an OCSP response. Throws an
+ exception if parsing fails. Note that this does not verify that the OCSP
+ response is valid (ie that the signature is correct), merely that the
+ ASN.1 structure matches an OCSP response.
+
+ .. cpp:function:: Certificate_Status_Code check_signature( \
+ const std::vector<Certificate_Store*>& trust_roots, \
+ const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path = {}) const
+
+ Find the issuing certificate of the OCSP response, and check the signature.
+
+ If possible, pass the full certificate path being validated in
+ the optional ``cert_path`` argument: this additional information
+ helps locate the OCSP signer's certificate in some cases. If this
+ does not return ``Certificate_Status_Code::OCSP_SIGNATURE_OK``,
+ then the request must not be be used further.
+
+ .. cpp:function:: Certificate_Status_Code verify_signature(const X509_Certificate& issuing_cert) const
+
+ If the certificate that issued the OCSP response is already known (eg,
+ because in some specific application all the OCSP responses will always
+ be signed by a single trusted issuer whose cert is baked into the code)
+ this provides an alternate version of `check_signature`.
+
+ .. cpp:function:: Certificate_Status_Code status_for(const X509_Certificate& issuer, \
+ const X509_Certificate& subject, \
+ std::chrono::system_clock::time_point ref_time = std::chrono::system_clock::now()) const
+
+ Assuming the signature is valid, returns the status for the subject certificate.
+ Make sure to get the ordering of the issuer and subject certificates correct.
+
+ The ``ref_time`` is normally just the system clock, but can be used if
+ validation against some other reference time is desired (such as for
+ testing, to verify an old previously valid OCSP response, or to use an
+ alternate time source such as the Roughtime protocol instead of the local
+ client system clock).
+
+ .. cpp:function:: const X509_Time& produced_at() const
+
+ Return the time this OCSP response was (claimed to be) produced at.
+
+ .. cpp:function:: const X509_DN& signer_name() const
+
+ Return the distinguished name of the signer. This is used to help
+ find the issuing certificate.
+
+ This field is optional in OCSP responses, and may not be set.
+
+ .. cpp:function:: const std::vector<uint8_t>& signer_key_hash() const
+
+ Return the SHA-1 hash of the public key of the signer. This is used to
+ help find the issuing certificate. The ``Certificate_Store`` API
+ ``find_cert_by_pubkey_sha1`` can search on this value.
+
+ This field is optional in OCSP responses, and may not be set.
+
+ .. cpp:function:: const std::vector<byte>& raw_bits() const
+
+ Return the entire raw ASN.1 blob (for debugging or specialized decoding needs)
+
+One common way of making OCSP requests is via HTTP, see :rfc:`2560`
+Appendix A for details. A basic implementation of this is the function
+``online_check``, which is available as long as the ``http_util`` module
+was compiled in; check by testing for the macro ``BOTAN_HAS_HTTP_UTIL``.
+
+.. cpp:function:: OCSP::Response online_check(const X509_Certificate& issuer, \
+ const X509_Certificate& subject, \
+ const Certificate_Store* trusted_roots)
+
+ Attempts to contact the OCSP responder specified in the subject certificate
+ over a new HTTP socket, parses and returns the response. If trusted_roots is
+ not null, then the response is additionally validated using OCSP response API
+ ``check_signature``. Otherwise, this call must be performed later by the
+ application.