You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2022/12/12 16:01:40 UTC

[commons-crypto] branch master updated: Refactor duplicate code

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

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-crypto.git


The following commit(s) were added to refs/heads/master by this push:
     new 05969be  Refactor duplicate code
05969be is described below

commit 05969beb9099e14498f597fe55ff6413fee07ae8
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Mon Dec 12 11:01:36 2022 -0500

    Refactor duplicate code
---
 .../org/apache/commons/crypto/cipher/OpenSsl.java  | 80 ++----------------
 .../commons/crypto/jna/OpenSslJnaCipher.java       | 86 +++----------------
 .../org/apache/commons/crypto/utils/Padding.java   | 44 ++++++++++
 .../commons/crypto/utils/Transformation.java       | 97 ++++++++++++++++++++++
 4 files changed, 156 insertions(+), 151 deletions(-)

diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java b/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java
index 1906719..5c58c2d 100644
--- a/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java
+++ b/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java
@@ -21,7 +21,6 @@ import java.nio.ByteBuffer;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.NoSuchAlgorithmException;
 import java.security.spec.AlgorithmParameterSpec;
-import java.util.StringTokenizer;
 
 import javax.crypto.BadPaddingException;
 import javax.crypto.IllegalBlockSizeException;
@@ -29,6 +28,8 @@ import javax.crypto.NoSuchPaddingException;
 import javax.crypto.ShortBufferException;
 
 import org.apache.commons.crypto.Crypto;
+import org.apache.commons.crypto.utils.Padding;
+import org.apache.commons.crypto.utils.Transformation;
 import org.apache.commons.crypto.utils.Utils;
 
 /**
@@ -37,8 +38,6 @@ import org.apache.commons.crypto.utils.Utils;
  */
 final class OpenSsl {
 
-    private static final String TRANSFORMATION_DELIM = "/";
-
     // Mode constant defined by OpenSsl JNI
     public static final int ENCRYPT_MODE = 1;
     public static final int DECRYPT_MODE = 0;
@@ -66,25 +65,6 @@ final class OpenSsl {
         }
     }
 
