Hello,
I'm currently struggling with creating a X.509 certificate that includes the optional 'Parameters' field for the AlgorithmIdentifier in the TBSCertificate. This field should contain the selected elliptic curve for the algorithm (SHA224WithECDSA). Creating the certificate without the optional parameter field works fines but I could not figure out how to add the Parameters field... so I wrote my own Signer class that just extends the "JcaContentSignerBuilder" and changes the 'AlgorithmIdentifier' which also works fine but then I get an error that says: "no such algorithm: 1.2.840.10045.4.3.1 for provider BC". So here is the code for the instantiation of my Signer class and the creation and checking of the certificate:
Code:
ContentSigner contentSigner = new TESTECCContentSigner("SHA224withECDSA").setProvider("BC").build((ECPrivateKey)ca_key_pair_.getPrivate());
// Generate signed certificate
X509Certificate X509cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(v3CertBuilder.build(contentSigner));
// Verify certificate (just as test)
X509cert.checkValidity(new Date());
X509cert.verify(ca_key_pair_.getPublic());
And here is the code of the Signer class, which alters the "sigAlgID" in a cruel way... which was just for testing the concept before I write the complete class on my own ;)
Code:
public class TESTECCContentSigner extends JcaContentSignerBuilder implements
ContentSigner {
public TESTECCContentSigner(String arg0) {
super(arg0);
//Change field sigAlgID
try {
final Field field = JcaContentSignerBuilder.class.getDeclaredField("sigAlgId");
field.setAccessible(true);
field.set(this, this.getAlgorithmIdentifier());
} catch (SecurityException ex) {
ex.printStackTrace();
} catch (NoSuchFieldException ex) {
ex.printStackTrace();
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
}
// TODO Auto-generated constructor stub
}
@Override
public ContentSigner build(java.security.PrivateKey privateKey) throws OperatorCreationException
{
ContentSigner tmp = super.build(privateKey);
return tmp;
}
@Override
public AlgorithmIdentifier getAlgorithmIdentifier() {
ASN1Sequence algIdentifierWithParam;
try {
algIdentifierWithParam = (ASN1Sequence) ASN1Sequence.fromByteArray(new byte[]{
0x30, 0x11,
0x06, 0x08,
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x01
,0x06, 0x05,
0x2b, 0x81, 0x04, 0x00, 0x1b // 27 = 1b
});
AlgorithmIdentifier myAlgID = new AlgorithmIdentifier(algIdentifierWithParam);
return myAlgID;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
assert(false);
return null;
}
Depending on the content of the algIdentifierWithParam = (ASN1Sequence) ASN1Sequence.fromByteArray(new byte[]{ ... }, I get no error for:
0x30, 0x0a,
0x06, 0x08,
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x01
but when I write this (which I would need):
0x30, 0x11,
0x06, 0x08,
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x01,
0x06, 0x05,
0x2b, 0x81, 0x04, 0x00, 0x1b
I get this "no such algorithm: 1.2.840.10045.4.3.1 for provider BC". I use the "*-jdk16-146.jar" fiesl of bouncy castle.
Thank you for your help,
Hannes