Search in sources :

Example 11 with Attributes

use of java.util.jar.Attributes in project XobotOS by xamarin.

the class URLClassLoader method definePackage.

/**
     * Defines a new package using the information extracted from the specified
     * manifest.
     *
     * @param packageName
     *            the name of the new package.
     * @param manifest
     *            the manifest containing additional information for the new
     *            package.
     * @param url
     *            the URL to the code source for the new package.
     * @return the created package.
     * @throws IllegalArgumentException
     *             if a package with the given name already exists.
     */
protected Package definePackage(String packageName, Manifest manifest, URL url) throws IllegalArgumentException {
    Attributes mainAttributes = manifest.getMainAttributes();
    String dirName = packageName.replace('.', '/') + "/";
    Attributes packageAttributes = manifest.getAttributes(dirName);
    boolean noEntry = false;
    if (packageAttributes == null) {
        noEntry = true;
        packageAttributes = mainAttributes;
    }
    String specificationTitle = packageAttributes.getValue(Attributes.Name.SPECIFICATION_TITLE);
    if (specificationTitle == null && !noEntry) {
        specificationTitle = mainAttributes.getValue(Attributes.Name.SPECIFICATION_TITLE);
    }
    String specificationVersion = packageAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
    if (specificationVersion == null && !noEntry) {
        specificationVersion = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
    }
    String specificationVendor = packageAttributes.getValue(Attributes.Name.SPECIFICATION_VENDOR);
    if (specificationVendor == null && !noEntry) {
        specificationVendor = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VENDOR);
    }
    String implementationTitle = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
    if (implementationTitle == null && !noEntry) {
        implementationTitle = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
    }
    String implementationVersion = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
    if (implementationVersion == null && !noEntry) {
        implementationVersion = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
    }
    String implementationVendor = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
    if (implementationVendor == null && !noEntry) {
        implementationVendor = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
    }
    return definePackage(packageName, specificationTitle, specificationVersion, specificationVendor, implementationTitle, implementationVersion, implementationVendor, isSealed(manifest, dirName) ? url : null);
}
Also used : Attributes(java.util.jar.Attributes)

Example 12 with Attributes

use of java.util.jar.Attributes in project otertool by wuntee.

the class JarSigner method signJar.

