From d09636ee0b9957ed60fc01224ddfbb03c4f4b7fa Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Mon, 25 Apr 2022 08:30:43 -0500 Subject: refactor: refactor pgp implementation This commit refactors the internal PGP implementation to make way for GPG integration. Signed-off-by: Tim Culverhouse Acked-by: Koni Marti Acked-by: Robin Jarry --- widgets/aerc.go | 10 +++++++--- widgets/compose.go | 51 +++++---------------------------------------------- widgets/msglist.go | 3 ++- widgets/msgviewer.go | 8 ++++---- widgets/pgpinfo.go | 27 +++++++++------------------ 5 files changed, 27 insertions(+), 72 deletions(-) (limited to 'widgets') diff --git a/widgets/aerc.go b/widgets/aerc.go index 717547d..0b4e36d 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -16,6 +16,7 @@ import ( "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib" + "git.sr.ht/~rjarry/aerc/lib/crypto" "git.sr.ht/~rjarry/aerc/lib/ui" "git.sr.ht/~rjarry/aerc/models" ) @@ -38,6 +39,8 @@ type Aerc struct { ui *ui.UI beep func() error dialog ui.DrawableInteractive + + Crypto crypto.Provider } type Choice struct { @@ -47,9 +50,9 @@ type Choice struct { } func NewAerc(conf *config.AercConfig, logger *log.Logger, - cmd func(cmd []string) error, complete func(cmd string) []string, - cmdHistory lib.History, deferLoop chan struct{}, -) *Aerc { + crypto crypto.Provider, cmd func(cmd []string) error, + complete func(cmd string) []string, cmdHistory lib.History, + deferLoop chan struct{}) *Aerc { tabs := ui.NewTabs(&conf.Ui) statusbar := ui.NewStack(conf.Ui) @@ -79,6 +82,7 @@ func NewAerc(conf *config.AercConfig, logger *log.Logger, statusline: statusline, prompts: ui.NewStack(conf.Ui), tabs: tabs, + Crypto: crypto, } statusline.SetAerc(aerc) diff --git a/widgets/compose.go b/widgets/compose.go index 5f2c706..6298be3 100644 --- a/widgets/compose.go +++ b/widgets/compose.go @@ -15,9 +15,7 @@ import ( "strings" "time" - "github.com/ProtonMail/go-crypto/openpgp" "github.com/emersion/go-message/mail" - "github.com/emersion/go-pgpmail" "github.com/gdamore/tcell/v2" "github.com/mattn/go-runewidth" "github.com/mitchellh/go-homedir" @@ -25,7 +23,6 @@ import ( "git.sr.ht/~rjarry/aerc/completer" "git.sr.ht/~rjarry/aerc/config" - "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib/format" "git.sr.ht/~rjarry/aerc/lib/templates" "git.sr.ht/~rjarry/aerc/lib/ui" @@ -455,38 +452,27 @@ func (c *Composer) WriteMessage(header *mail.Header, writer io.Writer) error { var cleartext io.WriteCloser var err error - var signer *openpgp.Entity + var signerEmail string if c.sign { - signer, err = getSigner(c) + signerEmail, err = getSenderEmail(c) if err != nil { return err } } else { - signer = nil + signerEmail = "" } if c.encrypt { - var to []*openpgp.Entity rcpts, err := getRecipientsEmail(c) if err != nil { return err } - for _, rcpt := range rcpts { - toEntity, err := lib.GetEntityByEmail(rcpt) - if err != nil { - return errors.Wrap(err, "no key for "+rcpt) - } - to = append(to, toEntity) - } - cleartext, err = pgpmail.Encrypt(&buf, header.Header.Header, - to, signer, nil) - + cleartext, err = c.aerc.Crypto.Encrypt(&buf, rcpts, signerEmail, c.aerc.DecryptKeys, header) if err != nil { return err } } else { - cleartext, err = pgpmail.Sign(&buf, header.Header.Header, - signer, nil) + cleartext, err = c.aerc.Crypto.Sign(&buf, signerEmail, c.aerc.DecryptKeys, header) if err != nil { return err } @@ -1031,30 +1017,3 @@ func (rm *reviewMessage) OnInvalidate(fn func(ui.Drawable)) { func (rm *reviewMessage) Draw(ctx *ui.Context) { rm.grid.Draw(ctx) } - -func getSigner(c *Composer) (signer *openpgp.Entity, err error) { - signerEmail, err := getSenderEmail(c) - if err != nil { - return nil, err - } - signer, err = lib.GetSignerEntityByEmail(signerEmail) - if err != nil { - return nil, err - } - - key, ok := signer.SigningKey(time.Now()) - if !ok { - return nil, fmt.Errorf("no signing key found for %s", signerEmail) - } - - if !key.PrivateKey.Encrypted { - return signer, nil - } - - _, err = c.aerc.DecryptKeys([]openpgp.Key{key}, false) - if err != nil { - return nil, err - } - - return signer, nil -} diff --git a/widgets/msglist.go b/widgets/msglist.go index 5eee7ed..df24526 100644 --- a/widgets/msglist.go +++ b/widgets/msglist.go @@ -295,7 +295,8 @@ func (ml *MessageList) MouseEvent(localX int, localY int, event tcell.Event) { if msg == nil { return } - lib.NewMessageStoreView(msg, store, ml.aerc.DecryptKeys, + lib.NewMessageStoreView(msg, store, ml.aerc.Crypto, + ml.aerc.DecryptKeys, func(view lib.MessageView, err error) { if err != nil { ml.aerc.PushError(err.Error()) diff --git a/widgets/msgviewer.go b/widgets/msgviewer.go index 89cbc2c..c88c981 100644 --- a/widgets/msgviewer.go +++ b/widgets/msgviewer.go @@ -75,9 +75,9 @@ func NewMessageViewer(acct *AccountView, {Strategy: ui.SIZE_EXACT, Size: ui.Const(headerHeight)}, } - if msg.PGPDetails() != nil { + if msg.MessageDetails() != nil { height := 1 - if msg.PGPDetails().IsSigned && msg.PGPDetails().IsEncrypted { + if msg.MessageDetails().IsSigned && msg.MessageDetails().IsEncrypted { height = 2 } rows = append(rows, ui.GridSpec{Strategy: ui.SIZE_EXACT, Size: ui.Const(height)}) @@ -107,8 +107,8 @@ func NewMessageViewer(acct *AccountView, borderChar := acct.UiConfig().BorderCharHorizontal grid.AddChild(header).At(0, 0) - if msg.PGPDetails() != nil { - grid.AddChild(NewPGPInfo(msg.PGPDetails(), acct.UiConfig())).At(1, 0) + if msg.MessageDetails() != nil { + grid.AddChild(NewPGPInfo(msg.MessageDetails(), acct.UiConfig())).At(1, 0) grid.AddChild(ui.NewFill(borderChar, borderStyle)).At(2, 0) grid.AddChild(switcher).At(3, 0) } else { diff --git a/widgets/pgpinfo.go b/widgets/pgpinfo.go index 6c07ed9..8dc0570 100644 --- a/widgets/pgpinfo.go +++ b/widgets/pgpinfo.go @@ -1,22 +1,18 @@ package widgets import ( - "errors" - "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib/ui" - - "github.com/ProtonMail/go-crypto/openpgp" - pgperrors "github.com/ProtonMail/go-crypto/openpgp/errors" + "git.sr.ht/~rjarry/aerc/models" ) type PGPInfo struct { ui.Invalidatable - details *openpgp.MessageDetails + details *models.MessageDetails uiConfig config.UIConfig } -func NewPGPInfo(details *openpgp.MessageDetails, uiConfig config.UIConfig) *PGPInfo { +func NewPGPInfo(details *models.MessageDetails, uiConfig config.UIConfig) *PGPInfo { return &PGPInfo{details: details, uiConfig: uiConfig} } @@ -27,38 +23,33 @@ func (p *PGPInfo) DrawSignature(ctx *ui.Context) { defaultStyle := p.uiConfig.GetStyle(config.STYLE_DEFAULT) // TODO: Nicer prompt for TOFU, fetch from keyserver, etc - if errors.Is(p.details.SignatureError, pgperrors.ErrUnknownIssuer) || - p.details.SignedBy == nil { + if p.details.SignatureValidity == models.UnknownEntity || + p.details.SignedBy == "" { x := ctx.Printf(0, 0, warningStyle, "*") x += ctx.Printf(x, 0, defaultStyle, " Signed with unknown key (%8X); authenticity unknown", p.details.SignedByKeyId) - } else if p.details.SignatureError != nil { + } else if p.details.SignatureValidity != models.Valid { x := ctx.Printf(0, 0, errorStyle, "Invalid signature!") x += ctx.Printf(x, 0, errorStyle, " This message may have been tampered with! (%s)", - p.details.SignatureError.Error()) + p.details.SignatureError) } else { - entity := p.details.SignedBy.Entity - ident := entity.PrimaryIdentity() - x := ctx.Printf(0, 0, validStyle, "✓ Authentic ") x += ctx.Printf(x, 0, defaultStyle, "Signature from %s (%8X)", - ident.Name, p.details.SignedByKeyId) + p.details.SignedBy, p.details.SignedByKeyId) } } func (p *PGPInfo) DrawEncryption(ctx *ui.Context, y int) { validStyle := p.uiConfig.GetStyle(config.STYLE_SUCCESS) defaultStyle := p.uiConfig.GetStyle(config.STYLE_DEFAULT) - entity := p.details.DecryptedWith.Entity - ident := entity.PrimaryIdentity() x := ctx.Printf(0, y, validStyle, "✓ Encrypted ") x += ctx.Printf(x, y, defaultStyle, - "To %s (%8X) ", ident.Name, p.details.DecryptedWith.PublicKey.KeyId) + "To %s (%8X) ", p.details.DecryptedWith, p.details.DecryptedWithKeyId) } func (p *PGPInfo) Draw(ctx *ui.Context) { -- cgit v1.2.3