github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/crypto/keys/client/import.go (about)

     1  package client
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"flag"
     7  	"fmt"
     8  	"os"
     9  
    10  	"github.com/gnolang/gno/tm2/pkg/commands"
    11  	"github.com/gnolang/gno/tm2/pkg/crypto/keys"
    12  )
    13  
    14  type ImportCfg struct {
    15  	RootCfg *BaseCfg
    16  
    17  	KeyName   string
    18  	ArmorPath string
    19  	Unsafe    bool
    20  }
    21  
    22  func NewImportCmd(rootCfg *BaseCfg, io commands.IO) *commands.Command {
    23  	cfg := &ImportCfg{
    24  		RootCfg: rootCfg,
    25  	}
    26  
    27  	return commands.NewCommand(
    28  		commands.Metadata{
    29  			Name:       "import",
    30  			ShortUsage: "import [flags]",
    31  			ShortHelp:  "imports encrypted private key armor",
    32  		},
    33  		cfg,
    34  		func(_ context.Context, _ []string) error {
    35  			return execImport(cfg, io)
    36  		},
    37  	)
    38  }
    39  
    40  func (c *ImportCfg) RegisterFlags(fs *flag.FlagSet) {
    41  	fs.StringVar(
    42  		&c.KeyName,
    43  		"name",
    44  		"",
    45  		"name of the private key",
    46  	)
    47  
    48  	fs.StringVar(
    49  		&c.ArmorPath,
    50  		"armor-path",
    51  		"",
    52  		"path to the encrypted armor file",
    53  	)
    54  
    55  	fs.BoolVar(
    56  		&c.Unsafe,
    57  		"unsafe",
    58  		false,
    59  		"import the private key armor as unencrypted",
    60  	)
    61  }
    62  
    63  func execImport(cfg *ImportCfg, io commands.IO) error {
    64  	// check keyname
    65  	if cfg.KeyName == "" {
    66  		return errors.New("name shouldn't be empty")
    67  	}
    68  
    69  	// Create a new instance of the key-base
    70  	kb, err := keys.NewKeyBaseFromDir(cfg.RootCfg.Home)
    71  	if err != nil {
    72  		return fmt.Errorf(
    73  			"unable to create a key base from directory %s, %w",
    74  			cfg.RootCfg.Home,
    75  			err,
    76  		)
    77  	}
    78  
    79  	// Read the raw encrypted armor
    80  	armor, err := os.ReadFile(cfg.ArmorPath)
    81  	if err != nil {
    82  		return fmt.Errorf(
    83  			"unable to read armor from path %s, %w",
    84  			cfg.ArmorPath,
    85  			err,
    86  		)
    87  	}
    88  
    89  	var (
    90  		decryptPassword string
    91  		encryptPassword string
    92  	)
    93  
    94  	if !cfg.Unsafe {
    95  		// Get the armor decrypt password
    96  		decryptPassword, err = io.GetPassword(
    97  			"Enter the passphrase to decrypt your private key armor:",
    98  			cfg.RootCfg.InsecurePasswordStdin,
    99  		)
   100  		if err != nil {
   101  			return fmt.Errorf(
   102  				"unable to retrieve armor decrypt password from user, %w",
   103  				err,
   104  			)
   105  		}
   106  	}
   107  
   108  	// Get the key-base encrypt password
   109  	encryptPassword, err = io.GetCheckPassword(
   110  		[2]string{
   111  			"Enter a passphrase to encrypt your private key:",
   112  			"Repeat the passphrase:",
   113  		},
   114  		cfg.RootCfg.InsecurePasswordStdin,
   115  	)
   116  	if err != nil {
   117  		return fmt.Errorf(
   118  			"unable to retrieve key encrypt password from user, %w",
   119  			err,
   120  		)
   121  	}
   122  
   123  	if cfg.Unsafe {
   124  		// Import the unencrypted private key
   125  		if err := kb.ImportPrivKeyUnsafe(
   126  			cfg.KeyName,
   127  			string(armor),
   128  			encryptPassword,
   129  		); err != nil {
   130  			return fmt.Errorf(
   131  				"unable to import the unencrypted private key, %w",
   132  				err,
   133  			)
   134  		}
   135  	} else {
   136  		// Import the encrypted private key
   137  		if err := kb.ImportPrivKey(
   138  			cfg.KeyName,
   139  			string(armor),
   140  			decryptPassword,
   141  			encryptPassword,
   142  		); err != nil {
   143  			return fmt.Errorf(
   144  				"unable to import the encrypted private key, %w",
   145  				err,
   146  			)
   147  		}
   148  	}
   149  
   150  	io.Printfln("Successfully imported private key %s", cfg.KeyName)
   151  
   152  	return nil
   153  }