Skip to content

Commit aacd531

Browse files
committed
Merge branch 'release/2.1.0'
2 parents 74174da + 739490c commit aacd531

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+856
-970
lines changed

pom.xml

Lines changed: 34 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<modelVersion>4.0.0</modelVersion>
33
<groupId>org.cryptomator</groupId>
44
<artifactId>cryptolib</artifactId>
5-
<version>2.0.3</version>
5+
<version>2.1.0</version>
66
<name>Cryptomator Crypto Library</name>
77
<description>This library contains all cryptographic functions that are used by Cryptomator.</description>
88
<url>https://github.com/cryptomator/cryptolib</url>
@@ -19,19 +19,19 @@
1919

2020
<!-- dependencies -->
2121
<gson.version>2.8.9</gson.version>
22-
<guava.version>30.1.1-jre</guava.version>
23-
<siv-mode.version>1.4.3</siv-mode.version>
24-
<bouncycastle.version>1.69</bouncycastle.version>
25-
<slf4j.version>1.7.31</slf4j.version>
22+
<guava.version>31.0.1-jre</guava.version>
23+
<siv-mode.version>1.4.4</siv-mode.version>
24+
<bouncycastle.version>1.70</bouncycastle.version>
25+
<slf4j.version>1.7.35</slf4j.version>
2626

2727
<!-- test dependencies -->
28-
<junit.jupiter.version>5.7.2</junit.jupiter.version>
29-
<mockito.version>3.11.2</mockito.version>
28+
<junit.jupiter.version>5.8.2</junit.jupiter.version>
29+
<mockito.version>4.3.1</mockito.version>
3030
<hamcrest.version>2.2</hamcrest.version>
31-
<jmh.version>1.32</jmh.version>
31+
<jmh.version>1.34</jmh.version>
3232

