JAR File Specification |
In many cases, JAR files are not just simple archives of javaclasses files and/or resources. They are used as building blocksfor applications and extensions. The META-INF directory, if itexists, is used to store package and extension configuration data,including security, versioning, extension and services.
Groups of name-value pairs are known as a "section". Sectionsare separated from other sections by empty lines.
Binary data of any form is represented as base64. Continuationsare required for binary data which causes line length to exceed 72bytes. Examples of binary data are digests and signatures.
Implementations shall support header values of up to 65535bytes.
All the specifications in this document use the same grammar inwhich terminal symbols are shown in fixed width font andnon-terminal symbols are shown in italic type face.
; Also: To prevent mangling of files sent via straighte-mail, no
; header will start with the four letters "From".
Non-terminal symbols defined in the above specification will bereferenced in the following specifications.
The main section contains security and configuration informationabout the JAR file itself, as well as the application or extensionthat this JAR file is a part of. It also defines main attributesthat apply to every individual manifest entry. No attributein this section can have its name equal to "Name".This section is terminated by an empty line.
The individual sections define various attributes for packagesor files contained in this JAR file. Not all files in the JAR fileneed to be listed in the manifest as entries, but all files whichare to be signed must be listed. The manifest file itself must notbe listed. Each section must start with an attribute with thename as "Name", and the value must be a relative path tothe file, or an absolute URL referencing data outside thearchive.
If there are multiple individual sections for the same fileentry, the attributes in these sections are merged. If a certainattribute have different values in different sections, the last oneis recognized.
Attributes which are not understood are ignored. Such attributesmay include implementation specific information used byapplications.
In the above specification, attributes that can appear in themain section are referred to as main attributes, whereas attributesthat can appear in individual sections are referred to as per-entryattributes. Certain attributes can appear both in the main sectionand the individual sections, in which case the per-entry attributevalue overrides the main attribute value for the specified entry.The two types of attributes are defined as follows.
Name: foo/bar/
Sealed: false
The per-entry attributes fall into the following groups:
These are the same set of attributes defined above as mainattributes that defines the extension package versioning andsealing information. When used as per-entry attributes, theseattributes overwrites the main attributes but only apply to theindividual file specified by the manifest entry.
java.security API. Every fileentry, including non-signature related files in theMETA-INF directory, will be signed if the JAR file issigned by the jarsigner tool. The signature related files are:META-INF/MANIFEST.MFMETA-INF/*.SFMETA-INF/*.DSAMETA-INF/*.RSAMETA-INF/SIG-*META-INFsubdirectories, they are not considered signature-related.Case-insensitive versions of these filenames are reserved and willalso not be signed.Subsets of a JAR file can be signed by using thejava.security API. A signed JAR file is exactly thesame as the original JAR file, except that its manifest is updatedand two additional files are added to theMETA-INFdirectory: a signature file and a signature block file. Whenjarsigner is not used, the signing program has to construct boththe signature file and the signature block file.
For every file entry signed in the signed JAR file, anindividual manifest entry is created for it as long as it does notalready exist in the manifest. Each manifest entry lists one ormore digest attribute and an optionalMagic attribute.
.SF. The major part of the file is similar to themanifest file. It consists of a main section which includesinformation supplied by the signer but not specific to anyparticular jar file entry. The main section entry,x-Digest-Manifest-Main-Attributes (wherex is a digest algorithm), contains the digest valuefor the main attributes of the manifest.The main section is followed by a list of individual entrieswhose names must also be present in the manifest file. Eachindividual entry must contain at least the digest of itscorresponding entry in the manifest file.
Paths or URLs appearing in the manifest file but not in thesignature file are not used in the calculation.
The manifest main attributes are also verified when verificationinformation is available in the signature file. If anx-Digest-Manifest-Main-Attributes entry exists in thesignature file, it is compared against a digest calculated againstthe main attributes in the manifest file. If this calculationfails, then jar validation fails. This decision can be remembered,for efficiency. If anx-Digest-Manifest-Main-Attributes entry does not existin the signature file, its nonexistence does not affect jarvalidation and the manifest main attributes are not verified.
To validate a file, a digest value in the signature file iscompared against a digest calculated against the correspondingentry in the manifest file. Then, a digest value in the manifestfile is compared against a digest calculated against the actualdata referenced in the "Name:" attribute, whichspecifies either a relative file path or URL.
Example manifest file:
The corresponding signature file would be:Manifest-Version: 1.0Created-By: 1.3 (Sun Microsystems, Inc) Name: common/class1.classMD5-Digest: (base64 representation of MD5 digest) Name: common/class2.classMD5-Digest: (base64 representation of MD5 digest)SHA-Digest: (base64 representation of SHA digest)
Signature-Version: 1.0MD5-Digest-Manifest-Main-Attributes: (base64 representation of MD5 digest) Name: common/class1.classMD5-Digest: (base64 representation of MD5 digest) Name: common/class2.classMD5-Digest: (base64 representation of MD5 digest)
The Magic attribute is optional but it is required that a parserunderstand the value of an entry's Magic key if it is verifyingthat entry's signature.
The value or values of the Magic attribute are a set ofcomma-separated context-specific strings. The spaces before andafter the commas are ignored. Case is ignored. The exact meaning ofthe magic attributes is application specific. These values indicatehow to compute the hash value contained in the manifest entry, andare therefore crucial to the proper verification of the signature.The keywords may be used for dynamic or embedded content, multiplehashes for multilingual documents, etc.
Here are two examples of the potential use of Magic attribute inthe manifest file:
Name: http://www.scripts.com/index#script1
SHA-Digest: (base64representation of SHA hash)
Magic: JavaScript,Dynamic
Name:http://www.tourist.com/guide.html
SHA-Digest: (base64representation of SHA hash)
SHA-Digest-French:(base64 representation of SHA hash)
SHA-Digest-German:(base64 representation of SHA hash)
Magic:Multilingual
In the first example, these Magic values may indicate that theresult of an http query is the script embedded in the document, asopposed to the document itself, and also that the script isgenerated dynamically. These two pieces of information indicate howto compute the hash value against which to compare the manifest'sdigest value, thus comparing a valid signature.
In the second example, the Magic value indicates that thedocument retrieved may have been content-negotiated for a specificlanguage, and that the digest to verify against is dependent onwhich language the document retrieved is written in.
.SFsignature file. These are binary files not intended to beinterpreted by humans.Digital signature files have the same filenames as the .SF filesbut different extensions. The extension varies depending on thetype of digital signature.
Digital signature files for signature algorithms not listed abovemust reside in the.RSA (PKCS7 signature, MD5 + RSA).DSA (PKCS7 signature, DSA)
META-INF directory and have theprefix "SIG-". The corresonding signature file(.SF file) must also have the same prefix.For those formats that do not support external signed data, thefile shall consist of a signed copy of the.SF file.Thus some data may be duplicated and a verifier should compare thetwo files.
Formats that support external data either reference the.SF file, or perform calculations on it with implicitreference.
Each.SF file may have multiple digital signatures,but those signatures should be generated by the same legalentity.
File name extensions may be 1 to 3alphanum characters.Unrecognized extensions are ignored.
Following is a list of additional restrictions and rules that applyto manifest and signature files.Attribute names are case insensitive. Programs which generatemanifest and signature files should use the cases shown in thisspecification however.
Attribute names cannot be repeated within a section.
The order of individual signature entries is not significant,except that the digests that get signed are in that order.
NUL, CR, and LF can't be embedded in header values, and NUL, CR,LF and ":" can't be embedded in header names.
Implementations should support 65535-byte (not character) headervalues, and 65535 headers per file. They might run out of memory,but there should not be hard-coded limits below these values.
The existingjar tool is enhanced to be able to examinea list of jar files and generate directory information as to whichclasses and resources reside in which jar file. This directoryinformation is stored in a simple text file namedINDEX.LIST in theMETA-INF directory of the rootjar file. When the classloader loads the root jar file, itreads theINDEX.LIST file and uses it to construct a hashtable of mappings from file and package names to lists of jar filenames. In order to find a class or a resource, the class loaderqueries the hashtable to find the proper jar file and thendownloads it if necessary.
Once the class loader finds aINDEX.LIST file in aparticular jar file, it always trusts the information listed in it.If a mapping is found for a particular class, but the class loaderfails to find it by following the link, an InvalidJarIndexExceptionis thrown. When this occurs, the application developer should rerunthejar tool on the extension to get the right informationinto the index file.
To prevent adding too much space overhead to the application andto speed up the construction of the in-memory hash table, theINDEX.LIST file is kept as small as possible. For classes withnon-null package names, mappings are recorded at the package level.Normally one package name is mapped to one jar file, but if aparticular package spans more than one jar file, then the mappedvalue of this package will be a list of jar files. For resourcefiles with non-empty directory prefixes, mappings are also recordedat the directory level. Only for classes with null packagename, and resource files which reside in the root directory, willthe mapping be recorded at the individual file level.
The UTF-8 encoding is used to support non ASCII characters infile or package names in the index file.
A service is represented by an abstract class. A provider of agiven service contains one or more concrete classes that extendthis service class with data and code specific to the provider.This provider class will typically not be the entire provideritself but rather a proxy that contains enough information todecide whether the provider is able to satisfy a particular requesttogether with code that can create the actual provider on demand.The details of provider classes tend to be highly service-specific;no single class or interface could possibly unify them, so no suchclass has been defined. The only requirement enforced here is thatprovider classes must have a zero-argument constructor so that theymay be instantiated during lookup.
public abstract CharEncodergetEncoder(String encodingName);
public abstract CharDecoder getDecoder(StringencodingName);
Each method returns an appropriate object or null if it cannottranslate the given encoding. Typical CharCodec providers willsupport more than one encoding.
If sun.io.StandardCodec is a provider of the CharCodec servicethen its jar file would contain the fileMETA-INF/services/java.io.spi.CharCodec. This file wouldcontain the single line:
sun.io.StandardCodec #Standard codecs for the platform
To locate an encoder for a given encoding name, the internal I/Ocode would do something like this:
CharEncoder getEncoder(String encodingName){
Iterator ps =Service.providers(CharCodec.class);
while (ps.hasNext()){
CharCodec cc = (CharCodec)ps.next();
CharEncoder ce = cc.getEncoder(encodingName);
if(ce != null)
return ce;
}
return null;
}
The provider-lookup mechanism always executes in the securitycontext of the caller. Trusted system code should typically invokethe methods in this class from within a privileged securitycontext.
![]() |