check signatures, addkeys, only drawer.nonce must be uniq
authornsz <nsz@port70.net>
Mon, 5 Dec 2011 19:48:53 +0000 (20:48 +0100)
committernsz <nsz@port70.net>
Mon, 5 Dec 2011 19:48:53 +0000 (20:48 +0100)
epoint-server.go
logic/logic.go

index 786c70c..425ea45 100644 (file)
@@ -126,6 +126,10 @@ func main() {
        if err != nil {
                log.Fatal(err)
        }
+       err = logic.StoreSk(serverkey)
+       if err != nil {
+               log.Fatal(err)
+       }
 
        // TODO: url from key
        f, err := os.Create(rootdir + "/form.html")
index c09054f..2099463 100644 (file)
@@ -6,6 +6,7 @@ import (
        "bytes"
        "crypto/openpgp"
        "epoint/document"
+       "epoint/dsakey"
        "epoint/store"
        "fmt"
        "time"
@@ -16,6 +17,29 @@ const IntLimit = 1e15
 
 var db *store.Conn
 
+func StoreSk(sk *openpgp.Entity) (err error) {
+       // TODO: initkey should save serverkey in db
+       b := new(bytes.Buffer)
+       err = sk.Serialize(b)
+       if err != nil {
+               return
+       }
+       return db.Set("key", fmt.Sprintf("%X", sk.PrimaryKey.Fingerprint), b.Bytes())
+}
+
+func GetKeys(fpr string) (es openpgp.EntityList, err error) {
+       b, err := db.Get("key", fpr)
+       if err != nil {
+               return
+       }
+       es, err = openpgp.ReadKeyRing(bytes.NewBuffer(b))
+       if err != nil {
+               // internal error: pubkey cannot be parsed
+               return
+       }
+       return
+}
+
 func AddKeys(d []byte) (err error) {
        entities, err := openpgp.ReadArmoredKeyRing(bytes.NewBuffer(d))
        if err != nil {
@@ -28,12 +52,30 @@ func AddKeys(d []byte) (err error) {
        }
        for _, e := range entities {
                // TODO: various checks..
+               isIssuer, issuer, denom, err1 := dsakey.CheckEntity(e)
+               err = err1
+               if err != nil {
+                       // TODO..
+                       continue
+               }
+               if !isIssuer {
+                       es, err := GetKeys(issuer)
+                       if err != nil {
+                               // TODO..
+                               continue
+                       }
+                       ok, _, den, err := dsakey.CheckEntity(es[0])
+                       if !ok || err != nil || den != denom {
+                               // TODO..
+                               continue
+                       }
+               }
                b := new(bytes.Buffer)
                err = e.Serialize(b)
                if err != nil {
                        return
                }
-               fpr := fmt.Sprintf("%040X", e.PrimaryKey.Fingerprint)
+               fpr := fmt.Sprintf("%X", e.PrimaryKey.Fingerprint)
                err = db.Set("key", fpr, b.Bytes())
                if err != nil {
                        return
@@ -90,26 +132,45 @@ func ParseDraft(d []byte) (draft *document.Draft, draftid string, err error) {
                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
+       }
+       err = document.Verify(signed, kr)
+       if err != nil {
+               return
+       }
+       _, issuer, denom, err := dsakey.CheckEntity(kr[0])
+       if err != nil {
+               return
+       }
+       k, err = db.Get("key", draft.Beneficiary)
+       if err != nil {
+               return
+       }
+       kr, err = openpgp.ReadKeyRing(bytes.NewBuffer(k))
+       if err != nil {
+               // internal error: pubkey cannot be parsed
+               return
+       }
+       _, issuer2, denom2, err := dsakey.CheckEntity(kr[0])
+       if err != nil {
+               return
+       }
+       if draft.Issuer != issuer ||
+               draft.Issuer != issuer2 ||
+               draft.Denomination != denom ||
+               draft.Denomination != denom2 {
+               err = fmt.Errorf("Issuer or denomination mismatch")
+               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)
@@ -128,23 +189,23 @@ func ParseDebitCert(d []byte) (cert *document.DebitCert, certid string, err erro
                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
-               }
-       */
+
+       k, err := db.Get("key", cert.AuthorizedBy)
+       if err != nil {
+               return
+       }
+       // TODO: keep our key at hand
+       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
+       err = document.Verify(signed, kr)
+       if err != nil {
+               return
+       }
+
        certid = document.Id(signed)
        return
 }
@@ -268,6 +329,7 @@ func EvalDraft(d []byte, sk *openpgp.Entity) (r []byte, err error) {
        _, err = db.Get("draft", draftid)
        if err == nil {
                // found
+               // TODO: certby/draft might not be ready even if draft is there
                return CertByDraft(draftid)
        }
        // if draft is ok we save it
@@ -277,12 +339,13 @@ func EvalDraft(d []byte, sk *openpgp.Entity) (r []byte, err error) {
                return
        }
        // TODO: db.Insert: fails if key exists
-       _, err = db.Get("draftby/nonce", draft.Nonce)
+       s := fmt.Sprintf("%s.%s", draft.Drawer, draft.Nonce)
+       _, err = db.Get("draftby/key.nonce", s)
        if err == nil {
                err = fmt.Errorf("draft nonce is not unique")
                return
        }
-       err = db.Set("draftby/nonce", draft.Nonce, d)
+       err = db.Set("draftby/key.nonce", s, d)
        if err != nil {
                // internal error
                return
@@ -418,7 +481,7 @@ func Init(rootdir string) (err error) {
        if err != nil {
                return
        }
-       err = db.Ensure("draftby/nonce")
+       err = db.Ensure("draftby/key.nonce")
        if err != nil {
                return
        }