diff options
Diffstat (limited to 'internal/cryptokit/age.go')
| -rw-r--r-- | internal/cryptokit/age.go | 91 |
1 files changed, 0 insertions, 91 deletions
diff --git a/internal/cryptokit/age.go b/internal/cryptokit/age.go deleted file mode 100644 index 525b1fa..0000000 --- a/internal/cryptokit/age.go +++ /dev/null @@ -1,91 +0,0 @@ -package cryptokit - -import ( - "bytes" - "errors" - "fmt" - "io" - "strings" - - "filippo.io/age" - "filippo.io/age/agessh" - agearmor "filippo.io/age/armor" -) - -const maxCryptoMessageBytes = 64 << 20 - -func parseAgeRecipient(value string) (age.Recipient, error) { - value = strings.TrimSpace(value) - if recipient, err := age.ParseX25519Recipient(value); err == nil { - return recipient, nil - } - if recipient, err := agessh.ParseRecipient(value); err == nil { - return recipient, nil - } - return nil, errors.New("unsupported age recipient: expected native X25519 or SSH Ed25519/RSA") -} - -func parseAgeIdentity(value string) (age.Identity, error) { - value = strings.TrimSpace(value) - if identity, err := age.ParseX25519Identity(value); err == nil { - return identity, nil - } - if identity, err := agessh.ParseIdentity([]byte(value)); err == nil { - return identity, nil - } - return nil, errors.New("unsupported age identity: expected native X25519 or SSH Ed25519/RSA private key") -} - -// EncryptAge encrypts to a user-provided native age X25519 recipient or SSH -// Ed25519/RSA recipient and returns ASCII-armored age text. -func EncryptAge(message []byte, recipientKey string) ([]byte, error) { - recipient, err := parseAgeRecipient(recipientKey) - if err != nil { - return nil, fmt.Errorf("parse age recipient: %w", err) - } - var output bytes.Buffer - armored := agearmor.NewWriter(&output) - writer, err := age.Encrypt(armored, recipient) - if err != nil { - _ = armored.Close() - return nil, fmt.Errorf("create age encryption: %w", err) - } - if _, err := writer.Write(message); err != nil { - _ = writer.Close() - _ = armored.Close() - return nil, fmt.Errorf("write age message: %w", err) - } - if err := writer.Close(); err != nil { - _ = armored.Close() - return nil, fmt.Errorf("close age message: %w", err) - } - if err := armored.Close(); err != nil { - return nil, fmt.Errorf("close age armor: %w", err) - } - return output.Bytes(), nil -} - -// DecryptAge decrypts an armored or binary age message with a user-provided -// native X25519 identity or an unencrypted SSH Ed25519/RSA private key. -func DecryptAge(message []byte, identityKey string) ([]byte, error) { - identity, err := parseAgeIdentity(identityKey) - if err != nil { - return nil, fmt.Errorf("parse age identity: %w", err) - } - var input io.Reader = bytes.NewReader(message) - if bytes.HasPrefix(bytes.TrimSpace(message), []byte(agearmor.Header)) { - input = agearmor.NewReader(input) - } - reader, err := age.Decrypt(input, identity) - if err != nil { - return nil, fmt.Errorf("create age decryption: %w", err) - } - plaintext, err := io.ReadAll(io.LimitReader(reader, maxCryptoMessageBytes+1)) - if err != nil { - return nil, fmt.Errorf("read age message: %w", err) - } - if len(plaintext) > maxCryptoMessageBytes { - return nil, errors.New("decrypted age message exceeds the 64 MiB limit") - } - return plaintext, nil -} |
