You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2014/07/02 09:47:49 UTC

svn commit: r1607266 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/services/jce/ engine/org/apache/derby/loc/ shared/org/apache/derby/shared/common/reference/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derby...

Author: kahatlen
Date: Wed Jul  2 07:47:49 2014
New Revision: 1607266

URL: http://svn.apache.org/r1607266
Log:
DERBY-6626: Check type of user-supplied modules before creating instances

Check that the encryptionProvider connection attribute specifies an
implementation of java.security.Provider before trying to create an
instance of it.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptParams.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptParams.sql

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java?rev=1607266&r1=1607265&r2=1607266&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java Wed Jul  2 07:47:49 2014
@@ -24,29 +24,23 @@ package org.apache.derby.impl.services.j
 import org.apache.derby.iapi.services.crypto.CipherFactory;
 import org.apache.derby.iapi.services.crypto.CipherProvider;
 
-import org.apache.derby.iapi.services.monitor.Monitor;
-import org.apache.derby.shared.common.sanity.SanityManager;
-
 import org.apache.derby.iapi.error.StandardException;
 
-import org.apache.derby.iapi.services.info.JVMInfo;
-import org.apache.derby.iapi.util.StringUtil;
-
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.reference.Attribute;
 import org.apache.derby.iapi.util.StringUtil;
 
 import java.util.Properties;
 import java.util.Enumeration;
-import java.security.Key;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
 import java.security.Provider;
 import java.security.SecureRandom;
 import java.security.Security;
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
 import java.security.MessageDigest;
-import java.security.spec.KeySpec;
-import java.security.spec.InvalidKeySpecException;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -54,13 +48,11 @@ import java.io.DataInputStream;
 
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
 import javax.crypto.spec.DESKeySpec;
 import javax.crypto.spec.SecretKeySpec;
 import org.apache.derby.iapi.store.raw.RawStoreFactory;
 
 import org.apache.derby.io.StorageFactory;
-import org.apache.derby.io.WritableStorageFactory;
 import org.apache.derby.io.StorageFile;
 import org.apache.derby.io.StorageRandomAccessFile;
 /**
@@ -68,7 +60,7 @@ import org.apache.derby.io.StorageRandom
 
 	@see CipherFactory
  */
