X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=logic%2Flogic.go;h=602f458b836e714af68eb3c657ab2e94dcfefdff;hb=2dba8527a9eff1f9931ccbb25df34dcb618460a7;hp=a9fd15b409c6655fad681a6b810b2d46c6402caa;hpb=8c18ef4b933521326f7b352829305dcaaeb8e7c4;p=epoint diff --git a/logic/logic.go b/logic/logic.go index a9fd15b..602f458 100644 --- a/logic/logic.go +++ b/logic/logic.go @@ -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,21 +52,39 @@ 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 } - 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 } - 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 } @@ -51,7 +93,7 @@ func AddKeys(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 @@ -65,7 +107,7 @@ func CertByDraft(draftid 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 @@ -90,7 +132,7 @@ 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 @@ -100,16 +142,35 @@ func ParseDraft(d []byte) (draft *document.Draft, draftid string, err error) { // internal error: pubkey cannot be parsed return } - cleaned, err = document.Verify(signed, kr) + 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 } - // TODO: verify issuer - _, err = db.Get("key", draft.Beneficiary) + 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 } + // 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 - cleaned, err = document.Verify(signed, kr) + err = document.Verify(signed, kr) if err != nil { return } -*/ + certid = document.Id(signed) return } @@ -160,7 +221,7 @@ func NewDebitCert(draftid string, draft *document.Draft) (*document.DebitCert, e 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 @@ -183,6 +244,10 @@ func NewDebitCert(draftid string, draft *document.Draft) (*document.DebitCert, e } // TODO: this is a hack oldcert, err := document.ToCert(iv) + if err != nil { + // internal error + return nil, err + } // TODO: sanity checks? oldcert.Holder == draft.Drawer cert.Serial = oldcert.Serial + 1 cert.Balance = oldcert.Balance + cert.Difference @@ -194,7 +259,7 @@ func NewDebitCert(draftid string, draft *document.Draft) (*document.DebitCert, e } cert.LastDebitSerial = oldcert.LastDebitSerial cert.LastCreditSerial = oldcert.LastCreditSerial - if oldcert.IsDebit { + if _,ok := iv.(*document.DebitCert); ok { cert.LastDebitSerial = oldcert.Serial } else { cert.LastCreditSerial = oldcert.Serial @@ -218,7 +283,7 @@ func NewCreditCert(draftid string, draft *document.Draft, dcertid string, dcert 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 @@ -250,7 +315,7 @@ func NewCreditCert(draftid string, draft *document.Draft, dcertid string, dcert } cert.LastDebitSerial = oldcert.LastDebitSerial cert.LastCreditSerial = oldcert.LastCreditSerial - if oldcert.IsDebit { + if _,ok := iv.(*document.DebitCert); ok { cert.LastDebitSerial = oldcert.Serial } else { cert.LastCreditSerial = oldcert.Serial @@ -260,7 +325,6 @@ func NewCreditCert(draftid string, draft *document.Draft, dcertid string, dcert 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 { @@ -269,6 +333,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,6 +342,18 @@ func EvalDraft(d []byte, sk *openpgp.Entity) (r []byte, err error) { // internal error return } + // TODO: db.Insert: fails if key exists + 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/key.nonce", s, d) + if err != nil { + // internal error + return + } // debit cert cert, err := NewDebitCert(draftid, draft) @@ -290,18 +367,18 @@ func EvalDraft(d []byte, sk *openpgp.Entity) (r []byte, err error) { // 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 } - 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? - 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 @@ -356,18 +433,18 @@ func EvalDebitCert(d []byte, sk *openpgp.Entity) (r []byte, err error) { // 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 } - 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? - 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 @@ -375,8 +452,8 @@ func EvalDebitCert(d []byte, sk *openpgp.Entity) (r []byte, err error) { 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 } @@ -392,27 +469,31 @@ func Init() (err error) { 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 } - err = db.Ensure("certid/debit") + err = db.Ensure("certby/key") if err != nil { return } - err = db.Ensure("certid/last") + err = db.Ensure("certby/key.serial") if err != nil { return } - err = db.Ensure("certid/all") + err = db.Ensure("draftby/key.nonce") if err != nil { return } - err = db.Ensure("fprlist/64") + err = db.Ensure("keysby/64") if err != nil { return } - err = db.Ensure("fprlist/32") + err = db.Ensure("keysby/32") if err != nil { return }