-    private enum Padding {
-        NoPadding, PKCS5Padding;
-
-        /**
-         * Gets the Padding instance.
-         *
-         * @param padding the padding.
-         * @return the value of Padding.
-         * @throws NoSuchPaddingException if the padding is not available.
-         */
-        static int get(final String padding) throws NoSuchPaddingException {
-            try {
-                return Padding.valueOf(padding).ordinal();
-            } catch (final Exception e) {
-                throw new NoSuchPaddingException("Algorithm not supported: " + padding);
-            }
-        }
-    }
-
     private static final Throwable loadingFailureReason;
 
     static {
@@ -145,63 +125,13 @@ final class OpenSsl {
         if (loadingFailureReason != null) {
             throw new IllegalStateException(loadingFailureReason);
         }
-        final Transform transform = tokenizeTransformation(transformation);
-        final int algorithmMode = AlgorithmMode.get(transform.algorithm, transform.mode);
-        final int padding = Padding.get(transform.padding);
+        final Transformation transform = Transformation.parse(transformation);
+        final int algorithmMode = AlgorithmMode.get(transform.getAlgorithm(), transform.getMode());
+        final int padding = Padding.get(transform.getPadding());
         final long context = OpenSslNative.initContext(algorithmMode, padding);
         return new OpenSsl(context, algorithmMode, padding);
     }
 
-    /** Nested class for algorithm, mode and padding. */
-    private static class Transform {
-        final String algorithm;
-        final String mode;
-        final String padding;
-
-        /**
-         * Constructs a {@link Transform} based on the algorithm, mode and padding.
-         *
-         * @param algorithm the algorithm
-         * @param mode the mode.
-         * @param padding the padding.
-         */
-        public Transform(final String algorithm, final String mode, final String padding) {
-            this.algorithm = algorithm;
-            this.mode = mode;
-            this.padding = padding;
-        }
-    }
-
-    /**
-     * Gets the tokens of transformation.
-     *
-     * @param transformation the transformation.
-     * @return the {@link Transform} instance.
-     * @throws NoSuchAlgorithmException if the transformation is null.
-     */
-    private static Transform tokenizeTransformation(final String transformation)
-            throws NoSuchAlgorithmException {
-        if (transformation == null) {
-            throw new NoSuchAlgorithmException("No transformation given.");
-        }
-
-        //
-        // Array containing the components of a Cipher transformation: index 0:
-        // algorithm (e.g., AES) index 1: mode (e.g., CTR) index 2: padding
-        // (e.g., NoPadding)
-        //
-        final String[] parts = new String[3];
-        int count = 0;
-        final StringTokenizer parser = new StringTokenizer(transformation, TRANSFORMATION_DELIM);
-        while (parser.hasMoreTokens() && count < 3) {
-            parts[count++] = parser.nextToken().trim();
-        }
-        if (count != 3 || parser.hasMoreTokens()) {
-            throw new NoSuchAlgorithmException("Invalid transformation format: " + transformation);
-        }
-        return new Transform(parts[0], parts[1], parts[2]);
-    }
-
     /**
      * Initializes this cipher with a key and IV.
      *
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java b/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java
index 86afd11..e1894ec 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java
@@ -30,12 +30,13 @@ import java.util.Properties;
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
 import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
 import javax.crypto.ShortBufferException;
 import javax.crypto.spec.IvParameterSpec;
 
 import org.apache.commons.crypto.cipher.CryptoCipher;
 import org.apache.commons.crypto.cipher.CryptoCipherFactory;
+import org.apache.commons.crypto.utils.Padding;
+import org.apache.commons.crypto.utils.Transformation;
 
 import com.sun.jna.NativeLong;
 import com.sun.jna.ptr.PointerByReference;
@@ -47,7 +48,7 @@ class OpenSslJnaCipher implements CryptoCipher {
 
     private PointerByReference algo;
     private final PointerByReference context;
-    private final AlgorithmMode algMode;
+    private final AlgorithmMode algorithmMode;
     private final int padding;
     private final String transformation;
     private final int IV_LENGTH = 16;
@@ -65,14 +66,14 @@ class OpenSslJnaCipher implements CryptoCipher {
             throw new GeneralSecurityException("Could not enable JNA access", OpenSslJna.initialisationError());
         }
         this.transformation = transformation;
-        final Transform transform = tokenizeTransformation(transformation);
-        algMode = AlgorithmMode.get(transform.algorithm, transform.mode);
+        final Transformation transform = Transformation.parse(transformation);
+        algorithmMode = AlgorithmMode.get(transform.getAlgorithm(), transform.getMode());
 
-        if (algMode != AlgorithmMode.AES_CBC && algMode != AlgorithmMode.AES_CTR) {
-            throw new GeneralSecurityException("unknown algorithm " + transform.algorithm + "_" + transform.mode);
+        if (algorithmMode != AlgorithmMode.AES_CBC && algorithmMode != AlgorithmMode.AES_CTR) {
+            throw new GeneralSecurityException("unknown algorithm " + transform.getAlgorithm() + "_" + transform.getMode());
         }
 
-        padding = Padding.get(transform.padding);
+        padding = Padding.get(transform.getPadding());
         context = OpenSslNativeJna.EVP_CIPHER_CTX_new();
 
     }
@@ -103,12 +104,12 @@ class OpenSslJnaCipher implements CryptoCipher {
         }
         iv = ((IvParameterSpec) params).getIV();
 
-        if ((algMode == AlgorithmMode.AES_CBC || algMode == AlgorithmMode.AES_CTR) && iv.length != IV_LENGTH) {
+        if ((algorithmMode == AlgorithmMode.AES_CBC || algorithmMode == AlgorithmMode.AES_CTR) && iv.length != IV_LENGTH) {
             throw new InvalidAlgorithmParameterException("Wrong IV length: must be 16 bytes long");
         }
         final int keyEncodedLength = key.getEncoded().length;
 
-        if (algMode == AlgorithmMode.AES_CBC) {
+        if (algorithmMode == AlgorithmMode.AES_CBC) {
             switch (keyEncodedLength) {
             case 16:
                 algo = OpenSslNativeJna.EVP_aes_128_cbc();
@@ -342,51 +343,6 @@ class OpenSslJnaCipher implements CryptoCipher {
         }
     }
 
-    // TODO DUPLICATED CODE, needs cleanup
-    /** Nested class for algorithm, mode and padding. */
-    private static class Transform {
-        final String algorithm;
-        final String mode;
-        final String padding;
-
-        /**
-         * Constructor of Transform.
-         *
-         * @param algorithm the algorithm name
-         * @param mode      the mode name
-         * @param padding   the padding name
-         */
-        public Transform(final String algorithm, final String mode, final String padding) {
-            this.algorithm = algorithm;
-            this.mode = mode;
-            this.padding = padding;
-        }
-    }
-
-    /**
-     * Tokenizes a transformation.
-     *
-     * @param transformation current transformation
-     * @return the Transform
-     * @throws NoSuchAlgorithmException if the algorithm is not supported
-     */
-    private static Transform tokenizeTransformation(final String transformation) throws NoSuchAlgorithmException {
-        if (transformation == null) {
-            throw new NoSuchAlgorithmException("No transformation given.");
-        }
-
-        //
-        // Array containing the components of a Cipher transformation: index 0:
-        // algorithm (e.g., AES) index 1: mode (e.g., CTR) index 2: padding (e.g.,
-        // NoPadding)
-        //
-        final String[] parts = transformation.split("/", 4);
-        if (parts.length != 3) {
-            throw new NoSuchAlgorithmException("Invalid transformation format: " + transformation);
-        }
-        return new Transform(parts[0], parts[1], parts[2]);
-    }
-
     /**
      * AlgorithmMode of JNA. Currently only support AES/CTR/NoPadding.
      */
@@ -410,28 +366,6 @@ class OpenSslJnaCipher implements CryptoCipher {
         }
     }
 
