From baba8fa92f47cad604f6d2a2714d09f89178fbff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Mon, 30 Apr 2018 23:35:10 +0200 Subject: Upgrading minio-go library to 6.0.0 (#8651) * Upgrading minio-go library to 6.0.0 * Removing unnecesary Gopkg constraint --- .../github.com/minio/minio-go/pkg/encrypt/cbc.go | 294 --------------------- .../minio/minio-go/pkg/encrypt/interface.go | 54 ---- .../github.com/minio/minio-go/pkg/encrypt/keys.go | 166 ------------ .../minio/minio-go/pkg/encrypt/server-side.go | 195 ++++++++++++++ 4 files changed, 195 insertions(+), 514 deletions(-) delete mode 100644 vendor/github.com/minio/minio-go/pkg/encrypt/cbc.go delete mode 100644 vendor/github.com/minio/minio-go/pkg/encrypt/interface.go delete mode 100644 vendor/github.com/minio/minio-go/pkg/encrypt/keys.go create mode 100644 vendor/github.com/minio/minio-go/pkg/encrypt/server-side.go (limited to 'vendor/github.com/minio/minio-go/pkg/encrypt') diff --git a/vendor/github.com/minio/minio-go/pkg/encrypt/cbc.go b/vendor/github.com/minio/minio-go/pkg/encrypt/cbc.go deleted file mode 100644 index b0f2d6e08..000000000 --- a/vendor/github.com/minio/minio-go/pkg/encrypt/cbc.go +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package encrypt - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/rand" - "encoding/base64" - "errors" - "io" -) - -// Crypt mode - encryption or decryption -type cryptMode int - -const ( - encryptMode cryptMode = iota - decryptMode -) - -// CBCSecureMaterials encrypts/decrypts data using AES CBC algorithm -type CBCSecureMaterials struct { - - // Data stream to encrypt/decrypt - stream io.Reader - - // Last internal error - err error - - // End of file reached - eof bool - - // Holds initial data - srcBuf *bytes.Buffer - - // Holds transformed data (encrypted or decrypted) - dstBuf *bytes.Buffer - - // Encryption algorithm - encryptionKey Key - - // Key to encrypts/decrypts data - contentKey []byte - - // Encrypted form of contentKey - cryptedKey []byte - - // Initialization vector - iv []byte - - // matDesc - currently unused - matDesc []byte - - // Indicate if we are going to encrypt or decrypt - cryptMode cryptMode - - // Helper that encrypts/decrypts data - blockMode cipher.BlockMode -} - -// NewCBCSecureMaterials builds new CBC crypter module with -// the specified encryption key (symmetric or asymmetric) -func NewCBCSecureMaterials(key Key) (*CBCSecureMaterials, error) { - if key == nil { - return nil, errors.New("Unable to recognize empty encryption properties") - } - return &CBCSecureMaterials{ - srcBuf: bytes.NewBuffer([]byte{}), - dstBuf: bytes.NewBuffer([]byte{}), - encryptionKey: key, - matDesc: []byte("{}"), - }, nil - -} - -// Close implements closes the internal stream. -func (s *CBCSecureMaterials) Close() error { - closer, ok := s.stream.(io.Closer) - if ok { - return closer.Close() - } - return nil -} - -// SetupEncryptMode - tells CBC that we are going to encrypt data -func (s *CBCSecureMaterials) SetupEncryptMode(stream io.Reader) error { - // Set mode to encrypt - s.cryptMode = encryptMode - - // Set underlying reader - s.stream = stream - - s.eof = false - s.srcBuf.Reset() - s.dstBuf.Reset() - - var err error - - // Generate random content key - s.contentKey = make([]byte, aes.BlockSize*2) - if _, err := rand.Read(s.contentKey); err != nil { - return err - } - // Encrypt content key - s.cryptedKey, err = s.encryptionKey.Encrypt(s.contentKey) - if err != nil { - return err - } - // Generate random IV - s.iv = make([]byte, aes.BlockSize) - if _, err = rand.Read(s.iv); err != nil { - return err - } - // New cipher - encryptContentBlock, err := aes.NewCipher(s.contentKey) - if err != nil { - return err - } - - s.blockMode = cipher.NewCBCEncrypter(encryptContentBlock, s.iv) - - return nil -} - -// SetupDecryptMode - tells CBC that we are going to decrypt data -func (s *CBCSecureMaterials) SetupDecryptMode(stream io.Reader, iv string, key string) error { - // Set mode to decrypt - s.cryptMode = decryptMode - - // Set underlying reader - s.stream = stream - - // Reset - s.eof = false - s.srcBuf.Reset() - s.dstBuf.Reset() - - var err error - - // Get IV - s.iv, err = base64.StdEncoding.DecodeString(iv) - if err != nil { - return err - } - - // Get encrypted content key - s.cryptedKey, err = base64.StdEncoding.DecodeString(key) - if err != nil { - return err - } - - // Decrypt content key - s.contentKey, err = s.encryptionKey.Decrypt(s.cryptedKey) - if err != nil { - return err - } - - // New cipher - decryptContentBlock, err := aes.NewCipher(s.contentKey) - if err != nil { - return err - } - - s.blockMode = cipher.NewCBCDecrypter(decryptContentBlock, s.iv) - return nil -} - -// GetIV - return randomly generated IV (per S3 object), base64 encoded. -func (s *CBCSecureMaterials) GetIV() string { - return base64.StdEncoding.EncodeToString(s.iv) -} - -// GetKey - return content encrypting key (cek) in encrypted form, base64 encoded. -func (s *CBCSecureMaterials) GetKey() string { - return base64.StdEncoding.EncodeToString(s.cryptedKey) -} - -// GetDesc - user provided encryption material description in JSON (UTF8) format. -func (s *CBCSecureMaterials) GetDesc() string { - return string(s.matDesc) -} - -// Fill buf with encrypted/decrypted data -func (s *CBCSecureMaterials) Read(buf []byte) (n int, err error) { - // Always fill buf from bufChunk at the end of this function - defer func() { - if s.err != nil { - n, err = 0, s.err - } else { - n, err = s.dstBuf.Read(buf) - } - }() - - // Return - if s.eof { - return - } - - // Fill dest buffer if its length is less than buf - for !s.eof && s.dstBuf.Len() < len(buf) { - - srcPart := make([]byte, aes.BlockSize) - dstPart := make([]byte, aes.BlockSize) - - // Fill src buffer - for s.srcBuf.Len() < aes.BlockSize*2 { - _, err = io.CopyN(s.srcBuf, s.stream, aes.BlockSize) - if err != nil { - break - } - } - - // Quit immediately for errors other than io.EOF - if err != nil && err != io.EOF { - s.err = err - return - } - - // Mark current encrypting/decrypting as finished - s.eof = (err == io.EOF) - - if s.eof && s.cryptMode == encryptMode { - if srcPart, err = pkcs5Pad(s.srcBuf.Bytes(), aes.BlockSize); err != nil { - s.err = err - return - } - } else { - _, _ = s.srcBuf.Read(srcPart) - } - - // Crypt srcPart content - for len(srcPart) > 0 { - - // Crypt current part - s.blockMode.CryptBlocks(dstPart, srcPart[:aes.BlockSize]) - - // Unpad when this is the last part and we are decrypting - if s.eof && s.cryptMode == decryptMode { - dstPart, err = pkcs5Unpad(dstPart, aes.BlockSize) - if err != nil { - s.err = err - return - } - } - - // Send crypted data to dstBuf - if _, wErr := s.dstBuf.Write(dstPart); wErr != nil { - s.err = wErr - return - } - // Move to the next part - srcPart = srcPart[aes.BlockSize:] - } - } - return -} - -// Unpad a set of bytes following PKCS5 algorithm -func pkcs5Unpad(buf []byte, blockSize int) ([]byte, error) { - len := len(buf) - if len == 0 { - return nil, errors.New("buffer is empty") - } - pad := int(buf[len-1]) - if pad > len || pad > blockSize { - return nil, errors.New("invalid padding size") - } - return buf[:len-pad], nil -} - -// Pad a set of bytes following PKCS5 algorithm -func pkcs5Pad(buf []byte, blockSize int) ([]byte, error) { - len := len(buf) - pad := blockSize - (len % blockSize) - padText := bytes.Repeat([]byte{byte(pad)}, pad) - return append(buf, padText...), nil -} diff --git a/vendor/github.com/minio/minio-go/pkg/encrypt/interface.go b/vendor/github.com/minio/minio-go/pkg/encrypt/interface.go deleted file mode 100644 index 482922ab7..000000000 --- a/vendor/github.com/minio/minio-go/pkg/encrypt/interface.go +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Package encrypt implements a generic interface to encrypt any stream of data. -// currently this package implements two types of encryption -// - Symmetric encryption using AES. -// - Asymmetric encrytion using RSA. -package encrypt - -import "io" - -// Materials - provides generic interface to encrypt any stream of data. -type Materials interface { - - // Closes the wrapped stream properly, initiated by the caller. - Close() error - - // Returns encrypted/decrypted data, io.Reader compatible. - Read(b []byte) (int, error) - - // Get randomly generated IV, base64 encoded. - GetIV() (iv string) - - // Get content encrypting key (cek) in encrypted form, base64 encoded. - GetKey() (key string) - - // Get user provided encryption material description in - // JSON (UTF8) format. This is not used, kept for future. - GetDesc() (desc string) - - // Setup encrypt mode, further calls of Read() function - // will return the encrypted form of data streamed - // by the passed reader - SetupEncryptMode(stream io.Reader) error - - // Setup decrypted mode, further calls of Read() function - // will return the decrypted form of data streamed - // by the passed reader - SetupDecryptMode(stream io.Reader, iv string, key string) error -} diff --git a/vendor/github.com/minio/minio-go/pkg/encrypt/keys.go b/vendor/github.com/minio/minio-go/pkg/encrypt/keys.go deleted file mode 100644 index 0ed95f5ff..000000000 --- a/vendor/github.com/minio/minio-go/pkg/encrypt/keys.go +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Minio Go Library for Amazon S3 Compatible Cloud Storage - * Copyright 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package encrypt - -import ( - "crypto/aes" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "errors" -) - -// Key - generic interface to encrypt/decrypt a key. -// We use it to encrypt/decrypt content key which is the key -// that encrypt/decrypt object data. -type Key interface { - // Encrypt data using to the set encryption key - Encrypt([]byte) ([]byte, error) - // Decrypt data using to the set encryption key - Decrypt([]byte) ([]byte, error) -} - -// SymmetricKey - encrypts data with a symmetric master key -type SymmetricKey struct { - masterKey []byte -} - -// Encrypt passed bytes -func (s *SymmetricKey) Encrypt(plain []byte) ([]byte, error) { - // Initialize an AES encryptor using a master key - keyBlock, err := aes.NewCipher(s.masterKey) - if err != nil { - return []byte{}, err - } - - // Pad the key before encryption - plain, _ = pkcs5Pad(plain, aes.BlockSize) - - encKey := []byte{} - encPart := make([]byte, aes.BlockSize) - - // Encrypt the passed key by block - for { - if len(plain) < aes.BlockSize { - break - } - // Encrypt the passed key - keyBlock.Encrypt(encPart, plain[:aes.BlockSize]) - // Add the encrypted block to the total encrypted key - encKey = append(encKey, encPart...) - // Pass to the next plain block - plain = plain[aes.BlockSize:] - } - return encKey, nil -} - -// Decrypt passed bytes -func (s *SymmetricKey) Decrypt(cipher []byte) ([]byte, error) { - // Initialize AES decrypter - keyBlock, err := aes.NewCipher(s.masterKey) - if err != nil { - return nil, err - } - - var plain []byte - plainPart := make([]byte, aes.BlockSize) - - // Decrypt the encrypted data block by block - for { - if len(cipher) < aes.BlockSize { - break - } - keyBlock.Decrypt(plainPart, cipher[:aes.BlockSize]) - // Add the decrypted block to the total result - plain = append(plain, plainPart...) - // Pass to the next cipher block - cipher = cipher[aes.BlockSize:] - } - - // Unpad the resulted plain data - plain, err = pkcs5Unpad(plain, aes.BlockSize) - if err != nil { - return nil, err - } - - return plain, nil -} - -// NewSymmetricKey generates a new encrypt/decrypt crypto using -// an AES master key password -func NewSymmetricKey(b []byte) *SymmetricKey { - return &SymmetricKey{masterKey: b} -} - -// AsymmetricKey - struct which encrypts/decrypts data -// using RSA public/private certificates -type AsymmetricKey struct { - publicKey *rsa.PublicKey - privateKey *rsa.PrivateKey -} - -// Encrypt data using public key -func (a *AsymmetricKey) Encrypt(plain []byte) ([]byte, error) { - cipher, err := rsa.EncryptPKCS1v15(rand.Reader, a.publicKey, plain) - if err != nil { - return nil, err - } - return cipher, nil -} - -// Decrypt data using public key -func (a *AsymmetricKey) Decrypt(cipher []byte) ([]byte, error) { - cipher, err := rsa.DecryptPKCS1v15(rand.Reader, a.privateKey, cipher) - if err != nil { - return nil, err - } - return cipher, nil -} - -// NewAsymmetricKey - generates a crypto module able to encrypt/decrypt -// data using a pair for private and public key -func NewAsymmetricKey(privData []byte, pubData []byte) (*AsymmetricKey, error) { - // Parse private key from passed data - priv, err := x509.ParsePKCS8PrivateKey(privData) - if err != nil { - return nil, err - } - privKey, ok := priv.(*rsa.PrivateKey) - if !ok { - return nil, errors.New("not a valid private key") - } - - // Parse public key from passed data - pub, err := x509.ParsePKIXPublicKey(pubData) - if err != nil { - return nil, err - } - - pubKey, ok := pub.(*rsa.PublicKey) - if !ok { - return nil, errors.New("not a valid public key") - } - - // Associate the private key with the passed public key - privKey.PublicKey = *pubKey - - return &AsymmetricKey{ - publicKey: pubKey, - privateKey: privKey, - }, nil -} diff --git a/vendor/github.com/minio/minio-go/pkg/encrypt/server-side.go b/vendor/github.com/minio/minio-go/pkg/encrypt/server-side.go new file mode 100644 index 000000000..2d3c70f00 --- /dev/null +++ b/vendor/github.com/minio/minio-go/pkg/encrypt/server-side.go @@ -0,0 +1,195 @@ +/* + * Minio Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2018 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package encrypt + +import ( + "crypto/md5" + "encoding/base64" + "encoding/json" + "errors" + "net/http" + + "golang.org/x/crypto/argon2" +) + +const ( + // sseGenericHeader is the AWS SSE header used for SSE-S3 and SSE-KMS. + sseGenericHeader = "X-Amz-Server-Side-Encryption" + + // sseKmsKeyID is the AWS SSE-KMS key id. + sseKmsKeyID = sseGenericHeader + "-Aws-Kms-Key-Id" + // sseEncryptionContext is the AWS SSE-KMS Encryption Context data. + sseEncryptionContext = sseGenericHeader + "-Encryption-Context" + + // sseCustomerAlgorithm is the AWS SSE-C algorithm HTTP header key. + sseCustomerAlgorithm = sseGenericHeader + "-Customer-Algorithm" + // sseCustomerKey is the AWS SSE-C encryption key HTTP header key. + sseCustomerKey = sseGenericHeader + "-Customer-Key" + // sseCustomerKeyMD5 is the AWS SSE-C encryption key MD5 HTTP header key. + sseCustomerKeyMD5 = sseGenericHeader + "-Customer-Key-MD5" + + // sseCopyCustomerAlgorithm is the AWS SSE-C algorithm HTTP header key for CopyObject API. + sseCopyCustomerAlgorithm = "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm" + // sseCopyCustomerKey is the AWS SSE-C encryption key HTTP header key for CopyObject API. + sseCopyCustomerKey = "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key" + // sseCopyCustomerKeyMD5 is the AWS SSE-C encryption key MD5 HTTP header key for CopyObject API. + sseCopyCustomerKeyMD5 = "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-MD5" +) + +// PBKDF creates a SSE-C key from the provided password and salt. +// PBKDF is a password-based key derivation function +// which can be used to derive a high-entropy cryptographic +// key from a low-entropy password and a salt. +type PBKDF func(password, salt []byte) ServerSide + +// DefaultPBKDF is the default PBKDF. It uses Argon2id with the +// recommended parameters from the RFC draft (1 pass, 64 MB memory, 4 threads). +var DefaultPBKDF PBKDF = func(password, salt []byte) ServerSide { + sse := ssec{} + copy(sse[:], argon2.IDKey(password, salt, 1, 64*1024, 4, 32)) + return sse +} + +// Type is the server-side-encryption method. It represents one of +// the following encryption methods: +// - SSE-C: server-side-encryption with customer provided keys +// - KMS: server-side-encryption with managed keys +// - S3: server-side-encryption using S3 storage encryption +type Type string + +const ( + // SSEC represents server-side-encryption with customer provided keys + SSEC Type = "SSE-C" + // KMS represents server-side-encryption with managed keys + KMS Type = "KMS" + // S3 represents server-side-encryption using S3 storage encryption + S3 Type = "S3" +) + +// ServerSide is a form of S3 server-side-encryption. +type ServerSide interface { + // Type returns the server-side-encryption method. + Type() Type + + // Marshal adds encryption headers to the provided HTTP headers. + // It marks an HTTP request as server-side-encryption request + // and inserts the required data into the headers. + Marshal(h http.Header) +} + +// NewSSE returns a server-side-encryption using S3 storage encryption. +// Using SSE-S3 the server will encrypt the object with server-managed keys. +func NewSSE() ServerSide { return s3{} } + +// NewSSEKMS returns a new server-side-encryption using SSE-KMS and the provided Key Id and context. +func NewSSEKMS(keyID string, context interface{}) (ServerSide, error) { + if context == nil { + return kms{key: keyID, hasContext: false}, nil + } + serializedContext, err := json.Marshal(context) + if err != nil { + return nil, err + } + return kms{key: keyID, context: serializedContext, hasContext: true}, nil +} + +// NewSSEC returns a new server-side-encryption using SSE-C and the provided key. +// The key must be 32 bytes long. +func NewSSEC(key []byte) (ServerSide, error) { + if len(key) != 32 { + return nil, errors.New("encrypt: SSE-C key must be 256 bit long") + } + sse := ssec{} + copy(sse[:], key) + return sse, nil +} + +// SSE transforms a SSE-C copy encryption into a SSE-C encryption. +// It is the inverse of SSECopy(...). +// +// If the provided sse is no SSE-C copy encryption SSE returns +// sse unmodified. +func SSE(sse ServerSide) ServerSide { + if sse == nil || sse.Type() != SSEC { + return sse + } + if sse, ok := sse.(ssecCopy); ok { + return ssec(sse) + } + return sse +} + +// SSECopy transforms a SSE-C encryption into a SSE-C copy +// encryption. This is required for SSE-C key rotation or a SSE-C +// copy where the source and the destination should be encrypted. +// +// If the provided sse is no SSE-C encryption SSECopy returns +// sse unmodified. +func SSECopy(sse ServerSide) ServerSide { + if sse == nil || sse.Type() != SSEC { + return sse + } + if sse, ok := sse.(ssec); ok { + return ssecCopy(sse) + } + return sse +} + +type ssec [32]byte + +func (s ssec) Type() Type { return SSEC } + +func (s ssec) Marshal(h http.Header) { + keyMD5 := md5.Sum(s[:]) + h.Set(sseCustomerAlgorithm, "AES256") + h.Set(sseCustomerKey, base64.StdEncoding.EncodeToString(s[:])) + h.Set(sseCustomerKeyMD5, base64.StdEncoding.EncodeToString(keyMD5[:])) +} + +type ssecCopy [32]byte + +func (s ssecCopy) Type() Type { return SSEC } + +func (s ssecCopy) Marshal(h http.Header) { + keyMD5 := md5.Sum(s[:]) + h.Set(sseCopyCustomerAlgorithm, "AES256") + h.Set(sseCopyCustomerKey, base64.StdEncoding.EncodeToString(s[:])) + h.Set(sseCopyCustomerKeyMD5, base64.StdEncoding.EncodeToString(keyMD5[:])) +} + +type s3 struct{} + +func (s s3) Type() Type { return S3 } + +func (s s3) Marshal(h http.Header) { h.Set(sseGenericHeader, "AES256") } + +type kms struct { + key string + context []byte + hasContext bool +} + +func (s kms) Type() Type { return KMS } + +func (s kms) Marshal(h http.Header) { + h.Set(sseGenericHeader, "aws:kms") + h.Set(sseKmsKeyID, s.key) + if s.hasContext { + h.Set(sseEncryptionContext, base64.StdEncoding.EncodeToString(s.context)) + } +} -- cgit v1.2.3-1-g7c22