code.vegaprotocol.io/vega@v0.79.0/cmd/vegawallet/commands/key_untaint.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package cmd
    17  
    18  import (
    19  	"context"
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  	"os"
    24  
    25  	"code.vegaprotocol.io/vega/cmd/vegawallet/commands/cli"
    26  	"code.vegaprotocol.io/vega/cmd/vegawallet/commands/flags"
    27  	"code.vegaprotocol.io/vega/cmd/vegawallet/commands/printer"
    28  	"code.vegaprotocol.io/vega/wallet/api"
    29  	"code.vegaprotocol.io/vega/wallet/wallets"
    30  
    31  	"github.com/spf13/cobra"
    32  )
    33  
    34  var (
    35  	untaintKeyLong = cli.LongDesc(`
    36  		Remove the taint from a key pair.
    37  
    38  		If you tainted a key for security reasons, you should not untaint it.
    39  	`)
    40  
    41  	untaintKeyExample = cli.Examples(`
    42  		# Untaint a key pair
    43  		{{.Software}} key untaint --wallet WALLET --pubkey PUBKEY
    44  	`)
    45  )
    46  
    47  type UntaintKeyHandler func(api.AdminUntaintKeyParams, string) error
    48  
    49  func NewCmdUntaintKey(w io.Writer, rf *RootFlags) *cobra.Command {
    50  	h := func(params api.AdminUntaintKeyParams, passphrase string) error {
    51  		ctx := context.Background()
    52  
    53  		walletStore, err := wallets.InitialiseStore(rf.Home, false)
    54  		if err != nil {
    55  			return fmt.Errorf("couldn't initialise wallets store: %w", err)
    56  		}
    57  		defer walletStore.Close()
    58  
    59  		if _, errDetails := api.NewAdminUnlockWallet(walletStore).Handle(ctx, api.AdminUnlockWalletParams{
    60  			Wallet:     params.Wallet,
    61  			Passphrase: passphrase,
    62  		}); errDetails != nil {
    63  			return errors.New(errDetails.Data)
    64  		}
    65  
    66  		if _, errDetails := api.NewAdminUntaintKey(walletStore).Handle(ctx, params); errDetails != nil {
    67  			return errors.New(errDetails.Data)
    68  		}
    69  		return nil
    70  	}
    71  
    72  	return BuildCmdUntaintKey(w, h, rf)
    73  }
    74  
    75  func BuildCmdUntaintKey(w io.Writer, handler UntaintKeyHandler, rf *RootFlags) *cobra.Command {
    76  	f := &UntaintKeyFlags{}
    77  
    78  	cmd := &cobra.Command{
    79  		Use:     "untaint",
    80  		Short:   "Remove the taint from a key pair",
    81  		Long:    untaintKeyLong,
    82  		Example: untaintKeyExample,
    83  		RunE: func(_ *cobra.Command, _ []string) error {
    84  			req, pass, err := f.Validate()
    85  			if err != nil {
    86  				return err
    87  			}
    88  
    89  			if err := handler(req, pass); err != nil {
    90  				return err
    91  			}
    92  
    93  			switch rf.Output {
    94  			case flags.InteractiveOutput:
    95  				PrintUntaintKeyResponse(w)
    96  			case flags.JSONOutput:
    97  				return nil
    98  			}
    99  
   100  			return nil
   101  		},
   102  	}
   103  
   104  	cmd.Flags().StringVarP(&f.Wallet,
   105  		"wallet", "w",
   106  		"",
   107  		"Wallet holding the public key",
   108  	)
   109  	cmd.Flags().StringVarP(&f.PublicKey,
   110  		"pubkey", "k",
   111  		"",
   112  		"Public key to untaint (hex-encoded)",
   113  	)
   114  	cmd.Flags().StringVarP(&f.PassphraseFile,
   115  		"passphrase-file", "p",
   116  		"",
   117  		"Path to the file containing the wallet's passphrase",
   118  	)
   119  
   120  	autoCompleteWallet(cmd, rf.Home, "wallet")
   121  
   122  	return cmd
   123  }
   124  
   125  type UntaintKeyFlags struct {
   126  	Wallet         string
   127  	PublicKey      string
   128  	PassphraseFile string
   129  }
   130  
   131  func (f *UntaintKeyFlags) Validate() (api.AdminUntaintKeyParams, string, error) {
   132  	if len(f.Wallet) == 0 {
   133  		return api.AdminUntaintKeyParams{}, "", flags.MustBeSpecifiedError("wallet")
   134  	}
   135  
   136  	if len(f.PublicKey) == 0 {
   137  		return api.AdminUntaintKeyParams{}, "", flags.MustBeSpecifiedError("pubkey")
   138  	}
   139  
   140  	passphrase, err := flags.GetPassphrase(f.PassphraseFile)
   141  	if err != nil {
   142  		return api.AdminUntaintKeyParams{}, "", err
   143  	}
   144  
   145  	return api.AdminUntaintKeyParams{
   146  		Wallet:    f.Wallet,
   147  		PublicKey: f.PublicKey,
   148  	}, passphrase, nil
   149  }
   150  
   151  func PrintUntaintKeyResponse(w io.Writer) {
   152  	p := printer.NewInteractivePrinter(w)
   153  
   154  	str := p.String()
   155  	defer p.Print(str)
   156  
   157  	str.CheckMark().SuccessText("Untainting succeeded").NextSection()
   158  
   159  	str.RedArrow().DangerText("Important").NextLine()
   160  	str.Text("If you tainted a key for security reasons, you should not use it.").NextLine()
   161  
   162  	str.BlueArrow().InfoText("Taint a key").NextLine()
   163  	str.Text("To taint a key pair, see the following command:").NextSection()
   164  	str.Code(fmt.Sprintf("%s key taint --help", os.Args[0])).NextLine()
   165  }