8210838: Override javax.crypto.Cipher.toString()
authorcoffeys
Mon, 19 Nov 2018 09:56:42 +0000
changeset 52603 e89a4cbffba0
parent 52602 4ea75a606797
child 52604 6548ad72dff8
8210838: Override javax.crypto.Cipher.toString() Reviewed-by: mullan, weijun
src/java.base/share/classes/javax/crypto/Cipher.java
test/jdk/javax/crypto/Cipher/TestCipherMode.java
--- a/src/java.base/share/classes/javax/crypto/Cipher.java	Sun Nov 18 19:45:33 2018 +0100
+++ b/src/java.base/share/classes/javax/crypto/Cipher.java	Mon Nov 19 09:56:42 2018 +0000
@@ -1183,21 +1183,6 @@
         }
     }
 
-    private static String getOpmodeString(int opmode) {
-        switch (opmode) {
-            case ENCRYPT_MODE:
-                return "encryption";
-            case DECRYPT_MODE:
-                return "decryption";
-            case WRAP_MODE:
-                return "key wrapping";
-            case UNWRAP_MODE:
-                return "key unwrapping";
-            default:
-                return "";
-        }
-    }
-
     /**
      * Initializes this cipher with a key.
      *
@@ -1325,9 +1310,7 @@
         this.opmode = opmode;
 
         if (!skipDebug && pdebug != null) {
-            pdebug.println("Cipher." + transformation + " " +
-                getOpmodeString(opmode) + " algorithm from: " +
-                getProviderName());
+            pdebug.println(this.toString());
         }
     }
 
@@ -1468,9 +1451,7 @@
         this.opmode = opmode;
 
         if (!skipDebug && pdebug != null) {
-            pdebug.println("Cipher." + transformation + " " +
-                getOpmodeString(opmode) + " algorithm from: " +
-                getProviderName());
+            pdebug.println(this.toString());
         }
     }
 
@@ -1611,9 +1592,7 @@
         this.opmode = opmode;
 
         if (!skipDebug && pdebug != null) {
-            pdebug.println("Cipher." + transformation + " " +
-                getOpmodeString(opmode) + " algorithm from: " +
-                getProviderName());
+            pdebug.println(this.toString());
         }
     }
 
@@ -1688,8 +1667,7 @@
 
     /**
      * Initializes this cipher with the public key from the given certificate
-     * and
-     * a source of randomness.
+     * and a source of randomness.
      *
      * <p>The cipher is initialized for one of the following four operations:
      * encryption, decryption, key wrapping
@@ -1757,8 +1735,7 @@
         initialized = false;
         checkOpmode(opmode);
 
-        // Check key usage if the certificate is of
-        // type X.509.
+        // Check key usage if the certificate is of type X.509.
         if (certificate instanceof java.security.cert.X509Certificate) {
             // Check whether the cert has a key usage extension
             // marked as a critical extension.
@@ -1801,9 +1778,7 @@
         this.opmode = opmode;
 
         if (!skipDebug && pdebug != null) {
-            pdebug.println("Cipher." + transformation + " " +
-                getOpmodeString(opmode) + " algorithm from: " +
-                getProviderName());
+            pdebug.println(this.toString());
         }
     }
 
@@ -2825,4 +2800,44 @@
         }
         spi.engineUpdateAAD(src);
     }
-}
+
+    /**
+     * Returns a String representation of this Cipher.
+     *
+     * @implNote
+     * This implementation returns a String containing the transformation,
+     * mode, and provider of this Cipher.
+     * The exact format of the String is unspecified and is subject to change.
+     *
+     * @return a String describing this Cipher
+     */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("Cipher.")
+                .append(transformation)
+                .append(", mode: ");
+        switch (opmode) {
+            case 0:
+                sb.append("not initialized");
+                break;
+            case ENCRYPT_MODE:
+                sb.append("encryption");
+                break;
+            case DECRYPT_MODE:
+                sb.append("decryption");
+                break;
+            case WRAP_MODE:
+                sb.append("key wrapping");
+                break;
+            case UNWRAP_MODE:
+                sb.append("key unwrapping");
+                break;
+            default:
+                // should never happen
+                sb.append("error:").append(Integer.toString(opmode));
+        }
+        sb.append(", algorithm from: ").append(getProviderName());
+        return sb.toString();
+    }
+}
\ No newline at end of file
--- a/test/jdk/javax/crypto/Cipher/TestCipherMode.java	Sun Nov 18 19:45:33 2018 +0100
+++ b/test/jdk/javax/crypto/Cipher/TestCipherMode.java	Mon Nov 19 09:56:42 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 4953556
+ * @bug 4953556 8210838
  * @summary ensure that IllegalStateException is thrown if the
  * Cipher object is initialized with a wrong mode, e.g. WRAP_MODE
  * for update()/doFinal() calls.
@@ -44,13 +44,13 @@
     public static void main(String[] argv) throws Exception {
         TestCipherMode test = new TestCipherMode();
         System.out.println("Testing ENCRYPT_MODE...");
-        test.checkMode(Cipher.ENCRYPT_MODE);
+        test.checkMode(Cipher.ENCRYPT_MODE, "encryption");
         System.out.println("Testing DECRYPT_MODE...");
-        test.checkMode(Cipher.DECRYPT_MODE);
+        test.checkMode(Cipher.DECRYPT_MODE, "decryption");
         System.out.println("Testing WRAP_MODE...");
-        test.checkMode(Cipher.WRAP_MODE);
+        test.checkMode(Cipher.WRAP_MODE, "key wrapping");
         System.out.println("Testing UNWRAP_MODE...");
-        test.checkMode(Cipher.UNWRAP_MODE);
+        test.checkMode(Cipher.UNWRAP_MODE, "key unwrapping");
         System.out.println("All Tests Passed");
    }
 
@@ -60,11 +60,23 @@
     private TestCipherMode() throws NoSuchAlgorithmException,
     NoSuchProviderException, NoSuchPaddingException {
         c = Cipher.getInstance(ALGO + "/ECB/PKCS5Padding", "SunJCE");
+        String output = c.toString();
+        if (!output.equals(
+                "Cipher.DES/ECB/PKCS5Padding, mode: not initialized, algorithm from: SunJCE")) {
+            throw new RuntimeException(
+                    "Unexpected Cipher.toString() output:" + output);
+        }
         key = new SecretKeySpec(new byte[8], ALGO);
     }
 
-    private void checkMode(int mode) throws Exception {
+    private void checkMode(int mode, String opString) throws Exception {
         c.init(mode, key);
+        String output = c.toString();
+        if (!output.contains("Cipher.DES/ECB/PKCS5Padding")
+                && !output.contains(opString)
+                && !output.contains("Algorithm from: SunJCE")) {
+            throw new Exception("Unexpected toString() output:" + output);
+        }
 
         switch (mode) {
         case Cipher.ENCRYPT_MODE: