diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-07-01 10:50:57 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-07-01 11:04:01 +0200 |
commit | 3c36d980d447251b34677c21bd4a141829c045f6 (patch) | |
tree | 0984edb40f5d59156633a60cce55cde5c12867ad | |
parent | 4115dda443f38119ad46262f7f4adc78cfa1bf83 (diff) | |
download | gnutls-3c36d980d447251b34677c21bd4a141829c045f6.tar.gz |
OCSP: find_signercert: improved DER length calculation
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.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/lib/x509/ocsp.c b/lib/x509/ocsp.c index 68e721eaac..321a676b3c 100644 --- a/lib/x509/ocsp.c +++ b/lib/x509/ocsp.c @@ -1923,9 +1923,10 @@ static gnutls_x509_crt_t find_signercert(gnutls_ocsp_resp_t resp) for (i = 0; i < ncerts; 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"); @@ -1946,19 +1947,36 @@ static gnutls_x509_crt_t find_signercert(gnutls_ocsp_resp_t resp) &spki); if (rc < 0 || spki.size < 6) { 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) && |