Just An Application

August 15, 2014

And Another One: Part Fourteen — JarVerifier.VerifierEntry.verify

File

    $(ANDROID_SRC)/libcore/luni/src/main/java/java/util/jar/JarVerifier.java

Source

    ...
    
    void verify() {
        byte[] d = digest.digest();
        if (!MessageDigest.isEqual(d, Base64.decode(hash))) {
            throw invalidDigest(JarFile.MANIFEST_NAME, name, jarName);
        }
        verifiedEntries.put(name, certificates);
    }
    
    ...

The documentation comment for this method is as follows

    ...
    
    /**
     * Verifies that the digests stored in the manifest match the decrypted
     * digests from the .SF file. This indicates the validity of the
     * signing, not the integrity of the file, as it's digest must be
     * calculated and verified when its contents are read.
     *
     * @throws SecurityException
     *             if the digest value stored in the manifest does not
     *             agree with the decrypted digest as recovered from the
     *             .SF file.
     */
    
    ...

which is interesting, to put it mildly, because it makes no sense at all.

As we have seen a VerifierEntry instance is created by the JarVerifier method initEntry.

The constructor is passed four values

  • the name of the file in the JAR

  • a MessageDigest instance

  • the Base64 encoded value of the digest of the file in the JAR obtained from the Manifest

  • the cerificates associated with the signature file(s) which contain entries for the attributes of the file in the JAR defined in the Manifest

Calls to the JarFile.JarFileInputStream read methods result in the VerifierEntry being passed what has been read from the file via calls to its write methods.

The write methods simply update the MessageDigest instance with the byte(s) they have been passed.

Once the end of the file has been reached then the verify method is called.

The method computes the digest of the file as contained in the JAR.

It decodes the Base64 digest as obtained from the Manifest.

It then compares the two and if they do not match it throws a SecurityException.

Otherwise it adds the array of certificates it was constructed with to the JarVerifier verifiedEntries Hashtable with the name of the file as the key.

In other words it does precisely the opposite of what the comment says.

It DOES ensure the integrity of the file, it DOES NOT verify

that the digests stored in the manifest match the decrypted digests from the .SF file.

because the VerifierEntry does not have any information from the signature file and even if it did it could not decrypt it because nothing in a signature file is encrypted.

I can only assume that the documentation comment wandered in from somewhere else and attached itself to the method and nobody noticed.

Just to compound the confusion the class documentation comment reads

    ...
    
    /**
     * Stores and a hash and a message digest and verifies that massage digest
     * matches the hash.
     */
        
    ...

Copyright (c) 2014 By Simon Lewis. All Rights Reserved.

Unauthorized use and/or duplication of this material without express and written permission from this blog’s author and owner Simon Lewis is strictly prohibited.

Excerpts and links may be used, provided that full and clear credit is given to Simon Lewis and justanapplication.wordpress.com with appropriate and specific direction to the original content.

Advertisements

1 Comment »

  1. […] we have seen the certificates would have been added by the verify method when it was called on the JarVerifier.VerifierEntry associated with the given member of the […]

    Pingback by And Another One: Part Fifteen — JarEntry.getCertificates And JarVerifier.getCertificates | Just An Application — August 15, 2014 @ 8:09 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: