@ -6,13 +6,13 @@ import (
"log"
"log"
"net/http"
"net/http"
"strconv"
"strconv"
"strings"
"time"
"time"
tree "github.com/vocdoni/dvote-census/tree"
tree "github.com/vocdoni/dvote-census/tree"
signature "github.com/vocdoni/dvote-relay/crypto/signature"
signature "github.com/vocdoni/dvote-relay/crypto/signature"
)
)
const hashSize = 32
const authTimeWindow = 10 // Time window (seconds) in which TimeStamp will be accepted if auth enabled
const authTimeWindow = 10 // Time window (seconds) in which TimeStamp will be accepted if auth enabled
var MkTrees map [ string ] * tree . Tree // MerkleTree dvote-census library
var MkTrees map [ string ] * tree . Tree // MerkleTree dvote-census library
var Signatures map [ string ] string
var Signatures map [ string ] string
@ -20,6 +20,7 @@ var Signature signature.SignKeys // Signature dvote-relay library
type Claim struct {
type Claim struct {
CensusID string ` json:"censusID" ` // References to MerkleTree namespace
CensusID string ` json:"censusID" ` // References to MerkleTree namespace
RootHash string ` json:"rootHash" ` // References to MerkleTree rootHash
ClaimData string ` json:"claimData" ` // Data to add to the MerkleTree
ClaimData string ` json:"claimData" ` // Data to add to the MerkleTree
ProofData string ` json:"proofData" ` // MerkleProof to check
ProofData string ` json:"proofData" ` // MerkleProof to check
TimeStamp string ` json:"timeStamp" ` // Unix TimeStamp in seconds
TimeStamp string ` json:"timeStamp" ` // Unix TimeStamp in seconds
@ -98,8 +99,9 @@ func claimHandler(w http.ResponseWriter, req *http.Request, op string) {
}
}
// Process data
// Process data
log . Printf ( "Received censusID:{%s} claimData:{%s} proofData:{%s} timeStamp:{%s} signature:{%s}\n" ,
c . CensusID , c . ClaimData , c . ProofData , c . TimeStamp , c . Signature )
log . Printf ( "censusID:{%s} rootHash:{%s} claimData:{%s} proofData:{%s} timeStamp:{%s} signature:{%s}\n" ,
c . CensusID , c . RootHash , c . ClaimData , c . ProofData , c . TimeStamp , c . Signature )
authString := fmt . Sprintf ( "%s%s%s%s" , c . CensusID , c . RootHash , c . ClaimData , c . TimeStamp )
resp . Error = false
resp . Error = false
resp . Response = ""
resp . Response = ""
censusFound := false
censusFound := false
@ -114,14 +116,8 @@ func claimHandler(w http.ResponseWriter, req *http.Request, op string) {
}
}
if op == "add" {
if op == "add" {
msg := fmt . Sprintf ( "%s%s%s" , c . CensusID , c . ClaimData , c . TimeStamp )
if auth := checkAuth ( c . TimeStamp , c . Signature , Signatures [ c . CensusID ] , msg ) ; auth {
if strings . HasPrefix ( c . CensusID , "0x" ) {
resp . Error = true
resp . Response = "add claim to snapshot is not allowed"
} else {
err = MkTrees [ c . CensusID ] . AddClaim ( [ ] byte ( c . ClaimData ) )
}
if auth := checkAuth ( c . TimeStamp , c . Signature , Signatures [ c . CensusID ] , authString ) ; auth {
err = MkTrees [ c . CensusID ] . AddClaim ( [ ] byte ( c . ClaimData ) )
} else {
} else {
resp . Error = true
resp . Error = true
resp . Response = "invalid authentication"
resp . Response = "invalid authentication"
@ -129,61 +125,107 @@ func claimHandler(w http.ResponseWriter, req *http.Request, op string) {
}
}
if op == "gen" {
if op == "gen" {
resp . Response , err = MkTrees [ c . CensusID ] . GenProof ( [ ] byte ( c . ClaimData ) )
var t * tree . Tree
var err error
if len ( c . RootHash ) > 1 { //if rootHash specified
t , err = MkTrees [ c . CensusID ] . Snapshot ( c . RootHash )
if err != nil {
log . Printf ( "Snapshot error: %s" , err . Error ( ) )
resp . Error = true
resp . Response = "invalid root hash"
reply ( & resp , w )
return
}
} else { //if rootHash not specified use current tree
t = MkTrees [ c . CensusID ]
}
resp . Response , err = t . GenProof ( [ ] byte ( c . ClaimData ) )
if err != nil {
resp . Error = true
resp . Response = err . Error ( )
reply ( & resp , w )
return
}
}
}
if op == "root" {
if op == "root" {
resp . Response = MkTrees [ c . CensusID ] . GetRoot ( )
resp . Response = MkTrees [ c . CensusID ] . GetRoot ( )
}
}
if op == "idx" {
}
if op == "dump" {
if op == "dump" {
values , err := MkTrees [ c . CensusID ] . Dump ( )
var t * tree . Tree
if auth := checkAuth ( c . TimeStamp , c . Signature , Signatures [ c . CensusID ] , authString ) ; ! auth {
resp . Error = true
resp . Response = "invalid authentication"
reply ( & resp , w )
return
}
if len ( c . RootHash ) > 1 { //if rootHash specified
t , err = MkTrees [ c . CensusID ] . Snapshot ( c . RootHash )
if err != nil {
log . Printf ( "Snapshot error: %s" , err . Error ( ) )
resp . Error = true
resp . Response = "invalid root hash"
reply ( & resp , w )
return
}
} else { //if rootHash not specified use current merkletree
t = MkTrees [ c . CensusID ]
}
//dump the claim data and return it
values , err := t . Dump ( )
if err != nil {
if err != nil {
resp . Error = true
resp . Error = true
resp . Response = fmt . Sprint ( err )
resp . Response = err . Error ( )
} else {
} else {
jValues , err := json . Marshal ( values )
jValues , err := json . Marshal ( values )
if err != nil {
if err != nil {
resp . Error = true
resp . Error = true
resp . Response = fmt . Sprint ( err )
resp . Response = err . Error ( )
} else {
} else {
resp . Response = string ( jValues )
resp . Response = string ( jValues )
}
}
}
}
}
}
if op == "snapshot" {
msg := fmt . Sprintf ( "%s%s%s" , c . CensusID , c . ClaimData , c . TimeStamp )
if auth := checkAuth ( c . TimeStamp , c . Signature , Signatures [ c . CensusID ] , msg ) ; auth {
if strings . HasPrefix ( c . CensusID , "0x" ) {
if op == "check" {
if len ( c . ProofData ) < 1 {
resp . Error = true
resp . Response = "proofData not provided"
reply ( & resp , w )
return
}
var t * tree . Tree
if len ( c . RootHash ) > 1 { //if rootHash specified
t , err = MkTrees [ c . CensusID ] . Snapshot ( c . RootHash )
if err != nil {
log . Printf ( "Snapshot error: %s" , err . Error ( ) )
resp . Error = true
resp . Error = true
resp . Response = "snapshot an snapshot makes no sense"
} else {
snapshotNamespace , err := MkTrees [ c . CensusID ] . Snapshot ( )
if err != nil {
resp . Error = true
resp . Response = fmt . Sprint ( err )
} else {
resp . Response = snapshotNamespace
}
resp . Response = "invalid root hash"
reply ( & resp , w )
return
}
}
} else {
resp . Error = true
resp . Response = "invalid authentication"
} else { //if rootHash not specified use current merkletree
t = MkTrees [ c . CensusID ]
}
}
}
if op == "check" {
if len ( c . ProofData ) < 1 {
validProof , err := t . CheckProof ( [ ] byte ( c . ClaimData ) , c . ProofData )
if err != nil {
resp . Error = true
resp . Error = true
resp . Response = "proofData not provided"
resp . Response = err . Error ( )
reply ( & resp , w )
return
}
if validProof {
resp . Response = "valid"
} else {
} else {
validProof , _ := MkTrees [ c . CensusID ] . CheckProof ( [ ] byte ( c . ClaimData ) , c . ProofData )
if validProof {
resp . Response = "valid"
} else {
resp . Response = "invalid"
}
resp . Response = "invalid"
}
}
}
}
@ -211,9 +253,6 @@ func Listen(port int, proto string) {
http . HandleFunc ( "/getRoot" , func ( w http . ResponseWriter , r * http . Request ) {
http . HandleFunc ( "/getRoot" , func ( w http . ResponseWriter , r * http . Request ) {
claimHandler ( w , r , "root" )
claimHandler ( w , r , "root" )
} )
} )
http . HandleFunc ( "/snapshot" , func ( w http . ResponseWriter , r * http . Request ) {
claimHandler ( w , r , "snapshot" )
} )
http . HandleFunc ( "/dump" , func ( w http . ResponseWriter , r * http . Request ) {
http . HandleFunc ( "/dump" , func ( w http . ResponseWriter , r * http . Request ) {
claimHandler ( w , r , "dump" )
claimHandler ( w , r , "dump" )
} )
} )