summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-11-21 14:59:31 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2018-01-27 16:09:53 +0100
commit291e3a0815bc2e4ca79c96558b749cd4337fd351 (patch)
tree964914317d34a3fda75741de944a0fc2fa4425e6
parent6d0e78c009b28630a46eeaa03e7f1d4d168cd453 (diff)
downloadgnutls-291e3a0815bc2e4ca79c96558b749cd4337fd351.tar.gz
ocsp: introduced gnutls_ocsp_resp_import2 and gnutls_ocsp_resp_export2
These allow importing and exporting an OCSP response to PEM format, in addition to DER. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/includes/gnutls/ocsp.h6
-rw-r--r--lib/libgnutls.map2
-rw-r--r--lib/x509/ocsp.c102
3 files changed, 99 insertions, 11 deletions
diff --git a/lib/includes/gnutls/ocsp.h b/lib/includes/gnutls/ocsp.h
index 8ade965dc0..996875d780 100644
--- a/lib/includes/gnutls/ocsp.h
+++ b/lib/includes/gnutls/ocsp.h
@@ -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);
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 2d611a012f..5ef66b7a59 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1207,6 +1207,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 {
diff --git a/lib/x509/ocsp.c b/lib/x509/ocsp.c
index 08f4c909ec..68e7820746 100644
--- a/lib/x509/ocsp.c
+++ b/lib/x509/ocsp.c
@@ -229,13 +229,46 @@ 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;
+ }
}
/**