Issue Details (XML | Word | Printable)

Key: DERBY-4328
Type: Bug Bug
Status: Reopened Reopened
Priority: Major Major
Assignee: Rick Hillegas
Reporter: Rick Hillegas
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Derby

The Developer's Guide falsely claims that you can use SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY to change the boot password on an encrypted database.

Created: 30/Jul/09 06:13 PM   Updated: 24/Aug/09 02:13 PM
Component/s: Documentation
Affects Version/s: None
Fix Version/s: 10.5.4.0

Time Tracking:
Not Specified

File Attachments:
  Size
File Licensed for inclusion in ASF works derby-4328-01-aa-removeFalseReencryptionClaim.diff 2009-07-30 07:27 PM Rick Hillegas 4 kB

Labels:


 Description  « Hide
This claim is made in the section titled 'Changing the boot password'. If you try to run the example, you get this error:

CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY( 'bootPassword', 'Thursday' , 'Saturday');
ERROR 42Y03: 'SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY' is not recognized as a function or procedure.

The correct way to change the boot password is documented earlier on in the section titled 'Encrypting databases with a new boot password'. We should remove the section titled 'Changing the boot password'.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Rick Hillegas added a comment - 30/Jul/09 07:27 PM
Attaching derby-4328-01-aa-removeFalseReencryptionClaim.diff. This removes the misleading section. Committed at subversion revision 799420.

Rick Hillegas added a comment - 30/Jul/09 07:50 PM
Ported 799420 from docs trunk to 10.5 branch at subversion revision 799428.

Knut Anders Hatlen added a comment - 17/Aug/09 02:24 PM
Sorry for the late response.

I'm reopening the issue because the code used to demonstrate that the developer's guide is wrong, does not do what the developer's guide says.

The developer's guide says that SYSCS_SET_DATABASE_PROPERTY should be called with two arguments. First argument should be 'bootPassword" and second argument should be on the form 'oldbpw , newbpw'. The code in the bug description calls SYSCS_SET_DATABASE_PROPERTY with three arguments, and it's therefore expected to fail.

I haven't tested if the documented syntax works, but it looks like there is code to handle it. See the code path SystemProcedures.SYSCS_SET_DATABASE_PROPERTY -> PropertyInfo.setDatabaseProperty -> RAMTransaction.setProperty -> PropertyConglomerate.setProperty -> PropertyConglomerate.bootPasswordChange.

Rick Hillegas added a comment - 17/Aug/09 03:42 PM
Thanks for pointing this out, Knut. I can verify that the following script runs as expected:

connect 'jdbc:derby:memory:encdbcbc_128;create=true;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thursday';
create table t1(i1 int);
insert into t1 values ( 1);
select * from t1;
call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('bootPassword', 'Thursday , Saturday');
disconnect;
connect 'jdbc:derby:memory:encdbcbc_128;shutdown=true';

-- should fail
connect 'jdbc:derby:memory:encdbcbc_128;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thursday';

-- should succeed
connect 'jdbc:derby:memory:encdbcbc_128;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Saturday';
select * from t1;
disconnect;

But now I don't understand how the passwords are supposed to be escaped if they contain commas or end in whitespace. It doesn't appear to me that the code addresses this issue. The second argument is parsed into old and new passwords by JCECipherFactory.changeBootPassword(). That method seems to just look for the first comma, then trims all the trailing whitespace off of the first boot password. See this script:

connect 'jdbc:derby:memory:encdbcbc_128;create=true;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thursday ,';
create table t1(i1 int);
insert into t1 values ( 1);
select * from t1;

-- this fails to parse the old boot password
call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('bootPassword', 'Thursday , , Saturday');
disconnect;
connect 'jdbc:derby:memory:encdbcbc_128;shutdown=true';

-- succeeds
connect 'jdbc:derby:memory:encdbcbc_128;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thursday ,';
select * from t1;
disconnect;

-- fails
connect 'jdbc:derby:memory:encdbcbc_128;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Saturday';

If someone wants to re-instate this documentation, then I think that the new documentation should address the escaping topic. I can see a couple resolutions of this issue:

1) Leave the situation as it is. Don't re-instate this documentation. Users can continue to change the boot password using the currently documented technique. The currently documented technique may have its own escaping issues involving semicolons.

2) Re-instate the documentation with a note that this technique will not work for boot passwords which contain commas or end in whitespace.

3) Invent some escaping syntax, wire it into JCECipherFactory, then describe that in the re-instated documentation. If we go this route, then we may want to make the escaping syntax work for the other (currently documented) technique for changing boot passwords.

Knut Anders Hatlen added a comment - 18/Aug/09 02:39 PM
Option 2 sounds good for now.

One possible future enhancement could be to introduce a system procedure for changing the boot password, which would help us around the quoting issues with both of the existing approaches. Something like this:

PreparedStatement ps = conn.prepareStatement("SYSCS_UTIL.SYSCS_CHANGE_BOOT_PASSWORD(?,?)");
ps.setString(1, " good, old password ");
ps.setString(2, "new, even better password ; 1,2,3,4 ");
ps.execute();

Rick Hillegas added a comment - 18/Aug/09 02:56 PM
Thanks, Knut. I think (1) or (2) would be adequate and I incline more toward (1). I don't see much value in the procedural api since there is another way to change the boot password. Given the escaping issues, I think that this procedural api is a little hokey. Does (2) support an important use-case?

Knut Anders Hatlen added a comment - 18/Aug/09 03:27 PM
My problem with (1) is that it would leave some functionality undocumented, and the code will probably live forever because no one understands why it's there. If we choose (1) I feel that we should also remove the code that implements it, but that could cause backward compatibility issues.

You mentioned that the alternative way to change the boot password may also have escaping issues, so I don't quite see why one should be left in the documentation and the other one removed.

Changing the password by using the newBootPassword attribute requires that the database is not booted. Doesn't that make it vulnerable to race conditions if others connect the database while we're attempting to change the boot password? In that case using the set-property method might be preferable.

Rick Hillegas added a comment - 18/Aug/09 07:32 PM
Thanks, Knut. I agree that the code supporting (2) should be left in place for compatibility reasons. I think that the escaping issue involving the semicolon is a general issue for all components of the connection url. If that issue isn't documented somewhere, I agree that we should address it in such a way that we cover all of those components. I don't think I understand the race condition: are you worried that the dbo will try to change the boot password to two different values simultaneously?

Rick Hillegas added a comment - 18/Aug/09 07:54 PM
I think that you cannot escape the semicolons in the connection url. That is, components of the connection url simply can't have semicolons in them. This creates another problem for using SYSCS_UTIL.SYSCS_CHANGE_BOOT_PASSWORD. Using that procedure, you can set the boot password to be an illegal password with an embedded semicolon. You then can't boot the database. The following script shows this behavior:

connect 'jdbc:derby:memory:encdbcbc_128;create=true;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thursday';
create table t1(i1 int);
insert into t1 values ( 1);
select * from t1;
call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('bootPassword', 'Thursday , Thurs;day');
disconnect;
connect 'jdbc:derby:memory:encdbcbc_128;shutdown=true';

-- fails
connect 'jdbc:derby:memory:encdbcbc_128;dataEncryption=true;encryptionKeyLength=128;encryptionAlgorithm=AES/CBC/NoPadding;bootPassword=Thurs;day';

Dag H. Wanvik added a comment - 19/Aug/09 01:53 AM
Note: Until DERBY-2409 is fixed, there is a concern that changing password using the URL may fail silently.

Knut Anders Hatlen added a comment - 19/Aug/09 07:12 AM
The race condition I'm talking about is the following: If you shut down the database and reboot it with the newBootPassword attribute, this may or may not actually change the password, depending on whether or not someone else has rebooted the database in the meantime. As Dag mentions, this may even go unnoticed because of DERBY-2409.