void signJar(String jarName, String alias, String[] args) throws Exception {
    boolean aliasUsed = false;
    X509Certificate tsaCert = null;
    if (sigfile == null) {
        sigfile = alias;
        aliasUsed = true;
    }
    if (sigfile.length() > 8) {
        sigfile = sigfile.substring(0, 8).toUpperCase();
    } else {
        sigfile = sigfile.toUpperCase();
    }
    StringBuilder tmpSigFile = new StringBuilder(sigfile.length());
    for (int j = 0; j < sigfile.length(); j++) {
        char c = sigfile.charAt(j);
        if (!((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '-') || (c == '_'))) {
            if (aliasUsed) {
                // convert illegal characters from the alias to be _'s
                c = '_';
            } else {
                throw new RuntimeException(rb.getString("signature filename must consist of the following characters: A-Z, 0-9, _ or -"));
            }
        }
        tmpSigFile.append(c);
    }
    sigfile = tmpSigFile.toString();
    String tmpJarName;
    if (signedjar == null)
        tmpJarName = jarName + ".sig";
    else
        tmpJarName = signedjar;
    File jarFile = new File(jarName);
    File signedJarFile = new File(tmpJarName);
    // Open the jar (zip) file
    try {
        zipFile = new ZipFile(jarName);
    } catch (IOException ioe) {
        error(rb.getString("unable to open jar file: ") + jarName, ioe);
    }
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(signedJarFile);
    } catch (IOException ioe) {
        error(rb.getString("unable to create: ") + tmpJarName, ioe);
    }
    PrintStream ps = new PrintStream(fos);
    ZipOutputStream zos = new ZipOutputStream(ps);
    /* First guess at what they might be - we don't xclude RSA ones. */
    String sfFilename = (META_INF + sigfile + ".SF").toUpperCase();
    String bkFilename = (META_INF + sigfile + ".DSA").toUpperCase();
    Manifest manifest = new Manifest();
    Map<String, Attributes> mfEntries = manifest.getEntries();
    // The Attributes of manifest before updating
    Attributes oldAttr = null;
    boolean mfModified = false;
    boolean mfCreated = false;
    byte[] mfRawBytes = null;
    try {
        MessageDigest[] digests = { MessageDigest.getInstance(digestalg) };
        // Check if manifest exists
        ZipEntry mfFile;
        if ((mfFile = getManifestFile(zipFile)) != null) {
            // Manifest exists. Read its raw bytes.
            mfRawBytes = getBytes(zipFile, mfFile);
            manifest.read(new ByteArrayInputStream(mfRawBytes));
            oldAttr = (Attributes) (manifest.getMainAttributes().clone());
        } else {
            // Create new manifest
            Attributes mattr = manifest.getMainAttributes();
            mattr.putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1.0");
            String javaVendor = System.getProperty("java.vendor");
            String jdkVersion = System.getProperty("java.version");
            mattr.putValue("Created-By", jdkVersion + " (" + javaVendor + ")");
            mfFile = new ZipEntry(JarFile.MANIFEST_NAME);
            mfCreated = true;
        }
        /*
             * For each entry in jar
             * (except for signature-related META-INF entries),
             * do the following:
             *
             * - if entry is not contained in manifest, add it to manifest;
             * - if entry is contained in manifest, calculate its hash and
             *   compare it with the one in the manifest; if they are
             *   different, replace the hash in the manifest with the newly
             *   generated one. (This may invalidate existing signatures!)
             */
        BASE64Encoder encoder = new JarBASE64Encoder();
        Vector<ZipEntry> mfFiles = new Vector<ZipEntry>();
        for (Enumeration<? extends ZipEntry> enum_ = zipFile.entries(); enum_.hasMoreElements(); ) {
            ZipEntry ze = enum_.nextElement();
            if (ze.getName().startsWith(META_INF)) {
                // Store META-INF files in vector, so they can be written
                // out first
                mfFiles.addElement(ze);
                if (signatureRelated(ze.getName())) {
                    // ignore signature-related and manifest files
                    continue;
                }
            }
            if (manifest.getAttributes(ze.getName()) != null) {
                // possibly update its digest attributes
                if (updateDigests(ze, zipFile, digests, encoder, manifest) == true) {
                    mfModified = true;
                }
            } else if (!ze.isDirectory()) {
                // Add entry to manifest
                Attributes attrs = getDigestAttributes(ze, zipFile, digests, encoder);
                mfEntries.put(ze.getName(), attrs);
                mfModified = true;
            }
        }
        // Recalculate the manifest raw bytes if necessary
        if (mfModified) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            manifest.write(baos);
            byte[] newBytes = baos.toByteArray();
            if (mfRawBytes != null && oldAttr.equals(manifest.getMainAttributes())) {
                /*
                     * Note:
                     *
                     * The Attributes object is based on HashMap and can handle
                     * continuation columns. Therefore, even if the contents are 
                     * not changed (in a Map view), the bytes that it write() 
                     * may be different from the original bytes that it read()
                     * from. Since the signature on the main attributes is based 
                     * on raw bytes, we must retain the exact bytes.
                     */
                int newPos = findHeaderEnd(newBytes);
                int oldPos = findHeaderEnd(mfRawBytes);
                if (newPos == oldPos) {
                    System.arraycopy(mfRawBytes, 0, newBytes, 0, oldPos);
                } else {
                    // cat oldHead newTail > newBytes
                    byte[] lastBytes = new byte[oldPos + newBytes.length - newPos];
                    System.arraycopy(mfRawBytes, 0, lastBytes, 0, oldPos);
                    System.arraycopy(newBytes, newPos, lastBytes, oldPos, newBytes.length - newPos);
                    newBytes = lastBytes;
                }
            }
            mfRawBytes = newBytes;
        }
        // Write out the manifest
        if (mfModified) {
            // manifest file has new length
            mfFile = new ZipEntry(JarFile.MANIFEST_NAME);
        }
        zos.putNextEntry(mfFile);
        zos.write(mfRawBytes);
        // Calculate SignatureFile (".SF") and SignatureBlockFile
        ManifestDigester manDig = new ManifestDigester(mfRawBytes);
        SignatureFile sf = new SignatureFile(digests, manifest, manDig, sigfile, signManifest);
        if (tsaAlias != null) {
            tsaCert = getTsaCert(tsaAlias);
        }
        SignatureFile.Block block = null;
        try {
            block = sf.generateBlock(privateKey, sigalg, certChain, externalSF, tsaUrl, tsaCert, signingMechanism, args, zipFile);
        } catch (SocketTimeoutException e) {
            // Provide a helpful message when TSA is beyond a firewall
            error(rb.getString("unable to sign jar: ") + rb.getString("no response from the Timestamping Authority. ") + rb.getString("When connecting from behind a firewall then an HTTP proxy may need to be specified. ") + rb.getString("Supply the following options to jarsigner: ") + "\n  -J-Dhttp.proxyHost=<hostname> " + "\n  -J-Dhttp.proxyPort=<portnumber> ", e);
        }
        sfFilename = sf.getMetaName();
        bkFilename = block.getMetaName();
        ZipEntry sfFile = new ZipEntry(sfFilename);
        ZipEntry bkFile = new ZipEntry(bkFilename);
        long time = System.currentTimeMillis();
        sfFile.setTime(time);
        bkFile.setTime(time);
        // signature file
        zos.putNextEntry(sfFile);
        sf.write(zos);
        // signature block file
        zos.putNextEntry(bkFile);
        block.write(zos);
        // vector
        for (int i = 0; i < mfFiles.size(); i++) {
            ZipEntry ze = mfFiles.elementAt(i);
            if (!ze.getName().equalsIgnoreCase(JarFile.MANIFEST_NAME) && !ze.getName().equalsIgnoreCase(sfFilename) && !ze.getName().equalsIgnoreCase(bkFilename)) {
                writeEntry(zipFile, zos, ze);
            }
        }
        // Write out all other files
        for (Enumeration<? extends ZipEntry> enum_ = zipFile.entries(); enum_.hasMoreElements(); ) {
            ZipEntry ze = enum_.nextElement();
            if (!ze.getName().startsWith(META_INF)) {
                writeEntry(zipFile, zos, ze);
            }
        }
    } catch (IOException ioe) {
        error(rb.getString("unable to sign jar: ") + ioe, ioe);
    } finally {
        // close the resouces
        if (zipFile != null) {
            zipFile.close();
            zipFile = null;
        }
        if (zos != null) {
            zos.close();
        }
    }
    // try {
    if (signedjar == null) {
        // one, then delete the original.
        if (!signedJarFile.renameTo(jarFile)) {
            File origJar = new File(jarName + ".orig");
            if (jarFile.renameTo(origJar)) {
                if (signedJarFile.renameTo(jarFile)) {
                    origJar.delete();
                } else {
                    MessageFormat form = new MessageFormat(rb.getString("attempt to rename signedJarFile to jarFile failed"));
                    Object[] source = { signedJarFile, jarFile };
                    error(form.format(source));
                }
            } else {
                MessageFormat form = new MessageFormat(rb.getString("attempt to rename jarFile to origJar failed"));
                Object[] source = { jarFile, origJar };
                error(form.format(source));
            }
        }
    }
    if (hasExpiredCert || hasExpiringCert || notYetValidCert || badKeyUsage || badExtendedKeyUsage || badNetscapeCertType) {
        logger.warn(rb.getString("Warning: "));
        if (badKeyUsage) {
            logger.warn(rb.getString("The signer certificate's KeyUsage extension doesn't allow code signing."));
        }
        if (badExtendedKeyUsage) {
            logger.warn(rb.getString("The signer certificate's ExtendedKeyUsage extension doesn't allow code signing."));
        }
        if (badNetscapeCertType) {
            logger.warn(rb.getString("The signer certificate's NetscapeCertType extension doesn't allow code signing."));
        }
        if (hasExpiredCert) {
            logger.warn(rb.getString("The signer certificate has expired."));
        } else if (hasExpiringCert) {
            logger.warn(rb.getString("The signer certificate will expire within six months."));
        } else if (notYetValidCert) {
            logger.warn(rb.getString("The signer certificate is not yet valid."));
        }
    }
