summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-11-29 14:27:44 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2018-02-19 15:29:36 +0100
commit74b73eab2460119dd7d5a3add2a1425c462f54b2 (patch)
tree503d16786d8426cf34be9ed2c9523988c1aa77f7
parent6a4251c035772691b6928cd7e24c194e5adcfc4b (diff)
downloadgnutls-74b73eab2460119dd7d5a3add2a1425c462f54b2.tar.gz
gnutls_ocsp_resp_list_import2: introduced
That is, introduced function to to import multiple OCSP PEM responses into a list. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/includes/gnutls/ocsp.h7
-rw-r--r--lib/libgnutls.map1
-rw-r--r--lib/x509.h2
-rw-r--r--lib/x509/ocsp.c137
4 files changed, 145 insertions, 2 deletions
diff --git a/lib/includes/gnutls/ocsp.h b/lib/includes/gnutls/ocsp.h
index 996875d780..966e1d5b8c 100644
--- a/lib/includes/gnutls/ocsp.h
+++ b/lib/includes/gnutls/ocsp.h
@@ -268,6 +268,13 @@ int gnutls_ocsp_resp_verify(gnutls_ocsp_resp_t resp,
int gnutls_ocsp_resp_check_crt(gnutls_ocsp_resp_t resp,
unsigned int indx, gnutls_x509_crt_t crt);
+int
+gnutls_ocsp_resp_list_import2(gnutls_ocsp_resp_t **ocsps,
+ unsigned int *size,
+ const gnutls_datum_t *resp_data,
+ gnutls_x509_crt_fmt_t format,
+ unsigned int flags);
+
/* *INDENT-OFF* */
#ifdef __cplusplus
}
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 599ef5e89d..d29d650a81 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1213,6 +1213,7 @@ GNUTLS_3_6_xx
gnutls_ocsp_status_request_get2;
gnutls_ocsp_resp_import2;
gnutls_ocsp_resp_export2;
+ gnutls_ocsp_resp_list_import2;
} GNUTLS_3_6_2;
GNUTLS_FIPS140_3_4 {
diff --git a/lib/x509.h b/lib/x509.h
index 4da17761cd..859824056a 100644
--- a/lib/x509.h
+++ b/lib/x509.h
@@ -30,6 +30,8 @@ int _gnutls_x509_cert_verify_peers(gnutls_session_t session,
#define PEM_CERT_SEP2 "-----BEGIN X509 CERTIFICATE"
#define PEM_CERT_SEP "-----BEGIN CERTIFICATE"
+#define PEM_OCSP_RESPONSE "-----BEGIN OCSP RESPONSE"
+#define BARE_PEM_OCSP_RESPONSE "OCSP RESPONSE"
#define PEM_CRL_SEP "-----BEGIN X509 CRL"
diff --git a/lib/x509/ocsp.c b/lib/x509/ocsp.c
index 68e7820746..9edaa48022 100644
--- a/lib/x509/ocsp.c
+++ b/lib/x509/ocsp.c
@@ -31,6 +31,7 @@
#include <pk.h>
#include "common.h"
#include "verify-high.h"
+#include "x509.h"
#include <gnutls/ocsp.h>
#include <auth/cert.h>
@@ -264,9 +265,10 @@ gnutls_ocsp_resp_import2(gnutls_ocsp_resp_t resp,
der.size = data->size;
if (fmt == GNUTLS_X509_FMT_PEM) {
- ret = gnutls_pem_base64_decode2("OCSP RESPONSE", data, &der);
- if (ret < 0)
+ ret = gnutls_pem_base64_decode2(BARE_PEM_OCSP_RESPONSE, data, &der);
+ if (ret < 0) {
return gnutls_assert_val(ret);
+ }
}
if (resp->init != 0) {
@@ -2410,3 +2412,134 @@ gnutls_ocsp_resp_verify(gnutls_ocsp_resp_t resp,
return rc;
}
+
+/**
+ * gnutls_x509_ocsp_resp_list_import2:
+ * @ocsps: Will hold the parsed OCSP response list.
+ * @size: It will contain the size of the list.
+ * @resp_data: The PEM encoded OCSP list.
+ * @format: Must be PEM.
+ * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
+ *
+ * This function will convert the given PEM encoded OCSP response list
+ * to the native gnutls_ocsp_resp_t format. The output will be stored
+ * in @ocsps which will allocated and initialized.
+ *
+ * The OCSP responses should have a header of "OCSP RESPONSE".
+ *
+ * To deinitialize responses, you need to deinitialize each %gnutls_ocsp_resp_t
+ * structure independently, and use gnutls_free() at @ocsps.
+ *
+ * In PEM files, when no OCSP responses are detected
+ * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
+ *
+ * Returns: the number of responses read or a negative error value.
+ *
+ * Since: 3.6.xx
+ **/
+int
+gnutls_ocsp_resp_list_import2(gnutls_ocsp_resp_t **ocsps,
+ unsigned int *size,
+ const gnutls_datum_t *resp_data,
+ gnutls_x509_crt_fmt_t format,
+ unsigned int flags)
+{
+ gnutls_ocsp_resp_t resp = NULL;
+ gnutls_ocsp_resp_t *new_ocsps;
+ int ret;
+ unsigned i;
+
+
+ if (format == GNUTLS_X509_FMT_PEM) {
+ /* load multiple responses */
+ gnutls_datum_t p = {resp_data->data, resp_data->size};
+
+ *size = 0;
+ *ocsps = NULL;
+
+ p.data = memmem(p.data, p.size, PEM_OCSP_RESPONSE,
+ sizeof(PEM_OCSP_RESPONSE)-1);
+ if (p.data == NULL) {
+ ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+ goto cleanup;
+ }
+
+ p.size -= p.data - resp_data->data;
+ if (p.size <= 0) {
+ ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+ goto cleanup;
+ }
+
+ do {
+ ret = gnutls_ocsp_resp_init(&resp);
+ if (ret < 0) {
+ gnutls_assert();
+ goto fail;
+ }
+
+ ret = gnutls_ocsp_resp_import2(resp, &p, GNUTLS_X509_FMT_PEM);
+ if (ret < 0) {
+ gnutls_assert();
+ goto fail;
+ }
+
+ new_ocsps = gnutls_realloc(*ocsps, (*size + 1)*sizeof(gnutls_ocsp_resp_t));
+ if (new_ocsps == NULL) {
+ resp = NULL;
+ gnutls_assert();
+ goto fail;
+ }
+
+ new_ocsps[*size] = resp;
+ resp = NULL;
+ (*size)++;
+ *ocsps = new_ocsps;
+
+ p.data++;
+ p.size--;
+
+ p.data = memmem(p.data, p.size, PEM_OCSP_RESPONSE,
+ sizeof(PEM_OCSP_RESPONSE)-1);
+ if (p.data == NULL)
+ break;
+ p.size = resp_data->size - (p.data - resp_data->data);
+ } while(p.size > 0);
+ } else {
+ /* DER: load a single response */
+ ret = gnutls_ocsp_resp_init(&resp);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ ret = gnutls_ocsp_resp_import2(resp, resp_data, GNUTLS_X509_FMT_DER);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ *ocsps = gnutls_malloc(1*sizeof(gnutls_ocsp_resp_t));
+ if (*ocsps == NULL) {
+ gnutls_assert();
+ ret = GNUTLS_E_MEMORY_ERROR;
+ goto cleanup;
+ }
+
+ (*ocsps)[0] = resp;
+ resp = NULL;
+ *size = 1;
+ }
+
+ ret = 0;
+ goto cleanup;
+
+ fail:
+ for (i=0;i<*size;i++) {
+ gnutls_ocsp_resp_deinit((*ocsps)[i]);
+ }
+ gnutls_free(*ocsps);
+
+ cleanup:
+ if (resp)
+ gnutls_ocsp_resp_deinit(resp);
+ return ret;
+}