pubaccesskey

package
v1.6.0 Latest Latest
Warning

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

Go to latest
Published: Nov 22, 2021 License: MIT Imports: 15 Imported by: 0

README

Pubaccesskey Manager

The pubaccesskey package defines Pubaccesskeys used for encrypting files in Pubaccess and provides a way to persist Pubaccesskeys using a SkykeyManager that manages these keys in a file on-disk.

The file consists of a header which is: SkykeyFileMagic | SkykeyVersion | Length

The SkykeyFileMagic never changes. The version only changes when backwards-incompatible changes are made to the design of Pubaccesskeys or to the way this file is structured. The length refers to the number of bytes in the file.

When adding a Pubaccesskey to the file, a Pubaccesskey is unmarshaled and appended to the end of the file and the file is then synced. Then the length field in the header is updated to indicate the newly written bytes and the file is synced once again.

Pubaccesskeys

A Pubaccesskey is a key associated with a name to be used in Pubaccess to share encrypted files. Each key has a name and a unique identifier.

The Pubaccesskey format is one byte called the PubaccesskeyType followed by rest of the data associated with that key.

Types

TypeInvalid represents an unusable, invalid key.

TypePublicID represents a pubaccesskey that uses the XChaCha20 cipher schemes and is currently used for encrypting skyfiles. In pubfile encryption the key ID is revealed in plaintext, therefore its name is TypePublicID Implicitly, this specifies the entropy length as the length of a key and nonce in that scheme. Its byte representation is 1 type byte and 56 entropy bytes.

TypePrivateID represents a pubaccesskey that uses the XChaCha20 cipher schemes and is can be used for encrypting skyfiles. Implicitly, this specifies the entropy length as the length of a key and nonce in that scheme. Its byte representation is 1 type byte and 56 entropy bytes. When used for pubfile encryption, the key ID is never revealed. Instead the Pubaccesskey is used to derive a file-specific key, which is then used to encrypt a known identifier. This means that without knowledge of the Pubaccesskey, you cannot tell which Skykeys were used for which pubfile and cannot even group together skyfiles encrypted with the same TypePrivateID Pubaccesskey. If you do have the Pubaccesskey, you can verify that fact by decrypting the identifier and checking against the known plaintext.

Encoding

Skykeys are meant to be shared using the string format which is a URI encoding with the optional pubaccesskey:" scheme and an optional name parameter including the pubaccesskey name. The key data (type and entropy) is stored as the base64-encoded path.

Some examples of valid encodings below:

  • (No URI scheme and no name): AT7-P751d_SEBhXvbOQTfswB62n2mqMe0Q89cQ911KGeuTIV2ci6GjG3Aj5CuVZUDS6hkG7pHXXZ
  • (No name): pubaccesskey:AT7-P751d_SEBhXvbOQTfswB62n2mqMe0Q89cQ911KGeuTIV2ci6GjG3Aj5CuVZUDS6hkG7pHXXZ
  • (No URI scheme): AT7-P751d_SEBhXvbOQTfswB62n2mqMe0Q89cQ911KGeuTIV2ci6GjG3Aj5CuVZUDS6hkG7pHXXZ?name=ExampleKey
  • (Includes URI scheme and name): pubaccesskey:AT7-P751d_SEBhXvbOQTfswB62n2mqMe0Q89cQ911KGeuTIV2ci6GjG3Aj5CuVZUDS6hkG7pHXXZ?name=ExampleKey

It is recommended that users include the URI scheme for maximum clarity, but the FromString method will be accept any strings of the above forms.

Usage

Skykeys are primarily used for encrypting skyfiles. Currently all pubaccesskeys are used with the XChaCha20 stream cipher. Key re-use is safe with this encryption scheme if we use random nonces for each message. This is safe until 2 << 96 messages are transmitted.

Key Derivation

The pubaccesskey manager stores only master pubaccesskeys. These pubaccesskeys are not used directly for encryption/decryption. Rather they are used to derive file-specific Skykeys. File-specific pubaccesskeys share the same key material as the master pubaccesskey they are derived from. They differ in the nonce value. This allows us to reuse the master pubaccesskey for multiple files, by using a new file-specific pubaccesskey for every new file.

The method GenerateFileSpecificSubkey is used to create new file-specific sub-keys from a master pubaccesskey.

Further levels of key derivation may be necessary and are supported by using the DeriveSubkey method.

Pubfile encryption

Two other types of subkeys are the ones actually used for encrypting skyfiles. There is a BaseSector derivation and a Fanout derivation which are used for encrypting the base sector and fanout of a pubfile respectively.

This is necessary because of the final level of key derivation used in the upload process of Sia. When splitting up files for redundancy, each (chunkIndex, pieceIndex) upload uses a different XChaCha20 nonce as well. To avoid re-using the same (chunkIndex, pieceIndex) derivation for the base sector and fanout sections, we just use a different nonce for each.

