Table of Contents ***************** Swbis 1 Prerequisites 2 Introduction 3 Making Distribution Tar Files 3.1 PSF Basics 3.1.1 Name-Version-Release 3.1.2 The Distribution Object 3.1.3 The Vendor Object 3.1.4 The vendor_tag Attribute 3.1.5 Package File Ownerships 3.2 PSFs for Source Packages 4 Verifying the Distribution 4.1 Verifying the Tar Archive File 4.2 Verifying the Unpacked Archive 4.2.1 The `checkdigest' script 4.3 Verifying Using Existing GNU Tools 5 Adding New Signatures 6 Guidelines for GNU Source Packages 7 Using Automake and Swbis 8 Using CVS and Swbis Swbis ***** This manual is for the use of GNU Swbis (version 0.499) in the creation and verification of software releases containing embedded GPG signatures. Copyright (C) 2006 Jim Lowe Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover texts being "A GNU Manual," and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled "GNU Free Documentation License." (a) The FSF's Back-Cover Text is: "You have freedom to copy and modify this GNU Manual, like GNU software. Copies published by the Free Software Foundation raise funds for GNU development." 1 Prerequisites *************** In general, you need Unix-like shell and utilites, including awk. A Posix shell is required, `bash' works fine. You will also need GNU tar version 1.14, 1.15.1 or 1.15.91, and GNU Privacy Guard (`gpg'). The GnuPG passphrase agent, (`gpg-agent') is supported though optional. The features described in the last two chapters dealing with Automake and CVS require GNU swbis version 0.499. 2 Introduction ************** This document explains how to create and verify tar archives using GNU Swbis using particular methods and policy suited for free software distribution tar files. The primary motivation for using Swbis is that it can create packages with an embedded GPG signature. The creation method described uses `swign' which employs `swpackage' and `tar' so that the archive is written entirely by `tar'. The packaging policy is designed so there are no package layout changes except for the addition of the meta-data directory `catalog'. This is accomplished by specifying the POSIX control directory as empty strings "" and using a implementation extension option to set the path name prefix to the package NAME-VERSION. The `catalog' directory conforms to the POSIX packaging standard ISO/IEC 15068-2:1999. The verification methods described include a procedure that does not require any part of Swbis. It uses `tar', `gpg', and a few other GNU utilities plus a Ext2 compatible file system to verify the package data. 3 Making Distribution Tar Files ******************************* Making a distribution tar file first requires making a input file called a "Product Specification File" or PSF for short. It directs `swpackage' on what files to package, the package structure, and what control directory names to use. It also can contain meta-data (i.e. attributes) that are transferred into the package meta-data file named "INDEX". Here are examples that use a internally generated PSF to get started quickly, however, it is recommended that you provide your own PSF according to guidelines below. Note that this will erase and replace a file named `catalog' which is the name of the ISO/IEC 15068-2 meta-data directory. cd somepackage-1.0 swign -u "Your GPG Name" @- | tar tvf - In this example `swign' generated a PSF since one was not supplied. Here is what it used. swign --show-psf distribution dfiles dfiles product title somepackage version 1.0 description Source package for somepackage version 1.0 tag somepackage revision 1.0 control_directory "" fileset tag somepackage-sources control_directory "" file_permissions -o jhl -g jhl directory . file * exclude catalog If you already have a PSF named `PSF', here's how to use it with `swign': cd somepackage-1.0 swign -s PSF -u "Your GPG Name" @- | tar tvf - The same package can be created with `swpackage', however, it requires specifying more options and the archive is written by `swpackage' instead of `tar', Here's how: cd somepackage-1.0 swpackage -s PSF -gpg-name "Your GPG Name" \ --dir=somepackage-0.1 --sign --files @- | tar tvf - 3.1 PSF Basics ============== For information about PSFs in general, see the info manual on the Swbis home page, or, the `sw' manual page. This section applies to all PSFs. Here some basic information. The PSF consists of "object keywords" and "attribute keywords". The most common "object keywords" are `distribution', `bundle', `vendor', `product', and `fileset'. All "attribute keywords" exist in an object context and some "attribute keywords" are used in several "object keywords" contexts. To disambiguate the following notation is used: OBJECT_NAME.ATTRIBUTE. Comments are lines or parts of lines that begin with `#'. Whitespace in a PSF is not significant. Objects are terminated by the next object keyword. Unrecognized "attributes" are allowed but unrecognized "objects" are not allowed. The `tag' attribute in all objects should not contain the following four characters ' ', ':','.', ',' (space, colon, comma, period). 3.1.1 Name-Version-Release -------------------------- Most GNU packages do not have a RELEASE part, but how this is modeled in a PSF is described here anyway. The RELEASE part is analogous to the `RPMTAG_RELEASE' and DEBIAN_REVISION attributes, hence GNU software releases do no have this part because GNU packages are the original 'upstream' releases relative to the packages of GNU/Linux distributions. The NAME becomes the PRODUCT.TAG attribute. The REVISION becomes the PRODUCT.REVISION attribute. The RELEASE becomes the PRODUCT.VENDOR_TAG attribute. 3.1.2 The Distribution Object ----------------------------- In most PSFs this object can be left empty. An empty object consists of just the object keyword followed by a newline. Any control or package meta-data files that apply to the distribution can tbe included in this object. For example: distribution dfiles dfiles AUTHORS /catalog/ /catalog/INDEX ... /catalog//md5sum /catalog//sha1sum /catalog//sig_header /catalog//signature ... For example: swverify -d @- /catalog/dfiles/checkdigest' * The package contains distribution file list `/catalog/dfiles/files' (if the checkdigest script requires it, which it should). 4.2.1 The `checkdigest' script ------------------------------ The `checkdigest' script is an implementation extension verification hook. `swverify' will execute it after verifying the GPG signature and `swverify' exits with its exit status. It is intended to be a shell script that verifies the unpacked archive using existing GNU tools using the techniques described in the next section "Verifying Using Existing GNU Tools". The file `checkdigest.sh' from the swbis distribution will work for any package. To include a `checkdigest' script in the package, add the following line to the `distribution' object in the PSF. checkdigest /catalog/dfiles/signature' file or add a new archive member, using the same tar header, placing it before or after the existing signature member. The signature itself must be formatted in a particular way and have a length in bytes that matches its tar header, this is currently 1024 bytes. Every signature must have the same tar header (i.e. same name) and this tar header is stored in the `/catalog/dfiles/sig_header' file. Hence, to make a new signature member, take the data part of `/catalog/dfiles/sig_header' (512 bytes) and append the 1024 bytes of the properly formatted signature, replace or add these 1536 bytes in the archive (this currently must be done by manually splitting the file into pieces, then concatenating it back together or by using a binary editor). Fortunately, swbis does have a utility to reproduce the signed data. `gpg' and `dd' will be used to make a signature and format it like this: # First, grab the sig_header tar zxpf somepackage-1.0.tar.gz -O \*/catalog/dfiles/sig_header | dd bs=512 count=1 of=/tmp/newsig # Now, make the new signature # Note: 'swverify -WC' writes the signed data to stdout swverify -WC >/tmp/newsig For example, a package with two (2) signatures looks like this: somepackage-1.0/catalog/ somepackage-1.0/catalog/INDEX ... somepackage-1.0/catalog/dfiles/sig_header somepackage-1.0/catalog/dfiles/signature somepackage-1.0/catalog/dfiles/signature ... Since all but the last signature is lost when unpacked, the last signature should be the considered the primary one. 6 Guidelines for GNU Source Packages ************************************ Here are itemized guidelines for GNU packages: * Use GNU tar version 1.15.x, GNU swbis version 0.483 or later versions. * Use the default `swign' format option `--format=ustar'. This corresponds to tar option `--format=ustar'. * Do not include symbolic or hard links in the distribution, make them when configuring if needed. * Try not to make file names longer than 99 bytes because this will make verification of the unpacked directory form a little problematic until some bugs in swbis and tar are fully converged. * Set the file ownerships in the package to numeric root/root. Using the `file_permissions -o 0 -g 0' directive in the PSF is the easiest way to do this. * Do include a `checkdigest' script. The file `./bin/checkdigest.sh' from the swbis distribution should work for any package. Here is an example PSF. # PSF.in -- Example 'swign' Input file for GNU packages. # Occurrences of %__tag and %__revision will be replaced # by values determined from the name of the current directory # that has the form: tag-revision distribution # dfiles dfiles # dfiles is the default AUTHORS <./AUTHORS # optional COPYING <./COPYING # optional checkdigest <./var/checkdigest.sh # or wherever it is on your system tag %__tag-%__revision # Optional, this will set '--dir' option of # of swpackage. vendor the_term_vendor_is_misleading True tag GNU title GNU's Not Unix description "The GNU Project was launched in 1984 to develop a complete UNIX-like operating system which is free software: free as in freedom, not price. See http://www.gnu.org." product title GNU %__tag vendor_tag GNU description Source package for %__tag # More can be added tag %__tag # This is the package name revision %__revision # This is the package version control_directory "" fileset tag source control_directory "" file_permissions -o 0 -g 0 directory . file * # exclude RCS # Not supported yet by swign # exclude CVS # Not supported yet by swign exclude catalog # required Here is how to use the PSF to create a package with an embedded GPG signature. cd somepackage-1.0 swign -s PSF.in -u "Your GPG name" @- | gzip -9 >../somepackage-1.0.tar.gz # Then do a couple quick tests swverify -d @- <../somepackage-1.0.tar.gz # If a checkdigest script was included and the file system is Ext2 # compatible then the following should work, try it swverify -d @. # For some newer file system you must use the --order-catalog option swverify --order-catalog -d @. To make a nearly identical package using `swpackage' # First, the replacement macros must be processed by swign swign -s PSF.in --show-psf | swpackage -s - --gpg-name="Your GPG name" \ --dir-owner=0 --dir-group=0 --files --sign @- | gzip -9 >../somepackage-1.0.tar.gz There are differences between `swign' and `swpackage'. `swign' uses `swpackage' but uses `tar' to write the final archive hence it is more fail safe against bugs. `swign' modifies the `./catalog/' making `.' immediately verifiable with `swverify' and is simpler to use. That's it. You now have a tar archive with one or more embedded signatures, that is created using `tar', is verifiable with existing tools, compatible with current practice, and conforms to the POSIX packaging standard. 7 Using Automake and Swbis ************************** This section describes an Automake target to include in the top level Makefile.am file. To use it, you must get your package working with Automake and able to create a distribution using one of the standard distribution targets such as `dist-gzip' that is already part of Automake. This example target is called `dist-swbis'. The target is designed to be symmetric with the other standard Automake targets such as `dist-gzip'. It uses the `swign' program. The `PSF.in' file must use the `%__tag' and `%__revision' macros described above. The passphrase input options and identity is controlled by environment variables: SWPACKAGEPASSFD, GNUPGNAME, GNUPGHOME. dist-swbis: distdir (cd $(distdir) && swign -s PSF.in --name-version=$(distdir) @-) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(sw_am__remove_distdir) # Provide am__remove_distdir ourselves since am__remove_distdir may be a # private automake variable. sw_am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } Here is an example invocation using the environment variable controls: export SWPACKAGEPASSFD=agent; export GNUPGNAME="Your Name"; make dist-swbis To input your passphrase from the tty, unset SWPACKAGEPASSFD or set it to "tty". The result should be a file named `DISTDIR.tar.gz' that has the same layout as the package produced by `dist-gzip' excpept this package will carry around your GPG signature in the additional ./catalog meta-data directory. The file should then be verified: swverify -d @-