64 lines
1.4 KiB
Go
64 lines
1.4 KiB
Go
|
|
package age
|
||
|
|
|
||
|
|
import (
|
||
|
|
"crypto/ed25519"
|
||
|
|
"io"
|
||
|
|
|
||
|
|
"filippo.io/age"
|
||
|
|
"filippo.io/age/armor"
|
||
|
|
"github.com/neilalexander/yggmail/internal/utils"
|
||
|
|
"github.com/neilalexander/yggmail/internal/utils/age/bech32"
|
||
|
|
)
|
||
|
|
|
||
|
|
func Recipient(pub ...ed25519.PublicKey) (rcpt []age.Recipient, err error) {
|
||
|
|
for _, p := range pub {
|
||
|
|
x, _ := utils.PubEd25519ToX25519(p)
|
||
|
|
s, _ := bech32.Encode("age", x)
|
||
|
|
r, err := age.ParseX25519Recipient(s)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
rcpt = append(rcpt, r)
|
||
|
|
}
|
||
|
|
return rcpt, nil
|
||
|
|
}
|
||
|
|
func Identity(pub ed25519.PrivateKey) (age.Identity, error) {
|
||
|
|
p, _ := utils.PrivEd25519ToX25519(pub)
|
||
|
|
s, _ := bech32.Encode("AGE-SECRET-KEY-", p)
|
||
|
|
return age.ParseX25519Identity(s)
|
||
|
|
}
|
||
|
|
|
||
|
|
type armorCloseWrapper struct {
|
||
|
|
io.WriteCloser // age writer
|
||
|
|
armorWriter io.WriteCloser
|
||
|
|
}
|
||
|
|
|
||
|
|
func (w *armorCloseWrapper) Close() error {
|
||
|
|
if err := w.WriteCloser.Close(); err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return w.armorWriter.Close()
|
||
|
|
}
|
||
|
|
|
||
|
|
func EncryptArmor(w io.Writer, i ...age.Recipient) (io.WriteCloser, error) {
|
||
|
|
aw := armor.NewWriter(w)
|
||
|
|
ew, err := age.Encrypt(aw, i...)
|
||
|
|
if err != nil {
|
||
|
|
aw.Close()
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
return &armorCloseWrapper{ew, aw}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func DecryptArmor(r io.Reader, i ...age.Identity) (io.Reader, error) {
|
||
|
|
r = armor.NewReader(r)
|
||
|
|
return Decrypt(r, i...)
|
||
|
|
}
|
||
|
|
|
||
|
|
func Encrypt(w io.Writer, i ...age.Recipient) (io.WriteCloser, error) {
|
||
|
|
return age.Encrypt(w, i...)
|
||
|
|
}
|
||
|
|
func Decrypt(r io.Reader, i ...age.Identity) (io.Reader, error) {
|
||
|
|
return age.Decrypt(r, i...)
|
||
|
|
}
|