[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug #340306: Specification draft for signed debs

Hi dpkg-sig, dpkg maintainers and FTP-masters,

I would like to help with reviving the idea of "signed deb".  I
noticed dpkg-sig/debsig-verify is on the dpkg maintainer's "RoadMap"
[DRM], hench the CC.  I also found [OSPEC], which may be of interest
or possible the "old spec".
  I think that we should start with creating "signatures support
inside .deb"-spec.  I have come up with an initial draft based on my
observations of dpkg-sig and debsig-verifiy below.  Feel free to
review and suggest ammends to it.

Once we have created the specification, I suggest we use dpkg-sig (and
possibly debsig-verify) to create a prototype implementation of it and
get archive support for it.

State of the art

So far the only tools I am aware of in this area are dpkg-sig and
debsig-verify (currently orphaned).  Both of these add a
"_gpg<role/name>" to the end of the existing deb:

 * debsig-verify uses this file as a gpg signature of:
    $ cat debian-binary control.tar.gz data.tar.gz
   (source [DSV-EX] and [OSPEC]).

 * dpkg-sig uses this this file as a signed dctrl file (e.g.
   similar to a signed .changes file) [DS-EX]

Obviously these two approaches are not compatible.  To me, it seems
the dpkg-sig signature is more flexible and easiest to extend.
  Should new members be added to the deb format later, it can
trivially be signed emitting checksums for it in the signed dctrl
file.  It is also contains a human readable description of what is

Archive support

The FTP masters have requested that all signatures are stored in a
single ar member of the deb.  That "member should then contain a flat
directory (ie no sub-directories) of signature files, [...]"
  They suggested that the member should be named "signatures.tar.gz"
(or so), but as it exceeds the name limits I will use "sigs.tar.gz"
for now.

Draft Specification

deb format changes

deb files can optionally have a member called "sigs.tar.gz" used for
verifying the authenticity and integrity of contents of the deb file.
The member should be the last, but may appear anytime after the
data.tar member.
  Implementations should (still) ignore any member after the data.tar
member except for the "sigs.tar.gz" if it is present.

The "sigs.tar.gz" may be used to sign any member preceeding it in the
deb file.  Implementations are not required to check for signatures
for any member occuring after the "sigs.tar.gz".

Rationale: I believe it makes sense to allow members to appear after
the "sigs.tar.gz".  We currently allow arbitrary members after the
data.tar member and if we require "sigs.tar.gz" to be last, then
implemenations would have to "move it to the back" when inserting a
"new member" - even if it isn't signed.
  This allows any tool that relies on being able to "inject" members
in a deb to continue working without any changes (assuming it is not
using the "sigs.tar.gz" member).
  Any tool "blindly" appending members in the back of a deb is
unlikely to be "aware" of the "sigs.tar.gz" and therefore will
probably not rely on its for signatures.  So I believe it is a safe
assumption that members after the "sigs.tar.gz" will not be signed.

As far as I can tell, these semantics provides backwards compatability
with the current format with the exception of any tool using
"sigs.tar.gz" differently (if any such tools exists).


The sigs.tar.gz member is a gzipped tar archive containing signatures,
as a series of clearsigned GPG plain text files.  The tarball may
optionally contain an entry for ".", the current directory.

The filename of the signature files must consists entirely of lower
letters and digits (i.e. "a-z" and "0-9") followed by ".asc".
Implementations should ignore files with a different file extension.

The contents of signature files are described below.

Rationale: I included the restriction on the file extension to allow
new files in the future (e.g. a "new kind" of signature file).

The choice of ".asc" was somewhat arbitrary, so if anyone has a better
suggestion, let me know.  I originally thought of using ".sig".
However, GPG uses it for "binary signatures" and I was afraid it
might cause some potentional issues.

(The first paragraph is pretty much required per FTP masters,
but is there for the sake of completeness.)

signature files

As mentioned previously, this will be a clearsigned debian control
file (syntax as described in Policy §5.1).  It contains the following

 * Format (required, simple).  The value of this field is "1.0"
   - used for versioning the format (in case we want to extend
 * Date (required, simple).  The date of the signature in RFC-2822
   - Technically redundant as the GPG signature already contains
     the signing date.
 * Signer (required, simple).  The person/entity signing this
   - When using role keys, this can be used to document who
     created the signature.  Otherwise it should be the same
     as the owner of the key.
 * Signing-Policy (optional, simple).  The URI to the "Signing
   Policy" of the signer (if any).
 * Checksums-<algorithm> (required, multiline).  Contains the
   checksums and sizes of files covered by this signature file.
   - Implementations are required to know/use "Md5", "Sha1" and
   - The first line must be empty.  Subsequent lines are:
       <checksum> <file-size> <filename>
     (Same as the fields of same name in .changes)
   - The filename should be the "unpacked" name of the file.
     (without the slash added by some ar implementations etc.)
 * Role (required, simple).  Defines the signers relation to the
   package.  It must be one of the following values:
    - "builder": The signer built the package.  At most one
      signature file can use this role.
    - "reviewer": The signer reviewed the package.  This role can
      be used in any number of signature files.
    - "vendor": The signer is a vendor (re-)distributing the
      package.  The name of the vendor will be in the Vendor
      field.  This role can be used in any number of signature
      files (assuming the vendors import the deb "as-is" and
      simply resign it).
  * Vendor (special, simple).  Contains the name of the Vendor
    - Field is mandatory if Role has the value "vendor", otherwise
      it should be absent.
    - Example value: Debian
  * Vendor-URI (optional, simple).  URI to the vendor's website or
    - Should be omitted if Vendor is not present.
    - Example value: http://debian.org

The entire control file must be covered by the signature.
Implementations should reject any signature file with contents that
are not part of the signature or covered by the signature.
  Unless verifiable by the signed contents of a signature, no unsigned
part of the signature file (such as its filename or its last
modification time) should be given any semantic value.

Rationale: Basic syntax/format was chosen, since it is widely
supported in Debian based tools and well documented.

I chose "Format" over "Version" because A) it is the same as in .dsc +
.changes and B) it prevents confusion with the "version of the

