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");
}
}
}