OSDN Git Service

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