diff options
author | Michael Brown | 2014-11-24 15:55:07 +0100 |
---|---|---|
committer | Michael Brown | 2014-11-24 16:05:43 +0100 |
commit | 5cbdc41778622c07429e00f5aee383b575532bf0 (patch) | |
tree | fb2e74c0565b9725332b0511ebf0f9fc3f91d1a2 /src/crypto | |
parent | [intel] Use autoloaded MAC address instead of EEPROM MAC address (diff) | |
download | ipxe-5cbdc41778622c07429e00f5aee383b575532bf0.tar.gz ipxe-5cbdc41778622c07429e00f5aee383b575532bf0.tar.xz ipxe-5cbdc41778622c07429e00f5aee383b575532bf0.zip |
[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 <brak@gameservers.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/crypto')
-rw-r--r-- | src/crypto/ocsp.c | 11 |
1 files changed, 8 insertions, 3 deletions
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 ) ); } /** |