-    /**
-     * Padding of JNA.
-     */
-    private enum Padding {
-        NoPadding, PKCS5Padding;
-
-        /**
-         * Gets the Padding instance.
-         *
-         * @param padding the padding name
-         * @return the AlgorithmMode instance
-         * @throws NoSuchPaddingException if the algorithm is not support
-         */
-        static int get(final String padding) throws NoSuchPaddingException {
-            try {
-                return Padding.valueOf(padding).ordinal();
-            } catch (final Exception e) {
-                throw new NoSuchPaddingException("Algorithm not supported: " + padding);
-            }
-        }
-    }
-
     @Override
     public int getBlockSize() {
         return CryptoCipherFactory.AES_BLOCK_SIZE;
diff --git a/src/main/java/org/apache/commons/crypto/utils/Padding.java b/src/main/java/org/apache/commons/crypto/utils/Padding.java
new file mode 100644
index 0000000..445f19a
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/utils/Padding.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.crypto.utils;
+
+import javax.crypto.NoSuchPaddingException;
+
+/**
+ * Padding types.
+ */
+public enum Padding {
+
+    NoPadding, PKCS5Padding;
+
+    /**
+     * Gets a Padding.
+     *
+     * @param padding the padding name.
+     * @return a Padding instance.
+     * @throws NoSuchPaddingException if the algorithm is not support
+     */
+    public static int get(final String padding) throws NoSuchPaddingException {
+        try {
+            return Padding.valueOf(padding).ordinal();
+        } catch (final Exception e) {
+            throw new NoSuchPaddingException("Algorithm not supported: " + padding);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/commons/crypto/utils/Transformation.java b/src/main/java/org/apache/commons/crypto/utils/Transformation.java
new file mode 100644
index 0000000..acef502
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/utils/Transformation.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.crypto.utils;
+
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Transformation algorithm, mode and padding, in the format "Algorithm/Mode/Padding", for example "AES/CBC/NoPadding".
+ *
+ * @since 1.2.0
+ */
+public class Transformation {
+
+    /**
+     * Parses a transformation.
+     *
+     * @param transformation current transformation
+     * @return the Transformation
+     * @throws NoSuchAlgorithmException if the algorithm is not supported
+     */
+    public static Transformation parse(final String transformation) throws NoSuchAlgorithmException {
+        if (transformation == null) {
+            throw new NoSuchAlgorithmException("No transformation given.");
+        }
+
+        //
+        // Array containing the components of a Cipher transformation: index 0:
+        // algorithm (e.g., AES) index 1: mode (e.g., CTR) index 2: padding (e.g.,
+        // NoPadding)
+        //
+        final String[] parts = transformation.split("/", 4);
+        if (parts.length != 3) {
+            throw new NoSuchAlgorithmException("Invalid transformation format: " + transformation);
+        }
+        return new Transformation(parts[0], parts[1], parts[2]);
+    }
+
+    final String algorithm;
+    final String mode;
+    final String padding;
+
+    /**
+     * Constructs a new instance.
+     *
+     * @param algorithm the algorithm name
+     * @param mode the mode name
+     * @param padding the padding name
+     */
+    private Transformation(final String algorithm, final String mode, final String padding) {
+        this.algorithm = algorithm;
+        this.mode = mode;
+        this.padding = padding;
+    }
+
+    /**
+     * Gets the algorithm.
+     * 
+     * @return the algorithm.
+     */
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    /**
+     * Gets the mode.
+     * 
+     * @return the mode.
+     */
+    public String getMode() {
+        return mode;
+    }
+
+    /**
+     * Gets the padding.
+     * 
+     * @return the padding.
+     */
+    public String getPadding() {
+        return padding;
+    }
+}
\ No newline at end of file