mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
2a68f0f001
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
73 lines
2.3 KiB
Go
73 lines
2.3 KiB
Go
package encryption
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/docker/swarmkit/api"
|
|
|
|
"golang.org/x/crypto/nacl/secretbox"
|
|
)
|
|
|
|
const naclSecretboxKeySize = 32
|
|
const naclSecretboxNonceSize = 24
|
|
|
|
// This provides the default implementation of an encrypter and decrypter, as well
|
|
// as the default KDF function.
|
|
|
|
// NACLSecretbox is an implementation of an encrypter/decrypter. Encrypting
|
|
// generates random Nonces.
|
|
type NACLSecretbox struct {
|
|
key [naclSecretboxKeySize]byte
|
|
}
|
|
|
|
// NewNACLSecretbox returns a new NACL secretbox encrypter/decrypter with the given key
|
|
func NewNACLSecretbox(key []byte) NACLSecretbox {
|
|
secretbox := NACLSecretbox{}
|
|
copy(secretbox.key[:], key)
|
|
return secretbox
|
|
}
|
|
|
|
// Algorithm returns the type of algorhtm this is (NACL Secretbox using XSalsa20 and Poly1305)
|
|
func (n NACLSecretbox) Algorithm() api.MaybeEncryptedRecord_Algorithm {
|
|
return api.MaybeEncryptedRecord_NACLSecretboxSalsa20Poly1305
|
|
}
|
|
|
|
// Encrypt encrypts some bytes and returns an encrypted record
|
|
func (n NACLSecretbox) Encrypt(data []byte) (*api.MaybeEncryptedRecord, error) {
|
|
var nonce [24]byte
|
|
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Seal's first argument is an "out", the data that the new encrypted message should be
|
|
// appended to. Since we don't want to append anything, we pass nil.
|
|
encrypted := secretbox.Seal(nil, data, &nonce, &n.key)
|
|
return &api.MaybeEncryptedRecord{
|
|
Algorithm: n.Algorithm(),
|
|
Data: encrypted,
|
|
Nonce: nonce[:],
|
|
}, nil
|
|
}
|
|
|
|
// Decrypt decrypts a MaybeEncryptedRecord and returns some bytes
|
|
func (n NACLSecretbox) Decrypt(record api.MaybeEncryptedRecord) ([]byte, error) {
|
|
if record.Algorithm != n.Algorithm() {
|
|
return nil, fmt.Errorf("not a NACL secretbox record")
|
|
}
|
|
if len(record.Nonce) != naclSecretboxNonceSize {
|
|
return nil, fmt.Errorf("invalid nonce size for NACL secretbox: require 24, got %d", len(record.Nonce))
|
|
}
|
|
|
|
var decryptNonce [naclSecretboxNonceSize]byte
|
|
copy(decryptNonce[:], record.Nonce[:naclSecretboxNonceSize])
|
|
|
|
// Open's first argument is an "out", the data that the decrypted message should be
|
|
// appended to. Since we don't want to append anything, we pass nil.
|
|
decrypted, ok := secretbox.Open(nil, record.Data, &decryptNonce, &n.key)
|
|
if !ok {
|
|
return nil, fmt.Errorf("decryption error using NACL secretbox")
|
|
}
|
|
return decrypted, nil
|
|
}
|