Fields Summary |
---|
public static int | KEYIndex of the key in arrays returned by getAllCerts. |
public static int | CERTIndex of the cert in arrays returned by getAllCerts. |
public static final String | JAR_SIGNATUREApp Descriptor key for . |
public static final String | CP_ATTRApp Descriptor key for . |
public static final String | JAR_URLApp Descriptor key for . |
public static final String | JAR_SIZEApp Descriptor key for . |
public static final String | SEP_ATTRApp Descriptor key for . |
public static final String | SIGN_ALGSHA1 with RSA constant. |
private KeyStore | keystoreKeyStore to get certificiates and keys from. |
Methods Summary |
---|
public void | addCert(java.lang.String alias, int chainNum, int certNum)Retrieves a certificate out of a KeyStore and adds it
to the app descriptor as:
content_provider.certificate-1-1:
Instance variable keystore must not be null,
and should have been set by loadKeyStore
before this method is called.
String certtoadd = getEncodedCertificate(alias);
String chain = CP_ATTR + chainNum + "-";
int i;
if (certNum != 0) {
// replace the certificate
setProperty(chain + certNum, certtoadd);
return;
}
// find the number after the highest number certificate in the chain
for (i = 1; ; i++) {
if (getProperty(chain + i) == null) {
break;
}
}
addProperty(chain + i, certtoadd);
|
public void | addJarSignature(java.lang.String alias, char[] keypass)Adds a Base64 encoded signature of the jar file at the URL
specified by the MIDlet-Jar-URL key in the app descriptor.
load and loadKeyStore must be
call before this method.
The line in the app descriptor corresponding to this
insertion will look like this:
MIDlet-Jar-RSA-SHA1:j3zKCv6eud2Ubkw80XjpNb7tk5s...
If a MIDlet-Jar-RSA-SHA1 property already exists it will
be replaced.
String urlStr = getProperty(JAR_URL);
if (urlStr == null) {
throw new AppDescriptorException(JAR_URL + " not in descriptor");
}
URL url = new URL(urlStr);
InputStream jarStream = url.openStream();
addJarSignature(alias, keypass, jarStream);
|
public void | addJarSignature(java.lang.String alias, char[] keypass, java.io.InputStream jarStream)Adds a Base64 encoded signature of the jar file provided in
an input stream to the app descriptor.
The line in the app descriptor corresponding to this
insertion will look like this:
MIDlet-Jar-RSA-SHA1:j3zKCv6eud2Ubkw80XjpNb7tk5s...
If a MIDlet-Jar-RSA-SHA1 property already exists it will
be replaced.
setProperty(JAR_SIGNATURE, getEncodedSig(alias, keypass, jarStream));
|
private java.security.cert.X509Certificate | base64CertToX509Cert(java.lang.String b64str)base64CertToX509Cert - A helper function used by
verify
X509Certificate c = null;
byte[] certificateData = Base64.decode(b64str);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
ByteArrayInputStream bais =
new ByteArrayInputStream(certificateData);
while (bais.available() > 0) {
c = (X509Certificate)cf.generateCertificate(bais);
}
try {
bais.close();
} catch (IOException ioe) {
}
return c;
|
static java.lang.String | createFingerprint(byte[] certificateBytes, java.lang.String algorithm)createFingerprint - A helper function used by
getdigest .
createFingerprint , given a certificated encoded
as a byte array will compute a "fingerprint", or Message
Digest of the certificate using the selected algorithm
type.
A fingerprint is meant to be human readable, and is thus
returned as a hex string separated at byte boundaries by
a delimeter ":".
MessageDigest md = MessageDigest.getInstance(algorithm);
md.update(certificateBytes);
byte[] digest = md.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < digest.length; i++) {
int b = digest[i] & 0xff;
String hex = Integer.toHexString(b);
if (i != 0) {
sb.append(":");
}
if (hex.length() == 1) {
sb.append("0");
}
sb.append(hex);
}
return sb.toString();
|
public java.util.Vector | getAllCerts()Returns all X509Certificate objects from the app descriptor.
After finding a certificate property in the app descriptor,
decodes it from Base64 into a byte-encoded certificate and then
creates the X509 format certificate from that opaque data.
Vector certs = new Vector();
for (int idx = 0; idx < size(); idx++) {
String key = getKeyAt(idx);
String base64 = getValueAt(idx);
if (key.startsWith(CP_ATTR)) {
X509Certificate c = base64CertToX509Cert(base64);
Object[] temp = new Object[2];
temp[KEY] = key;
temp[CERT] = c;
certs.addElement(temp);
}
}
return certs;
|
public java.security.cert.X509Certificate | getCert(int chainNum, int certNum)Returns an X509Certificate object from the app descriptor property
chosen by certnum , or
null if that certificate does not exist in the descriptor.
After finding the chosen property in the app descriptor,
decodes it from Base64 into a byte-encoded certificate and then
creates the X509 format certificate from that opaque data.
X509Certificate c = null;
String base64 = getProperty(CP_ATTR + chainNum + "-" + certNum);
if (base64 != null) {
c = base64CertToX509Cert(base64);
}
return c;
|
public java.security.cert.X509Certificate | getCertAttribute(int chainNum, int certNum)Returns an X509Certificate object from the app descriptor property
chosen by certnum , or
null if that certificate does not exist in the descriptor.
After finding the chosen property in the app descriptor,
decodes it from Base64 into a byte-encoded certificate and then
creates the X509 format certificate from that opaque data.
X509Certificate c = null;
String base64 = getProperty(CP_ATTR + chainNum + "-" + certNum);
if (base64 != null) {
c = base64CertToX509Cert(base64);
}
return c;
|
public java.lang.String | getCertDigest(int chainNum, int certNum, java.lang.String alg)Returns a message digest of a certificate in "human readable"
from from the app descriptor property
chosen by certnum , or
null if that certificate does not exist in the descriptor.
After finding the chosen property in the app descriptor,
decodes it from Base64 into a byte-encoded certificate and then
creates a readable digest String based on that data.
String digest = null;
String base64 = getProperty(CP_ATTR + chainNum + "-" + certNum);
if (base64 != null) {
byte[] certificateData = Base64.decode(base64);
digest = createFingerprint(certificateData, alg);
}
return digest;
|
private java.lang.String | getEncodedCertificate(java.lang.String alias)getEncodedCertificate - A helper function used
by addCert .
Retrieves a certificate out of a KeyStore and returns it
as a Base64 encoded String. Instance variable keystore
must not be null, and should have been set by loadKeyStore
before this method is called.
Certificate cert;
if (keystore == null) {
throw new AppDescriptorException(
AppDescriptorException.KEYSTORE_NOT_INITIALIZED);
}
// Load a keystore data structure to get keys from
cert = keystore.getCertificate(alias);
if (cert == null) {
throw new CertificateException("Certificate not found");
}
byte[] certbytes = cert.getEncoded();
// return the (x.509?) encoded cert in base64
return Base64.encode(certbytes);
|
private java.lang.String | getEncodedSig(java.lang.String alias, char[] keypass, java.io.InputStream stream)A helper function used by sign .
Produces a base64 encoded signature for the given buffer.
int bytesRead;
byte[] buffer = new byte[10240];
// get a signature object
Signature signature = Signature.getInstance(SIGN_ALG);
// init the signature with a private key for signing
Key pk = keystore.getKey(alias, keypass);
signature.initSign((PrivateKey)pk);
for (; ; ) {
bytesRead = stream.read(buffer);
if (bytesRead == -1) {
break;
}
signature.update(buffer, 0, bytesRead);
}
// return the signature
byte[] raw = signature.sign();
return Base64.encode(raw);
|
private int | getNextCertIndex(java.lang.String key)getNextCertIndex - A helper function used by
addcert .
Iterates through the current properties data returns the
index of the first unused key index for either a content-provider
(cp) or https certificate.
int idx = 1;
while (idx > 0) {
String value = getProperty(key + idx);
if (value == null) {
break;
}
idx++;
}
return idx;
|
private java.security.cert.X509Certificate | getVerifyCert(java.lang.String alias)getVerifyCert - A helper function used by
verify .
Outputs an app descriptor file to the caller provided
ByteArrayOutputStream baos and returns a
base64 encoded signature for those bits. The signature
is valid only for exactly the returned bits. If
encoding is not specified, a default encoding
type of Ascii with Unicode escapes is used.
X509Certificate returncert = null;
X509Certificate current = null;
X509Certificate operatorXcert = null;
Certificate operatorcert = null;
byte[] operatordata;
String operatordn = null;
String currentdn = null;
String rv = null;
// get the operator verification cert from the keystore
operatorcert = keystore.getCertificate(alias);
// convert opaque operator cert into X509 encoding so we
// can use it.
operatordata = operatorcert.getEncoded();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
ByteArrayInputStream bais = new ByteArrayInputStream(operatordata);
while (bais.available() > 0) {
operatorXcert = (X509Certificate)cf.generateCertificate(bais);
}
try {
bais.close();
} catch (IOException ioe) {
}
// Get the operator's distinguished name
operatordn = (operatorXcert.getSubjectDN()).getName();
/*
* Now we search for a CP_ATTR type certificate
* who's issuer DN matches "operatordn."
* It is the certificate that should verify the
* signature on this app descriptor.
*
* Before it can do that, it must be trusted by being
* verified by the "operator" certificate.
* The calls to verify() and checkValidity() do this.
*/
int count = 1;
while ((current = getCert(1, count)) != null) {
currentdn = (current.getIssuerDN()).getName();
if (operatordn.equals(currentdn)) {
// verify cert sig with operator public key
current.verify(operatorcert.getPublicKey());
// check cert validity dates
current.checkValidity();
returncert = current;
break;
}
count++;
}
return returncert;
|
public synchronized void | load(java.io.InputStream inputJad, java.lang.String encoding)Used to input a stored app descriptor into an AppDescriptor
instance from a stream. The input stream will be converted
to Unicode using encoding if it is specified.
If encoding is not specified, a default
encoding of type "UTF8" escapes will be used.
Overrides Properties.load
super.load(inputJad, encoding);
|
public synchronized void | loadKeyStore(java.io.InputStream ksfile, char[] storepass)Provides a KeyStore instance for use by this AppDescriptor
object. (The default KeyStore type from the Java security
properties file is used. This should be type "JKS", and is
the only supported keystore format.)
This KeyStore is required by the addcert ,
sign , signcert , and verify
methods. If any of these methods is called before
loadKeyStore an exception will be thrown.
try {
keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(ksfile, storepass);
} catch (Exception e) {
throw new Exception("loadKeyStore failed");
}
|
public synchronized void | store(java.io.OutputStream outputJad, java.lang.String encoding)Used to store an app descriptor instance into a jad file
through an output stream. The internal Unicode stream
will be converted to an output format using
encoding if it is specified.
If encoding is not specified, a default
encoding of type Ascii with Unicode escapes will be used.
Overrides Properties.store
if (encoding != null) {
JadWriter.write(this, outputJad, encoding);
} else {
JadWriter.write(this, outputJad);
}
|
public synchronized void | storeKeyStore(java.lang.String ksfname, char[] storepass)Store a the keystore in the descriptor in a file.
FileOutputStream fout = new FileOutputStream(ksfname);
keystore.store(fout, storepass);
fout.close();
|