From 5cbdc41778622c07429e00f5aee383b575532bf0 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 24 Nov 2014 14:55:07 +0000 Subject: [crypto] Fix parsing of OCSP responder ID key hash We currently compare the entirety of the KeyHash object (including the ASN.1 tag and length byte) against the raw SHA-1 hash of the certificate's public key. This causes OCSP validation to fail for any responses which identify the responder by key hash rather than by name, and hence prevents the use of X.509 certificates where any certificate in the chain has an OCSP responder which chooses to identify itself via its key hash. Fix by adding the missing asn1_enter() required to enter the ASN.1 octet string containing the key hash. Also add a corresponding test case including an OCSP response where the responder is identified by key hash, to ensure that this functionality cannot be broken in future. Debugged-by: Brian Rak Signed-off-by: Michael Brown --- src/crypto/ocsp.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/crypto') diff --git a/src/crypto/ocsp.c b/src/crypto/ocsp.c index d4815a1b..66e47c57 100644 --- a/src/crypto/ocsp.c +++ b/src/crypto/ocsp.c @@ -405,12 +405,17 @@ static int ocsp_compare_responder_name ( struct ocsp_check *ocsp, static int ocsp_compare_responder_key_hash ( struct ocsp_check *ocsp, struct x509_certificate *cert ) { struct ocsp_responder *responder = &ocsp->response.responder; + struct asn1_cursor key_hash; uint8_t ctx[SHA1_CTX_SIZE]; uint8_t digest[SHA1_DIGEST_SIZE]; int difference; + /* Enter responder key hash */ + memcpy ( &key_hash, &responder->id, sizeof ( key_hash ) ); + asn1_enter ( &key_hash, ASN1_OCTET_STRING ); + /* Sanity check */ - difference = ( sizeof ( digest ) - responder->id.len ); + difference = ( sizeof ( digest ) - key_hash.len ); if ( difference ) return difference; @@ -421,8 +426,8 @@ static int ocsp_compare_responder_key_hash ( struct ocsp_check *ocsp, cert->subject.public_key.raw_bits.len ); digest_final ( &sha1_algorithm, ctx, digest ); - /* Compare responder ID with SHA1 hash of certificate's public key */ - return memcmp ( digest, responder->id.data, sizeof ( digest ) ); + /* Compare responder key hash with hash of certificate's public key */ + return memcmp ( digest, key_hash.data, sizeof ( digest ) ); } /** -- cgit v1.2.3-55-g7522