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

Path Encryption #448

Merged
merged 8 commits into from Oct 15, 2018
Merged

Path Encryption #448

merged 8 commits into from Oct 15, 2018

Conversation

mobyvb
Copy link
Member

@mobyvb mobyvb commented Oct 9, 2018

No description provided.

@cla-bot cla-bot bot added the cla-signed label Oct 9, 2018
@mobyvb mobyvb changed the title [WIPbegin adding path encryption [WIP] Path Encryption Oct 9, 2018
@mobyvb mobyvb added the WIP Work In Progress label Oct 9, 2018
@mobyvb mobyvb force-pushed the path-encryption branch 2 times, most recently from 4b53db6 to 5ac1d4c Compare October 10, 2018 16:41
key, err = deriveSecret(key, seg)
if err != nil {
return nil, err
// TODO(moby) this is a hacky way to deal with buckets
Copy link
Contributor

Choose a reason for hiding this comment

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

you're a hacky way to deal with buckets

Copy link
Member Author

Choose a reason for hiding this comment

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

No u

dylanlott
dylanlott previously approved these changes Oct 11, 2018
Copy link
Contributor

@dylanlott dylanlott left a comment

Choose a reason for hiding this comment

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

LGTM

@dylanlott dylanlott dismissed their stale review October 11, 2018 05:37

Didn't mean to make an Approved yet while it's still WIP

@mobyvb mobyvb changed the title [WIP] Path Encryption Path Encryption Oct 11, 2018
@mobyvb mobyvb removed the WIP Work In Progress label Oct 11, 2018
@@ -61,6 +61,34 @@ func (p Path) HasPrefix(prefix Path) bool {
return true
}

// EncryptWithBucket creates new Path by encrypting the current path with the given key
// while keeping the bucket portion of the path unencrypted
func (p Path) EncryptWithBucket(key []byte) (encrypted Path, err error) {
Copy link
Member

Choose a reason for hiding this comment

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

The logic in this method is specific to the Stream Store. The Path type is abstract and knows nothing about buckets. Thus, similar to the getSegmentPath method, it would be better if this method is a private helper function in the Stream Store.

Also encryptAfterBucket would be a better name. It makes it clear that encryption is applied after the bucket part of the path.

Same applies for DecryptWithBucket.

// EncryptWithBucket creates new Path by encrypting the current path with the given key
// while keeping the bucket portion of the path unencrypted
func (p Path) EncryptWithBucket(key []byte) (encrypted Path, err error) {
pathItems := []string(p)
Copy link
Member

Choose a reason for hiding this comment

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

We don't need this type cast. We can call directly p[0] and p[1:].

bucket := pathItems[0]
toEncrypt := Path(pathItems[1:])

encPath, err := toEncrypt.Encrypt(key)
Copy link
Member

Choose a reason for hiding this comment

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

Although we don't encrypt the bucket part of the path, we still need to derive a key from it. We want a file with the same path to be encrypted differently under different buckets.

So we need something like:

bucketKey, err := DeriveKey(key, 1)

Same applies for DecryptWithBucket.

func (p Path) EncryptWithBucket(key []byte) (encrypted Path, err error) {
pathItems := []string(p)
bucket := pathItems[0]
toEncrypt := Path(pathItems[1:])
Copy link
Member

Choose a reason for hiding this comment

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

We don't need this type case too. toEncrypt := p[1:] should be enough.

Copy link
Member

Choose a reason for hiding this comment

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

Also what happens if the path consists only of the bucket, i.e. the use case for adding, removing and listing buckets?

return nil, false, err
}

prefixNoBucket := paths.Path([]string(prefix)[1:])
Copy link
Member

Choose a reason for hiding this comment

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

When deriving the key we should include the bucket part, as explained for the EncryptWithBucket method.

return nil, false, err
}

encStartAfter, err := startAfter.Encrypt(prefixKey)
Copy link
Member

Choose a reason for hiding this comment

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

What if the prefix is nil? This would mean that startAfter and endBefore include the bucket part too, doesn't it? In this case, I guess we should call EncryptWithBucket instead.

Copy link
Member Author

Choose a reason for hiding this comment

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

The problem is they won't include the bucket part if the prefix is not nil, so I will make two separate cases for this

Copy link
Member

Choose a reason for hiding this comment

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

The new listNoPrefix helper method duplicates quite some logic from the main List method. It would be cleaner and easier to maintain if we would just define a smaller helper methods like:

// encryptMarker is a helper method for encrypting startAfter and endBefore markers
func (s *streamStore) encryptMarker(marker paths.Path, prefixKey []byte) (paths.Path, error) {
	if bytes.Equal(s.rootKey, prefixKey) { // empty prefix
		return encryptAfterBucket(marker, s.rootKey)
	}
	return marker.Encrypt(prefixKey)
}

and use it to encrypt startAfter and endBefore.

Similar for decrypting.

@@ -363,7 +408,11 @@ func (s *streamStore) List(ctx context.Context, prefix, startAfter, endBefore pa
if err != nil {
return nil, false, err
}
items[i] = ListItem{Path: item.Path, Meta: newMeta, IsPrefix: item.IsPrefix}
decPath, err := item.Path.Decrypt(prefixKey)
Copy link
Member

Choose a reason for hiding this comment

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

Here too: what if the prefix is nil?

Copy link
Contributor

@jhagans3 jhagans3 left a comment

Choose a reason for hiding this comment

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

Looks good to me

return nil, false, err
}

encStartAfter, err := startAfter.Encrypt(prefixKey)
Copy link
Member

Choose a reason for hiding this comment

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

The new listNoPrefix helper method duplicates quite some logic from the main List method. It would be cleaner and easier to maintain if we would just define a smaller helper methods like:

// encryptMarker is a helper method for encrypting startAfter and endBefore markers
func (s *streamStore) encryptMarker(marker paths.Path, prefixKey []byte) (paths.Path, error) {
	if bytes.Equal(s.rootKey, prefixKey) { // empty prefix
		return encryptAfterBucket(marker, s.rootKey)
	}
	return marker.Encrypt(prefixKey)
}

and use it to encrypt startAfter and endBefore.

Similar for decrypting.

@mobyvb mobyvb merged commit 3551b34 into master Oct 15, 2018
@mobyvb mobyvb deleted the path-encryption branch October 15, 2018 15:39
iglesiasbrandon pushed a commit that referenced this pull request Dec 7, 2018
* begin adding path encryption

* do not encrypt/decrypt first element of path (bucket)

* add path encryption for delete and list

* use encrypted paths in streamstore.Meta

* fix listing with encrypted paths

* move encrypt/decryptAfterBucket to streamstore

* fix listing with no prefix

* remove duplicate logic for listing with no prefix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants