initial work on openpgp key

This commit is contained in:
Xuu
2020-10-17 10:32:03 -06:00
parent df040b2004
commit 031fe1ac5e
5 changed files with 117 additions and 3 deletions

View File

@@ -2,13 +2,21 @@ package routes
import (
"bytes"
"crypto/sha1"
"encoding/json"
"fmt"
"io"
"net/http"
"net/mail"
"net/url"
"regexp"
"strings"
"github.com/coreos/bbolt"
"github.com/gorilla/mux"
"github.com/sour-is/crypto/openpgp"
"github.com/tv42/zbase32"
"sour.is/x/toolbox/httpsrv"
"sour.is/x/toolbox/log"
"sour.is/x/toolbox/uuid"
@@ -21,6 +29,7 @@ func init() {
httpsrv.HttpRegister("short", httpsrv.HttpRoutes{
{Name: "getShort", Method: "GET", Pattern: "/s/{id}", HandlerFunc: s.getShort},
{Name: "putShort", Method: "PUT", Pattern: "/s/{id}", HandlerFunc: s.putShort},
{Name: "getIdentity", Method: "GET", Pattern: "/id/{id}", HandlerFunc: s.getIdentity},
})
}
@@ -190,3 +199,101 @@ func (s *shortDB) PutURL(id string, url *shortURL) {
log.Errorf("ShortURL: failed to write db at [%s]", s.path)
}
}
func (s *shortDB) getIdentity(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
useArmored := false
addr := ""
if isFingerprint(id) {
addr = "https://keys.openpgp.org/vks/v1/by-fingerprint/" + strings.ToUpper(id)
useArmored = true
} else if email, err := mail.ParseAddress(id); err == nil {
addr = getWKDPubKeyAddr(email)
useArmored = false
} else {
httpsrv.WriteError(w, 400, err.Error())
return
}
resp, err := http.Get(addr)
if err != nil {
print(err)
}
defer resp.Body.Close()
if resp.Header.Get("Content-Type") == "application/pgp-keys" {
useArmored = true
}
log.Infos("getIdentity", "id", id, "useArmored", useArmored, "status", resp.Status, "addr", addr)
var lis openpgp.EntityList
if useArmored {
lis, err = openpgp.ReadArmoredKeyRing(resp.Body)
} else {
lis, err = openpgp.ReadKeyRing(resp.Body)
}
if err != nil {
fmt.Println(err)
httpsrv.WriteError(w, 400, "bad decode")
return
}
for _, entity := range lis {
entityString(w, entity)
}
}
func isFingerprint(s string) bool {
for _, r := range s {
switch r {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F':
default:
return false
}
}
return true
}
func entityString(out io.Writer, e *openpgp.Entity) {
if e == nil {
return
}
if e.Identities != nil {
fmt.Fprintln(out, "Identities:")
for name, identity := range e.Identities {
fmt.Fprintf(out, " %s:\n", name)
identityString(out, identity)
fmt.Fprintln(out)
}
}
}
func identityString(out io.Writer, i *openpgp.Identity) {
if i == nil || i.SelfSignature == nil {
return
}
fmt.Fprintf(out, "name: %s\n", i.Name)
for key, valueList := range i.SelfSignature.NotationData {
for _, value := range valueList {
fmt.Fprintln(out, " ", key, value)
}
}
}
func getWKDPubKeyAddr(email *mail.Address) string {
parts := strings.SplitN(email.Address, "@", 2)
hash := sha1.Sum([]byte(parts[0]))
lp := zbase32.EncodeToString(hash[:])
return fmt.Sprintf("https://%s/.well-known/openpgpkey/hu/%s", parts[1], lp)
}