cleanups
authornsz <nsz@port70.net>
Fri, 25 Nov 2011 11:15:12 +0000 (12:15 +0100)
committernsz <nsz@port70.net>
Fri, 25 Nov 2011 11:15:12 +0000 (12:15 +0100)
document/document.go
epoint-server.go
logic/logic.go

index 0fd13ce..0ac99b6 100644 (file)
@@ -32,6 +32,8 @@ package document
 // TODO: fields of notice (last notice, serial, failure notice,..)
 // TODO: limits and cert type specific input validation
 // TODO: fix Cert mess
 // TODO: fields of notice (last notice, serial, failure notice,..)
 // TODO: limits and cert type specific input validation
 // TODO: fix Cert mess
+// TODO: nonce is id, id is even number of hex digits
+// TODO: denom, issuer from key (key representation: armor?)
 
 import (
        "bytes"
 
 import (
        "bytes"
@@ -104,7 +106,7 @@ var fieldtype = map[string]string{
        "Last-Credit-Serial": "int",
        "Last-Debit-Serial":  "int",
        "Maturity-Date":      "date",
        "Last-Credit-Serial": "int",
        "Last-Debit-Serial":  "int",
        "Maturity-Date":      "date",
-       "Nonce":              "text",
+       "Nonce":              "id",
        "Notes":              "text",
        "References":         "ids",
        "Serial":             "int",
        "Notes":              "text",
        "References":         "ids",
        "Serial":             "int",
@@ -127,9 +129,9 @@ type Draft struct {
        Denomination string
        Issuer       string
        AuthorizedBy string
        Denomination string
        Issuer       string
        AuthorizedBy string
-       MaturityDate *int64  // optional
-       ExpiryDate   *int64  // optional
-       Nonce        *string // optional
+       MaturityDate *int64 // optional
+       ExpiryDate   *int64 // optional
+       Nonce        string
        Notes        *string // optional
 }
 
        Notes        *string // optional
 }
 
@@ -299,9 +301,9 @@ func Format(iv interface{}, key *openpgp.Entity) (s []byte, c *Signed, err error
 func Verify(c *Signed, key openpgp.KeyRing) (err error) {
        msg := bytes.NewBuffer(c.Body)
        sig := bytes.NewBuffer(c.Signature)
 func Verify(c *Signed, key openpgp.KeyRing) (err error) {
        msg := bytes.NewBuffer(c.Body)
        sig := bytes.NewBuffer(c.Signature)
-// TODO: verify signature
-       _,_ = msg,sig
-//     _, err = openpgp.CheckArmoredDetachedSignature(key, msg, sig)
+       // TODO: verify signature
+       _, _ = msg, sig
+       //      _, err = openpgp.CheckArmoredDetachedSignature(key, msg, sig)
        return
 }
 
        return
 }
 
@@ -312,6 +314,11 @@ func Sign(body []byte, key *openpgp.Entity) (c *Signed, err error) {
        c.Body = body
        w := new(bytes.Buffer)
        err = openpgp.ArmoredDetachSignText(w, key, bytes.NewBuffer(c.Body))
        c.Body = body
        w := new(bytes.Buffer)
        err = openpgp.ArmoredDetachSignText(w, key, bytes.NewBuffer(c.Body))
+       if err != nil {
+               return
+       }
+       // close armored document with a \n
+       _, _ = w.Write([]byte{'\n'})
        c.Signature = w.Bytes()
        return
 }
        c.Signature = w.Bytes()
        return
 }
index 8ceef64..786c70c 100644 (file)
@@ -10,8 +10,8 @@ import (
 )
 
 const (
 )
 
 const (
-       port    = ":8080"
-       rootdir = "teststore"
+       addr    = ":8080"
+       rootdir = "docroot"
        seckey  = "./key.sec"
 )
 
        seckey  = "./key.sec"
 )
 
@@ -19,18 +19,6 @@ var serverkey *openpgp.Entity
 
 // todo: http header limit: 64K, body limit: 64K
 
 
 // todo: http header limit: 64K, body limit: 64K
 
-// getPubkey(db, fpr) (pk, err)
-// putPubkey(db, fpr, pk) (err)
-// getDraft(db, id) (draft, err)
-// putDraft(db, id, draft) (err)
-
-// getCert(db, id) (cert, err)
-// putCert(db, id, cert) (err)
-// getCertBySerial(db, fpr, sn) (cert, err)
-// getCertByFpr(db, fpr) (cert, err)
-
-// todo: update cert (inc serial..)
-
 // Dummy initialization of serverkey
 func initkey() (err error) {
        f, err := os.Open(seckey)
 // Dummy initialization of serverkey
 func initkey() (err error) {
        f, err := os.Open(seckey)
@@ -68,33 +56,64 @@ func initkey() (err error) {
        return
 }
 
        return
 }
 
+func httpError(w http.ResponseWriter, code int, msg string) {
+       log.Printf("error: %d %s", code, msg)
+       http.Error(w, fmt.Sprintf("%d %s\n\n%s\n", code, http.StatusText(code), msg), code)
+}
+
+func httpReq(r *http.Request) string {
+       err := r.ParseForm()
+       form := ""
+       if err != nil {
+               form = err.Error()
+       } else {
+               a := []string{}
+               for k := range r.Form {
+                       a = append(a, k)
+               }
+               form = fmt.Sprintf("%v", a)
+       }
+       return fmt.Sprintf("%s %s params:%s", r.Method, r.URL.Raw, form)
+}
+
 func defaultHandler(w http.ResponseWriter, r *http.Request) {
 func defaultHandler(w http.ResponseWriter, r *http.Request) {
-       log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL.Raw)
+       log.Printf("%s %s", r.RemoteAddr, httpReq(r))
        fmt.Fprintf(w, "not implemented: %s %s\n", r.Method, r.URL.Raw)
 }
 
 func submitHandler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "not implemented: %s %s\n", r.Method, r.URL.Raw)
 }
 
 func submitHandler(w http.ResponseWriter, r *http.Request) {
-       log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL.Raw)
+       log.Printf("%s %s", r.RemoteAddr, httpReq(r))
        draft := r.FormValue("draft")
        debit := r.FormValue("debit")
        draft := r.FormValue("draft")
        debit := r.FormValue("debit")
