Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test for empty objects uploaded with SSE-C headers #927

Merged
merged 1 commit into from
Feb 27, 2018

Conversation

kannappanr
Copy link
Collaborator

@kannappanr kannappanr commented Feb 23, 2018

upload a zero-size object with SSE-C headers. Perform copyobject.
Do key rotation on the copied object and try to access
the object.

Fixes minio/mint#257

@kannappanr
Copy link
Collaborator Author

blocked until minio/minio#5544 is merged

@kannappanr kannappanr changed the title [WIP] test for empty objects uploaded with SSE-C headers test for empty objects uploaded with SSE-C headers Feb 23, 2018
@deekoder deekoder requested review from poornas, nitisht and aead and removed request for nitisht February 24, 2018 00:19
@kannappanr kannappanr force-pushed the zero_size_encrypted_object branch from 52a446a to 987f118 Compare February 24, 2018 00:35
Copy link
Member

@aead aead left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

opts.Set(k, v)
}
coreClient := minio.Core{c}
reader, _, err := coreClient.GetObject(bucketName, "object", opts)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need coreClient @kannappanr - this test also should add CopyObject

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

package main

import (
	"bytes"
	"crypto/md5"
	"crypto/tls"
	"encoding/base64"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"

	minio "github.com/minio/minio-go"
)

func main() {
	// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
	// my-objectname are dummy values, please replace them with original values.

	// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
	// determined based on the Endpoint value.
	minioClient, err := minio.New("127.0.0.1:9000", "minio", "minio123", true)
	if err != nil {
		log.Fatalln(err)
	}

	content := bytes.NewReader([]byte("hello, world"))
	key := []byte("32byteslongsecretkeymustprovided")
	h := md5.New()
	h.Write(key)
	encryptionKey := base64.StdEncoding.EncodeToString(key)
	encryptionKeyMD5 := base64.StdEncoding.EncodeToString(h.Sum(nil))

	// Amazon S3 does not store the encryption key you provide.
	// Instead S3 stores a randomly salted HMAC value of the
	// encryption key in order to validate future requests.
	// The salted HMAC value cannot be used to derive the value
	// of the encryption key or to decrypt the contents of the
	// encrypted object. That means, if you lose the encryption
	// key, you lose the object.
	var metadata = map[string]string{
		"x-amz-server-side-encryption-customer-algorithm": "AES256",
		"x-amz-server-side-encryption-customer-key":       encryptionKey,
		"x-amz-server-side-encryption-customer-key-MD5":   encryptionKeyMD5,
	}

	minioClient.SetCustomTransport(&http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		}})

	minioClient.TraceOn(os.Stderr)
	// minioClient.TraceOn(os.Stderr) // Enable to debug.
	_, err = minioClient.PutObject("testbucket", "my-encrypted-object.txt", content, content.Size(), minio.PutObjectOptions{
		UserMetadata: metadata,
	})
	if err != nil {
		log.Fatalln(err)
	}

	sseInfo := minio.NewSSEInfo(key, "")
	dstInfo, err := minio.NewDestinationInfo("testbucket", "my-new-encrypted-object.txt", &sseInfo, nil)
	if err != nil {
		log.Fatalln(err)
	}
	srcInfo := minio.NewSourceInfo("testbucket", "my-encrypted-object.txt", &sseInfo)
	if err = minioClient.CopyObject(dstInfo, srcInfo); err != nil {
		log.Fatalln(err)
	}

	opts := minio.GetObjectOptions{}
	for k, v := range metadata {
		opts.Set(k, v)
	}
	opts.SetRange(2, 3)

	r, err := minioClient.GetObject("testbucket", "my-new-encrypted-object.txt", opts)
	if err != nil {
		log.Fatalln(err)
	}
	b, err := ioutil.ReadAll(r)
	fmt.Println(err)
	fmt.Println(string(b))

	// -- Key rotation block --
	rkey := []byte("32byteslongsecretkeymustgenerate")
	rsseInfo := minio.NewSSEInfo(rkey, "")
	dstInfo, err = minio.NewDestinationInfo("testbucket", "my-new-encrypted-object.txt", &rsseInfo, map[string]string{
		"test": "test",
	})
	if err != nil {
		log.Fatalln(err)
	}
	srcInfo = minio.NewSourceInfo("testbucket", "my-new-encrypted-object.txt", &sseInfo)
	if err = minioClient.CopyObject(dstInfo, srcInfo); err != nil {
		log.Fatalln(err)
	}

	h = md5.New()
	h.Write(rkey)
	encryptionKey = base64.StdEncoding.EncodeToString(rkey)
	encryptionKeyMD5 = base64.StdEncoding.EncodeToString(h.Sum(nil))

	// Amazon S3 does not store the encryption key you provide.
	// Instead S3 stores a randomly salted HMAC value of the
	// encryption key in order to validate future requests.
	// The salted HMAC value cannot be used to derive the value
	// of the encryption key or to decrypt the contents of the
	// encrypted object. That means, if you lose the encryption
	// key, you lose the object.
	metadata = map[string]string{
		"x-amz-server-side-encryption-customer-algorithm": "AES256",
		"x-amz-server-side-encryption-customer-key":       encryptionKey,
		"x-amz-server-side-encryption-customer-key-MD5":   encryptionKeyMD5,
	}

	opts = minio.GetObjectOptions{}
	for k, v := range metadata {
		opts.Set(k, v)
	}
	opts.SetRange(2, 3)

	r, err = minioClient.GetObject("testbucket", "my-new-encrypted-object.txt", opts)
	if err != nil {
		log.Fatalln(err)
	}
	b, err = ioutil.ReadAll(r)
	fmt.Println(err)
	fmt.Println(string(b))
}

Take a look at the code here we should also add test for key rotation as well.

mustParseBool(os.Getenv(enableHTTPS)),
)
if err != nil {
logError(testName, function, args, startTime, "", "Minio v2 client object creation failed", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be MInio V4 client in the logError description

return
}

// 2. Download the object without SSE-C headers
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are downloading the object here with SSE headers; comment needs to be changed.

upload a zero-size object with SSE-C headers. Perform copyobject.
Do key rotation on the copied object  and try to access
the object.

Fixes minio/mint#257
@kannappanr kannappanr force-pushed the zero_size_encrypted_object branch from 5d93530 to 79832e7 Compare February 27, 2018 00:20
@kannappanr kannappanr merged commit 183b6f0 into minio:master Feb 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants