133 lines
3.2 KiB
Go
Executable File
133 lines
3.2 KiB
Go
Executable File
package main
|
|
|
|
import (
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
encrypt "fckeuspy-go/lib"
|
|
"html/template"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/dialog"
|
|
"fyne.io/fyne/v2/widget"
|
|
)
|
|
|
|
var (
|
|
priv *rsa.PrivateKey
|
|
pubPEM []byte
|
|
certPEM []byte // self-signed cert jen pro sdílení identity (volitelné)
|
|
tmpl *template.Template
|
|
)
|
|
|
|
type envelope struct {
|
|
// Encrypted AES key, Nonce, Ciphertext (GCM)
|
|
EK string `json:"ek"` // base64(RSA-OAEP(aesKey))
|
|
N string `json:"n"` // base64(nonce 12B)
|
|
CT string `json:"ct"` // base64(GCM(ciphertext||tag))
|
|
}
|
|
|
|
func main() {
|
|
if err := rootCmd.Execute(); err != nil {
|
|
log.Printf("Chyba: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
// Malé zpoždění pro případné async logy
|
|
time.Sleep(50 * time.Millisecond)
|
|
}
|
|
|
|
func runFyne() {
|
|
storageDir, w := NewUI()
|
|
vaultPath := filepath.Join(storageDir, "vault.enc")
|
|
placeholder := widget.NewLabel("Inicializace trezoru…")
|
|
w.SetContent(placeholder)
|
|
|
|
showDialog := func() {
|
|
ShowPasswordVaultDialog(w, vaultPath, func(create bool, password string, commonName string) {
|
|
if password == "" { // Cancel nebo zavření dialogu => ukonči app
|
|
fyne.CurrentApp().Quit()
|
|
return
|
|
}
|
|
var store encrypt.SecureJSONStore
|
|
var err error
|
|
if create {
|
|
store, err = encrypt.CreateEncryptedStore(vaultPath, password, true, commonName)
|
|
} else {
|
|
store, err = encrypt.OpenEncryptedStore(vaultPath, password)
|
|
if err != nil {
|
|
dialog.NewError(err, w).Show()
|
|
return
|
|
}
|
|
}
|
|
if err != nil {
|
|
dialog.NewError(err, w).Show()
|
|
return
|
|
}
|
|
vs, err := NewVaultService(store)
|
|
if err != nil {
|
|
dialog.NewError(err, w).Show()
|
|
return
|
|
}
|
|
parts := buildEntries()
|
|
fyne.CurrentApp().Driver().AllWindows()[0].SetTitle("Encryptor (Vault)")
|
|
w.SetContent(buildTabbedUI(parts, vs, vaultPath))
|
|
})
|
|
}
|
|
|
|
// Pokud soubor neexistuje, dialog v režimu vytvořit (default). Pokud existuje, uživatel může přepnout.
|
|
showDialog()
|
|
w.ShowAndRun()
|
|
}
|
|
|
|
func RunWebApp() {
|
|
// Otevři nebo vytvoř šifrovaný trezor a načti identitu pouze z něj
|
|
vaultPath := os.Getenv("VAULT_PATH")
|
|
if vaultPath == "" {
|
|
vaultPath = "./vault.enc"
|
|
}
|
|
pw := os.Getenv("VAULT_PASSWORD")
|
|
if pw == "" {
|
|
log.Fatal("VAULT_PASSWORD must be set for web mode")
|
|
}
|
|
var store encrypt.SecureJSONStore
|
|
if _, statErr := os.Stat(vaultPath); os.IsNotExist(statErr) {
|
|
s, err := encrypt.CreateEncryptedStore(vaultPath, pw, true, "")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
store = s
|
|
} else {
|
|
s, err := encrypt.OpenEncryptedStore(vaultPath, pw)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
store = s
|
|
}
|
|
// Načti privátní klíč a veřejné materiály
|
|
privPEM := store.IdentityPrivatePEM()
|
|
if privPEM == "" {
|
|
log.Fatal("missing private key in vault")
|
|
}
|
|
block, _ := pem.Decode([]byte(privPEM))
|
|
if block == nil || block.Type != "RSA PRIVATE KEY" {
|
|
log.Fatal("invalid private key PEM in vault")
|
|
}
|
|
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
priv = key
|
|
pubPEM = []byte(store.IdentityPublicPEM())
|
|
certPEM = []byte(store.IdentityCertPEM())
|
|
|
|
// 2) šablony
|
|
tmpl = template.Must(template.ParseGlob("templates/*.html"))
|
|
|
|
muxServer := NewServer()
|
|
log.Fatal(http.ListenAndServe(":8080", muxServer))
|
|
}
|