// Copyright The Monogon Project Authors.
// SPDX-License-Identifier: Apache-2.0

package main

// Minimal GnuTLS certtool-like tool in Go. Implements only what's needed for
// compatibility with `swtpm_localca`.

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"log"
	"math/big"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/spf13/pflag"
)

var (
	flagGeneratePrivkey     bool
	flagGenerateSelfSigned  bool
	flagGenerateCertificate bool

	flagOutfile           string
	flagTemplate          string
	flagLoadPrivkey       string
	flagLoadCAPrivkey     string
	flagLoadCACertificate string
)

func main() {
	pflag.BoolVar(&flagGeneratePrivkey, "generate-privkey", false, "Generate RSA private kay")
	pflag.BoolVar(&flagGenerateSelfSigned, "generate-self-signed", false, "Generate self-signed certificate")
	pflag.BoolVar(&flagGenerateCertificate, "generate-certificate", false, "Sign certificate")

	pflag.StringVar(&flagOutfile, "outfile", "", "Output file for operation")
	pflag.StringVar(&flagTemplate, "template", "", "Certificate template file (GnuTLS proprietary)")
	pflag.StringVar(&flagLoadPrivkey, "load-privkey", "", "Path to private key")
	pflag.StringVar(&flagLoadCAPrivkey, "load-ca-privkey", "", "Path to CA private key")
	pflag.StringVar(&flagLoadCACertificate, "load-ca-certificate", "", "Path to CA certificate")
	pflag.Parse()

	modesActive := 0
	for _, mode := range []bool{flagGeneratePrivkey, flagGenerateSelfSigned, flagGenerateCertificate} {
		if mode {
			modesActive++
		}
	}
	if modesActive != 1 {
		log.Fatalf("Exactly one of --generate-privkey, --generate-self-signed, --generate-certificate must be set")
	}

	if flagGeneratePrivkey || flagGenerateSelfSigned || flagGenerateCertificate {
		if flagOutfile == "" {
			log.Fatalf("--outfile must be set")
		}
	}
	if flagGenerateSelfSigned || flagGenerateCertificate {
		if flagTemplate == "" {
			log.Fatalf("--template must be set")
		}
		if flagLoadPrivkey == "" {
			log.Fatalf("--load-privkey must be set")
		}
		if flagOutfile == "" {
			log.Fatalf("--outfile must be set")
		}
	}
	if flagGenerateCertificate {
		if flagLoadCAPrivkey == "" {
			log.Fatalf("--load-ca-privkey must be set")
		}
		if flagLoadCACertificate == "" {
			log.Fatalf("--load-ca-certificate must be set")
		}
	}
	switch {
	case flagGeneratePrivkey:
		generatePrivkey(flagOutfile)
	case flagGenerateSelfSigned:
		generateSelfSigned(flagTemplate, flagLoadPrivkey, flagOutfile)
	case flagGenerateCertificate:
		generateCertificate(flagTemplate, flagLoadPrivkey, flagLoadCAPrivkey, flagLoadCACertificate, flagOutfile)
	}
}

func generatePrivkey(outfile string) {
	priv, err := rsa.GenerateKey(rand.Reader, 3072)
	if err != nil {
		log.Fatalf("Could not generate RSA key: %v", err)
	}
	block := pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: x509.MarshalPKCS1PrivateKey(priv),
	}
	if err := os.WriteFile(outfile, pem.EncodeToMemory(&block), 0600); err != nil {
		log.Fatalf("Could not write RSA key: %v", err)
	}
}

