aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2020-06-25 13:04:02 +0100
committerMichael Brown <mcb30@ipxe.org>2020-06-25 13:04:54 +0100
commit3f637d7462e7688638b4084717297db8638bdffb (patch)
treebb75718cc7ebb13c2fd3cbbc8a1071b8d51f0f43
parenta61b27b97f572a83ede765a0e779694865950cf2 (diff)
downloadipxe-3f637d7462e7688638b4084717297db8638bdffb.zip
ipxe-3f637d7462e7688638b4084717297db8638bdffb.tar.gz
ipxe-3f637d7462e7688638b4084717297db8638bdffb.tar.bz2
[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>
-rw-r--r--src/crypto/ocsp.c40
1 files changed, 25 insertions, 15 deletions
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_responder_id ( struct ocsp_check *ocsp,
*/
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;
}