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 2012/09/01 17:57:34 UTC

svn commit: r1379782 - in /commons/proper/codec/trunk: b/ b/src/ b/src/test/ b/src/test/java/ b/src/test/java/org/ b/src/test/java/org/apache/ b/src/test/java/org/apache/commons/ b/src/test/java/org/apache/commons/codec/ b/src/test/java/org/apache/comm...

Author: ggregory
Date: Sat Sep  1 15:57:33 2012
New Revision: 1379782

URL: http://svn.apache.org/viewvc?rev=1379782&view=rev
Log:
Partial patch application of [CODEC-148] More tests and minor things.

Added:
    commons/proper/codec/trunk/b/
    commons/proper/codec/trunk/b/src/
    commons/proper/codec/trunk/b/src/test/
    commons/proper/codec/trunk/b/src/test/java/
    commons/proper/codec/trunk/b/src/test/java/org/
    commons/proper/codec/trunk/b/src/test/java/org/apache/
    commons/proper/codec/trunk/b/src/test/java/org/apache/commons/
    commons/proper/codec/trunk/b/src/test/java/org/apache/commons/codec/
    commons/proper/codec/trunk/b/src/test/java/org/apache/commons/codec/digest/
    commons/proper/codec/trunk/b/src/test/java/org/apache/commons/codec/digest/Sha2CryptTest.java   (with props)
Modified:
    commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Crypt.java
    commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Md5Crypt.java
    commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/MessageDigestAlgorithms.java
    commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Sha2Crypt.java
    commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Apr1CryptTest.java
    commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/B64Test.java
    commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/CryptTest.java
    commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/DigestUtilsTest.java
    commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Md5CryptTest.java
    commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Sha256CryptTest.java
    commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Sha512CryptTest.java
    commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/UnixCryptTest.java

Added: commons/proper/codec/trunk/b/src/test/java/org/apache/commons/codec/digest/Sha2CryptTest.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/b/src/test/java/org/apache/commons/codec/digest/Sha2CryptTest.java?rev=1379782&view=auto
==============================================================================
--- commons/proper/codec/trunk/b/src/test/java/org/apache/commons/codec/digest/Sha2CryptTest.java (added)
+++ commons/proper/codec/trunk/b/src/test/java/org/apache/commons/codec/digest/Sha2CryptTest.java Sat Sep  1 15:57:33 2012
@@ -0,0 +1,13 @@
+package org.apache.commons.codec.digest;
+
+import static org.junit.Assert.assertNotNull;
+import org.junit.Test;
+
+public class Sha2CryptTest {
+
+    @Test
+    public void testCtor() {
+        assertNotNull(new Sha2Crypt());
+    }
+
+}

Propchange: commons/proper/codec/trunk/b/src/test/java/org/apache/commons/codec/digest/Sha2CryptTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/codec/trunk/b/src/test/java/org/apache/commons/codec/digest/Sha2CryptTest.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Crypt.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Crypt.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Crypt.java (original)
+++ commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Crypt.java Sat Sep  1 15:57:33 2012
@@ -16,8 +16,6 @@
  */
 package org.apache.commons.codec.digest;
 
-import java.security.NoSuchAlgorithmException;
-
 import org.apache.commons.codec.Charsets;
 
 /**
@@ -41,9 +39,10 @@ public class Crypt {
      * @param keyBytes
      *            plaintext password
      * @return hash value
-     * @throws NoSuchAlgorithmException if no algorithm implementation is available
+     * @throws RuntimeException
+     *            when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String crypt(byte[] keyBytes) throws NoSuchAlgorithmException {
+    public static String crypt(byte[] keyBytes) {
         return crypt(keyBytes, null);
     }
 
@@ -58,10 +57,12 @@ public class Crypt {
      * @param salt
      *            salt value
      * @return hash value
-     * @throws IllegalArgumentException if the salt does not match the allowed pattern
-     * @throws NoSuchAlgorithmException if no algorithm implementation is available
+     * @throws IllegalArgumentException
+     *              if the salt does not match the allowed pattern
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String crypt(byte[] keyBytes, String salt) throws NoSuchAlgorithmException {
+    public static String crypt(byte[] keyBytes, String salt) {
         if (salt == null) {
             return Sha2Crypt.sha512Crypt(keyBytes);
         } else if (salt.startsWith(Sha2Crypt.SHA512_PREFIX)) {
@@ -84,9 +85,10 @@ public class Crypt {
      * @param key
      *            plaintext password
      * @return hash value
-     * @throws NoSuchAlgorithmException if no algorithm implementation is available
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String crypt(String key) throws NoSuchAlgorithmException {
+    public static String crypt(String key) {
         return crypt(key, null);
     }
 
@@ -136,10 +138,12 @@ public class Crypt {
      * @param salt
      *            salt value
      * @return hash value, i.e. encrypted password including the salt string
-     * @throws IllegalArgumentException if the salt does not match the allowed pattern
-     * @throws NoSuchAlgorithmException if no algorithm implementation is available
+     * @throws IllegalArgumentException
+     *              if the salt does not match the allowed pattern
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.     *
      */