// certificateFromTemplate parses a GnuTLS 'template' file. This template file is
// made up of newline-separated stanzas, with an optional 'data' part after a =
// character.
//
// Supported stanzas (on conflict last stanza wins):
//
//	cn=data: set subject CN to data
//	ca: mark certificate as CA
//	cert_signing_key: enable keyCertSign KeyUsage
//	expiration_days: number of days in which cert expires (if -1/default, no expiry date)
func certificateFromTemplate(template string) *x509.Certificate {
	serial, err := rand.Int(rand.Reader, big.NewInt(1).Lsh(big.NewInt(1), 128))
	if err != nil {
		log.Fatalf("Could not generate serial: %v", err)
	}
	res := x509.Certificate{
		SerialNumber:          serial,
		NotBefore:             time.Now().Add(-time.Minute),
		BasicConstraintsValid: true,
		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
	}
	for _, line := range strings.Split(template, "\n") {
		line = strings.TrimSpace(line)
		if line == "" {
			continue
		}
		parts := strings.SplitN(line, "=", 2)
		for i := range parts {
			parts[i] = strings.TrimSpace(parts[i])
		}
		switch parts[0] {
		case "cn":
			res.Subject.CommonName = parts[1]
		case "ca":
			res.IsCA = true
		case "cert_signing_key":
			res.KeyUsage |= x509.KeyUsageCertSign
		case "expiration_days":
			days, err := strconv.ParseInt(parts[1], 10, 64)
			if err != nil {
				log.Fatalf("Invalid expiration_days: %q", err)
			}
			if days != -1 {
				res.NotAfter = time.Now().Add(time.Hour * 24 * time.Duration(days))
			} else {
				res.NotAfter = time.Unix(253402300799, 0)
			}
		default:
			log.Fatalf("Unhandled template line %q", line)
		}
	}
	return &res
}

func readPrivkey(path string) *rsa.PrivateKey {
	bytes, err := os.ReadFile(path)
	if err != nil {
		log.Fatalf("Could not read private key: %v", err)
	}
	block, _ := pem.Decode(bytes)
	if block.Type != "RSA PRIVATE KEY" {
		log.Fatalf("Private key contains invalid PEM data")
	}
	res, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		log.Fatalf("Could not parse private key: %v", err)
	}
	return res
}

func readCertificate(path string) *x509.Certificate {
	bytes, err := os.ReadFile(path)
	if err != nil {
		log.Fatalf("Could not read certificate: %v", err)
	}
	block, _ := pem.Decode(bytes)
	if block.Type != "CERTIFICATE" {
		log.Fatalf("Certificate contains invalid PEM data")
	}
	res, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		log.Fatalf("Could not parse certificate: %v", err)
	}
	return res
}

func generateSelfSigned(templatePath, privkeyPath, outfile string) {
	template, err := os.ReadFile(templatePath)
	if err != nil {
		log.Fatalf("Could not read template: %v", err)
	}
	priv := readPrivkey(privkeyPath)
	cert := certificateFromTemplate(string(template))

	derBytes, err := x509.CreateCertificate(rand.Reader, cert, cert, priv.Public(), priv)
	if err != nil {
		log.Fatalf("Could not generate self-signed certificate: %v", err)
	}
	block := pem.Block{
		Type:  "CERTIFICATE",
		Bytes: derBytes,
	}
	if err := os.WriteFile(outfile, pem.EncodeToMemory(&block), 0600); err != nil {
		log.Fatalf("Could not write self-signed certificate: %v", err)
	}
}

func generateCertificate(templatePath, privkeyPath, caPrivkeyPath, caCertificatePath, outfile string) {
	template, err := os.ReadFile(templatePath)
	if err != nil {
		log.Fatalf("Could not read template: %v", err)
	}
	priv := readPrivkey(privkeyPath)
	caPriv := readPrivkey(caPrivkeyPath)
	cert := certificateFromTemplate(string(template))
	ca := readCertificate(caCertificatePath)

	derBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, priv.Public(), caPriv)
	if err != nil {
		log.Fatalf("Could not generate certificate: %v", err)
	}
	block := pem.Block{
		Type:  "CERTIFICATE",
		Bytes: derBytes,
	}
	if err := os.WriteFile(outfile, pem.EncodeToMemory(&block), 0600); err != nil {
		log.Fatalf("Could not write certificate: %v", err)
	}
}
