Skip to content

Commit ae0a626

Browse files
authored
Fixes #465 (#466)
* Fixes #465 * Added more tests and allow mode config with integration tests
1 parent 1f87d58 commit ae0a626

6 files changed

Lines changed: 84 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file.
33
This project aims to adhere to [Semantic Versioning](http://semver.org/).
44

55
## [3.3.1] -
6+
### Added
7+
- [Allow for authentication to be disabled in CSE](https://github.com/joyent/java-manta/issues/465)
8+
Client side encryption HMAC authentication of ciphertext for CTR/CBC ciphers
9+
can now be disabled. The default authentication mode continues to be
10+
Mandatory.
611
### Changed
712
- [Deprecate Jobs Multipart implementation and disable integration tests](https://github.com/joyent/java-manta/issues/459)
813
### Fixed

USAGE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ Note: Dynamic Updates marked with an asterisk (*) are enabled by the `AuthAwareC
199199
encryption is enabled.
200200
* `manta.encryption_auth_mode` (**MANTA_ENCRYPTION_AUTH_MODE**)
201201
[EncryptionAuthenticationMode](/java-manta-client-unshaded/src/main/java/com/joyent/manta/config/EncryptionAuthenticationMode.java)
202-
enum type indicating that authenticating encryption verification is either Mandatory or Optional.
202+
enum type indicating that authenticating encryption verification is either `Mandatory`, `Optional` or `Disabled`.
203203
* `manta.encryption_key_path` (**MANTA_ENCRYPTION_KEY_PATH**)
204204
The path on the local filesystem or a URI understandable by the JVM indicating the
205205
location of the private key used to perform client-side encryption. If this value is

java-manta-client-unshaded/src/main/java/com/joyent/manta/config/EncryptionAuthenticationMode.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@ public enum EncryptionAuthenticationMode {
2626
* {@link com.joyent.manta.exception.UnauthenticatableOperationException}
2727
* exception.
2828
*/
29-
Mandatory;
29+
Mandatory,
30+
31+
/**
32+
* Disabled mode will disable ciphertext verification upon decryption.
33+
* HMACs will still be created when encrypting.
34+
*/
35+
Disabled;
3036

3137
/**
3238
* The default encryption object authentication mode (Mandatory).

java-manta-client-unshaded/src/main/java/com/joyent/manta/http/EncryptionHttpHelper.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,12 @@ public MantaObjectInputStream httpRequestAsInputStream(final HttpUriRequest requ
281281
throws IOException {
282282
final boolean hasRangeRequest = requestHeaders != null && requestHeaders.getRange() != null;
283283

284+
/* Errors when we attempt to do an HTTP range request when authentication
285+
* mode is set to Mandatory because HTTP range requests will only work
286+
* with authentication disabled. When you do a range request, it gets
287+
* arbitrary bytes from the ciphertext of the source object which means
288+
* that you will not be able to verify the ciphertext using the HMAC
289+
* because you don't have all of the bytes available. */
284290
if (hasRangeRequest && encryptionAuthenticationMode.equals(EncryptionAuthenticationMode.Mandatory)) {
285291
String msg = "HTTP range requests (random reads) aren't supported when using "
286292
+ "client-side encryption in mandatory authentication mode.";
@@ -373,8 +379,12 @@ public MantaObjectInputStream httpRequestAsInputStream(final HttpUriRequest requ
373379
return new MantaEncryptedObjectInputStream(rawStream, this.cipherDetails,
374380
secretKey, false, initialSkipBytes, plaintextRangeLength, unboundedEnd);
375381
} else {
382+
/* We skip authentication on the ciphertext only when it is explicitly
383+
* disabled. For the Mandatory and Optional modes, it is enabled. */
384+
final boolean authenticateCiphertext =
385+
!encryptionAuthenticationMode.equals(EncryptionAuthenticationMode.Disabled);
376386
return new MantaEncryptedObjectInputStream(rawStream, this.cipherDetails,
377-
secretKey, true);
387+
secretKey, authenticateCiphertext);
378388
}
379389
}
380390

java-manta-client-unshaded/src/test/java/com/joyent/manta/config/SystemSettingsConfigContextTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,49 @@ public void verifyEmbeddedKeyOverwritesDefaultKeyPath() {
110110
assertEquals(config.getMantaUser(), user);
111111
assertNull(config.getMantaKeyPath());
112112
}
113+
114+
public void authenticationModeCanBeSetToMandatory() {
115+
final String input = "Mandatory";
116+
final EncryptionAuthenticationMode expected = EncryptionAuthenticationMode.Mandatory;
117+
118+
final Properties properties = new Properties();
119+
properties.setProperty(MANTA_ENCRYPTION_AUTHENTICATION_MODE_KEY, input);
120+
final SystemSettingsConfigContext instance = new SystemSettingsConfigContext(
121+
false, properties);
122+
123+
final EncryptionAuthenticationMode actual = instance.getEncryptionAuthenticationMode();
124+
Assert.assertEquals(actual, expected, String.format(
125+
"[%s] set for [%s] didn't set the authentication mode correctly",
126+
input, MANTA_ENCRYPTION_AUTHENTICATION_MODE_KEY));
127+
}
128+
129+
public void authenticationModeCanBeSetToOptional() {
130+
final String input = "Optional";
131+
final EncryptionAuthenticationMode expected = EncryptionAuthenticationMode.Optional;
132+
133+
final Properties properties = new Properties();
134+
properties.setProperty(MANTA_ENCRYPTION_AUTHENTICATION_MODE_KEY, input);
135+
final SystemSettingsConfigContext instance = new SystemSettingsConfigContext(
136+
false, properties);
137+
138+
final EncryptionAuthenticationMode actual = instance.getEncryptionAuthenticationMode();
139+
Assert.assertEquals(actual, expected, String.format(
140+
"[%s] set for [%s] didn't set the authentication mode correctly",
141+
input, MANTA_ENCRYPTION_AUTHENTICATION_MODE_KEY));
142+
}
143+
144+
public void authenticationModeCanBeSetToDisabled() {
145+
final String input = "Disabled";
146+
final EncryptionAuthenticationMode expected = EncryptionAuthenticationMode.Disabled;
147+
148+
final Properties properties = new Properties();
149+
properties.setProperty(MANTA_ENCRYPTION_AUTHENTICATION_MODE_KEY, input);
150+
final SystemSettingsConfigContext instance = new SystemSettingsConfigContext(
151+
false, properties);
152+
153+
final EncryptionAuthenticationMode actual = instance.getEncryptionAuthenticationMode();
154+
Assert.assertEquals(actual, expected, String.format(
155+
"[%s] set for [%s] didn't set the authentication mode correctly",
156+
input, MANTA_ENCRYPTION_AUTHENTICATION_MODE_KEY));
157+
}
113158
}

java-manta-it/src/test/java/com/joyent/manta/config/IntegrationTestConfigContext.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111
import com.joyent.manta.client.crypto.SecretKeyUtils;
1212
import com.joyent.manta.client.crypto.SupportedCipherDetails;
1313
import com.joyent.manta.client.crypto.SupportedCiphersLookupMap;
14+
import com.joyent.manta.util.MantaUtils;
1415
import org.apache.commons.lang3.BooleanUtils;
1516
import org.apache.commons.lang3.ObjectUtils;
1617

18+
import javax.crypto.SecretKey;
1719
import java.io.IOException;
1820
import java.util.Base64;
1921
import java.util.UUID;
20-
import javax.crypto.SecretKey;
2122

2223

2324
/**
@@ -68,7 +69,12 @@ private static <T> SettableConfigContext<T> enableTestEncryption(
6869
if (usingEncryption) {
6970
context.setClientEncryptionEnabled(true);
7071
context.setEncryptionKeyId("integration-test-key");
71-
context.setEncryptionAuthenticationMode(EncryptionAuthenticationMode.Optional);
72+
73+
EncryptionAuthenticationMode envSettingsMode = MantaUtils.parseEnumOrNull(
74+
encryptionAuthenticationMode(), EncryptionAuthenticationMode.class);
75+
76+
context.setEncryptionAuthenticationMode(ObjectUtils.firstNonNull(
77+
envSettingsMode, EncryptionAuthenticationMode.Optional));
7278

7379
SupportedCipherDetails cipherDetails = SupportedCiphersLookupMap.INSTANCE.getOrDefault(encryptionCipher,
7480
DefaultsConfigContext.DEFAULT_CIPHER);
@@ -98,6 +104,13 @@ public static String encryptionCipher() {
98104
return sysProp != null ? sysProp : envVar;
99105
}
100106

107+
public static String encryptionAuthenticationMode() {
108+
String sysProp = System.getProperty(MapConfigContext.MANTA_ENCRYPTION_AUTHENTICATION_MODE_KEY);
109+
String envVar = System.getenv(EnvVarConfigContext.MANTA_ENCRYPTION_AUTHENTICATION_MODE_ENV_KEY);
110+
111+
return sysProp != null ? sysProp : envVar;
112+
}
113+
101114
public static String generateSuiteBasePath(final ConfigContext config) {
102115
final String integrationTestBase = ObjectUtils.firstNonNull(
103116
System.getenv("MANTA_IT_PATH"),

0 commit comments

Comments
 (0)