-    public static String crypt(String key, String salt) throws NoSuchAlgorithmException {
+    public static String crypt(String key, String salt) {
         return crypt(key.getBytes(Charsets.UTF_8), salt);
     }
 }

Modified: commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Md5Crypt.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Md5Crypt.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Md5Crypt.java (original)
+++ commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Md5Crypt.java Sat Sep  1 15:57:33 2012
@@ -17,7 +17,6 @@
 package org.apache.commons.codec.digest;
 
 import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -51,9 +50,6 @@ public class Md5Crypt {
     /** The number of bytes of the final hash. */
     private static final int BLOCKSIZE = 16;
 
-    /** The MessageDigest MD5_ALGORITHM. */
-    private static final String MD5_ALGORITHM = "MD5";
-
     /** The Identifier of this crypt() variant. */
     static final String MD5_PREFIX = "$1$";
 
@@ -63,9 +59,10 @@ public class Md5Crypt {
     /**
      * See {@link #apr1Crypt(String, String)} for details.
      *
-     * @throws NoSuchAlgorithmException if no "MD5" algorithm implementation is available
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.     *
      */
-    public static String apr1Crypt(byte[] keyBytes) throws NoSuchAlgorithmException {
+    public static String apr1Crypt(byte[] keyBytes) {
         return apr1Crypt(keyBytes, APR1_PREFIX + B64.getRandomSalt(8));
     }
 
@@ -73,9 +70,10 @@ public class Md5Crypt {
      * See {@link #apr1Crypt(String, String)} for details.
      *
      * @throws IllegalArgumentException if the salt does not match the allowed pattern
-     * @throws NoSuchAlgorithmException if no "MD5" algorithm implementation is available
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String apr1Crypt(byte[] keyBytes, String salt) throws NoSuchAlgorithmException {
+    public static String apr1Crypt(byte[] keyBytes, String salt) {
         // to make the md5Crypt regex happy
         if (salt != null && !salt.startsWith(APR1_PREFIX)) {
             salt = APR1_PREFIX + salt;
@@ -86,9 +84,10 @@ public class Md5Crypt {
     /**
      * See {@link #apr1Crypt(String, String)} for details.
      *
-     * @throws NoSuchAlgorithmException if no "MD5" algorithm implementation is available
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String apr1Crypt(String keyBytes) throws NoSuchAlgorithmException {
+    public static String apr1Crypt(String keyBytes) {
         return apr1Crypt(keyBytes.getBytes(Charsets.UTF_8));
     }
 
@@ -104,10 +103,12 @@ public class Md5Crypt {
      *            salt string including the prefix and optionally garbage at the end.
      *            Will be generated randomly if null.
      * @return computed hash value
-     * @throws IllegalArgumentException if the salt does not match the allowed pattern
-     * @throws NoSuchAlgorithmException if no "MD5" algorithm implementation is available
+     * @throws IllegalArgumentException
+     *              if the salt does not match the allowed pattern
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String apr1Crypt(String keyBytes, String salt) throws NoSuchAlgorithmException {
+    public static String apr1Crypt(String keyBytes, String salt) {
         return apr1Crypt(keyBytes.getBytes(Charsets.UTF_8), salt);
     }
 
@@ -116,9 +117,10 @@ public class Md5Crypt {
      * <p>
      * See {@link Crypt#crypt(String, String)} for details.
      *
-     * @throws NoSuchAlgorithmException if no "MD5" algorithm implementation is available
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String md5Crypt(final byte[] keyBytes) throws NoSuchAlgorithmException {
+    public static String md5Crypt(final byte[] keyBytes) {
         return md5Crypt(keyBytes, MD5_PREFIX + B64.getRandomSalt(8));
     }
 
@@ -133,10 +135,12 @@ public class Md5Crypt {
      *            salt string including the prefix and optionally garbage at the end.
      *            Will be generated randomly if null.
      * @return computed hash value
-     * @throws IllegalArgumentException if the salt does not match the allowed pattern
-     * @throws NoSuchAlgorithmException if no "MD5" algorithm implementation is available
+     * @throws IllegalArgumentException
+     *              if the salt does not match the allowed pattern
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String md5Crypt(byte[] keyBytes, String salt) throws NoSuchAlgorithmException {
+    public static String md5Crypt(byte[] keyBytes, String salt) {
         return md5Crypt(keyBytes, salt, MD5_PREFIX);
     }
 
@@ -145,11 +149,13 @@ public class Md5Crypt {
      * <p>
      * See {@link Crypt#crypt(String, String)} or {@link #apr1Crypt(String, String)} for details.
      *
-     * @throws IllegalArgumentException if the salt does not match the allowed pattern
-     * @throws NoSuchAlgorithmException if no "MD5" algorithm implementation is available
+     * @throws IllegalArgumentException
+     *              if the salt does not match the allowed pattern
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
     public static String md5Crypt(final byte[] keyBytes, final String salt, final String prefix)
-            throws NoSuchAlgorithmException {
+            {
         int keyLen = keyBytes.length;
 
         // Extract the real salt from the given string which can be a complete hash string.
@@ -166,7 +172,7 @@ public class Md5Crypt {
         }
         byte[] saltBytes = saltString.getBytes(Charsets.UTF_8);
 
-        MessageDigest ctx = MessageDigest.getInstance(MD5_ALGORITHM);
+        MessageDigest ctx = DigestUtils.getMd5Digest();
 
         /*
          * The password first, since that is what is most unknown
@@ -186,7 +192,7 @@ public class Md5Crypt {
         /*
          * Then just as many characters of the MD5(pw,salt,pw)
          */
-        MessageDigest ctx1 = MessageDigest.getInstance(MD5_ALGORITHM);
+        MessageDigest ctx1 = DigestUtils.getMd5Digest();
         ctx1.update(keyBytes);
         ctx1.update(saltBytes);
         ctx1.update(keyBytes);
@@ -227,7 +233,7 @@ public class Md5Crypt {
          * need 30 seconds to build a 1000 entry dictionary...
          */
         for (int i = 0; i < ROUNDS; i++) {
-            ctx1 = MessageDigest.getInstance(MD5_ALGORITHM);
+            ctx1 = DigestUtils.getMd5Digest();
             if ((i & 1) != 0) {
                 ctx1.update(keyBytes);
             } else {

Modified: commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/MessageDigestAlgorithms.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/MessageDigestAlgorithms.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/MessageDigestAlgorithms.java (original)
+++ commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/MessageDigestAlgorithms.java Sat Sep  1 15:57:33 2012
@@ -20,9 +20,9 @@ package org.apache.commons.codec.digest;
 import java.security.MessageDigest;
 
 /**
- * Standard {@link MessageDigest} algorithm names from the <cite>Java Cryptography Architecture Standard Algorithm 
- * Name Documentation</cite>.
- * 
+ * Standard {@link MessageDigest} algorithm names from the <cite>Java Cryptography Architecture Standard Algorithm Name
+ * Documentation</cite>.
+ *
  * @see <a href="http://docs.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html">Java Cryptography
  *      Architecture Standard Algorithm Name Documentation</a>
  * @since 1.7
@@ -30,6 +30,10 @@ import java.security.MessageDigest;
  */
 public class MessageDigestAlgorithms {
 
+    private MessageDigestAlgorithms() {
+        // cannot be instantiated.
+    }
+
     /**
      * The MD2 message digest algorithm defined in RFC 1319.
      */

Modified: commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Sha2Crypt.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Sha2Crypt.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Sha2Crypt.java (original)
+++ commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/digest/Sha2Crypt.java Sat Sep  1 15:57:33 2012
@@ -17,7 +17,6 @@
 package org.apache.commons.codec.digest;
 
 import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -52,18 +51,12 @@ public class Sha2Crypt {
     /** Prefix for optional rounds specification. */
     private static final String ROUNDS_PREFIX = "rounds=";
 
-    /** The SHA-256 MessageDigest algorithm. */
-    private static final String SHA256_ALGORITHM = "SHA-256";
-
     /** The number of bytes the final hash value will have (SHA-256 variant). */
     private static final int SHA256_BLOCKSIZE = 32;
 
     /** The prefixes that can be used to identify this crypt() variant (SHA-256). */
     static final String SHA256_PREFIX = "$5$";
 
-    /** The SHA-512 MessageDigest algorithm. */
-    private static final String SHA512_ALGORITHM = "SHA-512";
-
     /** The number of bytes the final hash value will have (SHA-512 variant). */
     private static final int SHA512_BLOCKSIZE = 64;
 
@@ -79,9 +72,10 @@ public class Sha2Crypt {
      * <p>
      * See {@link Crypt#crypt(String, String)} for details.
      *
-     * @throws NoSuchAlgorithmException if no "SHA-256" algorithm implementation is available
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String sha256Crypt(byte[] keyBytes) throws NoSuchAlgorithmException {
+    public static String sha256Crypt(byte[] keyBytes) {
         return sha256Crypt(keyBytes, null);
     }
 
@@ -91,13 +85,14 @@ public class Sha2Crypt {
      * See {@link Crypt#crypt(String, String)} for details.
      *
      * @throws IllegalArgumentException if the salt does not match the allowed pattern
-     * @throws NoSuchAlgorithmException if no "SHA-256" algorithm implementation is available
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String sha256Crypt(byte[] keyBytes, String salt) throws NoSuchAlgorithmException {
+    public static String sha256Crypt(byte[] keyBytes, String salt) {
         if (salt == null) {
             salt = SHA256_PREFIX + B64.getRandomSalt(8);
         }
-        return sha2Crypt(keyBytes, salt, SHA256_PREFIX, SHA256_BLOCKSIZE, SHA256_ALGORITHM);
+        return sha2Crypt(keyBytes, salt, SHA256_PREFIX, SHA256_BLOCKSIZE, MessageDigestAlgorithms.SHA_256);
     }
 
     /**
@@ -121,10 +116,11 @@ public class Sha2Crypt {
      *            {@link MessageDigest} algorithm identifier string
      * @return complete hash value including prefix and salt
      * @throws IllegalArgumentException if the given salt is {@code null} or does not match the allowed pattern
-     * @throws NoSuchAlgorithmException if no implementation for the given algorithm is available
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
     private static String sha2Crypt(byte[] keyBytes, String salt, String saltPrefix, int blocksize, String algorithm)
-            throws NoSuchAlgorithmException {
+            {
 
         int keyLen = keyBytes.length;
 
@@ -150,7 +146,7 @@ public class Sha2Crypt {
 
         // 1. start digest A
         // Prepare for the real work.
-        MessageDigest ctx = MessageDigest.getInstance(algorithm);
+        MessageDigest ctx = DigestUtils.getDigest(algorithm);
 
         // 2. the password string is added to digest A
         /*
@@ -178,7 +174,7 @@ public class Sha2Crypt {
          * Compute alternate sha512 sum with input KEY, SALT, and KEY. The final result will be added to the first
          * context.
          */
-        MessageDigest altCtx = MessageDigest.getInstance(algorithm);
+        MessageDigest altCtx = DigestUtils.getDigest(algorithm);
 
         // 5. add the password to digest B
         /*
@@ -256,7 +252,7 @@ public class Sha2Crypt {
         /*
          * Start computation of P byte sequence.
          */
-        altCtx = MessageDigest.getInstance(algorithm);
+        altCtx = DigestUtils.getDigest(algorithm);
 
         // 14. for every byte in the password (excluding the terminating NUL byte
         // in the C representation of the string)
@@ -297,7 +293,7 @@ public class Sha2Crypt {
         /*
          * Start computation of S byte sequence.
          */
-        altCtx = MessageDigest.getInstance(algorithm);
+        altCtx = DigestUtils.getDigest(algorithm);
 
         // 18. repeast the following 16+A[0] times, where A[0] represents the first
         // byte in digest A interpreted as an 8-bit unsigned value
@@ -351,7 +347,7 @@ public class Sha2Crypt {
             /*
              * New context.
              */
-            ctx = MessageDigest.getInstance(algorithm);
+            ctx = DigestUtils.getDigest(algorithm);
 
             // b) for odd round numbers add the byte sequense P to digest C
             // c) for even round numbers add digest A/C
@@ -504,9 +500,10 @@ public class Sha2Crypt {
      * <p>
      * See {@link Crypt#crypt(String, String)} for details.
      *
-     * @throws NoSuchAlgorithmException if no "SHA-512" algorithm implementation is available
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String sha512Crypt(byte[] keyBytes) throws NoSuchAlgorithmException {
+    public static String sha512Crypt(byte[] keyBytes) {
         return sha512Crypt(keyBytes, null);
     }
 
@@ -516,12 +513,13 @@ public class Sha2Crypt {
      * See {@link Crypt#crypt(String, String)} for details.
      *
      * @throws IllegalArgumentException if the salt does not match the allowed pattern
-     * @throws NoSuchAlgorithmException if no "SHA-512" algorithm implementation is available
+     * @throws RuntimeException
+     *              when a {@link java.security.NoSuchAlgorithmException} is caught.
      */
-    public static String sha512Crypt(byte[] keyBytes, String salt) throws NoSuchAlgorithmException {
+    public static String sha512Crypt(byte[] keyBytes, String salt) {
         if (salt == null) {
             salt = SHA512_PREFIX + B64.getRandomSalt(8);
         }
-        return sha2Crypt(keyBytes, salt, SHA512_PREFIX, SHA512_BLOCKSIZE, SHA512_ALGORITHM);
+        return sha2Crypt(keyBytes, salt, SHA512_PREFIX, SHA512_BLOCKSIZE, MessageDigestAlgorithms.SHA_512);
     }
 }

Modified: commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Apr1CryptTest.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Apr1CryptTest.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Apr1CryptTest.java (original)
+++ commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Apr1CryptTest.java Sat Sep  1 15:57:33 2012
@@ -16,18 +16,16 @@
  */
 package org.apache.commons.codec.digest;
 
+import org.apache.commons.codec.Charsets;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
-
-import java.security.NoSuchAlgorithmException;
-
-import org.apache.commons.codec.Charsets;
 import org.junit.Test;
 
 public class Apr1CryptTest {
 
     @Test
-    public void testApr1CryptStrings() throws NoSuchAlgorithmException {
+    public void testApr1CryptStrings() {
         // A random example using htpasswd
         assertEquals("$apr1$TqI9WECO$LHZB2DqRlk9nObiB6vJG9.", Md5Crypt.apr1Crypt("secret", "$apr1$TqI9WECO"));
         // empty data
@@ -42,7 +40,12 @@ public class Apr1CryptTest {
     }
 
     @Test
-    public void testApr1CryptBytes() throws NoSuchAlgorithmException {
+    public void testApr1CryptBytes() {
+        // random salt
+        byte[] keyBytes = new byte[] { '!', 'b', 'c', '.' };
+        String hash = Md5Crypt.apr1Crypt(keyBytes);
+        assertEquals(hash, Md5Crypt.apr1Crypt("!bc.", hash));
+
         // An empty Bytearray equals an empty String
         assertEquals("$apr1$foo$P27KyD1htb4EllIPEYhqi0", Md5Crypt.apr1Crypt(new byte[0], "$apr1$foo"));
         // UTF-8 stores \u00e4 "a with diaeresis" as two bytes 0xc3 0xa4.
@@ -52,7 +55,7 @@ public class Apr1CryptTest {
     }
 
     @Test
-    public void testApr1CryptExplicitCall() throws NoSuchAlgorithmException {
+    public void testApr1CryptExplicitCall() {
         // When explicitly called the prefix is optional
         assertEquals("$apr1$1234$mAlH7FRST6FiRZ.kcYL.j1", Md5Crypt.apr1Crypt("secret", "1234"));
         // When explicitly called without salt, a random one will be used.
@@ -60,13 +63,32 @@ public class Apr1CryptTest {
         assertTrue(Md5Crypt.apr1Crypt("secret".getBytes(), null).matches("^\\$apr1\\$[a-zA-Z0-9./]{0,8}\\$.{1,}$"));
     }
 
+    @Test
+    public void testApr1LongSalt() {
+        assertEquals("$apr1$12345678$0lqb/6VUFP8JY/s/jTrIk0", Md5Crypt.apr1Crypt("secret", "12345678901234567890"));
+    }
+
     @Test(expected = NullPointerException.class)
-    public void testApr1CryptNullData() throws NoSuchAlgorithmException {
+    public void testApr1CryptNullData() {
         Md5Crypt.apr1Crypt((byte[]) null);
     }
 
     @Test(expected = IllegalArgumentException.class)
-    public void testApr1CryptWithEmptySalt() throws NoSuchAlgorithmException {
+    public void testApr1CryptWithEmptySalt() {
         Md5Crypt.apr1Crypt("secret".getBytes(), "");
     }
+
+    @Test
+    public void testApr1CryptWithoutSalt() {
+        // Without salt, a random is generated
+        String hash = Md5Crypt.apr1Crypt("secret");
+        assertTrue(hash.matches("^\\$apr1\\$[a-zA-Z0-9\\./]{8}\\$[a-zA-Z0-9\\./]{22}$"));
+        String hash2 = Md5Crypt.apr1Crypt("secret");
+        assertNotSame(hash, hash2);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testApr1CryptWithInvalidSalt() {
+        Md5Crypt.apr1Crypt(new byte[0], "!");
+    }
 }

Modified: commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/B64Test.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/B64Test.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/B64Test.java (original)
+++ commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/B64Test.java Sat Sep  1 15:57:33 2012
@@ -17,11 +17,18 @@
 package org.apache.commons.codec.digest;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import org.junit.Test;
 
 public class B64Test {
 
     @Test
+    public void testB64T() {
+        assertNotNull(new B64()); // for the 100% code coverage :)
+        assertEquals(64, B64.B64T.length());
+    }
+
+    @Test
     public void testB64from24bit() {
         StringBuilder buffer = new StringBuilder("");
         B64.b64from24bit((byte) 8, (byte) 16, (byte) 64, 2, buffer);

Modified: commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/CryptTest.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/CryptTest.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/CryptTest.java (original)
+++ commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/CryptTest.java Sat Sep  1 15:57:33 2012
@@ -16,21 +16,32 @@
  */
 package org.apache.commons.codec.digest;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-
-import java.security.NoSuchAlgorithmException;
-
 import org.junit.Test;
 
 public class CryptTest {
 
     @Test
-    public void testDefaultCryptVariant() throws NoSuchAlgorithmException {
+    public void testCrypt() {
+        assertNotNull(new Crypt()); // just for Test Coverage
+    }
+
+    @Test
+    public void testDefaultCryptVariant() {
         // If salt is null or completely omitted, a random "$6$" is used.
         assertTrue(Crypt.crypt("secret").startsWith("$6$"));
         assertTrue(Crypt.crypt("secret", null).startsWith("$6$"));
     }
 
+    @Test
+    public void testCryptWithBytes() {
+        byte[] keyBytes = new byte[] { 'b', 'y', 't', 'e' };
+        String hash = Crypt.crypt(keyBytes);
+        assertEquals(hash, Crypt.crypt("byte", hash));
+    }
+
     /**
      * An empty string as salt is invalid.
      *
@@ -39,7 +50,7 @@ public class CryptTest {
      * hash would not be verifyable with other implementations of crypt().
      */
     @Test(expected = IllegalArgumentException.class)
-    public void testCryptWithEmptySalt() throws NoSuchAlgorithmException {
+    public void testCryptWithEmptySalt() {
         Crypt.crypt("secret", "");
     }
 

Modified: commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/DigestUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/DigestUtilsTest.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/DigestUtilsTest.java (original)
+++ commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/DigestUtilsTest.java Sat Sep  1 15:57:33 2012
@@ -17,9 +17,6 @@
 
 package org.apache.commons.codec.digest;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.security.MessageDigest;
@@ -27,6 +24,9 @@ import java.util.Random;
 
 import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.codec.binary.StringUtils;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
 import org.junit.Test;
 
 /**
@@ -51,7 +51,7 @@ public class DigestUtilsTest {
 
     @Test
     public void testConstructable() {
-        new DigestUtils();
+        assertNotNull(new DigestUtils());
     }
 
     @Test

Modified: commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Md5CryptTest.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Md5CryptTest.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Md5CryptTest.java (original)
+++ commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Md5CryptTest.java Sat Sep  1 15:57:33 2012
@@ -16,18 +16,21 @@
  */
 package org.apache.commons.codec.digest;
 
+import org.apache.commons.codec.Charsets;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-
-import java.security.NoSuchAlgorithmException;
-
-import org.apache.commons.codec.Charsets;
 import org.junit.Test;
 
 public class Md5CryptTest {
 
     @Test
-    public void testMd5CryptStrings() throws NoSuchAlgorithmException {
+    public void testCtor() {
+        assertNotNull(new Md5Crypt()); // for code-coverage
+    }
+
+    @Test
+    public void testMd5CryptStrings() {
         // empty data
         assertEquals("$1$foo$9mS5ExwgIECGE5YKlD5o91", Crypt.crypt("", "$1$foo"));
         // salt gets cut at dollar sign
@@ -40,7 +43,7 @@ public class Md5CryptTest {
     }
 
     @Test
-    public void testMd5CryptBytes() throws NoSuchAlgorithmException {
+    public void testMd5CryptBytes() {
         // An empty Bytearray equals an empty String
         assertEquals("$1$foo$9mS5ExwgIECGE5YKlD5o91", Crypt.crypt(new byte[0], "$1$foo"));
         // UTF-8 stores \u00e4 "a with diaeresis" as two bytes 0xc3 0xa4.
@@ -50,18 +53,23 @@ public class Md5CryptTest {
     }
 
     @Test
-    public void testMd5CryptExplicitCall() throws NoSuchAlgorithmException {
+    public void testMd5CryptExplicitCall() {
         assertTrue(Md5Crypt.md5Crypt("secret".getBytes()).matches("^\\$1\\$[a-zA-Z0-9./]{0,8}\\$.{1,}$"));
         assertTrue(Md5Crypt.md5Crypt("secret".getBytes(), null).matches("^\\$1\\$[a-zA-Z0-9./]{0,8}\\$.{1,}$"));
     }
 
+    @Test
+    public void testMd5CryptLongInput() {
+        assertEquals("$1$1234$MoxekaNNUgfPRVqoeYjCD/", Crypt.crypt("12345678901234567890", "$1$1234"));
+    }
+
     @Test(expected = NullPointerException.class)
-    public void testMd5CryptNullData() throws NoSuchAlgorithmException {
+    public void testMd5CryptNullData() {
         Md5Crypt.md5Crypt((byte[]) null);
     }
 
     @Test(expected = IllegalArgumentException.class)
-    public void testMd5CryptWithEmptySalt() throws NoSuchAlgorithmException {
+    public void testMd5CryptWithEmptySalt() {
         Md5Crypt.md5Crypt("secret".getBytes(), "");
     }
 }

Modified: commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Sha256CryptTest.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Sha256CryptTest.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Sha256CryptTest.java (original)
+++ commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Sha256CryptTest.java Sat Sep  1 15:57:33 2012
@@ -16,18 +16,17 @@
  */
 package org.apache.commons.codec.digest;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
 
 import org.apache.commons.codec.Charsets;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import org.junit.Test;
 
 public class Sha256CryptTest {
 
     @Test
-    public void testSha256CryptStrings() throws NoSuchAlgorithmException {
+    public void testSha256CryptStrings() {
         // empty data
         assertEquals("$5$foo$Fq9CX624QIfnCAmlGiPKLlAasdacKCRxZztPoeo7o0B", Crypt.crypt("", "$5$foo"));
         // salt gets cut at dollar sign
@@ -40,7 +39,7 @@ public class Sha256CryptTest {
     }
 
     @Test
-    public void testSha256CryptBytes() throws NoSuchAlgorithmException {
+    public void testSha256CryptBytes() {
         // An empty Bytearray equals an empty String
         assertEquals("$5$foo$Fq9CX624QIfnCAmlGiPKLlAasdacKCRxZztPoeo7o0B", Crypt.crypt(new byte[0], "$5$foo"));
         // UTF-8 stores \u00e4 "a with diaeresis" as two bytes 0xc3 0xa4.
@@ -50,18 +49,33 @@ public class Sha256CryptTest {
     }
 
     @Test
-    public void testSha256CryptExplicitCall() throws NoSuchAlgorithmException {
+    public void testSha2CryptRounds() {
+        // minimum rounds?
+        assertEquals("$5$rounds=1000$abcd$b8MCU4GEeZIekOy5ahQ8EWfT330hvYGVeDYkBxXBva.", Sha2Crypt.sha256Crypt("secret".getBytes(Charsets.UTF_8), "$5$rounds=50$abcd$"));
+        assertEquals("$5$rounds=1001$abcd$SQsJZs7KXKdd2DtklI3TY3tkD7UYA99RD0FBLm4Sk48", Sha2Crypt.sha256Crypt("secret".getBytes(Charsets.UTF_8), "$5$rounds=1001$abcd$"));
+        assertEquals("$5$rounds=9999$abcd$Rh/8ngVh9oyuS6lL3.fsq.9xbvXJsfyKWxSjO2mPIa7", Sha2Crypt.sha256Crypt("secret".getBytes(Charsets.UTF_8), "$5$rounds=9999$abcd"));
+    }
+
+    @Test
+    public void testSha256CryptExplicitCall() {
         assertTrue(Sha2Crypt.sha256Crypt("secret".getBytes()).matches("^\\$5\\$[a-zA-Z0-9./]{0,16}\\$.{1,}$"));
         assertTrue(Sha2Crypt.sha256Crypt("secret".getBytes(), null).matches("^\\$5\\$[a-zA-Z0-9./]{0,16}\\$.{1,}$"));
     }
 
     @Test(expected = NullPointerException.class)
-    public void testSha256CryptNullData() throws NoSuchAlgorithmException {
+    public void testSha256CryptNullData() {
         Sha2Crypt.sha256Crypt((byte[]) null);
     }
 
     @Test(expected = IllegalArgumentException.class)
-    public void testSha256CryptWithEmptySalt() throws NoSuchAlgorithmException {
+    public void testSha256CryptWithEmptySalt() {
         Sha2Crypt.sha256Crypt("secret".getBytes(), "");
     }
+
+    @Test
+    public void testSha256LargetThanBlocksize() {
+        byte[] buffer = new byte[200];
+        Arrays.fill(buffer, 0, 200, (byte)'A');
+        assertEquals("$5$abc$HbF3RRc15OwNKB/RZZ5F.1I6zsLcKXHQoSdB9Owx/Q8", Sha2Crypt.sha256Crypt(buffer, "$5$abc"));
+    }
 }

Modified: commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Sha512CryptTest.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Sha512CryptTest.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Sha512CryptTest.java (original)
+++ commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/Sha512CryptTest.java Sat Sep  1 15:57:33 2012
@@ -16,18 +16,18 @@
  */
 package org.apache.commons.codec.digest;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
 
 import org.apache.commons.codec.Charsets;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.Ignore;
 import org.junit.Test;
 
 public class Sha512CryptTest {
 
     @Test
-    public void testSha512CryptStrings() throws NoSuchAlgorithmException {
+    public void testSha512CryptStrings() {
         // empty data
         assertEquals("$6$foo$Nywkte7LPWjaJhWjNeGJN.dFdY3pN1wYlGifyRLYOVlGS9EMSiZaDDe/BGSOYQ327q9.32I4UqQ5odsqvsBLX/", Crypt.crypt("", "$6$foo"));
         // salt gets cut at dollar sign
@@ -40,7 +40,7 @@ public class Sha512CryptTest {
     }
 
     @Test
-    public void testSha512CryptBytes() throws NoSuchAlgorithmException {
+    public void testSha512CryptBytes() {
         // An empty Bytearray equals an empty String
         assertEquals("$6$foo$Nywkte7LPWjaJhWjNeGJN.dFdY3pN1wYlGifyRLYOVlGS9EMSiZaDDe/BGSOYQ327q9.32I4UqQ5odsqvsBLX/", Crypt.crypt(new byte[0], "$6$foo"));
         // UTF-8 stores \u00e4 "a with diaeresis" as two bytes 0xc3 0xa4.
@@ -50,18 +50,44 @@ public class Sha512CryptTest {
     }
 
     @Test
-    public void testSha512CryptExplicitCall() throws NoSuchAlgorithmException {
+    public void testSha512CryptExplicitCall() {
         assertTrue(Sha2Crypt.sha512Crypt("secret".getBytes()).matches("^\\$6\\$[a-zA-Z0-9./]{0,16}\\$.{1,}$"));
         assertTrue(Sha2Crypt.sha512Crypt("secret".getBytes(), null).matches("^\\$6\\$[a-zA-Z0-9./]{0,16}\\$.{1,}$"));
     }
 
     @Test(expected = NullPointerException.class)
-    public void testSha512CryptNullData() throws NoSuchAlgorithmException {
+    public void testSha512CryptNullData() {
         Sha2Crypt.sha512Crypt((byte[]) null);
     }
 
+    @Ignore
+    public void testSha512CryptNullSalt() {
+        // cannot be tested as sha512Crypt() with all params is private and
+        // all public methods check for salt==null.
+    }
+
+    @Test
+    public void testSha2CryptRounds() {
+        // minimum rounds?
+        assertEquals("$5$rounds=1000$abcd$b8MCU4GEeZIekOy5ahQ8EWfT330hvYGVeDYkBxXBva.", Sha2Crypt.sha256Crypt("secret".getBytes(Charsets.UTF_8), "$5$rounds=50$abcd$"));
+        assertEquals("$5$rounds=1001$abcd$SQsJZs7KXKdd2DtklI3TY3tkD7UYA99RD0FBLm4Sk48", Sha2Crypt.sha256Crypt("secret".getBytes(Charsets.UTF_8), "$5$rounds=1001$abcd$"));
+        assertEquals("$5$rounds=9999$abcd$Rh/8ngVh9oyuS6lL3.fsq.9xbvXJsfyKWxSjO2mPIa7", Sha2Crypt.sha256Crypt("secret".getBytes(Charsets.UTF_8), "$5$rounds=9999$abcd"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSha2CryptWrongSalt() {
+        Sha2Crypt.sha512Crypt("secret".getBytes(Charsets.UTF_8), "xx");
+    }
+
     @Test(expected = IllegalArgumentException.class)
-    public void testSha512CryptWithEmptySalt() throws NoSuchAlgorithmException {
+    public void testSha512CryptWithEmptySalt() {
         Sha2Crypt.sha512Crypt("secret".getBytes(), "");
     }
+
+    @Test
+    public void testSha256LargetThanBlocksize() {
+        byte[] buffer = new byte[200];
+        Arrays.fill(buffer, 0, 200, (byte)'A');
+        assertEquals("$6$abc$oP/h8PRhCKIA66KSTjGwNsQMSLLZnuFOTjOhrqNrDkKgjTlpePSqibB0qtmDapMbP/zN1cUEYSeHFrpgqZ.GG1", Sha2Crypt.sha512Crypt(buffer, "$6$abc"));
+    }
 }

Modified: commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/UnixCryptTest.java
URL: http://svn.apache.org/viewvc/commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/UnixCryptTest.java?rev=1379782&r1=1379781&r2=1379782&view=diff
==============================================================================
--- commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/UnixCryptTest.java (original)
+++ commons/proper/codec/trunk/src/test/java/org/apache/commons/codec/digest/UnixCryptTest.java Sat Sep  1 15:57:33 2012
@@ -16,18 +16,22 @@
  */
 package org.apache.commons.codec.digest;
 
+import org.apache.commons.codec.Charsets;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
-
-import java.security.NoSuchAlgorithmException;
-
-import org.apache.commons.codec.Charsets;
 import org.junit.Test;
 
 public class UnixCryptTest {
 
     @Test
-    public void testUnixCryptStrings() throws NoSuchAlgorithmException {
+    public void testCtor() {
+        assertNotNull(new UnixCrypt());
+    }
+
+    @Test
+    public void testUnixCryptStrings() {
         // trivial test
         assertEquals("xxWAum7tHdIUw", Crypt.crypt("secret", "xx"));
         // empty data
@@ -38,7 +42,7 @@ public class UnixCryptTest {
     }
 
     @Test
-    public void testUnixCryptBytes() throws NoSuchAlgorithmException {
+    public void testUnixCryptBytes() {
         // An empty Bytearray equals an empty String
         assertEquals("12UFlHxel6uMM", Crypt.crypt(new byte[0], "12"));
         // UTF-8 stores \u00e4 "a with diaeresis" as two bytes 0xc3 0xa4.
@@ -60,6 +64,16 @@ public class UnixCryptTest {
     }
 
     /**
+     * Single character salts are illegal!
+     * E.g. with glibc 2.13, crypt("secret", "x") = "xxZREZpkHZpkI" but
+     * crypt("secret", "xx") = "xxWAum7tHdIUw" which makes it unverifyable.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testUnixCryptWithHalfSalt() {
+        UnixCrypt.crypt("secret", "x");
+    }
+
+    /**
      * Unimplemented "$foo$" salt prefixes would be threated as UnixCrypt salt.
      */
     @Test(expected = IllegalArgumentException.class)
@@ -76,4 +90,12 @@ public class UnixCryptTest {
     public void testUnixCryptWithEmptySalt() {
         UnixCrypt.crypt("secret", "");
     }
+
+    @Test
+    public void testUnixCryptWithoutSalt() {
+        String hash = UnixCrypt.crypt("foo");
+        assertTrue(hash.matches("^[a-zA-Z0-9./]{13}$"));
+        String hash2 = UnixCrypt.crypt("foo");
+        assertNotSame(hash, hash2);
+    }
 }