-       if len(draft) > 0 {
+       key := r.FormValue("key")
+       switch {
+       case draft != "":
                cert, err := logic.EvalDraft([]byte(draft), serverkey)
                if err != nil {
                cert, err := logic.EvalDraft([]byte(draft), serverkey)
                if err != nil {
-                       log.Printf("eval draft fail: %s", err)
-                       fmt.Fprintf(w, "eval draft fail: %s\n", err)
+                       msg := fmt.Sprintf("eval draft failed: %s", err)
+                       httpError(w, 404, msg)
                } else {
                        w.Write(cert)
                }
                } else {
                        w.Write(cert)
                }
-       } else if len(debit) > 0 {
+       case debit != "":
                cert, err := logic.EvalDebitCert([]byte(debit), serverkey)
                if err != nil {
                cert, err := logic.EvalDebitCert([]byte(debit), serverkey)
                if err != nil {
-                       log.Printf("eval debit fail: %s", err)
-                       fmt.Fprintf(w, "eval debit fail: %s\n", err)
+                       msg := fmt.Sprintf("eval debit failed: %s", err)
+                       httpError(w, 404, msg)
                } else {
                        w.Write(cert)
                }
                } else {
                        w.Write(cert)
                }
-       } else {
-               fmt.Fprintf(w, "expected draft or debit param, got: %s %s\n", r.Method, r.URL.Raw)
+       case key != "":
+               err := logic.AddKeys([]byte(key))
+               if err != nil {
+                       msg := fmt.Sprintf("add keys failed: %s", err)
+                       httpError(w, 404, msg)
+               } else {
+                       w.Write([]byte("ok\nTODO: create cert 1 here?"))
+               }
+       default:
+               msg := fmt.Sprintf("expected key, draft or debit param, got: %s", httpReq(r))
+               httpError(w, 404, msg)
        }
 }
 
        }
 }
 
