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 su...@apache.org on 2006/07/20 02:37:08 UTC

svn commit: r423682 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/services/jce/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/suites/ testing/org/apache/derbyTesting/functionTests/tes...

Author: suresht
Date: Wed Jul 19 17:37:07 2006
New Revision: 423682

URL: http://svn.apache.org/viewvc?rev=423682&view=rev
Log:
DERBY-1373: Encrypted databases cannot be booted using the jar subprotocol 

Patch Contributed by Sunitha Kambhampati.

This patch makes the following changes:
1) Instead of using RandomAccessFile, the verifyKey.dat is read 
   as a InputStream.

2) Add a new test (encryptionKey_jar.sql) for booting encrypted 
  database using encryptionKey via classpath, and jar subprotocol.


Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptionKey_jar.out   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar.sql   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar_app.properties   (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionAll.runall
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant

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=423682&r1=423681&r2=423682&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 19 17:37:07 2006
@@ -48,6 +48,8 @@
 import java.security.spec.InvalidKeySpecException;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.DataInputStream;
 
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
@@ -836,6 +838,8 @@
 					// SECURITY PERMISSION - MP1 and/or OP4
 					// depends on the value of activePerms
 					return activeFile.getRandomAccessFile(activePerms);
+                case 3:
+                    return activeFile.getInputStream();
 
 			}
 
@@ -894,6 +898,7 @@
 		// using MD5 of the unencrypted data. That way, on next database boot a check is performed
 		// to verify if the key is the same as used when the database was created
 
+        InputStream verifyKeyInputStream = null;
 		StorageRandomAccessFile verifyKeyFile = null;
 		byte[] data = new byte[VERIFYKEY_DATALEN];
 		try
@@ -916,15 +921,18 @@
 			}
 			else
 			{
-				// open file for reading only
-				verifyKeyFile = privAccessFile(sf,Attribute.CRYPTO_EXTERNAL_KEY_VERIFY_FILE,"r");
+				// Read from verifyKey.dat as an InputStream. This allows for 
+                // reading the information from verifyKey.dat successfully even when using the jar
+                // subprotocol to boot derby. (DERBY-1373) 
+				verifyKeyInputStream = privAccessGetInputStream(sf,Attribute.CRYPTO_EXTERNAL_KEY_VERIFY_FILE);
+                DataInputStream dis = new DataInputStream(verifyKeyInputStream);
 				// then read the checksum length 
-				int checksumLen = verifyKeyFile.readInt();
+				int checksumLen = dis.readInt();
 
 				byte[] originalChecksum = new byte[checksumLen];
-				verifyKeyFile.readFully(originalChecksum);
+				dis.readFully(originalChecksum);
 
-				verifyKeyFile.readFully(data);
+				dis.readFully(data);
 
 				// decrypt data with key
 				CipherProvider tmpCipherProvider = createNewCipher(DECRYPT,mainSecretKey,mainIV);
@@ -949,6 +957,8 @@
 			{
 				if(verifyKeyFile != null)
 					verifyKeyFile.close();
+                if (verifyKeyInputStream != null )
+                    verifyKeyInputStream.close();
 			}
 			catch(IOException ioee)
 			{
@@ -1009,5 +1019,27 @@
 		}
 	}
 
+	/**
+	 access a InputStream for a given file for reading.
+	 @param storageFactory   factory used for io access
+	 @param  fileName        name of the file to open as a stream for reading
+	 @return InputStream returns the stream for the file with fileName for reading
+	 @exception IOException Any exception during accessing the file for read
+	 */
+	private InputStream privAccessGetInputStream(StorageFactory storageFactory,String fileName)
+	throws StandardException
+	{
+	    StorageFile verifyKeyFile = storageFactory.newStorageFile("",fileName);
+	    activeFile  = verifyKeyFile;
+	    this.action = 3;
+	    try
+	    {
+	        return (InputStream)java.security.AccessController.doPrivileged(this);
+	    }
+	    catch( java.security.PrivilegedActionException pae)
+	    {
+	        throw (StandardException)pae.getException();
+	    }
+	}
 
 }

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptionKey_jar.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptionKey_jar.out?rev=423682&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptionKey_jar.out (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptionKey_jar.out Wed Jul 19 17:37:07 2006
@@ -0,0 +1,90 @@
+ij> -- Test cases to test booting of encrypted databases using encryptionKey 
+-- when using jar, classpath subprotocol.
+--------------------------------------------------------------------
+-- Case: create encrypted database using encryptionKey, jar it up and then test 
+-- using the jar protocol.
+-- create encrypted database.
+connect 'jdbc:derby:encdb;create=true;dataEncryption=true;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768';
+ij> create table t1(a int ) ;
+0 rows inserted/updated/deleted
+ij> insert into t1 values(1) ;
+1 row inserted/updated/deleted
+ij> insert into t1 values(2) ;
+1 row inserted/updated/deleted
+ij> insert into t1 values(3) ;
+1 row inserted/updated/deleted
+ij> insert into t1 values(4) ;
+1 row inserted/updated/deleted
+ij> insert into t1 values(5) ;
+1 row inserted/updated/deleted
+ij> connect 'jdbc:derby:encdb;shutdown=true';
+ERROR 08006: Database 'encdb' shutdown.
+ij> -- now create archive of encrypted database.
+connect 'jdbc:derby:wombat;create=true';
+ij(CONNECTION1)> create procedure CREATEARCHIVE(jarName VARCHAR(20), path VARCHAR(20), dbName VARCHAR(20))
+LANGUAGE JAVA PARAMETER STYLE JAVA
+NO SQL
+EXTERNAL NAME 'org.apache.derbyTesting.functionTests.tests.lang.dbjarUtil.createArchive';
+0 rows inserted/updated/deleted
+ij(CONNECTION1)> -- archive the encdb and put in ina.jar with dbname as db1 and ina2.jar as db2.
+call CREATEARCHIVE('ina.jar', 'encdb', 'db1');
+0 rows inserted/updated/deleted
+ij(CONNECTION1)> call CREATEARCHIVE('ina2.jar','encdb','db2');
+0 rows inserted/updated/deleted
+ij(CONNECTION1)> disconnect;
+ij> -- now that we have the database in a jar file,
+-- test using the jar protocol to connect to the db1 that is in ina.jar
+-- Should pass: ( DERBY-1373)
+connect 'jdbc:derby:jar:(ina.jar)db1;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768' AS DB1;
+ij(DB1)> select * from t1 order by a;
+A          
+-----------
+1          
+2          
+3          
+4          
+5          
+ij(DB1)> connect 'jdbc:derby:;shutdown=true';
+ERROR XJ015: Derby system shutdown.
+ij(DB1)> -- NEGATIVE CASE: Test with wrong encryption key. This should fail.
+connect 'jdbc:derby:jar:(ina.jar)db1;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666760' AS DB1;
+ERROR XJ040: Failed to start database 'jar:(ina.jar)db1', see the next exception for details.
+ERROR XBCXK: The given encryption key does not match the encryption key used when creating the database. Please ensure that you are using the correct encryption key and try again. 
+ij(DB1)> disconnect;
+ij> -- test reading a database from a jar file and loading
+-- classes etc. from the jars within the database.
+-- first using the jar protocol and then the classpath option.
+connect 'jdbc:derby:jar:(ina.jar)db1;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768' AS DB1;
+ij(DB1)> connect 'jdbc:derby:;shutdown=true';
+ERROR XJ015: Derby system shutdown.
+ij(DB1)> -- connect to database in jar file using classpath subprotocol.
+-- should fail as it is not on the classpath yet.
+connect 'jdbc:derby:classpath:db2;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768' AS DB2CL;
+ERROR XJ004: Database 'classpath:db2' not found.
+ij(DB1)> -- create a class loader for this current thread
+connect 'jdbc:derby:encdb;dataEncryption=true;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768';
+ij(CONNECTION1)> create procedure setDBContextClassLoader(JARNAME VARCHAR(20))
+LANGUAGE JAVA PARAMETER STYLE JAVA
+NO SQL
+EXTERNAL NAME 'org.apache.derbyTesting.functionTests.tests.lang.dbjarUtil.setDBContextClassLoader';
+0 rows inserted/updated/deleted
+ij(CONNECTION1)> call setDBContextClassLoader('ina2.jar');
+0 rows inserted/updated/deleted
+ij(CONNECTION1)> disconnect;
+ij> -- connect using classpath option with correct encryption key.
+connect 'jdbc:derby:classpath:db2;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768' AS DB2CL;
+ij(DB2CL)> select * from t1 order by a;
+A          
+-----------
+1          
+2          
+3          
+4          
+5          
+ij(DB2CL)> connect 'jdbc:derby:;shutdown=true';
+ERROR XJ015: Derby system shutdown.
+ij(DB2CL)> -- try with wrong encryption key, this should fail.
+connect 'jdbc:derby:classpath:db2;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666760' AS DB2CL;
+ERROR XJ040: Failed to start database 'classpath:db2', see the next exception for details.
+ERROR XBCXK: The given encryption key does not match the encryption key used when creating the database. Please ensure that you are using the correct encryption key and try again. 
+ij(DB2CL)> exit;

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptionKey_jar.out
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionAll.runall
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionAll.runall?rev=423682&r1=423681&r2=423682&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionAll.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionAll.runall Wed Jul 19 17:37:07 2006
@@ -3,3 +3,4 @@
 store/encryptionKey.sql
 store/encryptDatabaseTest1.sql
 store/encryptDatabaseTest2.sql
+store/encryptionKey_jar.sql

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant?rev=423682&r1=423681&r2=423682&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant Wed Jul 19 17:37:07 2006
@@ -64,6 +64,8 @@
 encryptParams_app.properties
 encryptionKey.sql
 encryptionKey_app.properties
+encryptionKey_jar.sql
+encryptionKey_jar_app.properties
 global_xactTable.view
 heapscan.sql
 heapscan_app.properties

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar.sql
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar.sql?rev=423682&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar.sql (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar.sql Wed Jul 19 17:37:07 2006
@@ -0,0 +1,68 @@
+-- Test cases to test booting of encrypted databases using encryptionKey 
+-- when using jar, classpath subprotocol.
+
+--------------------------------------------------------------------
+-- Case: create encrypted database using encryptionKey, jar it up and then test 
+-- using the jar protocol.
+
+-- create encrypted database.
+connect 'jdbc:derby:encdb;create=true;dataEncryption=true;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768';
+create table t1(a int ) ;
+insert into t1 values(1) ;
+insert into t1 values(2) ;
+insert into t1 values(3) ;
+insert into t1 values(4) ;
+insert into t1 values(5) ;
+connect 'jdbc:derby:encdb;shutdown=true';
+
+-- now create archive of encrypted database.
+connect 'jdbc:derby:wombat;create=true';
+create procedure CREATEARCHIVE(jarName VARCHAR(20), path VARCHAR(20), dbName VARCHAR(20))
+LANGUAGE JAVA PARAMETER STYLE JAVA
+NO SQL
+EXTERNAL NAME 'org.apache.derbyTesting.functionTests.tests.lang.dbjarUtil.createArchive';
+
+-- archive the encdb and put in ina.jar with dbname as db1 and ina2.jar as db2.
+call CREATEARCHIVE('ina.jar', 'encdb', 'db1');
+call CREATEARCHIVE('ina2.jar','encdb','db2');
+disconnect;
+
+-- now that we have the database in a jar file,
+-- test using the jar protocol to connect to the db1 that is in ina.jar
+-- Should pass: ( DERBY-1373)
+connect 'jdbc:derby:jar:(ina.jar)db1;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768' AS DB1;
+select * from t1 order by a;
+connect 'jdbc:derby:;shutdown=true';
+
+-- NEGATIVE CASE: Test with wrong encryption key. This should fail.
+connect 'jdbc:derby:jar:(ina.jar)db1;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666760' AS DB1;
+disconnect;
+
+-- test reading a database from a jar file and loading
+-- classes etc. from the jars within the database.
+-- first using the jar protocol and then the classpath option.
+
+connect 'jdbc:derby:jar:(ina.jar)db1;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768' AS DB1;
+connect 'jdbc:derby:;shutdown=true';
+
+-- connect to database in jar file using classpath subprotocol.
+-- should fail as it is not on the classpath yet.
+connect 'jdbc:derby:classpath:db2;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768' AS DB2CL;
+
+-- create a class loader for this current thread
+connect 'jdbc:derby:encdb;dataEncryption=true;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768';
+create procedure setDBContextClassLoader(JARNAME VARCHAR(20))
+LANGUAGE JAVA PARAMETER STYLE JAVA
+NO SQL
+EXTERNAL NAME 'org.apache.derbyTesting.functionTests.tests.lang.dbjarUtil.setDBContextClassLoader';
+
+call setDBContextClassLoader('ina2.jar');
+disconnect;
+
+-- connect using classpath option with correct encryption key.
+connect 'jdbc:derby:classpath:db2;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666768' AS DB2CL;
+select * from t1 order by a;
+connect 'jdbc:derby:;shutdown=true';
+-- try with wrong encryption key, this should fail.
+connect 'jdbc:derby:classpath:db2;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=6162636465666760' AS DB2CL;
+exit;
\ No newline at end of file

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar.sql
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar_app.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar_app.properties?rev=423682&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar_app.properties (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar_app.properties Wed Jul 19 17:37:07 2006
@@ -0,0 +1,14 @@
+#database=jdbc:derby:wombat;create=true;dataEncryption=true;bootPassword=Thursday
+
+#
+derby.optimizer.noTimeout=true
+
+ij.showNoConnectionsAtStart=true
+ij.showNoCountForSelect=true
+runwithjdk13=false
+useextdirs=true
+# Test fails with security manager because it uses some functions in 
+# org/apache/derbyTesting/functionTests/tests/lang/dbjarUtil.java for
+# creating archive and these methods do not use a privileged block
+# to read the properties etc.  
+noSecurityManager=true

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptionKey_jar_app.properties
------------------------------------------------------------------------------
    svn:eol-style = native