The Date and Signer field were added because it gives a human readable
information about the signature (without having to use GPG to extract
it).  Open question: Should we have an optional field to document the
"ID" of the key (for role keys)?

The choice of the "Checksums-*" seemed obvious to me.  Any tool
checking .dsc or .changes files should already have code to verify
these fields, so it should allow implementations to reuse existing
code.  Also it trivially allows adding new algorithms in the future.

The last paragraph (only trust the signed part) should be straight
forward, but I included it because I noticed a possible flaw in
  In [OSPEC], the origin is determined only from its member name.
This would allow someone to rename the signature and thereby change
"what" you signed.  As [OSPEC]'s policies relies on the member names
it could possibly be abused in some way.

Open question: should we allow implementation specific fields with the
usual "X-<field>" notation (or something similar)?


[OSPEC] also includes a section of how to create policies to verify
these deb signatures.  I do believe a standardized "verfication policy
framework" is a commendable thing, but I also believe it written on
top of this specification later.

I also wonder if we should permit signatures to sign other signatures.
As an example, "When I signed this deb, there was also a signature
from Alice (who signed it as role X)".

This was my draft specification signing debs.  As mentioned earlier -
feedback and changes are more than welcome. :)


PS: I am not subscribed to the bug, so please CC me accordingly.

[DRM] https://wiki.debian.org/Teams/Dpkg/RoadMap

Merge back functionality from dpkg-sig, debsigs-verify, etc:
  * Draft a new spec for the signature support inside .deb.
  * Write a dpkg-sig (or similarly named program) in C (Depends: #refactor-deb).
  * The archive should allow signed packages. Tracked in 34030

[OSPEC] http://quux.org:70/devel/debian/debsigs.txt

[DSV] http://purplefloyd.wordpress.com/2009/02/05/signing-deb-packages/

Admittedly, I have not actually tested it and merely assumed that blog
post and [OSPEC] were "up to date".


Example output on a locally tested package:

Hash: SHA256

Version: 4
Signer: Niels Thykier <niels@thykier.net>
Date: Sat Jun  9 15:28:24 2012
Role: nt
        3cf918272ffa5de195752d73f3da3e5e 7959c969e092f2a5a8604e2287807ac5b1b384ad 4 debian-binary
        942b15255d6977315435aad5b17d900e 0d8d802b45df7032e8155c05d8cb9b2ead13987e 8911 control.tar.gz
        ec796ed1f636278915db1aeec1eeecf6 ca84c27f130bab7ee287f055eeaae7f7da51c2bb 683401 data.tar.gz
Version: GnuPG v1.4.12 (GNU/Linux)


Reply to: