]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
lib/x509: use common routine for parsing data version
authorDmitry Baryshkov <dbaryshkov@gmail.com>
Thu, 12 Mar 2020 09:56:37 +0000 (12:56 +0300)
committerDmitry Baryshkov <dbaryshkov@gmail.com>
Thu, 12 Mar 2020 16:47:22 +0000 (19:47 +0300)
OSS Fuzzer noted an issue in parsing (incorrect) CRL files with
zero-length version field. Certificate parser does not have this issue,
while CRL and OCSP Request and Response parsers shows this problem. To
remove code duplication extract common function and use it from all four
parsers.

Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
fuzz/gnutls_x509_crl_parser_fuzzer.repro/698e01fdc3f9a4c402424302768da75f2464a63f [new file with mode: 0644]
lib/x509/common.c
lib/x509/common.h
lib/x509/crl.c
lib/x509/ocsp.c
lib/x509/output.c
lib/x509/x509.c
tests/cert-tests/data/crl-demo3.pem

diff --git a/fuzz/gnutls_x509_crl_parser_fuzzer.repro/698e01fdc3f9a4c402424302768da75f2464a63f b/fuzz/gnutls_x509_crl_parser_fuzzer.repro/698e01fdc3f9a4c402424302768da75f2464a63f
new file mode 100644 (file)
index 0000000..9cc53a3
Binary files /dev/null and b/fuzz/gnutls_x509_crl_parser_fuzzer.repro/698e01fdc3f9a4c402424302768da75f2464a63f differ
index 4939d07d2be69b804b3518404cb1d833f4448f3b..fbc7cc975fe59cc73533309b327740c52a4307f2 100644 (file)
@@ -1926,3 +1926,23 @@ gnutls_gost_paramset_t gnutls_oid_to_gost_paramset(const char *oid)
        else
                return gnutls_assert_val(GNUTLS_GOST_PARAMSET_UNKNOWN);
 }
+
+int _gnutls_x509_get_version(ASN1_TYPE root, const char *name)
+{
+       uint8_t version[8];
+       int len, result;
+
+       len = sizeof(version);
+       result = asn1_read_value(root, name, version, &len);
+       if (result != ASN1_SUCCESS) {
+               if (result == ASN1_ELEMENT_NOT_FOUND)
+                       return 1;       /* the DEFAULT version */
+               gnutls_assert();
+               return _gnutls_asn2err(result);
+       }
+
+       if (len != 1 || version[0] >= 0x80)
+               return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
+
+       return (int) version[0] + 1;
+}
index 498ccc4e97090cc6f5214a30465172ef7e577e3a..54ded21188620d710cdf35e3eb7cdae0b4e9e91c 100644 (file)
@@ -264,6 +264,8 @@ int _gnutls_x509_decode_ext(const gnutls_datum_t *der, gnutls_x509_ext_st *out);
 int _gnutls_x509_raw_crt_to_raw_pubkey(const gnutls_datum_t * cert,
                           gnutls_datum_t * rpubkey);
 
+int _gnutls_x509_get_version(ASN1_TYPE root, const char *name);
+
 int x509_crt_to_raw_pubkey(gnutls_x509_crt_t crt,
                           gnutls_datum_t * rpubkey);
 
