added sanity check for auditor url and pub key

This commit is contained in:
Özgür Kesim 2022-01-25 17:48:47 +01:00
parent 18af4066bb
commit 2d6022e6b2
Signed by: oec
GPG Key ID: 3D76A56D79EDD9D7

View File

@ -49,6 +49,7 @@ type Input struct {
ReserveClosingDelay RelativeTime `json:"reserve_closing_delay"` ReserveClosingDelay RelativeTime `json:"reserve_closing_delay"`
Signkeys []SignKey `json:"signkeys"` Signkeys []SignKey `json:"signkeys"`
Denoms []DenomKey `json:"denoms"` Denoms []DenomKey `json:"denoms"`
Auditors []Auditor `json:"auditors"`
// Recoup []??? `json:"recoup"` // Recoup []??? `json:"recoup"`
} `json:"arguments"` } `json:"arguments"`
} }
@ -75,6 +76,31 @@ type DenomKey struct {
MasterSig EdDSASignature `json:"master_sig"` 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 { type AbsoluteTime struct {
// TODO: en-/decode "never" // TODO: en-/decode "never"
TMs uint64 `json:"t_ms"` TMs uint64 `json:"t_ms"`
@ -87,6 +113,10 @@ type RelativeTime struct {
type EdDSAPublicKey ed25519.PublicKey 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) { func (ep *EdDSAPublicKey) UnmarshalJSON(in []byte) (e error) {
var buf []byte var buf []byte
// decode crockford.base32 // decode crockford.base32
@ -112,6 +142,14 @@ func (ep *EdDSAPublicKey) MarshalJSON() ([]byte, error) {
return buf, nil 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 const CURRENCY_LEN = 12
type Amount struct { type Amount struct {
@ -442,6 +480,17 @@ type SignOperation struct {
type SHA512Hash [sha512.Size]byte 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) { func (h *SHA512Hash) MarshalJSON() ([]byte, error) {
enc, err := crockfordEncode((*h)[:]) enc, err := crockfordEncode((*h)[:])
if err != nil { if err != nil {
@ -483,7 +532,7 @@ func Verify(denom *DenomKey, master *EdDSAPublicKey, sig []byte) bool {
4 + // purpose 4 + // purpose
ed25519.PublicKeySize + // master ed25519.PublicKeySize + // master
4*8 + // start and expire* 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 sha512.Size // denomHash
buf := make([]byte, size) 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 be.PutUint64(buf[n:], v*1000) // milli -> micro
n += 8 n += 8
} }
for _, v := range [][]byte{ for _, f := range [](func() []byte){
denom.Value.Binary(), denom.Value.Binary,
denom.FeeWithdraw.Binary(), denom.FeeWithdraw.Binary,
denom.FeeDeposit.Binary(), denom.FeeDeposit.Binary,
denom.FeeRefresh.Binary(), denom.FeeRefresh.Binary,
denom.FeeRefund.Binary(), denom.FeeRefund.Binary,
} { } {
v := f()
copy(buf[n:], v) copy(buf[n:], v)
n += len(v) n += len(v)
} }
@ -551,7 +601,7 @@ func SignDenom(denom *DenomKey, ahash SHA512Hash, master *EdDSAPublicKey, pk *ed
sha512.Size + // auditor_url_hash sha512.Size + // auditor_url_hash
ed25519.PublicKeySize + // master ed25519.PublicKeySize + // master
4*8 + // start and expire* 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 sha512.Size // denomHash
buf := make([]byte, size) 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 be.PutUint64(buf[n:], v*1000) // milli -> micro
n += 8 n += 8
} }
for _, v := range [][]byte{ for _, f := range [](func() []byte){
denom.Value.Binary(), denom.Value.Binary,
denom.FeeWithdraw.Binary(), denom.FeeWithdraw.Binary,
denom.FeeDeposit.Binary(), denom.FeeDeposit.Binary,
denom.FeeRefresh.Binary(), denom.FeeRefresh.Binary,
denom.FeeRefund.Binary(), denom.FeeRefund.Binary,
} { } {
v := f()
copy(buf[n:], v) copy(buf[n:], v)
n += len(v) n += len(v)
} }
bin := denom.DenomPub.Binary() 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) hash := sha512.Sum512(bin)
copy(buf[n:], hash[:]) copy(buf[n:], hash[:])
@ -649,7 +703,7 @@ func main() {
var dec *json.Decoder var dec *json.Decoder
input := new(Input) input := new(Input)
if *injson == "-" { if *injson == "-" || *injson == "" {
dec = json.NewDecoder(os.Stdin) dec = json.NewDecoder(os.Stdin)
} else { } else {
f, e := os.Open(*injson) f, e := os.Open(*injson)
@ -665,6 +719,11 @@ func main() {
log.Fatal(e) log.Fatal(e)
} }
e = input.checkAuditor(*url, EdDSAPublicKey(pub))
if e != nil {
log.Fatal(e)
}
output, err := Sign(input, *url, pk) output, err := Sign(input, *url, pk)
if err != nil { if err != nil {
log.Fatalf("error signing: %v", err) log.Fatalf("error signing: %v", err)