aboutsummaryrefslogtreecommitdiff
path: root/cmd/taler-auditor-offline-signing
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/taler-auditor-offline-signing')
-rw-r--r--cmd/taler-auditor-offline-signing/main.go89
1 files changed, 74 insertions, 15 deletions
diff --git a/cmd/taler-auditor-offline-signing/main.go b/cmd/taler-auditor-offline-signing/main.go
index 8b21be8..fdb632a 100644
--- a/cmd/taler-auditor-offline-signing/main.go
+++ b/cmd/taler-auditor-offline-signing/main.go
@@ -49,6 +49,7 @@ type Input struct {
ReserveClosingDelay RelativeTime `json:"reserve_closing_delay"`
Signkeys []SignKey `json:"signkeys"`
Denoms []DenomKey `json:"denoms"`
+ Auditors []Auditor `json:"auditors"`
// Recoup []??? `json:"recoup"`
} `json:"arguments"`
}
@@ -75,6 +76,31 @@ type DenomKey struct {
MasterSig EdDSASignature `json:"master_sig"`
}
+type Auditor struct {
+ AuditorName string `json:"auditor_name"`
+ AuditorPub EdDSAPublicKey `json:"auditor_pub"`
+ AuditorUrl string `json:"auditor_url"`
+ DenominationKeys []struct {
+ DenomPubH SHA512Hash `json:"denom_pub_h"`
+ AuditorSig EdDSASignature `json:"auditor_sig"`
+ } `json:"denomination_keys"`
+}
+
+func (in *Input) checkAuditor(url string, local EdDSAPublicKey) (e error) {
+
+ for _, au := range in.Arguments.Auditors {
+ if au.AuditorUrl == url && au.AuditorPub.Equal(ed25519.PublicKey(local)) {
+ return nil
+ } else if au.AuditorUrl == url {
+ return fmt.Errorf("Public key mismatch for auditor %q! Local: %s, JSON: %s\n", url, local, au.AuditorPub)
+ } else if au.AuditorPub.Equal(ed25519.PublicKey(local)) {
+ return fmt.Errorf("URL mismatch auditor with pub-key %s! Local: %v, JSON: %v\n", au.AuditorPub, url, au.AuditorUrl)
+ }
+ }
+
+ return fmt.Errorf("No such auditor found! URL: %q, PubKey: %v\n", url, local)
+}
+
type AbsoluteTime struct {
// TODO: en-/decode "never"
TMs uint64 `json:"t_ms"`
@@ -87,6 +113,10 @@ type RelativeTime struct {
type EdDSAPublicKey ed25519.PublicKey
+func (ep *EdDSAPublicKey) Equal(p ed25519.PublicKey) bool {
+ return ((*ed25519.PublicKey)(ep)).Equal(p)
+}
+
func (ep *EdDSAPublicKey) UnmarshalJSON(in []byte) (e error) {
var buf []byte
// decode crockford.base32
@@ -112,6 +142,14 @@ func (ep *EdDSAPublicKey) MarshalJSON() ([]byte, error) {
return buf, nil
}
+func (ep EdDSAPublicKey) String() string {
+ enc, err := crockfordEncode([]byte(ep))
+ if err != nil {
+ return fmt.Sprintf("[error crockfordEncode:%v] pub:%v", err, []byte(ep))
+ }
+ return string(enc)
+}
+
const CURRENCY_LEN = 12
type Amount struct {
@@ -442,6 +480,17 @@ type SignOperation struct {
type SHA512Hash [sha512.Size]byte
+func (h *SHA512Hash) UnmarshalJSON(in []byte) (e error) {
+ var buf []byte
+ // decode crockford.base32
+ if buf, e = crockfordDecode(bytes.Trim(in, `"`)); e != nil {
+ return fmt.Errorf("couldn't decode SHA512 as crockford.base32: %v (%v)", e, string(in))
+ }
+
+ copy([]byte(h[:]), buf[:sha512.Size])
+ return nil
+}
+
func (h *SHA512Hash) MarshalJSON() ([]byte, error) {
enc, err := crockfordEncode((*h)[:])
if err != nil {
@@ -483,7 +532,7 @@ func Verify(denom *DenomKey, master *EdDSAPublicKey, sig []byte) bool {
4 + // purpose
ed25519.PublicKeySize + // master
4*8 + // start and expire*
- 5*(8+4+len(denom.Value.Currency)) + // value and fee*
+ 5*(8+4+CURRENCY_LEN) + // value and fee*
sha512.Size // denomHash
buf := make([]byte, size)
@@ -503,13 +552,14 @@ func Verify(denom *DenomKey, master *EdDSAPublicKey, sig []byte) bool {
be.PutUint64(buf[n:], v*1000) // milli -> micro
n += 8
}
- for _, v := range [][]byte{
- denom.Value.Binary(),
- denom.FeeWithdraw.Binary(),
- denom.FeeDeposit.Binary(),
- denom.FeeRefresh.Binary(),
- denom.FeeRefund.Binary(),
+ for _, f := range [](func() []byte){
+ denom.Value.Binary,
+ denom.FeeWithdraw.Binary,
+ denom.FeeDeposit.Binary,
+ denom.FeeRefresh.Binary,
+ denom.FeeRefund.Binary,
} {
+ v := f()
copy(buf[n:], v)
n += len(v)
}
@@ -551,7 +601,7 @@ func SignDenom(denom *DenomKey, ahash SHA512Hash, master *EdDSAPublicKey, pk *ed
sha512.Size + // auditor_url_hash
ed25519.PublicKeySize + // master
4*8 + // start and expire*
- 5*(8+4+len(denom.Value.Currency)) + // value and fee*
+ 5*(8+4+CURRENCY_LEN) + // value and fee*
sha512.Size // denomHash
buf := make([]byte, size)
@@ -573,17 +623,21 @@ func SignDenom(denom *DenomKey, ahash SHA512Hash, master *EdDSAPublicKey, pk *ed
be.PutUint64(buf[n:], v*1000) // milli -> micro
n += 8
}
- for _, v := range [][]byte{
- denom.Value.Binary(),
- denom.FeeWithdraw.Binary(),
- denom.FeeDeposit.Binary(),
- denom.FeeRefresh.Binary(),
- denom.FeeRefund.Binary(),
+ for _, f := range [](func() []byte){
+ denom.Value.Binary,
+ denom.FeeWithdraw.Binary,
+ denom.FeeDeposit.Binary,
+ denom.FeeRefresh.Binary,
+ denom.FeeRefund.Binary,
} {
+ v := f()
copy(buf[n:], v)
n += len(v)
}
bin := denom.DenomPub.Binary()
+ // Future:
+ // bin = append(bin, 0, 0, 0, 0) // age mask
+ // bin = append(bin, 0, 0, 0, 1) // cipher == RSA
hash := sha512.Sum512(bin)
copy(buf[n:], hash[:])
@@ -649,7 +703,7 @@ func main() {
var dec *json.Decoder
input := new(Input)
- if *injson == "-" {
+ if *injson == "-" || *injson == "" {
dec = json.NewDecoder(os.Stdin)
} else {
f, e := os.Open(*injson)
@@ -665,6 +719,11 @@ func main() {
log.Fatal(e)
}
+ e = input.checkAuditor(*url, EdDSAPublicKey(pub))
+ if e != nil {
+ log.Fatal(e)
+ }
+
output, err := Sign(input, *url, pk)
if err != nil {
log.Fatalf("error signing: %v", err)