Quadcap Embeddable Database

com/quadcap/sql/file/EncryptedBlockStore.java

Go to the documentation of this file.
00001 package com.quadcap.sql.file; 00002 00003 /* 00004 * Copyright 1999 by Stan Bailes and Quadcap Software. 00005 * 00006 **/ 00007 00008 import java.io.IOException; 00009 00010 import java.nio.ByteBuffer; 00011 00012 import com.quadcap.crypto.Digest; 00013 import com.quadcap.crypto.Key; 00014 import com.quadcap.crypto.KeyFactory; 00015 import com.quadcap.crypto.SymmetricKey; 00016 00017 /** 00018 * 00019 * 00020 * @author Stan Bailes 00021 */ 00022 public class EncryptedBlockStore extends BlockStore { 00023 SymmetricKey key; 00024 Key encrypt; 00025 Key decrypt; 00026 byte[] buf0; 00027 ByteBuffer b0; 00028 00029 /** 00030 * Create a new EncryptedBlockStore object using the specified file and 00031 * blocksize. 00032 * 00033 * @param file the underlying file. 00034 * @param ra the randomly-accessible version of the file. 00035 * @param blocksize the block size to use for accessing the file. 00036 */ 00037 public EncryptedBlockStore() { 00038 } 00039 00040 static final int oHASH_PASSWD_start = BlockFile.oHASH_PASSWD_start; 00041 static final int oHASH_PASSWD_len = BlockFile.oHASH_PASSWD_len; 00042 00043 public void setKey(SymmetricKey key) throws IOException { 00044 this.key = key; 00045 this.encrypt = key.getEncryptionKey(); 00046 this.decrypt = key.getDecryptionKey(); 00047 this.buf0 = new byte[blockSize]; 00048 b0 = ByteBuffer.wrap(buf0); 00049 byte[] digest = makeDigest(key.toString()); 00050 if (!isEncrypted()) { 00051 synchronized (lock) { 00052 buf0[0] = 0x0e; // 4c -> ec! Encrypted. 00053 fra.write(0, buf0, 0, 1); 00054 fra.write(oHASH_PASSWD_start, digest, 0, digest.length); 00055 } 00056 } else { 00057 synchronized (lock) { 00058 fra.read(oHASH_PASSWD_start, buf0, 0, oHASH_PASSWD_len); 00059 for (int i = 0; i < digest.length; i++) { 00060 if (digest[i] != buf0[i]) { 00061 throw new IOException("Bad username/password"); 00062 } 00063 } 00064 } 00065 } 00066 } 00067 00068 byte[] makeDigest(String s) { 00069 Digest d = KeyFactory.createDigest("SHA1"); 00070 for (int i = 0; i < s.length(); i++) { 00071 char c = s.charAt(i); 00072 d.update((byte)((c >> 8) & 0xff)); 00073 d.update((byte)(c & 0xff)); 00074 } 00075 return d.digest(); 00076 } 00077 00078 /** 00079 * Read a block into a buffer. If the specified block is beyond the 00080 * current end of file, then grow the file 00081 * 00082 * @param blockNum the number of the block to read. 00083 * @param buf the buffer into which the data is read. 00084 */ 00085 public void read(long blockNum, byte[] buf) 00086 throws IOException 00087 { 00088 synchronized (lock) { 00089 if (blockNum != 0 && decrypt != null) { 00090 super.read(blockNum, buf0); 00091 b0.rewind(); 00092 decrypt.f(b0, ByteBuffer.wrap(buf)); 00093 } else { 00094 super.read(blockNum, buf); 00095 } 00096 } 00097 } 00098 00099 /** 00100 * Write a block from a buffer into the file. 00101 * 00102 * @param blockNum the number of the block to write. 00103 * @param buf the buffer from which the data is written. 00104 * @exception IOException if an I/O error occurs. 00105 */ 00106 public void write(long blockNum, byte[] buf) 00107 throws IOException 00108 { 00109 synchronized (lock) { 00110 if (blockNum != 0 && encrypt != null) { 00111 b0.clear(); 00112 encrypt.f(ByteBuffer.wrap(buf), b0); 00113 super.write(blockNum, buf0); 00114 } else { 00115 super.write(blockNum, buf); 00116 } 00117 } 00118 } 00119 }