Skip to content

Commit

Permalink
Merge branch 'release/2.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
infeo committed Nov 23, 2022
2 parents 74174da + 739490c commit aacd531
Show file tree
Hide file tree
Showing 48 changed files with 856 additions and 970 deletions.
91 changes: 34 additions & 57 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>cryptolib</artifactId>
<version>2.0.3</version>
<version>2.1.0</version>
<name>Cryptomator Crypto Library</name>
<description>This library contains all cryptographic functions that are used by Cryptomator.</description>
<url>https://github.com/cryptomator/cryptolib</url>
Expand All @@ -19,19 +19,19 @@

<!-- dependencies -->
<gson.version>2.8.9</gson.version>
<guava.version>30.1.1-jre</guava.version>
<siv-mode.version>1.4.3</siv-mode.version>
<bouncycastle.version>1.69</bouncycastle.version>
<slf4j.version>1.7.31</slf4j.version>
<guava.version>31.0.1-jre</guava.version>
<siv-mode.version>1.4.4</siv-mode.version>
<bouncycastle.version>1.70</bouncycastle.version>
<slf4j.version>1.7.35</slf4j.version>

<!-- test dependencies -->
<junit.jupiter.version>5.7.2</junit.jupiter.version>
<mockito.version>3.11.2</mockito.version>
<junit.jupiter.version>5.8.2</junit.jupiter.version>
<mockito.version>4.3.1</mockito.version>
<hamcrest.version>2.2</hamcrest.version>
<jmh.version>1.32</jmh.version>
<jmh.version>1.34</jmh.version>

<!-- build plugin dependencies -->
<dependency-check.version>6.2.2</dependency-check.version>
<dependency-check.version>6.5.3</dependency-check.version>
<jacoco.version>0.8.7</jacoco.version>
<nexus-staging.version>1.6.8</nexus-staging.version>
</properties>
Expand Down Expand Up @@ -131,7 +131,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<version>3.0.0</version>
<executions>
<execution>
<id>enforce-java</id>
Expand All @@ -151,15 +151,31 @@
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<version>3.9.0</version>
<configuration>
<encoding>UTF-8</encoding>
<showWarnings>true</showWarnings>
</configuration>
<executions>
<execution>
<id>java9</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>9</release>
<compileSourceRoots>
<compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot>
</compileSourceRoots>
<multiReleaseOutput>true</multiReleaseOutput>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<version>3.4.0</version>
<executions>
<execution>
<phase>package</phase>
Expand All @@ -179,7 +195,7 @@
<relocations>
<relocation>
<pattern>org.bouncycastle</pattern>
<shadedPattern>org.cryptomator.cryptolib.org.bouncycastle</shadedPattern>
<shadedPattern>org.cryptomator.cryptolib.shaded.bouncycastle</shadedPattern>
</relocation>
</relocations>
<filters>
Expand All @@ -194,56 +210,15 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.moditect</groupId>
<artifactId>moditect-maven-plugin</artifactId>
<version>1.0.0.RC1</version>
<executions>
<execution>
<id>add-module-infos</id>
<phase>package</phase>
<goals>
<goal>add-module-info</goal>
</goals>
<configuration>
<jvmVersion>9</jvmVersion>
<overwriteExistingFiles>true</overwriteExistingFiles>
<module>
<moduleInfoSource>
module org.cryptomator.cryptolib {
requires org.cryptomator.siv;
requires com.google.gson;
requires com.google.common;
requires org.slf4j;

exports org.cryptomator.cryptolib.api;
exports org.cryptomator.cryptolib.common;

opens org.cryptomator.cryptolib.common to com.google.gson;

uses org.cryptomator.cryptolib.api.CryptorProvider;

provides org.cryptomator.cryptolib.api.CryptorProvider
with org.cryptomator.cryptolib.v1.CryptorProviderImpl, org.cryptomator.cryptolib.v2.CryptorProviderImpl;
}
</moduleInfoSource>
</module>
<jdepsExtraArgs>
<arg>--multi-release=9</arg>
</jdepsExtraArgs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<version>3.0.0-M5</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<version>3.2.2</version>
<configuration>
<archive>
<manifestEntries>
Expand All @@ -267,7 +242,7 @@
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.0</version>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
Expand All @@ -277,6 +252,8 @@
</execution>
</executions>
<configuration>
<release>9</release>
<sourcepath>${project.basedir}/src/main/java9:${project.build.sourceDirectory}</sourcepath>
<tags>
<!-- workaround for "unknown tag: implNote", see https://blog.codefx.org/java/new-javadoc-tags/#Maven -->
<tag>
Expand Down
19 changes: 11 additions & 8 deletions src/main/java/org/cryptomator/cryptolib/common/AesKeyWrap.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,26 @@

