keymgr

package
v0.0.0-...-ddd0786 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 5, 2016 License: ISC Imports: 17 Imported by: 0

Documentation

Overview

Package keymgr is a key manager for use with bmclient. However, it is meant to be used independently and handles hierarchically deterministic keys, imported keys (from PyBitmessage or other legacy systems), as well as channels.

The file format for storage is a JSON document encrypted with SalsaX20 and MAC'd with Poly1305. The scheme used is byte compatible with secretbox from NaCl. Currently, it supports encrypting the entire file containing identity information (encryption and signing keys, required PoW constants, etc) and master key.

Future support for separately encrypting master key and signing keys is planned. This could be useful for:

  • Read only bmclient nodes that are intended to only receive and decrypt messages bound for them and are not likely to be used for sending messages.
  • Security conscious users who might be worried about memory-reading malware. Note that even if we configure bmclient as such, the malware would still be able to get the user's private encryption key. By the very nature of Bitmessage, private encryption keys need to be in memory all the time.

The contents of the encrypted file are arranged as such: Nonce (24 bytes) || Salt for PBKDF2 (32 bytes) || Encrypted data

Both the nonce and salt are re-generated each time the file needs to be saved. This, along with a high number of PBKDF2 iterations (2^15), helps to ensure that an adversary with access to the key file will have an extremely hard time trying to bruteforce it. Rainbow tables will be useless.

WARNING (again): The key manager is insecure against memory reading malware

and is at the mercy of Go's garbage collector.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrDecryptionFailed is returned when decryption of the key file fails.
	// This could be due to invalid passphrase or corrupt/tampered data.
	ErrDecryptionFailed = errors.New("invalid passphrase")

	// ErrDuplicateIdentity is returned by Import when the identity to be
	// imported already exists in the key manager.
	ErrDuplicateIdentity = errors.New("identity already in key manager")

	// ErrNonexistentIdentity is returned when the identity doesn't exist in the
	// key manager.
	ErrNonexistentIdentity = errors.New("identity doesn't exist")
)
View Source
var (
	// ErrUnknownKeyfileVersion  is returned when the version of the keyfile is
	// unknown. Maybe we are using a newer keyfile with an older bmclient.
	ErrUnknownKeyfileVersion = errors.New("unknown keyfile version")
)

Functions

This section is empty.

Types

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager is the key manager used for managing imported as well as hierarchically deterministic keys. It is safe for access from multiple goroutines.

func FromEncrypted

func FromEncrypted(enc, pass []byte) (*Manager, error)

FromEncrypted creates a new Manager object from the specified encrypted data and passphrase. The actual key used for decryption is derived from the salt, which is a part of enc, and the passphrase using PBKDF2.

func FromPlaintext

func FromPlaintext(r io.Reader) (*Manager, error)

Imports a key manager from plaintext.

func New

func New(seed []byte) (*Manager, error)

New creates a new key manager and generates a master key from the provided seed. The seed must be between 128 and 512 bits and should be generated by a cryptographically secure random generation source. Refer to docs for hdkeychain.NewMaster and hdkeychain.GenerateSeed for more info.

func (*Manager) Addresses

func (mgr *Manager) Addresses() []string

GetAddresses returns the set of addresses in the key manager.

func (*Manager) ExportEncrypted

func (mgr *Manager) ExportEncrypted(pass []byte) ([]byte, error)

ExportEncrypted encrypts the current state of the key manager with the specified password and returns it. The salt used as input to PBKDF2 as well as nonce for input to secretbox are randomly generated. The actual key used for encryption is derived from the salt and the passphrase using PBKDF2.

func (*Manager) ExportPlaintext

func (mgr *Manager) ExportPlaintext() ([]byte, error)

ExportPlaintext exports the state of the key manager in an unencrypted state. It's useful for debugging or manual inspection of keys.

func (*Manager) ForEach

func (mgr *Manager) ForEach(f func(*PrivateID) error) error

