]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
ocsp: introduced gnutls_ocsp_resp_import2 and gnutls_ocsp_resp_export2
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 21 Nov 2017 13:59:31 +0000 (14:59 +0100)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 19 Feb 2018 14:29:36 +0000 (15:29 +0100)
These allow importing and exporting an OCSP response to PEM format,
in addition to DER.

Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
lib/includes/gnutls/ocsp.h
lib/libgnutls.map
lib/x509/ocsp.c

index 8ade965dc0e52c80c16db890e7b87cd0db2e4b08..996875d7809fb745c53931e996c67993ac467374 100644 (file)
@@ -196,8 +196,14 @@ void gnutls_ocsp_resp_deinit(gnutls_ocsp_resp_t resp);
 
 int gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp,
                            const gnutls_datum_t * data);
+int gnutls_ocsp_resp_import2(gnutls_ocsp_resp_t resp,
+                            const gnutls_datum_t * data,
+                            gnutls_x509_crt_fmt_t fmt);
 int gnutls_ocsp_resp_export(gnutls_ocsp_resp_t resp,
                            gnutls_datum_t * data);
+int gnutls_ocsp_resp_export2(gnutls_ocsp_resp_t resp,
+                            gnutls_datum_t * data,
+                            gnutls_x509_crt_fmt_t fmt);
 int gnutls_ocsp_resp_print(gnutls_ocsp_resp_t resp,
                           gnutls_ocsp_print_formats_t format,
                           gnutls_datum_t * out);
index 9a0660eb4b31cf972bad4f391073dbc5d11a8965..599ef5e89d29f40bfa0b64e4dd106c37e1855b3c 100644 (file)
@@ -1211,6 +1211,8 @@ GNUTLS_3_6_xx
        gnutls_ext_get_current_msg;
        gnutls_reauth;
        gnutls_ocsp_status_request_get2;
+       gnutls_ocsp_resp_import2;
+       gnutls_ocsp_resp_export2;
 } GNUTLS_3_6_2;
 
 GNUTLS_FIPS140_3_4 {
index 08f4c909eca2717d959bb9579c7a01b8c6f7c608..68e78207461901244910709c53e360fe4e5f2361 100644 (file)
@@ -228,14 +228,47 @@ gnutls_ocsp_req_import(gnutls_ocsp_req_t req, const gnutls_datum_t * data)
 int
 gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp,
                        const gnutls_datum_t * data)