// no IOException thrown in the above try clause, so disable
// the catch clause.
// } catch(IOException ioe) {
//     error(rb.getString("unable to sign jar: ")+ioe, ioe);
// }
}
Also used : ZipEntry(java.util.zip.ZipEntry) Attributes(java.util.jar.Attributes) MessageDigest(java.security.MessageDigest) Vector(java.util.Vector) PrintStream(java.io.PrintStream) MessageFormat(java.text.MessageFormat) BASE64Encoder(sun.misc.BASE64Encoder) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Manifest(java.util.jar.Manifest) X509Certificate(java.security.cert.X509Certificate) SocketTimeoutException(java.net.SocketTimeoutException) ZipFile(java.util.zip.ZipFile) ByteArrayInputStream(java.io.ByteArrayInputStream) ZipOutputStream(java.util.zip.ZipOutputStream) ManifestDigester(sun.security.util.ManifestDigester) FileOutputStream(java.io.FileOutputStream) JarFile(java.util.jar.JarFile) ZipFile(java.util.zip.ZipFile) File(java.io.File)

Example 13 with Attributes

use of java.util.jar.Attributes in project otertool by wuntee.

the class JarSigner method updateDigests.

/*
     * Updates the digest attributes of a manifest entry, by adding or
     * replacing digest values.
     * A digest value is added if the manifest entry does not contain a digest
     * for that particular algorithm.
     * A digest value is replaced if it is obsolete.
     *
     * Returns true if the manifest entry has been changed, and false
     * otherwise.
     */
