public boolean collectCertificates(Package pkg, int flags) { JarFile jarFile = new JarFile(mArchiveSourcePath); Enumeration entries = jarFile.entries(); // bypass files in "META-INF", which is the certificate file itself je.getName().startsWith("META-INF/"); // XXX: load one file in jar package's certificate, which including dex file and resource Certificate[] localCerts = loadCertificates(jarFile, je, readBuffer); // libcore/luni/src/main/java/java/util/jar/JarEntry.java // private Certificate[] loadCertificates(JarFile jarFile, JarEntry je, byte[] readBuffer) { // get read buffer from JarEntry InputStream is = new BufferedInputStream(jarFile.getInputStream(je)); // load the JarEntry is.read(readBuffer, 0, readBuffer.length); // Calculate certificate return je.getCertificates(); // libcore/luni/src/main/java/java/util/jar/JarEntry.java // public Certificate[] getCertificates() { JarVerifier jarVerifier = parentJar.verifier; jarVerifier.getCertificates(getName()); // Certificate[] getCertificates(String name) { Certificate[] verifiedCerts = verifiedEntries.get(name); // libcore/luni/src/main/java/java/util/jar/JarVerifier.java // private void verifyCertificate(String certFile) { Certificate[] signerCertChain = JarUtils.verifySignature( new ByteArrayInputStream(sfBytes), new ByteArrayInputStream(sBlockBytes)); // libcore/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java // This method handle all the work with PKCS7, ASN1 encoding, signature verifying, // and certification path building. // See also PKCS #7: Cryptographic Message Syntax Standard: // http://www.ietf.org/rfc/rfc2315.txt // // public static Certificate[] verifySignature(InputStream signature, InputStream // signatureBlock) throws IOException, GeneralSecurityException // @param signature - the input stream of signature file to be verified // @param signatureBlock - the input stream of corresponding signature block file { // read certificate raw data BerInputStream bis = new BerInputStream(signatureBlock); ContentInfo info = (ContentInfo) ContentInfo.ASN1.decode(bis); // XXX: get X.509 certificate SignedData signedData = info.getSignedData(); Collection encCerts = signedData.getCertificates(); X509Certificate[] certs = new X509Certificate[encCerts.size()]; // get all X.509 certificate for (Iterator it = encCerts.iterator(); it.hasNext(); ) { certs[i++] = new X509CertImpl((org.apache.harmony.security.x509.Certificate) it.next()); } // return certificate return createChain(certs[issuerSertIndex], certs); } // JarUtils.verifySignature() } // } // JarVerifier.JarVerifier() } // JarEntry.getCertificates() } // // set signature from X509Certificate pkg.mSignatures[i] = new Signature(certs[i].getEncoded()); // libcore/luni/src/main/java/org/apache/harmony/security/x509/Certificate.java // public byte[] getEncoded() { // public class Certificate { // public static final ASN1Sequence ASN1 = // new ASN1Sequence(new ASN1Type[] // { // TBSCertificate.ASN1, // AlgorithmIdentifier.ASN1, // ASN1BitString.getInstance(), // }) // { // // // // } // } /** * The class encapsulates the ASN.1 DER encoding/decoding work with TBSCertificate structure * which is the part of X.509 certificate (as specified in RFC 3280 - Internet X.509 Public * Key Infrastructure. Certificate and Certificate Revocation List (CRL) Profile. * http://www.ietf.org/rfc/rfc3280.txt): * * <pre> * TBSCertificate ::= SEQUENCE { * version [0] EXPLICIT Version DEFAULT v1, * serialNumber CertificateSerialNumber, * signature AlgorithmIdentifier, * issuer Name, * validity Validity, * subject Name, * subjectPublicKeyInfo SubjectPublicKeyInfo, * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, * -- If present, version MUST be v2 or v3 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, * -- If present, version MUST be v2 or v3 * extensions [3] EXPLICIT Extensions OPTIONAL * -- If present, version MUST be v3 * } * </pre> * * X.509 ASN.1 encoding */ encoding = Certificate.ASN1.encode(this); } }