Skip to content

Commit f5e9748

Browse files
support only one single key loader that must be provided by the user
1 parent f84d710 commit f5e9748

15 files changed

+53
-100
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1818

1919
<!-- dependencies -->
20-
<cryptolib.version>2.0.0-beta6</cryptolib.version>
20+
<cryptolib.version>2.0.0-beta7</cryptolib.version>
2121
<jwt.version>3.12.0</jwt.version>
2222
<dagger.version>2.31</dagger.version>
2323
<guava.version>30.1-jre</guava.version>

src/main/java/org/cryptomator/cryptofs/CryptoFileSystemProperties.java

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,14 @@
99
package org.cryptomator.cryptofs;
1010

1111
import com.google.common.base.Strings;
12-
import org.cryptomator.cryptofs.common.Constants;
1312
import org.cryptomator.cryptolib.api.MasterkeyLoader;
14-
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
1513

1614
import java.net.URI;
1715
import java.nio.file.FileSystems;
1816
import java.nio.file.Path;
1917
import java.util.AbstractMap;
2018
import java.util.Collection;
2119
import java.util.EnumSet;
22-
import java.util.HashSet;
2320
import java.util.Map;
2421
import java.util.Set;
2522
import java.util.function.Consumer;
@@ -51,9 +48,7 @@ public class CryptoFileSystemProperties extends AbstractMap<String, Object> {
5148
*
5249
* @since 2.0.0
5350
*/
54-
public static final String PROPERTY_KEYLOADERS = "keyLoaders";
55-
56-
static final Collection<MasterkeyLoader> DEFAULT_KEYLOADERS = Set.of();
51+
public static final String PROPERTY_KEYLOADER = "keyLoader";
5752

5853
/**
5954
* Key identifying the name of the vault config file located inside the vault directory.
@@ -102,7 +97,7 @@ public enum FileSystemFlags {
10297

10398
private CryptoFileSystemProperties(Builder builder) {
10499
this.entries = Set.of( //
105-
Map.entry(PROPERTY_KEYLOADERS, builder.keyLoaders), //
100+
Map.entry(PROPERTY_KEYLOADER, builder.keyLoader), //
106101
Map.entry(PROPERTY_FILESYSTEM_FLAGS, builder.flags), //
107102
Map.entry(PROPERTY_VAULTCONFIG_FILENAME, builder.vaultConfigFilename), //
108103
Map.entry(PROPERTY_MASTERKEY_FILENAME, builder.masterkeyFilename), //
@@ -111,24 +106,8 @@ private CryptoFileSystemProperties(Builder builder) {
111106
);
112107
}
113108

114-
Collection<MasterkeyLoader> keyLoaders() {
115-
return (Collection<MasterkeyLoader>) get(PROPERTY_KEYLOADERS);
116-
}
117-
118-
/**
119-
* Selects the first applicable MasterkeyLoader that supports the given scheme.
120-
*
121-
* @param scheme An URI scheme used in key IDs
122-
* @return A key loader
123-
* @throws MasterkeyLoadingFailedException If the scheme is not supported by any key loader
124-
*/
125-
MasterkeyLoader keyLoader(String scheme) throws MasterkeyLoadingFailedException {
126-
for (MasterkeyLoader loader : keyLoaders()) {
127-
if (loader.supportsScheme(scheme)) {
128-
return loader;
129-
}
130-
}
131-
throw new MasterkeyLoadingFailedException("No key loader for key type: " + scheme);
109+
MasterkeyLoader keyLoader() {
110+
return (MasterkeyLoader) get(PROPERTY_KEYLOADER);
132111
}
133112

134113
public VaultCipherCombo cipherCombo() {
@@ -205,7 +184,7 @@ public static CryptoFileSystemProperties wrap(Map<String, ?> properties) {
205184
public static class Builder {
206185

207186
public VaultCipherCombo cipherCombo = DEFAULT_CIPHER_COMBO;
208-
private Collection<MasterkeyLoader> keyLoaders = new HashSet<>(DEFAULT_KEYLOADERS);
187+
private MasterkeyLoader keyLoader = null;
209188
private final Set<FileSystemFlags> flags = EnumSet.copyOf(DEFAULT_FILESYSTEM_FLAGS);
210189
private String vaultConfigFilename = DEFAULT_VAULTCONFIG_FILENAME;
211190
private String masterkeyFilename = DEFAULT_MASTERKEY_FILENAME;
@@ -215,7 +194,7 @@ private Builder() {
215194
}
216195

217196
private Builder(Map<String, ?> properties) {
218-
checkedSet(Collection.class, PROPERTY_KEYLOADERS, properties, this::withKeyLoaders);
197+
checkedSet(MasterkeyLoader.class, PROPERTY_KEYLOADER, properties, this::withKeyLoader);
219198
checkedSet(String.class, PROPERTY_VAULTCONFIG_FILENAME, properties, this::withVaultConfigFilename);
220199
checkedSet(String.class, PROPERTY_MASTERKEY_FILENAME, properties, this::withMasterkeyFilename);
221200
checkedSet(Set.class, PROPERTY_FILESYSTEM_FLAGS, properties, this::withFlags);
@@ -262,26 +241,14 @@ public Builder withCipherCombo(VaultCipherCombo cipherCombo) {
262241
}
263242

264243
/**
265-
* Sets the keyLoaders for a CryptoFileSystem.
266-
*
267-
* @param keyLoaders A set of keyLoaders to load the key configured in the vault configuration
268-
* @return this
269-
* @since 2.0.0
270-
*/
271-
public Builder withKeyLoaders(MasterkeyLoader... keyLoaders) {
272-
return withKeyLoaders(asList(keyLoaders));
273-
}
274-
275-
/**
276-
* Sets the keyLoaders for a CryptoFileSystem.
244+
* Sets the keyloader for a CryptoFileSystem.
277245
*
278-
* @param keyLoaders A set of keyLoaders to load the key configured in the vault configuration
246+
* @param keyLoader A factory creating a {@link MasterkeyLoader} capable of handling the given {@code scheme}.
279247
* @return this
280248
* @since 2.0.0
281249
*/
282-
public Builder withKeyLoaders(Collection<MasterkeyLoader> keyLoaders) {
283-
this.keyLoaders.clear();
284-
this.keyLoaders.addAll(keyLoaders);
250+
public Builder withKeyLoader(MasterkeyLoader keyLoader) {
251+
this.keyLoader = keyLoader;
285252
return this;
286253
}
287254

@@ -345,8 +312,8 @@ public CryptoFileSystemProperties build() {
345312
}
346313

347314
private void validate() {
348-
if (keyLoaders.isEmpty()) {
349-
throw new IllegalStateException("at least one keyloader is required");
315+
if (keyLoader == null) {
316+
throw new IllegalStateException("keyLoader is required");
350317
}
351318
if (Strings.nullToEmpty(masterkeyFilename).trim().isEmpty()) {
352319
throw new IllegalStateException("masterkeyFilename is required");

src/main/java/org/cryptomator/cryptofs/CryptoFileSystemProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public static void initialize(Path pathToVault, CryptoFileSystemProperties prope
142142
}
143143
byte[] rawKey = new byte[0];
144144
var config = VaultConfig.createNew().cipherCombo(properties.cipherCombo()).shorteningThreshold(Constants.DEFAULT_SHORTENING_THRESHOLD).build();
145-
try (Masterkey key = properties.keyLoader(keyId.getScheme()).loadKey(keyId);
145+
try (Masterkey key = properties.keyLoader().loadKey(keyId);
146146
Cryptor cryptor = config.getCipherCombo().getCryptorProvider(strongSecureRandom()).withKey(key)) {
147147
rawKey = key.getEncoded();
148148
// save vault config:

src/main/java/org/cryptomator/cryptofs/CryptoFileSystems.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public CryptoFileSystemImpl create(CryptoFileSystemProvider provider, Path pathT
4949

5050
var configLoader = VaultConfig.decode(token);
5151
var keyId = configLoader.getKeyId();
52-
try (Masterkey key = properties.keyLoader(keyId.getScheme()).loadKey(keyId)) {
52+
try (Masterkey key = properties.keyLoader().loadKey(keyId)) {
5353
var config = configLoader.verify(key.getEncoded(), Constants.VAULT_VERSION);
5454
var adjustedProperties = adjustForCapabilities(pathToVault, properties);
5555
var cryptor = config.getCipherCombo().getCryptorProvider(csprng).withKey(key.clone());

src/test/java/org/cryptomator/cryptofs/CryptoFileChannelWriteReadIntegrationTest.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,8 @@ public class Windows {
6666
@BeforeAll
6767
public void setupClass(@TempDir Path tmpDir) throws IOException, MasterkeyLoadingFailedException {
6868
MasterkeyLoader keyLoader = Mockito.mock(MasterkeyLoader.class);
69-
Mockito.when(keyLoader.supportsScheme(Mockito.any())).thenReturn(true);
7069
Mockito.when(keyLoader.loadKey(Mockito.any())).thenAnswer(ignored -> new Masterkey(new byte[64]));
71-
CryptoFileSystemProperties properties = cryptoFileSystemProperties().withKeyLoaders(keyLoader).build();
70+
CryptoFileSystemProperties properties = cryptoFileSystemProperties().withKeyLoader(keyLoader).build();
7271
CryptoFileSystemProvider.initialize(tmpDir, properties, URI.create("test:key"));
7372
fileSystem = CryptoFileSystemProvider.newFileSystem(tmpDir, properties);
7473
}
@@ -142,9 +141,8 @@ public void beforeAll() throws IOException, MasterkeyLoadingFailedException {
142141
Path vaultPath = inMemoryFs.getPath("vault");
143142
Files.createDirectories(vaultPath);
144143
MasterkeyLoader keyLoader = Mockito.mock(MasterkeyLoader.class);
145-
Mockito.when(keyLoader.supportsScheme("test")).thenReturn(true);
146144
Mockito.when(keyLoader.loadKey(Mockito.any())).thenAnswer(ignored -> new Masterkey(new byte[64]));
147-
var properties = CryptoFileSystemProperties.cryptoFileSystemProperties().withKeyLoaders(keyLoader).build();
145+
var properties = cryptoFileSystemProperties().withKeyLoader(keyLoader).build();
148146
CryptoFileSystemProvider.initialize(vaultPath, properties, URI.create("test:key"));
149147
fileSystem = new CryptoFileSystemProvider().newFileSystem(vaultPath, properties);
150148
file = fileSystem.getPath("/test.txt");

src/test/java/org/cryptomator/cryptofs/CryptoFileSystemPropertiesTest.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import java.util.Map;
1616
import java.util.Map.Entry;
1717
import java.util.Objects;
18-
import java.util.Set;
1918

2019
import static org.cryptomator.cryptofs.CryptoFileSystemProperties.*;
2120
import static org.hamcrest.CoreMatchers.sameInstance;
@@ -37,7 +36,7 @@ public void testSetNoPassphrase() {
3736
public void testSetMasterkeyFilenameAndReadonlyFlag() {
3837
String masterkeyFilename = "aMasterkeyFilename";
3938
CryptoFileSystemProperties inTest = cryptoFileSystemProperties() //
40-
.withKeyLoaders(keyLoader) //
39+
.withKeyLoader(keyLoader) //
4140
.withMasterkeyFilename(masterkeyFilename) //
4241
.withFlags(FileSystemFlags.READONLY)
4342
.build();
@@ -46,7 +45,7 @@ public void testSetMasterkeyFilenameAndReadonlyFlag() {
4645
MatcherAssert.assertThat(inTest.readonly(), is(true));
4746
MatcherAssert.assertThat(inTest.entrySet(),
4847
containsInAnyOrder( //
49-
anEntry(PROPERTY_KEYLOADERS, Set.of(keyLoader)), //
48+
anEntry(PROPERTY_KEYLOADER, keyLoader), //
5049
anEntry(PROPERTY_VAULTCONFIG_FILENAME, DEFAULT_VAULTCONFIG_FILENAME), //
5150
anEntry(PROPERTY_MASTERKEY_FILENAME, masterkeyFilename), //
5251
anEntry(PROPERTY_MAX_CLEARTEXT_NAME_LENGTH, DEFAULT_MAX_CLEARTEXT_NAME_LENGTH), //
@@ -58,7 +57,7 @@ public void testSetMasterkeyFilenameAndReadonlyFlag() {
5857
public void testFromMap() {
5958
Map<String, Object> map = new HashMap<>();
6059
String masterkeyFilename = "aMasterkeyFilename";
61-
map.put(PROPERTY_KEYLOADERS, Set.of(keyLoader));
60+
map.put(PROPERTY_KEYLOADER, keyLoader);
6261
map.put(PROPERTY_MASTERKEY_FILENAME, masterkeyFilename);
6362
map.put(PROPERTY_MAX_CLEARTEXT_NAME_LENGTH, 255);
6463
map.put(PROPERTY_FILESYSTEM_FLAGS, EnumSet.of(FileSystemFlags.READONLY));
@@ -69,7 +68,7 @@ public void testFromMap() {
6968
MatcherAssert.assertThat(inTest.maxCleartextNameLength(), is(255));
7069
MatcherAssert.assertThat(inTest.entrySet(),
7170
containsInAnyOrder( //
72-
anEntry(PROPERTY_KEYLOADERS, Set.of(keyLoader)), //
71+
anEntry(PROPERTY_KEYLOADER, keyLoader), //
7372
anEntry(PROPERTY_VAULTCONFIG_FILENAME, DEFAULT_VAULTCONFIG_FILENAME), //
7473
anEntry(PROPERTY_MASTERKEY_FILENAME, masterkeyFilename), //
7574
anEntry(PROPERTY_MAX_CLEARTEXT_NAME_LENGTH, 255), //
@@ -81,7 +80,7 @@ public void testFromMap() {
8180
public void testWrapMapWithTrueReadonly() {
8281
Map<String, Object> map = new HashMap<>();
8382
String masterkeyFilename = "aMasterkeyFilename";
84-
map.put(PROPERTY_KEYLOADERS, Set.of(keyLoader));
83+
map.put(PROPERTY_KEYLOADER, keyLoader);
8584
map.put(PROPERTY_MASTERKEY_FILENAME, masterkeyFilename);
8685
map.put(PROPERTY_FILESYSTEM_FLAGS, EnumSet.of(FileSystemFlags.READONLY));
8786
CryptoFileSystemProperties inTest = CryptoFileSystemProperties.wrap(map);
@@ -90,7 +89,7 @@ public void testWrapMapWithTrueReadonly() {
9089
MatcherAssert.assertThat(inTest.readonly(), is(true));
9190
MatcherAssert.assertThat(inTest.entrySet(),
9291
containsInAnyOrder( //
93-
anEntry(PROPERTY_KEYLOADERS, Set.of(keyLoader)), //
92+
anEntry(PROPERTY_KEYLOADER, keyLoader), //
9493
anEntry(PROPERTY_VAULTCONFIG_FILENAME, DEFAULT_VAULTCONFIG_FILENAME), //
9594
anEntry(PROPERTY_MASTERKEY_FILENAME, masterkeyFilename), //
9695
anEntry(PROPERTY_MAX_CLEARTEXT_NAME_LENGTH, DEFAULT_MAX_CLEARTEXT_NAME_LENGTH), //
@@ -102,7 +101,7 @@ public void testWrapMapWithTrueReadonly() {
102101
public void testWrapMapWithFalseReadonly() {
103102
Map<String, Object> map = new HashMap<>();
104103
String masterkeyFilename = "aMasterkeyFilename";
105-
map.put(PROPERTY_KEYLOADERS, Set.of(keyLoader));
104+
map.put(PROPERTY_KEYLOADER, keyLoader);
106105
map.put(PROPERTY_MASTERKEY_FILENAME, masterkeyFilename);
107106
map.put(PROPERTY_FILESYSTEM_FLAGS, EnumSet.noneOf(FileSystemFlags.class));
108107
CryptoFileSystemProperties inTest = CryptoFileSystemProperties.wrap(map);
@@ -111,7 +110,7 @@ public void testWrapMapWithFalseReadonly() {
111110
MatcherAssert.assertThat(inTest.readonly(), is(false));
112111
MatcherAssert.assertThat(inTest.entrySet(),
113112
containsInAnyOrder( //
114-
anEntry(PROPERTY_KEYLOADERS, Set.of(keyLoader)), //
113+
anEntry(PROPERTY_KEYLOADER, keyLoader), //
115114
anEntry(PROPERTY_VAULTCONFIG_FILENAME, DEFAULT_VAULTCONFIG_FILENAME), //
116115
anEntry(PROPERTY_MASTERKEY_FILENAME, masterkeyFilename), //
117116
anEntry(PROPERTY_MAX_CLEARTEXT_NAME_LENGTH, DEFAULT_MAX_CLEARTEXT_NAME_LENGTH), //
@@ -155,14 +154,14 @@ public void testWrapMapWithInvalidPassphrase() {
155154
@Test
156155
public void testWrapMapWithoutReadonly() {
157156
Map<String, Object> map = new HashMap<>();
158-
map.put(PROPERTY_KEYLOADERS, Set.of(keyLoader));
157+
map.put(PROPERTY_KEYLOADER, keyLoader);
159158
CryptoFileSystemProperties inTest = CryptoFileSystemProperties.wrap(map);
160159

161160
MatcherAssert.assertThat(inTest.masterkeyFilename(), is(DEFAULT_MASTERKEY_FILENAME));
162161
MatcherAssert.assertThat(inTest.readonly(), is(false));
163162
MatcherAssert.assertThat(inTest.entrySet(),
164163
containsInAnyOrder( //
165-
anEntry(PROPERTY_KEYLOADERS, Set.of(keyLoader)), //
164+
anEntry(PROPERTY_KEYLOADER, keyLoader), //
166165
anEntry(PROPERTY_VAULTCONFIG_FILENAME, DEFAULT_VAULTCONFIG_FILENAME), //
167166
anEntry(PROPERTY_MASTERKEY_FILENAME, DEFAULT_MASTERKEY_FILENAME), //
168167
anEntry(PROPERTY_MAX_CLEARTEXT_NAME_LENGTH, DEFAULT_MAX_CLEARTEXT_NAME_LENGTH), //
@@ -181,7 +180,7 @@ public void testWrapMapWithoutPassphrase() {
181180

182181
@Test
183182
public void testWrapCryptoFileSystemProperties() {
184-
CryptoFileSystemProperties inTest = cryptoFileSystemProperties().withKeyLoaders(keyLoader).build();
183+
CryptoFileSystemProperties inTest = cryptoFileSystemProperties().withKeyLoader(keyLoader).build();
185184

186185
MatcherAssert.assertThat(CryptoFileSystemProperties.wrap(inTest), is(sameInstance(inTest)));
187186
}
@@ -190,7 +189,7 @@ public void testWrapCryptoFileSystemProperties() {
190189
public void testMapIsImmutable() {
191190
Assertions.assertThrows(UnsupportedOperationException.class, () -> {
192191
cryptoFileSystemProperties() //
193-
.withKeyLoaders(keyLoader) //
192+
.withKeyLoader(keyLoader) //
194193
.build() //
195194
.put("test", "test");
196195
});
@@ -200,7 +199,7 @@ public void testMapIsImmutable() {
200199
public void testEntrySetIsImmutable() {
201200
Assertions.assertThrows(UnsupportedOperationException.class, () -> {
202201
cryptoFileSystemProperties() //
203-
.withKeyLoaders(keyLoader) //
202+
.withKeyLoader(keyLoader) //
204203
.build() //
205204
.entrySet() //
206205
.add(null);
@@ -211,7 +210,7 @@ public void testEntrySetIsImmutable() {
211210
public void testEntryIsImmutable() {
212211
Assertions.assertThrows(UnsupportedOperationException.class, () -> {
213212
cryptoFileSystemProperties() //
214-
.withKeyLoaders(keyLoader) //
213+
.withKeyLoader(keyLoader) //
215214
.build() //
216215
.entrySet() //
217216
.iterator().next() //

0 commit comments

Comments
 (0)