3333
<!-- build plugin dependencies -->
34-
<dependency-check.version>6.2.2</dependency-check.version>
34+
<dependency-check.version>6.5.3</dependency-check.version>
3535
<jacoco.version>0.8.7</jacoco.version>
3636
<nexus-staging.version>1.6.8</nexus-staging.version>
3737
</properties>
@@ -131,7 +131,7 @@
131131
<plugin>
132132
<groupId>org.apache.maven.plugins</groupId>
133133
<artifactId>maven-enforcer-plugin</artifactId>
134-
<version>3.0.0-M3</version>
134+
<version>3.0.0</version>
135135
<executions>
136136
<execution>
137137
<id>enforce-java</id>
@@ -151,15 +151,31 @@
151151
</plugin>
152152
<plugin>
153153
<artifactId>maven-compiler-plugin</artifactId>
154-
<version>3.8.1</version>
154+
<version>3.9.0</version>
155155
<configuration>
156156
<encoding>UTF-8</encoding>
157157
<showWarnings>true</showWarnings>
158158
</configuration>
159+
<executions>
160+
<execution>
161+
<id>java9</id>
162+
<phase>compile</phase>
163+
<goals>
164+
<goal>compile</goal>
165+
</goals>
166+
<configuration>
167+
<release>9</release>
168+
<compileSourceRoots>
169+
<compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot>
170+
</compileSourceRoots>
171+
<multiReleaseOutput>true</multiReleaseOutput>
172+
</configuration>
173+
</execution>
174+
</executions>
159175
</plugin>
160176
<plugin>
161177
<artifactId>maven-shade-plugin</artifactId>
162-
<version>3.2.4</version>
178+
<version>3.4.0</version>
163179
<executions>
164180
<execution>
165181
<phase>package</phase>
@@ -179,7 +195,7 @@
179195
<relocations>
180196
<relocation>
181197
<pattern>org.bouncycastle</pattern>
182-
<shadedPattern>org.cryptomator.cryptolib.org.bouncycastle</shadedPattern>
198+
<shadedPattern>org.cryptomator.cryptolib.shaded.bouncycastle</shadedPattern>
183199
</relocation>
184200
</relocations>
185201
<filters>
@@ -194,56 +210,15 @@
194210
</execution>
195211
</executions>
196212
</plugin>
197-
<plugin>
198-
<groupId>org.moditect</groupId>
199-
<artifactId>moditect-maven-plugin</artifactId>
200-
<version>1.0.0.RC1</version>
201-
<executions>
202-
<execution>
203-
<id>add-module-infos</id>
204-
<phase>package</phase>
205-
<goals>
206-
<goal>add-module-info</goal>
207-
</goals>
208-
<configuration>
209-
<jvmVersion>9</jvmVersion>
210-
<overwriteExistingFiles>true</overwriteExistingFiles>
211-
<module>
212-
<moduleInfoSource>
213-
module org.cryptomator.cryptolib {
214-
requires org.cryptomator.siv;
215-
requires com.google.gson;
216-
requires com.google.common;
217-
requires org.slf4j;
218-
219-
exports org.cryptomator.cryptolib.api;
220-
exports org.cryptomator.cryptolib.common;
221-
222-
opens org.cryptomator.cryptolib.common to com.google.gson;
223-
224-
uses org.cryptomator.cryptolib.api.CryptorProvider;
225-
226-
provides org.cryptomator.cryptolib.api.CryptorProvider
227-
with org.cryptomator.cryptolib.v1.CryptorProviderImpl, org.cryptomator.cryptolib.v2.CryptorProviderImpl;
228-
}
229-
</moduleInfoSource>
230-
</module>
231-
<jdepsExtraArgs>
232-
<arg>--multi-release=9</arg>
233-
</jdepsExtraArgs>
234-
</configuration>
235-
</execution>
236-
</executions>
237-
</plugin>
238213
<plugin>
239214
<groupId>org.apache.maven.plugins</groupId>
240215
<artifactId>maven-surefire-plugin</artifactId>
241-
<version>2.22.2</version>
216+
<version>3.0.0-M5</version>
242217
</plugin>
243218
<plugin>
244219
<groupId>org.apache.maven.plugins</groupId>
245220
<artifactId>maven-jar-plugin</artifactId>
246-
<version>3.2.0</version>
221+
<version>3.2.2</version>
247222
<configuration>
248223
<archive>
249224
<manifestEntries>
@@ -267,7 +242,7 @@
267242
</plugin>
268243
<plugin>
269244
<artifactId>maven-javadoc-plugin</artifactId>
270-
<version>3.3.0</version>
245+
<version>3.3.1</version>
271246
<executions>
272247
<execution>
273248
<id>attach-javadocs</id>
@@ -277,6 +252,8 @@
277252
</execution>
278253
</executions>
279254
<configuration>
255+
<release>9</release>
256+
<sourcepath>${project.basedir}/src/main/java9:${project.build.sourceDirectory}</sourcepath>
280257
<tags>
281258
<!-- workaround for "unknown tag: implNote", see https://blog.codefx.org/java/new-javadoc-tags/#Maven -->
282259
<tag>

src/main/java/org/cryptomator/cryptolib/common/AesKeyWrap.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,26 @@
1616

