Implement import and export key for platform api

This commit is contained in:
Aaron Buchwald 2020-06-03 21:04:01 -04:00
parent 5847e69e45
commit b6d8ebefe6
No known key found for this signature in database
GPG Key ID: C71A37CF7072977F
3 changed files with 111 additions and 0 deletions

View File

@ -43,6 +43,87 @@ var (
// Service defines the API calls that can be made to the platform chain
type Service struct{ vm *VM }
// ExportKeyArgs are arguments for ExportKey
type ExportKeyArgs struct {
Username string `json:"username"`
Password string `json:"password"`
Address string `json:"address"`
}
// ExportKeyReply is the response for ExportKey
type ExportKeyReply struct {
// The decrypted PrivateKey for the Address provided in the arguments
PrivateKey formatting.CB58 `json:"privateKey"`
}
// ExportKey returns a private key from the provided user
func (service *Service) ExportKey(r *http.Request, args *ExportKeyArgs, reply *ExportKeyReply) error {
service.vm.SnowmanVM.Ctx.Log.Verbo("ExportKey called for user '%s'", args.Username)
address, err := service.vm.ParseAddress(args.Address)
if err != nil {
return fmt.Errorf("problem parsing address: %w", err)
}
addr, err := ids.ToShortID(address)
if err != nil {
return fmt.Errorf("problem parsing address: %w", err)
}
db, err := service.vm.SnowmanVM.Ctx.Keystore.GetDatabase(args.Username, args.Password)
if err != nil {
return fmt.Errorf("problem retrieving user: %w", err)
}
user := user{db: db}
sk, err := user.getKey(addr)
if err != nil {
return fmt.Errorf("problem retrieving private key: %w", err)
}
reply.PrivateKey.Bytes = sk.Bytes()
return nil
}
// ImportKeyArgs are arguments for ImportKey
type ImportKeyArgs struct {
Username string `json:"username"`
Password string `json:"password"`
PrivateKey formatting.CB58 `json:"privateKey"`
}
// ImportKeyReply is the response for ImportKey
type ImportKeyReply struct {
// The address controlled by the PrivateKey provided in the arguments
Address string `json:"address"`
}
// ImportKey adds a private key to the provided user
func (service *Service) ImportKey(r *http.Request, args *ImportKeyArgs, reply *ImportKeyReply) error {
service.vm.SnowmanVM.Ctx.Log.Verbo("ImportKey called for user '%s'", args.Username)
db, err := service.vm.SnowmanVM.Ctx.Keystore.GetDatabase(args.Username, args.Password)
if err != nil {
return fmt.Errorf("problem retrieving data: %w", err)
}
user := user{db: db}
factory := crypto.FactorySECP256K1R{}
skIntf, err := factory.ToPrivateKey(args.PrivateKey.Bytes)
if err != nil {
return fmt.Errorf("problem parsing private key %s: %w", args.PrivateKey, err)
}
sk := skIntf.(*crypto.PrivateKeySECP256K1R)
if err := user.putAccount(sk); err != nil {
return fmt.Errorf("problem saving key %w", err)
}
reply.Address = service.vm.Format(sk.PublicKey().Address().Bytes())
return nil
}
/*
******************************************************
******************* Get Subnets **********************

View File

@ -32,3 +32,21 @@ func TestCreateBlockchainArgsParsing(t *testing.T) {
t.Fatal(err)
}
}
func TestExportKey(t *testing.T) {
jsonString := `{"username":"ScoobyUser","password":"ShaggyPassword1","address":"6Y3kysjF9jnHnYkdS9yGAuoHyae2eNmeV"}`
args := ExportKeyArgs{}
err := json.Unmarshal([]byte(jsonString), &args)
if err != nil {
t.Fatal(err)
}
}
func TestImportKey(t *testing.T) {
jsonString := `{"username":"ScoobyUser","password":"ShaggyPassword1","privateKey":"ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN"}`
args := ImportKeyArgs{}
err := json.Unmarshal([]byte(jsonString), &args)
if err != nil {
t.Fatal(err)
}
}

View File

@ -20,6 +20,7 @@ import (
"github.com/ava-labs/gecko/snow/engine/common"
"github.com/ava-labs/gecko/snow/validators"
"github.com/ava-labs/gecko/utils/crypto"
"github.com/ava-labs/gecko/utils/formatting"
"github.com/ava-labs/gecko/utils/logging"
"github.com/ava-labs/gecko/utils/math"
"github.com/ava-labs/gecko/utils/timer"
@ -854,3 +855,14 @@ func (vm *VM) GetAtomicUTXOs(addrs ids.Set) ([]*ava.UTXO, error) {
}
return utxos, nil
}
func (vm *VM) ParseAddress(addrStr string) ([]byte, error) {
cb58 := formatting.CB58{}
err := cb58.FromString(addrStr)
return cb58.Bytes, err
}
// Format ...
func (vm *VM) Format(b []byte) string {
return formatting.CB58{Bytes: b}.String()
}