Skip to content

Commit a6604c5

Browse files
authored
feat: apply canonical JSON Format (#117)
1 parent de1c010 commit a6604c5

File tree

5 files changed

+140
-3
lines changed

5 files changed

+140
-3
lines changed

Diff for: go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ require (
5656
github.com/cosmos/gorocksdb v1.2.0 // indirect
5757
github.com/cosmos/iavl v0.19.4 // indirect
5858
github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect
59+
github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7 // indirect
5960
github.com/danieljoos/wincred v1.1.2 // indirect
6061
github.com/davecgh/go-spew v1.1.1 // indirect
6162
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect

Diff for: go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
146146
github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM=
147147
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
148148
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
149+
github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7 h1:vU+EP9ZuFUCYE0NYLwTSob+3LNEJATzNfP/DC7SWGWI=
150+
github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
149151
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
150152
github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0=
151153
github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0=

Diff for: server/service/datadeal/json_canononical_test.go

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package datadeal
2+
3+
import (
4+
"crypto/sha256"
5+
"testing"
6+
7+
"github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestCanonicalJSON(t *testing.T) {
12+
jsonDataBz := []byte(
13+
`
14+
{
15+
"invalid_key_name": "name",
16+
"invalid_key_description": "description",
17+
"invalid_key_body": [{ "type": "markdown", "attributes": { "value": "val1" } }]
18+
}
19+
`)
20+
21+
// WhiteSpace before "name"
22+
jsonDataBzSpace := []byte(
23+
`
24+
{
25+
"invalid_key_name": "name",
26+
"invalid_key_description": "description",
27+
"invalid_key_body": [{ "type": "markdown", "attributes": { "value": "val1" } }]
28+
}
29+
`)
30+
31+
// WhiteSpace before "}" bracket
32+
jsonDataBzBracket := []byte(
33+
`
34+
{
35+
"invalid_key_name": "name",
36+
"invalid_key_description": "description",
37+
"invalid_key_body": [{ "type": "markdown", "attributes": { "value": "val1" } }]
38+
}
39+
`)
40+
41+
jsonDataBzOrder := []byte(
42+
`
43+
{
44+
"invalid_key_description": "description",
45+
"invalid_key_name": "name",
46+
"invalid_key_body": [{ "type": "markdown", "attributes": { "value": "val1" } }]
47+
}
48+
`)
49+
50+
jsonData, err := jsoncanonicalizer.Transform(jsonDataBz)
51+
require.NoError(t, err)
52+
dataHash := sha256.Sum256(jsonData)
53+
54+
jsonDataSpace, err := jsoncanonicalizer.Transform(jsonDataBzSpace)
55+
require.NoError(t, err)
56+
dataHashSpace := sha256.Sum256(jsonDataSpace)
57+
58+
jsonDataOrder, err := jsoncanonicalizer.Transform(jsonDataBzOrder)
59+
require.NoError(t, err)
60+
dataHashOrder := sha256.Sum256(jsonDataOrder)
61+
62+
jsonDataBracket, err := jsoncanonicalizer.Transform(jsonDataBzBracket)
63+
require.NoError(t, err)
64+
dataHashBracket := sha256.Sum256(jsonDataBracket)
65+
66+
require.Equal(t, dataHash, dataHashOrder)
67+
require.Equal(t, dataHash, dataHashSpace)
68+
require.Equal(t, dataHashOrder, dataHashSpace)
69+
require.Equal(t, dataHash, dataHashBracket)
70+
}
71+
72+
func TestCanonicalJSON_DataHash_Not_Equal(t *testing.T) {
73+
jsonDataBz := []byte(
74+
`
75+
{
76+
"invalid_key_name": "name",
77+
"invalid_key_description": "description",
78+
"invalid_key_body": [{ "type": "markdown", "attributes": { "value": "val1" } }]
79+
}
80+
`)
81+
82+
// WhiteSpace before "name"
83+
jsonDataBzSpace := []byte(
84+
`
85+
{
86+
"invalid_key_name": "name",
87+
"invalid_key_description": "description",
88+
"invalid_key_body": [{ "type": "markdown", "attributes": { "value": "val1" } }]
89+
}
90+
`)
91+
92+
// WhiteSpace before "}" bracket
93+
jsonDataBzBracket := []byte(
94+
`
95+
{
96+
"invalid_key_name": "name",
97+
"invalid_key_description": "description",
98+
"invalid_key_body": [{ "type": "markdown", "attributes": { "value": "val1" } }]
99+
}
100+
`)
101+
102+
jsonDataBzOrder := []byte(
103+
`
104+
{
105+
"invalid_key_description": "description",
106+
"invalid_key_name": "name",
107+
"invalid_key_body": [{ "type": "markdown", "attributes": { "value": "val1" } }]
108+
}
109+
`)
110+
111+
jsonData, err := jsoncanonicalizer.Transform(jsonDataBz)
112+
require.NoError(t, err)
113+
dataHash := sha256.Sum256(jsonData)
114+
115+
dataHashSpace := sha256.Sum256(jsonDataBzSpace)
116+
dataHashBracket := sha256.Sum256(jsonDataBzBracket)
117+
dataHashOrder := sha256.Sum256(jsonDataBzOrder)
118+
119+
require.NotEqual(t, dataHash, dataHashSpace)
120+
require.NotEqual(t, dataHash, dataHashBracket)
121+
require.NotEqual(t, dataHash, dataHashOrder)
122+
}

Diff for: server/service/datadeal/service_data_validation.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/medibloc/vc-sdk/pkg/vdr"
99

1010
"github.com/btcsuite/btcd/btcec"
11+
"github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer"
1112
"github.com/gogo/protobuf/proto"
1213
datadealtypes "github.com/medibloc/panacea-core/v2/x/datadeal/types"
1314
"github.com/medibloc/panacea-oracle/crypto"
@@ -81,8 +82,14 @@ func (s *dataDealServiceServer) ValidateData(ctx context.Context, req *datadeal.
8182
return nil, fmt.Errorf("failed to decrypt data")
8283
}
8384

85+
decryptedDataBz, err := jsoncanonicalizer.Transform(decryptedData)
86+
if err != nil {
87+
log.Debugf("invalid JSON format: %s", err.Error())
88+
return nil, fmt.Errorf("invalid JSON format")
89+
}
90+
8491
// Validate data hash
85-
dataHashBz := crypto.KDFSHA256(decryptedData)
92+
dataHashBz := crypto.KDFSHA256(decryptedDataBz)
8693
dataHash := hex.EncodeToString(dataHashBz)
8794

8895
if req.DataHash != dataHash {

Diff for: server/service/datadeal/service_data_validation_test.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
1212
sdk "github.com/cosmos/cosmos-sdk/types"
1313
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
14+
"github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer"
1415
datadealtypes "github.com/medibloc/panacea-core/v2/x/datadeal/types"
1516
"github.com/medibloc/panacea-oracle/crypto"
1617
"github.com/medibloc/panacea-oracle/mocks"
@@ -77,7 +78,9 @@ func (suite *dataDealServiceServerTestSuite) TestValidateDataSuccess() {
7778
encryptedData, err := crypto.Encrypt(sharedKey, nil, jsonDataBz)
7879
suite.Require().NoError(err)
7980

80-
dataHash := sha256.Sum256(jsonDataBz)
81+
jsonData, err := jsoncanonicalizer.Transform(jsonDataBz)
82+
suite.Require().NoError(err)
83+
dataHash := sha256.Sum256(jsonData)
8184

8285
req := &datadeal.ValidateDataRequest{
8386
DealId: 1,
@@ -294,7 +297,9 @@ func (suite *dataDealServiceServerTestSuite) TestValidateDataInvalidJSONSchema()
294297
encryptedData, err := crypto.Encrypt(sharedKey, nil, jsonDataBz)
295298
suite.Require().NoError(err)
296299

297-
dataHash := sha256.Sum256(jsonDataBz)
300+
jsonData, err := jsoncanonicalizer.Transform(jsonDataBz)
301+
suite.Require().NoError(err)
302+
dataHash := sha256.Sum256(jsonData)
298303

299304
req := &datadeal.ValidateDataRequest{
300305
DealId: 1,

0 commit comments

Comments
 (0)