Signed module-file format

Sean Mullan Sean.Mullan at Sun.COM
Tue Mar 16 06:31:27 PDT 2010


Hi,

Here's an initial proposal to extend the module-file format to support 
digital signatures.

Comments welcome.

Thanks,
Sean

Signed Module File Format
=========================

This proposal discusses a format for a signed module. It is based on the 
current jigsaw module-file format: 
http://cr.openjdk.java.net/~mr/jigsaw/notes/module-file-format/


Layout
------

A new SIGNATURE section is defined to contain the signature. It is 
optional. If specified, it must be the first optional section (i.e. 
directly after the MODULE_INFO section). Grammar:

ModuleFileHeader
SectionHeader(MODULE_INFO) [module-info data]
(SectionHeader(SIGNATURE)[signature data])?
(SectionHeader(CLASSES) [class data])?
(SectionHeader(RESOURCES) (SubSectionFileHeader [file data])+)?
(SectionHeader(NATIVE_LIBS) (SubSectionFileHeader [file data])+)?
(SectionHeader(NATIVE_CMDS) (SubSectionFileHeader [file data])+)?
(SectionHeader(CONFIG) (SubSectionFileHeader+ [file data])+)?

The ModuleFileHeader whole file hash must also exclude the SIGNATURE 
section, if specified:

ModuleFileHeader {
   ...
   u2 hashType;     // One of FileConstants.ModuleFile.HashType
                    //   (applies to all hashes in this file)
   u2 hashLength;   // Length of following hash
   b* hash;         // Hash of entire file (except this hash
                    // and SIGNATURE section, if specified)
}

The SIGNATURE data is defined as follows:

Signature {
   u2 signatureType;     // One of FileConstants.ModuleFile.SignatureType
   u2 signatureLength;   // Length of following signature
   b* signature;         // Signature
}

The signatureType describes the format of the signature (ex: PKCS #7, 
XML Signature, PGP). All JDK 7 implementations MUST support signatures 
of type PKCS7.

Section/Header Hashes
---------------------

It should be possible to verify the hash of each section as they are read.

However, one issue with the current module file format is that it is not 
possible to verify the integrity of the ModuleFileHeader or the 
SectionHeaders without downloading the whole file and checking the whole 
file hash. Two changes will address this:

    1. Add an additional hash that covers just the ModuleFileHeader.
    2. Change the section hashes to cover both the header (excluding the 
hash itself) and the content.

PKCS7 Signature Type
--------------------

The PKCS7 Signature Type is a PKCS #7 signature (the Signed-data content 
type). It is encoded according to the PKCS #7 format defined here: 
http://www.rsa.com/rsalabs/node.asp?id=2129

SignedData ::= SEQUENCE {
   version Version,
   digestAlgorithms DigestAlgorithmIdentifiers,
   contentInfo ContentInfo,
   certificates
      [0] IMPLICIT ExtendedCertificatesAndCertificates
        OPTIONAL,
   crls
     [1] IMPLICIT CertificateRevocationLists OPTIONAL,
   signerInfos SignerInfos }

The digestAlgorithms field contains one element - the digest algorithm 
(as an AlgorithmIdentifier) specified in the module header.

The contentInfo (what is being signed) is of type data. The content 
itself is omitted. This avoids replicating the data in the module file.

The certificates field contains the certificates of the signer's 
certificate chain.

The crls field is currently unused.

All JDK 7 implementations MUST support the SHA256withRSA signature 
algorithm.

What is signed
--------------

The content that is signed is the following:

Data ::= OCTET STRING

where the octet string contains the following bytes:

ToBeSignedContent {
      u2 moduleHeaderHashLength;
      b* moduleHeaderHash;
      u2 moduleInfoHashLength;
      b* moduleInfoHash;
      u2 sectionHashLength;
      b* sectionHash;
      ...
      // other section hashes (must be in same order as module file)
      ...
      u2 moduleFileHashLength;
      b* moduleFileHash;
}

The hashes (and their lengths) are the corresponding values in the 
module file.

Tool Support
------------

jpkg will need to be enhanced to support generation of signed modules. 
New command line options will be needed to specify keystore filenames, 
aliases, passwords, etc.

jmod will need to be enhanced to automatically verify signed modules. (A 
-noverify option can be specified to disable verification).

It would be useful to have a public API for signing and verifying modules.

Open Issues
-----------

     * Multiple signer support: it should be possible to add support for 
this without changing the file format, since the underlying PKCS7 
signature format supports multiple signers.

     * It may be useful to have a mechanism to allow you to re-check the 
integrity of what is stored on the filesystem (the uncompressed data). 
Since the hashes may be over compressed data, the signature cannot be 
used to verify that same data, after it is uncompressed.

     * Should we require support for more than one cryptographic 
signature algorithm? This is probably a good idea and SHA256withECDSA 
would be a logical choice.

     * Support for timestamps: signed JARs already support timestamps, 
and this is useful to verify that a signature was created when the 
certificate was valid and not revoked. We should allow revocation 
information (CRLs or OCSP responses) to be added to the signed module 
when it is timestamped. This allows the verifier to verify that the 
certificate was not revoked when it was signed. These features should 
not require changes to the signed module-file format (since the 
underlying PKCS7 format can carry timestamps and CRLs).

     * Certificate duplication: certificates may be duplicated across 
modules created by the same signer. It should be possible to avoid this 
redundancy. Possible solutions include: 1) using the id-ad-caIssuers 
field of the X.509 AuthorityInformationAccess extension to get the 
intermediate CA certificates in a signer's chain, and 2) providing a 
mechanism to download the signer's certificate.



More information about the jigsaw-dev mailing list