diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-07-01 10:50:57 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-07-01 13:05:10 +0200 |
commit | 23489789f05d5901c8d2e38dbf73f019abf06799 (patch) | |
tree | f004a8d7dfc973cc9c0b3dd08e24c004d7ffe922 /lib | |
parent | 3db11f9acfc1a6b5772db2917016f32197e39517 (diff) | |
download | gnutls-23489789f05d5901c8d2e38dbf73f019abf06799.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>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/x509/ocsp.c | 37 |
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) && |