@@ -103,26 +122,42 @@ func main() {
        if err != nil {
                log.Fatal(err)
        }
        if err != nil {
                log.Fatal(err)
        }
-       err = logic.Init()
+       err = logic.Init(rootdir)
        if err != nil {
                log.Fatal(err)
        }
 
        if err != nil {
                log.Fatal(err)
        }
 
-       http.HandleFunc("/", defaultHandler)
+       // TODO: url from key
+       f, err := os.Create(rootdir + "/form.html")
+       if err != nil {
+               log.Fatal(err)
+       }
+       _, _ = fmt.Fprintf(f, `<html><head><title>epoint-server submit form</title></head><body>
+<h2>epoint-server submit form</h2>
+<h3>web form</h3>
+<p>submit one document at once
+<form method="post" action="http://localhost%s/submit">
+<p>key:<br><textarea name="key" rows="5" cols="80"></textarea>
+<p>draft:<br><textarea name="draft" rows="5" cols="80"></textarea>
+<p>debit:<br><textarea name="debit" rows="5" cols="80"></textarea>
+<p><input type="submit">
+</form>
+<h3>command line</h3>
+<pre>
+curl --data-urlencode name@path/to/file.txt host/submit
+</pre>
+where 'name' is 'key', 'draft' or 'debit'.
+</body></html>
+`, addr)
+       _ = f.Close()
 
        // queries
 
        // queries
-       http.HandleFunc("/serverkey", func(w http.ResponseWriter, r *http.Request) {
-               http.ServeFile(w, r, rootdir+"/serverkey")
-       })
-//     http.HandleFunc("/status", defaultHandler)
-//     http.HandleFunc("/pubkey", defaultHandler)
-//     http.HandleFunc("/daft", defaultHandler)
-//     http.HandleFunc("/cert", defaultHandler)
+       http.Handle("/", http.FileServer(http.Dir(rootdir)))
 
        // actions
        // withdraw, draw, deposit, process, clear
        http.HandleFunc("/submit", submitHandler)
 
 
        // actions
        // withdraw, draw, deposit, process, clear
        http.HandleFunc("/submit", submitHandler)
 
-       log.Printf("start service, server id: %X\n", serverkey.PrimaryKey.Fingerprint)
-       log.Fatal(http.ListenAndServe(port, nil))
+       log.Printf("start service on %s, server key id: %X\n", addr, serverkey.PrimaryKey.Fingerprint)
+       log.Fatal(http.ListenAndServe(addr, nil))
 }
 }
