This commit is contained in:
programmer10110 2020-09-17 15:03:10 +03:00
parent 3db687fbeb
commit f508750a30
3 changed files with 64 additions and 14 deletions

View File

@ -67,7 +67,7 @@ func NewAirgappedMachine(dbPath string) (*AirgappedMachine, error) {
return nil, fmt.Errorf("failed to open db file %s for keys: %w", dbPath, err) return nil, fmt.Errorf("failed to open db file %s for keys: %w", dbPath, err)
} }
err = am.loadKeysFromDB(dbPath) err = am.LoadKeysFromDB()
if err != nil && err != leveldb.ErrNotFound { if err != nil && err != leveldb.ErrNotFound {
return nil, fmt.Errorf("failed to load keys from db %s: %w", dbPath, err) return nil, fmt.Errorf("failed to load keys from db %s: %w", dbPath, err)
} }
@ -76,7 +76,7 @@ func NewAirgappedMachine(dbPath string) (*AirgappedMachine, error) {
am.secKey = am.suite.Scalar().Pick(am.suite.RandomStream()) am.secKey = am.suite.Scalar().Pick(am.suite.RandomStream())
am.pubKey = am.suite.Point().Mul(am.secKey, nil) am.pubKey = am.suite.Point().Mul(am.secKey, nil)
return am, am.saveKeysToDB(dbPath) return am, am.SaveKeysToDB()
} }
if err = am.loadAddressFromDB(dbPath); err != nil { if err = am.loadAddressFromDB(dbPath); err != nil {
@ -95,13 +95,13 @@ func (am *AirgappedMachine) GetAddress() string {
return am.ParticipantAddress return am.ParticipantAddress
} }
func (am *AirgappedMachine) loadKeysFromDB(dbPath string) error { func (am *AirgappedMachine) LoadKeysFromDB() error {
pubKeyBz, err := am.db.Get([]byte(pubKeyDBKey), nil) pubKeyBz, err := am.db.Get([]byte(pubKeyDBKey), nil)
if err != nil { if err != nil {
if err == leveldb.ErrNotFound { if err == leveldb.ErrNotFound {
return err return err
} }
return fmt.Errorf("failed to get public key from db %s: %w", dbPath, err) return fmt.Errorf("failed to get public key from db: %w", err)
} }
privateKeyBz, err := am.db.Get([]byte(privateKeyDBKey), nil) privateKeyBz, err := am.db.Get([]byte(privateKeyDBKey), nil)
@ -109,7 +109,7 @@ func (am *AirgappedMachine) loadKeysFromDB(dbPath string) error {
if err == leveldb.ErrNotFound { if err == leveldb.ErrNotFound {
return err return err
} }
return fmt.Errorf("failed to get private key from db %s: %w", dbPath, err) return fmt.Errorf("failed to get private key from db: %w", err)
} }
am.pubKey = am.suite.Point() am.pubKey = am.suite.Point()
@ -140,7 +140,7 @@ func (am *AirgappedMachine) saveAddressToDB(address string) error {
return am.db.Put([]byte(participantAddressKey), []byte(address), nil) return am.db.Put([]byte(participantAddressKey), []byte(address), nil)
} }
func (am *AirgappedMachine) saveKeysToDB(dbPath string) error { func (am *AirgappedMachine) SaveKeysToDB() error {
pubKeyBz, err := am.pubKey.MarshalBinary() pubKeyBz, err := am.pubKey.MarshalBinary()
if err != nil { if err != nil {
@ -153,20 +153,20 @@ func (am *AirgappedMachine) saveKeysToDB(dbPath string) error {
tx, err := am.db.OpenTransaction() tx, err := am.db.OpenTransaction()
if err != nil { if err != nil {
return fmt.Errorf("failed to open transcation for db %s: %w", dbPath, err) return fmt.Errorf("failed to open transcation for db: %w", err)
} }
defer tx.Discard() defer tx.Discard()
if err = tx.Put([]byte(pubKeyDBKey), pubKeyBz, nil); err != nil { if err = tx.Put([]byte(pubKeyDBKey), pubKeyBz, nil); err != nil {
return fmt.Errorf("failed to put pub key into db %s: %w", dbPath, err) return fmt.Errorf("failed to put pub key into db: %w", err)
} }
if err = tx.Put([]byte(privateKeyDBKey), privateKeyBz, nil); err != nil { if err = tx.Put([]byte(privateKeyDBKey), privateKeyBz, nil); err != nil {
return fmt.Errorf("failed to put private key into db %s: %w", dbPath, err) return fmt.Errorf("failed to put private key into db: %w", err)
} }
if err = tx.Commit(); err != nil { if err = tx.Commit(); err != nil {
return fmt.Errorf("failed to commit tx for saving keys into db %s: %w", dbPath, err) return fmt.Errorf("failed to commit tx for saving keys into db: %w", err)
} }
return nil return nil
} }
@ -179,7 +179,7 @@ func (am *AirgappedMachine) getParticipantID(dkgIdentifier string) (int, error)
return dkgInstance.ParticipantID, nil return dkgInstance.ParticipantID, nil
} }
func (am *AirgappedMachine) encryptData(dkgIdentifier, to string, data []byte) ([]byte, error) { func (am *AirgappedMachine) encryptDataForParticipant(dkgIdentifier, to string, data []byte) ([]byte, error) {
dkgInstance, ok := am.dkgInstances[dkgIdentifier] dkgInstance, ok := am.dkgInstances[dkgIdentifier]
if !ok { if !ok {
return nil, fmt.Errorf("invalid dkg identifier: %s", dkgIdentifier) return nil, fmt.Errorf("invalid dkg identifier: %s", dkgIdentifier)
@ -197,7 +197,7 @@ func (am *AirgappedMachine) encryptData(dkgIdentifier, to string, data []byte) (
return encryptedData, nil return encryptedData, nil
} }
func (am *AirgappedMachine) decryptData(data []byte) ([]byte, error) { func (am *AirgappedMachine) decryptDataFromParticipant(data []byte) ([]byte, error) {
decryptedData, err := ecies.Decrypt(am.suite, am.secKey, data, am.suite.Hash) decryptedData, err := ecies.Decrypt(am.suite, am.secKey, data, am.suite.Hash)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to decrypt data: %w", err) return nil, fmt.Errorf("failed to decrypt data: %w", err)

View File

@ -177,7 +177,7 @@ func (am *AirgappedMachine) handleStateDkgDealsAwaitConfirmations(o *client.Oper
return fmt.Errorf("failed to marshal deal: %w", err) return fmt.Errorf("failed to marshal deal: %w", err)
} }
toParticipant := dkgInstance.GetParticipantByIndex(index) toParticipant := dkgInstance.GetParticipantByIndex(index)
encryptedDeal, err := am.encryptData(o.DKGIdentifier, toParticipant, dealBz) encryptedDeal, err := am.encryptDataForParticipant(o.DKGIdentifier, toParticipant, dealBz)
if err != nil { if err != nil {
return fmt.Errorf("failed to encrypt deal: %w", err) return fmt.Errorf("failed to encrypt deal: %w", err)
} }
@ -213,7 +213,7 @@ func (am *AirgappedMachine) handleStateDkgResponsesAwaitConfirmations(o *client.
} }
for _, entry := range payload { for _, entry := range payload {
decryptedDealBz, err := am.decryptData(entry.DkgDeal) decryptedDealBz, err := am.decryptDataFromParticipant(entry.DkgDeal)
if err != nil { if err != nil {
return fmt.Errorf("failed to decrypt deal: %w", err) return fmt.Errorf("failed to decrypt deal: %w", err)
} }

50
airgapped/encryption.go Normal file
View File

@ -0,0 +1,50 @@
package airgapped
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
"golang.org/x/crypto/scrypt"
"io"
)
func encrypt(key, data []byte) ([]byte, error) {
//TODO: salt
derivedKey, err := scrypt.Key(key, nil, 32768, 8, 1, 32)
block, err := aes.NewCipher(derivedKey)
if err != nil {
return nil, err
}
cipherData := make([]byte, aes.BlockSize+len(data))
iv := cipherData[:aes.BlockSize]
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(cipherData[aes.BlockSize:], data)
return cipherData, nil
}
func decrypt(key, data []byte) ([]byte, error) {
//TODO: salt
derivedKey, err := scrypt.Key(key, nil, 32768, 8, 1, 32)
block, err := aes.NewCipher(derivedKey)
if err != nil {
return nil, err
}
if len(data) < aes.BlockSize {
return nil, fmt.Errorf("ciphertext block size is too short")
}
iv := data[:aes.BlockSize]
data = data[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(data, data)
return data, nil
}