Davanum Srinivas wrote:
Heiner,

I've added a temporary fix to using BouncyCastle's classes if
sun.security.util.DerValue. Am adding the "temporary" qualifier
because Sean has promised a better fix :)

Here's my belated fix. This method simply strips off the first 4 bytes of the extension value: 2 bytes for the extension value OCTET STRING tag and length, and another 2 bytes for the key identifier OCTET STRING tag and length. This implementation does not account for OCTET STRINGs >= 128 bytes, but neither does the former method. Since neither of the recommended PKIX algorithms for generating subject key identifiers exceed this length, this should not be a problem.

I have written a small test to make sure the old and new methods
return the same value. It is also attached.

    public static byte[] getSKIBytesFromCert2(X509Certificate cert)
        throws XMLSecurityException {

        /*
         * Gets the DER-encoded OCTET string for the extension value (extnValue)
         * identified by the passed-in oid String. The oid string is
         * represented by a set of positive whole numbers separated by periods.
         */
        byte[] derEncodedValue = cert.getExtensionValue(XMLX509SKI.SKI_OID);

        if (cert.getVersion() < 3) {
            Object exArgs[] = { new Integer(cert.getVersion()) };

            throw new XMLSecurityException("certificate.noSki.lowVersion",
                                           exArgs);
        }

        /**
         * Strip away first four bytes from the DerValue (tag and length of
         * ExtensionValue OCTET STRING and KeyIdentifier OCTET STRING)
         */
        byte abyte0[] = new byte[derEncodedValue.length - 4];

        System.arraycopy(derEncodedValue, 4, abyte0, 0, abyte0.length);

        log.debug("Base64 of SKI is " + Base64.encode(abyte0));

        return abyte0;
    }

------------------------------------------------------------

import java.io.FileInputStream;
import java.security.cert.*;
import java.util.Arrays;
import org.apache.xml.security.keys.content.x509.XMLX509SKI;
import sun.misc.HexDumpEncoder;

public class TestSKI {

    public static void main(String[] args) throws Exception {

        HexDumpEncoder hd = new HexDumpEncoder();
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate cert = (X509Certificate)
            cf.generateCertificate(new FileInputStream(args[0]));
        byte[] ski = XMLX509SKI.getSKIBytesFromCert(cert);
        System.out.println("ski length:" + ski.length);
        System.out.println("ski hex:" + hd.encodeBuffer(ski));
        byte[] ski2 = XMLX509SKI.getSKIBytesFromCert2(cert);
        System.out.println("ski2 length:" + ski2.length);
        System.out.println("ski2 hex:" + hd.encodeBuffer(ski2));
        if (!Arrays.equals(ski, ski2)) {
            throw new Exception("skis are not equal");
        }
    }
}




Reply via email to