summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2017-07-01 10:50:57 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-07-01 13:05:10 +0200
commit23489789f05d5901c8d2e38dbf73f019abf06799 (patch)
treef004a8d7dfc973cc9c0b3dd08e24c004d7ffe922
parent3db11f9acfc1a6b5772db2917016f32197e39517 (diff)
downloadgnutls-tmp-ocsp-improvements.tar.gz
OCSP: find_signercert: improved DER length calculationtmp-ocsp-improvements
Previously we were assuming a fixed amount of length bytes which is not correct for all possible lengths. Use libtasn1 to decode the length field. Resolves: #223 Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
-rw-r--r--lib/x509/ocsp.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/lib/x509/ocsp.c b/lib/x509/ocsp.c
index 90f4ab5dc0..08f4c909ec 100644
--- a/lib/x509/ocsp.c
+++ b/lib/x509/ocsp.c
@@ -1,6 +1,8 @@
/*
* Copyright (C) 2011-2012 Free Software Foundation, Inc.
- * Author: Simon Josefsson
+ * Copyright (C) 2016-2017 Red Hat, Inc.
+ *
+ * Author: Simon Josefsson, Nikos Mavrogiannopoulos
*
* This file is part of GnuTLS.
*
@@ -33,6 +35,8 @@
#include <gnutls/ocsp.h>
#include <auth/cert.h>
+#include <assert.h>
+
typedef struct gnutls_ocsp_req_int {
ASN1_TYPE req;
unsigned init;
@@ -1922,11 +1926,13 @@ static gnutls_x509_crt_t find_signercert(gnutls_ocsp_resp_t resp)
}
for (i = 0; i < ncerts; i++) {
+ assert(certs[i] != NULL);
_gnutls_cert_log("checking whether signed against", certs[i]);
if (keyid.data != NULL) {
- uint8_t digest[128]; /* to support longer key IDs */
+ uint8_t digest[64]; /* to support longer key IDs */
gnutls_datum_t spki;
size_t digest_size = sizeof(digest);
+ int len;
_gnutls_debug_log("checking key ID against SPK identifier\n");
@@ -1948,19 +1954,36 @@ static gnutls_x509_crt_t find_signercert(gnutls_ocsp_resp_t resp)
if (rc < 0 || spki.size < 6) {
gnutls_assert();
signercert = NULL;
- goto quit;
+ continue;
}
/* For some reason the protocol requires we skip the
* tag, length and number of unused bits.
*/
- spki.data += 5;
- spki.size -= 5;
- rc = gnutls_hash_fast(GNUTLS_DIG_SHA1, spki.data, spki.size, digest);
+ if (spki.data[0] != 0x03) { /* bit string */
+ gnutls_assert();
+ signercert = NULL;
+ continue;
+ }
+
+ rc = asn1_get_length_der(spki.data+1, spki.size-1, &len);
+ if (rc <= 0) {
+ gnutls_assert();
+ signercert = NULL;
+ continue;
+ }
+ len += 1+1; /* skip unused bits as well */
+ if (len >= (int)spki.size) {
+ gnutls_assert();
+ signercert = NULL;
+ continue;
+ }
+
+ rc = gnutls_hash_fast(GNUTLS_DIG_SHA1, spki.data+len, spki.size-len, digest);
if (rc < 0) {
gnutls_assert();
signercert = NULL;
- goto quit;
+ continue;
}
if ((20 == keyid.size) &&