index 82deb5e60a88d1afba757bbf40098aaf05d1e72d..76d90925e80aa100ee564088b8a973b8764a132c 100644 (file)
@@ -484,23 +484,12 @@ gnutls_x509_crl_get_signature(gnutls_x509_crl_t crl,
  **/
 int gnutls_x509_crl_get_version(gnutls_x509_crl_t crl)
 {
-       uint8_t version[8];
-       int len, result;
-
        if (crl == NULL) {
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
        }
 
-       len = sizeof(version);
-       if ((result =
-            asn1_read_value(crl->crl, "tbsCertList.version", version,
-                            &len)) != ASN1_SUCCESS) {
-               gnutls_assert();
-               return _gnutls_asn2err(result);
-       }
-
-       return (int) version[0] + 1;
+       return _gnutls_x509_get_version(crl->crl, "tbsCertList.version");
 }
 
 /**
index 38df56ef1cae744a58173ab630068fb1b44c190e..caa511e9db728ba98d2985cf781ffc4d5f40e516 100644 (file)
@@ -456,25 +456,12 @@ int gnutls_ocsp_resp_export2(gnutls_ocsp_resp_const_t resp, gnutls_datum_t * dat
  **/
 int gnutls_ocsp_req_get_version(gnutls_ocsp_req_const_t req)
 {
-       uint8_t version[8];
-       int len, ret;
-
        if (req == NULL) {
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
        }
 
-       len = sizeof(version);
-       ret =
-           asn1_read_value(req->req, "tbsRequest.version", version, &len);
-       if (ret != ASN1_SUCCESS) {
-               if (ret == ASN1_ELEMENT_NOT_FOUND)
-                       return 1;       /* the DEFAULT version */
-               gnutls_assert();
-               return _gnutls_asn2err(ret);
-       }
-
-       return (int) version[0] + 1;
+       return _gnutls_x509_get_version(req->req, "tbsRequest.version");
 }
 
 /**
@@ -1153,26 +1140,12 @@ gnutls_ocsp_resp_get_response(gnutls_ocsp_resp_const_t resp,
  **/
 int gnutls_ocsp_resp_get_version(gnutls_ocsp_resp_const_t resp)
 {
-       uint8_t version[8];
-       int len, ret;
-
        if (resp == NULL) {
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
        }
 
-       len = sizeof(version);
-       ret =
-           asn1_read_value(resp->resp, "tbsResponseData.version", version,
-                           &len);
-       if (ret != ASN1_SUCCESS) {
-               if (ret == ASN1_ELEMENT_NOT_FOUND)
-                       return 1;       /* the DEFAULT version */
-               gnutls_assert();
-               return _gnutls_asn2err(ret);
-       }
-
-       return (int) version[0] + 1;
+       return _gnutls_x509_get_version(resp->resp, "tbsResponseData.version");
 }
 
 /**
index 7278c3c0f8d8c33fd08dd04676887285c1e9db5d..8084b92b2905c4d49dbe9ddbaa74b3cf0bc25bf8 100644 (file)
@@ -2204,9 +2204,7 @@ print_crl(gnutls_buffer_st * str, gnutls_x509_crl_t crl, int notsigned)
        /* Version. */
        {
                int version = gnutls_x509_crl_get_version(crl);
-               if (version == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
-                       adds(str, _("\tVersion: 1 (default)\n"));
-               else if (version < 0)
+               if (version < 0)
                        addf(str, "error: get_version: %s\n",
                             gnutls_strerror(version));
                else
index 57c718289474edd97b88725ee4292530ce35aba7..2091f3ae643b5cec630a245a1d307335183eb4cc 100644 (file)
@@ -1177,29 +1177,12 @@ gnutls_x509_crt_get_signature(gnutls_x509_crt_t cert,
  **/
 int gnutls_x509_crt_get_version(gnutls_x509_crt_t cert)
 {
-       uint8_t version[8];
-       int len, result;
-
        if (cert == NULL) {
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
        }
 
-       len = sizeof(version);
-       if ((result =
-            asn1_read_value(cert->cert, "tbsCertificate.version", version,
-                            &len)) != ASN1_SUCCESS) {
-
-               if (result == ASN1_ELEMENT_NOT_FOUND)
-                       return 1;       /* the DEFAULT version */
-               gnutls_assert();
-               return _gnutls_asn2err(result);
-       }
-
-       if (len != 1 || version[0] >= 0x80)
-               return gnutls_assert_val(GNUTLS_E_CERTIFICATE_ERROR);
-
-       return (int) version[0] + 1;
+       return _gnutls_x509_get_version(cert->cert, "tbsCertificate.version");
 }
 
 /**
index 1e04338c67ab57dfe2ffeca6c35e89b148cdccbf..a91b1f905ab158d6a09856fc0f0af6de37623d7e 100644 (file)
@@ -1,5 +1,5 @@
 X.509 Certificate Revocation List Information:
-       Version: 1 (default)
+       Version: 1
        Issuer: OU=VeriSign Commercial Software Publishers CA,O=VeriSign\, Inc.,L=Internet
        Update dates:
                Issued: Wed Mar 08 09:00:11 UTC 2017