From 68da8a674aa490494f80aab1d08de8beca7d57ce Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Fri, 28 Jul 2017 00:52:04 +0300 Subject: [PATCH 1/3] Improve internal PGP provider 1. Print additional details about keys being used for signing 2. Skip expired keys 3. Add `\n` to logged messages --- pgp/internal.go | 29 ++++++++++--- pgp/openpgp.go | 50 +++++++++++++++++++++++ system/t06_publish/PublishRepo31Test_gold | 1 + 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/pgp/internal.go b/pgp/internal.go index 32afab87..3747d627 100644 --- a/pgp/internal.go +++ b/pgp/internal.go @@ -108,13 +108,20 @@ func (g *GoSigner) Init() error { return errors.Wrap(err, "error load secret keyring") } - if len(g.secretKeyring) == 0 { - return fmt.Errorf("looks like there are no keys in gpg, please create one (official manual: http://www.gnupg.org/gph/en/manual.html)") - } - if g.keyRef == "" { // no key reference, pick the first key - g.signer = g.secretKeyring[0] + for _, signer := range g.secretKeyring { + if !validEntity(signer) { + continue + } + + g.signer = signer + break + } + + if g.signer == nil { + return fmt.Errorf("looks like there are no keys in gpg, please create one (official manual: http://www.gnupg.org/gph/en/manual.html)") + } } else { pickKeyLoop: for _, signer := range g.secretKeyring { @@ -124,6 +131,10 @@ func (g *GoSigner) Init() error { break } + if !validEntity(signer) { + continue + } + for name := range signer.Identities { if strings.Contains(name, g.keyRef) { g.signer = signer @@ -148,6 +159,12 @@ func (g *GoSigner) Init() error { i++ } + fmt.Printf("openpgp: %s-bit %s key, ID %s, created %s\n", + keyBits(g.signer.PrimaryKey.PublicKey), + pubkeyAlgorithmName(g.signer.PrimaryKey.PubKeyAlgo), + KeyFromUint64(g.signer.PrimaryKey.KeyId), + g.signer.PrimaryKey.CreationTime.Format("2006-01-02")) + if g.passphrase == "" { if g.batch { return errors.New("key is locked with passphrase, but no passphrase was given in batch mode") @@ -456,7 +473,7 @@ func loadKeyRing(name string, ignoreMissing bool) (openpgp.EntityList, error) { if err != nil { if os.IsNotExist(err) { if !ignoreMissing { - fmt.Printf("opengpg: failure opening keyring '%s': %s", name, err) + fmt.Printf("opengpg: failure opening keyring '%s': %s\n", name, err) } return nil, nil } diff --git a/pgp/openpgp.go b/pgp/openpgp.go index 6c5e15d6..046feb48 100644 --- a/pgp/openpgp.go +++ b/pgp/openpgp.go @@ -3,6 +3,9 @@ package pgp import ( "bytes" "crypto" + "crypto/dsa" + "crypto/ecdsa" + "crypto/rsa" "hash" "io" "strconv" @@ -191,3 +194,50 @@ func pubkeyAlgorithmName(algorithm packet.PublicKeyAlgorithm) string { return "unknown" } + +func keyBits(key interface{}) string { + switch k := key.(type) { + case *rsa.PublicKey: + return strconv.Itoa(k.N.BitLen()) + case *dsa.PublicKey: + return strconv.Itoa(k.P.BitLen()) + case *ecdsa.PublicKey: + return strconv.Itoa(k.Curve.Params().BitSize) + default: + return "?" + } +} + +func validEntity(entity *openpgp.Entity) bool { + var selfSig *packet.Signature + for _, ident := range entity.Identities { + if selfSig == nil { + selfSig = ident.SelfSignature + } else if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId { + selfSig = ident.SelfSignature + break + } + } + + if selfSig == nil { + return false + } + + if len(entity.Revocations) > 0 { + return false + } + + if selfSig.RevocationReason != nil { + return false + } + + if !selfSig.FlagsValid { + return false + } + + if selfSig.KeyLifetimeSecs != nil && selfSig.CreationTime.Add(time.Duration(*selfSig.KeyLifetimeSecs)*time.Second).Before(time.Now()) { + return false + } + + return true +} diff --git a/system/t06_publish/PublishRepo31Test_gold b/system/t06_publish/PublishRepo31Test_gold index 7f8c4b42..1c29ddaf 100644 --- a/system/t06_publish/PublishRepo31Test_gold +++ b/system/t06_publish/PublishRepo31Test_gold @@ -1,4 +1,5 @@ openpgp: Passphrase is required to unlock private key "Aptly Tester (don't use it) " +openpgp: 1024-bit DSA key, ID F30E8CB9CDDE2AF8, created 2014-08-30 Loading packages... Generating metadata files and linking package files... Finalizing metadata files... From cbb576cbccdf0a7dbc9ff647078e99b194d1d619 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Fri, 28 Jul 2017 18:49:18 +0300 Subject: [PATCH 2/3] Fix up system tests --- system/t04_mirror/CreateMirror30Test_gold | 5 +++-- system/t06_publish/PublishRepo31Test_gold | 2 +- system/t06_publish/repo.py | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/system/t04_mirror/CreateMirror30Test_gold b/system/t04_mirror/CreateMirror30Test_gold index e01c573d..94ee222b 100644 --- a/system/t04_mirror/CreateMirror30Test_gold +++ b/system/t04_mirror/CreateMirror30Test_gold @@ -1,10 +1,11 @@ opengpg: failure opening keyring '${HOME}/.gnupg/aptlytest.gpg': open ${HOME}/.gnupg/aptlytest.gpg: no such file or directory + Looks like your keyring with trusted keys is empty. You might consider importing some keys. Downloading http://mirror.yandex.ru/debian-backports/dists/squeeze-backports/InRelease... -openpgp: Signature made Sun, 13 Mar 2016 12:02:54 MSK using RSA key ID 8B48AD6246925553 +openpgp: RSA key ID 8B48AD6246925553 openpgp: Can't check signature: public key not found Downloading http://mirror.yandex.ru/debian-backports/dists/squeeze-backports/Release... Downloading http://mirror.yandex.ru/debian-backports/dists/squeeze-backports/Release.gpg... -openpgp: Signature made Sun, 13 Mar 2016 12:02:54 MSK using RSA key ID 8B48AD6246925553 +openpgp: RSA key ID 8B48AD6246925553 openpgp: Can't check signature: public key not found ERROR: unable to fetch mirror: failed to verify detached signature: openpgp: signature made by unknown entity diff --git a/system/t06_publish/PublishRepo31Test_gold b/system/t06_publish/PublishRepo31Test_gold index 1c29ddaf..11837d56 100644 --- a/system/t06_publish/PublishRepo31Test_gold +++ b/system/t06_publish/PublishRepo31Test_gold @@ -1,5 +1,5 @@ openpgp: Passphrase is required to unlock private key "Aptly Tester (don't use it) " -openpgp: 1024-bit DSA key, ID F30E8CB9CDDE2AF8, created 2014-08-30 +openpgp: 1024-bit DSA key, ID F30E8CB9CDDE2AF8, created Loading packages... Generating metadata files and linking package files... Finalizing metadata files... diff --git a/system/t06_publish/repo.py b/system/t06_publish/repo.py index 6d24e7bf..a476658f 100644 --- a/system/t06_publish/repo.py +++ b/system/t06_publish/repo.py @@ -1,6 +1,7 @@ import os import hashlib import inspect +import re import zlib from lib import BaseTest @@ -747,6 +748,9 @@ class PublishRepo31Test(BaseTest): gold_processor = BaseTest.expand_environ configOverride = {"gpgProvider": "internal"} + def outputMatchPrepare(_, s): + return re.sub(r' \d{4}-\d{2}-\d{2}', '', s) + def check(self): super(PublishRepo31Test, self).check() From e9b2c18e2f0ee6fe7b7d08b875ad255c37e8a35f Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Fri, 28 Jul 2017 21:36:38 +0300 Subject: [PATCH 3/3] Attempt to fix the tests --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1d93d436..e8c9b6bd 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ check: system/env else \ gometalinter --config=linter.json ./...; \ fi - . system/env/bin/activate && flake8 --max-line-length=200 --exclude=env/ system/ + . system/env/bin/activate && flake8 --max-line-length=200 --exclude=system/env/ system/ install: go install -v -ldflags "-X main.Version=$(VERSION)"