package main import ( "crypto/x509" "encoding/pem" "fmt" "log" "os" "slices" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/widget" ) func main() { a := app.NewWithID("nl.systemec.pfxgen") w := a.NewWindow("Systemec PKCS12-Generator") w.Resize(fyne.NewSize(600, 400)) var keyPath, certPath string // Labels to show selected filenames fileLabel1 := widget.NewLabel("No file selected") fileLabel2 := widget.NewLabel("No file selected") radioLabel1 := widget.NewLabel("Select which Sectigo Intermediate") // Certificate Keyfile btn1 := widget.NewButton("Upload Private Key File", func() { dialog.ShowFileOpen(func(r fyne.URIReadCloser, err error) { if r != nil { fileLabel1.SetText(r.URI().Name()) keyPath = r.URI().Path() } }, w) }) // Certificate file btn2 := widget.NewButton("Upload Certificate File", func() { dialog.ShowFileOpen(func(r fyne.URIReadCloser, err error) { if r != nil { fileLabel2.SetText(r.URI().Name()) certPath = r.URI().Path() } }, w) }) // Certificate Intermediate var newSectigoSelected bool caRadio := widget.NewRadioGroup([]string{"New Sectigo (2025+)", "Old Sectigo (2025-)"}, func(selected string) { switch selected { case "New Sectigo (2025+)": newSectigoSelected = true case "Old Sectigo (2025-)": newSectigoSelected = false default: //Fallback newSectigoSelected = true } }) caRadio.SetSelected("New Sectigo (2025+)") // default entry := widget.NewEntry() entry.SetPlaceHolder("") entry.Disable() actionBtn := widget.NewButton("Generate PKCS12 (pfx)", func() { files := []string{keyPath, certPath} var caCert string if newSectigoSelected { caCert = sectigoNew } else { caCert = sectigoOld } allPresent := true if slices.Contains(files, "") { allPresent = false } if !allPresent { fmt.Println("One or more files missing!") return } entry.SetText(integrityCheckAndGo(keyPath, certPath, caCert)) }) cancelBtn := widget.NewButton("Exit", func() { fmt.Println("Quitting...") os.Exit(0) }) // CREATE LAYOUTS bottom := container.NewHBox( actionBtn, // left layout.NewSpacer(), // flexible space cancelBtn, // right ) centerContent := container.NewVBox( widget.NewLabel("Select relevant files."), container.New(layout.NewGridLayout(2), btn1, fileLabel1), container.New(layout.NewGridLayout(2), btn2, fileLabel2), layout.NewSpacer(), container.New(layout.NewGridLayout(2), radioLabel1, caRadio), layout.NewSpacer(), // optional flexible space entry, // just add the entry directly ) content := container.NewBorder( nil, // top bottom, // bottom nil, nil, // left, right centerContent, ) w.SetContent(content) w.ShowAndRun() } func readFile(path string) []byte { rawData, err := os.ReadFile(path) if err != nil { fmt.Printf("Error reading contents of %s, %e", path, err) return nil } else { return rawData } } func parsePrivateKey(keyData []byte) any { block, _ := pem.Decode(keyData) if block == nil { log.Fatal("failed to decode key PEM") } privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { log.Fatal(err) } return privateKey } func parseX509(certData []byte) *x509.Certificate { block, _ := pem.Decode(certData) if block == nil { log.Fatal("failed to parse PEM block") } cert, err := x509.ParseCertificate(block.Bytes) if err != nil { log.Fatal(err) } return cert } func integrityCheckAndGo(keyPath, certPath, caCertString string) string { if _, err := os.Stat(keyPath); err != nil { fmt.Printf("Error checking Private Keyfile, %e", err) return "Error..." } if _, err := os.Stat(certPath); err != nil { fmt.Printf("Error checking Certificate file, %e", err) return "Error..." } keyData := readFile(keyPath) // Read the private key file (PEM/DER) certData := readFile(certPath) // Read the certificate file (PEM/DER) key := parsePrivateKey(keyData) // Convert bytes to Go private key object cert := parseX509(certData) // Convert bytes to Go x509.Certificate caCert := parseX509([]byte(caCertString)) checkPublicKey(cert) // Print the information about the key if checkCertKeyPair(cert.PublicKey, key) { fmt.Println("Private key matches certificate") } else { fmt.Println("Private key does NOT match certificate") } return generatePKCS12(key, cert, caCert) } func generatePKCS12(pKey any, cert, caCert *x509.Certificate) string { return "Nice" }