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

Encrypted Repository with AES GCM Packets #48221

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ef2f8aa
Encrypted blob store repository - take I (#46170)
albertzaharovits Oct 10, 2019
236aa79
Done Encryption without mark/reset
albertzaharovits Oct 13, 2019
26a6594
Mark in progress
albertzaharovits Oct 14, 2019
f1d5a84
Mark reset maybe works????
albertzaharovits Oct 14, 2019
be0cc44
Looking good, ready to fire up tests
albertzaharovits Oct 14, 2019
b647657
hardcore simple tests work!
albertzaharovits Oct 15, 2019
56f3c1e
Encryption/decryption whizzes!
albertzaharovits Oct 15, 2019
3d462e6
Before separation of MarkDecorator
albertzaharovits Oct 16, 2019
498f77c
Refactored mark and reset
albertzaharovits Oct 16, 2019
c8faeac
Refactored tests to use on large global array
albertzaharovits Oct 16, 2019
4052dcd
Fix mark reset bug
albertzaharovits Oct 17, 2019
33133fc
Tests counters
albertzaharovits Oct 17, 2019
b25598a
Reset in rewind tests
albertzaharovits Oct 17, 2019
710ea8a
Failed decryption tests
albertzaharovits Oct 17, 2019
1a7801f
Adapted Encrypted Repository but it does not work yet
albertzaharovits Oct 17, 2019
afafe76
Check passes, no javadoc, no integ tests
albertzaharovits Oct 17, 2019
780f8a1
Works!
albertzaharovits Oct 17, 2019
51273d5
GCMPacketsInputStream javadoc
albertzaharovits Oct 17, 2019
c2ba0f7
Merge branch 'master' into packet-based-cipherstream
albertzaharovits Oct 17, 2019
6ce7d1a
Merge branch 'master' into packet-based-cipherstream
albertzaharovits Oct 22, 2019
7a25aef
Merge branch 'master' into packet-based-cipherstream
albertzaharovits Oct 22, 2019
5145e16
Merge branch 'master' into packet-based-cipherstream
albertzaharovits Oct 25, 2019
2a6bfb3
Merge branch 'master' into packet-based-cipherstream
albertzaharovits Oct 31, 2019
4bc1315
Rough EncryptedBlobMetadata
albertzaharovits Oct 31, 2019
06ff4c0
Merge branch 'master' into packet-based-cipherstream
albertzaharovits Nov 3, 2019
a609b6e
Merge branch 'repository-encrypted-client-side' into packet-based-cip…
albertzaharovits Nov 12, 2019
6b8a6f3
GCMPacketsEncryptor close/mark/reset TODO
albertzaharovits Nov 17, 2019
3c97079
Close/mark/reset done!
albertzaharovits Nov 17, 2019
5dc188e
GCMPacketsEncryptorInputStream done!
albertzaharovits Nov 17, 2019
cc9cbc4
GCMPacketsDecryptorInputStream Done!
albertzaharovits Nov 17, 2019
a460b09
Before EncryptedRepository retrofitting
albertzaharovits Nov 21, 2019
835c9d2
BlobEncriptionMetadata no InputStream use write method
albertzaharovits Nov 21, 2019
dd7f4e1
All crypto in-place!
albertzaharovits Nov 21, 2019
7e5bb3b
Deleted GCMPacketsCipherInputStream
albertzaharovits Nov 21, 2019
58ea4f3
Revert "Deleted GCMPacketsCipherInputStream"
albertzaharovits Nov 22, 2019
f78b589
Encryption new way
albertzaharovits Nov 28, 2019
86bd583
Merge branch 'repository-encrypted-client-side' into packet-based-cip…
albertzaharovits Nov 28, 2019
c658601
Merge branch 'repository-encrypted-client-side' into packet-based-cip…
albertzaharovits Dec 6, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ protected AzureBlobStore createBlobStore() {
}

@Override
protected ByteSizeValue chunkSize() {
public ByteSizeValue chunkSize() {
return chunkSize;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ protected GoogleCloudStorageBlobStore createBlobStore() {
}

@Override
protected ByteSizeValue chunkSize() {
public ByteSizeValue chunkSize() {
return chunkSize;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ protected HdfsBlobStore createBlobStore() {
}

@Override
protected ByteSizeValue chunkSize() {
public ByteSizeValue chunkSize() {
return chunkSize;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ protected BlobStore getBlobStore() {
}

@Override
protected ByteSizeValue chunkSize() {
public ByteSizeValue chunkSize() {
return chunkSize;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent imp

protected final ChecksumBlobStoreFormat<SnapshotInfo> snapshotFormat;

private final NamedXContentRegistry namedXContentRegistry;

private final boolean readOnly;

private final ChecksumBlobStoreFormat<BlobStoreIndexShardSnapshot> indexShardSnapshotFormat;
Expand Down Expand Up @@ -234,6 +236,7 @@ protected BlobStoreRepository(
restoreRateLimiter = getRateLimiter(metadata.settings(), "max_restore_bytes_per_sec", new ByteSizeValue(40, ByteSizeUnit.MB));
readOnly = metadata.settings().getAsBoolean("readonly", false);
this.basePath = basePath;
this.namedXContentRegistry = namedXContentRegistry;

indexShardSnapshotFormat = new ChecksumBlobStoreFormat<>(SNAPSHOT_CODEC, SNAPSHOT_NAME_FORMAT,
BlobStoreIndexShardSnapshot::fromXContent, namedXContentRegistry, compress);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ protected BlobStore createBlobStore() throws Exception {
}

@Override
protected ByteSizeValue chunkSize() {
public ByteSizeValue chunkSize() {
return chunkSize;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
import java.time.Clock;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -310,12 +309,6 @@ public static Path resolveConfigFile(Environment env, String name) {
return config;
}

@Override
public Map<String, Repository.Factory> getRepositories(Environment env, NamedXContentRegistry namedXContentRegistry,
ClusterService clusterService) {
return Collections.singletonMap("source", SourceOnlySnapshotRepository.newRepositoryFactory());
}

@Override
public Optional<EngineFactory> getEngineFactory(IndexSettings indexSettings) {
if (indexSettings.getValue(SourceOnlySnapshotRepository.SOURCE_ONLY)) {
Expand Down
31 changes: 31 additions & 0 deletions x-pack/plugin/repository-encrypted/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
evaluationDependsOn(xpackModule('core'))

apply plugin: 'elasticsearch.esplugin'
esplugin {
name 'repository-encrypted'
description 'Elasticsearch Expanded Pack Plugin - client-side encrypted repositories.'
classname 'org.elasticsearch.repositories.encrypted.EncryptedRepositoryPlugin'
extendedPlugins = ['x-pack-core']
}

thirdPartyAudit {
ignoreViolations (
Copy link
Contributor

Choose a reason for hiding this comment

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

we should add a comment (or a TODO to do it) to say why it's ok to ignore those

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will add integ tests when everything is put together, we won't merge to master without integ tests for sure. I will add a TODO if you think so.

'org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider$CoreSecureRandom',
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF',
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$BaseTLSKeyGeneratorSpi',
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSKeyMaterialGenerator',
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSKeyMaterialGenerator$2',
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSMasterSecretGenerator',
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSMasterSecretGenerator$2',
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSPRFKeyGenerator',
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSRsaPreMasterSecretGenerator',
'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSRsaPreMasterSecretGenerator$2',
)
}

dependencies {
compile "org.bouncycastle:bc-fips:1.0.1"
compile "org.bouncycastle:bcpkix-fips:1.0.3"
}

integTest.enabled = false
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ed8dd3144761eaa33b9c56f5e2bef85f1b731d6f
12 changes: 12 additions & 0 deletions x-pack/plugin/repository-encrypted/licenses/bc-fips-LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Copyright (c) 2000 - 2019 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
33c47b105777c9dcc8a08188186bd35401366bd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Copyright (c) 2000 - 2019 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package org.elasticsearch.repositories.encrypted;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

public class BlobEncryptionMetadata {

private final int maxPacketSizeInBytes;
private final int authTagSizeInBytes;
private final int ivSizeInBytes;
private final byte[] dataEncryptionKeyMaterial;
private List<PacketInfo> packetsInfoList;

public BlobEncryptionMetadata(int maxPacketSizeInBytes, int ivSizeInBytes, int authTagSizeInBytes,
byte[] dataEncryptionKeyMaterial, List<PacketInfo> packetsInfoList) {
this.maxPacketSizeInBytes = maxPacketSizeInBytes;
this.ivSizeInBytes = ivSizeInBytes;
this.authTagSizeInBytes = authTagSizeInBytes;
this.dataEncryptionKeyMaterial = dataEncryptionKeyMaterial;
// consistency check of the packet infos
for (PacketInfo packetInfo : packetsInfoList) {
if (packetInfo.getSizeInBytes() > maxPacketSizeInBytes) {
throw new IllegalArgumentException();
}
if (packetInfo.getIv().length != ivSizeInBytes) {
throw new IllegalArgumentException();
}
if (packetInfo.getAuthTag().length != authTagSizeInBytes) {
throw new IllegalArgumentException();
}
}
this.packetsInfoList = Collections.unmodifiableList(packetsInfoList);
}

public BlobEncryptionMetadata(InputStream inputStream) throws IOException {
this.maxPacketSizeInBytes = readInt(inputStream);
this.authTagSizeInBytes = readInt(inputStream);
this.ivSizeInBytes = readInt(inputStream);

int dataEncryptionKeySizeInBytes = readInt(inputStream);
this.dataEncryptionKeyMaterial = readExactlyNBytes(inputStream, dataEncryptionKeySizeInBytes);

int packetsInfoListSize = readInt(inputStream);
List<PacketInfo> packetsInfo = new ArrayList<>(packetsInfoListSize);
for (int i = 0; i < packetsInfoListSize; i++) {
PacketInfo packetInfo = new PacketInfo(inputStream, ivSizeInBytes, authTagSizeInBytes);
// consistency check of the packet infos
if (packetInfo.getSizeInBytes() > this.maxPacketSizeInBytes) {
throw new IllegalArgumentException();
}
if (packetInfo.getIv().length != this.ivSizeInBytes) {
throw new IllegalArgumentException();
}
if (packetInfo.getAuthTag().length != this.authTagSizeInBytes) {
throw new IllegalArgumentException();
}
packetsInfo.add(packetInfo);
}
this.packetsInfoList = Collections.unmodifiableList(packetsInfo);
}

public byte[] getDataEncryptionKeyMaterial() {
return dataEncryptionKeyMaterial;
}

public int getMaxPacketSizeInBytes() {
return maxPacketSizeInBytes;
}

public int getAuthTagSizeInBytes() {
return authTagSizeInBytes;
}

public int getIvSizeInBytes() {
return ivSizeInBytes;
}

public List<PacketInfo> getPacketsInfoList() {
return packetsInfoList;
}

public void write(OutputStream out) throws IOException {
writeInt(out, maxPacketSizeInBytes);
writeInt(out, authTagSizeInBytes);
writeInt(out, ivSizeInBytes);

writeInt(out, dataEncryptionKeyMaterial.length);
out.write(dataEncryptionKeyMaterial);

writeInt(out, packetsInfoList.size());
for (PacketInfo packetInfo : packetsInfoList) {
packetInfo.write(out);
}
}

private static int readInt(InputStream inputStream) throws IOException {
return ((inputStream.read() & 0xFF) << 24) |
((inputStream.read() & 0xFF) << 16) |
((inputStream.read() & 0xFF) << 8 ) |
((inputStream.read() & 0xFF) << 0 );
}

private static void writeInt(OutputStream out, int val) throws IOException {
out.write(val >>> 24);
out.write(val >>> 16);
out.write(val >>> 8);
out.write(val);
}

private static byte[] readExactlyNBytes(InputStream inputStream, int nBytes) throws IOException {
byte[] ans = new byte[nBytes];
if (nBytes != inputStream.readNBytes(ans, 0, nBytes)) {
throw new IOException("Fewer than [" + nBytes + "] read");
}
return ans;
}

static class PacketInfo {

private final byte[] iv;
private final byte[] authTag;
private final int sizeInBytes;

PacketInfo(byte[] iv, byte[] authTag, int sizeInBytes) {
this.iv = iv;
this.authTag = authTag;
this.sizeInBytes = sizeInBytes;
}

PacketInfo(InputStream inputStream, int ivSizeInBytes, int authTagSizeInBytes) throws IOException {
this.iv = readExactlyNBytes(inputStream, ivSizeInBytes);
this.authTag = readExactlyNBytes(inputStream, authTagSizeInBytes);
this.sizeInBytes = readInt(inputStream);
}

byte[] getIv() {
return iv;
}

byte[] getAuthTag() {
return authTag;
}

int getSizeInBytes() {
return sizeInBytes;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PacketInfo that = (PacketInfo) o;
return sizeInBytes == that.sizeInBytes &&
Arrays.equals(iv, that.iv) &&
Arrays.equals(authTag, that.authTag);
}

@Override
public int hashCode() {
int result = Objects.hash(sizeInBytes);
result = 31 * result + Arrays.hashCode(iv);
result = 31 * result + Arrays.hashCode(authTag);
return result;
}

public void write(OutputStream out) throws IOException {
out.write(iv);
out.write(authTag);
writeInt(out, sizeInBytes);
}

}

}
Loading