From 2332d10505c32f623303478d8099ebb8c5639eef Mon Sep 17 00:00:00 2001 From: Björn Persson Date: May 23 2016 12:34:29 +0000 Subject: Clarified documentation and messages. · Clarified that multiple pairs and triples can be given. · Clarified that source files can be specified as numbers or filenames, but not as pathnames. · Explained how signatures and keyrings are found in a way more focused on the user's perspective. · Used "common keyring" to denote a keyring that may used for multiple signatures, avoiding "default keyring". · Stated clearly that keyrings must contain only trusted keys. --- diff --git a/README.rst b/README.rst index 04c3e3e..7864348 100644 --- a/README.rst +++ b/README.rst @@ -7,6 +7,10 @@ signatures, and keyring(s) are listed in the spec with Source: tags. The macro can automatically determine which Source: files contain sources, signatures and a keyring, or it can be passed the numbers or names of the Source: entries to check. +ASCII-armored signatures and keyrings can be identified reliably. Unarmored +signatures and keyrings will be found automatically only if they have certain +filename suffixes, as their file formats aren't easily recognized. + A separate macro file containing a redifinition of ``%autosetup`` is also provided which will, by default, run ``%gpg_verify`` in automatic mode. @@ -14,32 +18,37 @@ How to call %gpg_verify ----------------------- ``%gpg_verify`` [-k keyring] [source,signature[,keyring]] ... - -k keyring Specify default keyring - - keyring, source and signature are either source numbers or filenames. + -k keyring Specify a common keyring to verify all signatures against, + except when an argument specifies its own keyring. -``%gpg_verify`` first determine the default keyring, which will either be taken -from the ``-k`` option or will be automatically determined by looking through -all available Source: files. Armored keyrings will be found by searching for -``BEGIN PGP PUBLIC KEY BLOCK``. Binary keys will only be found if named ending -in ``.gpg`` since they contain no identifying metadata. + keyring, source and signature are either source numbers or filenames. A + pathname including directories is not allowed. -If arguments were given, they are taken either as ``source,signature`` pairs or -``source,signature,keyring`` triples. If the keyring is not specified, the -default keyring will be used. If none was determined, the package build will -be aborted. Then all provided signatures are verified by calling gpg2 as -necessary to dearmor, and gpgv2 to verify. If any verifications fail, the -package build will be aborted. +If one or more arguments were given, they are taken either as +``source,signature`` pairs or ``source,signature,keyring`` triples. When an +argument specifies a keyring, that signature will be verified against the keys +in that keyring. For arguments that don't specify a keyring, the common +keyring specified with the ``-k`` option will be used, if any. If ``-k`` isn't +given, ``%gpg_verify`` will attempt to locate a keyring among the Source: +files. The first source file that contains ``BEGIN PGP PUBLIC KEY BLOCK`` in +the beginning or has a name ending in ``.gpg`` will be used as the common +keyring. If none is found, the package build will be aborted. Then all +provided signatures are verified by calling gpg2 as necessary to dearmor, and +gpgv2 to verify. If any verifications fail, the package build will be aborted. If no arguments were given (called "automatic mode"), ``%gpg_verify`` will -attempt to locate signatures in the provided Source: files. Armored signatures -will be found if they contain ``BEGIN PGP SIGNATURE``; binary signatures must -be named ending with ``.sig``. For each signature found, the macro will -attempt to locate a matching source file by trimming the final file extension -from the signature filename. If no matching source was found, the package -build will be aborted. Then the paired signatures and source files are -verified using the default keyring, and the package build will be aborted if -necessary. +attempt to locate signatures in the provided Source: files. Any source file +that contains ``BEGIN PGP SIGNATURE`` in the beginning or is named ending with +``.sig`` will be considered a signature. For each signature found, the macro +will attempt to locate a matching source file by trimming the final file +extension from the signature filename. If no matching source was found, the +package build will be aborted. Then the paired signatures and source files are +verified using the keyring specified with ``-k``, if any, or else the first one +found, and the package build will be aborted if any verifications fail. + +In all cases it is assumed that all the keys in all keyrings, whether +automatically found or explicitly specified, are trusted to authenticate the +source files. There must not be any untrusted keys included. Testing the macro @@ -47,7 +56,7 @@ Testing the macro A sample spec is provided which will test various aspects of the macro. Note that this spec is intended to be used as a test and example of multiple -different calling conventions, but in regular use te macro will almost never be +different calling conventions, but in regular use the macro will almost never be used more than once. The spec contains some Lua code to manipulate internal RPM state which exists only to facilitate testing and isn't anything you'd ever have to do in your own packages. diff --git a/macros.gpg b/macros.gpg index f76e690..a842a27 100644 --- a/macros.gpg +++ b/macros.gpg @@ -6,15 +6,24 @@ # tries to pair each signature file with a source. If there is no source found # which matches a signature, the build is aborted. # -# -k gives a keyring to use by default. +# -k gives a common keyring to verify all signatures against, except when an +# argument specifies its own keyring. # -# If no default keyring is specified, the macro will default to the first one -# it finds in the source list. -# -# The arguments must be of the form "F,S,K" or "F,S". +# Each argument must be of the form "F,S,K" or "F,S", where each of F, S and K +# is either the number or the filename of one of the source files in the +# package. A pathname including directories is not allowed. # F is a source file to check. # S is a signature. -# K is a key. If none is provided, the default will be used. +# K is a keyring. +# +# When an argument specifies a keyring, that signature will be verified against +# the keys in that keyring. For arguments that don't specify a keyring, the one +# specified with -k will be used, if any. If no keyring is specified either +# way, the macro will default to the first one it finds in the source list. +# +# It is assumed that all the keys in all keyrings, whether automatically found +# or explicitly specified, are trusted to authenticate the source files. There +# must not be any untrusted keys included. # Some utility functions to the global namespace # Most of these should come from the utility macros in the other repo. @@ -213,10 +222,10 @@ if defkeyspec then defkey = check_sources_list({defkeyspec})[1] if not defkey then - rpmerror('Provided default keyring ' .. defkeyspec .. ' is not a valid source number.') + rpmerror('The provided keyring ' .. defkeyspec .. ' is not a valid source number or filename.') \ elseif not keyring_table[defkey] then - rpmerror('Provided default keyring ' .. defkeyspec .. ' does not appear to contain a keyring.') + rpmerror('The provided keyring ' .. defkeyspec .. ' does not appear to contain a keyring.') defkey = nil end end @@ -224,7 +233,7 @@ if defkey then db('Defkey: ' .. defkey) else - db('No default key yet') + db('No common key yet') if keyrings[1] then defkey = keyrings[1] db('Using first found keyring file: '..defkey) @@ -232,7 +241,7 @@ end \ -- Check over any given args to make sure they're valid, and to see if a - -- default key is required. + -- common key is required. local needdefkey = false local double = rex.newPOSIX('^([^,]+),([^,]+)$') local triple = rex.newPOSIX('^([^,]+),([^,]+),([^,]+)$') @@ -251,7 +260,7 @@ parsed.keyfile = s[3] table.insert(arglist, parsed) elseif double:gmatch(arg, storematch) > 0 then - db('Looks OK; needs default key') + db('Looks OK; needs common key') needdefkey = true local parsed = {srcnum=captures[1], signum=captures[2], keynum=defkeyspec, keyfile=defkey} s = check_sources_list({captures[1], captures[2]}) @@ -263,12 +272,12 @@ end end \ - -- So we now know if one of those args needs a default key + -- So we now know if one of those args needs a common key if needdefkey and not defkey then - rpmerror('No default key specified or found, yet the arguments require one.') + rpmerror('No common key was specified or found, yet the arguments require one.') end \ - -- And if we have no arguments at all and no defkey was found, + -- And if we have no arguments at all and no common key was found, -- then we can't do an automatic check if not defkey and args == '' then rpmerror('No keyring specified and none found; cannot auto-check.')