From 384d0393e0797c8e6a6a2a44f4184958c3c04a97 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Tue, 20 Apr 2021 01:35:45 -0400 Subject: [PATCH] internal/plugin,cmd/age: add support for encrypting to plugin identities --- agessh/agessh.go | 4 ++-- cmd/age/age.go | 3 +++ internal/plugin/client.go | 22 +++++++++++++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/agessh/agessh.go b/agessh/agessh.go index 2e6a7c6..27b463d 100644 --- a/agessh/agessh.go +++ b/agessh/agessh.go @@ -103,7 +103,7 @@ func NewRSAIdentity(key *rsa.PrivateKey) (*RSAIdentity, error) { return i, nil } -func (i *RSAIdentity) Recipient() age.Recipient { +func (i *RSAIdentity) Recipient() *RSARecipient { return &RSARecipient{ sshKey: i.sshKey, pubKey: &i.k.PublicKey, @@ -288,7 +288,7 @@ func ed25519PrivateKeyToCurve25519(pk ed25519.PrivateKey) []byte { return out[:curve25519.ScalarSize] } -func (i *Ed25519Identity) Recipient() age.Recipient { +func (i *Ed25519Identity) Recipient() *Ed25519Recipient { return &Ed25519Recipient{ sshKey: i.sshKey, theirPublicKey: i.ourPublicKey, diff --git a/cmd/age/age.go b/cmd/age/age.go index 29747a6..1717c0e 100644 --- a/cmd/age/age.go +++ b/cmd/age/age.go @@ -19,6 +19,7 @@ import ( "filippo.io/age" "filippo.io/age/agessh" "filippo.io/age/armor" + "filippo.io/age/internal/plugin" "golang.org/x/term" ) @@ -402,6 +403,8 @@ func identitiesToRecipients(ids []age.Identity) ([]age.Recipient, error) { switch id := id.(type) { case *age.X25519Identity: recipients = append(recipients, id.Recipient()) + case *plugin.Identity: + recipients = append(recipients, id.Recipient()) case *agessh.RSAIdentity: recipients = append(recipients, id.Recipient()) case *agessh.Ed25519Identity: diff --git a/internal/plugin/client.go b/internal/plugin/client.go index cd8533a..21e2973 100644 --- a/internal/plugin/client.go +++ b/internal/plugin/client.go @@ -27,6 +27,9 @@ type Recipient struct { name string encoding string + // identity is true when encoding is an identity string. + identity bool + // DisplayMessage is a callback that will be invoked by Wrap if the plugin // wishes to display a message to the user. If DisplayMessage is nil or // returns an error, failure will be reported to the plugin. @@ -73,11 +76,14 @@ func (r *Recipient) Wrap(fileKey []byte) (stanzas []*age.Stanza, err error) { } defer conn.Close() - // Phase 1: client sends recipient and file key + // Phase 1: client sends recipient or identity and file key s := &format.Stanza{ Type: "add-recipient", Args: []string{r.encoding}, } + if r.identity { + s.Type = "add-identity" + } if err := s.Marshal(conn); err != nil { return nil, err } @@ -231,6 +237,20 @@ func (i *Identity) Name() string { return i.name } +// Recipient returns a Recipient wrapping this identity. When that Recipient is +// used to encrypt a file key, the identity encoding is provided as-is to the +// plugin, which is expected to support encrypting to identities. +func (i *Identity) Recipient() *Recipient { + return &Recipient{ + name: i.name, + encoding: i.encoding, + identity: true, + + DisplayMessage: i.DisplayMessage, + RequestValue: i.RequestValue, + } +} + func (i *Identity) Unwrap(stanzas []*age.Stanza) (fileKey []byte, err error) { defer func() { if err != nil {