github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/api/hsm.go (about)

     1  package api
     2  
     3  import (
     4  	"context"
     5  
     6  	log "github.com/sirupsen/logrus"
     7  
     8  	"github.com/bytom/bytom/blockchain/txbuilder"
     9  	"github.com/bytom/bytom/crypto/ed25519/chainkd"
    10  )
    11  
    12  type createKeyResp struct {
    13  	Alias    string       `json:"alias"`
    14  	XPub     chainkd.XPub `json:"xpub"`
    15  	File     string       `json:"file"`
    16  	Mnemonic string       `json:"mnemonic,omitempty"`
    17  }
    18  
    19  func (a *API) pseudohsmCreateKey(ctx context.Context, in struct {
    20  	Alias    string `json:"alias"`
    21  	Password string `json:"password"`
    22  	Mnemonic string `json:"mnemonic"`
    23  	Language string `json:"language"`
    24  }) Response {
    25  	if in.Language == "" {
    26  		in.Language = "en"
    27  	}
    28  	if len(in.Mnemonic) > 0 {
    29  		xpub, err := a.wallet.Hsm.ImportKeyFromMnemonic(in.Alias, in.Password, in.Mnemonic, in.Language)
    30  		if err != nil {
    31  			return NewErrorResponse(err)
    32  		}
    33  		return NewSuccessResponse(&createKeyResp{Alias: xpub.Alias, XPub: xpub.XPub, File: xpub.File})
    34  	}
    35  	xpub, mnemonic, err := a.wallet.Hsm.XCreate(in.Alias, in.Password, in.Language)
    36  	if err != nil {
    37  		return NewErrorResponse(err)
    38  	}
    39  	return NewSuccessResponse(&createKeyResp{Alias: xpub.Alias, XPub: xpub.XPub, File: xpub.File, Mnemonic: *mnemonic})
    40  }
    41  
    42  func (a *API) pseudohsmUpdateKeyAlias(ctx context.Context, in struct {
    43  	XPub     chainkd.XPub `json:"xpub"`
    44  	NewAlias string       `json:"new_alias"`
    45  }) Response {
    46  	if err := a.wallet.Hsm.UpdateKeyAlias(in.XPub, in.NewAlias); err != nil {
    47  		return NewErrorResponse(err)
    48  	}
    49  	return NewSuccessResponse(nil)
    50  }
    51  
    52  func (a *API) pseudohsmListKeys(ctx context.Context) Response {
    53  	return NewSuccessResponse(a.wallet.Hsm.ListKeys())
    54  }
    55  
    56  func (a *API) pseudohsmDeleteKey(ctx context.Context, x struct {
    57  	Password string       `json:"password"`
    58  	XPub     chainkd.XPub `json:"xpub"`
    59  }) Response {
    60  	if err := a.wallet.Hsm.XDelete(x.XPub, x.Password); err != nil {
    61  		return NewErrorResponse(err)
    62  	}
    63  	return NewSuccessResponse(nil)
    64  }
    65  
    66  type signTemplateResp struct {
    67  	Tx           *txbuilder.Template `json:"transaction"`
    68  	SignComplete bool                `json:"sign_complete"`
    69  }
    70  
    71  func (a *API) signTemplate(ctx context.Context, x struct {
    72  	Password string             `json:"password"`
    73  	Txs      txbuilder.Template `json:"transaction"`
    74  }) Response {
    75  	if err := txbuilder.Sign(ctx, &x.Txs, x.Password, a.pseudohsmSignTemplate); err != nil {
    76  		log.WithField("build err", err).Error("fail on sign transaction.")
    77  		return NewErrorResponse(err)
    78  	}
    79  	log.Info("Sign Transaction complete.")
    80  	return NewSuccessResponse(&signTemplateResp{Tx: &x.Txs, SignComplete: txbuilder.SignProgress(&x.Txs)})
    81  }
    82  
    83  type signTemplatesResp struct {
    84  	Tx           []*txbuilder.Template `json:"transaction"`
    85  	SignComplete bool                  `json:"sign_complete"`
    86  }
    87  
    88  func (a *API) signTemplates(ctx context.Context, x struct {
    89  	Password string                `json:"password"`
    90  	Txs      []*txbuilder.Template `json:"transactions"`
    91  }) Response {
    92  	signComplete := true
    93  	for _, tx := range x.Txs {
    94  		if err := txbuilder.Sign(ctx, tx, x.Password, a.pseudohsmSignTemplate); err != nil {
    95  			log.WithField("build err", err).Error("fail on sign transaction.")
    96  			return NewErrorResponse(err)
    97  		}
    98  		signComplete = signComplete && txbuilder.SignProgress(tx)
    99  	}
   100  
   101  	log.Info("Sign Chain Tx complete.")
   102  	return NewSuccessResponse(&signTemplatesResp{Tx: x.Txs, SignComplete: signComplete})
   103  }
   104  
   105  func (a *API) pseudohsmSignTemplate(ctx context.Context, xpub chainkd.XPub, path [][]byte, data [32]byte, password string) ([]byte, error) {
   106  	return a.wallet.Hsm.XSign(xpub, path, data[:], password)
   107  }
   108  
   109  // ResetPasswordResp is response for reset key password
   110  type ResetPasswordResp struct {
   111  	Changed bool `json:"changed"`
   112  }
   113  
   114  func (a *API) pseudohsmResetPassword(ctx context.Context, ins struct {
   115  	XPub        chainkd.XPub `json:"xpub"`
   116  	OldPassword string       `json:"old_password"`
   117  	NewPassword string       `json:"new_password"`
   118  }) Response {
   119  	resp := &ResetPasswordResp{Changed: false}
   120  	if err := a.wallet.Hsm.ResetPassword(ins.XPub, ins.OldPassword, ins.NewPassword); err != nil {
   121  		return NewSuccessResponse(resp)
   122  	}
   123  	resp.Changed = true
   124  	return NewSuccessResponse(resp)
   125  }
   126  
   127  // CheckPasswordResp is response for check key password
   128  type CheckPasswordResp struct {
   129  	CheckResult bool `json:"check_result"`
   130  }
   131  
   132  func (a *API) pseudohsmCheckPassword(ctx context.Context, ins struct {
   133  	XPub     chainkd.XPub `json:"xpub"`
   134  	Password string       `json:"password"`
   135  }) Response {
   136  	resp := &CheckPasswordResp{CheckResult: false}
   137  	if _, err := a.wallet.Hsm.LoadChainKDKey(ins.XPub, ins.Password); err != nil {
   138  		return NewSuccessResponse(resp)
   139  	}
   140  	resp.CheckResult = true
   141  	return NewSuccessResponse(resp)
   142  }