Address pull request comments; key header and hex encoding
* Remove key header from unencrypted key file format and replace it with a version field * Change encoding of bytes in key files from base64 to hex
This commit is contained in:
		@@ -26,6 +26,7 @@ package crypto
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"crypto/ecdsa"
 | 
						"crypto/ecdsa"
 | 
				
			||||||
 | 
						"encoding/hex"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -33,6 +34,10 @@ import (
 | 
				
			|||||||
	"github.com/ethereum/go-ethereum/common"
 | 
						"github.com/ethereum/go-ethereum/common"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						version = "1"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Key struct {
 | 
					type Key struct {
 | 
				
			||||||
	Id uuid.UUID // Version 4 "random" for unique id not derived from key data
 | 
						Id uuid.UUID // Version 4 "random" for unique id not derived from key data
 | 
				
			||||||
	// to simplify lookups we also store the address
 | 
						// to simplify lookups we also store the address
 | 
				
			||||||
@@ -43,29 +48,31 @@ type Key struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type plainKeyJSON struct {
 | 
					type plainKeyJSON struct {
 | 
				
			||||||
	Id         []byte
 | 
						Version    string
 | 
				
			||||||
	Address    []byte
 | 
						Id         string
 | 
				
			||||||
	PrivateKey []byte
 | 
						Address    string
 | 
				
			||||||
 | 
						PrivateKey string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type encryptedKeyJSON struct {
 | 
					type encryptedKeyJSON struct {
 | 
				
			||||||
	Id      []byte
 | 
						Version string
 | 
				
			||||||
	Address []byte
 | 
						Id      string
 | 
				
			||||||
 | 
						Address string
 | 
				
			||||||
	Crypto  cipherJSON
 | 
						Crypto  cipherJSON
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type cipherJSON struct {
 | 
					type cipherJSON struct {
 | 
				
			||||||
	MAC        []byte
 | 
						MAC        string
 | 
				
			||||||
	Salt       []byte
 | 
						Salt       string
 | 
				
			||||||
	IV         []byte
 | 
						IV         string
 | 
				
			||||||
	KeyHeader  keyHeaderJSON
 | 
						KeyHeader  keyHeaderJSON
 | 
				
			||||||
	CipherText []byte
 | 
						CipherText string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type keyHeaderJSON struct {
 | 
					type keyHeaderJSON struct {
 | 
				
			||||||
	Version   string
 | 
						Version   string
 | 
				
			||||||
	Kdf       string
 | 
						Kdf       string
 | 
				
			||||||
	KdfParams scryptParamsJSON // TODO: make more generic?
 | 
						KdfParams scryptParamsJSON
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type scryptParamsJSON struct {
 | 
					type scryptParamsJSON struct {
 | 
				
			||||||
@@ -78,9 +85,10 @@ type scryptParamsJSON struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (k *Key) MarshalJSON() (j []byte, err error) {
 | 
					func (k *Key) MarshalJSON() (j []byte, err error) {
 | 
				
			||||||
	jStruct := plainKeyJSON{
 | 
						jStruct := plainKeyJSON{
 | 
				
			||||||
		k.Id,
 | 
							version,
 | 
				
			||||||
		k.Address.Bytes(),
 | 
							k.Id.String(),
 | 
				
			||||||
		FromECDSA(k.PrivateKey),
 | 
							hex.EncodeToString(k.Address[:]),
 | 
				
			||||||
 | 
							hex.EncodeToString(FromECDSA(k.PrivateKey)),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	j, err = json.Marshal(jStruct)
 | 
						j, err = json.Marshal(jStruct)
 | 
				
			||||||
	return j, err
 | 
						return j, err
 | 
				
			||||||
@@ -94,12 +102,22 @@ func (k *Key) UnmarshalJSON(j []byte) (err error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u := new(uuid.UUID)
 | 
						u := new(uuid.UUID)
 | 
				
			||||||
	*u = keyJSON.Id
 | 
						*u = uuid.Parse(keyJSON.Id)
 | 
				
			||||||
	k.Id = *u
 | 
						k.Id = *u
 | 
				
			||||||
	k.Address = common.BytesToAddress(keyJSON.Address)
 | 
						addr, err := hex.DecodeString(keyJSON.Address)
 | 
				
			||||||
	k.PrivateKey = ToECDSA(keyJSON.PrivateKey)
 | 
						if err != nil {
 | 
				
			||||||
 | 
					 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						privkey, err := hex.DecodeString(keyJSON.PrivateKey)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						k.Address = common.BytesToAddress(addr)
 | 
				
			||||||
 | 
						k.PrivateKey = ToECDSA(privkey)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewKeyFromECDSA(privateKeyECDSA *ecdsa.PrivateKey) *Key {
 | 
					func NewKeyFromECDSA(privateKeyECDSA *ecdsa.PrivateKey) *Key {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,6 +68,7 @@ import (
 | 
				
			|||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"crypto/aes"
 | 
						"crypto/aes"
 | 
				
			||||||
	"crypto/cipher"
 | 
						"crypto/cipher"
 | 
				
			||||||
 | 
						"encoding/hex"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
@@ -164,15 +165,16 @@ func (ks keyStorePassphrase) StoreKey(key *Key, auth string) (err error) {
 | 
				
			|||||||
	mac := Sha3(keyHeaderJSONStr, derivedKey[16:32], cipherText)
 | 
						mac := Sha3(keyHeaderJSONStr, derivedKey[16:32], cipherText)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cipherStruct := cipherJSON{
 | 
						cipherStruct := cipherJSON{
 | 
				
			||||||
		mac,
 | 
							hex.EncodeToString(mac),
 | 
				
			||||||
		salt,
 | 
							hex.EncodeToString(salt),
 | 
				
			||||||
		iv,
 | 
							hex.EncodeToString(iv),
 | 
				
			||||||
		keyHeaderJSON,
 | 
							keyHeaderJSON,
 | 
				
			||||||
		cipherText,
 | 
							hex.EncodeToString(cipherText),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	keyStruct := encryptedKeyJSON{
 | 
						keyStruct := encryptedKeyJSON{
 | 
				
			||||||
		key.Id,
 | 
							version,
 | 
				
			||||||
		key.Address.Bytes(),
 | 
							key.Id.String(),
 | 
				
			||||||
 | 
							hex.EncodeToString(key.Address[:]),
 | 
				
			||||||
		cipherStruct,
 | 
							cipherStruct,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	keyJSON, err := json.Marshal(keyStruct)
 | 
						keyJSON, err := json.Marshal(keyStruct)
 | 
				
			||||||
@@ -190,7 +192,7 @@ func (ks keyStorePassphrase) DeleteKey(keyAddr common.Address, auth string) (err
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	keyDirPath := filepath.Join(ks.keysDirPath, keyAddr.Hex())
 | 
						keyDirPath := filepath.Join(ks.keysDirPath, hex.EncodeToString(keyAddr[:]))
 | 
				
			||||||
	return os.RemoveAll(keyDirPath)
 | 
						return os.RemoveAll(keyDirPath)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -203,12 +205,28 @@ func DecryptKey(ks keyStorePassphrase, keyAddr common.Address, auth string) (key
 | 
				
			|||||||
	keyProtected := new(encryptedKeyJSON)
 | 
						keyProtected := new(encryptedKeyJSON)
 | 
				
			||||||
	err = json.Unmarshal(fileContent, keyProtected)
 | 
						err = json.Unmarshal(fileContent, keyProtected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	keyId = keyProtected.Id
 | 
						keyId = uuid.Parse(keyProtected.Id)
 | 
				
			||||||
	mac := keyProtected.Crypto.MAC
 | 
					
 | 
				
			||||||
	salt := keyProtected.Crypto.Salt
 | 
						mac, err := hex.DecodeString(keyProtected.Crypto.MAC)
 | 
				
			||||||
	iv := keyProtected.Crypto.IV
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						salt, err := hex.DecodeString(keyProtected.Crypto.Salt)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iv, err := hex.DecodeString(keyProtected.Crypto.IV)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	keyHeader := keyProtected.Crypto.KeyHeader
 | 
						keyHeader := keyProtected.Crypto.KeyHeader
 | 
				
			||||||
	cipherText := keyProtected.Crypto.CipherText
 | 
						cipherText, err := hex.DecodeString(keyProtected.Crypto.CipherText)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// used in MAC
 | 
						// used in MAC
 | 
				
			||||||
	keyHeaderJSONStr, err := json.Marshal(keyHeader)
 | 
						keyHeaderJSONStr, err := json.Marshal(keyHeader)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -98,12 +98,12 @@ func (ks keyStorePlain) DeleteKey(keyAddr common.Address, auth string) (err erro
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetKeyFile(keysDirPath string, keyAddr common.Address) (fileContent []byte, err error) {
 | 
					func GetKeyFile(keysDirPath string, keyAddr common.Address) (fileContent []byte, err error) {
 | 
				
			||||||
	fileName := keyAddr.Hex()
 | 
						fileName := hex.EncodeToString(keyAddr[:])
 | 
				
			||||||
	return ioutil.ReadFile(filepath.Join(keysDirPath, fileName, fileName))
 | 
						return ioutil.ReadFile(filepath.Join(keysDirPath, fileName, fileName))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func WriteKeyFile(addr common.Address, keysDirPath string, content []byte) (err error) {
 | 
					func WriteKeyFile(addr common.Address, keysDirPath string, content []byte) (err error) {
 | 
				
			||||||
	addrHex := addr.Hex()
 | 
						addrHex := hex.EncodeToString(addr[:])
 | 
				
			||||||
	keyDirPath := filepath.Join(keysDirPath, addrHex)
 | 
						keyDirPath := filepath.Join(keysDirPath, addrHex)
 | 
				
			||||||
	keyFilePath := filepath.Join(keyDirPath, addrHex)
 | 
						keyFilePath := filepath.Join(keyDirPath, addrHex)
 | 
				
			||||||
	err = os.MkdirAll(keyDirPath, 0700) // read, write and dir search for user
 | 
						err = os.MkdirAll(keyDirPath, 0700) // read, write and dir search for user
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user