3

I'm very new to android and java both, so hopefully I'm missing something easy here. All I want to do is create a simple PKCS10 certificate signing request. I have some code that will compile and run on my ubuntu box (java-6-openjdk), but throws a null pointer exception in the android emulator:

        KeyPair myKeyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
        X500Principal subject = new X500Principal("CN=Test V3 Certificate");
        PKCS10CertificationRequest csr = new PKCS10CertificationRequest
                        ( "SHA1withRSA",
                           subject,
                           myKeyPair.getPublic(),
                           null,
                           myKeyPair.getPrivate()
                );

        byte[] outBytes = csr.getEncoded();
        return new String(outBytes);

In the debugger I can see I have apparently constructed a PKCS10CertificationRequest, but I can't do anything with it (like getEncoded() or even toString()) without error. When I call getEncoded() it fails on the android emulator; this is the stack trace:

06-22 04:41:06.143: WARN/System.err(337): java.lang.NullPointerException: obj == null
06-22 04:41:06.213: WARN/System.err(337):     at org.bouncycastle.asn1.ASN1Collection.addObject(ASN1Collection.java:95)
06-22 04:41:06.353: WARN/System.err(337):     at org.bouncycastle.asn1.DERSequence.<init>(DERSequence.java:34)
06-22 04:41:06.433: WARN/System.err(337):     at org.bouncycastle.asn1.x509.AlgorithmIdentifier.toASN1Object(AlgorithmIdentifier.java:
124)
06-22 04:41:06.453: WARN/System.err(337):     at org.bouncycastle.asn1.ASN1Encodable.getDERObject(ASN1Encodable.java:
77)
06-22 04:41:06.483: WARN/System.err(337):     at org.bouncycastle.asn1.DEROutputStream.writeObject(DEROutputStream.java:
74)
06-22 04:41:06.523: WARN/System.err(337):     at org.bouncycastle.asn1.DERSequence.encode(DERSequence.java:70)
06-22 04:41:06.544: WARN/System.err(337):     at org.bouncycastle.asn1.DEROutputStream.writeObject(DEROutputStream.java:
74)
06-22 04:41:06.593: WARN/System.err(337):     at org.bouncycastle.jce.PKCS10CertificationRequest.getEncoded(PKCS10CertificationRequest.java:
443)

I've tried this with both the API levels 7 and 8. I know there's a ton of other details I could post about the versions of various components of my system. Like I said, I'm new to this, so right now I'm more looking for a direction to go in than necessarily a final answer.

Thanks very much,

Adam Mackler

Adam Mackler
  • 1,980
  • 1
  • 18
  • 32

2 Answers2

3

You ran into a BouncyCastle bug. I am not sure it's fixed. I ended up using my own PKCS10CertificateRequest. You just need to change this one line in the constructor,

   this.sigAlgId = new AlgorithmIdentifier(sigOID, null);

to

   this.sigAlgId = new AlgorithmIdentifier(sigOID);
ZZ Coder
  • 74,484
  • 29
  • 137
  • 169
  • Thanks for your reply, ZZ. Can you tell me whether that change you suggest--adding the null second argument--worked for you on the android platform and if so which version? – Adam Mackler Jun 24 '10 at 23:12
  • The change is to REMOVING null, not ADDING. This was done on J2SE 5, not on Android. This bug has been there for a while. I doubt Andoid version matters. – ZZ Coder Jun 25 '10 at 00:22
  • Ah, yes you did say that. My bad. And your fix does seem to work! I think what threw me off (besides not reading carefully) is that the most recent bouncycastle sources changed that null to an instance of DERNull (called INSTANCE). And the android sources did the same thing, but gave it a different name (THE_ONE). I didn't even think that just leaving it out would work, but apparently it does. Thank you very much for taking the time to share you knowledge. You've been very helpful. – Adam Mackler Jun 26 '10 at 15:02
1

Old post I know, but just ran into the same problem and solved it thanks to this post. Seems like this 'bug' is still around. Targeting a 2.3 Android.

Solved it by using reflection, so just wanted to share that here. Just injecting the 'correct' contructed AlgorithmIdentifier.

PKCS10CertificationRequest pkcs10 = new PKCS10CertificationRequest("SHA1WithRSA", subjectName, publicKey, null, privateKey, "BC");


//FIX ANDROID BUG BY REFLECTION
// 1.2.840.113549.1.1.5 == SHA1WithRSA (lookup identifier for your use)
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(new DERObjectIdentifier("1.2.840.113549.1.1.5"));

Field field = CertificationRequest.class.getDeclaredField("sigAlgId");
field.setAccessible(true);
field.set(pkcs10, algorithmIdentifier);

//After this you can access the pkcs10 object.
Tue Skeltved
  • 196
  • 3