01: /*
02:
03: Derby - Class org.apache.derby.impl.store.raw.data.DecryptInputStream
04:
05: Licensed to the Apache Software Foundation (ASF) under one or more
06: contributor license agreements. See the NOTICE file distributed with
07: this work for additional information regarding copyright ownership.
08: The ASF licenses this file to you under the Apache License, Version 2.0
09: (the "License"); you may not use this file except in compliance with
10: the License. You may obtain a copy of the License at
11:
12: http://www.apache.org/licenses/LICENSE-2.0
13:
14: Unless required by applicable law or agreed to in writing, software
15: distributed under the License is distributed on an "AS IS" BASIS,
16: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17: See the License for the specific language governing permissions and
18: limitations under the License.
19:
20: */
21:
22: package org.apache.derby.impl.store.raw.data;
23:
24: import org.apache.derby.iapi.error.StandardException;
25: import org.apache.derby.iapi.store.raw.data.DataFactory;
26: import org.apache.derby.iapi.store.raw.RawStoreFactory;
27:
28: import org.apache.derby.iapi.services.io.CompressedNumber;
29:
30: import java.io.InputStream;
31: import java.io.IOException;
32:
33: /**
34: A DecryptInputStream is used by stream container to access an encrypted
35: stream of bytes.
36: */
37: public class DecryptInputStream extends BufferedByteHolderInputStream {
38:
39: // if database is encrypted, bytes to reserve at the beginning of the buffer
40: //protected static final int ENCRYPTION_RESERVE = dataFactory.getEncryptionBlockSize() - 1;
41:
42: protected DataFactory dataFactory;
43: protected InputStream in;
44:
45: public DecryptInputStream(InputStream in, ByteHolder bh,
46: DataFactory dataFactory) throws IOException {
47:
48: super (bh);
49: this .in = in;
50: this .dataFactory = dataFactory;
51: fillByteHolder();
52: }
53:
54: public void fillByteHolder() throws IOException {
55:
56: if (this .bh.available() == 0) {
57:
58: this .bh.clear();
59:
60: try {
61: // from the stream, read the actual length of the bytes
62: // before it was padded and encrypted.
63: int realLen = CompressedNumber.readInt(in);
64: // if it is -1, we have reached the end of the file.
65: // then we are done.
66: if (realLen == -1)
67: return;
68:
69: // calculate out what the padding was based on the actual length
70: int tail = realLen
71: % dataFactory.getEncryptionBlockSize();
72: int padding = (tail == 0) ? 0 : (dataFactory
73: .getEncryptionBlockSize() - tail);
74: int encryptedLen = realLen + padding;
75:
76: // read all encrypted data including the padding.
77: byte[] ciphertext = new byte[encryptedLen];
78: in.read(ciphertext, 0, encryptedLen);
79: byte[] cleartext = new byte[encryptedLen];
80: // decrypt the data, and stored it in a new byte array.
81: dataFactory.decrypt(ciphertext, 0, encryptedLen,
82: cleartext, 0);
83:
84: // only put the actual data without the padding into the byte holder.
85: bh.write(cleartext, padding, realLen);
86:
87: } catch (StandardException se) {
88: throw new IOException();
89: }
90:
91: // allow reading from the byte holder.
92: this.bh.startReading();
93: }
94: }
95: }
|