Commit Graph

5490 Commits

Author SHA1 Message Date
Andres Amaya Garcia
02d7ddcfcc Add verification for each OCSP SingleResponse
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.
2018-01-18 22:03:28 +00:00
Andres Amaya Garcia
07a934c0a0 Add OCSP response signature verification
The signature is calculated over the hash of the DER encoded
ResponseData as per RFC 6960.
2018-01-18 22:03:28 +00:00
Andres Amaya Garcia
9b0136dcb9 Finish OCSP response issuer finding function
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.
2018-01-18 22:03:28 +00:00
Andres Amaya Garcia
eb00356168 Add skeleton code to find OCSP response issuer
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
2018-01-18 22:03:28 +00:00
Andres Amaya Garcia
016dda5a7f Add main OCSP response verification function
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.
2018-01-18 22:03:26 +00:00
Andres Amaya Garcia
6a6011043b Rework mbedtls_x509_ocsp_response_info()
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.
2018-01-18 22:01:44 +00:00
Andres Amaya Garcia
22b7c1745f Rename x509_ocsp_response functions to fit pattern
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
2018-01-18 19:45:30 +00:00
Andres Amaya Garcia
b3b380d700 Run generate_features.pl and generate_visualc_files.pl 2018-01-18 19:45:30 +00:00
Andres Amaya Garcia
f49c82717c Increase DER OCSP response buffer len to place larger test data 2018-01-18 19:45:30 +00:00
Andres Amaya Garcia
2868fad4af Add signature and certs tests for OCSP parsing 2018-01-18 19:45:30 +00:00
Andres Amaya Garcia
49afce56a0 Fix spacing around + in test_suite_x509parse_ocsp.data 2018-01-18 19:45:30 +00:00
Andres Amaya Garcia
7283253073 Use more specific error code when parsing GenTime
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.
2018-01-18 19:45:29 +00:00
Andres Amaya Garcia
2fbc131d8c Update comments in OCSP code and add missing checks 2018-01-18 19:45:29 +00:00
Andres Amaya Garcia
bb0ed5770f Remove debugging code from x509parse_ocsp test suite 2018-01-18 19:45:29 +00:00
Andres Amaya Garcia
da29b86513 Add negative tests for OCSP ResponseData 2018-01-18 19:45:29 +00:00
Andres Amaya Garcia
8df18f0caa Remove SHA1 from the list of dependencies for OCSP 2018-01-18 19:45:29 +00:00
Andres Amaya Garcia
a5487f5620 Add test suite for x509ocsp parsing
This commit only adds the test code for
mbedtls_x509_ocsp_parse_response() and an initial set of negative tests

