You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/06/17 11:04:37 UTC

[james-project] 05/09: JAMES-2146 Refactor Jmap signature handler

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 41553be8cde4501ce16de1bced01e9359d68e61e
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu Jun 6 11:05:11 2019 +0700

    JAMES-2146 Refactor Jmap signature handler
---
 .../james/jmap/crypto/JamesSignatureHandler.java   | 42 ++++---------------
 ...ider.java => JamesSignatureHandlerFixture.java} | 48 +++++-----------------
 .../jmap/crypto/JamesSignatureHandlerTest.java     | 18 +-------
 .../james/jmap/crypto/SecurityKeyLoaderTest.java   | 11 +----
 .../james/jmap/crypto/SignedTokenFactoryTest.java  |  3 +-
 .../james/jmap/crypto/SignedTokenManagerTest.java  |  3 +-
 6 files changed, 24 insertions(+), 101 deletions(-)

diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/JamesSignatureHandler.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/JamesSignatureHandler.java
index 82ee210..69b2441 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/JamesSignatureHandler.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/crypto/JamesSignatureHandler.java
@@ -19,24 +19,14 @@
 
 package org.apache.james.jmap.crypto;
 
-import java.io.InputStream;
 import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
 import java.security.Signature;
 import java.security.SignatureException;
-import java.security.cert.Certificate;
 import java.util.Base64;
-import java.util.Optional;
 
 import javax.inject.Inject;
 
