[jboss-svn-commits] JBL Code SVN: r35200 - in labs/jbossrules/trunk: drools-compiler/src/test/resources/org/drools/integrationtests and 9 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Sep 20 18:17:32 EDT 2010
Author: tirelli
Date: 2010-09-20 18:17:32 -0400 (Mon, 20 Sep 2010)
New Revision: 35200
Added:
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/droolsClient.keystore
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/droolsServer.keystore
labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/droolsClient.keystore
labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/droolsServer.keystore
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/KeyStoreHelper.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/core/
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/core/util/
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/core/util/KeyStoreHelperTest.java
labs/jbossrules/trunk/drools-core/src/test/resources/org/drools/core/
labs/jbossrules/trunk/drools-core/src/test/resources/org/drools/core/util/
labs/jbossrules/trunk/drools-core/src/test/resources/org/drools/core/util/droolsClient.keystore
labs/jbossrules/trunk/drools-core/src/test/resources/org/drools/core/util/droolsServer.keystore
Modified:
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MarshallingTest.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/JavaDialectRuntimeData.java
Log:
JBRULES-2702: porting fix to trunk
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MarshallingTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MarshallingTest.java 2010-09-20 20:19:30 UTC (rev 35199)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MarshallingTest.java 2010-09-20 22:17:32 UTC (rev 35200)
@@ -11,6 +11,7 @@
import java.io.OptionalDataException;
import java.io.Reader;
import java.io.StringReader;
+import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -48,6 +49,7 @@
import org.drools.compiler.PackageBuilder;
import org.drools.compiler.PackageBuilderConfiguration;
import org.drools.core.util.DroolsStreamUtils;
+import org.drools.core.util.KeyStoreHelper;
import org.drools.impl.EnvironmentFactory;
import org.drools.impl.KnowledgeBaseImpl;
import org.drools.impl.StatefulKnowledgeSessionImpl;
@@ -1058,6 +1060,170 @@
}
+ /*
+ * Testing the signature framework
+ */
+ public void testSignedSerialization1() throws Exception {
+ try {
+ setPrivateKeyProperties();
+ setPublicKeyProperties();
+
+ //Compile a package
+ PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_Dynamic1_0.drl" ) ) );
+
+ // Test package serialization/deserialization
+ Package pkg = SerializationHelper.serializeObject( builder.getPackage() );
+
+ // Create a rulebase
+ RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ ruleBase.addPackage( pkg );
+
+ // Test rulebase serialization/deserialization
+ byte[] serializedRulebase = DroolsStreamUtils.streamOut( ruleBase );
+ ruleBase = (RuleBase) DroolsStreamUtils.streamIn( serializedRulebase );
+ } finally {
+ unsetPrivateKeyProperties();
+ unsetPublicKeyProperties();
+ }
+ }
+
+ /*
+ * Deserializing a signed package without the proper public key
+ * should fail.
+ */
+ public void testSignedSerialization2() throws Exception {
+ try {
+ // set only the serialisation properties, but not the deserialization
+ setPrivateKeyProperties();
+
+ //Compile a package
+ PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_Dynamic1_0.drl" ) ) );
+
+ try {
+ // Test package serialization/deserialization
+ Package pkg = SerializationHelper.serializeObject( builder.getPackage() );
+ fail( "Deserialisation should have failed." );
+ } catch ( Exception e ) {
+ // success
+ }
+ } finally {
+ unsetPrivateKeyProperties();
+ }
+ }
+
+ /*
+ * Deserializing a signed rulebase without the proper public key
+ * should fail.
+ */
+ public void testSignedSerialization3() throws Exception {
+ try {
+ // set only the serialisation properties, but not the deserialization
+ setPrivateKeyProperties();
+
+ //Compile a package
+ PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_Dynamic1_0.drl" ) ) );
+
+ // Create a rulebase
+ RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ ruleBase.addPackage( builder.getPackage() );
+
+ // Test rulebase serialization/deserialization
+ byte[] serializedRulebase = DroolsStreamUtils.streamOut( ruleBase );
+
+ try {
+ ruleBase = (RuleBase) DroolsStreamUtils.streamIn( serializedRulebase );
+ fail( "Deserialisation should have failed." );
+ } catch ( Exception e ) {
+ // success
+ }
+ } finally {
+ unsetPrivateKeyProperties();
+ }
+ }
+
+ /*
+ * A client environment configured to use signed serialization
+ * should refuse any non-signed serialized rulebase
+ */
+ public void testSignedSerialization4() throws Exception {
+
+ //Compile a package
+ PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_Dynamic1_0.drl" ) ) );
+
+ // Create a rulebase
+ RuleBase ruleBase = RuleBaseFactory.newRuleBase();
+ ruleBase.addPackage( builder.getPackage() );
+
+ // Test rulebase serialization/deserialization
+ byte[] serializedRulebase = DroolsStreamUtils.streamOut( ruleBase );
+
+ try {
+ // set only the deserialisation properties, but not the serialization
+ setPublicKeyProperties();
+ ruleBase = (RuleBase) DroolsStreamUtils.streamIn( serializedRulebase );
+ fail( "Should not deserialize an unsigned rulebase on an environment configured to work with signed rulebases." );
+ } catch ( Exception e ) {
+ // success
+ } finally {
+ unsetPublicKeyProperties();
+ }
+ }
+
+ private void setPublicKeyProperties() {
+ // Set the client properties to de-serialise the signed packages
+ URL clientKeyStoreURL = getClass().getResource( "droolsClient.keystore" );
+ System.setProperty( KeyStoreHelper.PROP_SIGN,
+ "true" );
+ System.setProperty( KeyStoreHelper.PROP_PUB_KS_URL,
+ clientKeyStoreURL.toExternalForm() );
+ System.setProperty( KeyStoreHelper.PROP_PUB_KS_PWD,
+ "clientpwd" );
+ }
+
+ private void unsetPublicKeyProperties() {
+ // Un-set the client properties to de-serialise the signed packages
+ System.setProperty( KeyStoreHelper.PROP_SIGN,
+ "" );
+ System.setProperty( KeyStoreHelper.PROP_PUB_KS_URL,
+ "" );
+ System.setProperty( KeyStoreHelper.PROP_PUB_KS_PWD,
+ "" );
+ }
+
+ private void setPrivateKeyProperties() {
+ // Set the server properties to serialise the signed packages
+ URL serverKeyStoreURL = getClass().getResource( "droolsServer.keystore" );
+ System.setProperty( KeyStoreHelper.PROP_SIGN,
+ "true" );
+ System.setProperty( KeyStoreHelper.PROP_PVT_KS_URL,
+ serverKeyStoreURL.toExternalForm() );
+ System.setProperty( KeyStoreHelper.PROP_PVT_KS_PWD,
+ "serverpwd" );
+ System.setProperty( KeyStoreHelper.PROP_PVT_ALIAS,
+ "droolsKey" );
+ System.setProperty( KeyStoreHelper.PROP_PVT_PWD,
+ "keypwd" );
+ }
+
+ private void unsetPrivateKeyProperties() {
+ // Un-set the server properties to serialise the signed packages
+ System.setProperty( KeyStoreHelper.PROP_SIGN,
+ "" );
+ System.setProperty( KeyStoreHelper.PROP_PVT_KS_URL,
+ "" );
+ System.setProperty( KeyStoreHelper.PROP_PVT_KS_PWD,
+ "" );
+ System.setProperty( KeyStoreHelper.PROP_PVT_ALIAS,
+ "" );
+ System.setProperty( KeyStoreHelper.PROP_PVT_PWD,
+ "" );
+ }
+
+
/**
* In this case we are dealing with facts which are not on the systems classpath.
*
Copied: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/droolsClient.keystore (from rev 35196, labs/jbossrules/branches/4.0.x/drools-compiler/src/test/java/org/drools/integrationtests/droolsClient.keystore)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/droolsServer.keystore (from rev 35196, labs/jbossrules/branches/4.0.x/drools-compiler/src/test/java/org/drools/integrationtests/droolsServer.keystore)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/droolsClient.keystore (from rev 35196, labs/jbossrules/branches/4.0.x/drools-compiler/src/test/resources/org/drools/integrationtests/droolsClient.keystore)
===================================================================
(Binary files differ)
Copied: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/droolsServer.keystore (from rev 35196, labs/jbossrules/branches/4.0.x/drools-compiler/src/test/resources/org/drools/integrationtests/droolsServer.keystore)
===================================================================
(Binary files differ)
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java 2010-09-20 20:19:30 UTC (rev 35199)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/RuleBaseConfiguration.java 2010-09-20 22:17:32 UTC (rev 35200)
@@ -108,6 +108,8 @@
KnowledgeBaseConfiguration,
Externalizable {
private static final long serialVersionUID = 510l;
+
+ public static final String DEFAULT_SIGN_ON_SERIALIZATION = "false";
private ChainedProperties chainedProperties;
Copied: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/KeyStoreHelper.java (from rev 35196, labs/jbossrules/branches/4.0.x/drools-core/src/main/java/org/drools/util/KeyStoreHelper.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/KeyStoreHelper.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/core/util/KeyStoreHelper.java 2010-09-20 22:17:32 UTC (rev 35200)
@@ -0,0 +1,220 @@
+/**
+ *
+ */
+package org.drools.core.util;
+
+import java.io.IOException;
+import java.net.URL;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.Properties;
+
+import org.drools.RuleBaseConfiguration;
+import org.drools.RuntimeDroolsException;
+
+/**
+ * A helper class to deal with the key store and signing process during
+ * Serialisation
+ *
+ * This class will read and use the following system properties:
+ *
+ * drools.serialisation.sign = <false|true>
+ * drools.serialisation.private.keyStoreURL = <URL>
+ * drools.serialisation.private.keyStorePwd = <password>
+ * drools.serialisation.private.keyAlias = <key>
+ * drools.serialisation.private.keyPwd = <password>
+ * drools.serialisation.public.keyStoreURL = <URL>
+ * drools.serialisation.public.keyStorePwd = <password>
+ *
+ * @author etirelli
+ *
+ */
+public class KeyStoreHelper {
+
+ // true if packages should be signed during serialization
+ public static final String PROP_SIGN = "drools.serialisation.sign";
+ // the URL to the key store where the private key is stored
+ public static final String PROP_PVT_KS_URL = "drools.serialisation.private.keyStoreURL";
+ // the key store password
+ public static final String PROP_PVT_KS_PWD = "drools.serialisation.private.keyStorePwd";
+ // the private key identifier
+ public static final String PROP_PVT_ALIAS = "drools.serialisation.private.keyAlias";
+ // the private key password
+ public static final String PROP_PVT_PWD = "drools.serialisation.private.keyPwd";
+ // the URL to the key store where the public key is stored
+ public static final String PROP_PUB_KS_URL = "drools.serialisation.public.keyStoreURL";
+ // the key store password
+ public static final String PROP_PUB_KS_PWD = "drools.serialisation.public.keyStorePwd";
+
+ private boolean signed;
+ private URL pvtKeyStoreURL;
+ private char[] pvtKeyStorePwd;
+ private String pvtKeyAlias;
+ private char[] pvtKeyPassword;
+ private URL pubKeyStoreURL;
+ private char[] pubKeyStorePwd;
+
+ private KeyStore pvtKeyStore;
+ private KeyStore pubKeyStore;
+
+ /**
+ * Creates a KeyStoreHelper and initialises the KeyStore, by loading its entries.
+ *
+ * @throws RuntimeDroolsException in case any error happens when initialising and loading the keystore.
+ */
+ public KeyStoreHelper() {
+ try {
+ Properties prop = System.getProperties();
+ this.signed = Boolean.valueOf( prop.getProperty( PROP_SIGN,
+ RuleBaseConfiguration.DEFAULT_SIGN_ON_SERIALIZATION ) ).booleanValue();
+ String url = prop.getProperty( PROP_PVT_KS_URL,
+ "" );
+ if ( url.length() > 0 ) {
+ this.pvtKeyStoreURL = new URL( url );
+ }
+ this.pvtKeyStorePwd = prop.getProperty( PROP_PVT_KS_PWD,
+ "" ).toCharArray();
+ this.pvtKeyAlias = prop.getProperty( PROP_PVT_ALIAS,
+ "" );
+ this.pvtKeyPassword = prop.getProperty( PROP_PVT_PWD,
+ "" ).toCharArray();
+
+ url = prop.getProperty( PROP_PUB_KS_URL,
+ "" );
+ if ( url.length() > 0 ) {
+ this.pubKeyStoreURL = new URL( url );
+ }
+ this.pubKeyStorePwd = prop.getProperty( PROP_PUB_KS_PWD,
+ "" ).toCharArray();
+ initKeyStore();
+ } catch ( Exception e ) {
+ throw new RuntimeDroolsException( "Error initialising KeyStore: " + e.getMessage(),
+ e );
+ }
+ }
+
+ private void initKeyStore() throws NoSuchAlgorithmException,
+ CertificateException,
+ IOException,
+ KeyStoreException {
+ if ( pvtKeyStoreURL != null ) {
+ this.pvtKeyStore = KeyStore.getInstance( "JKS" );
+ this.pvtKeyStore.load( pvtKeyStoreURL.openStream(),
+ pvtKeyStorePwd );
+ }
+ if ( pubKeyStoreURL != null ) {
+ this.pubKeyStore = KeyStore.getInstance( "JKS" );
+ this.pubKeyStore.load( pubKeyStoreURL.openStream(),
+ pubKeyStorePwd );
+ }
+ }
+
+ /**
+ * Generates the signature for the given byte[] using MD5 with RSA algorithm and the
+ * private key with which this helper was initialised.
+ *
+ * @param data the byte[] of data to be signed
+ *
+ * @return the signature, encrypted with the private key
+ *
+ * @throws UnrecoverableKeyException
+ * @throws KeyStoreException
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeyException
+ * @throws SignatureException
+ */
+ public byte[] signDataWithPrivateKey(byte[] data) throws UnrecoverableKeyException,
+ KeyStoreException,
+ NoSuchAlgorithmException,
+ InvalidKeyException,
+ SignatureException {
+ if( pvtKeyStore == null ) {
+ throw new RuntimeDroolsException( "Key store with private key not configured. Please configure it properly before using signed serialization." );
+ }
+ PrivateKey pvtkey = (PrivateKey) pvtKeyStore.getKey( pvtKeyAlias,
+ pvtKeyPassword );
+ Signature sig = Signature.getInstance( "MD5withRSA" );
+ sig.initSign( pvtkey );
+ sig.update( data );
+ return sig.sign();
+ }
+
+ /**
+ * Checks the given byte[] data against the signature, using the
+ * public key with which this helper was initialised and the algorithm
+ * MD5 with RSA.
+ *
+ * @param data the original data that was signed
+ * @param signature the provided signature
+ *
+ * @return true in case the signature matches, false otherwise.
+ *
+ * @throws KeyStoreException
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeyException
+ * @throws SignatureException
+ */
+ public boolean checkDataWithPublicKey(final String publicKeyAlias,
+ final byte[] data,
+ final byte[] signature) throws KeyStoreException,
+ NoSuchAlgorithmException,
+ InvalidKeyException,
+ SignatureException {
+ if( pvtKeyStore == null ) {
+ throw new RuntimeDroolsException( "Key store with public key not configured. Please configure it properly before using signed serialization." );
+ }
+ Certificate cert = pubKeyStore.getCertificate( publicKeyAlias );
+ if( cert == null ) {
+ throw new RuntimeDroolsException( "Public certificate for key '"+publicKeyAlias+"' not found in the configured key store. Impossible to deserialize the object." );
+ }
+ Signature sig = Signature.getInstance( "MD5withRSA" );
+ sig.initVerify( cert.getPublicKey() );
+ sig.update( data );
+ return sig.verify( signature );
+ }
+
+ public boolean isSigned() {
+ return signed;
+ }
+
+ public URL getPvtKeyStoreURL() {
+ return pvtKeyStoreURL;
+ }
+
+ public char[] getPvtKeyStorePwd() {
+ return pvtKeyStorePwd;
+ }
+
+ public String getPvtKeyAlias() {
+ return pvtKeyAlias;
+ }
+
+ public char[] getPvtKeyPassword() {
+ return pvtKeyPassword;
+ }
+
+ public URL getPubKeyStoreURL() {
+ return pubKeyStoreURL;
+ }
+
+ public char[] getPubKeyStorePwd() {
+ return pubKeyStorePwd;
+ }
+
+ public KeyStore getPvtKeyStore() {
+ return pvtKeyStore;
+ }
+
+ public KeyStore getPubKeyStore() {
+ return pubKeyStore;
+ }
+
+}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/JavaDialectRuntimeData.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/JavaDialectRuntimeData.java 2010-09-20 20:19:30 UTC (rev 35199)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/rule/JavaDialectRuntimeData.java 2010-09-20 22:17:32 UTC (rev 35200)
@@ -17,14 +17,21 @@
package org.drools.rule;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.Externalizable;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
+import java.io.ObjectInputStream;
import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
import java.security.AccessController;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
+import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -34,8 +41,9 @@
import java.util.Map.Entry;
import org.drools.RuntimeDroolsException;
-import org.drools.common.DroolsObjectInput;
+import org.drools.common.DroolsObjectInputStream;
import org.drools.core.util.DroolsClassLoader;
+import org.drools.core.util.KeyStoreHelper;
import org.drools.core.util.StringUtils;
import org.drools.spi.Wireable;
@@ -85,12 +93,31 @@
*
*/
public void writeExternal(ObjectOutput stream) throws IOException {
- stream.writeInt( this.store.size() );
+ KeyStoreHelper helper = new KeyStoreHelper();
+
+ stream.writeBoolean( helper.isSigned() );
+ if ( helper.isSigned() ) {
+ stream.writeObject( helper.getPvtKeyAlias() );
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutput out = new ObjectOutputStream( bos );
+
+ out.writeInt( this.store.size() );
for ( Iterator it = this.store.entrySet().iterator(); it.hasNext(); ) {
Entry entry = (Entry) it.next();
- stream.writeObject( entry.getKey() );
- stream.writeObject( entry.getValue() );
+ out.writeObject( entry.getKey() );
+ out.writeObject( entry.getValue() );
}
+ out.flush();
+ out.close();
+ byte[] buff = bos.toByteArray();
+ stream.writeObject( buff );
+ if ( helper.isSigned() ) {
+ sign( stream,
+ helper,
+ buff );
+ }
stream.writeInt( this.invokerLookups.size() );
for ( Iterator it = this.invokerLookups.entrySet().iterator(); it.hasNext(); ) {
@@ -98,8 +125,20 @@
stream.writeObject( entry.getKey() );
stream.writeObject( entry.getValue() );
}
+
}
+ private void sign(final ObjectOutput stream,
+ KeyStoreHelper helper,
+ byte[] buff) {
+ try {
+ stream.writeObject( helper.signDataWithPrivateKey( buff ) );
+ } catch ( Exception e ) {
+ throw new RuntimeDroolsException( "Error signing object store: " + e.getMessage(),
+ e );
+ }
+ }
+
/**
* Handles the read serialization of the PackageCompilationData. Patterns in Rules may reference generated data which cannot be serialized by
* default methods. The PackageCompilationData holds a reference to the generated bytecode; which must be restored before any Rules.
@@ -108,19 +147,74 @@
*/
public void readExternal(ObjectInput stream) throws IOException,
ClassNotFoundException {
- DroolsObjectInput droolsStream = (DroolsObjectInput) stream;
- for ( int i = 0, length = stream.readInt(); i < length; i++ ) {
- this.store.put( stream.readObject(),
- stream.readObject() );
+ KeyStoreHelper helper = new KeyStoreHelper();
+ boolean signed = stream.readBoolean();
+ if ( helper.isSigned() != signed ) {
+ throw new RuntimeDroolsException( "This environment is configured to work with " +
+ (helper.isSigned() ? "signed" : "unsigned") +
+ " serialized objects, but the given object is " +
+ (signed ? "signed" : "unsigned") + ". Deserialization aborted." );
}
+ String pubKeyAlias = null;
+ if ( signed ) {
+ pubKeyAlias = (String) stream.readObject();
+ if ( helper.getPubKeyStore() == null ) {
+ throw new RuntimeDroolsException( "The package was serialized with a signature. Please configure a public keystore with the public key to check the signature. Deserialization aborted." );
+ }
+ }
+
+ // Return the object stored as a byte[]
+ byte[] bytes = (byte[]) stream.readObject();
+ if ( signed ) {
+ checkSignature( stream,
+ helper,
+ bytes,
+ pubKeyAlias );
+ }
+
+ ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream( bytes ) );
+ for ( int i = 0, length = in.readInt(); i < length; i++ ) {
+ this.store.put( in.readObject(),
+ in.readObject() );
+ }
+ in.close();
+
for ( int i = 0, length = stream.readInt(); i < length; i++ ) {
this.invokerLookups.put( stream.readObject(),
stream.readObject() );
}
+
// mark it as dirty, so that it reloads everything.
this.dirty = true;
}
+ private void checkSignature(final ObjectInput stream,
+ final KeyStoreHelper helper,
+ final byte[] bytes,
+ final String pubKeyAlias) throws ClassNotFoundException,
+ IOException {
+ byte[] signature = (byte[]) stream.readObject();
+ try {
+ if ( !helper.checkDataWithPublicKey( pubKeyAlias,
+ bytes,
+ signature ) ) {
+ throw new RuntimeDroolsException( "Signature does not match serialized package. This is a security violation. Deserialisation aborted." );
+ }
+ } catch ( InvalidKeyException e ) {
+ throw new RuntimeDroolsException( "Invalid key checking signature: " + e.getMessage(),
+ e );
+ } catch ( KeyStoreException e ) {
+ throw new RuntimeDroolsException( "Error accessing Key Store: " + e.getMessage(),
+ e );
+ } catch ( NoSuchAlgorithmException e ) {
+ throw new RuntimeDroolsException( "No algorithm available: " + e.getMessage(),
+ e );
+ } catch ( SignatureException e ) {
+ throw new RuntimeDroolsException( "Signature Exception: " + e.getMessage(),
+ e );
+ }
+ }
+
public void onAdd(DialectRuntimeRegistry registry,
DroolsCompositeClassLoader rootClassLoader) {
this.registry = registry;
@@ -215,15 +309,15 @@
public void removeRule(Package pkg,
Rule rule) {
-
+
if ( !(rule instanceof Query) ) {
// Query's don't have a consequence, so skip those
final String consequenceName = rule.getConsequence().getClass().getName();
-
+
// check for compiled code and remove if present.
if ( remove( consequenceName ) ) {
removeClasses( rule.getLhs() );
-
+
// Now remove the rule class - the name is a subset of the consequence name
String sufix = StringUtils.ucFirst( rule.getConsequence().getName() ) + "ConsequenceInvoker";
remove( consequenceName.substring( 0,
@@ -474,13 +568,13 @@
public Class< ? > loadClass(final String name,
final boolean resolve) throws ClassNotFoundException {
try {
- if( cache.containsKey( name ) ) {
+ if ( cache.containsKey( name ) ) {
this.cacheHits++;
Object result = cache.get( name );
- if( result instanceof ClassNotFoundException ) {
+ if ( result instanceof ClassNotFoundException ) {
throw (ClassNotFoundException) result;
} else {
- return (Class<?>) result;
+ return (Class< ? >) result;
}
}
Class< ? > cls = fastFindClass( name );
@@ -500,11 +594,13 @@
} else {
this.failedCalls++;
}
- cache.put( name, cls );
+ cache.put( name,
+ cls );
return cls;
} catch ( ClassNotFoundException e ) {
this.failedCalls++;
- cache.put( name, e );
+ cache.put( name,
+ e );
throw e;
}
}
@@ -520,7 +616,7 @@
}
return null;
}
-
+
public void reset() {
this.cacheHits = this.failedCalls = this.successfulCalls = 0;
this.cache.clear();
Copied: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/core/util/KeyStoreHelperTest.java (from rev 35196, labs/jbossrules/branches/4.0.x/drools-core/src/test/java/org/drools/util/KeyStoreHelperTest.java)
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/core/util/KeyStoreHelperTest.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/core/util/KeyStoreHelperTest.java 2010-09-20 22:17:32 UTC (rev 35200)
@@ -0,0 +1,61 @@
+package org.drools.core.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.security.InvalidKeyException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
+import java.security.UnrecoverableKeyException;
+
+import junit.framework.TestCase;
+
+import org.drools.core.util.KeyStoreHelper;
+
+public class KeyStoreHelperTest extends TestCase {
+
+ public void testSignDataWithPrivateKey() throws UnsupportedEncodingException,
+ UnrecoverableKeyException,
+ InvalidKeyException,
+ KeyStoreException,
+ NoSuchAlgorithmException,
+ SignatureException {
+ // The server signs the data with the private key
+
+ // Set properties to simulate the server
+ URL serverKeyStoreURL = getClass().getResource( "droolsServer.keystore" );
+ System.setProperty( KeyStoreHelper.PROP_SIGN, "true" );
+ System.setProperty( KeyStoreHelper.PROP_PVT_KS_URL, serverKeyStoreURL.toExternalForm() );
+ System.setProperty( KeyStoreHelper.PROP_PVT_KS_PWD, "serverpwd" );
+ System.setProperty( KeyStoreHelper.PROP_PVT_ALIAS, "droolsKey" );
+ System.setProperty( KeyStoreHelper.PROP_PVT_PWD, "keypwd" );
+ KeyStoreHelper serverHelper = new KeyStoreHelper();
+
+ // get some data to sign
+ byte[] data = "Hello World".getBytes( "UTF8" );
+
+ // sign the data
+ byte[] signature = serverHelper.signDataWithPrivateKey( data );
+
+ // now, initialise the client helper
+
+ // Set properties to simulate the client
+ URL clientKeyStoreURL = getClass().getResource( "droolsClient.keystore" );
+ System.setProperty( KeyStoreHelper.PROP_SIGN, "true" );
+ System.setProperty( KeyStoreHelper.PROP_PUB_KS_URL, clientKeyStoreURL.toExternalForm() );
+ System.setProperty( KeyStoreHelper.PROP_PUB_KS_PWD, "clientpwd" );
+ // client needs no password to access the certificate and public key
+ KeyStoreHelper clientHelper = new KeyStoreHelper( );
+
+ // check the signature against the data
+ assertTrue( clientHelper.checkDataWithPublicKey( "droolsKey",
+ data,
+ signature ) );
+
+ // check some fake data
+ assertFalse( clientHelper.checkDataWithPublicKey( "droolsKey",
+ "fake".getBytes( "UTF8" ),
+ signature ) );
+ }
+
+}
Added: labs/jbossrules/trunk/drools-core/src/test/resources/org/drools/core/util/droolsClient.keystore
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/drools-core/src/test/resources/org/drools/core/util/droolsClient.keystore
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: labs/jbossrules/trunk/drools-core/src/test/resources/org/drools/core/util/droolsServer.keystore
===================================================================
(Binary files differ)
Property changes on: labs/jbossrules/trunk/drools-core/src/test/resources/org/drools/core/util/droolsServer.keystore
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
More information about the jboss-svn-commits
mailing list