1717
public class AesKeyWrap {
1818

19+
private AesKeyWrap() {
20+
}
21+
1922
/**
2023
* @param kek Key encrypting key
2124
* @param key Key to be wrapped
2225
* @return Wrapped key
2326
*/
2427
public static byte[] wrap(DestroyableSecretKey kek, SecretKey key) {
25-
try (DestroyableSecretKey kekCopy = kek.copy()) {
26-
final Cipher cipher = CipherSupplier.RFC3394_KEYWRAP.forWrapping(kekCopy);
27-
return cipher.wrap(key);
28+
try (DestroyableSecretKey kekCopy = kek.copy();
29+
ObjectPool.Lease<Cipher> cipher = CipherSupplier.RFC3394_KEYWRAP.keyWrapCipher(kekCopy)) {
30+
return cipher.get().wrap(key);
2831
} catch (InvalidKeyException | IllegalBlockSizeException e) {
2932
throw new IllegalArgumentException("Unable to wrap key.", e);
3033
}
3134
}
3235

3336
/**
34-
* @param kek Key encrypting key
35-
* @param wrappedKey Key to be unwrapped
37+
* @param kek Key encrypting key
38+
* @param wrappedKey Key to be unwrapped
3639
* @param wrappedKeyAlgorithm Key designation, i.e. algorithm to be associated with the unwrapped key.
3740
* @return Unwrapped key
3841
* @throws InvalidKeyException If unwrapping failed (i.e. wrong kek)
@@ -43,9 +46,9 @@ public static DestroyableSecretKey unwrap(DestroyableSecretKey kek, byte[] wrapp
4346

4447
// visible for testing
4548
static DestroyableSecretKey unwrap(DestroyableSecretKey kek, byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException {
46-
try (DestroyableSecretKey kekCopy = kek.copy()) {
47-
final Cipher cipher = CipherSupplier.RFC3394_KEYWRAP.forUnwrapping(kekCopy);
48-
return DestroyableSecretKey.from(cipher.unwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType));
49+
try (DestroyableSecretKey kekCopy = kek.copy();
50+
ObjectPool.Lease<Cipher> cipher = CipherSupplier.RFC3394_KEYWRAP.keyUnwrapCipher(kekCopy)) {
51+
return DestroyableSecretKey.from(cipher.get().unwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType));
4952
} catch (NoSuchAlgorithmException e) {
5053
throw new IllegalArgumentException("Invalid algorithm: " + wrappedKeyAlgorithm, e);
5154
}

src/main/java/org/cryptomator/cryptolib/common/ByteBuffers.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
public class ByteBuffers {
1616

17+
private ByteBuffers() {
18+
}
19+
1720
/**
1821
* Copies as many bytes as possible from the given source to the destination buffer.
1922
* The position of both buffers will be incremented by as many bytes as have been copied.

src/main/java/org/cryptomator/cryptolib/common/CipherSupplier.java

Lines changed: 108 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import java.security.InvalidKeyException;
1616
import java.security.NoSuchAlgorithmException;
1717
import java.security.spec.AlgorithmParameterSpec;
18-
import java.util.function.Function;
1918

2019
public final class CipherSupplier {
2120

@@ -24,51 +23,140 @@ public final class CipherSupplier {
2423
public static final CipherSupplier RFC3394_KEYWRAP = new CipherSupplier("AESWrap");
2524

2625
private final String cipherAlgorithm;
27-
private final ThreadLocal<Cipher> threadLocal;
26+
private final ObjectPool<Cipher> cipherPool;
2827

2928
public CipherSupplier(String cipherAlgorithm) {
3029
this.cipherAlgorithm = cipherAlgorithm;
31-
this.threadLocal = new Provider();
32-
this.threadLocal.get(); // eagerly initialize to provoke exceptions
30+
this.cipherPool = new ObjectPool<>(this::createCipher);
31+
try (ObjectPool.Lease<Cipher> lease = cipherPool.get()) {
32+
lease.get(); // eagerly initialize to provoke exceptions
33+
}
3334
}
3435

35-
private class Provider extends ThreadLocal<Cipher> {
36-
@Override
37-
protected Cipher initialValue() {
38-
try {
39-
return Cipher.getInstance(cipherAlgorithm);
40-
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
41-
throw new IllegalArgumentException("Invalid cipher algorithm or padding.", e);
42-
}
36+
private Cipher createCipher() {
37+
try {
38+
return Cipher.getInstance(cipherAlgorithm);
39+
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
40+
throw new IllegalArgumentException("Invalid cipher algorithm or padding.", e);
4341
}
4442
}
4543

44+
/**
45+
* Leases a reusable cipher object initialized for encryption.
46+
*
47+
* @param key Encryption key
48+
* @param params Params such as IV/Nonce
49+
* @return A lease supplying a refurbished Cipher
50+
*/
51+
public ObjectPool.Lease<Cipher> encryptionCipher(SecretKey key, AlgorithmParameterSpec params) {
52+
ObjectPool.Lease<Cipher> lease = cipherPool.get();
53+
initMode(lease.get(), Cipher.ENCRYPT_MODE, key, params);
54+
return lease;
55+
}
56+
57+
/**
58+
* Creates a new Cipher object initialized for encryption.
59+
*
60+
* @param key Encryption key
61+
* @param params Params such as IV/Nonce
62+
* @return New Cipher instance
63+
* @deprecated Use {@link #encryptionCipher(SecretKey, AlgorithmParameterSpec)} instead.
64+
*/
65+
@Deprecated
4666
public Cipher forEncryption(SecretKey key, AlgorithmParameterSpec params) {
47-
return forMode(Cipher.ENCRYPT_MODE, key, params);
67+
final Cipher cipher = createCipher();
68+
initMode(cipher, Cipher.ENCRYPT_MODE, key, params);
69+
return cipher;
70+
}
71+
72+
/**
73+
* Leases a reusable cipher object initialized for decryption.
74+
*
75+
* @param key Decryption key
76+
* @param params Params such as IV/Nonce
77+
* @return A lease supplying a refurbished Cipher
78+
*/
79+
public ObjectPool.Lease<Cipher> decryptionCipher(SecretKey key, AlgorithmParameterSpec params) {
80+
ObjectPool.Lease<Cipher> lease = cipherPool.get();
81+
initMode(lease.get(), Cipher.DECRYPT_MODE, key, params);
82+
return lease;
4883
}
4984

85+
/**
86+
* Creates a new Cipher object initialized for decryption.
87+
*
88+
* @param key Encryption key
89+
* @param params Params such as IV/Nonce
90+
* @return New Cipher instance
91+
* @deprecated Use {@link #decryptionCipher(SecretKey, AlgorithmParameterSpec)} instead.
92+
*/
93+
@Deprecated
5094
public Cipher forDecryption(SecretKey key, AlgorithmParameterSpec params) {
51-
return forMode(Cipher.DECRYPT_MODE, key, params);
95+
final Cipher cipher = createCipher();
96+
initMode(cipher, Cipher.DECRYPT_MODE, key, params);
97+
return cipher;
5298
}
5399

100+
/**
101+
* Leases a reusable cipher object initialized for wrapping a key.
102+
*
103+
* @param kek Key encryption key
104+
* @return A lease supplying a refurbished Cipher
105+
*/
106+
public ObjectPool.Lease<Cipher> keyWrapCipher(SecretKey kek) {
107+
ObjectPool.Lease<Cipher> lease = cipherPool.get();
108+
initMode(lease.get(), Cipher.WRAP_MODE, kek, null);
109+
return lease;
110+
}
111+
112+
/**
113+
* Creates a new Cipher object initialized for wrapping a key.
114+
*
115+
* @param kek Key encryption key
116+
* @return New Cipher instance
117+
* @deprecated Use {@link #keyWrapCipher(SecretKey)} instead.
118+
*/
119+
@Deprecated
54120
public Cipher forWrapping(SecretKey kek) {
55-
return forMode(Cipher.WRAP_MODE, kek, null);
121+
final Cipher cipher = createCipher();
122+
initMode(cipher, Cipher.WRAP_MODE, kek, null);
123+
return cipher;
56124
}
57125

126+
/**
127+
* Leases a reusable cipher object initialized for unwrapping a key.
128+
*
129+
* @param kek Key encryption key
130+
* @return A lease supplying a refurbished Cipher
131+
*/
132+
public ObjectPool.Lease<Cipher> keyUnwrapCipher(SecretKey kek) {
133+
ObjectPool.Lease<Cipher> lease = cipherPool.get();
134+
initMode(lease.get(), Cipher.UNWRAP_MODE, kek, null);
135+
return lease;
136+
}
137+
138+
/**
139+
* Creates a new Cipher object initialized for unwrapping a key.
140+
*
141+
* @param kek Key encryption key
142+
* @return New Cipher instance
143+
* @deprecated Use {@link #keyUnwrapCipher(SecretKey)} instead.
144+
*/
145+
@Deprecated
58146
public Cipher forUnwrapping(SecretKey kek) {
59-
return forMode(Cipher.UNWRAP_MODE, kek, null);
147+
final Cipher cipher = createCipher();
148+
initMode(cipher, Cipher.UNWRAP_MODE, kek, null);
149+
return cipher;
60150
}
61151

62-
// visible for testing
63-
Cipher forMode(int ciphermode, SecretKey key, AlgorithmParameterSpec params) {
64-
final Cipher cipher = threadLocal.get();
152+
private void initMode(Cipher cipher, int ciphermode, SecretKey key, AlgorithmParameterSpec params) {
65153
try {
66154
cipher.init(ciphermode, key, params);
67-
return cipher;
68155
} catch (InvalidKeyException e) {
69156
throw new IllegalArgumentException("Invalid key.", e);
70157
} catch (InvalidAlgorithmParameterException e) {
71158
throw new IllegalArgumentException("Algorithm parameter not appropriate for " + cipher.getAlgorithm() + ".", e);
72159
}
73160
}
161+
74162
}

0 commit comments

Comments
 (0)