Documentation

Index

Constants

View Source
const (
	// SkykeyScheme is the URI scheme for encoded pubaccesskeys.
	SkykeyScheme = "pubaccesskey"

	// SkykeyIDLen is the length of a PubaccesskeyID
	SkykeyIDLen = 16

	// MaxKeyNameLen is the maximum length of a pubaccesskey's name.
	MaxKeyNameLen = 128

	// TypeInvalid represents an invalid pubaccesskey type.
	TypeInvalid = PubaccesskeyType(0x00)

	// TypePublicID is a Pubaccesskey that uses XChaCha20. It reveals its
	// pubaccesskey ID in *every* pubfile it encrypts.
	TypePublicID = PubaccesskeyType(0x01)

	// TypePrivateID is a Pubaccesskey that uses XChaCha20 that does not
	// reveal its pubaccesskey ID when encrypting Skyfiles. Instead, it marks the pubaccesskey
	// used for encryption by storing an encrypted identifier that can only be
	// successfully decrypted with the correct pubaccesskey.
	TypePrivateID = PubaccesskeyType(0x02)
)

Variables

View Source
var (
	// SkykeySpecifier is used as a prefix when hashing Pubaccesskeys to compute their
	// ID.
	SkykeySpecifier = types.NewSpecifier("Pubaccesskey")

	// ErrInvalidPubaccesskeyType is returned when an invalid PubaccesskeyType is being used.
	ErrInvalidPubaccesskeyType = errors.New("Invalid pubaccesskey type")
)
View Source
var (

	// SkykeyFileMagic is the first piece of data found in a Pubaccesskey file.
	SkykeyFileMagic = types.NewSpecifier("PubaccesskeyFile")

	// SkykeyPersistFilename is the name of the pubaccesskey persistence file.
	SkykeyPersistFilename = "pubaccesskeys.dat"

	// ErrNoSkykeysWithThatID indicates that the Pubaccesskey manager doesn't have a key
	// with that ID.
	ErrNoSkykeysWithThatID = errors.New("No Pubaccesskey is associated with that ID")

	// ErrSkykeyWithIDAlreadyExists indicates that a key cannot be created or
	// added because a key with the same ID (and therefore same key entropy) is
	// already being stored.
	ErrSkykeyWithIDAlreadyExists = errors.New("Pubaccesskey ID already exists.")

	// ErrSkykeyWithNameAlreadyExists indicates that a key cannot be created or added
	// because a key with the same name is already being stored.
	ErrSkykeyWithNameAlreadyExists = errors.New("Pubaccesskey name already used by another key.")

	// ErrNoSkykeysWithThatName indicates that the key manager doesn't have
	// a key with that ID
	ErrNoSkykeysWithThatName = errors.New("No Pubaccesskey with that name")
)

Persistence constants

Functions

This section is empty.

Types

type Pubaccesskey

type Pubaccesskey struct {
	Name    string
	Type    PubaccesskeyType
	Entropy []byte
}

Pubaccesskey is a key used to encrypt/decrypt skyfiles.

func (*Pubaccesskey) CipherKey

func (sk *Pubaccesskey) CipherKey() (crypto.CipherKey, error)

CipherKey returns the crypto.CipherKey equivalent of this Pubaccesskey.

func (*Pubaccesskey) CipherType

func (sk *Pubaccesskey) CipherType() crypto.CipherType

CipherType returns the crypto.CipherType used by this Pubaccesskey.

func (*Pubaccesskey) DeriveSubkey

func (sk *Pubaccesskey) DeriveSubkey(derivation []byte) (Pubaccesskey, error)

DeriveSubkey is used to create Skykeys with the same key, but with a different nonce. This is used to create file-specific keys, and separate keys for Pubfile baseSector uploads and fanout uploads.

func (*Pubaccesskey) FromString

func (sk *Pubaccesskey) FromString(s string) error

FromString decodes the base64 string into a Pubaccesskey.

func (*Pubaccesskey) GenerateFileSpecificSubkey

func (sk *Pubaccesskey) GenerateFileSpecificSubkey() (Pubaccesskey, error)

GenerateFileSpecificSubkey creates a new subkey specific to a certain file being uploaded/downloaded. Skykeys can only be used once with a given nonce, so this method is used to generate keys with new nonces when a new file is uploaded.

func (*Pubaccesskey) GenerateSkyfileEncryptionID

func (sk *Pubaccesskey) GenerateSkyfileEncryptionID() ([SkykeyIDLen]byte, error)

GenerateSkyfileEncryptionID creates an encrypted identifier that is used for PrivateID encrypted files. NOTE: This method MUST only be called using a FileSpecificSkykey.

