[ocsp] Accept SHA1 certID responses even if SHA1 is not enabled

Various implementation quirks in OCSP servers make it impractical to
use anything other than SHA1 to construct the issuerNameHash and
issuerKeyHash identifiers in the request certID.  For example: both
the OpenCA OCSP responder used by ipxe.org and the Boulder OCSP
responder used by LetsEncrypt will fail if SHA256 is used in the
request certID.

As of commit 6ffe28a ("[ocsp] Accept response certID with missing
hashAlgorithm parameters") we rely on asn1_digest_algorithm() to parse
the algorithm identifier in the response certID.  This will fail if
SHA1 is disabled via config/crypto.h.

Fix by using a direct ASN.1 object comparison on the OID within the
algorithm identifier.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
diff --git a/src/crypto/ocsp.c b/src/crypto/ocsp.c
index 2c747fb..9ced59e 100644
--- a/src/crypto/ocsp.c
+++ b/src/crypto/ocsp.c
@@ -476,33 +476,43 @@
  */
 static int ocsp_parse_cert_id ( struct ocsp_check *ocsp,
 				const struct asn1_cursor *raw ) {
+	static struct asn1_cursor algorithm = {
+		.data = ocsp_algorithm_id,
+		.len = sizeof ( ocsp_algorithm_id ),
+	};
+	struct asn1_cursor cert_id;
 	struct asn1_cursor cursor;
-	struct asn1_algorithm *algorithm;
 	int rc;
 
-	/* Check certID algorithm */
-	memcpy ( &cursor, raw, sizeof ( cursor ) );
-	asn1_enter ( &cursor, ASN1_SEQUENCE );
-	if ( ( rc = asn1_digest_algorithm ( &cursor, &algorithm ) ) != 0 ) {
-		DBGC ( ocsp, "OCSP %p \"%s\" certID unknown algorithm: %s\n",
-		       ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
-		return rc;
+	/* Enter cert ID */
+	memcpy ( &cert_id, raw, sizeof ( cert_id ) );
+	asn1_enter ( &cert_id, ASN1_SEQUENCE );
+
+	/* Check certID algorithm (but not parameters) */
+	memcpy ( &cursor, &cert_id, sizeof ( cursor ) );
+	if ( ( rc = ( asn1_enter ( &cursor, ASN1_SEQUENCE ),
+		      asn1_shrink ( &cursor, ASN1_OID ),
+		      asn1_shrink ( &algorithm, ASN1_OID ) ) ) != 0 ) {
+		DBGC ( ocsp, "OCSP %p \"%s\" certID missing algorithm:\n",
+		       ocsp, x509_name ( ocsp->cert ) );
+		DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
+		return -EACCES_CERT_MISMATCH;
 	}
-	if ( algorithm->digest != &ocsp_digest_algorithm ) {
-		DBGC ( ocsp, "OCSP %p \"%s\" certID wrong algorithm %s\n",
-		       ocsp, x509_name ( ocsp->cert ),
-		       algorithm->digest->name );
+	if ( asn1_compare ( &cursor, &algorithm ) != 0 ) {
+		DBGC ( ocsp, "OCSP %p \"%s\" certID wrong algorithm:\n",
+		       ocsp, x509_name ( ocsp->cert ) );
+		DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
 		return -EACCES_CERT_MISMATCH;
 	}
 
 	/* Check remaining certID fields */
-	asn1_skip ( &cursor, ASN1_SEQUENCE );
-	if ( asn1_compare ( &cursor, &ocsp->request.cert_id_tail ) != 0 ) {
+	asn1_skip ( &cert_id, ASN1_SEQUENCE );
+	if ( asn1_compare ( &cert_id, &ocsp->request.cert_id_tail ) != 0 ) {
 		DBGC ( ocsp, "OCSP %p \"%s\" certID mismatch:\n",
 		       ocsp, x509_name ( ocsp->cert ) );
 		DBGC_HDA ( ocsp, 0, ocsp->request.cert_id_tail.data,
 			   ocsp->request.cert_id_tail.len );
-		DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
+		DBGC_HDA ( ocsp, 0, cert_id.data, cert_id.len );
 		return -EACCES_CERT_MISMATCH;
 	}