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 da...@apache.org on 2012/02/22 00:52:16 UTC
svn commit: r1292084 - in
/db/derby/code/trunk/java/testing/org/apache/derbyTesting:
functionTests/master/ functionTests/suites/ functionTests/tests/store/ junit/
Author: dag
Date: Tue Feb 21 23:52:15 2012
New Revision: 1292084
URL: http://svn.apache.org/viewvc?rev=1292084&view=rev
Log:
DERBY-2687 store/encryptDatabase.sql fails intermittently with ClassNotFoundException, Log Corrupted
Patch derby-2687-2 + removed an additional unused line. This converts
encryptDatabase.sql to JUnit and also makes the test ignore a hash
collision case: the stored two byte digest of the secret key can in can
1/2**16 cases match the the digest of bogus key gotten by decoding the
encrypted key using the wrong bootpassword, thus allowing boot to
proceed using a wrong encryption key, leading to a boot crash (the
"boot issue").
Another issue (less likely) can still make the test fail (the
"bootpassword change issue"), but cf. the improvement issue DERBY-5622
which would resolve that.
Added:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/EncryptDatabaseTest.java (with props)
Removed:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/encryptDatabase.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionAES.properties
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionAES.runall
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptDatabase.sql
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/encryptDatabase_app.properties
Modified:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryption.runall
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionBlowfish.runall
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionCFB.runall
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionDES.runall
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionECB.runall
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionOFB.runall
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/_Suite.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/Decorator.java
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryption.runall
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryption.runall?rev=1292084&r1=1292083&r2=1292084&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryption.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryption.runall Tue Feb 21 23:52:15 2012
@@ -1,3 +1,2 @@
unit/T_Cipher.unit
-store/encryptDatabase.sql
store/EncryptionTest.java
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionBlowfish.runall
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionBlowfish.runall?rev=1292084&r1=1292083&r2=1292084&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionBlowfish.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionBlowfish.runall Tue Feb 21 23:52:15 2012
@@ -1,2 +1 @@
unit/T_CipherBlowfish.unit
-store/encryptDatabase.sql
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionCFB.runall
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionCFB.runall?rev=1292084&r1=1292083&r2=1292084&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionCFB.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionCFB.runall Tue Feb 21 23:52:15 2012
@@ -1,2 +1 @@
unit/T_CipherCFB.unit
-store/encryptDatabase.sql
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionDES.runall
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionDES.runall?rev=1292084&r1=1292083&r2=1292084&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionDES.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionDES.runall Tue Feb 21 23:52:15 2012
@@ -1,2 +1 @@
unit/T_CipherDES.unit
-store/encryptDatabase.sql
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionECB.runall
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionECB.runall?rev=1292084&r1=1292083&r2=1292084&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionECB.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionECB.runall Tue Feb 21 23:52:15 2012
@@ -1,2 +1 @@
unit/T_CipherECB.unit
-store/encryptDatabase.sql
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionOFB.runall
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionOFB.runall?rev=1292084&r1=1292083&r2=1292084&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionOFB.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/encryptionOFB.runall Tue Feb 21 23:52:15 2012
@@ -1,2 +1 @@
unit/T_CipherOFB.unit
-store/encryptDatabase.sql
Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/EncryptDatabaseTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/EncryptDatabaseTest.java?rev=1292084&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/EncryptDatabaseTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/EncryptDatabaseTest.java Tue Feb 21 23:52:15 2012
@@ -0,0 +1,325 @@
+/*
+
+ Derby - Class org.apache.derbyTesting.functionTests.tests.store.EncryptDatabaseTest
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you 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.derbyTesting.functionTests.tests.store;
+
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Arrays;
+import java.util.List;
+import javax.sql.DataSource;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derbyTesting.junit.*;
+
+
+/**
+ * Database encryption testing, mainly that handling of bootPassword works ok
+ * across encryption algorithms. Converted from {@code encryptDatabase.sql} in
+ * old harness, which was used in suites for the different algoritms,
+ * e.g. {@code encryptionECB}. DERBY-2687.
+ */
+
+public class EncryptDatabaseTest extends BaseJDBCTestCase
+{
+ // SQL states
+ private static final String ENCRYPTION_NOCHANGE_ALGORITHM = "XBCXD";
+ private static final String ENCRYPTION_NOCHANGE_PROVIDER = "XBCXE";
+ private static final String ILLEGAL_BP_LENGTH = "XBCX2";
+ private static final String NULL_BOOT_PASSWORD = "XBCX5";
+ private static final String WRONG_BOOT_PASSWORD = "XBCXA";
+ private static final String WRONG_PASSWORD_CHANGE_FORMAT = "XBCX7";
+
+
+ public EncryptDatabaseTest(String name) {
+ super(name);
+ }
+
+
+ /**
+ * Construct top level suite in this JUnit test
+ *
+ * @return A suite containing embedded suites
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite("EncryptDatabase");
+ suite.addTest(wrapTest());
+ suite.addTest(wrapTest("DESede/CBC/NoPadding")); // from encryption
+ suite.addTest(wrapTest("DESede/CFB/NoPadding")); // from encryptionCFB
+ suite.addTest(wrapTest("DES/OFB/NoPadding")); // from encryptionOFB
+ suite.addTest(wrapTest("DES/ECB/NoPadding")); // from encryptionECB
+ suite.addTest(wrapTest("DES/CBC/NoPadding")); // from encryptionDES
+ suite.addTest(wrapTest("Blowfish/CBC/NoPadding")); // from e..Blowfish
+ suite.addTest(wrapTest("AES/CBC/NoPadding")); // from encryptionAES
+ suite.addTest(wrapTest("AES/OFB/NoPadding"));
+ return suite;
+ }
+
+
+ private static Test wrapTest() {
+ return Decorator.encryptedDatabaseBpw(
+ TestConfiguration.embeddedSuite(
+ EncryptDatabaseTest.class),
+ "Thursday"); // only initial bootPassword, though..
+ }
+
+
+ private static Test wrapTest(String encryptionMethod) {
+ return Decorator.encryptedDatabaseBpw(
+ TestConfiguration.embeddedSuite(
+ EncryptDatabaseTest.class),
+ encryptionMethod,
+ "Thursday"); // only initial bootPassword, though..
+ }
+
+
+ public void testEncryption() throws SQLException {
+
+ // for bug 3668 - you couldn't change the password without exiting
+ // out of db create session
+
+ Statement s = createStatement();
+ s.executeUpdate("call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'Thursday, Wednesday')");
+
+ TestConfiguration.getCurrent().shutdownEngine();
+
+ // -- test for bug 3668
+ // -- try the old password, should fail
+ assertFailedBoot("Thursday");
+
+ assertSuccessfulBoot("Wednesday");
+ s = createStatement();
+
+ // -- switch back to old password
+ s.executeUpdate("call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'Wednesday, Thursday')");
+
+ // create table t1 ( a char(20));
+ s.executeUpdate("create table t1 ( a char(20))");
+
+ // -- make sure we cannot access the secret key
+
+ JDBC.assertSingleValueResultSet(
+ s.executeQuery("values SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY(" +
+ "'bootPassword')"),
+ null);
+
+ JDBC.assertSingleValueResultSet(
+ s.executeQuery("values SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY(" +
+ "'encryptedBootPassword')"),
+ null);
+
+ s.executeUpdate("insert into t1 values ('hello world')");
+
+ // -- change the secret key
+
+ // -- these should fail
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', null)",
+ NULL_BOOT_PASSWORD);
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'wrongkey, ')",
+ ILLEGAL_BP_LENGTH);
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'Thursday')",
+ WRONG_PASSWORD_CHANGE_FORMAT);
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'Thursday , ')",
+ ILLEGAL_BP_LENGTH);
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'Thursday , short')",
+ ILLEGAL_BP_LENGTH);
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'Thursdya , derbypwd')",
+ WRONG_BOOT_PASSWORD);
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'Thursdayx , derbypwd')",
+ WRONG_BOOT_PASSWORD);
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'xThursday , derbypwd')",
+ WRONG_BOOT_PASSWORD);
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'thursday , derbypwd')",
+ WRONG_BOOT_PASSWORD);
+
+ s.executeUpdate("call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', ' Thursday , Saturday')");
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'Thursday , derbypwd')",
+ WRONG_BOOT_PASSWORD);
+
+
+ // -- change it again
+
+ s.executeUpdate("call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'Saturday,derbypwd')");
+
+ // -- make sure we cannot access the secret key
+ JDBC.assertSingleValueResultSet(
+ s.executeQuery("values SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY(" +
+ "'bootPassword')"),
+ null);
+
+ JDBC.assertSingleValueResultSet(
+ s.executeQuery("values SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY(" +
+ "'encryptedBootPassword')"),
+ null);
+
+
+ TestConfiguration.getCurrent().shutdownEngine();
+
+ assertFailedBoot(null);
+ assertFailedBoot("Thursday");
+ assertFailedBoot("Saturday");
+ assertSuccessfulBoot("derbypwd");
+
+ s = createStatement();
+
+ JDBC.assertSingleValueResultSet(
+ s.executeQuery("values SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY(" +
+ "'bootPassword')"),
+ null);
+
+ JDBC.assertSingleValueResultSet(
+ s.executeQuery("values SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY(" +
+ "'encryptedBootPassword')"),
+ null);
+
+ // -- change it again, make sure it trims white spaces
+
+ s.executeUpdate("call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', ' derbypwd , bbderbypwdx ')");
+ s.executeUpdate("call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'bootPassword', 'bbderbypwdx, derbypwdxx ')");
+
+
+ JDBC.assertSingleValueResultSet(
+ s.executeQuery("values SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY(" +
+ "'bootPassword')"),
+ null);
+
+ JDBC.assertSingleValueResultSet(
+ s.executeQuery("values SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY(" +
+ "'encryptedBootPassword')"),
+ null);
+
+ TestConfiguration.getCurrent().shutdownEngine();
+
+ assertFailedBoot("derbypwd");
+ assertSuccessfulBoot("derbypwdxx");
+
+ s = createStatement();
+
+ JDBC.assertSingleValueResultSet(
+ s.executeQuery("select * from t1"),
+ "hello world");
+
+ // test that you cannot change the encryption provider or algorithm
+ // after database creation
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'encryptionAlgorithm', 'DES/blabla/NoPadding')",
+ ENCRYPTION_NOCHANGE_ALGORITHM);
+
+ assertFailedStatement(
+ s,
+ "call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(" +
+ "'encryptionProvider', 'com.pom.aplomb')",
+ ENCRYPTION_NOCHANGE_PROVIDER);
+ }
+
+
+ private void assertFailedBoot(String bootPassword) throws SQLException {
+ DataSource ds = JDBCDataSource.getDataSource();
+
+ JDBCDataSource.setBeanProperty(
+ ds, "connectionAttributes",
+ (bootPassword != null ? "bootPassword=" + bootPassword
+ : "")); // "": lest we inherit bootPassword from current config
+
+
+ try {
+ ds.getConnection();
+ fail("boot worked: unexpected");
+ } catch (SQLException e) {
+
+ String [] accepted = new String[]{
+ "XBM06", // normal: wrong bootpassword
+ "XJ040"}; // Java error during boot: DERBY-2687
+ // Remove when DERBY-5622 is fixed.
+ boolean found = Arrays.asList(accepted).contains(e.getSQLState());
+
+ if (!found) {
+ throw e;
+ }
+ }
+ }
+
+
+ private static void assertSuccessfulBoot(String bootPassword)
+ throws SQLException {
+
+ DataSource ds = JDBCDataSource.getDataSource();
+ JDBCDataSource.setBeanProperty(
+ ds, "connectionAttributes", "bootPassword=" + bootPassword);
+ ds.getConnection().close();
+ }
+
+
+ private static void assertFailedStatement(Statement s,
+ String sql,
+ String state) {
+ assertStatementError(state, s, sql);
+ }
+}
Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/EncryptDatabaseTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/_Suite.java?rev=1292084&r1=1292083&r2=1292084&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/_Suite.java Tue Feb 21 23:52:15 2012
@@ -95,6 +95,7 @@ public class _Suite extends BaseTestCase
suite.addTest(EncryptionKeyBlowfishTest.suite());
suite.addTest(EncryptionKeyDESTest.suite());
suite.addTest(EncryptionAESTest.suite());
+ suite.addTest(EncryptDatabaseTest.suite());
}
return suite;
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/Decorator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/Decorator.java?rev=1292084&r1=1292083&r2=1292084&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/Decorator.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/Decorator.java Tue Feb 21 23:52:15 2012
@@ -57,16 +57,36 @@ public class Decorator {
*/
public static Test encryptedDatabase(Test test)
{
+ return encryptedDatabaseBpw(test, getBootPhrase(16));
+ }
+
+ /**
+ * Decorate a set of tests to use an encrypted
+ * single use database. This is to run tests
+ * using encryption as a general test and
+ * not specific tests of how encryption is handled.
+ * E.g. tests of setting various URL attributes
+ * would be handled in a specific test.
+ * <BR>
+ * The database will use the default encryption
+ * algorithm.
+ *
+ * @param test test to decorate
+ * @param bootPassword boot passphrase to use
+ * @return decorated tests
+ */
+ public static Test encryptedDatabaseBpw(Test test, String bootPassword)
+ {
if (JDBC.vmSupportsJSR169())
return new TestSuite("no encryption support");
Properties attributes = new Properties();
attributes.setProperty("dataEncryption", "true");
- attributes.setProperty("bootPassword", getBootPhrase(16));
+ attributes.setProperty("bootPassword", bootPassword);
return attributesDatabase(attributes, test);
}
-
+
/**
* Decorate a set of tests to use an encrypted
* single use database. This is to run tests
@@ -86,14 +106,37 @@ public class Decorator {
*/
public static Test encryptedDatabase(Test test, final String algorithm)
{
+ return encryptedDatabaseBpw(test, algorithm, getBootPhrase(16));
+ }
+
+
+ /**
+ * Decorate a set of tests to use an encrypted
+ * single use database. This is to run tests
+ * using encryption as a general test and
+ * not specific tests of how encryption is handled.
+ * E.g. tests of setting various URL attributes
+ * would be handled in a specific test.
+ * <BR>
+ * The database will use the specified encryption
+ * algorithm.
+ *
+ * @param test test to decorate
+ * @param bootPassword boot passphrase to use
+ * @return decorated tests
+ */
+ public static Test encryptedDatabaseBpw(Test test,
+ final String algorithm,
+ String bootPassword)
+ {
Properties attributes = new Properties();
attributes.setProperty("dataEncryption", "true");
- attributes.setProperty("bootPassword", getBootPhrase(64));
+ attributes.setProperty("bootPassword", bootPassword);
attributes.setProperty("encryptionAlgorithm", algorithm);
return attributesDatabase(attributes, test);
}
-
+
private static String getBootPhrase(int length)
{
Random rand = new Random();