func (Pubaccesskey) ID

func (sk Pubaccesskey) ID() (keyID PubaccesskeyID)

ID returns the ID for the Pubaccesskey. A master Pubaccesskey and all file-specific pubaccesskeys derived from it share the same ID because they only differ in nonce values, not key values. This fact is used to identify the master Pubaccesskey with which a Pubaccess file was encrypted.

func (*Pubaccesskey) IsValid

func (sk *Pubaccesskey) IsValid() error

IsValid returns an nil if the pubaccesskey is valid and an error otherwise.

func (*Pubaccesskey) MatchesSkyfileEncryptionID

func (sk *Pubaccesskey) MatchesSkyfileEncryptionID(encryptionID, nonce []byte) (bool, error)

MatchesSkyfileEncryptionID returns true if and only if the pubaccesskey was the one used with this nonce to create the encryptionID.

func (*Pubaccesskey) Nonce

func (sk *Pubaccesskey) Nonce() []byte

Nonce returns the nonce of this Pubaccesskey.

func (*Pubaccesskey) SubkeyWithNonce

func (sk *Pubaccesskey) SubkeyWithNonce(nonce []byte) (Pubaccesskey, error)

SubkeyWithNonce creates a new subkey with the same key data as this key, but with the given nonce.

func (Pubaccesskey) ToString

func (sk Pubaccesskey) ToString() (string, error)

ToString encodes the Pubaccesskey as a base64 string.

type PubaccesskeyID

type PubaccesskeyID [SkykeyIDLen]byte

PubaccesskeyID is the identifier of a pubaccesskey.

func (*PubaccesskeyID) FromString

func (id *PubaccesskeyID) FromString(s string) error

FromString decodes the base64 string into a Pubaccesskey ID.

func (PubaccesskeyID) ToString

func (id PubaccesskeyID) ToString() string

ToString encodes the PubaccesskeyID as a base64 string.

type PubaccesskeyType

type PubaccesskeyType byte

PubaccesskeyType encodes the encryption scheme and method used by the Pubaccesskey.

func (PubaccesskeyType) CipherType

func (t PubaccesskeyType) CipherType() crypto.CipherType

CipherType returns the crypto.CipherType used by this Pubaccesskey.

func (*PubaccesskeyType) FromString

func (t *PubaccesskeyType) FromString(s string) error

FromString reads a PubaccesskeyType from a string.

func (PubaccesskeyType) ToString

func (t PubaccesskeyType) ToString() string

ToString returns the string representation of the ciphertype.

type SkykeyManager

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

SkykeyManager manages the creation and handling of new pubaccesskeys which can be referenced by their unique name or identifier.

func NewSkykeyManager

func NewSkykeyManager(persistDir string) (*SkykeyManager, error)

NewSkykeyManager creates a SkykeyManager for managing pubaccesskeys.

func (*SkykeyManager) AddKey

func (sm *SkykeyManager) AddKey(sk Pubaccesskey) error

AddKey adds the given Pubaccesskey to the pubaccesskey manager.

func (*SkykeyManager) CreateKey

func (sm *SkykeyManager) CreateKey(name string, skykeyType PubaccesskeyType) (Pubaccesskey, error)

CreateKey creates a new Pubaccesskey under the given name and PubaccesskeyType.

func (*SkykeyManager) DeleteKeyByID

func (sm *SkykeyManager) DeleteKeyByID(id PubaccesskeyID) error

DeleteKeyByID deletes the pubaccesskey with the given ID.

func (*SkykeyManager) DeleteKeyByName

func (sm *SkykeyManager) DeleteKeyByName(name string) error

DeleteKeyByName deletes the pubaccesskey with the given name.

func (*SkykeyManager) IDByName

func (sm *SkykeyManager) IDByName(name string) (PubaccesskeyID, error)

IDByName returns the ID associated with the given key name.

func (*SkykeyManager) KeyByID

func (sm *SkykeyManager) KeyByID(id PubaccesskeyID) (Pubaccesskey, error)

KeyByID returns the Pubaccesskey associated with that ID.

func (*SkykeyManager) KeyByName

func (sm *SkykeyManager) KeyByName(name string) (Pubaccesskey, error)

KeyByName returns the Pubaccesskey associated with that key name.

func (*SkykeyManager) Skykeys

func (sm *SkykeyManager) Skykeys() []Pubaccesskey

Skykeys returns a slice containing each Pubaccesskey being stored.

func (*SkykeyManager) SupportsPubaccesskeyType

func (sm *SkykeyManager) SupportsPubaccesskeyType(skykeyType PubaccesskeyType) bool

SupportsPubaccesskeyType returns true if and only if the SkykeyManager supports skykeys with the given type.

Jump to

Keyboard shortcuts

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