OSDN Git Service

Hulk did something
[bytom/vapor.git] / blockchain / pseudohsm / image.go
1 // Package pseudohsm provides a pseudo HSM for development environments.
2 package pseudohsm
3
4 import (
5         "encoding/hex"
6         "encoding/json"
7         "io/ioutil"
8         "path/filepath"
9
10         log "github.com/sirupsen/logrus"
11
12         "github.com/vapor/crypto/ed25519/chainkd"
13 )
14
15 const logModule = "pseudohsm"
16
17 // KeyImage is the struct for hold export key data
18 type KeyImage struct {
19         XKeys []*encryptedKeyJSON `json:"xkeys"`
20 }
21
22 // Backup export all the HSM keys into array
23 func (h *HSM) Backup() (*KeyImage, error) {
24         image := &KeyImage{}
25         xpubs := h.cache.keys()
26         for _, xpub := range xpubs {
27                 data, err := ioutil.ReadFile(xpub.File)
28                 if err != nil {
29                         return nil, err
30                 }
31
32                 xKey := &encryptedKeyJSON{}
33                 if err := json.Unmarshal(data, xKey); err != nil {
34                         return nil, err
35                 }
36
37                 image.XKeys = append(image.XKeys, xKey)
38         }
39         return image, nil
40 }
41
42 // Restore import the keyImages into HSM
43 func (h *HSM) Restore(image *KeyImage) error {
44         h.cacheMu.Lock()
45         defer h.cacheMu.Unlock()
46
47         for _, xKey := range image.XKeys {
48                 data, err := hex.DecodeString(xKey.XPub)
49                 if err != nil {
50                         return ErrXPubFormat
51                 }
52
53                 var xPub chainkd.XPub
54                 copy(xPub[:], data)
55                 if h.cache.hasKey(xPub) {
56                         log.WithFields(log.Fields{
57                                 "module": logModule,
58                                 "alias":  xKey.Alias,
59                                 "id":     xKey.ID,
60                                 "xPub":   xKey.XPub,
61                         }).Warning("skip restore key due to already existed")
62                         continue
63                 }
64
65                 if ok := h.cache.hasAlias(xKey.Alias); ok {
66                         return ErrDuplicateKeyAlias
67                 }
68
69                 rawKey, err := json.Marshal(xKey)
70                 if err != nil {
71                         return err
72                 }
73
74                 _, fileName := filepath.Split(xKey.ID)
75                 file := h.keyStore.JoinPath(keyFileName(fileName))
76                 if err := writeKeyFile(file, rawKey); err != nil {
77                         return err
78                 }
79
80                 h.cache.reload()
81         }
82         return nil
83 }