package org.cesecore.internal;
import static org.junit.Assert.assertTrue;
import java.io.UnsupportedEncodingException;
import java.lang.Thread.State;
import java.util.HashMap;
import org.apache.log4j.Logger;
import org.junit.Test;
/**
* @version $Id: UpgradeableDataHashMapTest.java 12784 2011-10-01 15:28:38Z anatom $
*/
public class UpgradeableDataHashMapTest {
static final Logger log = Logger.getLogger(UpgradeableDataHashMapTest.class);
/**
* Test if UpgradeableDataHashMap is vulnerable to CVE-2010-4476 through
* the XML Serialization we use for storing UpgradeableDataHashMap.
*
* When "2.2250738585072012e-308" is converted to a float, the code toggles
* between two values causing the the Thread to hang.
*
* UpgradeableDataHashMap.VERSION is normally stored as a Float.
*/
@Test
public void testCVE_2010_4476() {
final String XML_W_BADFLOAT = ""
+ "";
final String XML_W_BADDERFLOAT = ""
+ "";
final String FAIL_MESSAGE = "JDK is vulnerable to CVE-2010-4476 (requires write access to EJBCA database to exploit).";
assertTrue(FAIL_MESSAGE, new DecoderThread(XML_W_BADFLOAT).execute());
assertTrue(FAIL_MESSAGE, new DecoderThread(XML_W_BADDERFLOAT).execute());
}
/** Separate thread for test that might hang. */
class DecoderThread implements Runnable { // NOPMD this is a stand-alone test, not a part of a JEE application
final String decodeXML;
DecoderThread(String decodeXML) {
this.decodeXML = decodeXML;
}
protected boolean execute() {
Thread t = new Thread(this); // NOPMD this is a stand-alone test, not a part of a JEE application
t.start();
try {
t.join(4000); //Wait 5 seconds for thread to complete
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!t.getState().equals(State.TERMINATED)) {
t.interrupt();
return false;
}
return true;
}
@SuppressWarnings("unchecked")
@Override
public void run() {
try {
final java.beans.XMLDecoder decoder = new java.beans.XMLDecoder(new java.io.ByteArrayInputStream(decodeXML.getBytes("UTF8")));
final HashMap