Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
New Developer
mindaxi
Posts: 31
Registered: ‎09-08-2009
My Device: Not Specified

Problem with the CMS API

Hello,

     I have met some problem in using the CMS API, Now I got the Inputstream from the server which contains the encrypt information which can give me an certificate. Here is my plan, first I want to get the CMSSignedDataInputStream, and then with this inputStream, I want then get the CMSEnvelopedDataInputStream. Then get the certificates.

    Here comes the problem, I  succeeded get the CMSSignedDataInputStream with the keyStore. But I do not know how to do with the inputStream to get the CMSEnvelopedDataInputStream. I tried to find the informations from Google.Is there someone know how to do this. Any useful information or links can be helpful. thanks advance, by the way sorry for my poor English. I really need some help:smileyhappy:

New Contributor
AnisimovSPB
Posts: 9
Registered: ‎06-25-2010
My Device: BB 8900

Re: Problem with the CMS API

[ Edited ]

I don't know, is this a right way to parse CMS message, but here is come code for you:

 

        Base64InputStream b64is = new Base64InputStream(new ByteArrayInputStream(bytes));
        try {
            try {
                CMSContext context = CMSInputStream.getCMSContext(b64is);
                CMSInputStream cisPrototype = CMSInputStream.getCMSInputStream(context, DeviceKeyStore.getInstance(), null, true);
                try {
                    if (cisPrototype instanceof CMSSignedDataInputStream) {
                        CMSSignedDataInputStream cis = (CMSSignedDataInputStream) cisPrototype;
                        CMSInputStream internalStream = cis.getCMSInputStream();
                        MIMEInputStream mis = new MIMEInputStream(internalStream);
                        try {
                            String contType = mis.getContentType();
                            System.out.println("content-type:" + contType);
                            String contentDisposition = mis.getHeader("Content-Disposition");
                            System.out.println("content-disposition:" + contentDisposition);
                            String charset = mis.getContentTypeParameter("charset");
                            System.out.println("charset:" + charset);
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            byte[] buffer = new byte[1024];
                            try {
                                int len = 0;
                                do {
                                    len = mis.read(buffer, 0, buffer.length);
                                    baos.write(buffer, 0, len);
                                } while (len == buffer.length);
                            } finally {
                                baos.close();
                            }
                            String string;
                            if (charset == null) {
                                string = new String(baos.toByteArray());
                            } else {
                                string = new String(baos.toByteArray(), charset);
                            }
                            System.out.println("string:" + string);
                        } finally {
                            mis.close();
                        }
                    }
                } finally {
                    cisPrototype.close();
                }
            } finally {
                b64is.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

New Developer
mindaxi
Posts: 31
Registered: ‎09-08-2009
My Device: Not Specified

Re: Problem with the CMS API

  Hello,

    Thank you very much for your reply,  AnisimovSPB. Nice code, but I have always got the problem that when I succeded get the CMSSignedDataInputStream, I want do the next thing that I use the method getCMSInputStream() with the CMSSignedDataInputStream that I got, it gave me always a null.


Dose anyone know that what wrong with this CMSSignedDataInputStream,  by the way I use the keyStore like this RIMKeyStore rks = new RIMKeyStore("xxx"); and after that I add the information by useing the set.


Thanks advance and I hope you all have a nice day.


New Contributor
AnisimovSPB
Posts: 9
Registered: ‎06-25-2010
My Device: BB 8900

Re: Problem with the CMS API

As far as I understand, you should always use current instance of DeviceKeyStore because BlackBerry searches appropriate certificates from the real keystore to check SMIME signature when you call CMSSignedDataInputStream.verify(CMSEntityIdentifier). The DeviceKeyStore contains CA certificates, one of which could be a root for SMIME message sender's certificate. If so, it could validate user's certificate and validate it's owner signature.

 

Debugging the work of S/MIME library in JDE I realized that it always uses DeviceKeyStore instance during SMIME body verification. Every time I open SMIME message I sent it does something like this:

CMSContext context = CMSInputStream.getContext(Base64InputStream);

CMSInputStream cis = CMSInputStream.getCMSInputStream(context, DeviceKeyStore.getInstance(), null, true); // cis is usually an instance of CMSSignedDataInputStream

if (cis.isDataPresent()) {

    ... do something ..

    if (cis.isSignedReceiptRequested()) {

        ... do something ...

    }

    CMSInputStream internalStream = cis.getCMSInputStream();

    MIMETypeInputStream mis = new MIMEInputStream(internalStream);

    ... do something ...

}

 

If you want to see, how SMIME library checks SMIME message signatures and body, you should do the next things:

1) Download AEP SMIME Package

2) Install "net_rim_bb_smime.cod" .cod module into your simulator (just run the simulator and select File -> Load Java Program

3a) Install CA certificate (.cer file), then create a key pair, create public key X509 certificate which is signed by your CA and then install your private key with your public key certificate into your DeviceKeyStore using DeviceKeyStore.getInstance().set(...) method

or (more simple way)

3b) Create a key pair, then create self-signed X509 Certificate (using X509Certificate.create(..) method) and then install private key with your public key certificate into your DeviceKeyStore using DeviceKeyStore.getInstance().set(...) method

4) Select your certificate in S/MIME options

5) Go to blackberry email client, compose new email message choosing "Sign" SMIME option.

6) Send message

7) Make sure that you are in debug mode

8) Order the JDE to stop when a net.rim.device.api.crypto.cms.CMSSignedDataInputStream instance is created (make a breakpoint when instance of this class created)

9) Open the email you signed and sent

10) Observe :smileyhappy:))

 

My revelation was the BB never searches digest algorithm via it's name and OID (in CMSUtilities.getSignatureDigest() method). It is a disappointing imperfection, because it doesn't let me add new digest algorithms using OIDs.add(...) and DigestFactory.register(...) methods.

 

 

 

 

 

New Contributor
AnisimovSPB
Posts: 9
Registered: ‎06-25-2010
My Device: BB 8900

Re: Problem with the CMS API

It is also possible that you have zero-sized byte array of your SMIME message part. If so you need to download the remainder from your server with AttachmentDownloadManager or using "Message.addMessageListener(MessageListener)" and "Transport.more(BodyPart, boolean)" methods.