📄 appdescriptor.java
字号:
/* * @(#)AppDescriptor.java 1.8 02/08/22 @(#) * * Copyright (c) 2001-2002 Sun Microsystems, Inc. All rights reserved. * PROPRIETARY/CONFIDENTIAL * Use is subject to license terms. */package com.sun.midp.jadtool;/* * TODO: * Web proxy - The URL retrieval mechanism in AppDescriptor does not * work through a proxy server at this time. */import java.io.*;import java.util.*;import java.net.URL;import java.net.MalformedURLException;import java.security.KeyStore;import java.security.MessageDigest;import java.security.DigestInputStream;import java.security.NoSuchAlgorithmException;import java.security.KeyStoreException;import java.security.Key;import java.security.PrivateKey;import java.security.Signature;import java.security.SignatureException;import java.security.InvalidKeyException;import java.security.NoSuchProviderException;import java.security.UnrecoverableKeyException;import java.security.cert.Certificate;import java.security.cert.X509Certificate;import java.security.cert.CertificateFactory;import java.security.cert.CertificateException;import java.security.cert.CertificateExpiredException;import java.security.cert.CertificateNotYetValidException;import com.sun.midp.jadtool.AppDescriptorException;import com.sun.midp.midletsuite.*;/** * Java API for signing MIDletSuites. * <p> * AppDescriptor is an extension of the Properties class which provides * additional methods for adding message digest and certificate * properties as well as signing the app descriptor file and verifying * a signed app descriptor file. */public class AppDescriptor extends JadProperties { /** Index of the key in arrays returned by getAllCerts. */ public static int KEY = 0; /** Index of the cert in arrays returned by getAllCerts. */ public static int CERT = 1; /** App Descriptor key for . */ public static final String JAR_SIGNATURE = "MIDlet-Jar-RSA-SHA1"; /** App Descriptor key for . */ public static final String CP_ATTR = "MIDlet-Certificate-"; /** App Descriptor key for . */ public static final String JAR_URL = "MIDlet-Jar-URL"; /** App Descriptor key for . */ public static final String JAR_SIZE = "MIDlet-Jar-Size"; /** App Descriptor key for . */ public static final String SEP_ATTR = ": "; /** SHA1 with RSA constant. */ public static final String SIGN_ALG = "SHA1withRSA"; /** KeyStore to get certificiates and keys from. */ private KeyStore keystore = null; /** * Default constructor */ public AppDescriptor() { super(); } /** * Used to input a stored app descriptor into an AppDescriptor * instance from a stream. The input stream will be converted * to Unicode using <code>encoding</code> if it is specified. * If <code>encoding</code> is not specified, a default * encoding of type "UTF8" escapes will be used. * * Overrides <code>Properties.load</code> * * @param inputJad App descriptor input stream. * @param encoding Encoding of the inputJad stream. * * @exception IOException If an error occurs while loading the * inputJad stream. * @exception UnsupportedEncodingException If the given encoding * type is not supported. * @exception InvalidJadException If the JAD has a format error */ public synchronized void load(InputStream inputJad, String encoding) throws UnsupportedEncodingException, IOException, InvalidJadException { super.load(inputJad, 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 * <code>encoding</code> if it is specified. * If <code>encoding</code> is not specified, a default * encoding of type Ascii with Unicode escapes will be used. * * Overrides <code>Properties.store</code> * * @param outputJad App descriptor output stream. * @param encoding Encoding of the outputJad stream. * * @exception IOException If an error occurs while writing the * inputJad stream. * @exception UnsupportedEncodingException If the given encoding * type is not supported. */ public synchronized void store(OutputStream outputJad, String encoding) throws UnsupportedEncodingException, IOException { if (encoding != null) { JadWriter.write(this, outputJad, encoding); } else { JadWriter.write(this, outputJad); } } /** * 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.) * <p> * This KeyStore is required by the <code>addcert</code>, * <code>sign</code>, <code>signcert</code>, and <code>verify</code> * methods. If any of these methods is called before * <code>loadKeyStore</code> an exception will be thrown. * * @param ksfile The input stream stream to load a KeyStore from. * @param storepass The password to unlock the KeyStore, can be null. * @exception KeyStoreException The default keystore provider type * is not available in any of the provider packages * searched. * @exception IOException Thrown if there is a problem parsing * the input stream or loading its data. * @exception CertificateException Thrown if there is trouble loading * certificates into the KeyStore * @exception NoSuchAlgorithmException Thrown if the algorithm * needed to verify the KeyStore cannot be found. */ public synchronized void loadKeyStore(InputStream ksfile, char[] storepass) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, Exception { try { keystore = KeyStore.getInstance(KeyStore.getDefaultType()); keystore.load(ksfile, storepass); } catch (Exception e) { throw new Exception("loadKeyStore failed"); } } /** * Store a the keystore in the descriptor in a file. * * @param ksfname file to use * @param storepass password of keystore */ public synchronized void storeKeyStore(String ksfname, char[] storepass) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException { FileOutputStream fout = new FileOutputStream(ksfname); keystore.store(fout, storepass); fout.close(); } /** * Adds a Base64 encoded signature of the jar file at the URL * specified by the MIDlet-Jar-URL key in the app descriptor. * <code>load</code> and <code>loadKeyStore</code> must be * call before this method. * <p> * The line in the app descriptor corresponding to this * insertion will look like this: * <p> * MIDlet-Jar-RSA-SHA1:j3zKCv6eud2Ubkw80XjpNb7tk5s... * * If a MIDlet-Jar-RSA-SHA1 property already exists it will * be replaced. * * @param alias Alias of the signing key in the keystore. * @param keypass Password to access the signing (private) key. * * @exception AppDescriptorException JAR URL or content provider * certificate was * not found in the app descriptor. * @exception MalformedURLException The URL corresponding to * the MIDlet-Jar-URL key could not be parsed. * @exception IOException error reading the JAR * @exception NoSuchAlgorithmException If SHA1 or RSA need by * getEncodedSig could not be found in an * installed JCA provider. * @exception KeyStoreException * @exception InvalidKeyException * @exception SignatureException * @exception UnrecoverableKeyException */ public void addJarSignature(String alias, char[] keypass) throws AppDescriptorException, MalformedURLException, IOException, KeyStoreException, InvalidKeyException, SignatureException, NoSuchAlgorithmException, UnrecoverableKeyException { 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); } /** * Adds a Base64 encoded signature of the jar file provided in * an input stream to the app descriptor. * <p> * 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. * * @param alias Alias of the signing key in the keystore. * @param keypass Password to access the signing (private) key. * @param jarStream stream to read the jar file from * * @exception IOException If there is a problem reading the * input stream. * @exception NoSuchAlgorithmException If SHA1 or RSA need by * getEncodedSig could not be found in an * installed JCA provider. * @exception KeyStoreException * @exception InvalidKeyException * @exception SignatureException * @exception UnrecoverableKeyException */ public void addJarSignature(String alias, char[] keypass, InputStream jarStream) throws IOException, NoSuchAlgorithmException, KeyStoreException, InvalidKeyException, SignatureException, NoSuchAlgorithmException, UnrecoverableKeyException { setProperty(JAR_SIGNATURE, getEncodedSig(alias, keypass, jarStream)); } /** * Retrieves a certificate out of a KeyStore and adds it * to the app descriptor as: * <p> * content_provider.certificate-1-1:<Base64 encoded newcert> * <p> * Instance variable <code>keystore</code> must not be null, * and should have been set by <code>loadKeyStore</code> * before this method is called. * * @param alias Alias of the chosen certificate in the keystore * @param chainNum number of the chain to add certificate to * @param certNum number of the certificate in the chain to replace it, * or 0 to add the certificate at the end of the chain * * @exception KeyStoreException If there is an error with the keystore. * @exception CertificateException If there is a problem with the * encoding of the certificate. * @exception AppDescriptorException If the KeyStore has not been * initialized (keystore is null) */ public void addCert(String alias, int chainNum, int certNum) throws CertificateException, KeyStoreException, AppDescriptorException { 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); } /** * Returns an X509Certificate object from the app descriptor property * chosen by <code>certnum</code>, or * null if that certificate does not exist in the descriptor. * <p> * 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. * * @param chainNum number of the certificate chain * @param certNum number of the certificate in the chain * * @return an X509Certificate object or null if the certificate is * not in the JAD * * @exception CertificateException If there is a format problem with * the certificate */ public X509Certificate getCert(int chainNum, int certNum) throws CertificateException { X509Certificate c = null; String base64 = getProperty(CP_ATTR + chainNum + "-" + certNum); if (base64 != null) { c = base64CertToX509Cert(base64); } return c; } /** * Returns an X509Certificate object from the app descriptor property * chosen by <code>certnum</code>, or * null if that certificate does not exist in the descriptor. * <p> * 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. * * @param chainNum number of the certificate chain * @param certNum number of the certificate in the chain * * @return an X509Certificate object or null if the certificate is * not in the JAD * * @exception CertificateException If there is a format problem with
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -