db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sure...@apache.org
Subject svn commit: r416536 - in /db/derby/code/trunk/java: engine/org/apache/derby/ engine/org/apache/derby/iapi/reference/ engine/org/apache/derby/iapi/services/crypto/ engine/org/apache/derby/impl/services/jce/ engine/org/apache/derby/impl/store/raw/ testin...
Date Fri, 23 Jun 2006 01:12:17 GMT
Author: suresht
Date: Thu Jun 22 18:12:17 2006
New Revision: 416536

URL: http://svn.apache.org/viewvc?rev=416536&view=rev
Log:
DERBY-1156 (partial): re-encryting an encrypted database 

This patch adds some code required to support reconfigure(rencryption) of
an already existing encrypted database with a new password(secret key)
or an external user specified encryption key. Two new attributes 
"newBootPassword" and "newEncryptionkey" are introduced to support this 
functionality. 

- modified the code to support two have instance of two cipher 
   factories to exist. So that the existing data can decrypted with
   the old encryption key using one cipher factory and rewrite the data 
   with new encryption keys using another cipher factory. 

- re-enryption of the database with new keys is similar to encrypting 
   an already existing database. All the container data is read through 
   the page cache and  rewritten using the new encryption keys. 

- Added test case to test the re-encryption of an encrypted database.
 

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/crypto/CipherFactoryBuilder.java
  (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactoryBuilder.java
  (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Module.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java
    db/derby/code/trunk/java/engine/org/apache/derby/modules.properties
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptDatabaseTest1.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptDatabaseTest1.sql
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/crypto/T_Cipher.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java?rev=416536&r1=416535&r2=416536&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Attribute.java Thu Jun
22 18:12:17 2006
@@ -92,6 +92,16 @@
 
 	String BOOT_PASSWORD = "bootPassword";
 
+    /**
+	    The attribute that is used to chage the secret key of an encrypted
+        database. The secret key must be at least 8 characters long.
+		This key must not be stored persistently in cleartext anywhere. 
+	 */
+
+	String NEW_BOOT_PASSWORD = "newBootPassword";
+
+
+
 	/**
 		The attribute that is used for the database name, from
 		the JDBC notion of jdbc:<subprotocol>:<subname>
@@ -171,6 +181,16 @@
 		external to the database, ie by the application.
 	*/
 	String CRYPTO_EXTERNAL_KEY = "encryptionKey";
+
+
+    /**
+	    The attribute that is used to chage the encryption 
+        key of an encrypted database. When this is specified
+        all the supplied crypto information is stored
+        external to the database, ie by the application.
+	*/
+	String NEW_CRYPTO_EXTERNAL_KEY = "newEncryptionKey";
+
 
 	/**
 	   One can encrypt the database with an encryption key at create time.

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Module.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Module.java?rev=416536&r1=416535&r2=416536&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Module.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Module.java Thu Jun 22
18:12:17 2006
@@ -23,7 +23,7 @@
 public interface Module {
 
 	String CacheFactory = "org.apache.derby.iapi.services.cache.CacheFactory";
-	String CipherFactory = "org.apache.derby.iapi.services.crypto.CipherFactory";
+	String CipherFactoryBuilder = "org.apache.derby.iapi.services.crypto.CipherFactoryBuilder";
 	String ClassFactory = "org.apache.derby.iapi.services.loader.ClassFactory";
 	String DaemonFactory = "org.apache.derby.iapi.services.daemon.DaemonFactory";
 	String JavaFactory ="org.apache.derby.iapi.services.compiler.JavaFactory";

Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/crypto/CipherFactoryBuilder.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/crypto/CipherFactoryBuilder.java?rev=416536&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/crypto/CipherFactoryBuilder.java
(added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/crypto/CipherFactoryBuilder.java
Thu Jun 22 18:12:17 2006
@@ -0,0 +1,50 @@
+/*
+
+   Derby - Class org.apache.derby.iapi.services.crypto.CipherFactoryBuilder
+
+   Copyright 1998, 2006 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+
+
+package org.apache.derby.iapi.services.crypto;
+import org.apache.derby.iapi.error.StandardException;
+import java.util.Properties;
+
+
+/*
+ * Interface to create instances of the cipher factory 
+ * based on the user specified encryption properties.
+ */
+
+public interface CipherFactoryBuilder
+{
+
+    /**
+     * Create an instance of the cipher factory.
+     *
+     * @param create    true, if the database is getting configured 
+     *                  for encryption.
+     * @param props	    encryption properties/attributes to use
+     *                  for creating the cipher factory.
+     * @param newAttrs  true, if cipher factory has to be created using 
+     *                  the new attributes specified by the user. 
+     *                 
+     */
+    public CipherFactory createCipherFactory(boolean create, 
+                                             Properties props, 
+                                             boolean newAttrs) 
+        throws StandardException;
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/crypto/CipherFactoryBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

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=416536&r1=416535&r2=416536&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
Thu Jun 22 18:12:17 2006
@@ -23,7 +23,6 @@
 import org.apache.derby.iapi.services.crypto.CipherFactory;
 import org.apache.derby.iapi.services.crypto.CipherProvider;
 
-import org.apache.derby.iapi.services.monitor.ModuleControl;
 import org.apache.derby.iapi.services.monitor.Monitor;
 import org.apache.derby.iapi.services.sanity.SanityManager;
 
@@ -66,7 +65,7 @@
 
 	@see CipherFactory
  */
-public final class JCECipherFactory implements CipherFactory, ModuleControl, java.security.PrivilegedExceptionAction
+public final class JCECipherFactory implements CipherFactory, java.security.PrivilegedExceptionAction
 {
     private final static String MESSAGE_DIGEST = "MD5";
 
@@ -113,6 +112,29 @@
 	private int action;
 	private String activePerms;
 
+
+    /*
+     * Constructor of JCECipherFactory, initializes the new instances.
+     *
+     * @param create    true, if the database is getting configured 
+     *                  for encryption.
+     * @param props	    encryption properties/attributes to use
+     *                  for creating the cipher factory.
+     * @param newAttrs  true, if cipher factory has to be created using 
+     *                  should using the new attributes specified by the user.  
+     *                  For example to reencrypt the database with 
+     *                  a new password.
+     */
+    public JCECipherFactory(boolean create, 
+                            Properties props,
+                            boolean newAttributes) 
+        throws StandardException
+    {
+        init(create, props, newAttributes);
+    }
+    
+
+
 	static String providerErrorName(String cps) {
 
 		return cps == null ? "default" : cps;
@@ -373,11 +395,11 @@
 		return new JCECipherProvider(mode, secretKey, iv, cryptoAlgorithm, cryptoProviderShort);
 	}
 
-	/*
-	 * module control methods
-	 */
 
-	public void	boot(boolean create, Properties properties)
+    /*
+     * Initilize the new instance of this class. 
+     */
+	public void	init(boolean create, Properties properties, boolean newAttrs)
 		throws StandardException
 	{
 
@@ -385,7 +407,13 @@
 		boolean storeProperties = create;
         persistentProperties = new Properties();
 
-		String externalKey = properties.getProperty(Attribute.CRYPTO_EXTERNAL_KEY);
+        // get the external key specified by the user to 
+        // encrypt the database. If user is reencrypting the
+        // database with a new encryption key,  read the value of 
+        // the new encryption key. 
+        String externalKey =  properties.getProperty((newAttrs ? 
+                                                      Attribute.NEW_CRYPTO_EXTERNAL_KEY:
+                                                      Attribute.CRYPTO_EXTERNAL_KEY));
 		if (externalKey != null) {
 			storeProperties = false;
 		}
@@ -549,10 +577,15 @@
 			if (externalKey != null) {
 
 				// incorrect to specify external key and boot password
-				if (properties.getProperty(Attribute.BOOT_PASSWORD) != null)
+				if (properties.getProperty((newAttrs ? 
+                                            Attribute.NEW_BOOT_PASSWORD :
+                                            Attribute.BOOT_PASSWORD)) != null)
 					throw StandardException.newException(SQLState.SERVICE_WRONG_BOOT_PASSWORD);
 
-				generatedKey = org.apache.derby.iapi.util.StringUtil.fromHexString(externalKey, 0, externalKey.length());
+				generatedKey = 
+                    org.apache.derby.iapi.util.StringUtil.fromHexString(externalKey, 
+                                                                        0, 
+                                                                        externalKey.length());
                 if (generatedKey == null) {
                     throw StandardException.newException(
                         // If length is even, we assume invalid character(s),
@@ -564,8 +597,8 @@
 
 			} else {
 
-				generatedKey = handleBootPassword(create, properties);
-				if(create)
+				generatedKey = handleBootPassword(create, properties, newAttrs);
+				if(create || newAttrs)
 				   persistentProperties.put(Attribute.CRYPTO_KEY_LENGTH,
                                             keyLengthBits+"-"+generatedKey.length);
 			}
@@ -608,10 +641,18 @@
 		throw StandardException.newException(SQLState.MISSING_ENCRYPTION_PROVIDER, t);
 	}
 
-	private byte[] handleBootPassword(boolean create, Properties properties)
+
+	private byte[] handleBootPassword(boolean create, 
+                                      Properties properties, 
+                                      boolean newPasswd)
 		throws StandardException {
 
-		String inputKey = properties.getProperty(Attribute.BOOT_PASSWORD);
+
+        // get the key  specifed by the user. If user is reencrypting the
+        // database; read the value of the new password. 
+		String inputKey = properties.getProperty((newPasswd ? 
+                                                  Attribute.NEW_BOOT_PASSWORD : 
+                                                  Attribute.BOOT_PASSWORD));
 		if (inputKey == null)
 		{
 			throw StandardException.newException(SQLState.SERVICE_WRONG_BOOT_PASSWORD);
@@ -638,7 +679,7 @@
 
 		byte[] generatedKey;
 
-		if (create)
+		if (create || newPasswd)
 		{
 			//
 			generatedKey = generateUniqueBytes();
@@ -653,11 +694,6 @@
 		}
 
 		return generatedKey;
-	}
-
-	public void stop()
-	{
-
 	}
 
     /* 

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactoryBuilder.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactoryBuilder.java?rev=416536&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactoryBuilder.java
(added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactoryBuilder.java
Thu Jun 22 18:12:17 2006
@@ -0,0 +1,61 @@
+/*
+
+   Derby - Class org.apache.derby.iapi.services.crypto.JCECipherFactoryBuilder
+
+   Copyright 1998, 2006 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+
+package org.apache.derby.impl.services.jce;
+
+import org.apache.derby.iapi.services.crypto.CipherFactory;
+import org.apache.derby.iapi.services.crypto.CipherFactoryBuilder;
+import org.apache.derby.iapi.error.StandardException;
+import java.util.Properties;
+
+
+/**
+ * Cipher Factory instance builder. New instances of the cipher 
+ * factory are created based on the on the user specified 
+ * encryption properties.
+ */
+
+public class JCECipherFactoryBuilder implements CipherFactoryBuilder
+{
+
+    
+	public JCECipherFactoryBuilder() {
+	}
+
+
+    /**
+     * Create an instance of the cipher factory.
+     *
+     * @param create    true, if the database is getting configured 
+     *                  for encryption.
+     * @param props	    encryption properties/attributes to use
+     *                  for creating the cipher factory.
+     * @param newAttrs  true, if cipher factory has to be created using 
+     *                  should using the new attributes specified by the user.  
+     */
+    public CipherFactory createCipherFactory(boolean create, 
+                                             Properties props, 
+                                             boolean newAttrs) 
+        throws StandardException
+
+    {
+        return new JCECipherFactory(create, props, newAttrs);
+    }
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/jce/JCECipherFactoryBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java?rev=416536&r1=416535&r2=416536&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/RawStore.java Thu Jun
22 18:12:17 2006
@@ -24,6 +24,7 @@
 import org.apache.derby.iapi.services.daemon.DaemonService;
 import org.apache.derby.iapi.services.context.ContextManager;
 import org.apache.derby.iapi.services.context.ContextService;
+import org.apache.derby.iapi.services.crypto.CipherFactoryBuilder;
 import org.apache.derby.iapi.services.crypto.CipherFactory;
 import org.apache.derby.iapi.services.crypto.CipherProvider;
 import org.apache.derby.iapi.services.locks.LockFactory;
@@ -113,7 +114,7 @@
 	private CipherProvider decryptionEngine;
     private CipherProvider newEncryptionEngine;
 	private CipherProvider newDecryptionEngine;
-	private CipherFactory cipherFactory;
+	private CipherFactory  currentCipherFactory;
 	private int counter_encrypt;
 	private int counter_decrypt;
 	private int encryptionBlockSize = RawStoreFactory.DEFAULT_ENCRYPTION_BLOCKSIZE;
@@ -179,6 +180,8 @@
 		storageFactory = dataFactory.getStorageFactory();
 
         String restoreFromBackup = null;
+        boolean reEncrypt = false;
+        CipherFactory newCipherFactory = null;
 
 		if (properties != null)
 		{
@@ -202,6 +205,7 @@
                 properties.getProperty(Attribute.DATA_ENCRYPTION);
             databaseEncrypted = Boolean.valueOf(dataEncryption).booleanValue(); 
 
+
             if (!create && restoreFromBackup == null) {
                 // check if database is already encrypted, by directly peeking at the
                 // database service propertes instead of the properties passed 
@@ -228,11 +232,27 @@
                     // set database as un-encrypted, we will set it as encrypted 
                     // after encrypting the existing data. 
                     databaseEncrypted = false;
+                } else {
+                    // check if the user has requested to renecrypt  an
+                    // encrypted datbase with new encryption password/key.
+                    if (encryptedDatabase) {
+                        if (properties.getProperty(
+                                       Attribute.NEW_BOOT_PASSWORD) != null) {
+                            reEncrypt = true;
+                        }
+                        else if (properties.getProperty(
+                                       Attribute.NEW_CRYPTO_EXTERNAL_KEY) != null){
+                            reEncrypt = true;
+                        };
+                        encryptDatabase = reEncrypt;
+                    }
+
                 }
                 
                 // NOTE: if user specifies Attribute.DATA_ENCRYPTION on the
                 // connection URL by mistake on an already encrypted database, 
                 // it is ignored.
+
             }
 
             // setup encryption engines. 
@@ -241,14 +261,26 @@
                 // check if database is configured for encryption, during
                 // configuration  some of the properties database; so that
                 // user does not have to specify them on the URL everytime.
-                boolean setupEncryption = create || encryptDatabase; 
-
-                cipherFactory =
-                    (CipherFactory)Monitor.bootServiceModule(setupEncryption, this,
-						org.apache.derby.iapi.reference.Module.CipherFactory, properties);
+                // Incase of re-encryption of an already of encrypted database
+                // only some information needs to updated; it is not treated 
+                // like the configuring the database for encryption first time. 
+                boolean setupEncryption = create || (encryptDatabase &&  !reEncrypt);
+
+                // start the cipher factory module, that is is used to create 
+                // instances of the cipher factory with specific enctyption 
+                // properties. 
+
+                CipherFactoryBuilder cb =  (CipherFactoryBuilder)
+                    Monitor.startSystemModule(org.apache.derby.iapi.reference.Module.CipherFactoryBuilder);
+
+                // create instance of the cipher factory with the 
+                // specified encryption properties. 
+                currentCipherFactory = cb.createCipherFactory(setupEncryption, 
+                                                              properties, 
+                                                              false);
 
                 // The database can be encrypted using an encryption key that is given at
-                // connection url. For security reasons, this key is not made persistent
+                 // connection url. For security reasons, this key is not made persistent
                 // in the database. But it is necessary to verify the encryption key 
                 // whenever booting the database if it is similar to the key that was used
                 // during creation time. This needs to happen before we access the data/logs
to 
@@ -259,10 +291,10 @@
                 // is used during boot time
   
 
-                cipherFactory.verifyKey(setupEncryption,storageFactory,properties);
+                currentCipherFactory.verifyKey(setupEncryption, storageFactory, properties);
 
                 // Initializes the encryption and decryption engines
-                encryptionEngine = cipherFactory.
+                encryptionEngine = currentCipherFactory.
                     createNewCipher(CipherFactory.ENCRYPT);
                 
                 // At creation time of an encrypted database, store the encryption block
size
@@ -295,23 +327,40 @@
                         encryptionBlockSize = encryptionEngine.getEncryptionBlockSize();
                 }   
 
-                decryptionEngine = cipherFactory.
+                decryptionEngine = currentCipherFactory.
                     createNewCipher(CipherFactory.DECRYPT);
 
-                random = cipherFactory.getSecureRandom();
+                random = currentCipherFactory.getSecureRandom();
                     
                 if (encryptDatabase) {
-                    // for now there is only one encryption engine, 
-                    // configuring an unencrypted database for encryption 
-                    // is supported at this moment.
-                    newDecryptionEngine = decryptionEngine;   
-                    newEncryptionEngine = encryptionEngine;
+
+                    if (reEncrypt) {
+                        // create new cipher factory with the new encrytpion
+                        // properties specified by the user. This cipher factory
+                        // is used to create the new encryption/decryption
+                        // engines to reencrypt the database with the new
+                        // encryption keys. 
+                        newCipherFactory = 
+                            cb.createCipherFactory(setupEncryption, 
+                                                   properties, 
+                                                   true);
+                        newDecryptionEngine = 
+                            newCipherFactory.createNewCipher(CipherFactory.DECRYPT);
+                        newEncryptionEngine = 
+                            newCipherFactory.createNewCipher(CipherFactory.ENCRYPT);
+                    } else {
+                        // there is only one engine when configuring an 
+                        // unencrypted database for encryption 
+                        newDecryptionEngine = decryptionEngine;
+                        newEncryptionEngine = encryptionEngine;
+
+                    }
                 }
 
                 // save the encryption properties if encryption is enabled 
                 // at database creation time. 
                 if(create)
-                    cipherFactory.saveProperties(properties) ;
+                    currentCipherFactory.saveProperties(properties) ;
 			}
 		}
 
@@ -412,7 +461,9 @@
         // if user requested to encrpty an unecrypted database or encrypt with
         // new alogorithm then do that now.  
         if (encryptDatabase) {
-            configureDatabaseForEncryption(properties);
+            configureDatabaseForEncryption(properties, 
+                                           reEncrypt, 
+                                           newCipherFactory);
         }
 	}
 
@@ -1149,6 +1200,8 @@
 	*/
 
 
+    
+
 	/**
 		Encrypt cleartext into ciphertext.
 
@@ -1161,8 +1214,8 @@
                        boolean newEngine)
 		 throws StandardException
 	{
-		if (databaseEncrypted == false && encryptDatabase == false || 
-            encryptionEngine == null && newEncryptionEngine == null)
+		if ((databaseEncrypted == false && encryptDatabase == false) || 
+            (encryptionEngine == null && newEncryptionEngine == null))
         {
             throw StandardException.newException(
                         SQLState.STORE_FEATURE_NOT_IMPLEMENTED);
@@ -1235,7 +1288,7 @@
 		// oldkey , newkey.
 		String changeString = (String)changePassword;
 
-		return cipherFactory.changeBootPassword((String)changePassword, properties, encryptionEngine);
+		return currentCipherFactory.changeBootPassword((String)changePassword, properties, encryptionEngine);
 
 	}
 
@@ -1265,7 +1318,9 @@
      * @param properties  properties related to this database.
      * @exception StandardException Standard Cloudscape Error Policy
      */
-    public void configureDatabaseForEncryption(Properties properties) 
+    public void configureDatabaseForEncryption(Properties properties,
+                                               boolean reEncrypt, 
+                                               CipherFactory newCipherFactory) 
         throws StandardException 
     {
 
@@ -1308,15 +1363,28 @@
                 databaseEncrypted = true;
                 encryptDatabase = false;
                 //switch the encryption/decryption engine to the new ones.
-                decryptionEngine = newDecryptionEngine;  
-                encryptionEngine = newEncryptionEngine;
+                if (reEncrypt) {
+                    decryptionEngine = newDecryptionEngine;  
+                    encryptionEngine = newEncryptionEngine;
+                    currentCipherFactory = newCipherFactory;
+                }
+
                 //force a checkpoint with new encryption algorithm
                 logFactory.checkpoint(this, dataFactory, xactFactory, true);
                 // store the encryption block size;
                 properties.put(RawStoreFactory.ENCRYPTION_BLOCKSIZE,
                                String.valueOf(encryptionBlockSize));
                 // save the encryption properties.
-                cipherFactory.saveProperties(properties) ;
+                currentCipherFactory.saveProperties(properties) ;
+
+                // incase of rencrytion of database, save information needed 
+                // to verify the new key on a next boot. 
+                if (reEncrypt) {
+                    currentCipherFactory.verifyKey(reEncrypt, 
+                                               storageFactory, 
+                                               properties);
+                }
+
             }                
             newDecryptionEngine = null;   
             newEncryptionEngine = null;

Modified: db/derby/code/trunk/java/engine/org/apache/derby/modules.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/modules.properties?rev=416536&r1=416535&r2=416536&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/modules.properties (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/modules.properties Thu Jun 22 18:12:17
2006
@@ -131,7 +131,7 @@
 
 # cryptography - requires JDK 1.2 and greater and com.sun.crypto.provider.SunJCE
 #
-derby.module.cryptographyJ2=org.apache.derby.impl.services.jce.JCECipherFactory
+derby.module.cryptographyJ2=org.apache.derby.impl.services.jce.JCECipherFactoryBuilder
 derby.env.jdk.cryptographyJ2=2
 derby.env.classes.cryptographyJ2=javax.crypto.SecretKey
 cloudscape.config.cryptographyJ2=derby

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptDatabaseTest1.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptDatabaseTest1.out?rev=416536&r1=416535&r2=416536&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptDatabaseTest1.out
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptDatabaseTest1.out
Thu Jun 22 18:12:17 2006
@@ -1,4 +1,5 @@
-ij> -- This script tests configuring an un-enctypted database for encryption. 
+ij> -- This script tests configuring an un-enctypted database for encryption and
+-- reencryption of an encrypted database with new enryption key/password.
 disconnect;
 ij> ---test configure the database for encrypion with encryption key.
 connect 'wombat_key;create=true';
@@ -48,6 +49,50 @@
 ij> disconnect;
 ij> connect 'wombat_key;shutdown=true';
 ERROR 08006: Database 'wombat_key' shutdown.
+ij> --- reencrypt the database with a different encryption key
+connect 'jdbc:derby:wombat_key;encryptionKey=6162636465666768;newEncryptionKey=5666768616263646';
+ij> select * from t1;
+A          
+-----------
+1          
+2          
+3          
+4          
+5          
+6          
+7          
+ij> insert into t1 values(7);
+1 row inserted/updated/deleted
+ij> insert into t1 values(8);
+1 row inserted/updated/deleted
+ij> disconnect;
+ij> connect 'wombat_key;shutdown=true';
+ERROR 08006: Database 'wombat_key' shutdown.
+ij> --- boot the database with the new encyrption key. 
+connect 'jdbc:derby:wombat_key;encryptionKey=5666768616263646';
+ij> select * from t1;
+A          
+-----------
+1          
+2          
+3          
+4          
+5          
+6          
+7          
+7          
+8          
+ij> insert into t1 values(9);
+1 row inserted/updated/deleted
+ij> insert into t1 values(10);
+1 row inserted/updated/deleted
+ij> disconnect;
+ij> connect 'wombat_key;shutdown=true';
+ERROR 08006: Database 'wombat_key' shutdown.
+ij> --- attempt to boot with the old encrytion key, it should fail.
+connect 'jdbc:derby:wombat_key;encryptionKey=6162636465666768';
+ERROR XJ040: Failed to start database 'wombat_key', 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> -- test confugring the database for encrypion with a boot password. 
 connect 'wombat_pwd;create=true';
 ij> create table t2(a int ) ;
@@ -93,4 +138,50 @@
 5          
 6          
 7          
+ij> disconnect;
+ij> connect 'wombat_pwd;shutdown=true';
+ERROR 08006: Database 'wombat_pwd' shutdown.
+ij> --- reconfigure the database with a different password. 
+connect 'jdbc:derby:wombat_pwd;bootPassword=xyz1234abc;newBootPassword=new1234xyz';
+ij> select * from t2 ;
+A          
+-----------
+1          
+2          
+3          
+4          
+5          
+6          
+7          
+ij> insert into t2 values(8);
+1 row inserted/updated/deleted
+ij> insert into t2 values(9);
+1 row inserted/updated/deleted
+ij> insert into t2 values(10);
+1 row inserted/updated/deleted
+ij> disconnect;
+ij> connect 'wombat_pwd;shutdown=true';
+ERROR 08006: Database 'wombat_pwd' shutdown.
+ij> -- boot the database with the new password. 
+connect 'jdbc:derby:wombat_pwd;bootPassword=new1234xyz';
+ij> select * from t2 ;
+A          
+-----------
+1          
+2          
+3          
+4          
+5          
+6          
+7          
+8          
+9          
+10         
+ij> disconnect;
+ij> connect 'wombat_pwd;shutdown=true';
+ERROR 08006: Database 'wombat_pwd' shutdown.
+ij> -- attempt to boot the database with the old password, it should fail. 
+connect 'jdbc:derby:wombat_pwd;bootPassword=xyz1234abc';
+ERROR XJ040: Failed to start database 'wombat_pwd', see the next exception for details.
+ERROR XBM06: Startup failed. An encrypted database cannot be accessed without the correct
boot password.  
 ij> 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptDatabaseTest1.sql
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptDatabaseTest1.sql?rev=416536&r1=416535&r2=416536&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptDatabaseTest1.sql
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptDatabaseTest1.sql
Thu Jun 22 18:12:17 2006
@@ -1,4 +1,5 @@
--- This script tests configuring an un-enctypted database for encryption. 
+-- This script tests configuring an un-enctypted database for encryption and
+-- reencryption of an encrypted database with new enryption key/password.
 
 disconnect;
 ---test configure the database for encrypion with encryption key.
@@ -24,6 +25,24 @@
 disconnect;
 connect 'wombat_key;shutdown=true';
 
+--- reencrypt the database with a different encryption key
+connect 'jdbc:derby:wombat_key;encryptionKey=6162636465666768;newEncryptionKey=5666768616263646';
+select * from t1;
+insert into t1 values(7);
+insert into t1 values(8);
+disconnect;
+connect 'wombat_key;shutdown=true';
+
+--- boot the database with the new encyrption key. 
+connect 'jdbc:derby:wombat_key;encryptionKey=5666768616263646';
+select * from t1;
+insert into t1 values(9);
+insert into t1 values(10);
+disconnect;
+connect 'wombat_key;shutdown=true';
+--- attempt to boot with the old encrytion key, it should fail.
+connect 'jdbc:derby:wombat_key;encryptionKey=6162636465666768';
+
 -- test confugring the database for encrypion with a boot password. 
 connect 'wombat_pwd;create=true';
 create table t2(a int ) ;
@@ -44,3 +63,25 @@
 connect 'wombat_pwd;shutdown=true';
 connect 'jdbc:derby:wombat_pwd;bootPassword=xyz1234abc';
 select * from t2 ;
+disconnect;
+connect 'wombat_pwd;shutdown=true';
+
+
+--- reconfigure the database with a different password. 
+connect 'jdbc:derby:wombat_pwd;bootPassword=xyz1234abc;newBootPassword=new1234xyz';
+select * from t2 ;
+insert into t2 values(8);
+insert into t2 values(9);
+insert into t2 values(10);
+disconnect;
+connect 'wombat_pwd;shutdown=true';
+-- boot the database with the new password. 
+connect 'jdbc:derby:wombat_pwd;bootPassword=new1234xyz';
+select * from t2 ;
+disconnect;
+connect 'wombat_pwd;shutdown=true';
+-- attempt to boot the database with the old password, it should fail. 
+connect 'jdbc:derby:wombat_pwd;bootPassword=xyz1234abc';
+
+
+

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/crypto/T_Cipher.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/crypto/T_Cipher.java?rev=416536&r1=416535&r2=416536&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/crypto/T_Cipher.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/crypto/T_Cipher.java
Thu Jun 22 18:12:17 2006
@@ -79,7 +79,7 @@
 	byte[] IV;
 
 	CipherFactory factory;
-
+    
 	public T_Cipher()
 	{
 		super();
@@ -90,7 +90,7 @@
 	*/
 
 	public String getModuleToTestProtocolName() {
-		return org.apache.derby.iapi.reference.Module.CipherFactory;
+		return org.apache.derby.iapi.reference.Module.CipherFactoryBuilder;
 	}
 
     protected String getAlgorithm()
@@ -212,8 +212,11 @@
         REPORT("encryption algorithm used : " + getAlgorithm());
         REPORT("encryption provider used : " + provider);
 
-		factory = (CipherFactory)Monitor.bootServiceModule(true, (Object)null,
-            org.apache.derby.iapi.reference.Module.CipherFactory, props);
+        CipherFactoryBuilder cb =  (CipherFactoryBuilder)
+            Monitor.startSystemModule(org.apache.derby.iapi.reference.Module.CipherFactoryBuilder);
+
+        factory = cb.createCipherFactory(true, props, false);
+
 		if (factory == null)
 			throw T_Fail.testFailMsg("cannot find Cipher factory ");
 



Mime
View raw message