summaryrefslogtreecommitdiffstats
path: root/src/crypto
diff options
context:
space:
mode:
authorMichael Brown2014-11-24 15:55:07 +0100
committerMichael Brown2014-11-24 16:05:43 +0100
commit5cbdc41778622c07429e00f5aee383b575532bf0 (patch)
treefb2e74c0565b9725332b0511ebf0f9fc3f91d1a2 /src/crypto
parent[intel] Use autoloaded MAC address instead of EEPROM MAC address (diff)
downloadipxe-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.c11
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 ) );
}
/**