Apologies in advance for what will be a long post: this has taken a bit of work.
I've written a J2ME application (using Netbeans and the Sun WTK2.2) and have successfully tested it in the emulator. The application is reasonably small (20K) but its data set is 250K (which I put in a J2ME record store). For testing, I initially simply put the data set in a file and included it in the jar and that worked fine in the emulator, but my phone (a stock Nokia 6101 from T-Mobile USA) has a limit of 166K on applications and so that doesn't really work. I switched to a remote download of the data file and that was where the problem arose, because the phone will not allow me to download anything in an unsigned app. After running around a bit and realizing that (at this time) I'm uninterested in paying for a code-signing certificate, I started looking into self signing.
I checked out the Nokia specs at http://www.forum.nokia.com/info/sw.n..._8_en.pdf.html which lists all the mime types supported by the various phones, and concluded that the only way to get a certificate on the phone would be using the application/vnd.wap.hashed-certificate format. I looked at the Open Mobile Alliance specifications at http://www.openmobilealliance.org/te.../wapindex.html and after reading through a couple of the wireless security specifications, I tried to build my own CA certificate that I could install in the phone to let me sign applications.
Specifically, this is what I did:
1. Create using OpenSSL a new CA certificate (details on this abound on the web: Google is your friend).
2. Convert the PEM-encoded certificate into a DER-encoded certificate (binary) using OpenSSL.
3. Modified my apache installation with this line:
AddType application/vnd.wap.hashed-certificate .whc
The extension was arbitrarily chosen as something obscure.
4. Created using java a certificate file based on the wireless security specs.
5. Tried to download it to the phone using the browser.
Now I'm halfway there: the phone tries to install my binary file and then complains about the Authority certificate being corrupt (which makes perfect sense: I have no real clue what I'm doing in terms of generating the certificate file, so I'd have been extremely impressed if it accepted it). What I'm looking for is insight/knowledge/wisdom from anyone who's had experience with a properly encoded CA certificate to shed some light on exactly what a properly structured wap hashed certificate file looks like. If anyone has access to one such file that they could give me to deconstruct, I'll gladly document and donate the knowledge back. Right now, I'm using the following Java code to generate the wap hashed certificate input.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import com.ideasynthesis.utilities.Base64Utils;
public class createCert
{
public static void main(String[] args) throws IOException
{
ByteArrayOutputStream fos = new ByteArrayOutputStream(2048);
// write pieces
// the version (1)
fos.write(1);
// the certificate display name
String displayName = "My Personal CA";
// character set (106: UTF-8)
fos.write(106 >> 8);
fos.write(106);
// size
byte[] data = displayName.getBytes("UTF-8");
int size = data.length;
fos.write(size);
// data
fos.write(data);
//
// certificate
//
File inputCert = new File(args[0]);
FileInputStream fis = new FileInputStream(inputCert);
// format (x509 certificate)
fos.write(2);
// size
size = (int)inputCert.length();
fos.write(hibyte(size));
fos.write(size);
// certificate data
int ch;
while((ch = fis.read()) != -1) fos.write(ch);
fis.close();
// url
String cainfo_url = "www.nokia.com";
size = cainfo_url.length();
// size
fos.write(size);
// url data
for(ch=0;ch<size;ch++) fos.write(cainfo_url.charAt(ch));
// hash
fos.write(0);
fos.close();
// output it
FileOutputStream os = new FileOutputStream(args[1]);
data = fos.toByteArray();
size = data.length;
//char[] output = Base64Utils.encode(data);
//size=output.length;
for(ch=0;ch<size;ch++){
//os.write(output[ch]);
os.write(data[ch]);
}
os.close();
}
private static int topbyte(int input){ return input >> 24; }
private static int thirdbyte(int input){ return input >> 16; }
private static int hibyte(int input){ return input >> 8; }
}
Important questions:
1. The spec doesn't say whether or not it needs to be Base64 encoded: anyone know if that's a necessary step or not?
2. This takes a DER encoded input file (args[1]). Is the DER encoding the proper certificate encoding?
3. If you're looking at the specs, I'm basing my output on page 19 of the WPKI definition document (WAP-217-WPKI) and on pages 63, 64 and 67 of the WTLS spec (WAP-261-WTLS) of the openmobilaalliance link I placed above. I was a little fuzzy on the structure definitions used in the WTLS spec, so clarification from any informed souls would be appreciated.
Thanks for reading this far,
Black.

Reply With Quote

