diff --git a/code/go/0chain.net/blobbercore/handler/handler.go b/code/go/0chain.net/blobbercore/handler/handler.go index 49da5ac50..2a5f51563 100644 --- a/code/go/0chain.net/blobbercore/handler/handler.go +++ b/code/go/0chain.net/blobbercore/handler/handler.go @@ -14,6 +14,7 @@ import ( "0chain.net/blobbercore/datastore" "0chain.net/blobbercore/stats" "0chain.net/core/common" + "0chain.net/core/encryption" . "0chain.net/core/logging" "go.uber.org/zap" @@ -105,7 +106,7 @@ func setupHandlerContext(ctx context.Context, r *http.Request) context.Context { ctx = context.WithValue(ctx, constants.CLIENT_CONTEXT_KEY, r.Header.Get(common.ClientHeader)) ctx = context.WithValue(ctx, constants.CLIENT_KEY_CONTEXT_KEY, - r.Header.Get(common.ClientKeyHeader)) + encryption.MiraclToHerumiPK(r.Header.Get(common.ClientKeyHeader))) ctx = context.WithValue(ctx, constants.ALLOCATION_CONTEXT_KEY, vars["allocation"]) // signature is not requered for all requests, but if header is empty it won`t affect anything diff --git a/code/go/0chain.net/blobbercore/handler/handler_integration_tests.go b/code/go/0chain.net/blobbercore/handler/handler_integration_tests.go index d386f15b1..f94b30354 100644 --- a/code/go/0chain.net/blobbercore/handler/handler_integration_tests.go +++ b/code/go/0chain.net/blobbercore/handler/handler_integration_tests.go @@ -18,6 +18,7 @@ import ( "0chain.net/blobbercore/datastore" "0chain.net/blobbercore/stats" "0chain.net/core/common" + "0chain.net/core/encryption" "0chain.net/core/node" "github.com/gorilla/mux" @@ -99,7 +100,7 @@ func setupHandlerContext(ctx context.Context, r *http.Request) context.Context { ctx = context.WithValue(ctx, constants.CLIENT_CONTEXT_KEY, r.Header.Get(common.ClientHeader)) ctx = context.WithValue(ctx, constants.CLIENT_KEY_CONTEXT_KEY, - r.Header.Get(common.ClientKeyHeader)) + encryption.MiraclToHerumiPK(r.Header.Get(common.ClientKeyHeader))) ctx = context.WithValue(ctx, constants.ALLOCATION_CONTEXT_KEY, vars["allocation"]) return ctx diff --git a/code/go/0chain.net/blobbercore/handler/helper.go b/code/go/0chain.net/blobbercore/handler/helper.go index b412aa718..c6afa5b96 100644 --- a/code/go/0chain.net/blobbercore/handler/helper.go +++ b/code/go/0chain.net/blobbercore/handler/helper.go @@ -13,13 +13,14 @@ import ( "0chain.net/blobbercore/blobbergrpc" "0chain.net/blobbercore/constants" + "0chain.net/core/encryption" ) func setupGRPCHandlerContext(ctx context.Context, r *blobbergrpc.RequestContext) context.Context { ctx = context.WithValue(ctx, constants.CLIENT_CONTEXT_KEY, r.Client) ctx = context.WithValue(ctx, constants.CLIENT_KEY_CONTEXT_KEY, - r.ClientKey) + encryption.MiraclToHerumiPK(r.ClientKey)) ctx = context.WithValue(ctx, constants.ALLOCATION_CONTEXT_KEY, r.Allocation) return ctx diff --git a/code/go/0chain.net/blobbercore/handler/object_operation_handler.go b/code/go/0chain.net/blobbercore/handler/object_operation_handler.go index 59e6ddd26..1c092cdd7 100644 --- a/code/go/0chain.net/blobbercore/handler/object_operation_handler.go +++ b/code/go/0chain.net/blobbercore/handler/object_operation_handler.go @@ -416,7 +416,8 @@ func (fsh *StorageHandler) CommitWrite(ctx context.Context, r *http.Request) (*C } allocationTx := ctx.Value(constants.ALLOCATION_CONTEXT_KEY).(string) clientID := ctx.Value(constants.CLIENT_CONTEXT_KEY).(string) - clientKey := ctx.Value(constants.CLIENT_KEY_CONTEXT_KEY).(string) + clientKey := encryption.MiraclToHerumiPK( + ctx.Value(constants.CLIENT_KEY_CONTEXT_KEY).(string)) clientKeyBytes, _ := hex.DecodeString(clientKey) allocationObj, err := fsh.verifyAllocation(ctx, allocationTx, false) diff --git a/code/go/0chain.net/blobbercore/readmarker/protocol.go b/code/go/0chain.net/blobbercore/readmarker/protocol.go index 1089a7dc9..9a5fa4653 100644 --- a/code/go/0chain.net/blobbercore/readmarker/protocol.go +++ b/code/go/0chain.net/blobbercore/readmarker/protocol.go @@ -35,7 +35,7 @@ func (rm *ReadMarkerEntity) VerifyMarker(ctx context.Context, sa *allocation.All return common.NewError("read_marker_validation_failed", "Read Marker is not for the blobber") } - clientPublicKey := ctx.Value(constants.CLIENT_KEY_CONTEXT_KEY).(string) + clientPublicKey := encryption.MiraclToHerumiPK(ctx.Value(constants.CLIENT_KEY_CONTEXT_KEY).(string)) if len(clientPublicKey) == 0 || clientPublicKey != rm.LatestRM.ClientPublicKey { return common.NewError("read_marker_validation_failed", "Could not get the public key of the client") } diff --git a/code/go/0chain.net/blobbercore/writemarker/protocol.go b/code/go/0chain.net/blobbercore/writemarker/protocol.go index c152adde2..c88d2de89 100644 --- a/code/go/0chain.net/blobbercore/writemarker/protocol.go +++ b/code/go/0chain.net/blobbercore/writemarker/protocol.go @@ -48,7 +48,7 @@ func (wm *WriteMarkerEntity) VerifyMarker(ctx context.Context, sa *allocation.Al return common.NewError("write_marker_validation_failed", "Write Marker size does not match the connection size") } - clientPublicKey := ctx.Value(constants.CLIENT_KEY_CONTEXT_KEY).(string) + clientPublicKey := encryption.MiraclToHerumiPK(ctx.Value(constants.CLIENT_KEY_CONTEXT_KEY).(string)) if len(clientPublicKey) == 0 { return common.NewError("write_marker_validation_failed", "Could not get the public key of the client") } diff --git a/code/go/0chain.net/core/encryption/keys.go b/code/go/0chain.net/core/encryption/keys.go index bda80893a..809259866 100644 --- a/code/go/0chain.net/core/encryption/keys.go +++ b/code/go/0chain.net/core/encryption/keys.go @@ -6,8 +6,10 @@ import ( "0chain.net/core/common" "0chain.net/core/config" + . "0chain.net/core/logging" "github.com/0chain/gosdk/core/zcncrypto" + "github.com/herumi/bls-go-binary/bls" ) /*ReadKeys - reads a publicKey and a privateKey from a Reader. @@ -38,3 +40,29 @@ func Verify(publicKey string, signature string, hash string) (bool, error) { } return false, common.NewError("invalid_signature_scheme", "Invalid signature scheme. Please check configuration") } + +// If input is normal herumi/bls public key, it returns it immmediately. +// So this is completely backward compatible with herumi/bls. +// If input is MIRACL public key, convert it to herumi/bls public key. +// +// This is an example of the raw public key we expect from MIRACL +var miraclExamplePK = `0418a02c6bd223ae0dfda1d2f9a3c81726ab436ce5e9d17c531ff0a385a13a0b491bdfed3a85690775ee35c61678957aaba7b1a1899438829f1dc94248d87ed36817f6dfafec19bfa87bf791a4d694f43fec227ae6f5a867490e30328cac05eaff039ac7dfc3364e851ebd2631ea6f1685609fc66d50223cc696cb59ff2fee47ac` +// +// This is an example of the same MIRACL public key serialized with ToString(). +// pk ([1bdfed3a85690775ee35c61678957aaba7b1a1899438829f1dc94248d87ed368,18a02c6bd223ae0dfda1d2f9a3c81726ab436ce5e9d17c531ff0a385a13a0b49],[039ac7dfc3364e851ebd2631ea6f1685609fc66d50223cc696cb59ff2fee47ac,17f6dfafec19bfa87bf791a4d694f43fec227ae6f5a867490e30328cac05eaff]) +func MiraclToHerumiPK(pk string) string { + if len(pk) != len(miraclExamplePK) { + // If input is normal herumi/bls public key, it returns it immmediately. + return pk + } + n1 := pk[2:66] + n2 := pk[66:(66+64)] + n3 := pk[(66+64):(66+64+64)] + n4 := pk[(66+64+64):(66+64+64+64)] + var p bls.PublicKey + err := p.SetHexString("1 " + n2 + " " + n1 + " " + n4 + " " + n3) + if err != nil { + Logger.Error("MiraclToHerumiPK: " + err.Error()) + } + return p.SerializeToHexStr() +} diff --git a/code/go/0chain.net/core/encryption/keys_test.go b/code/go/0chain.net/core/encryption/keys_test.go new file mode 100644 index 000000000..050c8e8ca --- /dev/null +++ b/code/go/0chain.net/core/encryption/keys_test.go @@ -0,0 +1,19 @@ +package encryption + +import ( + "testing" + "github.com/herumi/bls-go-binary/bls" + "github.com/stretchr/testify/require" +) + +func TestMiraclToHerumiPK(t *testing.T) { + miraclpk1 := `0418a02c6bd223ae0dfda1d2f9a3c81726ab436ce5e9d17c531ff0a385a13a0b491bdfed3a85690775ee35c61678957aaba7b1a1899438829f1dc94248d87ed36817f6dfafec19bfa87bf791a4d694f43fec227ae6f5a867490e30328cac05eaff039ac7dfc3364e851ebd2631ea6f1685609fc66d50223cc696cb59ff2fee47ac` + pk1 := MiraclToHerumiPK(miraclpk1) + + require.EqualValues(t, pk1, "68d37ed84842c91d9f82389489a1b1a7ab7a957816c635ee750769853aeddf1b490b3aa185a3f01f537cd1e9e56c43ab2617c8a3f9d2a1fd0dae23d26b2ca018") + + // Assert DeserializeHexStr works on the output of MiraclToHerumiPK + var pk bls.PublicKey + err := pk.DeserializeHexStr(pk1) + require.NoError(t, err) +} diff --git a/code/go/0chain.net/go.mod b/code/go/0chain.net/go.mod index ef3b0dd34..8bdf88b70 100644 --- a/code/go/0chain.net/go.mod +++ b/code/go/0chain.net/go.mod @@ -9,6 +9,7 @@ require ( github.com/gorilla/mux v1.7.3 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.3.0 + github.com/herumi/bls-go-binary v0.0.0-20191119080710-898950e1a520 // indirect github.com/jackc/pgproto3/v2 v2.0.4 // indirect github.com/koding/cache v0.0.0-20161222233015-e8a81b0b3f20 github.com/minio/minio-go v6.0.14+incompatible diff --git a/code/go/0chain.net/validatorcore/storage/context.go b/code/go/0chain.net/validatorcore/storage/context.go index 79a977074..d033b5e03 100644 --- a/code/go/0chain.net/validatorcore/storage/context.go +++ b/code/go/0chain.net/validatorcore/storage/context.go @@ -5,12 +5,14 @@ import ( "net/http" "0chain.net/core/common" + "0chain.net/core/encryption" ) func SetupContext(handler common.JSONResponderF) common.JSONResponderF { return func(ctx context.Context, r *http.Request) (interface{}, error) { ctx = context.WithValue(ctx, CLIENT_CONTEXT_KEY, r.Header.Get(common.ClientHeader)) - ctx = context.WithValue(ctx, CLIENT_KEY_CONTEXT_KEY, r.Header.Get(common.ClientKeyHeader)) + ctx = context.WithValue(ctx, CLIENT_KEY_CONTEXT_KEY, + encryption.MiraclToHerumiPK(r.Header.Get(common.ClientKeyHeader))) res, err := handler(ctx, r) return res, err }