index a9fd15b..c09054f 100644 (file)
@@ -38,11 +38,11 @@ func AddKeys(d []byte) (err error) {
                if err != nil {
                        return
                }
                if err != nil {
                        return
                }
-               err = db.Append("fprlist/64", fpr[len(fpr)-16:], []byte(fpr))
+               err = db.Append("keysby/64", fpr[len(fpr)-16:], []byte(fpr))
                if err != nil {
                        return
                }
                if err != nil {
                        return
                }
-               err = db.Append("fprlist/32", fpr[len(fpr)-8:], []byte(fpr))
+               err = db.Append("keysby/32", fpr[len(fpr)-8:], []byte(fpr))
                if err != nil {
                        return
                }
                if err != nil {
                        return
                }
@@ -51,7 +51,7 @@ func AddKeys(d []byte) (err error) {
 }
 
 func CertByDraft(draftid string) (d []byte, err error) {
 }
 
 func CertByDraft(draftid string) (d []byte, err error) {
-       certid, err := db.Get("certid/debit", draftid)
+       certid, err := db.Get("certby/draft", draftid)
        if err != nil {
                // TODO: we have the draft but the cert is not ready
                return
        if err != nil {
                // TODO: we have the draft but the cert is not ready
                return
@@ -65,7 +65,7 @@ func CertByDraft(draftid string) (d []byte, err error) {
 }
 
 func CertByDebitCert(debitid string) (d []byte, err error) {
 }
 
 func CertByDebitCert(debitid string) (d []byte, err error) {
-       creditid, err := db.Get("certid/credit", debitid)
+       creditid, err := db.Get("certby/debit", debitid)
        if err != nil {
                // TODO: we have the debit cert but the credit cert is not ready
                return
        if err != nil {
                // TODO: we have the debit cert but the credit cert is not ready
                return
@@ -90,26 +90,26 @@ func ParseDraft(d []byte) (draft *document.Draft, draftid string, err error) {
                return
        }
        draftid = document.Id(signed)
                return
        }
        draftid = document.Id(signed)
-/*
-       k, err := db.Get("key", draft.Drawer)
-       if err != nil {
-               return
-       }
-       kr, err := openpgp.ReadKeyRing(bytes.NewBuffer(k))
-       if err != nil {
-               // internal error: pubkey cannot be parsed
-               return
-       }
-       cleaned, err = document.Verify(signed, kr)
-       if err != nil {
-               return
-       }
-       // TODO: verify issuer
-       _, err = db.Get("key", draft.Beneficiary)
-       if err != nil {
-               return
-       }
-*/
+       /*
+               k, err := db.Get("key", draft.Drawer)
+               if err != nil {
+                       return
+               }
+               kr, err := openpgp.ReadKeyRing(bytes.NewBuffer(k))
+               if err != nil {
+                       // internal error: pubkey cannot be parsed
+                       return
+               }
+               cleaned, err = document.Verify(signed, kr)
+               if err != nil {
+                       return
+               }
+               // TODO: verify issuer
+               _, err = db.Get("key", draft.Beneficiary)
+               if err != nil {
+                       return
+               }
+       */
        // TODO: do various format checks (AuthorizedBy check etc)
        if draft.Amount <= 0 || draft.Amount >= IntLimit {
                err = fmt.Errorf("draft amount is invalid: %d", draft.Amount)
        // TODO: do various format checks (AuthorizedBy check etc)
        if draft.Amount <= 0 || draft.Amount >= IntLimit {
                err = fmt.Errorf("draft amount is invalid: %d", draft.Amount)
@@ -128,23 +128,23 @@ func ParseDebitCert(d []byte) (cert *document.DebitCert, certid string, err erro
                err = fmt.Errorf("ParseDebitCert: expected a debit docuent")
                return
        }
                err = fmt.Errorf("ParseDebitCert: expected a debit docuent")
                return
        }
-/*
-       // TODO: keep our key at hand
-       k, err := db.Get("key", cert.AuthorizedBy)
-       if err != nil {
-               return
-       }
-       kr, err := openpgp.ReadKeyRing(bytes.NewBuffer(k))
-       if err != nil {
-               // internal error: pubkey cannot be parsed
-               return
-       }
-       // must clean up to make sure the hash is ok
-       cleaned, err = document.Verify(signed, kr)
-       if err != nil {
-               return
-       }
-*/
+       /*
+               // TODO: keep our key at hand
+               k, err := db.Get("key", cert.AuthorizedBy)
+               if err != nil {
+                       return
+               }
+               kr, err := openpgp.ReadKeyRing(bytes.NewBuffer(k))
+               if err != nil {
+                       // internal error: pubkey cannot be parsed
+                       return
+               }
+               // must clean up to make sure the hash is ok
+               cleaned, err = document.Verify(signed, kr)
+               if err != nil {
+                       return
+               }
+       */
        certid = document.Id(signed)
        return
 }
        certid = document.Id(signed)
        return
 }
@@ -160,7 +160,7 @@ func NewDebitCert(draftid string, draft *document.Draft) (*document.DebitCert, e
        cert.Draft = draftid
        cert.Beneficiary = draft.Beneficiary
 
        cert.Draft = draftid
        cert.Beneficiary = draft.Beneficiary
 
-       oid, err := db.Get("certid/last", draft.Drawer)
+       oid, err := db.Get("certby/key", draft.Drawer)
        oldcertid := string(oid)
        if err != nil {
                // first cert: drawer is issuer
        oldcertid := string(oid)
        if err != nil {
                // first cert: drawer is issuer
@@ -218,7 +218,7 @@ func NewCreditCert(draftid string, draft *document.Draft, dcertid string, dcert
        cert.Drawer = dcert.Holder
        cert.DebitCert = dcertid
 
        cert.Drawer = dcert.Holder
        cert.DebitCert = dcertid
 
-       oid, err := db.Get("certid/last", dcert.Beneficiary)
+       oid, err := db.Get("certby/key", dcert.Beneficiary)
        oldcertid := string(oid)
        if err != nil {
                // this is the first cert
        oldcertid := string(oid)
        if err != nil {
                // this is the first cert
@@ -260,7 +260,6 @@ func NewCreditCert(draftid string, draft *document.Draft, dcertid string, dcert
        return cert, nil
 }
 
        return cert, nil
 }
 
-// TODO: draft ref
 func EvalDraft(d []byte, sk *openpgp.Entity) (r []byte, err error) {
        draft, draftid, err := ParseDraft(d)
        if err != nil {
 func EvalDraft(d []byte, sk *openpgp.Entity) (r []byte, err error) {
        draft, draftid, err := ParseDraft(d)
        if err != nil {
@@ -277,6 +276,17 @@ func EvalDraft(d []byte, sk *openpgp.Entity) (r []byte, err error) {
                // internal error
                return
        }
                // internal error
                return
        }
+       // TODO: db.Insert: fails if key exists
+       _, err = db.Get("draftby/nonce", draft.Nonce)
+       if err == nil {
+               err = fmt.Errorf("draft nonce is not unique")
+               return
+       }
+       err = db.Set("draftby/nonce", draft.Nonce, d)
+       if err != nil {
+               // internal error
+               return
+       }
 
        // debit cert
        cert, err := NewDebitCert(draftid, draft)
 
        // debit cert
        cert, err := NewDebitCert(draftid, draft)
@@ -290,18 +300,18 @@ func EvalDraft(d []byte, sk *openpgp.Entity) (r []byte, err error) {
                // internal error
                return
        }
                // internal error
                return
        }
-       err = db.Set("certid/debit", draftid, []byte(certid))
+       err = db.Set("certby/draft", draftid, []byte(certid))
        if err != nil {
                // internal error
                return
        }
        if err != nil {
                // internal error
                return
        }
-       err = db.Set("certid/last", cert.Holder, []byte(certid))
+       err = db.Set("certby/key", cert.Holder, []byte(certid))
        if err != nil {
                // internal error
                return
        }
        // TODO: append?
        if err != nil {
                // internal error
                return
        }
        // TODO: append?
-       err = db.Set("certid/all", fmt.Sprintf("%s.%09d", cert.Holder, cert.Serial), []byte(certid))
+       err = db.Set("certby/key.serial", fmt.Sprintf("%s.%09d", cert.Holder, cert.Serial), []byte(certid))
        if err != nil {
                // internal error
                return
        if err != nil {
                // internal error
                return
@@ -356,18 +366,18 @@ func EvalDebitCert(d []byte, sk *openpgp.Entity) (r []byte, err error) {
                // internal error
                return
        }
                // internal error
                return
        }
-       err = db.Set("certid/credit", dcertid, []byte(certid))
+       err = db.Set("certby/debit", dcertid, []byte(certid))
        if err != nil {
                // internal error
                return
        }
        if err != nil {
                // internal error
                return
        }
-       err = db.Set("certid/last", cert.Holder, []byte(certid))
+       err = db.Set("certby/key", cert.Holder, []byte(certid))
        if err != nil {
                // internal error
                return
        }
        // TODO: append?
        if err != nil {
                // internal error
                return
        }
        // TODO: append?
-       err = db.Set("certid/all", fmt.Sprintf("%s.%09d", cert.Holder, cert.Serial), []byte(certid))
+       err = db.Set("certby/key.serial", fmt.Sprintf("%s.%09d", cert.Holder, cert.Serial), []byte(certid))
        if err != nil {
                // internal error
                return
        if err != nil {
                // internal error
                return
@@ -375,8 +385,8 @@ func EvalDebitCert(d []byte, sk *openpgp.Entity) (r []byte, err error) {
        return
 }
 
        return
 }
 
-func Init() (err error) {
-       db, err = store.Open("teststore")
+func Init(rootdir string) (err error) {
+       db, err = store.Open(rootdir)
        if err != nil {
                return
        }
        if err != nil {
                return
        }
@@ -392,27 +402,31 @@ func Init() (err error) {
        if err != nil {
                return
        }
        if err != nil {
                return
        }
-       err = db.Ensure("certid/credit")
+       err = db.Ensure("certby/draft")
+       if err != nil {
+               return
+       }
+       err = db.Ensure("certby/debit")
        if err != nil {
                return
        }
        if err != nil {
                return
        }
-       err = db.Ensure("certid/debit")
+       err = db.Ensure("certby/key")
        if err != nil {
                return
        }
        if err != nil {
                return
        }
-       err = db.Ensure("certid/last")
+       err = db.Ensure("certby/key.serial")
        if err != nil {
                return
        }
        if err != nil {
                return
        }
-       err = db.Ensure("certid/all")
+       err = db.Ensure("draftby/nonce")
        if err != nil {
                return
        }
        if err != nil {
                return
        }
-       err = db.Ensure("fprlist/64")
+       err = db.Ensure("keysby/64")
        if err != nil {
                return
        }
        if err != nil {
                return
        }
-       err = db.Ensure("fprlist/32")
+       err = db.Ensure("keysby/32")
        if err != nil {
                return
        }
        if err != nil {
                return
        }