forked from c4dt/dela
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
#5 Uses persistent storage only
Showing
3 changed files
with
53 additions
and
112 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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 |
---|---|---|
@@ -1,19 +1,63 @@ | ||
package key | ||
|
||
import ( | ||
"crypto/rand" | ||
"github.com/libp2p/go-libp2p/core/crypto" | ||
"go.dedis.ch/dela/core/store/kv" | ||
"golang.org/x/xerrors" | ||
) | ||
|
||
// Storage is an interface for storing and retrieving private keys. | ||
type Storage interface { | ||
// LoadOrCreate loads the private key associated with a mino instance. | ||
// If the key does not exist, it will create a new one. | ||
LoadOrCreate() (crypto.PrivKey, error) | ||
// Storage provides persistent Storage for private keys. | ||
type Storage struct { | ||
bucket []byte | ||
db kv.DB | ||
} | ||
|
||
// NewStorage creates a new private key storage | ||
// with caching for efficient access. | ||
func NewStorage(db kv.DB) Storage { | ||
return newMemoryStore(db) | ||
// NewStorage creates a new Storage for private keys. | ||
func NewStorage(db kv.DB) *Storage { | ||
return &Storage{ | ||
bucket: []byte("keys"), | ||
db: db, | ||
} | ||
} | ||
|
||
// LoadOrCreate loads the private key from Storage or | ||
// creates a new one if none exists. | ||
func (s *Storage) LoadOrCreate() (crypto.PrivKey, error) { | ||
key := []byte("private_key") | ||
var buffer []byte | ||
err := s.db.Update(func(tx kv.WritableTx) error { | ||
bucket, err := tx.GetBucketOrCreate(s.bucket) | ||
if err != nil { | ||
return xerrors.Errorf("could not get bucket: %v", err) | ||
} | ||
|
||
bytes := bucket.Get(key) | ||
if bytes == nil { | ||
private, _, err := crypto.GenerateEd25519Key(rand.Reader) | ||
if err != nil { | ||
return xerrors.Errorf("could not generate key: %v", err) | ||
} | ||
bytes, err = crypto.MarshalPrivateKey(private) | ||
if err != nil { | ||
return xerrors.Errorf("could not marshal key: %v", err) | ||
} | ||
err = bucket.Set(key, bytes) | ||
if err != nil { | ||
return xerrors.Errorf("could not store key: %v", err) | ||
} | ||
} | ||
buffer = make([]byte, len(bytes)) | ||
copy(buffer, bytes) | ||
return nil | ||
}) | ||
if err != nil { | ||
return nil, xerrors.Errorf("could not update db: %v", err) | ||
} | ||
|
||
private, err := crypto.UnmarshalPrivateKey(buffer) | ||
if err != nil { | ||
return nil, xerrors.Errorf("could not unmarshal key: %v", err) | ||
} | ||
return private, nil | ||
} |