-import org.apache.james.filesystem.api.FileSystem;
-import org.apache.james.jmap.JMAPConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,39 +37,21 @@ public class JamesSignatureHandler implements SignatureHandler {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(JamesSignatureHandler.class);
 
-    public static final String ALIAS = "james";
     public static final String ALGORITHM = "SHA1withRSA";
-    public static final String JKS = "JKS";
 
-    private final FileSystem fileSystem;
-    private final JMAPConfiguration jmapConfiguration;
+    private final SecurityKeyLoader keyLoader;
 
-    private PrivateKey privateKey;
-    private PublicKey publicKey;
+    private AsymmetricKeys securityKeys;
 
 
     @Inject
-    @VisibleForTesting JamesSignatureHandler(FileSystem fileSystem, JMAPConfiguration jmapConfiguration) {
-        this.fileSystem = fileSystem;
-        this.jmapConfiguration = jmapConfiguration;
+    @VisibleForTesting JamesSignatureHandler(SecurityKeyLoader keyLoader) {
+        this.keyLoader = keyLoader;
     }
 
     @Override
     public void init() throws Exception {
-        KeyStore keystore = KeyStore.getInstance(JKS);
-        InputStream fis = fileSystem.getResource(jmapConfiguration.getKeystore());
-        char[] secret = jmapConfiguration.getSecret().toCharArray();
-        keystore.load(fis, secret);
-        Certificate aliasCertificate = Optional
-                .ofNullable(keystore.getCertificate(ALIAS))
-                .orElseThrow(() -> new KeyStoreException("Alias '" + ALIAS + "' keystore can't be found"));
-
-        publicKey = aliasCertificate.getPublicKey();
-        Key key = keystore.getKey(ALIAS, secret);
-        if (! (key instanceof PrivateKey)) {
-            throw new KeyStoreException("Provided key is not a PrivateKey");
-        }
-        privateKey = (PrivateKey) key;
+        securityKeys = keyLoader.load();
     }
 
     @Override
@@ -87,7 +59,7 @@ public class JamesSignatureHandler implements SignatureHandler {
         Preconditions.checkNotNull(source);
         try {
             Signature javaSignature = Signature.getInstance(ALGORITHM);
-            javaSignature.initSign(privateKey);
+            javaSignature.initSign(securityKeys.getPrivateKey());
             javaSignature.update(source.getBytes());
             return Base64.getEncoder().encodeToString(javaSignature.sign());
         } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
@@ -101,7 +73,7 @@ public class JamesSignatureHandler implements SignatureHandler {
         Preconditions.checkNotNull(signature);
         try {
             Signature javaSignature = Signature.getInstance(ALGORITHM);
-            javaSignature.initVerify(publicKey);
+            javaSignature.initVerify(securityKeys.getPublicKey());
             javaSignature.update(source.getBytes());
             return javaSignature.verify(Base64.getDecoder().decode(signature));
         } catch (NoSuchAlgorithmException | InvalidKeyException e) {
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerFixture.java
similarity index 58%
rename from server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java
rename to server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerFixture.java
index c531581..392f50f 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerProvider.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerFixture.java
@@ -19,19 +19,13 @@
 
 package org.apache.james.jmap.crypto;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.Optional;
 
-import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.jmap.JMAPConfiguration;
-import org.apache.james.jmap.JMAPConfiguration.Builder;
 
-public class JamesSignatureHandlerProvider {
+class JamesSignatureHandlerFixture {
 
-    private static final String JWT_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" +
+    static final String JWT_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" +
         "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtlChO/nlVP27MpdkG0Bh\n" +
         "16XrMRf6M4NeyGa7j5+1UKm42IKUf3lM28oe82MqIIRyvskPc11NuzSor8HmvH8H\n" +
         "lhDs5DyJtx2qp35AT0zCqfwlaDnlDc/QDlZv1CoRZGpQk1Inyh6SbZwYpxxwh0fi\n" +
@@ -41,41 +35,19 @@ public class JamesSignatureHandlerProvider {
         "kwIDAQAB\n" +
         "-----END PUBLIC KEY-----";
 
-    public JamesSignatureHandlerProvider() {
-    }
-
-    public JamesSignatureHandler provide() throws Exception {
-        JamesSignatureHandler signatureHandler = new JamesSignatureHandler(newFileSystem(),
-                newConfigurationBuilder().build());
-        signatureHandler.init();
-        return signatureHandler;
-    }
+    static JamesSignatureHandler defaultSignatureHandler() {
 
-    public static Builder newConfigurationBuilder() {
-        return JMAPConfiguration.builder()
+        JMAPConfiguration jmapConfiguration = JMAPConfiguration.builder()
             .enable()
+            .jwtPublicKeyPem(Optional.of(JWT_PUBLIC_KEY))
             .keystore("keystore")
             .secret("james72laBalle")
-            .jwtPublicKeyPem(Optional.of(JWT_PUBLIC_KEY));
-    }
-
-    public static FileSystem newFileSystem() {
-        return new FileSystem() {
-            @Override
-            public InputStream getResource(String url) throws IOException {
-                return ClassLoader.getSystemResourceAsStream(url);
-            }
+            .build();
 
-            @Override
-            public File getFile(String fileURL) throws FileNotFoundException {
-                return null;
-            }
+        SecurityKeyLoader loader = new SecurityKeyLoader(
+            new ClassLoaderFileSystem(),
+            jmapConfiguration);
 
-            @Override
-            public File getBasedir() throws FileNotFoundException {
-                return null;
-            }
-        };
+        return new JamesSignatureHandler(loader);
     }
-
 }
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerTest.java
index 8dc44de..5b3e4a2 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/JamesSignatureHandlerTest.java
@@ -21,9 +21,6 @@ package org.apache.james.jmap.crypto;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import java.security.KeyStoreException;
-
-import org.apache.james.jmap.JMAPConfiguration;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -37,19 +34,8 @@ public class JamesSignatureHandlerTest {
 
     @Before
     public void setUp() throws Exception {
-       signatureHandler = new JamesSignatureHandlerProvider().provide();
-    }
-
-    @Test(expected = KeyStoreException.class)
-    public void initShouldThrowOnUnknownKeystore() throws Exception {
-        JMAPConfiguration jmapConfiguration = JamesSignatureHandlerProvider.newConfigurationBuilder()
-            .keystore("badAliasKeystore")
-            .secret("password")
-            .build();
-
-        JamesSignatureHandler signatureHandler = new JamesSignatureHandler(JamesSignatureHandlerProvider.newFileSystem(),
-                jmapConfiguration);
-        signatureHandler.init();
+       signatureHandler = JamesSignatureHandlerFixture.defaultSignatureHandler();
+       signatureHandler.init();
     }
 
     @Test
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SecurityKeyLoaderTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SecurityKeyLoaderTest.java
index 63c1acb..152f672 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SecurityKeyLoaderTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SecurityKeyLoaderTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.james.jmap.crypto;
 
+import static org.apache.james.jmap.crypto.JamesSignatureHandlerFixture.JWT_PUBLIC_KEY;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
@@ -31,16 +32,6 @@ import org.junit.jupiter.api.Test;
 
 class SecurityKeyLoaderTest {
 
-    private static final String JWT_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" +
-        "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtlChO/nlVP27MpdkG0Bh\n" +
-        "16XrMRf6M4NeyGa7j5+1UKm42IKUf3lM28oe82MqIIRyvskPc11NuzSor8HmvH8H\n" +
-        "lhDs5DyJtx2qp35AT0zCqfwlaDnlDc/QDlZv1CoRZGpQk1Inyh6SbZwYpxxwh0fi\n" +
-        "+d/4RpE3LBVo8wgOaXPylOlHxsDizfkL8QwXItyakBfMO6jWQRrj7/9WDhGf4Hi+\n" +
-        "GQur1tPGZDl9mvCoRHjFrD5M/yypIPlfMGWFVEvV5jClNMLAQ9bYFuOc7H1fEWw6\n" +
-        "U1LZUUbJW9/CH45YXz82CYqkrfbnQxqRb2iVbVjs/sHopHd1NTiCfUtwvcYJiBVj\n" +
-        "kwIDAQAB\n" +
-        "-----END PUBLIC KEY-----";
-
     @Test
     void loadShouldThrowWhenWrongKeystore() throws Exception {
         JMAPConfiguration jmapConfiguration = JMAPConfiguration.builder()
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenFactoryTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenFactoryTest.java
index dfe8c18..12d8aa9 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenFactoryTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenFactoryTest.java
@@ -39,7 +39,8 @@ public class SignedTokenFactoryTest {
 
     @Before
     public void setUp() throws Exception {
-        JamesSignatureHandler signatureHandler = new JamesSignatureHandlerProvider().provide();
+        JamesSignatureHandler signatureHandler = JamesSignatureHandlerFixture.defaultSignatureHandler();
+        signatureHandler.init();
         zonedDateTimeProvider = new FixedDateZonedDateTimeProvider();
         toKenFactory = new SignedTokenFactory(signatureHandler, zonedDateTimeProvider);
     }
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenManagerTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenManagerTest.java
index b31f0df..6614fde 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenManagerTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/crypto/SignedTokenManagerTest.java
@@ -44,7 +44,8 @@ public class SignedTokenManagerTest {
 
     @Before
     public void setUp() throws Exception {
-        JamesSignatureHandler signatureHandler = new JamesSignatureHandlerProvider().provide();
+        JamesSignatureHandler signatureHandler = JamesSignatureHandlerFixture.defaultSignatureHandler();
+        signatureHandler.init();
         zonedDateTimeProvider = new FixedDateZonedDateTimeProvider();
         tokenManager = new SignedTokenManager(signatureHandler, zonedDateTimeProvider);
         tokenFactory = new SignedTokenFactory(signatureHandler, zonedDateTimeProvider);


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org