The current trunk (410361) does not allow to have encrypted databases using encryptionKey with the jar subprotocol (and probably also the http/https and classpath subprotocols also).
The problem lies in the method run from JCECipherFactory. The call to getRandomAccessFile returns null when the verifyKeyFile is an instance of InputStreamFile and the key verification therefore fails. Included in this email is a new class InputStreamRandomAccessFile in package org.apache.derby.impl.io. This class provides simple implementations of readInt and readFully so the key verification process succeeds. Also included in this email is a patch to org/apache/derby/impl/io/InputStreamFile.java so the getRandomAccessFile creates an instance of InputStreamRandomAccessFile instead of returning null. I have tested my patch with an encrypted db accessed via the jar subprotocol, it has not been tested with any other subprotocol. Regards, Mathias.
InputStreamFile.java-patch
Description: Binary data
package org.apache.derby.impl.io;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.apache.derby.io.StorageRandomAccessFile;
public class InputStreamRandomAccessFile implements DataInput, DataOutput,
StorageRandomAccessFile {
private InputStream is = null;
public InputStreamRandomAccessFile (InputStreamFile isf) throws
FileNotFoundException {
this.is = isf.getInputStream();
}
public void readFully(byte[] arg0) throws IOException {
//
// Read arg0.length bytes of data
//
int n = 0;
while (n < arg0.length) {
int r = is.read(arg0,n,arg0.length - n);
if (r == -1) {
throw new EOFException();
}
n += r;
}
}
public void readFully(byte[] arg0, int arg1, int arg2) throws
IOException {
// TODO Auto-generated method stub
}
public int skipBytes(int arg0) throws IOException {
// TODO Auto-generated method stub
return 0;
}
public boolean readBoolean() throws IOException {
// TODO Auto-generated method stub
return false;
}
public byte readByte() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public int readUnsignedByte() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public short readShort() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public int readUnsignedShort() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public char readChar() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public int readInt() throws IOException {
int a = is.read();
int b = is.read();
int c = is.read();
int d = is.read();
if (a == -1 || b == -1 || c == -1 || d == -1) {
throw new EOFException();
}
return (((a & 0xff) << 24) | ((b & 0xff) << 16) |
((c & 0xff) << 8) | (d & 0xff));
}
public long readLong() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public float readFloat() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public double readDouble() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public String readLine() throws IOException {
// TODO Auto-generated method stub
return null;
}
public String readUTF() throws IOException {
// TODO Auto-generated method stub
return null;
}
public void write(int arg0) throws IOException {
// TODO Auto-generated method stub
}
public void write(byte[] arg0) throws IOException {
// TODO Auto-generated method stub
}
public void write(byte[] arg0, int arg1, int arg2) throws IOException {
// TODO Auto-generated method stub
}
public void writeBoolean(boolean arg0) throws IOException {
// TODO Auto-generated method stub
}
public void writeByte(int arg0) throws IOException {
// TODO Auto-generated method stub
}
public void writeShort(int arg0) throws IOException {
// TODO Auto-generated method stub
}
public void writeChar(int arg0) throws IOException {
// TODO Auto-generated method stub
}
public void writeInt(int arg0) throws IOException {
// TODO Auto-generated method stub
}
public void writeLong(long arg0) throws IOException {
// TODO Auto-generated method stub
}
public void writeFloat(float arg0) throws IOException {
// TODO Auto-generated method stub
}
public void writeDouble(double arg0) throws IOException {
// TODO Auto-generated method stub
}
public void writeBytes(String arg0) throws IOException {
// TODO Auto-generated method stub
}
public void writeChars(String arg0) throws IOException {
// TODO Auto-generated method stub
}
public void writeUTF(String arg0) throws IOException {
// TODO Auto-generated method stub
}
public void close() throws IOException {
// TODO Auto-generated method stub
}
public long getFilePointer() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public long length() throws IOException {
// TODO Auto-generated method stub
return 0;
}
public void seek(long newFilePointer) throws IOException {
// TODO Auto-generated method stub
}
public void setLength(long newLength) throws IOException {
// TODO Auto-generated method stub
}
public void sync(boolean metaData) throws IOException {
// TODO Auto-generated method stub
}
}
