cmd/age: add -e and support encrypting with -i

This will come in handy for symmetric plugins, but make it require an
explicit -e so that missing a -d can't cause a mistaken encryption.
This commit is contained in:
Filippo Valsorda
2021-03-09 20:02:53 -05:00
committed by Filippo Valsorda
parent 801a7e8b33
commit 732f3e8a94
5 changed files with 86 additions and 13 deletions

View File

@@ -102,6 +102,13 @@ func NewRSAIdentity(key *rsa.PrivateKey) (*RSAIdentity, error) {
return i, nil
}
func (i *RSAIdentity) Recipient() age.Recipient {
return &RSARecipient{
sshKey: i.sshKey,
pubKey: &i.k.PublicKey,
}
}
func (i *RSAIdentity) Unwrap(stanzas []*age.Stanza) ([]byte, error) {
return multiUnwrap(i.unwrap, stanzas)
}
@@ -303,6 +310,13 @@ func ed25519PrivateKeyToCurve25519(pk ed25519.PrivateKey) []byte {
return out[:curve25519.ScalarSize]
}
func (i *Ed25519Identity) Recipient() age.Recipient {
return &Ed25519Recipient{
sshKey: i.sshKey,
theirPublicKey: i.ourPublicKey,
}
}
func (i *Ed25519Identity) Unwrap(stanzas []*age.Stanza) ([]byte, error) {
return multiUnwrap(i.unwrap, stanzas)
}

View File

@@ -11,6 +11,7 @@ import (
"crypto/ed25519"
"crypto/rand"
"crypto/rsa"
"reflect"
"testing"
"filippo.io/age/agessh"
@@ -36,6 +37,11 @@ func TestSSHRSARoundTrip(t *testing.T) {
t.Fatal(err)
}
// TODO: replace this with (and go-diff) with go-cmp.
if !reflect.DeepEqual(r, i.Recipient()) {
t.Fatalf("i.Recipient is different from r")
}
fileKey := make([]byte, 16)
if _, err := rand.Read(fileKey); err != nil {
t.Fatal(err)
@@ -74,6 +80,11 @@ func TestSSHEd25519RoundTrip(t *testing.T) {
t.Fatal(err)
}
// TODO: replace this with (and go-diff) with go-cmp.
if !reflect.DeepEqual(r, i.Recipient()) {
t.Fatalf("i.Recipient is different from r")
}
fileKey := make([]byte, 16)
if _, err := rand.Read(fileKey); err != nil {
t.Fatal(err)

View File

@@ -55,6 +55,10 @@ func NewEncryptedSSHIdentity(pubKey ssh.PublicKey, pemBytes []byte, passphrase f
var _ age.Identity = &EncryptedSSHIdentity{}
func (i *EncryptedSSHIdentity) Recipient() (age.Recipient, error) {
return ParseRecipient(string(ssh.MarshalAuthorizedKey(i.pubKey)))
}
// Unwrap implements age.Identity. If the private key is still encrypted, and
// any of the stanzas match the public key, it will request the passphrase. The
// decrypted private key will be cached after the first successful invocation.