Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions deb/remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ func (repo *RemoteRepo) Fetch(d aptly.Downloader, verifier pgp.Verifier, ignoreS
return err
}

err = verifier.VerifyDetachedSignature(releasesig, release, true)
_, err = verifier.VerifyDetachedSignature(releasesig, release, true)
if err != nil {
return err
}
Expand Down Expand Up @@ -600,7 +600,7 @@ func (repo *RemoteRepo) DownloadPackageIndexes(progress aptly.Progress, d aptly.
return err
}

err = verifier.VerifyDetachedSignature(filesig, packagesFile, false)
_, err = verifier.VerifyDetachedSignature(filesig, packagesFile, false)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions deb/remote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ func (n *NullVerifier) InitKeyring(_ bool) error {
func (n *NullVerifier) AddKeyring(keyring string) {
}

func (n *NullVerifier) VerifyDetachedSignature(signature, cleartext io.Reader, hint bool) error {
return nil
func (n *NullVerifier) VerifyDetachedSignature(signature, cleartext io.Reader, hint bool) (*pgp.KeyInfo, error) {
return &pgp.KeyInfo{}, nil
}

func (n *NullVerifier) VerifyClearsigned(clearsigned io.Reader, hint bool) (*pgp.KeyInfo, error) {
Expand Down
16 changes: 10 additions & 6 deletions pgp/gnupg.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,12 @@ func (g *GpgVerifier) runGpgv(args []string, context string, showKeyTip bool) (*
}

// VerifyDetachedSignature verifies combination of signature and cleartext using gpgv
func (g *GpgVerifier) VerifyDetachedSignature(signature, cleartext io.Reader, showKeyTip bool) error {
func (g *GpgVerifier) VerifyDetachedSignature(signature, cleartext io.Reader, showKeyTip bool) (*KeyInfo, error) {
args := g.argsKeyrings()

sigf, err := os.CreateTemp("", "aptly-gpg")
if err != nil {
return err
return nil, err
}
defer func() {
_ = os.Remove(sigf.Name())
Expand All @@ -306,12 +306,12 @@ func (g *GpgVerifier) VerifyDetachedSignature(signature, cleartext io.Reader, sh

_, err = io.Copy(sigf, signature)
if err != nil {
return err
return nil, err
}

clearf, err := os.CreateTemp("", "aptly-gpg")
if err != nil {
return err
return nil, err
}
defer func() {
_ = os.Remove(clearf.Name())
Expand All @@ -320,12 +320,16 @@ func (g *GpgVerifier) VerifyDetachedSignature(signature, cleartext io.Reader, sh

_, err = io.Copy(clearf, cleartext)
if err != nil {
return err
return nil, err
}

args = append(args, sigf.Name(), clearf.Name())
_, err = g.runGpgv(args, "detached signature", showKeyTip)
return err
if err != nil {
return nil, err
}

return &KeyInfo{}, nil
}

// IsClearSigned returns true if file contains signature
Expand Down
27 changes: 22 additions & 5 deletions pgp/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ func (g *GoVerifier) printLog(signers []signatureResult) {
}

// VerifyDetachedSignature verifies combination of signature and cleartext using gpgv
func (g *GoVerifier) VerifyDetachedSignature(signature, cleartext io.Reader, showKeyTip bool) error {
func (g *GoVerifier) VerifyDetachedSignature(signature, cleartext io.Reader, showKeyTip bool) (*KeyInfo, error) {
var signatureBuf bytes.Buffer

signers, missingKeys, err := checkArmoredDetachedSignature(g.trustedKeyring, cleartext, io.TeeReader(signature, &signatureBuf))
Expand All @@ -409,10 +409,24 @@ func (g *GoVerifier) VerifyDetachedSignature(signature, cleartext io.Reader, sho
}

if err != nil {
return errors.Wrap(err, "failed to verify detached signature")
return nil, errors.Wrap(err, "failed to verify detached signature")
}

return nil
result := &KeyInfo{}

for _, signer := range signers {
if signer.Entity != nil {
if signer.IsExpired {
result.ExpiredKeys = append(result.ExpiredKeys, KeyFromUint64(signer.IssuerKeyID))
} else {
result.GoodKeys = append(result.GoodKeys, KeyFromUint64(signer.IssuerKeyID))
}
} else {
result.MissingKeys = append(result.MissingKeys, KeyFromUint64(signer.IssuerKeyID))
}
}

return result, nil
}

// IsClearSigned returns true if file contains signature
Expand Down Expand Up @@ -455,10 +469,13 @@ func (g *GoVerifier) VerifyClearsigned(clearsigned io.Reader, showKeyTip bool) (

for _, signer := range signers {
if signer.Entity != nil {
result.GoodKeys = append(result.GoodKeys, KeyFromUint64(signer.IssuerKeyID))
if signer.IsExpired {
result.ExpiredKeys = append(result.ExpiredKeys, KeyFromUint64(signer.IssuerKeyID))
} else {
result.GoodKeys = append(result.GoodKeys, KeyFromUint64(signer.IssuerKeyID))
}
} else {
result.MissingKeys = append(result.MissingKeys, KeyFromUint64(signer.IssuerKeyID))

}
}

Expand Down
7 changes: 7 additions & 0 deletions pgp/openpgp.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func hashForSignature(hashID crypto.Hash, sigType packet.SignatureType) (hash.Ha

type signatureResult struct {
CreationTime time.Time
IsExpired bool
IssuerKeyID uint64
PubKeyAlgo packet.PublicKeyAlgorithm
Entity *openpgp.Entity
Expand All @@ -59,6 +60,8 @@ func checkDetachedSignature(keyring openpgp.KeyRing, signed, signature io.Reader
return nil, 0, e
}

var now = time.Now()

packets := packet.NewReader(signature)
for {
p, err = packets.Next()
Expand All @@ -82,11 +85,14 @@ func checkDetachedSignature(keyring openpgp.KeyRing, signed, signature io.Reader
var pubKeyAlgo packet.PublicKeyAlgorithm
var keys []openpgp.Key

var sigExpired bool

switch sig := p.(type) {
case *packet.Signature:
if sig.IssuerKeyId == nil {
return nil, 0, errors.StructuralError("signature doesn't have an issuer")
}
sigExpired = sig.SigExpired(now)
issuerKeyID = *sig.IssuerKeyId
hashFunc = sig.Hash
sigType = sig.SigType
Expand Down Expand Up @@ -128,6 +134,7 @@ func checkDetachedSignature(keyring openpgp.KeyRing, signed, signature io.Reader
if err == nil {
signers = append(signers, signatureResult{
CreationTime: creationTime,
IsExpired: sigExpired || key.PublicKey.KeyExpired(key.SelfSignature, now),
IssuerKeyID: issuerKeyID,
PubKeyAlgo: pubKeyAlgo,
Entity: key.Entity,
Expand Down
3 changes: 2 additions & 1 deletion pgp/pgp.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func KeyFromUint64(key uint64) Key {
type KeyInfo struct {
GoodKeys []Key
MissingKeys []Key
ExpiredKeys []Key
}

// Signer interface describes facility implementing signing of files
Expand All @@ -53,7 +54,7 @@ type Signer interface {
type Verifier interface {
InitKeyring(verbose bool) error
AddKeyring(keyring string)
VerifyDetachedSignature(signature, cleartext io.Reader, showKeyTip bool) error
VerifyDetachedSignature(signature, cleartext io.Reader, showKeyTip bool) (*KeyInfo, error)
IsClearSigned(clearsigned io.Reader) (bool, error)
VerifyClearsigned(clearsigned io.Reader, showKeyTip bool) (*KeyInfo, error)
ExtractClearsigned(clearsigned io.Reader) (text *os.File, err error)
Expand Down
2 changes: 1 addition & 1 deletion pgp/sign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (s *SignerSuite) testSignDetached(c *C) {
err := s.signer.DetachedSign(s.clearF.Name(), s.signedF.Name())
c.Assert(err, IsNil)

err = s.verifier.VerifyDetachedSignature(s.signedF, s.clearF, false)
_, err = s.verifier.VerifyDetachedSignature(s.signedF, s.clearF, false)
c.Assert(err, IsNil)
}

Expand Down
19 changes: 13 additions & 6 deletions pgp/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,25 @@ type VerifierSuite struct {
func (s *VerifierSuite) TestVerifyDetached(c *C) {
for _, test := range []struct {
textName, signatureName string
expiredKeys []Key
}{
{"1.text", "1.signature"},
{"2.text", "2.signature"},
{"3.text", "3.signature"},
{"4.text", "4.signature"},
{"1.text", "1.signature", nil},
{"2.text", "2.signature", nil},
{"3.text", "3.signature", nil},
// 4.signature is signed by an expired key (wheezy, 8B48AD6246925553)
{"4.text", "4.signature", []Key{"8B48AD6246925553"}},
} {
cleartext, err := os.Open(test.textName)
c.Assert(err, IsNil)

signature, err := os.Open(test.signatureName)
c.Assert(err, IsNil)

err = s.verifier.VerifyDetachedSignature(signature, cleartext, false)
keyInfo, err := s.verifier.VerifyDetachedSignature(signature, cleartext, false)
c.Assert(err, IsNil)
if test.expiredKeys != nil {
c.Check(keyInfo.ExpiredKeys, DeepEquals, test.expiredKeys)
}

_ = signature.Close()
_ = cleartext.Close()
Expand All @@ -47,8 +52,10 @@ func (s *VerifierSuite) TestVerifyClearsigned(c *C) {

keyInfo, err := s.verifier.VerifyClearsigned(clearsigned, false)
c.Assert(err, IsNil)
c.Check(keyInfo.GoodKeys, DeepEquals, []Key{"04EE7237B7D453EC", "648ACFD622F3D138", "DCC9EFBF77E11517"})
// 04EE7237B7D453EC (stretch) is expired and must appear in ExpiredKeys, not GoodKeys
c.Check(keyInfo.GoodKeys, DeepEquals, []Key{"648ACFD622F3D138", "DCC9EFBF77E11517"})
c.Check(keyInfo.MissingKeys, DeepEquals, []Key(nil))
c.Check(keyInfo.ExpiredKeys, DeepEquals, []Key{"04EE7237B7D453EC"})

_ = clearsigned.Close()
}
Expand Down
Loading