Skip to content

8 bytes Subject Key identifier. #131

Closed
@MmKolodziej

Description

@MmKolodziej

Hey,

I'm having problems using SSL with JRuby when connecting to services which certificates use 8 bytes SKI. As defined in RFC#3280:

Two common
methods for generating key identifiers from the public key are:
(1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
value of the BIT STRING subjectPublicKey (excluding the tag,
length, and number of unused bits).
(2) The keyIdentifier is composed of a four bit type field with
the value 0100 followed by the least significant 60 bits of the
SHA-1 hash of the value of the BIT STRING subjectPublicKey
(excluding the tag, length, and number of unused bit string bits).

I've looked through multiple (100+ probably) publicly available certificates to find any using 8 bytes SKI, but each certificate I found used the first version from RFC, 20 bytes. The certificates I'm having problems with are self-signed and used behind a VPN, so I cannot prepare a good example.
Using JRuby 1.7.26 and jruby-openssl 0.9.20, the problem seems to be within X509Utils.java. The only debugging I have been able to do was rebuilding the gem with added System.out.printlns and comparing the OctetStrings.

The problem, in my opinion, lies within this if:

if ( der.getOctets().length > 20 ) {
  der = (DEROctetString) get(der.getOctets());
}

For certificates using 20-bytes SKI, the length here is 22 (tag, length and 20 bytes of actual key).
For certificates using 8-bytes SKI, the length here is 10, therefore the assignment of Octets only does not happen. This results in this comparison:
Arrays.equals( sakid.getKeyIdentifier(), iskid.getKeyIdentifier() )
failing because sakid.getKeyIdentifier() is calculated correctly, without tag and length ([67, 108, 30, 22, -44, 61, 5, 14] in my case), but iskid.getKeyIdentifier() contains tag and length ([4, 8, 67, 108, 30, 22, -44, 61, 5, 14]), so the check results in V_ERR_AKID_SKID_MISMATCH.

Removing the if mentioned (leaving the assignment untouched), results in SSL connection working for both type of certificates and all tests in jruby-openssl passing. I'm not sure why the if was introduced, since the tag and length should be stripped in all cases in my opinion.
If my assumptions are correct, the fix seems pretty easy, but I wouldn't know where to start in order to write a proper test for it.

Note: I can connect properly using any other HTTP client I could have thought of (MRI included).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions