Skip to content

Commit

Permalink
[crypto] Fix parsing of OCSP responder ID key hash
Browse files Browse the repository at this point in the history
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 <brak@gameservers.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Nov 24, 2014
1 parent a937615 commit 5cbdc41
Show file tree
Hide file tree
Showing 2 changed files with 419 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/crypto/ocsp.c
Expand Up @@ -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;

Expand All @@ -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 ) );
}

/**
Expand Down

0 comments on commit 5cbdc41

Please sign in to comment.