package org.owasp.esapi.reference.crypto;

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;

/**
 * Helper class to see if unlimited strength crypto is available. If it is
 * not, then symmetric encryption algorithms are restricted to 128-bit
 * key size or the encryption must provide key weakening or key escrow.
 * <p>
 * This program attempts to generate a 256-bit AES key and use it to do
 * to a simple encryption. If the encryption succeeds, the assumption is
 * that the JVM being used has the "unlimited" strength JCE jurisdiction
 * policy files installed.
 * </p><p>
 * We use this for JUnit tests. If unlimited strength crypto is not available,
 * we simply skip certain JUnit tests that would require it.
 */
public class CryptoPolicy {

    private static boolean checked = false;
    private static boolean unlimited = false;

    /**
     * Check to see if unlimited strength crypto is available.
     * There is an implicit assumption that the JCE jurisdiction policy
     * files are not going to be changing while this given JVM is running.
     *
     * @return True if we can provide keys longer than 128 bits.
     */
    public synchronized static boolean isUnlimitedStrengthCryptoAvailable()
    {
        if ( checked == false ) {
            unlimited = checkCrypto();
            checked = true;
        }
        return unlimited;
    }

    private static boolean checkCrypto()
    {
        try {
            KeyGenerator keyGen = KeyGenerator.getInstance("AES");
            keyGen.init(256);   // Max sym key size is 128 unless unlimited
                                // strength jurisdiction policy files installed.
            SecretKey skey = keyGen.generateKey();
            byte[] raw = skey.getEncoded();
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
            
                // This usually will throw InvalidKeyException unless the
                // unlimited jurisdiction policy files are installed. However,
                // it can succeed even if it's not a provider chooses to use
                // an exemption mechanism such as key escrow, key recovery, or
                // key weakening for this cipher instead.
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            
                // Try the encryption on dummy string to make sure it works.
                // Not using padding so # bytes must be multiple of AES cipher
                // block size which is 16 bytes. Also, OK not to use UTF-8 here.
            byte[] encrypted = cipher.doFinal("1234567890123456".getBytes());
            assert encrypted != null : "Encryption of test string failed!";
            ExemptionMechanism em = cipher.getExemptionMechanism();
            if ( em != null ) {
                System.out.println("Cipher uses exemption mechanism " + em.getName());
                return false;   // This is actually an indeterminate case, but
                                // we can't bank on it at least for this
                                // (default) provider.
            }
        } catch( InvalidKeyException ikex ) {
            System.out.println("Invalid key size - unlimited strength crypto NOT installed!");
            return false;
        } catch( Exception ex ) {
            System.out.println("Caught unexpected exception: " + ex);
            ex.printStackTrace(System.out);
            return false;
        }
        return true;
    }

    public static void main(String[] args)
    {
        if ( isUnlimitedStrengthCryptoAvailable() ) {
            System.out.println("Unlimited strength crypto IS available.");
        } else {
            System.out.println("Unlimited strength crypto is NOT available.");
        }
        System.exit( isUnlimitedStrengthCryptoAvailable() ? 0 : 1 );
    }
}
@@ -737,16 +737,728 @@
 ire it.%0A
+ * %3C/p%3E%3Cp%3E%0A * The reason for not adding this class to ESAPI proper is because its mostly%0A * pointless to find out at runtime that you don't have the unlimited strength%0A * JCE jurisdiction policy files installed. If you don't, you're SOL until you%0A * install them and even if you could do that from a running JVM, chances are%0A * slim to none that one could easily get your JCE provider to work with them.%0A * (Well, one %3Ci%3Emight%3C/i%3E be able to unload the JCE classes, but you hopefully%0A * are not running your JVM process as 'root' or other privileged account%0A * anyway, so you probably can't install these policy files from your JVM in%0A * the first place.)%0A * %3C/p%3E%0A * @author kevin.w.wall@gmail.com%0A * @since 2.0%0A
  */%0Apubl

Improve class javadoc.