So far, the tests introduced are manually crafted malicious OCSP
responses that tests several error conditions in the initial part of
the response structure including the response status, producedAt date,
ResponderID, part of the tsbResponseData, etc.
2018-01-18 19:45:29 +00:00
Andres Amaya Garcia
84038e81b0 Fix parsing of RevocationInfo
Remove double parsing of the SEQUENCE tag that encloses the
RevocationInfo ASN.1 structure in an OCSP response.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
f7a5ddf682 Fix init of OCSP response struct 2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
ee0b017085 Track OCSP ResponseData to facilitate verification 2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
b2ed34208d Fix typo in ocsp struct field name 2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
f43bc1077c OCSP parser rejects ResponseBytes on failure
Improve the OCSP parsing code so that it rejects OCSP responses that
have a failure code value in ResponseStatus but contain ResponseBytes.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
7bb5a85276 Factor OCSP code to parse hashes in response
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
4098d859fc Fix documentation spacing in x509.h 2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
fc3afe5c6b Ensure that the responseType is OCSP Basic
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
b85378efb3 Add missing dependencies to x509_ocsp.c
Add missing dependency checks to check_config.h and documentation to
config.h. Note that SHA-1 is required for OCSP as RFC 6960 Section
4.4.2 specifies that the ResponderID byKey is the SHA-1 hash of the
responder's public key. That is, without SHA-1 we might not be able to
tell who signed the OCSP response.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
1c0aac06f7 Make input buf const in mbedtls_x509_ocsp_parse_response()
Make the input buffer const in the function
mbedtls_x509_ocsp_parse_response() to follow the same coding pattern as
in mbedtls_x509_crt_parse().
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
462eb3bf1f Fix doxygen warnings in x509_ocsp.h
Fix copy-paste errors in doxygen documentation that were causing
warnings due to variable names not matching the function definition.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
26d32e49f8 Call correct free on OCSP response_id after fail
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
e8dc64cbf5 Add 1 to tmp buf size in x509_ocsp_info_certs()
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
7bdac59ad7 Add missing return in x509_ocsp_get_response()
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
03b02e3277 Prevent NULL pointer dereference in x509_ocsp.c
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
3140f2fac5 Create MBEDTLS_X509_OCSP_PARSE_C feature macro
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
dafbfc4b8a Relocate OCSP and CRL errors to x509.h
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
caa1c8f827 Implement mbedtls_x509_ocsp_response_free() 2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
e5356c2bed Implement mbedtls_x509_ocsp_response_init() 2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
aa8336eb9f Document that x509_ocsp_get_crl_reason() belongs in x509_crl 2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
544e072cdb Remove redundant bound checks in x509_ocsp.c
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
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
9fe79ac4d8 Improve comments in x509_ocsp_get_response_status 2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
98a0f21456 Add information string for certs in OCSP response 2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
98f7bb911f Parse certificates in in OCSP
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
b565031a2b Add informational string for signatureAlgorithm in OCSP 2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
77c0c8e9a2 Parse signatureAlgorithm of OCSP response
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()
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
647a62133d Add code to skip extensions in OCSP response
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
2777b0e4d7 Add informational string for SingleResponse in OCSP 2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
51e6b34cdb Parse CRLReason a concep imported from CRL profile
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) }
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
ba6e0c534c Parse RevokedInfo in OCSP response
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
98dc01ba67 Parse CertStatus in OCSP response
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.
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
cc4b2aa957 Parse CertID in OCSP response
Populate the function x509_ocsp_get_cert_id() that parses the following
ASN.1 structure:

   CertID          ::=     SEQUENCE {
       hashAlgorithm       AlgorithmIdentifier,
       issuerNameHash      OCTET STRING, -- Hash of issuer's DN
       issuerKeyHash       OCTET STRING, -- Hash of issuer's public key
       serialNumber        CertificateSerialNumber }

x509_ocsp_get_cert_id() parses the top-level SEQUENCE component and
calls the following helpers for the actual contents of the CertID:

    * mbedtls_x509_get_md_alg(): Parses the hashAlgorithm
    * x509_ocsp_get_octet_string(): Parses the OCTET STRINGs
      issuerNameHash and issuerKeyHash, but does not actually check
      that the length or hashes are actually correct or correspond
      to the expected length given the hashAlgorithm
    * mbedtls_x509_get_serial: Parses the serialNumber
2017-11-11 12:49:19 +00:00
Andres Amaya Garcia
45289f4ca6 Parse top-level of SingleResponse in OCSP response
Populate the function x509_ocsp_get_single_response() that parses the
following ASN.1 structure:

   SingleResponse ::= SEQUENCE {
      certID                       CertID,
      certStatus                   CertStatus,
      thisUpdate                   GeneralizedTime,
      nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
      singleExtensions   [1]       EXPLICIT Extensions OPTIONAL }

x509_ocsp_get_single_response() parses the top-level SEQUENCE and the
two explicit tags. Note that the tagged values at the end of the
SingleResponse are optional so this function takes care of the
following cases using a switch statement:

    * nextUpdate only
    * nextUpdate followed by SingleExtensions
    * singleExtensions only
2017-11-11 12:49:19 +00:00