github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/encryption/fernet.go (about) 1 package encryption 2 3 import ( 4 "fmt" 5 6 "github.com/docker/swarmkit/api" 7 8 "github.com/fernet/fernet-go" 9 ) 10 11 // Fernet wraps the `fernet` library as an implementation of encrypter/decrypter. 12 type Fernet struct { 13 key fernet.Key 14 } 15 16 // NewFernet returns a new Fernet encrypter/decrypter with the given key 17 func NewFernet(key []byte) Fernet { 18 frnt := Fernet{} 19 copy(frnt.key[:], key) 20 return frnt 21 } 22 23 // Algorithm returns the type of algorithm this is (Fernet, which uses AES128-CBC) 24 func (f Fernet) Algorithm() api.MaybeEncryptedRecord_Algorithm { 25 return api.MaybeEncryptedRecord_FernetAES128CBC 26 } 27 28 // Encrypt encrypts some bytes and returns an encrypted record 29 func (f Fernet) Encrypt(data []byte) (*api.MaybeEncryptedRecord, error) { 30 out, err := fernet.EncryptAndSign(data, &f.key) 31 if err != nil { 32 return nil, err 33 } 34 // fernet generates its own IVs, so nonce is empty 35 return &api.MaybeEncryptedRecord{ 36 Algorithm: f.Algorithm(), 37 Data: out, 38 }, nil 39 } 40 41 // Decrypt decrypts a MaybeEncryptedRecord and returns some bytes 42 func (f Fernet) Decrypt(record api.MaybeEncryptedRecord) ([]byte, error) { 43 if record.Algorithm != f.Algorithm() { 44 return nil, fmt.Errorf("record is not a Fernet message") 45 } 46 47 // -1 skips the TTL check, since we don't care about message expiry 48 out := fernet.VerifyAndDecrypt(record.Data, -1, []*fernet.Key{&f.key}) 49 // VerifyandDecrypt returns a nil message if it can't be verified and decrypted 50 if out == nil { 51 return nil, fmt.Errorf("no decryption key for record encrypted with %s", f.Algorithm()) 52 } 53 return out, nil 54 }