📄 appdescriptor.java
字号:
* the certificate */ public X509Certificate getCertAttribute(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 all X509Certificate objects from the app descriptor. * <p> * 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. * * @return Vector of object arrays, each containing key, and a * X509Certificate object */ public Vector getAllCerts() throws CertificateException { 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; } /** * Returns a message digest of a certificate in "human readable" * from 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 a readable digest String based on that data. * * @param chainNum number of the certificate chain * @param certNum number of the certificate in the chain * @param alg A Digest algorithm to use, e.g. "SHA1" or "MD5". * * @return A message digest of a certificate in hex as a String or * null if the certificate is not in the JAD. * * @exception NoSuchAlgorithmException Thrown if the digest * <code>algorithm</code> could not be found. */ public String getCertDigest(int chainNum, int certNum, String alg) throws NoSuchAlgorithmException { 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 METHODS ************* */ /** * <code>getEncodedCertificate</code> - A helper function used * by <code>addCert</code>. * * Retrieves a certificate out of a KeyStore and returns it * as a Base64 encoded String. 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 * @return Base64 encoded certificate as a String * @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); */ private String getEncodedCertificate(String alias) throws KeyStoreException, CertificateException, AppDescriptorException { 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); } /** * <code>getNextCertIndex</code> - A helper function used by * <code>addcert</code>. * * Iterates through the current properties data returns the * index of the first unused key index for either a content-provider * (cp) or https certificate. * * @param key What cert key should be used...CP_ATTR or HTTPS_ATTR * @return The first unused index for a particular certificate type. */ private int getNextCertIndex(String key) { int idx = 1; while (idx > 0) { String value = getProperty(key + idx); if (value == null) { break; } idx++; } return idx; } /** * <code>createFingerprint</code> - A helper function used by * <code>getdigest</code>. * * <code>createFingerprint</code>, given a certificated encoded * as a byte array will compute a "fingerprint", or Message * Digest of the certificate using the selected <code>algorithm</code> * type. * * A fingerprint is meant to be human readable, and is thus * returned as a hex string separated at byte boundaries by * a delimeter ":". * * @param certificateBytes - a certificate encoded as a byte array * @param algorithm - The name of a digest algorithm to use, * e.g. "SHA1" or "MD5" * @return the fingerprint in String form. * @exception NoSuchAlgorithmException Thrown if the digest * <code>algorithm</code> could not be found. */ static String createFingerprint(byte[] certificateBytes, String algorithm) throws NoSuchAlgorithmException { 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(); } /** * A helper function used by <code>sign</code>. * Produces a base64 encoded signature for the given buffer. * * @param alias Alias of the signing key in the keystore. * @param keypass Password to access the signing (private) key. * @param stream stream to read the bytes from * * @return Base64 encoded signature of bits in the buffer * * @exception IOException If there is a problem reading the * input stream. * @exception KeyStoreException * @exception InvalidKeyException * @exception SignatureException * @exception NoSuchAlgorithmException * @exception UnrecoverableKeyException */ private String getEncodedSig(String alias, char[] keypass, InputStream stream) throws KeyStoreException, InvalidKeyException, SignatureException, NoSuchAlgorithmException, UnrecoverableKeyException, IOException { 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); } /** * <code>getVerifyCert</code> - A helper function used by * <code>verify</code>. * * Outputs an app descriptor file to the caller provided * ByteArrayOutputStream <code>baos</code> and returns a * base64 encoded signature for those bits. The signature * is valid only for exactly the returned bits. If * <code>encoding</code> is not specified, a default encoding * type of Ascii with Unicode escapes is used. * * @param alias Alias of the verify key in the keystore. * @return Verified X509Certificate containing the public key * with which this app descriptor file's signature should * be verified. * @exception AppDescriptorException * @exception NoSuchAlgorithmException * @exception KeyStoreException * @exception CertificateException * @exception UnrecoverableKeyException * @exception InvalidKeyException * @exception NoSuchProviderException * @exception SignatureException */ private X509Certificate getVerifyCert(String alias) throws AppDescriptorException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException, InvalidKeyException, NoSuchProviderException, SignatureException { 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; } /** * <code>base64CertToX509Cert</code> - A helper function used by * <code>verify</code> * * @param b64str A certificate encoded as Base64 String * @return An X509Certificate object. * @exception CertificateException Thrown if there is an error * converting the <code>b64str</code> certificate * into X509 format. */ private X509Certificate base64CertToX509Cert(String b64str) throws CertificateException { 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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -