KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > schlichtherle > crypto > io > raes > RaesReadOnlyFile


1 /*
2  * Copyright 2005-2006 Schlichtherle IT Services
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package de.schlichtherle.crypto.io.raes;
18
19 import de.schlichtherle.crypto.io.CipherReadOnlyFile;
20 import de.schlichtherle.io.rof.FilterReadOnlyFile;
21 import de.schlichtherle.io.rof.ReadOnlyFile;
22 import de.schlichtherle.io.rof.SimpleReadOnlyFile;
23
24 import java.io.File JavaDoc;
25 import java.io.FileNotFoundException JavaDoc;
26 import java.io.IOException JavaDoc;
27
28 /**
29  * This class implements a {@link de.schlichtherle.io.rof.ReadOnlyFile}
30  * in order to provide transparent random read only access to the plain text
31  * data which has been encrypted and stored in a file according to the
32  * Random Access Encryption Specification (RAES).
33  * <p>
34  * To accomodate the transparent random read access feature, RAES specifies
35  * a multistep authentication process:
36  * <p>
37  * The first step is mandatory and implemented in the constructor of the
38  * concrete implementation of this abstract class.
39  * For this step only the cipher key and the file length is authenticated,
40  * which is fast to process (O(1)).
41  * <p>
42  * The second step is optional and must be initiated by the client by calling
43  * {@link #authenticate}.
44  * For this step the entire cipher text is authenticated, which is comparably
45  * slow (O(n)).
46  * Please note that this step does not require the cipher text to be
47  * decrypted first, which features comparably fast processing.
48  * <p>
49  * So it is up to the application which level of security it needs to
50  * provide:
51  * Most applications should always call <code>authenticate()</code> in
52  * order to guard against integrity attacks.
53  * However, some applications may provide additional (faster) methods for
54  * authentication of the pay load, in which case the authentication
55  * provided by this class may be safely skipped.
56  * <p>
57  * Note that this class implements its own virtual file pointer.
58  * Thus, if you would like to access the underlying <code>ReadOnlyFile</code>
59  * again after you have finished working with an instance of this class,
60  * you should synchronize their file pointers using the pattern as described
61  * in the base class {@link FilterReadOnlyFile}.
62  *
63  * @see RaesOutputStream
64  *
65  * @author Christian Schlichtherle
66  * @version @version@
67  * @since TrueZIP 6.0
68  */

69 public abstract class RaesReadOnlyFile
70         extends CipherReadOnlyFile
71         implements RAES {
72
73     static final int parseUByte(final byte[] bytes, final int offset) {
74         return bytes[offset] & 0xFF;
75     }
76
77     static final int parseUShort(final byte[] bytes, final int offset) {
78         return ((bytes[offset + 1] & 0xFF) << 8) | (bytes[offset] & 0xFF);
79     }
80     
81     static final long parseUInt(final byte[] bytes, int offset) {
82         offset += 3;
83         long v = bytes[offset--] & 0xFFl;
84         v <<= 8;
85         v |= bytes[offset--] & 0xFFl;
86         v <<= 8;
87         v |= bytes[offset--] & 0xFFl;
88         v <<= 8;
89         v |= bytes[offset] & 0xFFl;
90         return v;
91     }
92
93     /**
94      * Creates a new instance of <code>RaesReadOnlyFile</code>.
95      *
96      * @param file The file to read.
97      * @param parameters The {@link RaesParameters} required to access the
98      * RAES type actually found in the file.
99      * If the run time class of this parameter does not match the
100      * required parameter interface according to the RAES type found
101      * in the file, but is an instance of the
102      * {@link RaesParametersAgent} interface, it is used to find
103      * the required RAES parameters.
104      * This is applied recursively.
105      *
106      * @throws NullPointerException If any of the parameters is <tt>null</tt>.
107      * @throws FileNotFoundException If the file cannot get opened for reading.
108      * @throws RaesParametersException If no suitable RAES parameters have been
109      * provided or something is wrong with the parameters.
110      * @throws RaesException If the file is not RAES compatible.
111      * @throws IOException On any other I/O related issue.
112      */

113     public static RaesReadOnlyFile getInstance(
114             final File file,
115             final RaesParameters parameters)
116     throws FileNotFoundException JavaDoc,
117             RaesParametersException,
118             RaesException,
119             IOException JavaDoc {
120         final ReadOnlyFile rof = new SimpleReadOnlyFile(file);
121         try {
122             return getInstance(rof, parameters);
123         } catch (IOException JavaDoc failure) {
124             rof.close();
125             throw failure;
126         }
127     }
128
129     /**
130      * Creates a new instance of <tt>RaesReadOnlyFile</tt>.
131      *
132      * @param rof The read only file to read.
133      * @param parameters The {@link RaesParameters} required to access the
134      * RAES type actually found in the file.
135      * If the run time class of this parameter does not match the
136      * required parameter interface according to the RAES type found
137      * in the file, but is an instance of the
138      * {@link RaesParametersAgent} interface, it is used to find
139      * the required RAES parameters.
140      * This is applied recursively.
141      *
142      * @throws NullPointerException If any of the parameters is <tt>null</tt>.
143      * @throws FileNotFoundException If the file cannot get opened for reading.
144      * @throws RaesParametersException If no suitable RAES parameters have been
145      * provided or something is wrong with the parameters.
146      * @throws RaesException If the file is not RAES compatible.
147      * @throws IOException On any other I/O related issue.
148      */

149     public static RaesReadOnlyFile getInstance(
150             final ReadOnlyFile rof,
151             RaesParameters parameters)
152     throws FileNotFoundException JavaDoc,
153             RaesParametersException,
154             RaesException,
155             IOException JavaDoc {
156         // Load header data.
157
final byte[] leadIn = new byte[LEAD_IN_LENGTH];
158         rof.seek(0);
159         rof.readFully(leadIn);
160
161         // Check header data.
162
if (parseUInt(leadIn, 0) != RAES_SIGNATURE)
163             throw new RaesException("No RAES signature!");
164         final int type = parseUByte(leadIn, 4);
165         switch (type) {
166             case 0:
167                 parameters = getParameters(Type0RaesParameters.class, parameters);
168                 return new Type0RaesReadOnlyFile(
169                         rof, (Type0RaesParameters) parameters);
170
171             default:
172                 throw new RaesException("Unknown RAES type: " + type);
173         }
174     }
175
176     private static RaesParameters getParameters(
177             final Class JavaDoc type,
178             final RaesParameters parameters)
179     throws RaesParametersException {
180         // Order is important here to support multiple interface implementations!
181
if (parameters == null) {
182             throw new RaesParametersException();
183         } else if (type.isAssignableFrom(parameters.getClass())) {
184             return parameters;
185         } else if (parameters instanceof RaesParametersAgent) {
186             return getParameters(type,
187                     ((RaesParametersAgent) parameters).getParameters(type));
188         } else {
189             throw new RaesParametersException();
190         }
191     }
192
193     RaesReadOnlyFile(ReadOnlyFile rof) {
194         super(rof);
195     }
196
197     /**
198      * Returns the key size in bits which is actually used to decrypt the data
199      * of this RAES file.
200      */

201     public abstract int getKeySizeBits();
202
203     /**
204      * Authenticates all encrypted data in the read only file.
205      * It is safe to call this method multiple times to detect if the file
206      * has been tampered with meanwhile.
207      * <p>
208      * This is the second, optional step of authentication.
209      * The first, mandatory step is to computeMac the cipher key and
210      * cipher text length only and has already been successfully completed
211      * in the constructor.
212      *
213      * @throws RaesAuthenticationException If the computed MAC does not match
214      * the MAC declared in the RAES file.
215      * @throws IOException On any I/O related issue.
216      */

217     public abstract void authenticate()
218     throws RaesAuthenticationException, IOException JavaDoc;
219 }
220
Popular Tags