113 lines
2.6 KiB
Go
113 lines
2.6 KiB
Go
package localserver
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
const PEM_PRIVATE_KEY = "RSA PRIVATE KEY"
|
|
const PEM_PUBLIC_KEY = "RSA PUBLIC KEY"
|
|
const OPENSSH_PRIVATE_KEY = "OPENSSH PRIVATE KEY"
|
|
|
|
type EncryptionManager struct {
|
|
PrivKey *rsa.PrivateKey
|
|
PeerKeys map[string]*rsa.PublicKey
|
|
}
|
|
|
|
func NewEncryptionManager() (eManager *EncryptionManager) {
|
|
eManager = new(EncryptionManager)
|
|
return
|
|
}
|
|
|
|
func (em *EncryptionManager) GenerateKeyPair(ctx context.Context, name string, pwd string) (privKey *rsa.PrivateKey, err error) {
|
|
privKey, err = rsa.GenerateKey(rand.Reader, 1<<12)
|
|
if err != nil {
|
|
return
|
|
}
|
|
block := &pem.Block{
|
|
Type: PEM_PRIVATE_KEY,
|
|
Bytes: x509.MarshalPKCS1PrivateKey(privKey),
|
|
}
|
|
if pwd != "" {
|
|
block, err = x509.EncryptPEMBlock(rand.Reader, block.Type, block.Bytes, []byte(pwd), x509.PEMCipherAES256)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
f, err := os.Create(filepath.Join("config", name))
|
|
if err != nil {
|
|
return
|
|
}
|
|
_, err = f.Write(pem.EncodeToMemory(block))
|
|
if err != nil {
|
|
return
|
|
}
|
|
pubBlock := &pem.Block{
|
|
Type: PEM_PUBLIC_KEY,
|
|
Bytes: x509.MarshalPKCS1PublicKey(&privKey.PublicKey),
|
|
}
|
|
if pwd != "" {
|
|
pubBlock, err = x509.EncryptPEMBlock(rand.Reader, pubBlock.Type, pubBlock.Bytes, []byte(pwd), x509.PEMCipherAES256)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
pubf, err := os.Create(filepath.Join("config", fmt.Sprintf("%s.pub", name)))
|
|
if err != nil {
|
|
return
|
|
}
|
|
_, err = pubf.Write(pem.EncodeToMemory(pubBlock))
|
|
return
|
|
}
|
|
|
|
func (em *EncryptionManager) LoadPrivKey(privKeyPath string, password string) (err error) {
|
|
f, err := os.Open(privKeyPath)
|
|
if err != nil {
|
|
return
|
|
}
|
|
var buff []byte
|
|
buff, err = io.ReadAll(f)
|
|
if err != nil {
|
|
return
|
|
}
|
|
privPem, _ := pem.Decode(buff)
|
|
var privePemBytes []byte
|
|
if privPem.Type != PEM_PRIVATE_KEY && privPem.Type != OPENSSH_PRIVATE_KEY {
|
|
logger.Println(privPem.Type)
|
|
err = fmt.Errorf("RSA Private key is of wrong type")
|
|
return
|
|
}
|
|
if password != "" {
|
|
privePemBytes, err = x509.DecryptPEMBlock(privPem, []byte(password))
|
|
} else {
|
|
privePemBytes = privPem.Bytes
|
|
}
|
|
var parsedKey interface{}
|
|
if parsedKey, err = x509.ParsePKCS1PrivateKey(privePemBytes); err != nil {
|
|
logger.Printf("error one %v\n", err)
|
|
if parsedKey, err = x509.ParsePKCS8PrivateKey(privePemBytes); err != nil {
|
|
logger.Printf("error on parsing %v\n", err)
|
|
if parsedKey, err = x509.ParseECPrivateKey(privePemBytes); err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
}
|
|
var privKey *rsa.PrivateKey
|
|
var ok bool
|
|
privKey, ok = parsedKey.(*rsa.PrivateKey)
|
|
if !ok {
|
|
err = fmt.Errorf("Unable to parse this private key")
|
|
return
|
|
}
|
|
em.PrivKey = privKey
|
|
return
|
|
}
|