RC1
This commit is contained in:
63
main.go
63
main.go
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
@@ -43,6 +44,7 @@ type genResult struct {
|
||||
PrivateArmored string
|
||||
Fingerprint string
|
||||
Created time.Time
|
||||
UIDOnKey string // tatsächliche UID im Schlüssel
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -95,27 +97,69 @@ func handleGenerate(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, fmt.Sprintf("Fehler beim Erzeugen der Schlüssel: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
_ = resultTmpl.Execute(w, res)
|
||||
}
|
||||
|
||||
// sanitizeName entfernt verbotene Zeichen aus Name/Comment-Feldern, die vom OpenPGP-Format für UID reserviert sind
|
||||
func sanitizeName(s string) string {
|
||||
s = strings.TrimSpace(s)
|
||||
// Entferne reservierte und Steuerzeichen, die in der UID nicht vorkommen dürfen
|
||||
replacer := strings.NewReplacer("<", "", ">", "", "(", "", ")", "", "\r", "", "\n", "")
|
||||
s = replacer.Replace(s)
|
||||
// trim doppelte Spaces
|
||||
for strings.Contains(s, " ") {
|
||||
s = strings.ReplaceAll(s, " ", " ")
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func sanitizeEmail(s string) string {
|
||||
s = strings.TrimSpace(s)
|
||||
s = strings.ReplaceAll(s, " ", "") // keine Spaces
|
||||
replacer := strings.NewReplacer("<", "", ">", "", "(", "", ")", "", "\r", "", "\n", "")
|
||||
s = replacer.Replace(s)
|
||||
return s
|
||||
}
|
||||
|
||||
func validateEmailBasic(s string) bool {
|
||||
if s == "" {
|
||||
return false
|
||||
}
|
||||
if strings.ContainsAny(s, " <>()\r\n\t") {
|
||||
return false
|
||||
}
|
||||
// sehr einfache Plausibilitätsprüfung
|
||||
at := strings.IndexByte(s, '@')
|
||||
if at <= 0 || at == len(s)-1 {
|
||||
return false
|
||||
}
|
||||
if strings.Contains(s[at+1:], "@") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func generatePGP(in genInput) (*genResult, error) {
|
||||
// Kommentar wird in die User-ID integriert
|
||||
name := in.Name
|
||||
if in.Comment != "" {
|
||||
name = fmt.Sprintf("%s (%s)", in.Name, in.Comment)
|
||||
// Kommentar nicht in UID einbetten (gopenpgp's GenerateKey nimmt nur Name+Email)
|
||||
name := sanitizeName(in.Name)
|
||||
email := sanitizeEmail(in.Email)
|
||||
if !validateEmailBasic(email) {
|
||||
return nil, errors.New("ungültige E‑Mail-Adresse")
|
||||
}
|
||||
if name == "" {
|
||||
return nil, errors.New("Name darf nicht leer sein")
|
||||
}
|
||||
|
||||
// 1) Schlüssel erzeugen (noch unverschlüsselt)
|
||||
key, err := crypto.GenerateKey(name, in.Email, "rsa", in.RSABits)
|
||||
// 1) Schlüssel erzeugen (UID = "Name <email>")
|
||||
key, err := crypto.GenerateKey(name, email, "rsa", in.RSABits)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateKey: %w", err)
|
||||
}
|
||||
|
||||
// 2) Optional mit Passphrase sperren (at-rest Verschlüsselung)
|
||||
// 2) Optional mit Passphrase sperren
|
||||
if in.Passphrase != "" {
|
||||
if _, err := key.Lock([]byte(in.Passphrase)); err != nil {
|
||||
return nil, fmt.Errorf("Lock (Passphrase setzen) fehlgeschlagen: %w", err)
|
||||
return nil, fmt.Errorf("Passphrase setzen fehlgeschlagen: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +182,7 @@ func generatePGP(in genInput) (*genResult, error) {
|
||||
PrivateArmored: armoredPriv,
|
||||
Fingerprint: fp,
|
||||
Created: created,
|
||||
UIDOnKey: fmt.Sprintf("%s <%s>", name, email),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user