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
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ List of contributors, in chronological order:
* Raphael Medaer (https://github.com/rmedaer)
* Raul Benencia (https://github.com/rul)
* Don Kuntz (https://github.com/dkuntz2)
* Charles Duffy (https://github.com/charles-dyfis-net)
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ require (
github.com/aws/aws-sdk-go v1.25.0
github.com/cheggaaa/pb v1.0.10
github.com/fatih/color v1.7.0 // indirect
github.com/folbricht/tpmk v0.1.2-0.20210411225238-7061339773c3
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 // indirect
github.com/gin-gonic/gin v1.1.5-0.20170702092826-d459835d2b07
github.com/google/go-tpm v0.1.2-0.20190306182045-7a7fe86fbbf2
github.com/google/go-tpm-tools v0.0.0-20190131232102-89d1c95730e5
github.com/h2non/filetype v1.0.5
github.com/jlaffaye/ftp v0.0.0-20180404123514-2403248fa8cc // indirect
github.com/kjk/lzma v0.0.0-20161016003348-3fd93898850d
Expand All @@ -32,7 +35,7 @@ require (
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d
github.com/ugorji/go v1.1.4
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0
golang.org/x/crypto v0.0.0-20180403160946-b2aa35443fbc
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405
gopkg.in/cheggaaa/pb.v1 v1.0.28 // indirect
Expand Down
16 changes: 14 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/folbricht/sshtest v0.1.0/go.mod h1:HuLqb6uP2Ca4k9AwHeeivT0GLMomsBzq2PNVWO2ZL58=
github.com/folbricht/tpmk v0.1.2-0.20210411225238-7061339773c3 h1:oRWZHiWpr89KGd6xkJaZp+HJ+WKLNS2Ub9ExC7OUew4=
github.com/folbricht/tpmk v0.1.2-0.20210411225238-7061339773c3/go.mod h1:OMV4y1gh5ibhzmF59bQOm6klTYfZOHpotZHiD7eA/SY=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 h1:AzN37oI0cOS+cougNAV9szl6CVoj2RYwzS3DpUQNtlY=
Expand All @@ -22,10 +25,15 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-tpm v0.1.2-0.20190306182045-7a7fe86fbbf2 h1:e1kceXf1XB12ZNTi2UZiXtb0+c8+zlMlQarLiTohoUY=
github.com/google/go-tpm v0.1.2-0.20190306182045-7a7fe86fbbf2/go.mod h1:OGEdc1XfzTyNEQyahgeXVq+E0lMq3Vu/Y3bT9EfpRnE=
github.com/google/go-tpm-tools v0.0.0-20190131232102-89d1c95730e5 h1:ZP7wPiscXdeco0DkjnSLxwTksyFLG+w/sVFYZHh1sLQ=
github.com/google/go-tpm-tools v0.0.0-20190131232102-89d1c95730e5/go.mod h1:ApmLTU8fd5JJJ4J67y9sV16nOTR00GW2OabMwk7kSnE=
github.com/h2non/filetype v1.0.5 h1:Esu2EFM5vrzNynnGQpj0nxhCkzVQh2HRY7AXUh/dyJM=
github.com/h2non/filetype v1.0.5/go.mod h1:isekKqOuhMj+s/7r3rIeTErIRy4Rub5uBWHfvMusLMU=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jlaffaye/ftp v0.0.0-20180404123514-2403248fa8cc h1:lWFup/SOhwcpvRJIFqx/WQis5U4SrOSyWfSqvfdF09w=
github.com/jlaffaye/ftp v0.0.0-20180404123514-2403248fa8cc/go.mod h1:lli8NYPQOFy3O++YmYbqVgOcQ1JPCwdOy+5zSjKJ9qY=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
Expand Down Expand Up @@ -71,7 +79,10 @@ github.com/smira/go-ftp-protocol v0.0.0-20140829150050-066b75c2b70d h1:rvtR4+9N2
github.com/smira/go-ftp-protocol v0.0.0-20140829150050-066b75c2b70d/go.mod h1:Jm7yHrROA5tC42gyJ5EwiR8EWp0PUy0qOc4sE7Y8Uzo=
github.com/smira/go-xz v0.0.0-20150414201226-0c531f070014 h1:tne8XW3soRDJn4DIiqBc4jw+DPashtFMTSC9G0pC3ug=
github.com/smira/go-xz v0.0.0-20150414201226-0c531f070014/go.mod h1:smSuTvETRIkX95VAIWBdKoGJuUxif7NT7FgbkpVqOiA=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs=
Expand All @@ -80,14 +91,15 @@ github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ=
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM=
golang.org/x/crypto v0.0.0-20180403160946-b2aa35443fbc h1:Kx1Ke+iCR1aDjbWXgmEQGFxoHtNL49aRZGV7/+jJ41Y=
golang.org/x/crypto v0.0.0-20180403160946-b2aa35443fbc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576 h1:aUX/1G2gFSs4AsJJg2cL3HuoRhCSCz733FE5GUSuaT4=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
Expand Down
2 changes: 1 addition & 1 deletion man/aptly.1
Original file line number Diff line number Diff line change
Expand Up @@ -1444,7 +1444,7 @@ GPG passphrase\-file for the key (warning: could be insecure)
.
.TP
\-\fBsecret\-keyring\fR=
GPG secret keyring to use (instead of default)
GPG secret keyring to use (instead of default); may be of the form \fBtpm://HANDLE?dev=DEVICE\fR to use a TPM-backed key if the selected \fBgpgProvider\fR is \fBinternal\fR, where \fBHANDLE\fR is of the form \fB0x81000003\fR, and \fBdev\fR is a (URL-escaped) value similar to \fB/dev/tpmrm0\fR (which happens to be the default if not given).
.
.TP
\-\fBskip\-contents\fR
Expand Down
119 changes: 91 additions & 28 deletions pgp/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ import (
"fmt"
"io"
"io/ioutil"
"net/url"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"syscall"
"time"

"github.com/folbricht/tpmk"
"github.com/google/go-tpm/tpmutil"
"github.com/pkg/errors"

"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/clearsign"
openpgp_errors "golang.org/x/crypto/openpgp/errors"
"golang.org/x/crypto/openpgp/packet"
Expand All @@ -39,12 +44,33 @@ type GoSigner struct {
passphrase, passphraseFile string
batch bool

tpmPrivateKey *tpmk.RSAPrivateKey
publicKeyring openpgp.EntityList
secretKeyring openpgp.EntityList
signer *openpgp.Entity
signerConfig *packet.Config
}

func findKey(keyRef string, keyring openpgp.EntityList) *openpgp.Entity {
for _, signer := range keyring {
key := KeyFromUint64(signer.PrimaryKey.KeyId)
if key.Matches(Key(keyRef)) {
return signer
}

if !validEntity(signer) {
continue
}

for name := range signer.Identities {
if strings.Contains(name, keyRef) {
return signer
}
}
}
return nil
}

// SetBatch controls whether we allowed to interact with user
func (g *GoSigner) SetBatch(batch bool) {
g.batch = batch
Expand Down Expand Up @@ -104,12 +130,56 @@ func (g *GoSigner) Init() error {
return errors.Wrap(err, "error loading public keyring")
}

g.secretKeyring, err = loadKeyRing(g.secretKeyringFile, false)
if err != nil {
return errors.Wrap(err, "error load secret keyring")
if strings.HasPrefix(g.secretKeyringFile, "tpm://") {
// Expected form of tpm://0x81000002 -- optionally with query parameters holding extra values
// f/e, ?dev=%2Fdev%2Ftpmrm1 to specify the device as /dev/tpmrm1; or ?dev=sim for simulator
tpmSecretURL, err := url.Parse(g.secretKeyringFile)
if err != nil {
return errors.Wrap(err, "parsing TPM URI")
}
tpmQueryArgs := tpmSecretURL.Query()
devStrings, hasDev := tpmQueryArgs["dev"]
tpmDevFilename := "/dev/tpmrm0"
if hasDev && len(devStrings) != 0 {
if len(devStrings) > 1 {
return errors.Errorf("Parsing TPM address, more than one device name found")
}
tpmDevFilename = devStrings[0]
}
tpmDev, err := tpmk.OpenDevice(tpmDevFilename)
if err != nil {
return errors.Wrap(err, "opening TPM device")
}
tpmHandleInt, err := strconv.ParseUint(tpmSecretURL.Host, 0, 32)
if err != nil {
return errors.Wrap(err, "parsing TPM URI host as integer handle")
}
tpmHandle := tpmutil.Handle(tpmHandleInt)
privKey, err := tpmk.NewRSAPrivateKey(tpmDev, tpmHandle, g.passphrase)
if err != nil {
return errors.Wrap(err, "opening TPM key handle")
}
g.tpmPrivateKey = &privKey
} else {
g.secretKeyring, err = loadKeyRing(g.secretKeyringFile, false)
if err != nil {
return errors.Wrap(err, "error load secret keyring")
}
}

if g.keyRef == "" {
if g.secretKeyring == nil {
// Happens if our private key is TPM-backed; means we only have a public key
if g.keyRef == "" && len(g.publicKeyring) == 1 {
g.signer = g.publicKeyring[0]
} else if g.keyRef != "" {
g.signer = findKey(g.keyRef, g.publicKeyring)
if g.signer == nil {
return errors.Errorf("couldn't find key for key reference %+v in public keyring", g.keyRef)
}
} else {
return errors.Errorf("must either only have our signing key in the public keyring, or provide the identity of the signing key when in tpm mode")
}
} else if g.keyRef == "" {
// no key reference, pick the first key
for _, signer := range g.secretKeyring {
if !validEntity(signer) {
Expand All @@ -124,28 +194,9 @@ func (g *GoSigner) Init() error {
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 {
key := KeyFromUint64(signer.PrimaryKey.KeyId)
if key.Matches(Key(g.keyRef)) {
g.signer = signer
break
}

if !validEntity(signer) {
continue
}

for name := range signer.Identities {
if strings.Contains(name, g.keyRef) {
g.signer = signer
break pickKeyLoop
}
}
}

g.signer = findKey(g.keyRef, g.secretKeyring)
if g.signer == nil {
return errors.Errorf("couldn't find key for key reference %v", g.keyRef)
return errors.Errorf("couldn't find key for key reference %v in private keyring", g.keyRef)
}
}

Expand Down Expand Up @@ -232,9 +283,21 @@ func (g *GoSigner) DetachedSign(source string, destination string) error {
}
defer signature.Close()

err = openpgp.ArmoredDetachSign(signature, g.signer, message, g.signerConfig)
if err != nil {
return errors.Wrap(err, "error creating detached signature")
if g.tpmPrivateKey != nil {
encoder, err := armor.Encode(signature, openpgp.SignatureType, nil)
if err != nil {
return errors.Wrap(err, "error creating armoring encoder")
}
defer encoder.Close()
err = tpmk.OpenPGPDetachSign(encoder, g.signer, message, nil, g.tpmPrivateKey)
if err != nil {
return errors.Wrap(err, "error creating detached signature with TPM-backed key")
}
} else {
err = openpgp.ArmoredDetachSign(signature, g.signer, message, g.signerConfig)
if err != nil {
return errors.Wrap(err, "error creating detached signature")
}
}

return nil
Expand Down