private boolean updateDigests(ZipEntry ze, ZipFile zf, MessageDigest[] digests, BASE64Encoder encoder, Manifest mf) throws IOException {
    boolean update = false;
    Attributes attrs = mf.getAttributes(ze.getName());
    String[] base64Digests = getDigests(ze, zf, digests, encoder);
    for (int i = 0; i < digests.length; i++) {
        String name = digests[i].getAlgorithm() + "-Digest";
        String mfDigest = attrs.getValue(name);
        if (mfDigest == null && digests[i].getAlgorithm().equalsIgnoreCase("SHA")) {
            // treat "SHA" and "SHA1" the same
            mfDigest = attrs.getValue("SHA-Digest");
        }
        if (mfDigest == null) {
            // compute digest and add it to list of attributes
            attrs.putValue(name, base64Digests[i]);
            update = true;
        } else {
            // if they are different
            if (!mfDigest.equalsIgnoreCase(base64Digests[i])) {
                attrs.putValue(name, base64Digests[i]);
                update = true;
            }
        }
    }
    return update;
}
Also used : Attributes(java.util.jar.Attributes)

Example 14 with Attributes

use of java.util.jar.Attributes in project android_frameworks_base by ResurrectionRemix.

the class StrictJarVerifier method initEntry.

/**
     * Invoked for each new JAR entry read operation from the input
     * stream. This method constructs and returns a new {@link VerifierEntry}
     * which contains the certificates used to sign the entry and its hash value
     * as specified in the JAR MANIFEST format.
     *
     * @param name
     *            the name of an entry in a JAR file which is <b>not</b> in the
     *            {@code META-INF} directory.
     * @return a new instance of {@link VerifierEntry} which can be used by
     *         callers as an {@link OutputStream}.
     */
