2020-05-11 20:57:46 +02:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package storj
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/base32"
|
|
|
|
|
|
|
|
"github.com/zeebo/errs"
|
|
|
|
)
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// EncryptionParameters is the cipher suite and parameters used for encryption.
|
2020-05-11 20:57:46 +02:00
|
|
|
type EncryptionParameters struct {
|
|
|
|
// CipherSuite specifies the cipher suite to be used for encryption.
|
|
|
|
CipherSuite CipherSuite
|
|
|
|
// BlockSize determines the unit size at which encryption is performed.
|
|
|
|
// It is important to distinguish this from the block size used by the
|
|
|
|
// cipher suite (probably 128 bits). There is some small overhead for
|
|
|
|
// each encryption unit, so BlockSize should not be too small, but
|
|
|
|
// smaller sizes yield shorter first-byte latency and better seek times.
|
|
|
|
// Note that BlockSize itself is the size of data blocks _after_ they
|
|
|
|
// have been encrypted and the authentication overhead has been added.
|
|
|
|
// It is _not_ the size of the data blocks to _be_ encrypted.
|
|
|
|
BlockSize int32
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// IsZero returns true if no field in the struct is set to non-zero value.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (params EncryptionParameters) IsZero() bool {
|
|
|
|
return params == (EncryptionParameters{})
|
|
|
|
}
|
|
|
|
|
|
|
|
// CipherSuite specifies one of the encryption suites supported by Storj
|
|
|
|
// libraries for encryption of in-network data.
|
|
|
|
type CipherSuite byte
|
|
|
|
|
|
|
|
const (
|
|
|
|
// EncUnspecified indicates no encryption suite has been selected.
|
|
|
|
EncUnspecified = CipherSuite(iota)
|
|
|
|
// EncNull indicates use of the NULL cipher; that is, no encryption is
|
|
|
|
// done. The ciphertext is equal to the plaintext.
|
|
|
|
EncNull
|
|
|
|
// EncAESGCM indicates use of AES128-GCM encryption.
|
|
|
|
EncAESGCM
|
|
|
|
// EncSecretBox indicates use of XSalsa20-Poly1305 encryption, as provided
|
|
|
|
// by the NaCl cryptography library under the name "Secretbox".
|
|
|
|
EncSecretBox
|
|
|
|
// EncNullBase64URL is like EncNull but Base64 encodes/decodes the
|
2020-05-29 15:08:11 +02:00
|
|
|
// binary path data (URL-safe).
|
2020-05-11 20:57:46 +02:00
|
|
|
EncNullBase64URL
|
|
|
|
)
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// Constant definitions for key and nonce sizes.
|
2020-05-11 20:57:46 +02:00
|
|
|
const (
|
|
|
|
KeySize = 32
|
|
|
|
NonceSize = 24
|
|
|
|
)
|
|
|
|
|
|
|
|
// NewKey creates a new Storj key from humanReadableKey.
|
|
|
|
func NewKey(humanReadableKey []byte) (*Key, error) {
|
|
|
|
var key Key
|
|
|
|
|
|
|
|
// Because of backward compatibility the key is filled with 0 or truncated if
|
|
|
|
// humanReadableKey isn't of the same size that KeySize.
|
|
|
|
// See https://github.com/storj/storj/pull/1967#discussion_r285544849
|
|
|
|
copy(key[:], humanReadableKey)
|
|
|
|
return &key, nil
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// Key represents the largest key used by any encryption protocol.
|
2020-05-11 20:57:46 +02:00
|
|
|
type Key [KeySize]byte
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// Raw returns the key as a raw byte array pointer.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (key *Key) Raw() *[KeySize]byte {
|
|
|
|
return (*[KeySize]byte)(key)
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// IsZero returns true if key is nil or it points to its zero value.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (key *Key) IsZero() bool {
|
|
|
|
return key == nil || *key == (Key{})
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// ErrNonce is used when something goes wrong with a stream ID.
|
2020-05-11 20:57:46 +02:00
|
|
|
var ErrNonce = errs.Class("nonce error")
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// nonceEncoding is base32 without padding.
|
2020-05-11 20:57:46 +02:00
|
|
|
var nonceEncoding = base32.StdEncoding.WithPadding(base32.NoPadding)
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// Nonce represents the largest nonce used by any encryption protocol.
|
2020-05-11 20:57:46 +02:00
|
|
|
type Nonce [NonceSize]byte
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// NonceFromString decodes an base32 encoded.
|
2020-05-11 20:57:46 +02:00
|
|
|
func NonceFromString(s string) (Nonce, error) {
|
|
|
|
nonceBytes, err := nonceEncoding.DecodeString(s)
|
|
|
|
if err != nil {
|
|
|
|
return Nonce{}, ErrNonce.Wrap(err)
|
|
|
|
}
|
|
|
|
return NonceFromBytes(nonceBytes)
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// NonceFromBytes converts a byte slice into a nonce.
|
2020-05-11 20:57:46 +02:00
|
|
|
func NonceFromBytes(b []byte) (Nonce, error) {
|
|
|
|
if len(b) != len(Nonce{}) {
|
|
|
|
return Nonce{}, ErrNonce.New("not enough bytes to make a nonce; have %d, need %d", len(b), len(NodeID{}))
|
|
|
|
}
|
|
|
|
|
|
|
|
var nonce Nonce
|
|
|
|
copy(nonce[:], b)
|
|
|
|
return nonce, nil
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// IsZero returns whether nonce is unassigned.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (nonce Nonce) IsZero() bool {
|
|
|
|
return nonce == Nonce{}
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// String representation of the nonce.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (nonce Nonce) String() string { return nonceEncoding.EncodeToString(nonce.Bytes()) }
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// Bytes returns bytes of the nonce.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (nonce Nonce) Bytes() []byte { return nonce[:] }
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// Raw returns the nonce as a raw byte array pointer.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (nonce *Nonce) Raw() *[NonceSize]byte {
|
|
|
|
return (*[NonceSize]byte)(nonce)
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// Marshal serializes a nonce.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (nonce Nonce) Marshal() ([]byte, error) {
|
|
|
|
return nonce.Bytes(), nil
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// MarshalTo serializes a nonce into the passed byte slice.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (nonce *Nonce) MarshalTo(data []byte) (n int, err error) {
|
|
|
|
n = copy(data, nonce.Bytes())
|
|
|
|
return n, nil
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// Unmarshal deserializes a nonce.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (nonce *Nonce) Unmarshal(data []byte) error {
|
|
|
|
var err error
|
|
|
|
*nonce, err = NonceFromBytes(data)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// Size returns the length of a nonce (implements gogo's custom type interface).
|
2020-05-11 20:57:46 +02:00
|
|
|
func (nonce Nonce) Size() int {
|
|
|
|
return len(nonce)
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// MarshalJSON serializes a nonce to a json string as bytes.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (nonce Nonce) MarshalJSON() ([]byte, error) {
|
|
|
|
return []byte(`"` + nonce.String() + `"`), nil
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// UnmarshalJSON deserializes a json string (as bytes) to a nonce.
|
2020-05-11 20:57:46 +02:00
|
|
|
func (nonce *Nonce) UnmarshalJSON(data []byte) error {
|
|
|
|
var err error
|
|
|
|
*nonce, err = NonceFromString(string(data))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:08:11 +02:00
|
|
|
// EncryptedPrivateKey is a private key that has been encrypted.
|
2020-05-11 20:57:46 +02:00
|
|
|
type EncryptedPrivateKey []byte
|