-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cmd/wallet): Import key from PEM file
- Loading branch information
Showing
4 changed files
with
101 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package wallet | ||
|
||
import ( | ||
"encoding/base64" | ||
"encoding/hex" | ||
"encoding/pem" | ||
"fmt" | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/oasisprotocol/cli/cmd/common" | ||
"github.com/oasisprotocol/cli/config" | ||
"github.com/oasisprotocol/cli/wallet" | ||
walletFile "github.com/oasisprotocol/cli/wallet/file" | ||
) | ||
|
||
var importFileCmd = &cobra.Command{ | ||
Use: "import-file <file_name> <account_name>", | ||
Short: "Import an existing account from file", | ||
Long: "Import the private key from an existing PEM file", | ||
Args: cobra.ExactArgs(2), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
cfg := config.Global() | ||
filename := args[0] | ||
name := args[1] | ||
|
||
checkAccountExists(cfg, name) | ||
|
||
rawFile, err := os.ReadFile(filename) | ||
cobra.CheckErr(err) | ||
|
||
block, _ := pem.Decode(rawFile) | ||
if block == nil { | ||
cobra.CheckErr(fmt.Errorf("failed to decode PEM file")) | ||
} | ||
|
||
algorithm, err := detectAlgorithm(block.Type) | ||
cobra.CheckErr(err) | ||
|
||
// Ask for passphrase. | ||
passphrase := common.AskNewPassphrase() | ||
|
||
accCfg := &config.Account{ | ||
Kind: walletFile.Kind, | ||
Config: map[string]interface{}{ | ||
"algorithm": algorithm, | ||
}, | ||
} | ||
|
||
src := &wallet.ImportSource{ | ||
Kind: wallet.ImportKindPrivateKey, | ||
Data: encodeKeyData(algorithm, block.Bytes), | ||
} | ||
|
||
err = cfg.Wallet.Import(name, passphrase, accCfg, src) | ||
cobra.CheckErr(err) | ||
|
||
err = cfg.Save() | ||
cobra.CheckErr(err) | ||
}, | ||
} | ||
|
||
// detectAlgorithm detects the key type based on the PEM type. | ||
func detectAlgorithm(pemType string) (string, error) { | ||
switch pemType { | ||
case "ED25519 PRIVATE KEY": | ||
return wallet.AlgorithmEd25519Raw, nil | ||
case "EC PRIVATE KEY": | ||
return wallet.AlgorithmSecp256k1Raw, nil | ||
case "SR25519 PRIVATE KEY": | ||
return wallet.AlgorithmSr25519Raw, nil | ||
} | ||
|
||
return "", fmt.Errorf("unsupported PEM type: %s", pemType) | ||
} | ||
|
||
// encodeKeyData re-encodes the key in raw bytes back to the user-readable string for import. | ||
func encodeKeyData(algorithm string, rawKey []byte) string { | ||
switch algorithm { | ||
case wallet.AlgorithmEd25519Raw, wallet.AlgorithmSr25519Raw: | ||
return base64.StdEncoding.EncodeToString(rawKey) | ||
case wallet.AlgorithmSecp256k1Raw: | ||
return hex.EncodeToString(rawKey) | ||
} | ||
|
||
return "" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters