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

Using generic instead of object and rename #1

Open
wants to merge 5 commits into
base: crypto_final
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -16,16 +16,20 @@
/**
* Crypto provider abstractions for encryption and decryption of data. Allows registering multiple providers
* for defining different ways of encrypting or decrypting data.
*
* T - Encryption Metadata - crypto metadata instance.
* U - Parsed Encryption Metadata
*/
public interface CryptoProvider {
public interface CryptoHandler<T , U> {

/**
* To initialise or create a new crypto metadata to be used in encryption. This is needed to set the context before
* beginning encryption.
*
* @return crypto metadata instance
*/
Object initEncryptionMetadata();
// prepare encryption metadata
T initEncryptionMetadata();

/**
* To load crypto metadata to be used in encryption from content header.
Expand All @@ -34,7 +38,7 @@ public interface CryptoProvider {
*
* @return crypto metadata instance used in decryption.
*/
Object loadEncryptionMetadata(EncryptedHeaderContentSupplier encryptedHeaderContentSupplier) throws IOException;
U loadEncryptionMetadata(EncryptedHeaderContentSupplier encryptedHeaderContentSupplier) throws IOException;

/**
* Few encryption algorithms have certain conditions on the unit of content to be encrypted. This requires the
Expand All @@ -46,7 +50,7 @@ public interface CryptoProvider {
* @param contentSize Size of the raw content
* @return Adjusted size of the content.
*/
long adjustContentSizeForPartialEncryption(Object cryptoContext, long contentSize);
long adjustContentSizeForPartialEncryption(T cryptoContext, long contentSize);

/**
* Estimate length of the encrypted content. It should only be used to determine length of entire content after
Expand All @@ -56,15 +60,15 @@ public interface CryptoProvider {
* @param contentLength Size of the raw content
* @return Calculated size of the encrypted content.
*/
long estimateEncryptedLengthOfEntireContent(Object cryptoContext, long contentLength);
long estimateEncryptedLengthOfEntireContent(T cryptoContext, long contentLength);

/**
* For given encrypted content length, estimate the length of the decrypted content.
* @param cryptoContext crypto metadata instance consisting of encryption metadata used in encryption.
* @param contentLength Size of the encrypted content
* @return Calculated size of the decrypted content.
*/
long estimateDecryptedLength(Object cryptoContext, long contentLength);
long estimateDecryptedLength(U cryptoContext, long contentLength);

/**
* Wraps a raw InputStream with encrypting stream
Expand All @@ -73,7 +77,7 @@ public interface CryptoProvider {
* @param stream Raw InputStream to encrypt
* @return encrypting stream wrapped around raw InputStream.
*/
InputStreamContainer createEncryptingStream(Object encryptionMetadata, InputStreamContainer stream);
InputStreamContainer createEncryptingStream(T encryptionMetadata, InputStreamContainer stream);

/**
* Provides encrypted stream for a raw stream emitted for a part of content.
Expand All @@ -84,7 +88,7 @@ public interface CryptoProvider {
* @param streamIdx Index of the current stream.
* @return Encrypted stream for the provided raw stream.
*/
InputStreamContainer createEncryptingStreamOfPart(Object cryptoContext, InputStreamContainer stream, int totalStreams, int streamIdx);
InputStreamContainer createEncryptingStreamOfPart(T cryptoContext, InputStreamContainer stream, int totalStreams, int streamIdx);

/**
* This method accepts an encrypted stream and provides a decrypting wrapper.
Expand All @@ -107,5 +111,5 @@ public interface CryptoProvider {
* @param startPosOfRawContent starting position in the raw/decrypted content
* @param endPosOfRawContent ending position in the raw/decrypted content
*/
DecryptedRangedStreamProvider createDecryptingStreamOfRange(Object cryptoContext, long startPosOfRawContent, long endPosOfRawContent);
DecryptedRangedStreamProvider createDecryptingStreamOfRange(U cryptoContext, long startPosOfRawContent, long endPosOfRawContent);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@

package org.opensearch.encryption;

import org.opensearch.common.crypto.CryptoProvider;
import org.opensearch.common.crypto.CryptoHandler;
import org.opensearch.common.util.concurrent.RefCounted;

/**
* Crypto plugin interface used for encryption and decryption.
*/
public interface CryptoManager extends RefCounted {
public interface CryptoManager<T, U> extends RefCounted {

/**
* @return key provider type
Expand All @@ -29,5 +29,5 @@ public interface CryptoManager extends RefCounted {
/**
* @return Crypto provider for encrypting or decrypting raw content.
*/
CryptoProvider getCryptoProvider();
CryptoHandler<T, U> getCryptoProvider();
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
import com.amazonaws.encryptionsdk.CryptoAlgorithm;
import com.amazonaws.encryptionsdk.caching.CachingCryptoMaterialsManager;
import com.amazonaws.encryptionsdk.caching.LocalCryptoMaterialsCache;
import org.opensearch.common.crypto.CryptoProvider;
import org.opensearch.common.crypto.CryptoHandler;
import org.opensearch.common.crypto.MasterKeyProvider;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.common.util.concurrent.AbstractRefCounted;
import org.opensearch.encryption.frame.FrameCryptoProvider;
import org.opensearch.encryption.frame.FrameCryptoHandler;
import org.opensearch.encryption.frame.core.AwsCrypto;
import org.opensearch.encryption.keyprovider.CryptoMasterKey;

Expand Down Expand Up @@ -50,7 +50,7 @@ private String validateAndGetAlgorithmId(String algorithm) {
}
}

public CryptoManager getOrCreateCryptoManager(
public CryptoManager<?, ?> getOrCreateCryptoManager(
MasterKeyProvider keyProvider,
String keyProviderName,
String keyProviderType,
Expand All @@ -61,24 +61,24 @@ public CryptoManager getOrCreateCryptoManager(
keyProviderName,
validateAndGetAlgorithmId(algorithm)
);
CryptoProvider cryptoProvider = createCryptoProvider(algorithm, materialsManager, keyProvider);
return createCryptoManager(cryptoProvider, keyProviderType, keyProviderName, onClose);
CryptoHandler<?, ?> cryptoHandler = createCryptoProvider(algorithm, materialsManager, keyProvider);
return createCryptoManager(cryptoHandler, keyProviderType, keyProviderName, onClose);
}

// package private for tests
CryptoProvider createCryptoProvider(
CryptoHandler<?, ?> createCryptoProvider(
String algorithm,
CachingCryptoMaterialsManager materialsManager,
MasterKeyProvider masterKeyProvider
) {
switch (algorithm) {
case "ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY":
return new FrameCryptoProvider(
return new FrameCryptoHandler(
new AwsCrypto(materialsManager, CryptoAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY),
masterKeyProvider.getEncryptionContext()
);
case "ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384":
return new FrameCryptoProvider(
return new FrameCryptoHandler(
new AwsCrypto(materialsManager, CryptoAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384),
masterKeyProvider.getEncryptionContext()
);
Expand All @@ -103,8 +103,13 @@ CachingCryptoMaterialsManager createMaterialsManager(MasterKeyProvider masterKey
}

// package private for tests
CryptoManager createCryptoManager(CryptoProvider cryptoProvider, String keyProviderType, String keyProviderName, Runnable onClose) {
return new CryptoManagerImpl(keyProviderName, keyProviderType) {
<T, U> CryptoManager<?, ?> createCryptoManager(
CryptoHandler<T, U> cryptoHandler,
String keyProviderType,
String keyProviderName,
Runnable onClose
) {
return new CryptoManagerImpl<T, U>(keyProviderName, keyProviderType) {
@Override
protected void closeInternal() {
onClose.run();
Expand All @@ -121,15 +126,16 @@ public String name() {
}

@Override
public CryptoProvider getCryptoProvider() {
return cryptoProvider;
public CryptoHandler<T, U> getCryptoProvider() {
return cryptoHandler;
}
};
}

private static abstract class CryptoManagerImpl extends AbstractRefCounted implements CryptoManager {
private static abstract class CryptoManagerImpl<T, U> extends AbstractRefCounted implements CryptoManager<T, U> {
public CryptoManagerImpl(String keyProviderName, String keyProviderType) {
super(keyProviderName + "-" + keyProviderType);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
package org.opensearch.encryption.frame;

import com.amazonaws.encryptionsdk.ParsedCiphertext;
import org.opensearch.common.crypto.CryptoProvider;
import org.opensearch.common.crypto.CryptoHandler;
import org.opensearch.common.crypto.DecryptedRangedStreamProvider;
import org.opensearch.common.crypto.EncryptedHeaderContentSupplier;
import org.opensearch.encryption.frame.core.AwsCrypto;
Expand All @@ -20,14 +20,14 @@
import java.io.InputStream;
import java.util.Map;

public class FrameCryptoProvider implements CryptoProvider {
public class FrameCryptoHandler implements CryptoHandler<EncryptionMetadata, ParsedCiphertext> {
private final AwsCrypto awsCrypto;
private final Map<String, String> encryptionContext;

// package private for tests
private final int FRAME_SIZE = 8 * 1024;

public FrameCryptoProvider(AwsCrypto awsCrypto, Map<String, String> encryptionContext) {
public FrameCryptoHandler(AwsCrypto awsCrypto, Map<String, String> encryptionContext) {
this.awsCrypto = awsCrypto;
this.encryptionContext = encryptionContext;
}
Expand All @@ -40,7 +40,7 @@ public int getFrameSize() {
* Initialises metadata store used in encryption.
* @return crypto metadata object constructed with encryption metadata like data key pair, encryption algorithm, etc.
*/
public Object initEncryptionMetadata() {
public EncryptionMetadata initEncryptionMetadata() {
return awsCrypto.createCryptoContext(encryptionContext, getFrameSize());
}

Expand All @@ -57,7 +57,7 @@ public Object initEncryptionMetadata() {
* @param streamSize Size of the stream to be adjusted.
* @return Adjusted size of the stream.
*/
public long adjustContentSizeForPartialEncryption(Object cryptoContextObj, long streamSize) {
public long adjustContentSizeForPartialEncryption(EncryptionMetadata cryptoContextObj, long streamSize) {
EncryptionMetadata encryptionMetadata = validateEncryptionMetadata(cryptoContextObj);
return (streamSize - (streamSize % encryptionMetadata.getFrameSize())) + encryptionMetadata.getFrameSize();
}
Expand All @@ -69,7 +69,7 @@ public long adjustContentSizeForPartialEncryption(Object cryptoContextObj, long
* @param contentLength Size of the raw content
* @return Calculated size of the encrypted stream for the provided raw stream.
*/
public long estimateEncryptedLengthOfEntireContent(Object cryptoMetadataObj, long contentLength) {
public long estimateEncryptedLengthOfEntireContent(EncryptionMetadata cryptoMetadataObj, long contentLength) {
EncryptionMetadata encryptionMetadata = validateEncryptionMetadata(cryptoMetadataObj);
return encryptionMetadata.getCiphertextHeaderBytes().length + awsCrypto.estimateOutputSizeWithFooter(
encryptionMetadata.getFrameSize(),
Expand All @@ -87,17 +87,13 @@ public long estimateEncryptedLengthOfEntireContent(Object cryptoMetadataObj, lon
* @param contentLength Size of the encrypted content
* @return Calculated size of the encrypted stream for the provided raw stream.
*/
public long estimateDecryptedLength(Object cryptoMetadataObj, long contentLength) {
if (!(cryptoMetadataObj instanceof ParsedCiphertext)) {
throw new IllegalArgumentException("Unknown crypto metadata object received for adjusting range for decryption");
}
ParsedCiphertext parsedCiphertext = (ParsedCiphertext) cryptoMetadataObj;
public long estimateDecryptedLength(ParsedCiphertext cryptoMetadataObj, long contentLength) {
return awsCrypto.estimateDecryptedSize(
parsedCiphertext.getFrameLength(),
parsedCiphertext.getNonceLength(),
parsedCiphertext.getCryptoAlgoId().getTagLen(),
contentLength - parsedCiphertext.getOffset(),
parsedCiphertext.getCryptoAlgoId()
cryptoMetadataObj.getFrameLength(),
cryptoMetadataObj.getNonceLength(),
cryptoMetadataObj.getCryptoAlgoId().getTagLen(),
contentLength - cryptoMetadataObj.getOffset(),
cryptoMetadataObj.getCryptoAlgoId()
);
}

Expand All @@ -107,16 +103,13 @@ public long estimateDecryptedLength(Object cryptoMetadataObj, long contentLength
* @param stream Raw InputStream to encrypt
* @return encrypting stream wrapped around raw InputStream.
*/
public InputStreamContainer createEncryptingStream(Object cryptoContextObj, InputStreamContainer stream) {
public InputStreamContainer createEncryptingStream(EncryptionMetadata cryptoContextObj, InputStreamContainer stream) {
EncryptionMetadata encryptionMetadata = validateEncryptionMetadata(cryptoContextObj);
return createEncryptingStreamOfPart(encryptionMetadata, stream, 1, 0);
}

private EncryptionMetadata validateEncryptionMetadata(Object cryptoContext) {
if (!(cryptoContext instanceof EncryptionMetadata)) {
throw new IllegalArgumentException("Unknown crypto metadata object received");
}
return (EncryptionMetadata) cryptoContext;
private EncryptionMetadata validateEncryptionMetadata(EncryptionMetadata cryptoContext) {
Copy link
Owner

Choose a reason for hiding this comment

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

We can remove this method now.

return cryptoContext;
}

/**
Expand All @@ -132,7 +125,7 @@ private EncryptionMetadata validateEncryptionMetadata(Object cryptoContext) {
* @return Encrypted stream for the provided raw stream.
*/
public InputStreamContainer createEncryptingStreamOfPart(
Object cryptoContextObj,
EncryptionMetadata cryptoContextObj,
InputStreamContainer stream,
int totalStreams,
int streamIdx
Expand All @@ -157,7 +150,7 @@ private EncryptionMetadata parseEncryptionMetadata(Object cryptoContextObj) {
* @return parsed encryption metadata object
* @throws IOException if content fetch for header creation fails
*/
public Object loadEncryptionMetadata(EncryptedHeaderContentSupplier encryptedHeaderContentSupplier) throws IOException {
public ParsedCiphertext loadEncryptionMetadata(EncryptedHeaderContentSupplier encryptedHeaderContentSupplier) throws IOException {
byte[] encryptedHeader = encryptedHeaderContentSupplier.supply(0, 4095);
return new ParsedCiphertext(encryptedHeader);
}
Expand Down Expand Up @@ -214,21 +207,19 @@ private InputStream createBlockDecryptionStream(
* @return stream provider for decrypted stream for the specified range of content including adjusted range
*/
public DecryptedRangedStreamProvider createDecryptingStreamOfRange(
Object cryptoContext,
ParsedCiphertext cryptoContext,
long startPosOfRawContent,
long endPosOfRawContent
) {
if (!(cryptoContext instanceof ParsedCiphertext)) {
throw new IllegalArgumentException("Unknown crypto metadata object received for adjusting range for decryption");
}

ParsedCiphertext encryptionMetadata = (ParsedCiphertext) cryptoContext;
long adjustedStartPos = startPosOfRawContent - (startPosOfRawContent % encryptionMetadata.getFrameLength());
long endPosOverhead = (endPosOfRawContent + 1) % encryptionMetadata.getFrameLength();
long adjustedStartPos = startPosOfRawContent - (startPosOfRawContent % cryptoContext.getFrameLength());
long endPosOverhead = (endPosOfRawContent + 1) % cryptoContext.getFrameLength();
long adjustedEndPos = endPosOverhead == 0
? endPosOfRawContent
: (endPosOfRawContent - endPosOverhead + encryptionMetadata.getFrameLength());
long[] encryptedRange = transformToEncryptedRange(encryptionMetadata, adjustedStartPos, adjustedEndPos);
: (endPosOfRawContent - endPosOverhead + cryptoContext.getFrameLength());
long[] encryptedRange = transformToEncryptedRange(cryptoContext, adjustedStartPos, adjustedEndPos);
return new DecryptedRangedStreamProvider(encryptedRange, (encryptedStream) -> {
InputStream decryptedStream = createBlockDecryptionStream(
cryptoContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@

package org.opensearch.encryption;

import static org.mockito.Mockito.when;
import static org.mockito.Mockito.mock;

import com.amazonaws.encryptionsdk.caching.CachingCryptoMaterialsManager;
import org.junit.Before;
import org.opensearch.common.crypto.CryptoProvider;
import org.opensearch.common.crypto.CryptoHandler;
import org.opensearch.common.crypto.MasterKeyProvider;
import org.opensearch.common.unit.TimeValue;
import org.opensearch.test.OpenSearchTestCase;

import java.util.Collections;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class CryptoManagerFactoryTests extends OpenSearchTestCase {

private CryptoManagerFactory cryptoManagerFactory;
Expand All @@ -33,7 +33,7 @@ public void testGetOrCreateCryptoManager() {
MasterKeyProvider mockKeyProvider = mock(MasterKeyProvider.class);
when(mockKeyProvider.getEncryptionContext()).thenReturn(Collections.emptyMap());

CryptoManager cryptoManager = cryptoManagerFactory.getOrCreateCryptoManager(
CryptoManager<?, ?> cryptoManager = cryptoManagerFactory.getOrCreateCryptoManager(
mockKeyProvider,
"keyProviderName",
"keyProviderType",
Expand All @@ -48,13 +48,13 @@ public void testCreateCryptoProvider() {
MasterKeyProvider mockKeyProvider = mock(MasterKeyProvider.class);
when(mockKeyProvider.getEncryptionContext()).thenReturn(Collections.emptyMap());

CryptoProvider cryptoProvider = cryptoManagerFactory.createCryptoProvider(
CryptoHandler<?, ?> cryptoHandler = cryptoManagerFactory.createCryptoProvider(
"ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY",
mockMaterialsManager,
mockKeyProvider
);

assertNotNull(cryptoProvider);
assertNotNull(cryptoHandler);
}

public void testCreateMaterialsManager() {
Expand All @@ -71,9 +71,9 @@ public void testCreateMaterialsManager() {
}

public void testCreateCryptoManager() {
CryptoProvider mockCryptoProvider = mock(CryptoProvider.class);
CryptoManager cryptoManager = cryptoManagerFactory.createCryptoManager(
mockCryptoProvider,
CryptoHandler<?, ?> mockCryptoHandler = mock(CryptoHandler.class);
CryptoManager<?, ?> cryptoManager = cryptoManagerFactory.createCryptoManager(
mockCryptoHandler,
"keyProviderName",
"keyProviderType",
null
Expand Down
Loading
Loading