[ipxe-devel] OCSP issues

Brian Rak brak at gameservers.com
Thu Nov 20 19:40:12 UTC 2014


I found a nice ASN.1 parser (http://lapo.it/asn1js) that helped me 
figure this out:

\x04, \x014 indicates ASN1_OCTET STRING, 20 bytes

It seems that iPXE isn't reading the tag and type before trying to store 
the responder hash.  I was able to correct this with the following patch:

diff --git a/src/crypto/ocsp.c b/src/crypto/ocsp.c
old mode 100644
new mode 100755
index d4815a1..2bb176a
--- a/src/crypto/ocsp.c
+++ b/src/crypto/ocsp.c
@@ -412,7 +412,10 @@ static int ocsp_compare_responder_key_hash ( struct 
ocsp_check *ocsp,
         /* Sanity check */
         difference = ( sizeof ( digest ) - responder->id.len );
         if ( difference )
+       {
+               DBGC2 ( ocsp, "OCSP %p digest id length (%i) and 
responder id length (%i) do not match\n", ocsp, sizeof(digest), 
responder->id.len );
                 return difference;
+       }

         /* Generate SHA1 hash of certificate's public key */
         digest_init ( &sha1_algorithm, ctx );
@@ -438,10 +441,13 @@ static int ocsp_parse_responder_id ( struct 
ocsp_check *ocsp,
         struct asn1_cursor *responder_id = &responder->id;
         unsigned int type;

+       struct asn1_cursor cursor;
+
         /* Enter responder ID */
-       memcpy ( responder_id, raw, sizeof ( *responder_id ) );
-       type = asn1_type ( responder_id );
-       asn1_enter_any ( responder_id );
+       memcpy ( &cursor, raw, sizeof ( cursor ) );
+       type = asn1_type ( &cursor );
+       asn1_enter_any ( &cursor );
+       memcpy ( responder_id, &cursor, sizeof ( *responder_id ) );

         /* Identify responder ID type */
         switch ( type ) {
@@ -451,6 +457,9 @@ static int ocsp_parse_responder_id ( struct 
ocsp_check *ocsp,
                 responder->compare = ocsp_compare_responder_name;
                 return 0;
         case ASN1_EXPLICIT_TAG ( 2 ) :
+               asn1_enter_any ( &cursor );
+               memcpy ( responder_id, &cursor, sizeof ( *responder_id ) );
+
                 DBGC2 ( ocsp, "OCSP %p \"%s\" responder identified by key "
                         "hash\n", ocsp, x509_name ( ocsp->cert ) );
                 responder->compare = ocsp_compare_responder_key_hash;

Though, I'm not really sure why this patch is needed for responder keys, 
but not names.


On 11/20/2014 1:13 PM, Brian Rak wrote:
> Recently we switched over to SHA256 signed SSL certificates, and I've 
> been having issues with OCSP ever since.  It seems that OCSP 
> verification never completes for our certificate anymore, though it 
> works fine in browsers (and works according to ssllabs).
>
> I enabled OCSP debugging, and the root of the issue seems to be that 
> the length of the SHA1 hash and the length of the response don't match.
>
> I added this patch:
>
> diff --git a/src/crypto/ocsp.c b/src/crypto/ocsp.c
> old mode 100644
> new mode 100755
> index d4815a1..7fe30eb
> --- a/src/crypto/ocsp.c
> +++ b/src/crypto/ocsp.c
> @@ -411,8 +411,12 @@ static int ocsp_compare_responder_key_hash ( 
> struct ocsp_chec
>
>         /* Sanity check */
>         difference = ( sizeof ( digest ) - responder->id.len );
> +       DBGC2 ( ocsp, "OCSP %p digest id length: %i  responder id 
> length: %i\n", o
>         if ( difference )
> -               return difference;
> +       {
> +               DBGC2 ( ocsp, "OCSP %p digest id length (%i) and 
> responder id leng
> +               //return difference;
> +       }
>
>         /* Generate SHA1 hash of certificate's public key */
>         digest_init ( &sha1_algorithm, ctx );
> @@ -421,6 +425,12 @@ static int ocsp_compare_responder_key_hash ( 
> struct ocsp_chec
>                         cert->subject.public_key.raw_bits.len );
>         digest_final ( &sha1_algorithm, ctx, digest );
>
> +       DBGC2 ( ocsp, "responder key hash is:\n" );
> +       DBGC2_HDA ( ocsp, 0, responder->id.data, responder->id.len );
> +
> +       DBGC2 ( ocsp, "computed key hash is:\n" );
> +       DBGC2_HDA ( ocsp, 0, digest, sizeof(digest) );
> +
>         /* Compare responder ID with SHA1 hash of certificate's public 
> key */
>         return memcmp ( digest, responder->id.data, sizeof ( digest ) );
>  }
>
> Which produces the following output:
>
> <6>ipxe: OCSP 0x29704 digest id length: 20  responder id length: 22
> <6>ipxe: OCSP 0x29704 digest id length (20) and responder id length 
> (22) different!
> <6>ipxe: responder key hash is:
> <6>ipxe: 00000000 : 04 14 fa 58 db 09 53 bc-19 c5 e7 b5 8b f6 10 f8 : 
> ...X..S.........
> <6>ipxe: 00000010 : 1e 84 6d 3a 8f d8                               : 
> ..m:..
> <6>ipxe: computed key hash is:
> <6>ipxe: 00000000 : fa 58 db 09 53 bc 19 c5-e7 b5 8b f6 10 f8 1e 84 : 
> .X..S...........
> <6>ipxe: 00000010 : 6d 3a 8f d8                                     : 
> m:..
>
> It looks like there's an extra \x04\x14 at the beginning of the 
> response.  Other then that, the computed hash appears to match.
>
> Any idea where this is coming from?
>
> If I just add a dumb offset to this check:
>
> -       return memcmp ( digest, responder->id.data, sizeof ( digest ) );
> +       return memcmp ( digest, responder->id.data + 2, sizeof ( 
> digest ) );
>
> Verification works correctly (though, obviously this isn't a fix).
>
> Reproducing this is fairly straightforward, just try 'chain 
> https://api.vultr.com' (that particular url doesn't have a valid iPXE 
> script, but since the issue happens before that even gets executed 
> that should be ok)
>
> I'm on IRC as 'devicenull' if you need any further info.
> _______________________________________________
> ipxe-devel mailing list
> ipxe-devel at lists.ipxe.org
> https://lists.ipxe.org/mailman/listinfo.cgi/ipxe-devel




More information about the ipxe-devel mailing list