public class AesKeyWrap {

private AesKeyWrap() {
}

/**
* @param kek Key encrypting key
* @param key Key to be wrapped
* @return Wrapped key
*/
public static byte[] wrap(DestroyableSecretKey kek, SecretKey key) {
try (DestroyableSecretKey kekCopy = kek.copy()) {
final Cipher cipher = CipherSupplier.RFC3394_KEYWRAP.forWrapping(kekCopy);
return cipher.wrap(key);
try (DestroyableSecretKey kekCopy = kek.copy();
ObjectPool.Lease<Cipher> cipher = CipherSupplier.RFC3394_KEYWRAP.keyWrapCipher(kekCopy)) {
return cipher.get().wrap(key);
} catch (InvalidKeyException | IllegalBlockSizeException e) {
throw new IllegalArgumentException("Unable to wrap key.", e);
}
}

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

// visible for testing
static DestroyableSecretKey unwrap(DestroyableSecretKey kek, byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException {
try (DestroyableSecretKey kekCopy = kek.copy()) {
final Cipher cipher = CipherSupplier.RFC3394_KEYWRAP.forUnwrapping(kekCopy);
return DestroyableSecretKey.from(cipher.unwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType));
try (DestroyableSecretKey kekCopy = kek.copy();
ObjectPool.Lease<Cipher> cipher = CipherSupplier.RFC3394_KEYWRAP.keyUnwrapCipher(kekCopy)) {
return DestroyableSecretKey.from(cipher.get().unwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType));
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("Invalid algorithm: " + wrappedKeyAlgorithm, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

public class ByteBuffers {

private ByteBuffers() {
}

/**
* Copies as many bytes as possible from the given source to the destination buffer.
* The position of both buffers will be incremented by as many bytes as have been copied.
Expand Down
128 changes: 108 additions & 20 deletions src/main/java/org/cryptomator/cryptolib/common/CipherSupplier.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.function.Function;

public final class CipherSupplier {

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

private final String cipherAlgorithm;
private final ThreadLocal<Cipher> threadLocal;
private final ObjectPool<Cipher> cipherPool;

public CipherSupplier(String cipherAlgorithm) {
this.cipherAlgorithm = cipherAlgorithm;
this.threadLocal = new Provider();
this.threadLocal.get(); // eagerly initialize to provoke exceptions
this.cipherPool = new ObjectPool<>(this::createCipher);
try (ObjectPool.Lease<Cipher> lease = cipherPool.get()) {
lease.get(); // eagerly initialize to provoke exceptions
}
}

private class Provider extends ThreadLocal<Cipher> {
@Override
protected Cipher initialValue() {
try {
return Cipher.getInstance(cipherAlgorithm);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new IllegalArgumentException("Invalid cipher algorithm or padding.", e);
}
private Cipher createCipher() {
try {
return Cipher.getInstance(cipherAlgorithm);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new IllegalArgumentException("Invalid cipher algorithm or padding.", e);
}
}

/**
* Leases a reusable cipher object initialized for encryption.
*
* @param key Encryption key
* @param params Params such as IV/Nonce
* @return A lease supplying a refurbished Cipher
*/
public ObjectPool.Lease<Cipher> encryptionCipher(SecretKey key, AlgorithmParameterSpec params) {
ObjectPool.Lease<Cipher> lease = cipherPool.get();
initMode(lease.get(), Cipher.ENCRYPT_MODE, key, params);
return lease;
}

/**
* Creates a new Cipher object initialized for encryption.
*
* @param key Encryption key
* @param params Params such as IV/Nonce
* @return New Cipher instance
* @deprecated Use {@link #encryptionCipher(SecretKey, AlgorithmParameterSpec)} instead.
*/
@Deprecated
public Cipher forEncryption(SecretKey key, AlgorithmParameterSpec params) {
return forMode(Cipher.ENCRYPT_MODE, key, params);
final Cipher cipher = createCipher();
initMode(cipher, Cipher.ENCRYPT_MODE, key, params);
return cipher;
}

/**
* Leases a reusable cipher object initialized for decryption.
*
* @param key Decryption key
* @param params Params such as IV/Nonce
* @return A lease supplying a refurbished Cipher
*/
public ObjectPool.Lease<Cipher> decryptionCipher(SecretKey key, AlgorithmParameterSpec params) {
ObjectPool.Lease<Cipher> lease = cipherPool.get();
initMode(lease.get(), Cipher.DECRYPT_MODE, key, params);
return lease;
}

/**
* Creates a new Cipher object initialized for decryption.
*
* @param key Encryption key
* @param params Params such as IV/Nonce
* @return New Cipher instance
* @deprecated Use {@link #decryptionCipher(SecretKey, AlgorithmParameterSpec)} instead.
*/
@Deprecated
public Cipher forDecryption(SecretKey key, AlgorithmParameterSpec params) {
return forMode(Cipher.DECRYPT_MODE, key, params);
final Cipher cipher = createCipher();
initMode(cipher, Cipher.DECRYPT_MODE, key, params);
return cipher;
}

/**
* Leases a reusable cipher object initialized for wrapping a key.
*
* @param kek Key encryption key
* @return A lease supplying a refurbished Cipher
*/
public ObjectPool.Lease<Cipher> keyWrapCipher(SecretKey kek) {
ObjectPool.Lease<Cipher> lease = cipherPool.get();
initMode(lease.get(), Cipher.WRAP_MODE, kek, null);
return lease;
}

/**
* Creates a new Cipher object initialized for wrapping a key.
*
* @param kek Key encryption key
* @return New Cipher instance
* @deprecated Use {@link #keyWrapCipher(SecretKey)} instead.
*/
@Deprecated
public Cipher forWrapping(SecretKey kek) {
return forMode(Cipher.WRAP_MODE, kek, null);
final Cipher cipher = createCipher();
initMode(cipher, Cipher.WRAP_MODE, kek, null);
return cipher;
}

/**
* Leases a reusable cipher object initialized for unwrapping a key.
*
* @param kek Key encryption key
* @return A lease supplying a refurbished Cipher
*/
public ObjectPool.Lease<Cipher> keyUnwrapCipher(SecretKey kek) {
ObjectPool.Lease<Cipher> lease = cipherPool.get();
initMode(lease.get(), Cipher.UNWRAP_MODE, kek, null);
return lease;
}

/**
* Creates a new Cipher object initialized for unwrapping a key.
*
* @param kek Key encryption key
* @return New Cipher instance
* @deprecated Use {@link #keyUnwrapCipher(SecretKey)} instead.
*/
@Deprecated
public Cipher forUnwrapping(SecretKey kek) {
return forMode(Cipher.UNWRAP_MODE, kek, null);
final Cipher cipher = createCipher();
initMode(cipher, Cipher.UNWRAP_MODE, kek, null);
return cipher;
}

// visible for testing
Cipher forMode(int ciphermode, SecretKey key, AlgorithmParameterSpec params) {
final Cipher cipher = threadLocal.get();
private void initMode(Cipher cipher, int ciphermode, SecretKey key, AlgorithmParameterSpec params) {
try {
cipher.init(ciphermode, key, params);
return cipher;
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("Invalid key.", e);
} catch (InvalidAlgorithmParameterException e) {
throw new IllegalArgumentException("Algorithm parameter not appropriate for " + cipher.getAlgorithm() + ".", e);
}
}

}
Loading

0 comments on commit aacd531

Please sign in to comment.