X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=cmd%2Fepoint-client%2Fepoint-client.go;h=71bbe048abe425d6ef6a8e2c18a6ebc5aed69687;hb=b7259bc293641fbe83e44d0f886cea52b8816769;hp=428151937c44847b4b23efebbca3ee9c6147b480;hpb=a86164c8ba48de5cb1a95acc140e811d1c4b1241;p=epoint diff --git a/cmd/epoint-client/epoint-client.go b/cmd/epoint-client/epoint-client.go index 4281519..71bbe04 100644 --- a/cmd/epoint-client/epoint-client.go +++ b/cmd/epoint-client/epoint-client.go @@ -17,15 +17,17 @@ import ( "strconv" ) -// TODO: store documents, query store (keys), easy submit +// TODO: store documents, query document by id, easy submit var db *store.Conn -const usage = `usage: ./epoint-client [k|d|s|v|c] [args..] < [seed|document] +const usage = `usage: ./epoint-client [i|h|d|q|s|v|c] [args..] < [seed|document] server is http://localhost:8080 by default -k - make key, use seed for generation, args: [issuer] denomination +i - make issuer key, use seed for generation, args: denomination +h - make holder key, use seed for generation, args: issuer d - make draft, use seed for signing key, args: targetid value +q - query document, args: k|d|c id [server] s - submit a (key|draft|cert) document, args: k|d|c [server] v - verify a document (prints body of the document if ok) c - connect to server and get server key, args: [server] @@ -37,13 +39,32 @@ func rnd(n int) (r []byte, err error) { return } -func k(r []byte, issuer, denom string) (err error) { +func k(r []byte, cmd, arg string) (err error) { var e *openpgp.Entity - if issuer == "" { - e, err = key.Issuer(r, denom) + if cmd == "i" { + e, err = key.Issuer(r, arg) } else { - e, err = key.Holder(r, issuer, denom) + s, err1 := db.Get("key", arg) + err = err1 + if err != nil { + return + } + ie, err1 := key.Parse(s) + err = err1 + if err != nil { + return + } + isIssuer, _, denom, err1 := key.Check(ie) + err = err1 + if err != nil { + return + } + if !isIssuer { + err = fmt.Errorf("Not an issuer key: %s", arg) + return + } + e, err = key.Holder(r, arg, denom) } if err != nil { return @@ -143,14 +164,131 @@ func d(r []byte, target, value string) (err error) { return } draft.Nonce = fmt.Sprintf("%X", nonce) - s, _, err := document.Format(draft, e) + s, c, err := document.Format(draft, e) if err != nil { return } + log.Printf("draft id: %s", document.Id(c)) _, err = os.Stdout.Write(s) return } +func q(cmd, id, server string) (err error) { + log.Printf("document id: %s, server: %s", id, server) + m := map[string]string{ + "k": "key", + "d": "draft", + "c": "cert", + } + k, ok := m[cmd] + if !ok { + err = fmt.Errorf("unknown query command: %s", cmd) + return + } + d, err := db.Get(k, id) + if err != nil { + if _, ok := err.(store.NotFoundError); !ok { + return + } + } else { + _, err = os.Stdout.Write(d) + log.Printf("found %s in local store", id) + return + } + resp, err := http.Get(server+"/"+k+"/"+id) + if err != nil { + return + } + d, err = readall(resp.Body) + if err != nil { + return + } + err = resp.Body.Close() + if err != nil { + return + } + _, err = os.Stdout.Write(d) + if resp.StatusCode != 200 { + err = fmt.Errorf("request failed: %s", resp.Status) + return + } + if err != nil { + return + } + log.Printf("got %s from the server", id) + switch cmd { + case "k": + e, err1 := key.Parse(d) + err = err1 + if err != nil { + return + } + if id != key.Id(e) { + err = fmt.Errorf("id mismatch, expected %s, got %s", id, key.Id(e)) + return + } + err = db.Set("key", id, d) + case "d": + i, s, err1 := document.Parse(d) + err = err1 + if err != nil { + return + } + if id != document.Id(s) { + err = fmt.Errorf("id mismatch, expected %s, got %s", id, document.Id(s)) + return + } + draft := i.(*document.Draft) + b, err1 := db.Get("key", draft.Drawer) + err = err1 + if err != nil { + return + } + e, err1 := key.Parse(b) + err = err1 + if err != nil { + return + } + err = document.Verify(s, openpgp.EntityList{e}) + if err != nil { + return + } + err = db.Set("draft", id, d) + case "c": + i, s, err1 := document.Parse(d) + err = err1 + if err != nil { + return + } + if id != document.Id(s) { + err = fmt.Errorf("id mismatch, expected %s, got %s", id, document.Id(s)) + return + } + cert, err1 := document.ToCert(i) + err = err1 + if err != nil { + return + } + // TODO: check serverkey + b, err1 := db.Get("key", cert.AuthorizedBy) + err = err1 + if err != nil { + return + } + e, err1 := key.Parse(b) + err = err1 + if err != nil { + return + } + err = document.Verify(s, openpgp.EntityList{e}) + if err != nil { + return + } + err = db.Set("cert", id, d) + } + return +} + func s(d []byte, cmd, server string) (err error) { m := map[string]string{ "k": "key", @@ -162,19 +300,72 @@ func s(d []byte, cmd, server string) (err error) { err = fmt.Errorf("unknown submit command: %s", cmd) return } + id := "" + switch cmd { + case "k": + e, err1 := key.Parse(d) + err = err1 + if err != nil { + return + } + id = key.Id(e) + err = db.Set("key", id, d) + case "d": + _, s, err1 := document.Parse(d) + err = err1 + if err != nil { + return + } + id = document.Id(s) + err = db.Set("draft", id, d) + case "c": + _, s, err1 := document.Parse(d) + err = err1 + if err != nil { + return + } + id = document.Id(s) + err = db.Set("cert", id, d) + } + if err != nil { + return + } + log.Printf("document id: %s, server: %s", id, server) resp, err := http.PostForm(server+"/submit", url.Values{k: {string(d)}}) if err != nil { return } if resp.StatusCode != 200 { - log.Printf("request failed: %s\n", resp.Status) + log.Printf("request failed: %s", resp.Status) } // TODO: store result - _, err = io.Copy(os.Stdout, resp.Body) + b, err := readall(resp.Body) + defer resp.Body.Close() if err != nil { return } - err = resp.Body.Close() + _, err = os.Stdout.Write(b) + if err != nil { + return + } + cert, s, err := document.Parse(b) + if err != nil { + return + } + d, err = db.Get("", "serverkey") + if err != nil { + return + } + e, err := key.Parse(d) + if err != nil { + return + } + err = document.Verify(s, openpgp.EntityList{e}) + if err != nil { + return + } + log.Printf("response type: %T, response id: %s", cert, document.Id(s)) + err = db.Set("cert", document.Id(s), b) return } @@ -233,6 +424,10 @@ func c(server string) (err error) { return } log.Printf("got server key %s", key.Id(e)) + err = db.Set("key", key.Id(e), b) + if err != nil { + return + } err = db.Set("", "serverkey", b) return } @@ -314,23 +509,30 @@ func main() { db, err = initstore(storedir()) server := "http://localhost:8080" switch os.Args[1] { - case "k": - issuer := "" - denom := "" - if len(os.Args) == 4 { - issuer = os.Args[2] - denom = os.Args[3] - } else if len(os.Args) == 3 { - denom = os.Args[2] - } else { + case "h", "i": + if len(os.Args) != 3 { log.Fatal(usage) } - err = k(read(), issuer, denom) + err = k(read(), os.Args[1], os.Args[2]) case "d": if len(os.Args) != 4 { log.Fatal(usage) } err = d(read(), os.Args[2], os.Args[3]) + case "q": + cmd := "" + id := "" + if len(os.Args) == 5 { + cmd = os.Args[2] + id = os.Args[3] + server = os.Args[4] + } else if len(os.Args) == 4 { + cmd = os.Args[2] + id = os.Args[3] + } else { + log.Fatal(usage) + } + err = q(cmd, id, server) case "s": cmd := "" if len(os.Args) == 4 {