Methods Summary |
---|
public void | beginEntry(java.util.jar.JarEntry je, sun.security.util.ManifestEntryVerifier mev)This method scans to see which entry we're parsing and
keeps various state information depending on what type of
file is being parsed.
if (je == null)
return;
if (debug != null) {
debug.println("beginEntry "+je.getName());
}
String name = je.getName();
/*
* Assumptions:
* 1. The manifest should be the first entry in the META-INF directory.
* 2. The .SF/.DSA files follow the manifest, before any normal entries
* 3. Any of the following will throw a SecurityException:
* a. digest mismatch between a manifest section and
* the SF section.
* b. digest mismatch between the actual jar entry and the manifest
*/
if (parsingMeta) {
String uname = name.toUpperCase(Locale.ENGLISH);
if ((uname.startsWith("META-INF/") ||
uname.startsWith("/META-INF/"))) {
if (je.isDirectory()) {
mev.setEntry(null, je);
return;
}
if (SignatureFileVerifier.isBlockOrSF(uname)) {
/* We parse only DSA or RSA PKCS7 blocks. */
parsingBlockOrSF = true;
baos.reset();
mev.setEntry(null, je);
}
return;
}
}
if (parsingMeta) {
doneWithMeta();
}
if (je.isDirectory()) {
mev.setEntry(null, je);
return;
}
// be liberal in what you accept. If the name starts with ./, remove
// it as we internally canonicalize it with out the ./.
if (name.startsWith("./"))
name = name.substring(2);
// be liberal in what you accept. If the name starts with /, remove
// it as we internally canonicalize it with out the /.
if (name.startsWith("/"))
name = name.substring(1);
// only set the jev object for entries that have a signature
if (sigFileSigners.get(name) != null) {
mev.setEntry(name, je);
return;
}
// don't compute the digest for this entry
mev.setEntry(null, je);
return;
|
void | doneWithMeta()called to let us know we have processed all the
META-INF entries, and if we re-read one of them, don't
re-process it. Also gets rid of any data structures
we needed when parsing META-INF entries.
parsingMeta = false;
anyToVerify = !sigFileSigners.isEmpty();
baos = null;
sigFileData = null;
pendingBlocks = null;
signerCache = null;
manDig = null;
|
public java.security.cert.Certificate[] | getCerts(java.lang.String name)Return an array of java.security.cert.Certificate objects for
the given file in the jar.
return mapSignersToCertArray(getCodeSigners(name));
|
public java.security.CodeSigner[] | getCodeSigners(java.lang.String name)return an array of CodeSigner objects for
the given file in the jar. this array is not cloned.
return (CodeSigner[])verifiedSigners.get(name);
|
private static java.security.cert.Certificate[] | mapSignersToCertArray(java.security.CodeSigner[] signers)
if (signers != null) {
ArrayList certChains = new ArrayList();
for (int i = 0; i < signers.length; i++) {
certChains.addAll(
signers[i].getSignerCertPath().getCertificates());
}
// Convert into a Certificate[]
return (java.security.cert.Certificate[])
certChains.toArray(
new java.security.cert.Certificate[certChains.size()]);
}
return null;
|
boolean | nothingToVerify()returns true if there no files to verify.
should only be called after all the META-INF entries
have been processed.
return (anyToVerify == false);
|
private void | processEntry(sun.security.util.ManifestEntryVerifier mev)called when we reach the end of entry in one of the read() methods.
if (!parsingBlockOrSF) {
JarEntry je = mev.getEntry();
if ((je != null) && (je.signers == null)) {
je.signers = mev.verify(verifiedSigners, sigFileSigners);
je.certs = mapSignersToCertArray(je.signers);
}
} else {
try {
parsingBlockOrSF = false;
if (debug != null) {
debug.println("processEntry: processing block");
}
String uname = mev.getEntry().getName()
.toUpperCase(Locale.ENGLISH);
if (uname.endsWith(".SF")) {
String key = uname.substring(0, uname.length()-3);
byte bytes[] = baos.toByteArray();
// add to sigFileData in case future blocks need it
sigFileData.put(key, bytes);
// check pending blocks, we can now process
// anyone waiting for this .SF file
Iterator it = pendingBlocks.iterator();
while (it.hasNext()) {
SignatureFileVerifier sfv =
(SignatureFileVerifier) it.next();
if (sfv.needSignatureFile(key)) {
if (debug != null) {
debug.println(
"processEntry: processing pending block");
}
sfv.setSignatureFile(bytes);
sfv.process(sigFileSigners);
}
}
return;
}
// now we are parsing a signature block file
String key = uname.substring(0, uname.lastIndexOf("."));
if (signerCache == null)
signerCache = new ArrayList();
if (manDig == null) {
synchronized(manifestRawBytes) {
if (manDig == null) {
manDig = new ManifestDigester(manifestRawBytes);
manifestRawBytes = null;
}
}
}
SignatureFileVerifier sfv =
new SignatureFileVerifier(signerCache,
manDig, uname, baos.toByteArray());
if (sfv.needSignatureFileBytes()) {
// see if we have already parsed an external .SF file
byte[] bytes = (byte[]) sigFileData.get(key);
if (bytes == null) {
// put this block on queue for later processing
// since we don't have the .SF bytes yet
// (uname, block);
if (debug != null) {
debug.println("adding pending block");
}
pendingBlocks.add(sfv);
return;
} else {
sfv.setSignatureFile(bytes);
}
}
sfv.process(sigFileSigners);
} catch (sun.security.pkcs.ParsingException pe) {
if (debug != null) debug.println("processEntry caught: "+pe);
// ignore and treat as unsigned
} catch (IOException ioe) {
if (debug != null) debug.println("processEntry caught: "+ioe);
// ignore and treat as unsigned
} catch (SignatureException se) {
if (debug != null) debug.println("processEntry caught: "+se);
// ignore and treat as unsigned
} catch (NoSuchAlgorithmException nsae) {
if (debug != null) debug.println("processEntry caught: "+nsae);
// ignore and treat as unsigned
} catch (CertificateException ce) {
if (debug != null) debug.println("processEntry caught: "+ce);
// ignore and treat as unsigned
}
}
|
public void | update(int b, sun.security.util.ManifestEntryVerifier mev)update a single byte.
if (b != -1) {
if (parsingBlockOrSF) {
baos.write(b);
} else {
mev.update((byte)b);
}
} else {
processEntry(mev);
}
|
public void | update(int n, byte[] b, int off, int len, sun.security.util.ManifestEntryVerifier mev)update an array of bytes.
if (n != -1) {
if (parsingBlockOrSF) {
baos.write(b, off, n);
} else {
mev.update(b, off, n);
}
} else {
processEntry(mev);
}
|