From dfedde0df674e4181da57aa884f4dca4d4aa2a3a Mon Sep 17 00:00:00 2001 From: Max Dor Date: Fri, 1 Mar 2019 15:16:19 +0100 Subject: [PATCH] Improve crypto - Re-organize packages to be consistent - Add Key store tests --- src/main/java/io/kamax/mxisd/Mxisd.java | 6 +- .../io/kamax/mxisd/crypto/CryptoFactory.java | 6 +- .../{storage => }/crypto/GenericKey.java | 2 +- .../crypto/GenericKeyIdentifier.java | 26 +++- .../kamax/mxisd/{storage => }/crypto/Key.java | 2 +- .../{storage => }/crypto/KeyAlgorithm.java | 2 +- .../{storage => }/crypto/KeyIdentifier.java | 2 +- .../{storage => }/crypto/KeyManager.java | 2 +- .../mxisd/{storage => }/crypto/KeyType.java | 2 +- .../crypto/RegularKeyIdentifier.java | 2 +- .../mxisd/{storage => }/crypto/Signature.java | 2 +- .../crypto/SignatureManager.java | 17 ++- .../crypto => crypto/ed25519}/Ed25519Key.java | 7 +- .../ed25519}/Ed25519KeyManager.java | 24 ++-- .../ed25519/Ed25519RegularKeyIdentifier.java} | 9 +- .../ed25519}/Ed25519SignatureManager.java | 5 +- .../v1/EphemeralKeyIsValidHandler.java | 4 +- .../handler/identity/v1/KeyGetHandler.java | 6 +- .../identity/v1/RegularKeyIsValidHandler.java | 4 +- .../identity/v1/SignEd25519Handler.java | 2 +- .../identity/v1/SingleLookupHandler.java | 2 +- .../identity/v1/StoreInviteHandler.java | 2 +- .../mxisd/invitation/InvitationManager.java | 2 +- .../mxisd/storage/crypto/FileKeyJson.java | 2 + .../mxisd/storage/crypto/FileKeyStore.java | 53 +++++--- .../kamax/mxisd/storage/crypto/KeyStore.java | 7 +- .../mxisd/storage/crypto/MemoryKeyStore.java | 22 +-- .../test/{storage => }/crypto/KeyTest.java | 2 +- .../crypto/SignatureManagerTest.java | 13 +- .../test/storage/crypto/FileKeyStoreTest.java | 42 ++++++ .../test/storage/crypto/KeyStoreTest.java | 128 ++++++++++++++++++ .../storage/crypto/MemoryKeyStoreTest.java | 33 +++++ 32 files changed, 362 insertions(+), 78 deletions(-) rename src/main/java/io/kamax/mxisd/{storage => }/crypto/GenericKey.java (97%) rename src/main/java/io/kamax/mxisd/{storage => }/crypto/GenericKeyIdentifier.java (65%) rename src/main/java/io/kamax/mxisd/{storage => }/crypto/Key.java (96%) rename src/main/java/io/kamax/mxisd/{storage => }/crypto/KeyAlgorithm.java (95%) rename src/main/java/io/kamax/mxisd/{storage => }/crypto/KeyIdentifier.java (97%) rename src/main/java/io/kamax/mxisd/{storage => }/crypto/KeyManager.java (96%) rename src/main/java/io/kamax/mxisd/{storage => }/crypto/KeyType.java (96%) rename src/main/java/io/kamax/mxisd/{storage => }/crypto/RegularKeyIdentifier.java (96%) rename src/main/java/io/kamax/mxisd/{storage => }/crypto/Signature.java (95%) rename src/main/java/io/kamax/mxisd/{storage => }/crypto/SignatureManager.java (73%) rename src/main/java/io/kamax/mxisd/{storage/crypto => crypto/ed25519}/Ed25519Key.java (86%) rename src/main/java/io/kamax/mxisd/{storage/crypto => crypto/ed25519}/Ed25519KeyManager.java (86%) rename src/main/java/io/kamax/mxisd/{storage/crypto/Ed2219RegularKeyIdentifier.java => crypto/ed25519/Ed25519RegularKeyIdentifier.java} (76%) rename src/main/java/io/kamax/mxisd/{storage/crypto => crypto/ed25519}/Ed25519SignatureManager.java (94%) rename src/test/java/io/kamax/mxisd/test/{storage => }/crypto/KeyTest.java (96%) rename src/test/java/io/kamax/mxisd/test/{storage => }/crypto/SignatureManagerTest.java (86%) create mode 100644 src/test/java/io/kamax/mxisd/test/storage/crypto/FileKeyStoreTest.java create mode 100644 src/test/java/io/kamax/mxisd/test/storage/crypto/KeyStoreTest.java create mode 100644 src/test/java/io/kamax/mxisd/test/storage/crypto/MemoryKeyStoreTest.java diff --git a/src/main/java/io/kamax/mxisd/Mxisd.java b/src/main/java/io/kamax/mxisd/Mxisd.java index 2410f70..6eb47ed 100644 --- a/src/main/java/io/kamax/mxisd/Mxisd.java +++ b/src/main/java/io/kamax/mxisd/Mxisd.java @@ -27,6 +27,9 @@ import io.kamax.mxisd.backend.IdentityStoreSupplier; import io.kamax.mxisd.backend.sql.synapse.Synapse; import io.kamax.mxisd.config.MxisdConfig; import io.kamax.mxisd.crypto.CryptoFactory; +import io.kamax.mxisd.crypto.KeyManager; +import io.kamax.mxisd.crypto.SignatureManager; +import io.kamax.mxisd.crypto.ed25519.Ed25519KeyManager; import io.kamax.mxisd.directory.DirectoryManager; import io.kamax.mxisd.directory.DirectoryProviders; import io.kamax.mxisd.dns.ClientDnsOverwrite; @@ -47,9 +50,6 @@ import io.kamax.mxisd.profile.ProfileProviders; import io.kamax.mxisd.registration.RegistrationManager; import io.kamax.mxisd.session.SessionManager; import io.kamax.mxisd.storage.IStorage; -import io.kamax.mxisd.storage.crypto.Ed25519KeyManager; -import io.kamax.mxisd.storage.crypto.KeyManager; -import io.kamax.mxisd.storage.crypto.SignatureManager; import io.kamax.mxisd.storage.ormlite.OrmLiteSqlStorage; import org.apache.commons.lang.StringUtils; import org.apache.http.impl.client.CloseableHttpClient; diff --git a/src/main/java/io/kamax/mxisd/crypto/CryptoFactory.java b/src/main/java/io/kamax/mxisd/crypto/CryptoFactory.java index 38f1263..253e978 100644 --- a/src/main/java/io/kamax/mxisd/crypto/CryptoFactory.java +++ b/src/main/java/io/kamax/mxisd/crypto/CryptoFactory.java @@ -21,7 +21,11 @@ package io.kamax.mxisd.crypto; import io.kamax.mxisd.config.KeyConfig; -import io.kamax.mxisd.storage.crypto.*; +import io.kamax.mxisd.crypto.ed25519.Ed25519KeyManager; +import io.kamax.mxisd.crypto.ed25519.Ed25519SignatureManager; +import io.kamax.mxisd.storage.crypto.FileKeyStore; +import io.kamax.mxisd.storage.crypto.KeyStore; +import io.kamax.mxisd.storage.crypto.MemoryKeyStore; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/GenericKey.java b/src/main/java/io/kamax/mxisd/crypto/GenericKey.java similarity index 97% rename from src/main/java/io/kamax/mxisd/storage/crypto/GenericKey.java rename to src/main/java/io/kamax/mxisd/crypto/GenericKey.java index 7d59079..685ac2d 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/GenericKey.java +++ b/src/main/java/io/kamax/mxisd/crypto/GenericKey.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto; public class GenericKey implements Key { diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/GenericKeyIdentifier.java b/src/main/java/io/kamax/mxisd/crypto/GenericKeyIdentifier.java similarity index 65% rename from src/main/java/io/kamax/mxisd/storage/crypto/GenericKeyIdentifier.java rename to src/main/java/io/kamax/mxisd/crypto/GenericKeyIdentifier.java index 0390eda..9dda144 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/GenericKeyIdentifier.java +++ b/src/main/java/io/kamax/mxisd/crypto/GenericKeyIdentifier.java @@ -18,7 +18,11 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Objects; public class GenericKeyIdentifier implements KeyIdentifier { @@ -31,7 +35,11 @@ public class GenericKeyIdentifier implements KeyIdentifier { } public GenericKeyIdentifier(KeyType type, String algo, String serial) { - this.type = type; + if (StringUtils.isAnyBlank(algo, serial)) { + throw new IllegalArgumentException("Aglorith and/or Serial cannot be blank"); + } + + this.type = Objects.requireNonNull(type); this.algo = algo; this.serial = serial; } @@ -51,4 +59,18 @@ public class GenericKeyIdentifier implements KeyIdentifier { return serial; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof GenericKeyIdentifier)) return false; + GenericKeyIdentifier that = (GenericKeyIdentifier) o; + return type == that.type && + algo.equals(that.algo) && + serial.equals(that.serial); + } + + @Override + public int hashCode() { + return Objects.hash(type, algo, serial); + } } diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/Key.java b/src/main/java/io/kamax/mxisd/crypto/Key.java similarity index 96% rename from src/main/java/io/kamax/mxisd/storage/crypto/Key.java rename to src/main/java/io/kamax/mxisd/crypto/Key.java index 9a98917..628e237 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/Key.java +++ b/src/main/java/io/kamax/mxisd/crypto/Key.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto; /** * A signing key diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/KeyAlgorithm.java b/src/main/java/io/kamax/mxisd/crypto/KeyAlgorithm.java similarity index 95% rename from src/main/java/io/kamax/mxisd/storage/crypto/KeyAlgorithm.java rename to src/main/java/io/kamax/mxisd/crypto/KeyAlgorithm.java index bb453ee..4e63d35 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/KeyAlgorithm.java +++ b/src/main/java/io/kamax/mxisd/crypto/KeyAlgorithm.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto; public interface KeyAlgorithm { diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/KeyIdentifier.java b/src/main/java/io/kamax/mxisd/crypto/KeyIdentifier.java similarity index 97% rename from src/main/java/io/kamax/mxisd/storage/crypto/KeyIdentifier.java rename to src/main/java/io/kamax/mxisd/crypto/KeyIdentifier.java index db28f25..1954d06 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/KeyIdentifier.java +++ b/src/main/java/io/kamax/mxisd/crypto/KeyIdentifier.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto; /** * Identifying data for a given Key. diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/KeyManager.java b/src/main/java/io/kamax/mxisd/crypto/KeyManager.java similarity index 96% rename from src/main/java/io/kamax/mxisd/storage/crypto/KeyManager.java rename to src/main/java/io/kamax/mxisd/crypto/KeyManager.java index 68a2cbc..a36f70b 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/KeyManager.java +++ b/src/main/java/io/kamax/mxisd/crypto/KeyManager.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto; import java.util.List; diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/KeyType.java b/src/main/java/io/kamax/mxisd/crypto/KeyType.java similarity index 96% rename from src/main/java/io/kamax/mxisd/storage/crypto/KeyType.java rename to src/main/java/io/kamax/mxisd/crypto/KeyType.java index 84565f6..2b63ba2 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/KeyType.java +++ b/src/main/java/io/kamax/mxisd/crypto/KeyType.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto; /** * Types of keys used by an Identity server. diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/RegularKeyIdentifier.java b/src/main/java/io/kamax/mxisd/crypto/RegularKeyIdentifier.java similarity index 96% rename from src/main/java/io/kamax/mxisd/storage/crypto/RegularKeyIdentifier.java rename to src/main/java/io/kamax/mxisd/crypto/RegularKeyIdentifier.java index b1b8721..3990587 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/RegularKeyIdentifier.java +++ b/src/main/java/io/kamax/mxisd/crypto/RegularKeyIdentifier.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto; public class RegularKeyIdentifier extends GenericKeyIdentifier { diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/Signature.java b/src/main/java/io/kamax/mxisd/crypto/Signature.java similarity index 95% rename from src/main/java/io/kamax/mxisd/storage/crypto/Signature.java rename to src/main/java/io/kamax/mxisd/crypto/Signature.java index 9174449..08d5887 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/Signature.java +++ b/src/main/java/io/kamax/mxisd/crypto/Signature.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto; public interface Signature { diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/SignatureManager.java b/src/main/java/io/kamax/mxisd/crypto/SignatureManager.java similarity index 73% rename from src/main/java/io/kamax/mxisd/storage/crypto/SignatureManager.java rename to src/main/java/io/kamax/mxisd/crypto/SignatureManager.java index 316cb2c..bcfdcfa 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/SignatureManager.java +++ b/src/main/java/io/kamax/mxisd/crypto/SignatureManager.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto; import com.google.gson.JsonObject; @@ -26,10 +26,17 @@ import java.nio.charset.StandardCharsets; public interface SignatureManager { + /** + * Sign the message and produce a signatures object that can directly be added to the object being signed. + * + * @param domain The domain under which the signature should be added + * @param message The message to sign + * @return The signatures object + */ JsonObject signMessageGson(String domain, String message); /** - * Sign the canonical form of a JSON object + * Sign the canonical form of a JSON object. * * @param obj The JSON object to canonicalize and sign * @return The signature @@ -37,17 +44,17 @@ public interface SignatureManager { Signature sign(JsonObject obj); /** - * Sign the message, using UTF-8 as decoding character set + * Sign the message, using UTF-8 as decoding character set. * * @param message The UTF-8 encoded message - * @return + * @return The signature */ default Signature sign(String message) { return sign(message.getBytes(StandardCharsets.UTF_8)); } /** - * Sign the data + * Sign the data. * * @param data The data to sign * @return The signature diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/Ed25519Key.java b/src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519Key.java similarity index 86% rename from src/main/java/io/kamax/mxisd/storage/crypto/Ed25519Key.java rename to src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519Key.java index af31552..1416101 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/Ed25519Key.java +++ b/src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519Key.java @@ -18,7 +18,12 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto.ed25519; + +import io.kamax.mxisd.crypto.GenericKeyIdentifier; +import io.kamax.mxisd.crypto.Key; +import io.kamax.mxisd.crypto.KeyAlgorithm; +import io.kamax.mxisd.crypto.KeyIdentifier; public class Ed25519Key implements Key { diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/Ed25519KeyManager.java b/src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519KeyManager.java similarity index 86% rename from src/main/java/io/kamax/mxisd/storage/crypto/Ed25519KeyManager.java rename to src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519KeyManager.java index 2b4dae5..ac64475 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/Ed25519KeyManager.java +++ b/src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519KeyManager.java @@ -18,9 +18,11 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto.ed25519; import io.kamax.matrix.codec.MxBase64; +import io.kamax.mxisd.crypto.*; +import io.kamax.mxisd.storage.crypto.KeyStore; import net.i2p.crypto.eddsa.EdDSAPrivateKey; import net.i2p.crypto.eddsa.EdDSAPublicKey; import net.i2p.crypto.eddsa.KeyPairGenerator; @@ -38,6 +40,7 @@ import java.nio.ByteBuffer; import java.security.KeyPair; import java.time.Instant; import java.util.List; +import java.util.stream.Collectors; public class Ed25519KeyManager implements KeyManager { @@ -51,7 +54,12 @@ public class Ed25519KeyManager implements KeyManager { this.store = store; if (!store.getCurrentKey().isPresent()) { - List keys = store.list(KeyType.Regular); + List keys = store.list(KeyType.Regular).stream() + .map(this::getKey) + .filter(Key::isValid) + .map(Key::getId) + .collect(Collectors.toList()); + if (keys.isEmpty()) { keys.add(generateKey(KeyType.Regular)); } @@ -60,17 +68,17 @@ public class Ed25519KeyManager implements KeyManager { } } - protected String generateId() { + private String generateId() { ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.putLong(Instant.now().toEpochMilli() - 1546297200000L); // TS since 2019-01-01T00:00:00Z to keep IDs short return Base64.encodeBase64URLSafeString(buffer.array()) + RandomStringUtils.randomAlphanumeric(1); } - protected String getPrivateKeyBase64(EdDSAPrivateKey key) { + private String getPrivateKeyBase64(EdDSAPrivateKey key) { return MxBase64.encode(key.getSeed()); } - public EdDSAParameterSpec getKeySpecs() { + EdDSAParameterSpec getKeySpecs() { return keySpecs; } @@ -105,15 +113,15 @@ public class Ed25519KeyManager implements KeyManager { return store.get(id); } - public EdDSAPrivateKeySpec getPrivateKeySpecs(KeyIdentifier id) { + private EdDSAPrivateKeySpec getPrivateKeySpecs(KeyIdentifier id) { return new EdDSAPrivateKeySpec(Base64.decodeBase64(getKey(id).getPrivateKeyBase64()), keySpecs); } - public EdDSAPrivateKey getPrivateKey(KeyIdentifier id) { + EdDSAPrivateKey getPrivateKey(KeyIdentifier id) { return new EdDSAPrivateKey(getPrivateKeySpecs(id)); } - public EdDSAPublicKey getPublicKey(KeyIdentifier id) { + private EdDSAPublicKey getPublicKey(KeyIdentifier id) { EdDSAPrivateKeySpec privKeySpec = getPrivateKeySpecs(id); EdDSAPublicKeySpec pubKeySpec = new EdDSAPublicKeySpec(privKeySpec.getA(), keySpecs); return new EdDSAPublicKey(pubKeySpec); diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/Ed2219RegularKeyIdentifier.java b/src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519RegularKeyIdentifier.java similarity index 76% rename from src/main/java/io/kamax/mxisd/storage/crypto/Ed2219RegularKeyIdentifier.java rename to src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519RegularKeyIdentifier.java index 091728a..e0d5856 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/Ed2219RegularKeyIdentifier.java +++ b/src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519RegularKeyIdentifier.java @@ -18,11 +18,14 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto.ed25519; -public class Ed2219RegularKeyIdentifier extends RegularKeyIdentifier { +import io.kamax.mxisd.crypto.KeyAlgorithm; +import io.kamax.mxisd.crypto.RegularKeyIdentifier; - public Ed2219RegularKeyIdentifier(String serial) { +public class Ed25519RegularKeyIdentifier extends RegularKeyIdentifier { + + public Ed25519RegularKeyIdentifier(String serial) { super(KeyAlgorithm.Ed25519, serial); } diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/Ed25519SignatureManager.java b/src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519SignatureManager.java similarity index 94% rename from src/main/java/io/kamax/mxisd/storage/crypto/Ed25519SignatureManager.java rename to src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519SignatureManager.java index cbb1f1f..dab5a99 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/Ed25519SignatureManager.java +++ b/src/main/java/io/kamax/mxisd/crypto/ed25519/Ed25519SignatureManager.java @@ -18,11 +18,14 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.storage.crypto; +package io.kamax.mxisd.crypto.ed25519; import com.google.gson.JsonObject; import io.kamax.matrix.codec.MxBase64; import io.kamax.matrix.json.MatrixJson; +import io.kamax.mxisd.crypto.KeyIdentifier; +import io.kamax.mxisd.crypto.Signature; +import io.kamax.mxisd.crypto.SignatureManager; import net.i2p.crypto.eddsa.EdDSAEngine; import java.security.InvalidKeyException; diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/EphemeralKeyIsValidHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/EphemeralKeyIsValidHandler.java index d39ccc1..0f70013 100644 --- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/EphemeralKeyIsValidHandler.java +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/EphemeralKeyIsValidHandler.java @@ -20,9 +20,9 @@ package io.kamax.mxisd.http.undertow.handler.identity.v1; +import io.kamax.mxisd.crypto.KeyManager; +import io.kamax.mxisd.crypto.KeyType; import io.kamax.mxisd.http.IsAPIv1; -import io.kamax.mxisd.storage.crypto.KeyManager; -import io.kamax.mxisd.storage.crypto.KeyType; import io.undertow.server.HttpServerExchange; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/KeyGetHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/KeyGetHandler.java index 4a1ac69..8b1de81 100644 --- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/KeyGetHandler.java +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/KeyGetHandler.java @@ -21,11 +21,11 @@ package io.kamax.mxisd.http.undertow.handler.identity.v1; import com.google.gson.JsonObject; +import io.kamax.mxisd.crypto.GenericKeyIdentifier; +import io.kamax.mxisd.crypto.KeyManager; +import io.kamax.mxisd.crypto.KeyType; import io.kamax.mxisd.http.IsAPIv1; import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; -import io.kamax.mxisd.storage.crypto.GenericKeyIdentifier; -import io.kamax.mxisd.storage.crypto.KeyManager; -import io.kamax.mxisd.storage.crypto.KeyType; import io.undertow.server.HttpServerExchange; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RegularKeyIsValidHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RegularKeyIsValidHandler.java index f181ed9..6b5167c 100644 --- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RegularKeyIsValidHandler.java +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/RegularKeyIsValidHandler.java @@ -20,9 +20,9 @@ package io.kamax.mxisd.http.undertow.handler.identity.v1; +import io.kamax.mxisd.crypto.KeyManager; +import io.kamax.mxisd.crypto.KeyType; import io.kamax.mxisd.http.IsAPIv1; -import io.kamax.mxisd.storage.crypto.KeyManager; -import io.kamax.mxisd.storage.crypto.KeyType; import io.undertow.server.HttpServerExchange; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SignEd25519Handler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SignEd25519Handler.java index f76e7f5..8d6dc7e 100644 --- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SignEd25519Handler.java +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SignEd25519Handler.java @@ -26,11 +26,11 @@ import io.kamax.matrix._MatrixID; import io.kamax.matrix.json.GsonUtil; import io.kamax.matrix.json.MatrixJson; import io.kamax.mxisd.config.MxisdConfig; +import io.kamax.mxisd.crypto.SignatureManager; import io.kamax.mxisd.http.IsAPIv1; import io.kamax.mxisd.http.undertow.handler.BasicHttpHandler; import io.kamax.mxisd.invitation.IThreePidInviteReply; import io.kamax.mxisd.invitation.InvitationManager; -import io.kamax.mxisd.storage.crypto.SignatureManager; import io.undertow.server.HttpServerExchange; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SingleLookupHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SingleLookupHandler.java index 8702b5d..d81d38c 100644 --- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SingleLookupHandler.java +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/SingleLookupHandler.java @@ -26,12 +26,12 @@ import io.kamax.matrix.json.GsonUtil; import io.kamax.matrix.json.MatrixJson; import io.kamax.mxisd.config.MxisdConfig; import io.kamax.mxisd.config.ServerConfig; +import io.kamax.mxisd.crypto.SignatureManager; import io.kamax.mxisd.http.IsAPIv1; import io.kamax.mxisd.http.io.identity.SingeLookupReplyJson; import io.kamax.mxisd.lookup.SingleLookupReply; import io.kamax.mxisd.lookup.SingleLookupRequest; import io.kamax.mxisd.lookup.strategy.LookupStrategy; -import io.kamax.mxisd.storage.crypto.SignatureManager; import io.undertow.server.HttpServerExchange; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/StoreInviteHandler.java b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/StoreInviteHandler.java index 1d22ab4..11996a0 100644 --- a/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/StoreInviteHandler.java +++ b/src/main/java/io/kamax/mxisd/http/undertow/handler/identity/v1/StoreInviteHandler.java @@ -26,6 +26,7 @@ import io.kamax.matrix.MatrixID; import io.kamax.matrix._MatrixID; import io.kamax.matrix.json.GsonUtil; import io.kamax.mxisd.config.ServerConfig; +import io.kamax.mxisd.crypto.KeyManager; import io.kamax.mxisd.exception.BadRequestException; import io.kamax.mxisd.http.IsAPIv1; import io.kamax.mxisd.http.io.identity.StoreInviteRequest; @@ -35,7 +36,6 @@ import io.kamax.mxisd.invitation.IThreePidInvite; import io.kamax.mxisd.invitation.IThreePidInviteReply; import io.kamax.mxisd.invitation.InvitationManager; import io.kamax.mxisd.invitation.ThreePidInvite; -import io.kamax.mxisd.storage.crypto.KeyManager; import io.undertow.server.HttpServerExchange; import io.undertow.util.QueryParameterUtils; import org.apache.commons.lang3.StringUtils; diff --git a/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java b/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java index f8004a7..362f867 100644 --- a/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java +++ b/src/main/java/io/kamax/mxisd/invitation/InvitationManager.java @@ -29,6 +29,7 @@ import io.kamax.matrix.json.GsonUtil; import io.kamax.mxisd.config.InvitationConfig; import io.kamax.mxisd.config.MxisdConfig; import io.kamax.mxisd.config.ServerConfig; +import io.kamax.mxisd.crypto.*; import io.kamax.mxisd.dns.FederationDnsOverwrite; import io.kamax.mxisd.exception.BadRequestException; import io.kamax.mxisd.exception.ConfigurationException; @@ -40,7 +41,6 @@ import io.kamax.mxisd.lookup.strategy.LookupStrategy; import io.kamax.mxisd.notification.NotificationManager; import io.kamax.mxisd.profile.ProfileManager; import io.kamax.mxisd.storage.IStorage; -import io.kamax.mxisd.storage.crypto.*; import io.kamax.mxisd.storage.ormlite.dao.ThreePidInviteIO; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/FileKeyJson.java b/src/main/java/io/kamax/mxisd/storage/crypto/FileKeyJson.java index 15164e9..5938a9d 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/FileKeyJson.java +++ b/src/main/java/io/kamax/mxisd/storage/crypto/FileKeyJson.java @@ -20,6 +20,8 @@ package io.kamax.mxisd.storage.crypto; +import io.kamax.mxisd.crypto.Key; + public class FileKeyJson { public static FileKeyJson get(Key key) { diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/FileKeyStore.java b/src/main/java/io/kamax/mxisd/storage/crypto/FileKeyStore.java index 025353d..7ced08b 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/FileKeyStore.java +++ b/src/main/java/io/kamax/mxisd/storage/crypto/FileKeyStore.java @@ -23,6 +23,7 @@ package io.kamax.mxisd.storage.crypto; import com.google.gson.JsonObject; import io.kamax.matrix.crypto.KeyFileStore; import io.kamax.matrix.json.GsonUtil; +import io.kamax.mxisd.crypto.*; import io.kamax.mxisd.exception.ObjectNotFoundException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; @@ -54,31 +55,39 @@ public class FileKeyStore implements KeyStore { base = new File(path).getAbsoluteFile().toString(); File f = new File(base); - if (f.exists() && f.isFile()) { + if (!f.exists()) { try { - log.info("Found old key store format at {}, migrating...", base); - File oldStorePath = new File(f.toString() + ".backup-before-migration"); - FileUtils.moveFile(f, oldStorePath); FileUtils.forceMkdir(f); - - - String privKey = new KeyFileStore(oldStorePath.toString()).load().orElse(""); - if (StringUtils.isBlank(privKey)) { - log.info("Empty file, nothing to migrate"); - } else { - // We ensure this is valid Base64 data before migrating - Base64.decodeBase64(privKey); - - // We store the new key - add(new GenericKey(new GenericKeyIdentifier(KeyType.Regular, KeyAlgorithm.Ed25519, "0"), true, privKey)); - - log.info("Store migrated to new directory format"); - } } catch (IOException e) { - throw new RuntimeException("Unable to migrate store from old single file format to new directory format", e); + throw new RuntimeException("Unable to create key store"); } } else { - log.info("Key store is already in directory format"); + if (f.isFile()) { + try { + log.info("Found old key store format at {}, migrating...", base); + File oldStorePath = new File(f.toString() + ".backup-before-migration"); + FileUtils.moveFile(f, oldStorePath); + FileUtils.forceMkdir(f); + + + String privKey = new KeyFileStore(oldStorePath.toString()).load().orElse(""); + if (StringUtils.isBlank(privKey)) { + log.info("Empty file, nothing to migrate"); + } else { + // We ensure this is valid Base64 data before migrating + Base64.decodeBase64(privKey); + + // We store the new key + add(new GenericKey(new GenericKeyIdentifier(KeyType.Regular, KeyAlgorithm.Ed25519, "0"), true, privKey)); + + log.info("Store migrated to new directory format"); + } + } catch (IOException e) { + throw new RuntimeException("Unable to migrate store from old single file format to new directory format", e); + } + } else { + log.info("Key store is already in directory format"); + } } if (!f.isDirectory()) { @@ -207,6 +216,10 @@ public class FileKeyStore implements KeyStore { @Override public void setCurrentKey(KeyIdentifier id) throws IllegalArgumentException { + if (!has(id)) { + throw new IllegalArgumentException("Key " + id.getType() + ":" + id.getAlgorithm() + ":" + id.getSerial() + " is not known to the store"); + } + JsonObject json = new JsonObject(); json.addProperty("type", id.getType().name()); json.addProperty("algo", id.getAlgorithm()); diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/KeyStore.java b/src/main/java/io/kamax/mxisd/storage/crypto/KeyStore.java index 72c24b3..23c7277 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/KeyStore.java +++ b/src/main/java/io/kamax/mxisd/storage/crypto/KeyStore.java @@ -20,6 +20,9 @@ package io.kamax.mxisd.storage.crypto; +import io.kamax.mxisd.crypto.Key; +import io.kamax.mxisd.crypto.KeyIdentifier; +import io.kamax.mxisd.crypto.KeyType; import io.kamax.mxisd.exception.ObjectNotFoundException; import java.util.List; @@ -84,9 +87,9 @@ public interface KeyStore { * Store the information of which key is the current signing key * * @param id The key identifier - * @throws ObjectNotFoundException If the key is not known to the store + * @throws IllegalArgumentException If the key is not known to the store */ - void setCurrentKey(KeyIdentifier id) throws ObjectNotFoundException; + void setCurrentKey(KeyIdentifier id) throws IllegalArgumentException; /** * Retrieve the previously stored information of which key is the current signing key, if any diff --git a/src/main/java/io/kamax/mxisd/storage/crypto/MemoryKeyStore.java b/src/main/java/io/kamax/mxisd/storage/crypto/MemoryKeyStore.java index d2d8419..f67df68 100644 --- a/src/main/java/io/kamax/mxisd/storage/crypto/MemoryKeyStore.java +++ b/src/main/java/io/kamax/mxisd/storage/crypto/MemoryKeyStore.java @@ -20,18 +20,18 @@ package io.kamax.mxisd.storage.crypto; +import io.kamax.mxisd.crypto.*; import io.kamax.mxisd.exception.ObjectNotFoundException; -import org.apache.commons.lang3.StringUtils; import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class MemoryKeyStore implements KeyStore { - private Map>> keys = new ConcurrentHashMap<>(); + private Map>> keys = new ConcurrentHashMap<>(); private KeyIdentifier current; - private Map getMap(KeyType type, String algo) { + private Map getMap(KeyType type, String algo) { return keys.computeIfAbsent(type, k -> new ConcurrentHashMap<>()).computeIfAbsent(algo, k -> new ConcurrentHashMap<>()); } @@ -56,23 +56,23 @@ public class MemoryKeyStore implements KeyStore { @Override public Key get(KeyIdentifier id) throws ObjectNotFoundException { - String data = getMap(id.getType(), id.getAlgorithm()).get(id.getSerial()); + FileKeyJson data = getMap(id.getType(), id.getAlgorithm()).get(id.getSerial()); if (Objects.isNull(data)) { throw new ObjectNotFoundException("Key", id.getType() + ":" + id.getAlgorithm() + ":" + id.getSerial()); } - return new GenericKey(new GenericKeyIdentifier(id), StringUtils.isEmpty(data), data); + return new GenericKey(new GenericKeyIdentifier(id), data.isValid(), data.getKey()); } private void set(Key key) { - String data = key.isValid() ? key.getPrivateKeyBase64() : ""; + FileKeyJson data = FileKeyJson.get(key); getMap(key.getId().getType(), key.getId().getAlgorithm()).put(key.getId().getSerial(), data); } @Override public void add(Key key) throws IllegalStateException { if (has(key.getId())) { - throw new IllegalStateException(); + throw new IllegalStateException("Key " + key.getId().getId() + " already exists"); } set(key); @@ -89,13 +89,17 @@ public class MemoryKeyStore implements KeyStore { @Override public void delete(KeyIdentifier id) throws ObjectNotFoundException { + if (!has(id)) { + throw new ObjectNotFoundException("Key", id.getType() + ":" + id.getAlgorithm() + ":" + id.getSerial()); + } + keys.computeIfAbsent(id.getType(), k -> new ConcurrentHashMap<>()).computeIfAbsent(id.getAlgorithm(), k -> new ConcurrentHashMap<>()).remove(id.getSerial()); } @Override - public void setCurrentKey(KeyIdentifier id) throws ObjectNotFoundException { + public void setCurrentKey(KeyIdentifier id) throws IllegalArgumentException { if (!has(id)) { - throw new ObjectNotFoundException("Key", id.getType() + ":" + id.getAlgorithm() + ":" + id.getSerial()); + throw new IllegalArgumentException("Key " + id.getType() + ":" + id.getAlgorithm() + ":" + id.getSerial() + " is not known to the store"); } current = id; diff --git a/src/test/java/io/kamax/mxisd/test/storage/crypto/KeyTest.java b/src/test/java/io/kamax/mxisd/test/crypto/KeyTest.java similarity index 96% rename from src/test/java/io/kamax/mxisd/test/storage/crypto/KeyTest.java rename to src/test/java/io/kamax/mxisd/test/crypto/KeyTest.java index 4c5a365..aa0fd34 100644 --- a/src/test/java/io/kamax/mxisd/test/storage/crypto/KeyTest.java +++ b/src/test/java/io/kamax/mxisd/test/crypto/KeyTest.java @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.test.storage.crypto; +package io.kamax.mxisd.test.crypto; public class KeyTest { diff --git a/src/test/java/io/kamax/mxisd/test/storage/crypto/SignatureManagerTest.java b/src/test/java/io/kamax/mxisd/test/crypto/SignatureManagerTest.java similarity index 86% rename from src/test/java/io/kamax/mxisd/test/storage/crypto/SignatureManagerTest.java rename to src/test/java/io/kamax/mxisd/test/crypto/SignatureManagerTest.java index 9c4a3ac..06d2fed 100644 --- a/src/test/java/io/kamax/mxisd/test/storage/crypto/SignatureManagerTest.java +++ b/src/test/java/io/kamax/mxisd/test/crypto/SignatureManagerTest.java @@ -18,12 +18,19 @@ * along with this program. If not, see . */ -package io.kamax.mxisd.test.storage.crypto; +package io.kamax.mxisd.test.crypto; import com.google.gson.JsonObject; import io.kamax.matrix.json.GsonUtil; import io.kamax.matrix.json.MatrixJson; -import io.kamax.mxisd.storage.crypto.*; +import io.kamax.mxisd.crypto.Signature; +import io.kamax.mxisd.crypto.SignatureManager; +import io.kamax.mxisd.crypto.ed25519.Ed25519Key; +import io.kamax.mxisd.crypto.ed25519.Ed25519KeyManager; +import io.kamax.mxisd.crypto.ed25519.Ed25519RegularKeyIdentifier; +import io.kamax.mxisd.crypto.ed25519.Ed25519SignatureManager; +import io.kamax.mxisd.storage.crypto.KeyStore; +import io.kamax.mxisd.storage.crypto.MemoryKeyStore; import org.junit.BeforeClass; import org.junit.Test; @@ -36,7 +43,7 @@ public class SignatureManagerTest { private static SignatureManager signMgr; private static SignatureManager build(String keySeed) { - Ed25519Key key = new Ed25519Key(new Ed2219RegularKeyIdentifier("0"), keySeed); + Ed25519Key key = new Ed25519Key(new Ed25519RegularKeyIdentifier("0"), keySeed); KeyStore store = new MemoryKeyStore(); store.add(key); diff --git a/src/test/java/io/kamax/mxisd/test/storage/crypto/FileKeyStoreTest.java b/src/test/java/io/kamax/mxisd/test/storage/crypto/FileKeyStoreTest.java new file mode 100644 index 0000000..fdfed23 --- /dev/null +++ b/src/test/java/io/kamax/mxisd/test/storage/crypto/FileKeyStoreTest.java @@ -0,0 +1,42 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2019 Kamax Sàrl + * + * https://www.kamax.io/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package io.kamax.mxisd.test.storage.crypto; + +import io.kamax.mxisd.storage.crypto.FileKeyStore; +import io.kamax.mxisd.storage.crypto.KeyStore; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +public class FileKeyStoreTest extends KeyStoreTest { + + @Override + public KeyStore create() throws IOException { + String path = FileUtils.getTempDirectoryPath() + + "/mxisd-test-key-store-" + + UUID.randomUUID().toString().replace("-", ""); + FileUtils.forceDeleteOnExit(new File(path)); + return new FileKeyStore(path); + } + +} diff --git a/src/test/java/io/kamax/mxisd/test/storage/crypto/KeyStoreTest.java b/src/test/java/io/kamax/mxisd/test/storage/crypto/KeyStoreTest.java new file mode 100644 index 0000000..dd64dcf --- /dev/null +++ b/src/test/java/io/kamax/mxisd/test/storage/crypto/KeyStoreTest.java @@ -0,0 +1,128 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2019 Kamax Sàrl + * + * https://www.kamax.io/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package io.kamax.mxisd.test.storage.crypto; + +import io.kamax.mxisd.crypto.*; +import io.kamax.mxisd.exception.ObjectNotFoundException; +import io.kamax.mxisd.storage.crypto.KeyStore; +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.Before; +import org.junit.Test; + +import java.util.Optional; + +import static org.junit.Assert.*; + +public abstract class KeyStoreTest { + + private KeyStore store; + + public abstract KeyStore create() throws Exception; + + private Key generateRandomKey() { + KeyIdentifier keyId = new GenericKeyIdentifier(KeyType.Regular, "algo", RandomStringUtils.randomAlphanumeric(6)); + return new GenericKey(keyId, true, RandomStringUtils.randomAlphanumeric(48)); + } + + @Before + public void before() throws Exception { + store = create(); + } + + @Test + public void isEmptyAfterCreate() { + assertTrue(store.list().isEmpty()); + assertFalse(store.getCurrentKey().isPresent()); + } + + @Test + public void add() { + Key key = generateRandomKey(); + KeyIdentifier keyId = key.getId(); + + store.add(key); + + Key keyFromStore = store.get(keyId); + assertEquals(key.getId(), keyFromStore.getId()); + assertEquals(key.getPrivateKeyBase64(), keyFromStore.getPrivateKeyBase64()); + assertEquals(key.isValid(), keyFromStore.isValid()); + + assertTrue(store.list().contains(keyId)); + assertTrue(store.list(keyId.getType()).contains(keyId)); + } + + @Test(expected = IllegalStateException.class) + public void addDuplicate() { + Key key = generateRandomKey(); + store.add(key); + store.add(key); + } + + @Test + public void update() { + Key key = generateRandomKey(); + store.add(key); + + Key keyUpdated = new GenericKey(key.getId(), !key.isValid(), key.getPrivateKeyBase64()); + store.update(keyUpdated); + + Key keyFromStore = store.get(key.getId()); + assertEquals(key.getId(), keyFromStore.getId()); + assertEquals(key.getPrivateKeyBase64(), keyFromStore.getPrivateKeyBase64()); + assertEquals(key.isValid(), !keyFromStore.isValid()); + } + + @Test(expected = ObjectNotFoundException.class) + public void updateNonExisting() { + store.update(generateRandomKey()); + } + + @Test + public void delete() { + Key key = generateRandomKey(); + store.add(key); + + store.delete(key.getId()); + assertFalse(store.list().contains(key.getId())); + assertFalse(store.list(key.getId().getType()).contains(key.getId())); + } + + @Test(expected = ObjectNotFoundException.class) + public void deleteNonExisting() { + store.delete(generateRandomKey().getId()); + } + + @Test + public void setCurrentKey() { + Key key = generateRandomKey(); + store.add(key); + store.setCurrentKey(key.getId()); + Optional currentKey = store.getCurrentKey(); + assertTrue(currentKey.isPresent()); + assertEquals(currentKey.get(), key.getId()); + } + + @Test(expected = IllegalArgumentException.class) + public void setCurrentKeyNonExisting() { + store.setCurrentKey(generateRandomKey().getId()); + } + +} diff --git a/src/test/java/io/kamax/mxisd/test/storage/crypto/MemoryKeyStoreTest.java b/src/test/java/io/kamax/mxisd/test/storage/crypto/MemoryKeyStoreTest.java new file mode 100644 index 0000000..af918da --- /dev/null +++ b/src/test/java/io/kamax/mxisd/test/storage/crypto/MemoryKeyStoreTest.java @@ -0,0 +1,33 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2019 Kamax Sàrl + * + * https://www.kamax.io/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package io.kamax.mxisd.test.storage.crypto; + +import io.kamax.mxisd.storage.crypto.KeyStore; +import io.kamax.mxisd.storage.crypto.MemoryKeyStore; + +public class MemoryKeyStoreTest extends KeyStoreTest { + + @Override + public KeyStore create() { + return new MemoryKeyStore(); + } + +}