"bytes"
"crypto/openpgp"
"epoint/document"
+ "epoint/dsakey"
"epoint/store"
"fmt"
"time"
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 {
}
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
}
}
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
}
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
return
}
draftid = document.Id(signed)
-/*
+
k, err := db.Get("key", draft.Drawer)
if err != nil {
return
// 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)
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
}
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
}
// 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
}
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
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
}
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
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 {
_, 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
// 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)
// 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
// 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
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
}
- 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
}