+{
+       return gnutls_ocsp_resp_import2(resp, data, GNUTLS_X509_FMT_DER);
+}
+
+/**
+ * gnutls_ocsp_resp_import2:
+ * @resp: The data to store the parsed response.
+ * @data: DER or PEM encoded OCSP response.
+ * @fmt: DER or PEM
+ *
+ * This function will convert the given OCSP response to
+ * the native #gnutls_ocsp_resp_t format.  It also decodes the Basic
+ * OCSP Response part, if any.  The output will be stored in @resp.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ *
+ * Since: 3.6.xx
+ **/
+int
+gnutls_ocsp_resp_import2(gnutls_ocsp_resp_t resp,
+                        const gnutls_datum_t *data,
+                        gnutls_x509_crt_fmt_t fmt)
 {
        int ret = 0;
+       gnutls_datum_t der;
 
        if (resp == NULL || data == NULL) {
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
        }
 
+       der.data = data->data;
+       der.size = data->size;
+
+       if (fmt == GNUTLS_X509_FMT_PEM) {
+               ret = gnutls_pem_base64_decode2("OCSP RESPONSE", data, &der);
+               if (ret < 0)
+                       return gnutls_assert_val(ret);
+       }
+
        if (resp->init != 0) {
                /* Any earlier _asn1_strict_der_decode will modify the ASN.1
                   structure, so we need to replace it with a fresh
@@ -249,7 +282,8 @@ gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp,
                                          &resp->resp);
                if (ret != ASN1_SUCCESS) {
                        gnutls_assert();
-                       return _gnutls_asn2err(ret);
+                       ret = _gnutls_asn2err(ret);
+                       goto cleanup;
                }
 
                ret = asn1_create_element(_gnutls_get_pkix(),
@@ -257,7 +291,8 @@ gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp,
                                          &resp->basicresp);
                if (ret != ASN1_SUCCESS) {
                        gnutls_assert();
-                       return _gnutls_asn2err(ret);
+                       ret = _gnutls_asn2err(ret);
+                       goto cleanup;
                }
 
                gnutls_free(resp->der.data);
@@ -265,15 +300,18 @@ gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp,
        }
 
        resp->init = 1;
-       ret = _asn1_strict_der_decode(&resp->resp, data->data, data->size, NULL);
+       ret = _asn1_strict_der_decode(&resp->resp, der.data, der.size, NULL);
        if (ret != ASN1_SUCCESS) {
                gnutls_assert();
-               return _gnutls_asn2err(ret);
+               ret = _gnutls_asn2err(ret);
+               goto cleanup;
        }
 
        if (gnutls_ocsp_resp_get_status(resp) !=
-           GNUTLS_OCSP_RESP_SUCCESSFUL)
-               return GNUTLS_E_SUCCESS;
+           GNUTLS_OCSP_RESP_SUCCESSFUL) {
+               ret = GNUTLS_E_SUCCESS;
+               goto cleanup;
+       }
 
        ret =
            _gnutls_x509_read_value(resp->resp,
@@ -281,7 +319,7 @@ gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp,
                                    &resp->response_type_oid);
        if (ret < 0) {
                gnutls_assert();
-               return ret;
+               goto cleanup;
        }
 #define OCSP_BASIC "1.3.6.1.5.5.7.48.1.1"
 
@@ -294,7 +332,7 @@ gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp,
                                            "responseBytes.response", &resp->der);
                if (ret < 0) {
                        gnutls_assert();
-                       return ret;
+                       goto cleanup;
                }
 
                ret =
@@ -302,14 +340,19 @@ gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp,
                                      NULL);
                if (ret != ASN1_SUCCESS) {
                        gnutls_assert();
-                       return _gnutls_asn2err(ret);
+                       ret = _gnutls_asn2err(ret);
+                       goto cleanup;
                }
        } else {
                asn1_delete_structure(&resp->basicresp);
                resp->basicresp = NULL;
        }
 
-       return GNUTLS_E_SUCCESS;
+       ret = GNUTLS_E_SUCCESS;
+cleanup:
+       if (der.data != data->data)
+               gnutls_free(der.data);
+       return ret;
 }
 
 /**
@@ -356,12 +399,49 @@ int gnutls_ocsp_req_export(gnutls_ocsp_req_t req, gnutls_datum_t * data)
  **/
 int gnutls_ocsp_resp_export(gnutls_ocsp_resp_t resp, gnutls_datum_t * data)
 {
+       return gnutls_ocsp_resp_export2(resp, data, GNUTLS_X509_FMT_DER);
+}
+
+/**
+ * gnutls_ocsp_resp_export2:
+ * @resp: Holds the OCSP response
+ * @data: newly allocate buffer holding DER or PEM encoded OCSP response
+ * @fmt: DER or PEM
+ *
+ * This function will export the OCSP response to DER or PEM format.
+ *
+ * Returns: In case of failure a negative error code will be
+ *   returned, and 0 on success.
+ *
+ * Since: 3.6.xx
+ **/
+int gnutls_ocsp_resp_export2(gnutls_ocsp_resp_t resp, gnutls_datum_t * data,
+                            gnutls_x509_crt_fmt_t fmt)
+{
+       int ret;
+       gnutls_datum_t der;
+
        if (resp == NULL || data == NULL) {
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
        }
 
-       return _gnutls_x509_get_raw_field(resp->resp, "", data);
+       ret = _gnutls_x509_get_raw_field(resp->resp, "", &der);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
+
+       if (fmt == GNUTLS_X509_FMT_DER) {
+               data->data = der.data;
+               data->size = der.size;
+               return ret;
+       } else {
+               ret = gnutls_pem_base64_encode2("OCSP RESPONSE", &der, data);
+               gnutls_free(der.data);
+               if (ret < 0)
+                       return gnutls_assert_val(ret);
+
+               return 0;
+       }
 }
 
 /**