#836 Source File Verification
Opened 4 months ago by rombobeorn. Modified 4 months ago
rombobeorn/packaging-committee master  into  master

@@ -115,6 +115,112 @@ 


  Fedora's git repository is the canonical location for Fedora spec files. Maintainers MUST expect that other maintainers and automated tooling will make changes to their packages, potentially without communicating prior to doing so (though communication is always encouraged). If some maintainers are also attempting to keep copies of a spec in an outside repository, they MUST be prepared to merge changes made to the spec in Fedora's repository, and MUST NOT overwrite those changes with a copy from an external repository or using `+fedpkg import+`.


+ == Source File Verification


+ Where the upstream project publishes OpenPGP signatures of their releases,

+ Fedora packages *SHOULD* verify that signature as part of the RPM build process.


+ Although a checksum in the sources file certifies that a file retreived from the lookaside cache is the one that the packager uploaded,

+ it is silent on whether the file is what the upstream project released.

+ A signature by the upstream developers certifies that the source is identical to what they released.

+ Verifying the signature as part of the build ensures that packagers don't forget to verify it.


+ === Obtaining the Correct Keys


+ The verification method requires an OpenPGP keyring file

+ with one or more public keys from the upstream project.

+ The keyring shall contain all the keys that are trusted to certify the authenticity of the sources,

+ and *MUST NOT* contain any other keys.


+ Ideally the upstream project publishes such a keyring as a downloadable file.

+ You shall download that file

+ and do everything you reasonably can to verify that it is authentic.

+ Then you shall add it unmodified to the package SCM,

+ and provide its URL in the spec file

+ so that others can verify it.

+ The URL *MUST* use HTTPS or a similarly authenticated protocol if at all possible.


+ Even if you are unable to verify the key at the first addition,

+ it still enhances security in a trust-on-first-use way.

+ It will ensure that future attacks will be detected if the key is the right one,

+ or that a current attack will be detected later if future releases are signed by the correct key.


+ === Verifying Signatures


+ When source file verification is done,

+ it *MUST* be done first in the `%prep` section of the spec file,

+ before any potentially compromised code is executed.

+ The verification *MUST* be done with the macro +++<var>gpgverify</var>+++,

+ which expands into a command

+ whose parameters shall be the pathnames of the keyring, the signature and the signed file.

+ “`BuildRequires: gnupg2`” is necessary for the verification to work.


+ Any detached signature file

+ (e.g. foo.tar.gz.asc or foo.tar.gz.sig)

+ must be uploaded to the package lookaside cache alongside the source code,

+ while the keyring must be committed directly to the package SCM.


+ The following format must be used:


+ ....

+ Source0: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.gz

+ Source1: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.gz.asc

+ Source2: https://www.example.com/gpgkey-0123456789ABCDEF0123456789ABCDEF.gpg

+ …

+ BuildRequires: gnupg2

+ …

+ %prep

+ %{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'

+ ....


+ The first source is the actual tarball,

+ the second one is the signature from upstream,

+ and the third one is the keyring.


+ === Exceptions

+ If the upstream tarball of a package needs to be modified,

+ for example because it contains forbidden items,

+ then the tarball cannot be verified as part of the build process.

+ In this case the upstream OpenPGP keyring must still be included in the package SCM

+ and the instructions/script used to build the stripped-down tarball needs to verify the upstream source.


+ If the upstream project does not publish a keyring file

+ (for example if they publish only a fingerprint on their website

+ and refer to a keyserver network for downloading the key),

+ then you may need to create a keyring after you have verified the key.

+ In this case there is no upstream URL to the keyring,

+ so instead you should document how you created the keyring in a comment in the spec file.

+ A minimal keyring with the key with the fingerprint `7D33D762FD6C35130481347FDB4B54CBA4826A18` can be created with the following command:


+ ....

+ gpg2 --export --export-options export-minimal 7D33D762FD6C35130481347FDB4B54CBA4826A18 > gpgkey-7D33D762FD6C35130481347FDB4B54CBA4826A18.gpg

+ ....


+ If upstream signed a tarball differently,

+ for example by signing only the uncompressed tarball but distributing a compressed version,

+ then the verification step must the adjusted accordingly, for example:


+ ....

+ Source0: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.xz

+ Source1: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.asc

+ Source2: https://www.example.com/gpgkey-0123456789ABCDEF0123456789ABCDEF.gpg

+ …

+ BuildRequires: gnupg2 xz

+ …

+ %prep

+ xzcat '%{SOURCE0}' | %{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data=-

+ ....


+ Packages that are vital during bootstrapping of Fedora

+ may use a <<bootstrapping,bootstrap flag>> to skip the verification before GnuPG has been built.


+ === Help


+ If you need help getting your package compliant to this guideline,

+ or if you do not know what to do if a build fails on a signature verification,

+ then you should seek help on the Fedora devel mailing list before circumventing the check,

+ to make sure that you do not build compromised software.


  == Architecture Support


  All Fedora packages must successfully compile and build into binary rpms on at least one supported primary architecture, except where the package is useful only on a secondary architecture (such as an architecture-specific boot utility, microcode loader, or hardware configuration tool). Fedora packagers should make every effort to support all https://fedoraproject.org/wiki/Architectures#Primary_Architectures[primary architectures].

This is my proposal for a signature verification policy to resolve issue 610. It relies on the pull request https://src.fedoraproject.org/rpms/fedora-rpm-macros/pull-request/1, which makes the code templates simpler than in the proposal in the wiki. I have expanded the policy on how to obtain the keys, as that's the step where everything depends on the vigilance of the packager.

I don't have problem with MUST, but probably SHOULD would be more appropriate.

That "MUST" was there already in David Woodhouse's proposal in 2016. I can change it if the FPC wants. What do others think?

I agree, MUST is a bit strong here.
Especially since it would render all existing .specs for packages with verifiable upstream sources non-conformant.

Why not use plain gpg2 as suggested in https://pagure.io/packaging-committee/issue/610#comment-535966 ? It'll work across EPEL and Fedora the same way.

Metadata Update from @ignatenkobrain:
- Request assigned

4 months ago

Why not use plain gpg2 as suggested in https://pagure.io/packaging-committee/issue/610#comment-535966 ?

Because that's much harder to do right for packagers who aren't GnuPG experts:

  1. GnuPG doesn't accept armored keyrings, so a separate dearmoring step may or may not be necessary. This requires packagers to understand what ASCII-armor is, and makes for complex instructions in the guidelines, which are already uncomfortably long. Using my script, packagers don't need to even know that there is a difference between armored and unarmored keyrings.

  2. GnuPG requires specific unintuitive parameters, or else it may use the wrong keyring. This again makes the instructions complex. People tend to ignore instructions when they don't understand why the instructions are necessary. Some will undoubtedly try to simplify the command by omitting "--homedir" and "./", and thereby introduce security bugs. My script doesn't allow itself to be used wrong.

It'll work across EPEL and Fedora the same way.

So will my script. I have tested it in CentOS 6 and 7. We can add the script and macro to a suitable EPEL package and have them work the same way across EPEL and Fedora. Would epel-rpm-macros be a good choice?

rebased onto 8a80fb3

4 months ago

I have updated the proposed text to show that spec files must require GnuPG, matching this pull request:

I have also weakened the policy to "SHOULD" as requested.