package pki

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/x509"
	"encoding/pem"
	"os"
)

var PKIDir string

func GeneratePrivKey() (pub *ecdsa.PublicKey, priv *ecdsa.PrivateKey, err error) {
	if priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader); err == nil {
		pub = &priv.PublicKey
	}
	return
}

func saveCertificate(path string, cert []byte) error {
	if certOut, err := os.Create(path); err != nil {
		return err
	} else {
		pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: cert})
		certOut.Close()
	}
	return nil
}

func savePrivateKey(path string, private *ecdsa.PrivateKey) error {
	if keyOut, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600); err != nil {
		return err
	} else if key_b, err := x509.MarshalECPrivateKey(private); err != nil {
		return err
	} else {
		pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: key_b})
		keyOut.Close()
	}
	return nil
}

func savePrivateKeyEncrypted(path string, private *ecdsa.PrivateKey, password string) error {
	if password == "" {
		return savePrivateKey(path, private)
	}

	if keyOut, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600); err != nil {
		return err
	} else {
		defer keyOut.Close()

		if key_b, err := x509.MarshalECPrivateKey(private); err != nil {
			return err
		} else if key_c, err := x509.EncryptPEMBlock(rand.Reader, "EC PRIVATE KEY", key_b, []byte(password), x509.PEMCipherAES256); err != nil {
			return err
		} else {
			pem.Encode(keyOut, key_c)
		}
	}
	return nil
}
