Skip to content

Commit

Permalink
Release finding (#585)
Browse files Browse the repository at this point in the history
* add plain text of desc and poc in proto file

* add comment to finding

* add release finding process

* reset to release finding one by one, and merge encrypted_desc,desc to one accept interface

* fix lint

* fix finding comment
  • Loading branch information
kevin-yuhh committed Feb 2, 2023
1 parent b6228ec commit 89bcf97
Show file tree
Hide file tree
Showing 17 changed files with 1,716 additions and 267 deletions.
33 changes: 23 additions & 10 deletions proto/shentu/bounty/v1/bounty.proto
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,42 @@ message Finding {

uint64 finding_id = 1 [(gogoproto.jsontag) = "id", (gogoproto.moretags) = "yaml:\"id\""];
string title = 2 [(gogoproto.moretags) = "yaml:\"title\""];
google.protobuf.Any encrypted_desc = 3 [(cosmos_proto.accepts_interface) = "EncryptedDesc",(gogoproto.moretags) = "yaml:\"encrypted_desc\""];
google.protobuf.Any finding_desc = 3 [(cosmos_proto.accepts_interface) = "FindingDesc",(gogoproto.moretags) = "yaml:\"finding_desc\""];
uint64 program_id = 4 [(gogoproto.moretags) = "yaml:\"program_id\""];
SeverityLevel severity_level = 5 [(gogoproto.moretags) = "yaml:\"severity_level\""];;
google.protobuf.Any encrypted_poc = 6 [(cosmos_proto.accepts_interface) = "EncryptedPoc",(gogoproto.moretags) = "yaml:\"encrypted_poc\""];
google.protobuf.Any finding_poc = 6 [(cosmos_proto.accepts_interface) = "FindingPoc",(gogoproto.moretags) = "yaml:\"finding_poc\""];
string submitter_address = 7 [(gogoproto.moretags) = "yaml:\"submitter_address\""];
FindingStatus finding_status = 8 [(gogoproto.moretags) = "yaml:\"finding_status\""];

google.protobuf.Any encrypted_comment = 9 [(cosmos_proto.accepts_interface) = "EncryptedComment",(gogoproto.moretags) = "yaml:\"encrypted_comment\""];
google.protobuf.Any finding_comment = 9 [(cosmos_proto.accepts_interface) = "FindingComment",(gogoproto.moretags) = "yaml:\"finding_comment\""];
}

message EciesEncryptedDesc {
option (cosmos_proto.implements_interface) = "EncryptedDesc";
bytes encrypted_desc = 1;
option (cosmos_proto.implements_interface) = "FindingDesc";
bytes finding_desc = 1;
}

message EciesEncryptedPoc {
option (cosmos_proto.implements_interface) = "EncryptionPoc";
bytes encrypted_poc = 1;
option (cosmos_proto.implements_interface) = "FindingPoc";
bytes finding_poc = 1;
}

message EciesEncryptedComment {
option (cosmos_proto.implements_interface) = "EncryptionComment";
bytes encrypted_comment = 1;
option (cosmos_proto.implements_interface) = "FindingComment";
bytes finding_comment = 1;
}
message PlainTextDesc {
option (cosmos_proto.implements_interface) = "FindingDesc";
bytes finding_desc = 1;
}

message PlainTextPoc {
option (cosmos_proto.implements_interface) = "FindingPoc";
bytes finding_poc = 1;
}

message PlainTextComment {
option (cosmos_proto.implements_interface) = "FindingComment";
bytes finding_comment = 1;
}

enum SeverityLevel {
Expand Down
22 changes: 21 additions & 1 deletion proto/shentu/bounty/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ service Msg {

// HostRejectFinding defines a method for host reject a finding.
rpc HostRejectFinding(MsgHostRejectFinding) returns (MsgHostRejectFindingResponse);

// MsgReleaseFinding defines a method for release a finding.
rpc ReleaseFinding(MsgReleaseFinding) returns (MsgReleaseFindingResponse);
}

// MsgCreateProgram defines a SDK message for creating a new program.
Expand All @@ -48,6 +51,8 @@ message MsgCreateProgram {
message MsgCreateProgramResponse {
uint64 program_id = 1 [(gogoproto.jsontag) = "id", (gogoproto.moretags) = "yaml:\"id\""];
}

// MsgSubmitFinding defines a message to submit a finding.
message MsgSubmitFinding {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
Expand All @@ -60,6 +65,7 @@ message MsgSubmitFinding {
string submitter_address = 6 [(gogoproto.moretags) = "yaml:\"submitter_address\""];
}

// MsgSubmitFindingResponse defines the MsgSubmitFinding response type.
message MsgSubmitFindingResponse {
option (gogoproto.goproto_getters) = false;
uint64 finding_id = 1 [(gogoproto.jsontag) = "finding_id", (gogoproto.moretags) = "yaml:\"finding_id\""];
Expand Down Expand Up @@ -89,4 +95,18 @@ message MsgHostRejectFinding {
}

// MsgHostRejectFindingResponse defines the Msg/ostRejectFinding response type.
message MsgHostRejectFindingResponse {}
message MsgHostRejectFindingResponse {}

// MsgReleaseFinding defines a message to release a finding.
message MsgReleaseFinding {
option (gogoproto.equal) = false;

uint64 finding_id = 1 [(gogoproto.moretags) = "yaml:\"finding_id\""];
string desc = 2 [(gogoproto.moretags) = "yaml:\"desc\""];
string poc = 3 [(gogoproto.moretags) = "yaml:\"poc\""];
string comment = 4 [(gogoproto.moretags) = "yaml:\"comment\""];
string host_address = 5 [(gogoproto.moretags) = "yaml:\"host_address\""];
}

// MsgReleaseFindingResponse defines the MsgReleaseFinding response type.
message MsgReleaseFindingResponse {}
1 change: 1 addition & 0 deletions x/bounty/client/cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ const (

FlagFindingAddress = "finding-address"
FlagSubmitterAddress = "submitter-address"
FlagFindingID = "finding-id"
)
102 changes: 98 additions & 4 deletions x/bounty/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func NewTxCmd() *cobra.Command {
NewSubmitFindingCmd(),
NewHostAcceptFindingCmd(),
NewHostRejectFindingCmd(),
NewReleaseFindingCmd(),
)

return bountyTxCmds
Expand Down Expand Up @@ -166,7 +167,6 @@ func NewSubmitFindingCmd() *cobra.Command {

poc, _ := cmd.Flags().GetString(FlagFindingPoc)

//func EncryptMsg(cmd *cobra.Command, programID uint64, desc, poc string) (descAny, pocAny *codectypes.Any, err error) {
descAny, pocAny, err := EncryptMsg(cmd, pid, desc, poc)
if err != nil {
return err
Expand Down Expand Up @@ -208,7 +208,7 @@ func EncryptMsg(cmd *cobra.Command, programID uint64, desc, poc string) (descAny
return nil, nil, err
}
encDesc := types.EciesEncryptedDesc{
EncryptedDesc: encryptedDescBytes,
FindingDesc: encryptedDescBytes,
}
descAny, err = codectypes.NewAnyWithValue(&encDesc)
if err != nil {
Expand All @@ -220,7 +220,7 @@ func EncryptMsg(cmd *cobra.Command, programID uint64, desc, poc string) (descAny
return nil, nil, err
}
encPoc := types.EciesEncryptedPoc{
EncryptedPoc: encryptedPocBytes,
FindingPoc: encryptedPocBytes,
}
pocAny, err = codectypes.NewAnyWithValue(&encPoc)
if err != nil {
Expand Down Expand Up @@ -350,7 +350,7 @@ func HostProcessFinding(cmd *cobra.Command, args []string) (fid uint64,
return fid, commentAny, hostAddr, err
}
encComment := types.EciesEncryptedComment{
EncryptedComment: encryptedComment,
FindingComment: encryptedComment,
}
commentAny, err = codectypes.NewAnyWithValue(&encComment)
if err != nil {
Expand All @@ -359,3 +359,97 @@ func HostProcessFinding(cmd *cobra.Command, args []string) (fid uint64,

return fid, commentAny, hostAddr, nil
}

func NewReleaseFindingCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "release-finding",
Short: "release encrypted part of a finding ",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
hostAddr := clientCtx.GetFromAddress()

fid, err := cmd.Flags().GetUint64(FlagFindingID)
if err != nil {
return err
}

encKeyFile, err := cmd.Flags().GetString(FlagEncKeyFile)
if err != nil {
return err
}

findingDesc, findingPoc, findingComment, err := GetFindingPlainText(cmd, fid, encKeyFile)
if err != nil {
return err
}

msg := types.NewReleaseFinding(
hostAddr.String(),
fid,
findingDesc,
findingPoc,
findingComment,
)

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

cmd.Flags().String(FlagEncKeyFile, "", "The program's encryption key file to decrypt findings")
cmd.Flags().Uint64(FlagFindingID, 0, "The program's ID")
flags.AddTxFlagsToCmd(cmd)

_ = cmd.MarkFlagRequired(flags.FlagFrom)
_ = cmd.MarkFlagRequired(FlagFindingID)
_ = cmd.MarkFlagRequired(FlagEncKeyFile)

return cmd
}

func GetFindingPlainText(cmd *cobra.Command, fid uint64, encKeyFile string) (
desc, poc, comment string, err error) {
// get finding info
finding, err := GetFinding(cmd, fid)
if err != nil {
return "", "", "", err
}

prvKey := LoadPrvKey(encKeyFile)

if finding.FindingDesc == nil {
desc = ""
} else {
encryptedDescBytes := finding.FindingDesc.GetValue()
descBytes, err := prvKey.Decrypt(encryptedDescBytes[2:], nil, nil)
if err != nil {
return "", "", "", err
}
desc = string(descBytes)
}

if finding.FindingPoc == nil {
poc = ""
} else {
encryptedPocBytes := finding.FindingPoc.GetValue()
pocBytes, err := prvKey.Decrypt(encryptedPocBytes[2:], nil, nil)
if err != nil {
return "", "", "", err
}
poc = string(pocBytes)
}

if finding.FindingComment == nil {
comment = ""
} else {
encryptedCommentBytes := finding.FindingComment.GetValue()
commentBytes, err := prvKey.Decrypt(encryptedCommentBytes[2:], nil, nil)
if err != nil {
return "", "", "", err
}
comment = string(commentBytes)
}
return desc, poc, comment, nil
}
31 changes: 31 additions & 0 deletions x/bounty/client/cli/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,43 @@ import (

"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/ecies"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"

"github.com/shentufoundation/shentu/v2/x/bounty/types"
)

const (
keyFile = "./dec-key.json"
)

func TestAnyToBytes(t *testing.T) {
decKey, err := ecies.GenerateKey(rand.Reader, ecies.DefaultCurve, nil)
if err != nil {
t.Fatal(err.Error())
}
desc := "test"
encryptedDesc, err := ecies.Encrypt(rand.Reader, &decKey.PublicKey, []byte(desc), nil, nil)
if err != nil {
t.Fatal(err)
}

var descAny *codectypes.Any
encDesc := types.EciesEncryptedDesc{
FindingDesc: encryptedDesc,
}
if descAny, err = codectypes.NewAnyWithValue(&encDesc); err != nil {
t.Fatal(err)
}

descBytes := descAny.GetValue()[2:]
descDecrypt, err := decKey.Decrypt(descBytes, nil, nil)

if string(descDecrypt) != desc {
t.Fatal("error")
}
}

func TestSaveLoadKey(t *testing.T) {
decKey, err := ecies.GenerateKey(rand.Reader, ecies.DefaultCurve, nil)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions x/bounty/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
case *types.MsgHostRejectFinding:
res, err := msgServer.HostRejectFinding(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgReleaseFinding:
res, err := msgServer.ReleaseFinding(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)
}
Expand Down
10 changes: 6 additions & 4 deletions x/bounty/keeper/finding.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,12 @@ func (k Keeper) GetPidFindingIDList(ctx sdk.Context, pid uint64) ([]uint64, erro

func (k Keeper) AppendFidToFidList(ctx sdk.Context, pid, fid uint64) error {
fids, err := k.GetPidFindingIDList(ctx, pid)
if err.Error() == types.ErrorEmptyProgramIDFindingList {
fids = []uint64{}
} else if err != nil {
return err
if err != nil {
if err.Error() == types.ErrorEmptyProgramIDFindingList {
fids = []uint64{}
} else {
return err
}
}

fids = append(fids, fid)
Expand Down
Loading

0 comments on commit 89bcf97

Please sign in to comment.