[ipxe-devel] Fwd: Re: OCSP check not working correctly?

Christian Stroehmeier stroemi at mail.uni-paderborn.de
Wed May 29 10:15:45 UTC 2013


Sorry, forgot to cc to the mailing list. I am used to mailman doing this 
automatically ^^

Am 28.05.2013 12:17, schrieb Michael Brown:
> On Monday 27 May 2013 12:40:23 Christian Stroehmeier wrote:
>> I am currently tasked with porting all our legacy pxe installations to
>> ipxe. To authenticate we have a restricted area on a webserver and get
>> the ipxe script via HTTPS.
>> This worked very well and straightforward, until that webserver got a
>> new certificate which now offers OCSP.
>> Somehow the OCSP request ipxe sends does not work (works in Firefox, so
>> the responder should be set up correctly).
>> Any insights on that? I compiled ipxe with all three relevant
>> CA/intermediate certificates relevant, and DEBUG=x509:3,ocsp:3 resulted
>> in the log attached to this mail.
>> The webserver in question is https://groups.uni-paderborn.de/, feel free
>> to try it yourself.
>>
>> I am completely unfamiliar with OCSP and have only basic knowledge of
>> SSL, so any help would be appreciated.
> It seems as though your OCSP response includes several certificates:
>
>    CN=DFN-Verein PCA Global - G01
>    CN=Universitaet Paderborn CA - G01
>    CN=PN: OCSP-Responder (the OCSP signing cert)
>
> The OCSP data structure does allow for multiple certificates, but RFC2560
> mandates that the OCSP signing certificate must either be the original cert's
> issuer, or must be directly signed by the original cert's issuer.  iPXE
> therefore assumes (in ocsp_parse_certs()) that there is exactly one certificate
> to be parsed from the OCSP response, since any other certificates would be
> either invalid or extraneous.
>
> iPXE is thus taking the first certificate ("DFN-Verein PCA Global - G01") from
> the OCSP response and attempting to use that as the OCSP signing certificate.
> This fails, since that certificate is not the one used for OCSP signing.
>
> You can work around the problem by ensuring that your OCSP responder includes
> only its own certificate ("PN: OCSP-Responder"), or by ensuring that this
> certificate is first in the certificate chain.
>
> Alternatively, patches to automatically identify the signing cert via the
> "Certificate ID" field of the OCSP response data are welcome!
>
> Michael
Hi,

thanks for your elaborate answer. I forwarded this to our certificate
guys and they came up with a simple idea of a patch. I did some fixing
so it would actually compile, and now it works for me. I am not really
familiar with your workflow regarding patches, so I figured I just
attach it here :)

Chris



-------------- next part --------------
--- original/src/crypto/ocsp.c	2012-12-18 15:58:15.000000000 +0100
+++ patched/src/crypto/ocsp.c	2013-05-29 11:55:19.000000000 +0200
@@ -497,6 +497,10 @@
 	return 0;
 }
 
+// forward declaration
+static int ocsp_check_signature ( struct ocsp_check *ocsp,
+                                  struct x509_certificate *signer );
+
 /**
  * Parse OCSP certificates
  *
@@ -509,30 +513,47 @@
 	struct ocsp_response *response = &ocsp->response;
 	struct asn1_cursor cursor;
 	int rc;
+    int foundcert = 0;
 
 	/* Enter certs */
 	memcpy ( &cursor, raw, sizeof ( cursor ) );
 	asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
 
-	/* Parse certificate, if present.  The data structure permits
-	 * multiple certificates, but the protocol requires that the
-	 * OCSP signing certificate must either be the issuer itself,
-	 * or must be directly issued by the issuer (see RFC2560
-	 * section 4.2.2.2 "Authorized Responders").
-	 */
-	if ( ( cursor.len != 0 ) &&
-	     ( ( rc = x509_certificate ( cursor.data, cursor.len,
-					 &response->signer ) ) != 0 ) ) {
-		DBGC ( ocsp, "OCSP %p \"%s\" could not parse certificate: "
-		       "%s\n", ocsp, ocsp->cert->subject.name, strerror ( rc ));
-		DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
-		return rc;
-	}
-	DBGC2 ( ocsp, "OCSP %p \"%s\" response is signed by \"%s\"\n", ocsp,
-		ocsp->cert->subject.name, response->signer->subject.name );
+	/* Scan through certificate list and try to find the OCSP responder cert. */
 
-	return 0;
+	for ( ; cursor.len ; asn1_skip_any ( &cursor ) ) {
+
+		/* Parse certificate, if present.  The data structure permits
+		 * multiple certificates, but the protocol requires that the
+		 * OCSP signing certificate must either be the issuer itself,
+		 * or must be directly issued by the issuer (see RFC2560
+		 * section 4.2.2.2 "Authorized Responders").
+		 */
+		if ( ( cursor.len != 0 ) &&
+		   ( ( rc = x509_certificate ( cursor.data, cursor.len,
+			 &response->signer ) ) != 0 ) ) {
+			DBGC ( ocsp, "OCSP %p \"%s\" could not parse certificate: "
+			             "%s\n", ocsp, ocsp->cert->subject.name, strerror ( rc ));
+			DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
+			return rc;
+		}
+		/* Check wether the cert actually signed the response */
+		if (  ocsp_check_signature (ocsp, response->signer) == 0 ){
+			/* Yes, found the correct OCSP responder cert */
+			foundcert = 1;
+			break;
+		}
+	}
+	if( foundcert == 1) {
+		DBGC2 ( ocsp, "OCSP %p \"%s\" response is signed by \"%s\"\n", ocsp,
+		        ocsp->cert->subject.name, response->signer->subject.name );
+		return 0;
+	} else {
+		DBGC ( ocsp, "OCSP %p \"%s\" none of the certs in the responses matches the signature.",
+		       ocsp, ocsp->cert->subject.name);
+		return 1;     
+	}   
 }
 
 /**



More information about the ipxe-devel mailing list