-public final class JCECipherFactory implements CipherFactory, java.security.PrivilegedExceptionAction<Object>
+public final class JCECipherFactory implements CipherFactory
 {
     private final static String MESSAGE_DIGEST = "MD5";
 
@@ -110,9 +102,6 @@ public final class JCECipherFactory impl
 	    This does not include the MD5 checksum bytes
 	 */
 	private final static int VERIFYKEY_DATALEN = 4096;
-	private StorageFile activeFile;
-	private int action;
-	private String activePerms;
 
 
     /*
@@ -547,9 +536,24 @@ public final class JCECipherFactory impl
 				// provider package should be set by property
 				if (Security.getProvider(cryptoProviderShort) == null)
 				{
-					action = 1;
+                    Class cryptoClass = Class.forName(cryptoProvider);
+                    if (!Provider.class.isAssignableFrom(cryptoClass)) {
+                        throw StandardException.newException(
+                                SQLState.ENCRYPTION_NOT_A_PROVIDER,
+                                cryptoProvider);
+                    }
+
+                    final Provider provider =
+                            (Provider) cryptoClass.newInstance();
+
 					// add provider through privileged block.
-					java.security.AccessController.doPrivileged(this);
+                    AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                        @Override
+                        public Void run() {
+                            Security.addProvider(provider);
+                            return null;
+                        }
+                    });
 				}
 			}
 
@@ -604,10 +608,21 @@ public final class JCECipherFactory impl
 
 			return;
 		}
-		catch (java.security.PrivilegedActionException  pae)
+        catch (ClassNotFoundException cnfe)
+        {
+            t = StandardException.newException(
+                    SQLState.ENCRYPTION_NO_PROVIDER_CLASS,
+                    cnfe,
+                    cryptoProvider);
+        }
+        catch (InstantiationException ie)
 		{
-			t = pae.getException();
+            t = ie;
 		}
+        catch (IllegalAccessException iae)
+        {
+            t = iae;
+        }
 		catch (NoSuchAlgorithmException nsae)
 		{
 			t = nsae;
@@ -848,39 +863,6 @@ public final class JCECipherFactory impl
     }
 
 	/**
-	 	perform actions with privileges enabled.
-	 */
-	public final Object run() throws StandardException, InstantiationException, IllegalAccessException {
-
-		try {
-
-			switch(action)
-			{
-				case 1:
-					Security.addProvider(
-					(Provider)(Class.forName(cryptoProvider).newInstance()));
-					break;
-				case 2:
-					// SECURITY PERMISSION - MP1 and/or OP4
-					// depends on the value of activePerms
-					return activeFile.getRandomAccessFile(activePerms);
-                case 3:
-                    return activeFile.getInputStream();
-
-			}
-
-		} catch (ClassNotFoundException cnfe) {
-			throw StandardException.newException(SQLState.ENCRYPTION_NO_PROVIDER_CLASS,cryptoProvider);
-		}
-		catch(FileNotFoundException fnfe) {
-			throw StandardException.newException(SQLState.ENCRYPTION_UNABLE_KEY_VERIFICATION,cryptoProvider);
-		}
-		return null;
-	}
-
-
-
-	/**
 	    The database can be encrypted with an encryption key given in connection url.
 	    For security reasons, this key is not made persistent in the database.
 
@@ -1028,16 +1010,23 @@ public final class JCECipherFactory impl
 	 	@return	StorageRandomAccessFile returns file with fileName for writing
 		@exception IOException Any exception during accessing the file for read/write
 	 */
-	private StorageRandomAccessFile privAccessFile(StorageFactory storageFactory,String fileName,String filePerms)
+    private StorageRandomAccessFile privAccessFile(
+            StorageFactory storageFactory,
+            String fileName,
+            final String filePerms)
 		throws java.io.IOException
 	{
-		StorageFile verifyKeyFile = storageFactory.newStorageFile("",fileName);
-		activeFile  = verifyKeyFile;
-		this.action = 2;
-		activePerms = filePerms;
+        final StorageFile verifyKeyFile =
+                storageFactory.newStorageFile("", fileName);
 	    try
         {
-			return (StorageRandomAccessFile)java.security.AccessController.doPrivileged(this);
+            return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<StorageRandomAccessFile>() {
+                @Override
+                public StorageRandomAccessFile run() throws IOException {
+                    return verifyKeyFile.getRandomAccessFile(filePerms);
+                }
+            });
 		}
 		catch( java.security.PrivilegedActionException pae)
 		{
@@ -1055,16 +1044,24 @@ public final class JCECipherFactory impl
 	private InputStream privAccessGetInputStream(StorageFactory storageFactory,String fileName)
 	throws StandardException
 	{
-	    StorageFile verifyKeyFile = storageFactory.newStorageFile("",fileName);
-	    activeFile  = verifyKeyFile;
-	    this.action = 3;
+        final StorageFile verifyKeyFile
+                = storageFactory.newStorageFile("", fileName);
 	    try
 	    {
-	        return (InputStream)java.security.AccessController.doPrivileged(this);
+            return AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<InputStream>() {
+                @Override
+                public InputStream run() throws FileNotFoundException {
+                    return verifyKeyFile.getInputStream();
+                }
+            });
 	    }
 	    catch( java.security.PrivilegedActionException pae)
 	    {
-	        throw (StandardException)pae.getException();
+            throw StandardException.newException(
+                    SQLState.ENCRYPTION_UNABLE_KEY_VERIFICATION,
+                    pae.getCause(),
+                    cryptoProvider);
 	    }
 	}
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=1607266&r1=1607265&r2=1607266&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Wed Jul  2 07:47:49 2014
@@ -4002,6 +4002,12 @@ Guide.
             </msg>
 
             <msg>
+                <name>XBCXF.S.1</name>
+                <text>The class '{0}' does not implement the java.security.Provider interface.</text>
+                <arg>className</arg>
+            </msg>
+
+            <msg>
                 <name>XBCXG.S</name>
                 <text>The encryption provider '{0}' does not exist.</text>
                 <arg>providerName</arg>

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=1607266&r1=1607265&r2=1607266&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Wed Jul  2 07:47:49 2014
@@ -236,6 +236,7 @@ public interface SQLState {
     String ENCRYPTION_NOCHANGE_ALGORITHM     = "XBCXD.S";
     String ENCRYPTION_NOCHANGE_PROVIDER = "XBCXE.S";
     String ENCRYPTION_NO_PROVIDER_CLASS = "XBCXF.S";
+    String ENCRYPTION_NOT_A_PROVIDER    = "XBCXF.S.1";
     String ENCRYPTION_BAD_PROVIDER      = "XBCXG.S";
     String ENCRYPTION_BAD_ALG_FORMAT    = "XBCXH.S";
     String ENCRYPTION_BAD_FEEDBACKMODE  = "XBCXI.S";

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptParams.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptParams.out?rev=1607266&r1=1607265&r2=1607266&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptParams.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptParams.out Wed Jul  2 07:47:49 2014
@@ -112,12 +112,20 @@ connect 'jdbc:derby:wombatBad;create=tru
 ERROR XJ041: Failed to create database 'wombatBad', see the next exception for details.
 ERROR XBM01: Startup failed due to an exception. See next exception for details. 
 ERROR XBCXI: The feedback mode 'CNN' is not supported. Supported feedback modes are CBC, CFB, OFB and ECB.
-ij> -- create a new database with a bad provider
+ij> -- create a new database with a provider class that doesn't exist
 -- should not work
 connect 'jdbc:derby:wombatBad;create=true;dataEncryption=true;bootPassword=ThursdaySaturday;encryptionProvider=com.foo.bar';
 ERROR XJ041: Failed to create database 'wombatBad', see the next exception for details.
 ERROR XBM0G: Failed to start encryption engine. Please make sure you are running Java 2 and have downloaded an encryption provider such as jce and put it in your class path. 
 ERROR XBCXF: The class 'com.foo.bar' representing the encryption provider cannot be found.
+ERROR XJ001: Java exception: 'com.foo.bar: java.lang.ClassNotFoundException'.
+ij> -- create a new database with a provider class that doesn't implement the
+-- java.security.Provider interface
+-- should not work
+connect 'jdbc:derby:wombatBad;create=true;dataEncryption=true;bootPassword=ThursdaySaturday;encryptionProvider=java.lang.Object';
+ERROR XJ041: Failed to create database 'wombatBad', see the next exception for details.
+ERROR XBM01: Startup failed due to an exception. See next exception for details. 
+ERROR XBCXF: The class 'java.lang.Object' does not implement the java.security.Provider interface.
 ij> -- create a new database with a bad encryption algorithm format
 -- should not work
 connect 'jdbc:derby:wombatBad;create=true;dataEncryption=true;bootPassword=ThursdaySaturday;encryptionAlgorithm=DES';

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptParams.sql
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptParams.sql?rev=1607266&r1=1607265&r2=1607266&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptParams.sql (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptParams.sql Wed Jul  2 07:47:49 2014
@@ -98,10 +98,15 @@ connect 'jdbc:derby:wombatBad;create=tru
 -- should not work
 connect 'jdbc:derby:wombatBad;create=true;dataEncryption=true;bootPassword=ThursdaySaturday;encryptionAlgorithm=DES/CNN/NoPadding';
 
--- create a new database with a bad provider
+-- create a new database with a provider class that doesn't exist
 -- should not work
 connect 'jdbc:derby:wombatBad;create=true;dataEncryption=true;bootPassword=ThursdaySaturday;encryptionProvider=com.foo.bar';
 
+-- create a new database with a provider class that doesn't implement the
+-- java.security.Provider interface
+-- should not work
+connect 'jdbc:derby:wombatBad;create=true;dataEncryption=true;bootPassword=ThursdaySaturday;encryptionProvider=java.lang.Object';
+
 -- create a new database with a bad encryption algorithm format
 -- should not work
 connect 'jdbc:derby:wombatBad;create=true;dataEncryption=true;bootPassword=ThursdaySaturday;encryptionAlgorithm=DES';