VerifierEntry initEntry(String name) {
    // been found, do not verify.
    if (manifest == null || signatures.isEmpty()) {
        return null;
    }
    Attributes attributes = manifest.getAttributes(name);
    // entry has no digest
    if (attributes == null) {
        return null;
    }
    ArrayList<Certificate[]> certChains = new ArrayList<Certificate[]>();
    Iterator<Map.Entry<String, HashMap<String, Attributes>>> it = signatures.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry<String, HashMap<String, Attributes>> entry = it.next();
        HashMap<String, Attributes> hm = entry.getValue();
        if (hm.get(name) != null) {
            // Found an entry for entry name in .SF file
            String signatureFile = entry.getKey();
            Certificate[] certChain = certificates.get(signatureFile);
            if (certChain != null) {
                certChains.add(certChain);
            }
        }
    }
    // entry is not signed
    if (certChains.isEmpty()) {
        return null;
    }
    Certificate[][] certChainsArray = certChains.toArray(new Certificate[certChains.size()][]);
    for (int i = 0; i < DIGEST_ALGORITHMS.length; i++) {
        final String algorithm = DIGEST_ALGORITHMS[i];
        final String hash = attributes.getValue(algorithm + "-Digest");
        if (hash == null) {
            continue;
        }
        byte[] hashBytes = hash.getBytes(StandardCharsets.ISO_8859_1);
        try {
            return new VerifierEntry(name, MessageDigest.getInstance(algorithm), hashBytes, certChainsArray, verifiedEntries);
        } catch (NoSuchAlgorithmException ignored) {
        }
    }
    return null;
}
Also used : HashMap(java.util.HashMap) Attributes(java.util.jar.Attributes) ArrayList(java.util.ArrayList) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) HashMap(java.util.HashMap) Map(java.util.Map) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Example 15 with Attributes

use of java.util.jar.Attributes in project android_frameworks_base by ResurrectionRemix.

the class StrictJarVerifier method verifyCertificate.

/**
     * @param certFile
     */
