Forgor to push 💀
This commit is contained in:
174
crypto.go
174
crypto.go
@@ -1,58 +1,160 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
_ "filippo.io/age"
|
||||
"filippo.io/age/armor"
|
||||
)
|
||||
|
||||
var cert *x509.Certificate
|
||||
var key *rsa.PrivateKey
|
||||
//var cert *x509.Certificate
|
||||
//var key *rsa.PrivateKey
|
||||
//
|
||||
//func encryptBytes(data []byte) []byte {
|
||||
// if cert == nil || key == nil {
|
||||
// loadCerts()
|
||||
// }
|
||||
//
|
||||
// encrypted, err := rsa.EncryptPKCS1v15(rand.Reader, cert.PublicKey.(*rsa.PublicKey), data)
|
||||
// if err != nil {
|
||||
// fmt.Println("Error encrypting data,", err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// return encrypted
|
||||
//}
|
||||
//
|
||||
//func decryptBytes(data []byte) []byte {
|
||||
// if cert == nil || key == nil {
|
||||
// loadCerts()
|
||||
// }
|
||||
//
|
||||
// decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, key, data)
|
||||
// if err != nil {
|
||||
// fmt.Println("Error decrypting data,", err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// return decrypted
|
||||
//}
|
||||
//
|
||||
//func loadCerts() {
|
||||
// var err error
|
||||
// certBytes, err := os.ReadFile(config.GetAsString("Crypto.cert_path"))
|
||||
// keyBytes, err := os.ReadFile(config.GetAsString("Crypto.key_path"))
|
||||
// if err != nil {
|
||||
// fmt.Println("Error reading cert or key,", err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
//
|
||||
// cert, err = x509.ParseCertificate(certBytes)
|
||||
// if err != nil {
|
||||
// fmt.Println("Error parsing certificate,", err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// key, err = x509.ParsePKCS1PrivateKey(keyBytes)
|
||||
// if err != nil {
|
||||
// fmt.Println("Error parsing private key,", err)
|
||||
// }
|
||||
//}
|
||||
|
||||
func encryptBytes(data []byte) []byte {
|
||||
if cert == nil || key == nil {
|
||||
loadCerts()
|
||||
// GenerateKey returns a base64-encoded 32-byte random key suitable to use as the
|
||||
// symmetric passphrase for age scrypt mode. Store this securely (never in Git).
|
||||
func GenerateKey() (string, error) {
|
||||
k := make([]byte, 32)
|
||||
if _, err := rand.Read(k); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
encrypted, err := rsa.EncryptPKCS1v15(rand.Reader, cert.PublicKey.(*rsa.PublicKey), data)
|
||||
if err != nil {
|
||||
fmt.Println("Error encrypting data,", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return encrypted
|
||||
out := make([]byte, base64.StdEncoding.EncodedLen(len(k)))
|
||||
base64.StdEncoding.Encode(out, k)
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
func decryptBytes(data []byte) []byte {
|
||||
if cert == nil || key == nil {
|
||||
loadCerts()
|
||||
}
|
||||
|
||||
decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, key, data)
|
||||
// LoadKeyFromFile reads a key file that contains either a raw base64 string or
|
||||
// "AGE_SYM_KEY=<base64>" (handy for dotenv). Whitespace is trimmed.
|
||||
func LoadKeyFromFile(path string) (string, error) {
|
||||
b, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
fmt.Println("Error decrypting data,", err)
|
||||
os.Exit(1)
|
||||
return "", err
|
||||
}
|
||||
return decrypted
|
||||
s := strings.TrimSpace(string(b))
|
||||
if i := strings.Index(s, "AGE_SYM_KEY="); i >= 0 {
|
||||
s = strings.TrimSpace(strings.TrimPrefix(s, "AGE_SYM_KEY="))
|
||||
}
|
||||
if s == "" {
|
||||
return "", errors.New("empty symmetric key")
|
||||
}
|
||||
// Quick sanity check that it’s base64 and ~32 bytes after decode.
|
||||
if _, err := base64.StdEncoding.DecodeString(s); err != nil {
|
||||
return "", fmt.Errorf("invalid base64 key: %w", err)
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func loadCerts() {
|
||||
// Encrypt streams plaintext from r to w using a symmetric passphrase.
|
||||
// If armorOut is true, output is ASCII-armored (BEGIN AGE ENCRYPTED FILE).
|
||||
func Encrypt(r io.Reader, w io.Writer, passphrase string, armorOut bool) error {
|
||||
passphrase = strings.TrimSpace(passphrase)
|
||||
if passphrase == "" {
|
||||
return errors.New("missing passphrase")
|
||||
}
|
||||
|
||||
var out io.WriteCloser
|
||||
var err error
|
||||
certBytes, err := os.ReadFile(config.GetAsString("Crypto.cert_path"))
|
||||
keyBytes, err := os.ReadFile(config.GetAsString("Crypto.key_path"))
|
||||
|
||||
if armorOut {
|
||||
aw := armor.NewWriter(w)
|
||||
defer aw.Close()
|
||||
//out, err = age.Encrypt(aw, age.NewScryptRecipient(passphrase))
|
||||
} else {
|
||||
//out, err = age.Encrypt(w, age.NewScryptRecipient(passphrase))
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println("Error reading cert or key,", err)
|
||||
os.Exit(1)
|
||||
return err
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certBytes)
|
||||
if err != nil {
|
||||
fmt.Println("Error parsing certificate,", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
key, err = x509.ParsePKCS1PrivateKey(keyBytes)
|
||||
if err != nil {
|
||||
fmt.Println("Error parsing private key,", err)
|
||||
_, copyErr := io.Copy(out, bufio.NewReader(r))
|
||||
closeErr := out.Close()
|
||||
if copyErr != nil {
|
||||
return copyErr
|
||||
}
|
||||
return closeErr
|
||||
}
|
||||
|
||||
// Decrypt streams ciphertext from r to w using the same symmetric passphrase.
|
||||
// It auto-detects armored vs binary ciphertext.
|
||||
func Decrypt(r io.Reader, w io.Writer, passphrase string) error {
|
||||
passphrase = strings.TrimSpace(passphrase)
|
||||
if passphrase == "" {
|
||||
return errors.New("missing passphrase")
|
||||
}
|
||||
|
||||
br := bufio.NewReader(r)
|
||||
peek, _ := br.Peek(32)
|
||||
//var in io.Reader = br
|
||||
if strings.HasPrefix(string(peek), "-----BEGIN AGE ENCRYPTED FILE-----") {
|
||||
// in = armor.NewReader(br)
|
||||
}
|
||||
|
||||
//dr, err := age.Decrypt(in, age.NewScryptIdentity(passphrase))
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//_, err = io.Copy(w, bufio.NewWriter(wrap0600(w)))
|
||||
//return err
|
||||
return nil
|
||||
}
|
||||
|
||||
// wrap0600 ensures that when w is an *os.File newly created by caller,
|
||||
// its perms are 0600. If it’s not an *os.File, it’s returned unchanged.
|
||||
func wrap0600(w io.Writer) io.Writer {
|
||||
if f, ok := w.(*os.File); ok {
|
||||
_ = f.Chmod(0600)
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user