2020-03-03 22:20:07 +01:00
|
|
|
package widgets
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
|
2020-05-27 07:37:02 +02:00
|
|
|
"git.sr.ht/~sircmpwn/aerc/config"
|
2020-03-03 22:20:07 +01:00
|
|
|
"git.sr.ht/~sircmpwn/aerc/lib/ui"
|
|
|
|
|
|
|
|
"golang.org/x/crypto/openpgp"
|
|
|
|
pgperrors "golang.org/x/crypto/openpgp/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PGPInfo struct {
|
|
|
|
ui.Invalidatable
|
2020-05-27 07:37:02 +02:00
|
|
|
details *openpgp.MessageDetails
|
|
|
|
uiConfig config.UIConfig
|
2020-03-03 22:20:07 +01:00
|
|
|
}
|
|
|
|
|
2020-05-27 07:37:02 +02:00
|
|
|
func NewPGPInfo(details *openpgp.MessageDetails, uiConfig config.UIConfig) *PGPInfo {
|
|
|
|
return &PGPInfo{details: details, uiConfig: uiConfig}
|
2020-03-03 22:20:07 +01:00
|
|
|
}
|
|
|
|
|
2020-03-04 01:02:27 +01:00
|
|
|
func (p *PGPInfo) DrawSignature(ctx *ui.Context) {
|
2020-05-27 07:37:02 +02:00
|
|
|
errorStyle := p.uiConfig.GetStyle(config.STYLE_ERROR)
|
|
|
|
warningStyle := p.uiConfig.GetStyle(config.STYLE_WARNING)
|
|
|
|
validStyle := p.uiConfig.GetStyle(config.STYLE_SUCCESS)
|
|
|
|
defaultStyle := p.uiConfig.GetStyle(config.STYLE_DEFAULT)
|
2020-03-03 22:20:07 +01:00
|
|
|
|
|
|
|
// TODO: Nicer prompt for TOFU, fetch from keyserver, etc
|
|
|
|
if errors.Is(p.details.SignatureError, pgperrors.ErrUnknownIssuer) ||
|
|
|
|
p.details.SignedBy == nil {
|
|
|
|
|
2020-05-27 07:37:02 +02:00
|
|
|
x := ctx.Printf(0, 0, warningStyle, "*")
|
|
|
|
x += ctx.Printf(x, 0, defaultStyle,
|
2020-03-03 22:20:07 +01:00
|
|
|
" Signed with unknown key (%8X); authenticity unknown",
|
|
|
|
p.details.SignedByKeyId)
|
|
|
|
} else if p.details.SignatureError != nil {
|
2020-03-04 01:02:27 +01:00
|
|
|
x := ctx.Printf(0, 0, errorStyle, "Invalid signature!")
|
2020-05-27 07:37:02 +02:00
|
|
|
x += ctx.Printf(x, 0, errorStyle,
|
2020-03-03 22:20:07 +01:00
|
|
|
" This message may have been tampered with! (%s)",
|
|
|
|
p.details.SignatureError.Error())
|
|
|
|
} else {
|
|
|
|
entity := p.details.SignedBy.Entity
|
2020-05-19 13:06:49 +02:00
|
|
|
ident := entity.PrimaryIdentity()
|
|
|
|
|
2020-03-04 03:49:29 +01:00
|
|
|
x := ctx.Printf(0, 0, validStyle, "✓ Authentic ")
|
2020-05-27 07:37:02 +02:00
|
|
|
x += ctx.Printf(x, 0, defaultStyle,
|
2020-03-04 03:49:29 +01:00
|
|
|
"Signature from %s (%8X)",
|
2020-03-04 01:02:27 +01:00
|
|
|
ident.Name, p.details.SignedByKeyId)
|
2020-03-03 22:20:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PGPInfo) DrawEncryption(ctx *ui.Context, y int) {
|
2020-05-27 07:37:02 +02:00
|
|
|
validStyle := p.uiConfig.GetStyle(config.STYLE_SUCCESS)
|
|
|
|
defaultStyle := p.uiConfig.GetStyle(config.STYLE_DEFAULT)
|
2020-03-03 22:20:07 +01:00
|
|
|
entity := p.details.DecryptedWith.Entity
|
2020-05-19 13:06:49 +02:00
|
|
|
ident := entity.PrimaryIdentity()
|
2020-03-03 22:20:07 +01:00
|
|
|
|
2020-03-04 03:49:29 +01:00
|
|
|
x := ctx.Printf(0, y, validStyle, "✓ Encrypted ")
|
2020-05-27 07:37:02 +02:00
|
|
|
x += ctx.Printf(x, y, defaultStyle,
|
2020-03-04 03:49:29 +01:00
|
|
|
"To %s (%8X) ", ident.Name, p.details.DecryptedWith.PublicKey.KeyId)
|
2020-03-03 22:20:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PGPInfo) Draw(ctx *ui.Context) {
|
2020-05-27 07:37:02 +02:00
|
|
|
defaultStyle := p.uiConfig.GetStyle(config.STYLE_DEFAULT)
|
|
|
|
ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', defaultStyle)
|
2020-03-03 22:20:07 +01:00
|
|
|
if p.details.IsSigned && p.details.IsEncrypted {
|
2020-03-04 01:02:27 +01:00
|
|
|
p.DrawSignature(ctx)
|
2020-03-03 22:20:07 +01:00
|
|
|
p.DrawEncryption(ctx, 1)
|
|
|
|
} else if p.details.IsSigned {
|
2020-03-04 01:02:27 +01:00
|
|
|
p.DrawSignature(ctx)
|
2020-03-03 22:20:07 +01:00
|
|
|
} else if p.details.IsEncrypted {
|
|
|
|
p.DrawEncryption(ctx, 0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PGPInfo) Invalidate() {
|
|
|
|
p.DoInvalidate(p)
|
|
|
|
}
|