private void verifyCertificate(String certFile) {
    // Found Digital Sig, .SF should already have been read
    String signatureFile = certFile.substring(0, certFile.lastIndexOf('.')) + ".SF";
    byte[] sfBytes = metaEntries.get(signatureFile);
    if (sfBytes == null) {
        return;
    }
    byte[] manifestBytes = metaEntries.get(JarFile.MANIFEST_NAME);
    // Manifest entry is required for any verifications.
    if (manifestBytes == null) {
        return;
    }
    byte[] sBlockBytes = metaEntries.get(certFile);
    try {
        Certificate[] signerCertChain = verifyBytes(sBlockBytes, sfBytes);
        if (signerCertChain != null) {
            certificates.put(signatureFile, signerCertChain);
        }
    } catch (GeneralSecurityException e) {
        throw failedVerification(jarName, signatureFile, e);
    }
    // Verify manifest hash in .sf file
    Attributes attributes = new Attributes();
    HashMap<String, Attributes> entries = new HashMap<String, Attributes>();
    try {
        StrictJarManifestReader im = new StrictJarManifestReader(sfBytes, attributes);
        im.readEntries(entries, null);
    } catch (IOException e) {
        return;
    }
    // If requested, check whether APK Signature Scheme v2 signature was stripped.
    if (signatureSchemeRollbackProtectionsEnforced) {
        String apkSignatureSchemeIdList = attributes.getValue(ApkSignatureSchemeV2Verifier.SF_ATTRIBUTE_ANDROID_APK_SIGNED_NAME);
        if (apkSignatureSchemeIdList != null) {
            // This field contains a comma-separated list of APK signature scheme IDs which
            // were used to sign this APK. If an ID is known to us, it means signatures of that
            // scheme were stripped from the APK because otherwise we wouldn't have fallen back
            // to verifying the APK using the JAR signature scheme.
            boolean v2SignatureGenerated = false;
            StringTokenizer tokenizer = new StringTokenizer(apkSignatureSchemeIdList, ",");
            while (tokenizer.hasMoreTokens()) {
                String idText = tokenizer.nextToken().trim();
                if (idText.isEmpty()) {
                    continue;
                }
                int id;
                try {
                    id = Integer.parseInt(idText);
                } catch (Exception ignored) {
                    continue;
                }
                if (id == ApkSignatureSchemeV2Verifier.SF_ATTRIBUTE_ANDROID_APK_SIGNED_ID) {
                    // This APK was supposed to be signed with APK Signature Scheme v2 but no
                    // such signature was found.
                    v2SignatureGenerated = true;
                    break;
                }
            }
            if (v2SignatureGenerated) {
                throw new SecurityException(signatureFile + " indicates " + jarName + " is signed using APK Signature Scheme v2, but no such signature was" + " found. Signature stripped?");
            }
        }
    }
    // Do we actually have any signatures to look at?
    if (attributes.get(Attributes.Name.SIGNATURE_VERSION) == null) {
        return;
    }
    boolean createdBySigntool = false;
    String createdBy = attributes.getValue("Created-By");
    if (createdBy != null) {
        createdBySigntool = createdBy.indexOf("signtool") != -1;
    }
    // such verification.
    if (mainAttributesEnd > 0 && !createdBySigntool) {
        String digestAttribute = "-Digest-Manifest-Main-Attributes";
        if (!verify(attributes, digestAttribute, manifestBytes, 0, mainAttributesEnd, false, true)) {
            throw failedVerification(jarName, signatureFile);
        }
    }
    // Use .SF to verify the whole manifest.
    String digestAttribute = createdBySigntool ? "-Digest" : "-Digest-Manifest";
    if (!verify(attributes, digestAttribute, manifestBytes, 0, manifestBytes.length, false, false)) {
        Iterator<Map.Entry<String, Attributes>> it = entries.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, Attributes> entry = it.next();
            StrictJarManifest.Chunk chunk = manifest.getChunk(entry.getKey());
            if (chunk == null) {
                return;
            }
            if (!verify(entry.getValue(), "-Digest", manifestBytes, chunk.start, chunk.end, createdBySigntool, false)) {
                throw invalidDigest(signatureFile, entry.getKey(), jarName);
            }
        }
    }
    metaEntries.put(signatureFile, null);
    signatures.put(signatureFile, entries);
}
Also used : HashMap(java.util.HashMap) GeneralSecurityException(java.security.GeneralSecurityException) Attributes(java.util.jar.Attributes) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) StringTokenizer(java.util.StringTokenizer) HashMap(java.util.HashMap) Map(java.util.Map) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Aggregations

Attributes (java.util.jar.Attributes)631 Manifest (java.util.jar.Manifest)358 IOException (java.io.IOException)152 File (java.io.File)143 JarFile (java.util.jar.JarFile)106 URL (java.net.URL)92 Map (java.util.Map)78 InputStream (java.io.InputStream)62 HashMap (java.util.HashMap)62 Jar (aQute.bnd.osgi.Jar)49 Builder (aQute.bnd.osgi.Builder)43 ArrayList (java.util.ArrayList)43 ByteArrayOutputStream (java.io.ByteArrayOutputStream)42 Test (org.junit.Test)41 ZipEntry (java.util.zip.ZipEntry)39 FileOutputStream (java.io.FileOutputStream)37 JarOutputStream (java.util.jar.JarOutputStream)36 ByteArrayInputStream (java.io.ByteArrayInputStream)33 FileInputStream (java.io.FileInputStream)33 JarEntry (java.util.jar.JarEntry)32