📄 secureinstaller.java
字号:
/* * @(#)SecureInstaller.java 1.9 02/09/17 @(#) * * Copyright (c) 2000-2002 Sun Microsystems, Inc. All rights reserved. * PROPRIETARY/CONFIDENTIAL * Use is subject to license terms. */package com.sun.midp.midletsuite;import java.io.IOException;import java.io.InputStream;import java.io.ByteArrayOutputStream;import java.io.ByteArrayInputStream;import java.io.DataOutputStream;import java.io.DataInputStream;import java.lang.String;import java.lang.IllegalArgumentException;import java.util.Vector;import javax.microedition.io.Connector;import javax.microedition.io.Connection;import javax.microedition.io.HttpConnection;import javax.microedition.pki.CertificateException;import com.sun.midp.ssl.*;import com.sun.midp.io.*;import com.sun.midp.io.j2me.storage.*;import com.sun.midp.publickeystore.*;import com.sun.midp.security.*;/** * This class is able to verify JAD's signed according to the wireless * extension specification. */public class SecureInstaller extends Installer { /** * MIDlet property for the application signature */ private static final String SIG_PROP = "MIDlet-Jar-RSA-SHA1"; /** * MIDlet property for the content provider certificates */ private static final String CERT_PROP = "MIDlet-Certificate-"; /** Set to the issuer of last certificate chain checked. */ private String lastCa; /** Authenticated content provider certificate. */ private X509Certificate cpCert; /** * Looks up the domain of a MIDlet suite. * * @param storageName storage name of a MIDlet suite * @param ca CA of an installed suite * * @return security domain of the MIDlet suite */ protected String getSecurityDomainName(String storageName, String ca) { 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; } /** * Verifies a Jar. On success set the name of the domain owner in the * install state. Post any error back to the server. * * @param jarStorage System store for applications * @param jarFilename name of the jar to read. * * @exception IOException if any error prevents the reading * of the JAR * @exception InvalidJadException if the JAR is not valid or the * provider certificate is missing */ protected void verifyJar(RandomAccessStream jarStorage, String jarFilename) throws IOException, InvalidJadException { 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(); } } /** * 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. * * @exception InvalidJadException if the JAR is not valid or the * provider certificate is missing or a general certificate error */ private void findProviderCert() throws InvalidJadException { 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); } /** * 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. * * @param chainNum the number of the chain * * @return 1 if the CA of the chain is known, 0 if not, -1 if the * chain is not found * * @exception InvalidJadException if something other wrong with a * other than an unknown CA */ private int checkCertChain(int chainNum) throws InvalidJadException { 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()); } } /** * Common routine that verifies a stream of bytes. * The cpCert field must be set before calling. * * @param stream stream to verify * @param base64Signature The base64 encoding of the PKCS v1.5 SHA with * RSA signature of this stream. * * @exception NullPointerException if the public keystore has not been * established. * @exception InvalidJadException the JAR signature is not valid * @exception IOException if any error prevents the reading * of the JAR */ private void verifyStream(InputStream stream, String base64Signature) throws InvalidJadException, IOException { 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); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -