| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 | package serverctlimport (	"crypto/ed25519"	ssl "crypto/tls"	"crypto/x509"	"encoding/json"	"encoding/pem"	"errors"	"fmt"	"github.com/gravitl/netmaker/database"	"github.com/gravitl/netmaker/tls")// TlsConfig - holds this servers TLS conf in memoryvar TlsConfig ssl.Config// SaveCert - save a certificate to file and DBfunc SaveCert(path, name string, cert *x509.Certificate) error {	if err := SaveCertToDB(name, cert); err != nil {		return err	}	return tls.SaveCertToFile(path, name, cert)}// SaveCertToDB - save a certificate to the certs databasefunc SaveCertToDB(name string, cert *x509.Certificate) error {	if certBytes := pem.EncodeToMemory(&pem.Block{		Type:  "CERTIFICATE",		Bytes: cert.Raw,	}); len(certBytes) > 0 {		data, err := json.Marshal(&certBytes)		if err != nil {			return fmt.Errorf("failed to marshal certificate - %v ", err)		}		return database.Insert(name, string(data), database.CERTS_TABLE_NAME)	} else {		return fmt.Errorf("failed to write cert to DB - %s ", name)	}}// SaveKey - save a private key (ed25519) to file and DBfunc SaveKey(path, name string, key ed25519.PrivateKey) error {	if err := SaveKeyToDB(name, key); err != nil {		return err	}	return tls.SaveKeyToFile(path, name, key)}// SaveKeyToDB - save a private key (ed25519) to the specified pathfunc SaveKeyToDB(name string, key ed25519.PrivateKey) error {	privBytes, err := x509.MarshalPKCS8PrivateKey(key)	if err != nil {		return fmt.Errorf("failed to marshal key %v ", err)	}	if pemBytes := pem.EncodeToMemory(&pem.Block{		Type:  "PRIVATE KEY",		Bytes: privBytes,	}); len(pemBytes) > 0 {		data, err := json.Marshal(&pemBytes)		if err != nil {			return fmt.Errorf("failed to marshal key %v ", err)		}		return database.Insert(name, string(data), database.CERTS_TABLE_NAME)	} else {		return fmt.Errorf("failed to write key to DB - %v ", err)	}}// ReadCertFromDB - reads a certificate from the databasefunc ReadCertFromDB(name string) (*x509.Certificate, error) {	certString, err := database.FetchRecord(database.CERTS_TABLE_NAME, name)	if err != nil {		return nil, fmt.Errorf("unable to read file %w", err)	}	var certBytes []byte	if err = json.Unmarshal([]byte(certString), &certBytes); err != nil {		return nil, fmt.Errorf("unable to unmarshal db cert %w", err)	}	block, _ := pem.Decode(certBytes)	if block == nil || block.Type != "CERTIFICATE" {		return nil, errors.New("not a cert " + block.Type)	}	cert, err := x509.ParseCertificate(block.Bytes)	if err != nil {		return nil, fmt.Errorf("unable to parse cert %w", err)	}	return cert, nil}// ReadKeyFromDB - reads a private key (ed25519) from the databasefunc ReadKeyFromDB(name string) (*ed25519.PrivateKey, error) {	keyString, err := database.FetchRecord(database.CERTS_TABLE_NAME, name)	if err != nil {		return nil, fmt.Errorf("unable to read key value from db - %w", err)	}	var bytes []byte	if err = json.Unmarshal([]byte(keyString), &bytes); err != nil {		return nil, fmt.Errorf("unable to unmarshal db key - %w", err)	}	keyBytes, _ := pem.Decode(bytes)	key, err := x509.ParsePKCS8PrivateKey(keyBytes.Bytes)	if err != nil {		return nil, fmt.Errorf("unable to parse key from DB -  %w", err)	}	private := key.(ed25519.PrivateKey)	return &private, nil}// SetClientTLSConf - saves client cert for servers to connect to MQ broker withfunc SetClientTLSConf(serverClientPemPath, serverClientKeyPath string, ca *x509.Certificate) error {	certpool := x509.NewCertPool()	if caData := pem.EncodeToMemory(&pem.Block{		Type:  "CERTIFICATE",		Bytes: ca.Raw,	}); len(caData) <= 0 {		return fmt.Errorf("could not encode CA cert to memory for server client")	} else {		ok := certpool.AppendCertsFromPEM(caData)		if !ok {			return fmt.Errorf("failed to append root cert to server client cert")		}	}	clientKeyPair, err := ssl.LoadX509KeyPair(serverClientPemPath, serverClientKeyPath)	if err != nil {		return err	}	certs := []ssl.Certificate{clientKeyPair}	TlsConfig = ssl.Config{		RootCAs:            certpool,		ClientAuth:         ssl.NoClientCert,		ClientCAs:          nil,		Certificates:       certs,		InsecureSkipVerify: false,	}	return nil}
 |