The function mbedtls_x509_ocsp_response_verify_info() was added, which
is similar to mbedtls_x509_crt_verify_info() but for OCSP responses
instead of certificates. To avoid code duplication, both of these
functions actually call a new function mbedtls_x509_verify_info() in
x509.h with their specific flags and strings in an array of struct
mbedtls_x509_info_string.
Ensure that the internal function x509_ocsp_is_issuer() sets the in/out
issuer pointer to NULL when the supplied certificate is not the issuer
of the OCSP response.
Complete the code that implements the checks between the relationship
between the requested certificate and the OCSP response issuer as part
of the verification process. The checks essentially use the information
in the OCSP response and the supplied certificate chains to:
* Check whether the issuer is the parent of the requested cert
failing that, we check that
* There is a parent for the issuer in one of the supplied cert
chains
* The issuer's parent is also the parent of the requested cert
If either of the two checks succeeds, we accept this verification step.
Ensure that when the OCSP response issuer is not the parent of the cert
whose status was requested the issuer has OCSPSigning enabled in the
extended key usage X.509 extension.
Add code to identify the relationship between the OCSP request issuer
certificate and the certificate whose status was requested. According
to RFC 6960 Section 4.2.2.2 the OCSP response issuer can be:
1. A locally configured signing authority.
- This has not been implemented at this stage
2. The certificate of the CA that issued the certificate in question
3. A certificate that includes the value of id-kp-OCSPSigning in an
extended key usage extension and is issued by the CA that issued
the certificate in question
Note that at this stage the relationship between the certificates has
only been validated based on the information supplied within the OCSP
response.
Add skeleton code that will be filled in with functionality that
verifies a SingleResponse given the OCSP response issuer and the
requested certificate. Also, helper functions have been added to
x509_ocsp.c to find the parent of the requested certificate's status by
using the information in the OCSP SingleResponse supplied.
Modify the x509_crt.c and pkparse.c slightly so that the certificate
parsing (and mbedtls_x509_crt) keeps a pointer to the raw DER structure
containing the SubjectPublicKeyInfo. This improves the efficiency of
the OCSP response verification because we have to take the hash of the
certificate's key.
Add code that loops through every requested certificate and finds out
the corresponding SingleResponse in the OCSP response. This code is the
skeleton for the verification of each SingleResponse. However, at this
stage the verification code is very minimal.
The function follows RFC 6960 and uses either the responder's name or
the responder's hash of their key as available in the OCSP response to
locate the correct issuer certificate.
To avoid code duplication, some functionality from x509_crt.c module
was moved to x509.c and made public in x509.h.
Add the main skeleton code of a function
x509_ocsp_find_response_issuer_crt() that traverses the certs field in
the OCSP response and other user supplied certificates to find the OCSP
response's issuer. At the momment, the helper function is unimplemented
Add the main OCSP response verification function
mbedtls_x509_ocsp_verify_response() to the header file x509_ocsp.h and
a simple definition to x509_ocsp.c. At this stage, the verification
function only checks the response status and the timestamp and sets the
verification flags accordingly.
Also, new verification errors and flags are added as macros. These
values will be used in subsequent commits.
Rework the function mbedtls_x509_ocsp_response_info() to ensure that
it follows the example of similar functions in other X.509 components.
That is, the function should return the number of bytes written to the
provided buffer and in case of error return a negative value.
Rename the following functions in x509_ocsp.h and x509_ocsp.c to fit
the calling convention in other X.509 components (e.g CRL and CRT):
* mbedtls_x509_ocsp_parse_response -> mbedtls_x509_ocsp_response_parse
* mbedtls_x509_ocsp_parse_response_file -> mbedtls_x509_ocsp_response_parse_file
Return a mores specific error code MBEDTLS_ERR_X509_INVALID_DATE +
MBEDTLS_ERR_ASN1_UNEXPECTED_TAG instead of simply
MBEDTLS_ERR_X509_INVALID_DATE to help debugging.
Factor common code into a new function x509_ocsp_get_md(). The function
takes in a pointer to the DER-encoded buffer, parses the octet string
containing some hash value and then checks that the length corresponds
to the expected length for each md algorithm.
The responseType indicates a large portion of the syntax of an OCSP
response message. At this stage we only support OCSP Basic, so this
change ensure that the parser returns a failure code if the
responseType does not match the OID id-pkix-ocsp-basic.
Assign the type of response_id used in the OCSP response ID is recorded
before the actual ID is initialised. In this way, if the initialisation
call to a Name ID fails, the function mbedtls_x509_ocsp_response_free()
calls the correct free() function on the response ID avoiding potential
memory leaks.
Add 1 to a temporary buffer in x509_ocsp_info_certs() which is used to
construct the printing prefix to write an informational string of the
OCSP response for the user. The additional element added to the buffer
contains the \0 character. The missing element would cause a heap
overread of 1 when concatenating the prefix string with itself.
Add missing return statement in x509_ocsp_get_response() that would
otherwise allow the code to continue executing even though a parsing
failure has already been found.
Add a check at the beginning of the function
mbedtls_x509_ocsp_response_free() to ensure that the pointer passed to
is not NULL. This prevent a NULL pointer dereference that could lead to
crashes.
The new MBEDTLS_X509_OCSP_PARSE_C is a feature macro that can be
controlled from the config.h file to enable/disable the OCSP X509
feature at compile time.
Relocate the new OCSP and CRL X509 related errors to x509.h as the
error message generation scripts cannot handle these anywhere else.
Also, update the error.c file with the new human-readable strings
for the OCSP and CRL errors.
This patch removes several bound checks that were redundant due to the
structure of the code in which each function parses the top-level
components of ASN.1 structures and helper functions parse the sub-
components.
In the case of x509_ocsp_get_response(), the parsing of the OCTET
STRING was moved to its caller function as the main job of
x509_ocsp_get_response() is to parse the BasicOCSPResponse structure,
so the OCTET STRING is considered a top-level component similar to an
EXPLICIT tag
Populate the function x509_ocsp_get_certs() to parse the OPTIONAL list
of certificates in the BasicOCSPResponse ASN.1 structure of the OCSP
response:
certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
x509_ocsp_get_certs() only parses the SEQUENCE OF (the EXPLICIT tag is
parsed by the caller) and delegates the actual parsing of the
certificate to the x509_crt.c module.
NOTE: The parsing of certificates in x509_ocsp.c is currently very
inefficient in terms of space as x509_ocsp.c and x509_crt.c both make
an internal copy of the buffer passed to them. This will be optimised
in the future.
Populate the function x509_ocsp_get_sig_alg() that parses the
signatureAlgorithm from the BasicOCSPResponse ASN.1 structure. The
parsing is actually done by the preexisting functions:
* mbedtls_x509_get_alg()
* mbedtls_x509_get_sig_alg()
This is only placeholder code that does not actually check that the
extensions are at least well formed. Therefore, the function
x509_ocsp_get_extensions() has been marked as TODO.
Strictly speaking, the CRLReason is a concept imported from the CRL
profile defined in RFC 5280 Section 5.3.1. However, this is a CRL
extension that is not implemented in mbed TLS. Therefore, this patch
introduces the relevant macros with revocation reasons and error return
codes in x509_crt.h. Also the function x509_ocsp_get_crl_reason() to
parse the CRLReason. If necessary, this code can later be migrated to
x509_crl.c.
The CRL reason ASN1. structure is specified in RFC 5280 Section 5.3.1
as follows:
CRLReason ::= ENUMERATED {
unspecified (0),
keyCompromise (1),
cACompromise (2),
affiliationChanged (3),
superseded (4),
cessationOfOperation (5),
certificateHold (6),
-- value 7 is not used
removeFromCRL (8),
privilegeWithdrawn (9),
aACompromise (10) }
Populate the function x509_ocsp_get_revoked_info() with code to parse the
following ASN.1 structure:
RevokedInfo ::= SEQUENCE {
revocationTime GeneralizedTime,
revocationReason [0] EXPLICIT CRLReason OPTIONAL }
x509_ocsp_get_revoked_info() parses the top level SEQUENCE and the EXPLICIT
OPTIONAL tag, but delegates the parsing of GeneralizedTime and
CRL reason (if present) to x509_ocsp_get_generalized_time() and
x509_ocsp_get_crl_reason() respectively.
Populate the function x509_ocsp_get_cert_status() with code that parses
the following ASN.1 structure:
CertStatus ::= CHOICE {
good [0] IMPLICIT NULL,
revoked [1] IMPLICIT RevokedInfo,
unknown [2] IMPLICIT UnknownInfo }
x509_ocsp_get_cert_status() parses the top level CHOICE and IMPLICIT
components. In the case of status good and unknown, their value is both
expected to be NULL because according to RFC 6960 Section 4.2:
UnknownInfo ::= NULL
Therefore, no further parsing is needed here. In the case of status
revoked, the parsing of Revoked info is delegated to a helper function.