Update für bessere Kompatibilität
This commit is contained in:
@@ -1,4 +1,20 @@
|
||||
[
|
||||
{
|
||||
"id": "jbergner_at_send.nrw--DFC59FED5CE41CC7A753E9C3C37D763B38A3894C",
|
||||
"name": "Jan Bergner",
|
||||
"email": "jbergner@send.nrw",
|
||||
"fingerprint": "DFC59FED5CE41CC7A753E9C3C37D763B38A3894C",
|
||||
"filename": "Jan-Bergner_jbergner@send.nrw-0xC37D763B38A3894C-pub.asc",
|
||||
"created_at": "2026-02-19T13:00:29.6481446+01:00"
|
||||
},
|
||||
{
|
||||
"id": "tom.gilbo_at_hilden.de--7160BFBE0D520FDDA0BD3ADA5F09C4BD0EE0BE5A",
|
||||
"name": "Tom Gilbo",
|
||||
"email": "tom.gilbo@hilden.de",
|
||||
"fingerprint": "7160BFBE0D520FDDA0BD3ADA5F09C4BD0EE0BE5A",
|
||||
"filename": "public-2-.asc",
|
||||
"created_at": "2026-02-19T12:57:27.4968564+01:00"
|
||||
},
|
||||
{
|
||||
"id": "max_at_send.nrw--D88C7FA9A544ECF8BCCEC6EB8F0B3E5851F2C8CC",
|
||||
"name": "max",
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
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
|
||||
=BcaJ
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
55
data/keys/public-2-.asc
Normal file
55
data/keys/public-2-.asc
Normal file
@@ -0,0 +1,55 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Comment: https://gopenpgp.org
|
||||
Version: GopenPGP 2.9.0
|
||||
|
||||
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
|
||||
=IwML
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
131
main.go
131
main.go
@@ -271,16 +271,38 @@ func zbase32Encode(b []byte) string {
|
||||
return string(out)
|
||||
}
|
||||
|
||||
// wkdHash: z-base-32(SHA1(strings.ToLower(addr-spec))) + domain
|
||||
func wkdHash(email string) (hash string, domain string) {
|
||||
email = strings.ToLower(strings.TrimSpace(email))
|
||||
// wkdHash: z-base-32(SHA1(strings.ToLower(local-part))) + domain
|
||||
func wkdHash(email string) (hash string, domain string, local string) {
|
||||
email = strings.TrimSpace(email)
|
||||
parts := strings.Split(email, "@")
|
||||
if len(parts) != 2 {
|
||||
return "", ""
|
||||
return "", "", ""
|
||||
}
|
||||
domain = parts[1]
|
||||
s := sha1.Sum([]byte(email))
|
||||
return zbase32Encode(s[:]), domain
|
||||
local = parts[0] // keep original for ?l=
|
||||
domain = strings.ToLower(parts[1])
|
||||
lp := strings.ToLower(local)
|
||||
|
||||
s := sha1.Sum([]byte(lp))
|
||||
return zbase32Encode(s[:]), domain, local
|
||||
}
|
||||
|
||||
func armoredToBinary(arm []byte) ([]byte, error) {
|
||||
ents, err := openpgp.ReadArmoredKeyRing(bytes.NewReader(arm))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(ents) == 0 {
|
||||
return nil, fmt.Errorf("no keys in armored data")
|
||||
}
|
||||
|
||||
var out bytes.Buffer
|
||||
for _, e := range ents {
|
||||
// Serialize schreibt binary OpenPGP packets (kein Armor)
|
||||
if err := e.Serialize(&out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return out.Bytes(), nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
@@ -322,7 +344,7 @@ func main() {
|
||||
})
|
||||
// Upload with automatic fingerprint parsing
|
||||
mux.HandleFunc("/upload", func(w http.ResponseWriter, r *http.Request) {
|
||||
if enabled("WRITEACCESS", false) {
|
||||
if enabled("WRITEACCESS", true) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
@@ -428,16 +450,26 @@ func main() {
|
||||
mux.HandleFunc("/.well-known/openpgpkey/policy", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte("# WKD policy"))
|
||||
_, _ = w.Write([]byte("# WKD policy\n"))
|
||||
})
|
||||
// direct method: /.well-known/openpgpkey/hu/<hash>
|
||||
mux.HandleFunc("/.well-known/openpgpkey/hu/", func(w http.ResponseWriter, r *http.Request) {
|
||||
pathHash := strings.TrimPrefix(r.URL.Path, "/.well-known/openpgpkey/hu/")
|
||||
hash := strings.TrimPrefix(r.URL.Path, "/.well-known/openpgpkey/hu/")
|
||||
hash = strings.Trim(hash, "/")
|
||||
|
||||
// Optional: ?l=... (unverändert, percent-encoded) — nur als Hint/Check
|
||||
lParam := r.URL.Query().Get("l")
|
||||
|
||||
var match *KeyRecord
|
||||
var matchLocal string
|
||||
for _, it := range st.all() {
|
||||
h, _ := wkdHash(it.Email)
|
||||
if h == pathHash {
|
||||
h, _, local := wkdHash(it.Email)
|
||||
if h == hash {
|
||||
if lParam != "" && lParam != local {
|
||||
continue
|
||||
}
|
||||
match = &it
|
||||
matchLocal = local
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -445,27 +477,70 @@ func main() {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
data, err := os.ReadFile(filepath.Join(keysDir, match.Filename))
|
||||
|
||||
arm, err := os.ReadFile(filepath.Join(keysDir, match.Filename))
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/pgp-keys")
|
||||
bin, err := armoredToBinary(arm)
|
||||
if err != nil {
|
||||
http.Error(w, "invalid stored key data", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// WKD responses are typically application/octet-stream
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*") // optional, hilft manchen Tools
|
||||
if r.Method == http.MethodHead {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
_ = matchLocal // falls du später Logging möchtest
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(data)
|
||||
_, _ = w.Write(bin)
|
||||
})
|
||||
// advanced method: /openpgpkey/<domain>/hu/<hash>
|
||||
mux.HandleFunc("/openpgpkey/", func(w http.ResponseWriter, r *http.Request) {
|
||||
parts := strings.Split(strings.TrimPrefix(r.URL.Path, "/openpgpkey/"), "/")
|
||||
mux.HandleFunc("/.well-known/openpgpkey/", func(w http.ResponseWriter, r *http.Request) {
|
||||
// Nur advanced bedienen, wenn Host = openpgpkey.<domain>
|
||||
host := r.Host
|
||||
if i := strings.IndexByte(host, ':'); i >= 0 {
|
||||
host = host[:i]
|
||||
}
|
||||
if !strings.HasPrefix(strings.ToLower(host), "openpgpkey.") {
|
||||
// Für die Hauptdomain sind policy + /hu/ bereits separat gemappt
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Erwartet:
|
||||
// /.well-known/openpgpkey/<domain>/hu/<hash>
|
||||
// oder: /.well-known/openpgpkey/<domain>/policy
|
||||
rest := strings.TrimPrefix(r.URL.Path, "/.well-known/openpgpkey/")
|
||||
parts := strings.Split(strings.Trim(rest, "/"), "/")
|
||||
if len(parts) == 2 && parts[1] == "policy" {
|
||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte("# WKD policy\n"))
|
||||
return
|
||||
}
|
||||
if len(parts) != 3 || parts[1] != "hu" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
domain, hash := parts[0], parts[2]
|
||||
|
||||
domain := strings.ToLower(parts[0])
|
||||
hash := parts[2]
|
||||
lParam := r.URL.Query().Get("l")
|
||||
|
||||
var match *KeyRecord
|
||||
for _, it := range st.all() {
|
||||
h, d := wkdHash(it.Email)
|
||||
h, d, local := wkdHash(it.Email)
|
||||
if h == hash && strings.EqualFold(d, domain) {
|
||||
if lParam != "" && lParam != local {
|
||||
continue
|
||||
}
|
||||
match = &it
|
||||
break
|
||||
}
|
||||
@@ -474,14 +549,26 @@ func main() {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
data, err := os.ReadFile(filepath.Join(keysDir, match.Filename))
|
||||
|
||||
arm, err := os.ReadFile(filepath.Join(keysDir, match.Filename))
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/pgp-keys")
|
||||
bin, err := armoredToBinary(arm)
|
||||
if err != nil {
|
||||
http.Error(w, "invalid stored key data", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
if r.Method == http.MethodHead {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(data)
|
||||
_, _ = w.Write(bin)
|
||||
})
|
||||
|
||||
// --- Minimal HKP-compatible lookup ---
|
||||
|
||||
Reference in New Issue
Block a user