ForEach runs the specified function for all the identities stored in the key manager. It does not return until the function has been invoked for all keys and breaks early on error.

func (*Manager) ImportIdentity

func (mgr *Manager) ImportIdentity(privID PrivateID)

ImportIdentity imports an existing identity into the key manager. It's useful for users who have existing identities or want to subscribe to channels.

func (*Manager) ImportKeys

func (mgr *Manager) ImportKeys(data []byte) map[string]string

Import keys from Pybitmessage or another bmagent identity. Returns a map containing the imported addresses and names.

func (*Manager) ImportKeysFromPyBitmessage

func (mgr *Manager) ImportKeysFromPyBitmessage(f ini.File) map[string]string

Given an ini file like that created by PyBitmessage, import into the key manager.

func (*Manager) LookupByAddress

func (mgr *Manager) LookupByAddress(address string) *PrivateID

LookupByAddress looks up a private identity in the key manager by its address. If no matching identity can be found, ErrNonexistentIdentity is returned.

func (*Manager) NameAddress

func (mgr *Manager) NameAddress(address, name string) error

NameAddress names an address.

func (*Manager) Names

func (mgr *Manager) Names() map[string]string

Get the map of addresses to names.

func (*Manager) NewHDIdentity

func (mgr *Manager) NewHDIdentity(stream uint32, name string) *PrivateID

NewHDIdentity generates a new HD identity and numbers it based on previously derived identities. If 2^32 identities have already been generated, new identities would be duplicates because of overflow problems.

func (*Manager) NewHDUnnamedIdentity

func (mgr *Manager) NewHDUnnamedIdentity(stream uint32) *PrivateID

func (*Manager) NumDeterministic

func (mgr *Manager) NumDeterministic() int

NumDeterministic returns the number of identities that have been created deterministically (according to BIP-BM01).

func (*Manager) NumImported

func (mgr *Manager) NumImported() int

NumImported returns the number of imported identities that the key manager has in the database.

func (*Manager) Size

func (mgr *Manager) Size() int

func (*Manager) UnnameAddress

func (mgr *Manager) UnnameAddress(address string) error

UnnameAddress removes a name from the address.

type MasterKey

type MasterKey hdkeychain.ExtendedKey

MasterKey is the key from which all HD keys are derived. It's an ExtendedKey with JSON marshalling/unmarshalling support.

func (*MasterKey) MarshalJSON

func (k *MasterKey) MarshalJSON() ([]byte, error)

MarshalJSON marshals the object into JSON. Part of json.Marshaller interface.

func (*MasterKey) UnmarshalJSON

func (k *MasterKey) UnmarshalJSON(in []byte) error

UnmarshalJSON unmarshals the object from JSON. Part of json.Unmarshaller interface.

type PrivateID

type PrivateID struct {
	identity.Private

	// IsChan tells whether the identity is that of a channel. Based on this,
	// bmclient could figure out whether to prepare/send ack messages or not,
	// and handle this identity separately from others.
	IsChan bool

	// Disabled tells whether the identity has been marked as inactive. This
	// could be either because it cannot be removed (it's an HD identity that
	// we don't want to receive messages for anymore) or we want to store the
	// private keys for an imported identity but not actively listen on it.
	Disabled bool

	// IsImported says whether the identity is imported or derived.
	Imported bool

	// Name is a name for this id.
	Name string
}

PrivateID embeds an identity.Private object, adding support for JSON marshalling/unmarshalling and other params.

func (*PrivateID) Address

func (p *PrivateID) Address() string

func (*PrivateID) MarshalJSON

func (id *PrivateID) MarshalJSON() ([]byte, error)

MarshalJSON marshals the object into JSON. Part of json.Marshaller interface.

func (*PrivateID) UnmarshalJSON

func (id *PrivateID) UnmarshalJSON(in []byte) error

UnmarshalJSON unmarshals the object from JSON. Part of json.Unmarshaller interface.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL