SecureInstallerpublic class SecureInstaller extends Installer This class is able to verify JAD's signed according to the wireless
extension specification. |
Fields Summary |
---|
private static final String | SIG_PROPMIDlet property for the application signature | private static final String | CERT_PROPMIDlet property for the content provider certificates | private String | lastCaSet to the issuer of last certificate chain checked. | private X509Certificate | cpCertAuthenticated content provider certificate. |
Methods Summary |
---|
private int | checkCertChain(int chainNum)Check to see if a provider certificate chain is issued by a known
CA. Set the lastCA field to name of the CA in any case.
Authenticate the chain and set the cpCert field to the provider's
certificate if the CA is known.
int certNum;
Vector derCerts = new Vector();
String base64Cert;
byte[] derCert;
for (certNum = 1; ; certNum++) {
base64Cert = state.getAppProperty(CERT_PROP +
chainNum + "-" + certNum);
if (base64Cert == null) {
break;
}
try {
derCert = Base64.decode(base64Cert);
derCerts.addElement(X509Certificate.generateCertificate(
derCert, 0, derCert.length));
} catch (Exception e) {
throw new InvalidJadException(
InvalidJadException.CORRUPT_PROVIDER_CERT);
}
}
if (certNum == 1) {
// Chain not found
return -1;
}
try {
lastCa = X509Certificate.verifyChain(derCerts,
X509Certificate.DIGITAL_SIG_KEY_USAGE,
X509Certificate.CODE_SIGN_EXT_KEY_USAGE,
WebPublicKeyStore.getTrustedKeyStore()).getIssuer();
cpCert = (X509Certificate)derCerts.elementAt(0);
// Authenticated
return 1;
} catch (CertificateException ce) {
switch (ce.getReason()) {
case CertificateException.UNRECOGNIZED_ISSUER:
lastCa = ce.getCertificate().getIssuer();
// Issuer not found
return 0;
case CertificateException.EXPIRED:
case CertificateException.NOT_YET_VALID:
throw new InvalidJadException(
InvalidJadException.EXPIRED_PROVIDER_CERT,
ce.getCertificate().getSubject());
case CertificateException.ROOT_CA_EXPIRED:
throw new InvalidJadException(
InvalidJadException.EXPIRED_CA_KEY,
ce.getCertificate().getIssuer());
}
throw new InvalidJadException(
InvalidJadException.INVALID_PROVIDER_CERT,
ce.getCertificate().getSubject());
}
| private void | findProviderCert()Find the first provider certificate that is signed by a known CA.
Set the lastCA field to name of the CA. Set the cpCert field to the
provider certificate.
int chain;
int result;
/*
* To save memory for applications that do not use PKI,
* the public keys of the certificate authorities may not
* have been loaded yet.
*/
WebPublicKeyStore.loadCertificateAuthorities();
for (chain = 1; ; chain++) {
result = checkCertChain(chain); // sets the lastCa and cpCert
if (result == 1) {
// we found the good chain
return;
}
if (result == -1) {
// chain not found, done
break;
}
}
if (chain == 1) {
throw new
InvalidJadException(InvalidJadException.MISSING_PROVIDER_CERT);
}
// None of the certificates were issued by a known CA
throw new
InvalidJadException(InvalidJadException.UNKNOWN_CA, lastCa);
| protected java.lang.String | getSecurityDomainName(java.lang.String storageName, java.lang.String ca)Looks up the domain of a MIDlet suite.
Vector keys;
String domain;
/*
* look up the domain owner, then get the domain from the
* trusted key store and set the security domain
*/
try {
keys = WebPublicKeyStore.getTrustedKeyStore().
findKeys(ca);
domain = ((PublicKeyInfo)keys.elementAt(0)).getDomain();
} catch (Exception e) {
domain = "untrusted";
}
return domain;
| protected void | verifyJar(RandomAccessStream jarStorage, java.lang.String jarFilename)Verifies a Jar. On success set the name of the domain owner in the
install state. Post any error back to the server.
InputStream jarStream;
String jarSig;
jarSig = state.getAppProperty(SIG_PROP);
if (jarSig == null) {
// no signature to verify
return;
}
findProviderCert(); // This will fill in the cpCert and lastCa fields
jarStorage.connect(jarFilename, Connector.READ);
try {
jarStream = jarStorage.openInputStream();
try {
verifyStream(jarStream, jarSig);
state.ca = lastCa;
} finally {
jarStream.close();
}
} finally {
jarStorage.disconnect();
}
| private void | verifyStream(java.io.InputStream stream, java.lang.String base64Signature)Common routine that verifies a stream of bytes.
The cpCert field must be set before calling.
PublicKey cpKey;
byte[] sig;
Signature sigVerifier;
byte[] temp;
int bytesRead;
byte[] hash;
try {
cpKey = cpCert.getPublicKey();
} catch (CertificateException e) {
throw new
InvalidJadException(InvalidJadException.INVALID_PROVIDER_CERT);
}
try {
sig = Base64.decode(base64Signature);
} catch (IOException e) {
throw new
InvalidJadException(InvalidJadException.CORRUPT_SIGNATURE);
}
try {
// verify the jad signature
sigVerifier = Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1,
false);
sigVerifier.init(cpKey, Signature.MODE_VERIFY);
temp = new byte[1024];
for (; ; ) {
bytesRead = stream.read(temp);
if (bytesRead == -1) {
break;
}
sigVerifier.update(temp, 0, bytesRead);
}
if (!sigVerifier.verify(null, 0, 0,
sig, (short)0, (short)sig.length)) {
throw new
InvalidJadException(InvalidJadException.INVALID_SIGNATURE);
}
} catch (CryptoException e) {
throw new
InvalidJadException(InvalidJadException.INVALID_SIGNATURE);
}
|
|