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|r|q|s|v|c] [args..] < [seed|document]
server is http://localhost:8080 by default
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
+r - sign raw document, use seed for signing key, args: document
+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]
}
func d(r []byte, target, value string) (err error) {
- v, err := strconv.Atoi64(value)
+ v, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return
}
return
}
+// TODO: document.Sign does not handle dash escape
+func raw(r []byte, name string) (err error) {
+ e, err := key.Holder(r, "", "")
+ if err != nil {
+ return
+ }
+ log.Printf("signer: %s", key.Id(e))
+ f, err := os.Open(name)
+ if err != nil {
+ return
+ }
+ doc, err := readall(f)
+ if err != nil {
+ return
+ }
+ d, err := document.Sign(doc, e)
+ if err != nil {
+ return
+ }
+ s, err := document.FormatSigned(d)
+ if err != nil {
+ return
+ }
+ _, 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",
return dir
}
+// read all but at most 1M from r
func readall(r io.Reader) ([]byte, error) {
- b := make([]byte, 10000)
+ b := make([]byte, 1<<20)
n, err := io.ReadFull(r, b)
if err != io.ErrUnexpectedEOF {
if err == nil {
log.Fatal(usage)
}
err = d(read(), os.Args[2], os.Args[3])
+ case "r":
+ if len(os.Args) != 3 {
+ log.Fatal(usage)
+ }
+ err = raw(read(), os.Args[2])
+ 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 {