fckeuspy-go/lib/crypto.go
2025-09-24 22:13:03 +02:00

75 lines
1.9 KiB
Go

package encrypt
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"errors"
"fmt"
"math/big"
"time"
)
// No envelope here; server/UI define their own payload structs.
func parsePeerPublicKey(pemOrCert string) (*rsa.PublicKey, error) {
block, _ := pem.Decode([]byte(pemOrCert))
if block == nil {
return nil, errors.New("no PEM block found")
}
switch block.Type {
case "PUBLIC KEY":
k, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
rsaPub, ok := k.(*rsa.PublicKey)
if !ok {
return nil, errors.New("expecting RSA PUBLIC KEY")
}
return rsaPub, nil
case "RSA PUBLIC KEY":
return x509.ParsePKCS1PublicKey(block.Bytes)
case "CERTIFICATE":
c, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, err
}
rsaPub, ok := c.PublicKey.(*rsa.PublicKey)
if !ok {
return nil, errors.New("certificate does not contain RSA key")
}
return rsaPub, nil
default:
return nil, fmt.Errorf("unsupported PEM type: %s", block.Type)
}
}
func ParsePeerPublicKey(pemOrCert string) (*rsa.PublicKey, error) {
return parsePeerPublicKey(pemOrCert)
}
func generateSelfSignedCert(priv *rsa.PrivateKey, commonName string) ([]byte, error) {
if commonName == "" {
commonName = "Encryptor Local Identity"
}
tpl := &x509.Certificate{
SerialNumber: big.NewInt(time.Now().UnixNano()),
Subject: pkix.Name{CommonName: commonName},
NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().AddDate(1, 0, 0),
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
BasicConstraintsValid: true,
}
der, err := x509.CreateCertificate(rand.Reader, tpl, tpl, &priv.PublicKey, priv)
if err != nil {
return nil, err
}
buf := &bytes.Buffer{}
_ = pem.Encode(buf, &pem.Block{Type: "CERTIFICATE", Bytes: der})
return buf.Bytes(), nil
}