From 1f8290ca44df31cc4c4b68b30eef412476ed24e0 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Tue, 20 Jan 2015 23:55:13 +0100 Subject: Add ImportPreSaleKey * ImportPreSaleKey takes a KeyStore, a presale key JSON (e.g. file content) and a password string. It stores the key in the given key store. * Refactored common AES decryption and moved some functions to crypto.go --- crypto/key_store_passphrase.go | 46 +----------------------------------------- 1 file changed, 1 insertion(+), 45 deletions(-) (limited to 'crypto/key_store_passphrase.go') diff --git a/crypto/key_store_passphrase.go b/crypto/key_store_passphrase.go index e30a0a785..913b68498 100644 --- a/crypto/key_store_passphrase.go +++ b/crypto/key_store_passphrase.go @@ -178,22 +178,10 @@ func DecryptKey(ks keyStorePassphrase, keyId *uuid.UUID, auth string) (keyBytes if err != nil { return nil, err } - - AES256Block, err := aes.NewCipher(derivedKey) + plainText, err := aes_cbc_decrypt(derivedKey, cipherText, iv) if err != nil { return nil, err } - - AES256CBCDecrypter := cipher.NewCBCDecrypter(AES256Block, iv) - paddedPlainText := make([]byte, len(cipherText)) - AES256CBCDecrypter.CryptBlocks(paddedPlainText, cipherText) - - plainText := PKCS7Unpad(paddedPlainText) - if plainText == nil { - err = errors.New("Decryption failed: PKCS7Unpad failed after decryption") - return nil, err - } - keyBytes = plainText[:len(plainText)-32] keyBytesHash := plainText[len(plainText)-32:] if !bytes.Equal(Sha3(keyBytes), keyBytesHash) { @@ -211,35 +199,3 @@ func getEntropyCSPRNG(n int) []byte { } return mainBuff } - -// From https://leanpub.com/gocrypto/read#leanpub-auto-block-cipher-modes -func PKCS7Pad(in []byte) []byte { - padding := 16 - (len(in) % 16) - if padding == 0 { - padding = 16 - } - for i := 0; i < padding; i++ { - in = append(in, byte(padding)) - } - return in -} - -func PKCS7Unpad(in []byte) []byte { - if len(in) == 0 { - return nil - } - - padding := in[len(in)-1] - if int(padding) > len(in) || padding > aes.BlockSize { - return nil - } else if padding == 0 { - return nil - } - - for i := len(in) - 1; i > len(in)-int(padding)-1; i-- { - if in[i] != padding { - return nil - } - } - return in[:len(in)-int(padding)] -} -- cgit v1.2.3 From 8af42d42da1d428025622d3b76982798ec9436bd Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Wed, 21 Jan 2015 19:08:05 +0100 Subject: CamelCase aesCBCDecrypt --- crypto/key_store_passphrase.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crypto/key_store_passphrase.go') diff --git a/crypto/key_store_passphrase.go b/crypto/key_store_passphrase.go index 913b68498..80bf49d68 100644 --- a/crypto/key_store_passphrase.go +++ b/crypto/key_store_passphrase.go @@ -178,7 +178,7 @@ func DecryptKey(ks keyStorePassphrase, keyId *uuid.UUID, auth string) (keyBytes if err != nil { return nil, err } - plainText, err := aes_cbc_decrypt(derivedKey, cipherText, iv) + plainText, err := aesCBCDecrypt(derivedKey, cipherText, iv) if err != nil { return nil, err } -- cgit v1.2.3 From 512ffa2bf4308b44aa6f43f25238b375b58d7dbc Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Sun, 25 Jan 2015 02:07:20 +0100 Subject: Add accounts package and refactor key stores * Add initial UserAccount and AccountManager structs * Add NewAccount, Sign and Accounts functions * Refactor key stores to use key address as main identifier while keeping the UUID. * Use key address as file/dir names instead of UUID --- crypto/key_store_passphrase.go | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) (limited to 'crypto/key_store_passphrase.go') diff --git a/crypto/key_store_passphrase.go b/crypto/key_store_passphrase.go index 80bf49d68..807a91397 100644 --- a/crypto/key_store_passphrase.go +++ b/crypto/key_store_passphrase.go @@ -69,6 +69,7 @@ import ( "crypto/aes" "crypto/cipher" crand "crypto/rand" + "encoding/hex" "encoding/json" "errors" "io" @@ -96,18 +97,23 @@ func (ks keyStorePassphrase) GenerateNewKey(rand io.Reader, auth string) (key *K return GenerateNewKeyDefault(ks, rand, auth) } -func (ks keyStorePassphrase) GetKey(keyId *uuid.UUID, auth string) (key *Key, err error) { - keyBytes, err := DecryptKey(ks, keyId, auth) +func (ks keyStorePassphrase) GetKey(keyAddr []byte, auth string) (key *Key, err error) { + keyBytes, keyId, err := DecryptKey(ks, keyAddr, auth) if err != nil { return nil, err } key = &Key{ - Id: keyId, + Id: uuid.UUID(keyId), + Address: keyAddr, PrivateKey: ToECDSA(keyBytes), } return key, err } +func (ks keyStorePassphrase) GetKeyAddresses() (addresses [][]byte, err error) { + return GetKeyAddresses(ks.keysDirPath) +} + func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) { authArray := []byte(auth) salt := getEntropyCSPRNG(32) @@ -136,7 +142,8 @@ func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) { cipherText, } keyStruct := encryptedKeyJSON{ - *key.Id, + key.Id, + key.Address, cipherStruct, } keyJSON, err := json.Marshal(keyStruct) @@ -144,51 +151,50 @@ func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) { return err } - return WriteKeyFile(key.Id.String(), ks.keysDirPath, keyJSON) + return WriteKeyFile(key.Address, ks.keysDirPath, keyJSON) } -func (ks keyStorePassphrase) DeleteKey(keyId *uuid.UUID, auth string) (err error) { +func (ks keyStorePassphrase) DeleteKey(keyAddr []byte, auth string) (err error) { // only delete if correct passphrase is given - _, err = DecryptKey(ks, keyId, auth) + _, _, err = DecryptKey(ks, keyAddr, auth) if err != nil { return err } - keyDirPath := path.Join(ks.keysDirPath, keyId.String()) + keyDirPath := path.Join(ks.keysDirPath, hex.EncodeToString(keyAddr)) return os.RemoveAll(keyDirPath) } -func DecryptKey(ks keyStorePassphrase, keyId *uuid.UUID, auth string) (keyBytes []byte, err error) { - fileContent, err := GetKeyFile(ks.keysDirPath, keyId) +func DecryptKey(ks keyStorePassphrase, keyAddr []byte, auth string) (keyBytes []byte, keyId []byte, err error) { + fileContent, err := GetKeyFile(ks.keysDirPath, keyAddr) if err != nil { - return nil, err + return nil, nil, err } keyProtected := new(encryptedKeyJSON) err = json.Unmarshal(fileContent, keyProtected) + keyId = keyProtected.Id salt := keyProtected.Crypto.Salt - iv := keyProtected.Crypto.IV - cipherText := keyProtected.Crypto.CipherText authArray := []byte(auth) derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptr, scryptp, scryptdkLen) if err != nil { - return nil, err + return nil, nil, err } plainText, err := aesCBCDecrypt(derivedKey, cipherText, iv) if err != nil { - return nil, err + return nil, nil, err } keyBytes = plainText[:len(plainText)-32] keyBytesHash := plainText[len(plainText)-32:] if !bytes.Equal(Sha3(keyBytes), keyBytesHash) { err = errors.New("Decryption failed: checksum mismatch") - return nil, err + return nil, nil, err } - return keyBytes, err + return keyBytes, keyId, err } func getEntropyCSPRNG(n int) []byte { -- cgit v1.2.3 From 8d9752a557e33341a5fb73239dbae664b2f8aaa0 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Wed, 28 Jan 2015 05:12:57 +0100 Subject: Address pull request comments * Use crypto.Sign instead of directly calling secp256k1 lib * Rename UserAccount to Account and Addr to Address (for consistency) * Change AccountManager.Sign to take ptr to Account instead of address byte array * Simplify copying of Accounts in Accounts() * PubkeyToAddress and GetEntropyCSPRNG now exported --- crypto/key_store_passphrase.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'crypto/key_store_passphrase.go') diff --git a/crypto/key_store_passphrase.go b/crypto/key_store_passphrase.go index 807a91397..0862b7886 100644 --- a/crypto/key_store_passphrase.go +++ b/crypto/key_store_passphrase.go @@ -116,7 +116,7 @@ func (ks keyStorePassphrase) GetKeyAddresses() (addresses [][]byte, err error) { func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) { authArray := []byte(auth) - salt := getEntropyCSPRNG(32) + salt := GetEntropyCSPRNG(32) derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptr, scryptp, scryptdkLen) if err != nil { return err @@ -131,7 +131,7 @@ func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) { return err } - iv := getEntropyCSPRNG(aes.BlockSize) // 16 + iv := GetEntropyCSPRNG(aes.BlockSize) // 16 AES256CBCEncrypter := cipher.NewCBCEncrypter(AES256Block, iv) cipherText := make([]byte, len(toEncrypt)) AES256CBCEncrypter.CryptBlocks(cipherText, toEncrypt) @@ -197,7 +197,7 @@ func DecryptKey(ks keyStorePassphrase, keyAddr []byte, auth string) (keyBytes [] return keyBytes, keyId, err } -func getEntropyCSPRNG(n int) []byte { +func GetEntropyCSPRNG(n int) []byte { mainBuff := make([]byte, n) _, err := io.ReadFull(crand.Reader, mainBuff) if err != nil { -- cgit v1.2.3