KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * RaesTest.java
3  * JUnit based test
4  *
5  * Created on 6. Oktober 2005, 10:25
6  */

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

22
23 package de.schlichtherle.crypto.io.raes;
24
25 import de.schlichtherle.crypto.generators.DigestRandom;
26 import de.schlichtherle.crypto.modes.SICSeekableBlockCipher;
27 import de.schlichtherle.io.rof.ReadOnlyFile;
28 import de.schlichtherle.io.rof.SimpleReadOnlyFile;
29 import de.schlichtherle.util.Arrays;
30
31 import java.io.File JavaDoc;
32 import java.io.FileOutputStream JavaDoc;
33 import java.io.IOException JavaDoc;
34 import java.io.OutputStream JavaDoc;
35 import java.util.Random JavaDoc;
36 import java.util.logging.Logger JavaDoc;
37
38 import junit.framework.*;
39
40 import org.bouncycastle.crypto.digests.SHA256Digest;
41
42 /**
43  * @author Christian Schlichtherle
44  */

45 public class RaesTest extends TestCase {
46
47     private static final Logger JavaDoc logger = Logger.getLogger(
48             RaesTest.class.getName());
49
50     private static final String JavaDoc PASSWD = "secret";
51     
52     private static final Random rnd = new DigestRandom(new SHA256Digest());
53     
54     private static final int[] keyStrengths = {
55         Type0RaesParameters.KEY_STRENGTH_128,
56         Type0RaesParameters.KEY_STRENGTH_192,
57         Type0RaesParameters.KEY_STRENGTH_256
58     };
59     
60     private static RaesParameters createRaesParameters() {
61         return new Type0RaesParameters() {
62             boolean secondTry;
63             
64             public char[] getOpenPasswd() {
65                 if (secondTry) {
66                     logger.finer("First returned password was wrong, providing the right one now!");
67                     return PASSWD.toCharArray();
68                 } else {
69                     secondTry = true;
70                     return rnd.nextBoolean()
71                             ? PASSWD.toCharArray()
72                             : "wrong".toCharArray();
73                 }
74             }
75             
76             public void invalidOpenPasswd() {
77                 logger.finer("Password wrong!");
78             }
79             
80             public char[] getCreatePasswd() {
81                 return PASSWD.toCharArray();
82             }
83             
84             public int getKeyStrength() {
85                 return keyStrengths[rnd.nextInt(keyStrengths.length)];
86             }
87             
88             public void setKeyStrength(int keyStrength) {
89                 logger.finer("Key strength: " + keyStrength);
90             }
91         };
92     }
93     
94     public static Test suite() throws Exception JavaDoc {
95         boolean ea = false;
96         assert ea = true; // NOT ea == true !
97
logger.config("Java assertions enabled: " + ea);
98         if (!ea)
99             logger.info("You should enable assertions for additional white box testing.");
100         
101         TestSuite suite = new TestSuite(RaesTest.class);
102         /*TestSuite suite = new TestSuite();
103         suite.addTest(new RaesTest(
104                 "testRandomReadChunksAndAuthenticate"));*/

105         
106         return suite;
107     }
108     
109     /** The plain text. */
110     private byte[] data;
111     
112     private File plainFile;
113     private ReadOnlyFile srof;
114     
115     /**
116      * The Bouncy Castle cipher to use for decryption of the cipher text
117      * message.
118      */

119     private SICSeekableBlockCipher decryptEngine;
120     
121     private File cipherFile;
122     private RaesReadOnlyFile rrof;
123     
124     public RaesTest(String JavaDoc testName) throws Exception JavaDoc {
125         super(testName);
126     }
127     
128     protected void setUp() throws Exception JavaDoc {
129         // Create rnd plain text of min 1B and max 1MB.
130
final int length = 1 + rnd.nextInt(1024 * 1024);
131         data = new byte[length];
132         assertTrue(data.length > 0);
133         rnd.nextBytes(data);
134         
135         final File dir = new File(System.getProperty("java.io.tmpdir"));
136         
137         // Encrypt the plain text to cipherFile.
138
createCipherFile(dir);
139         
140         // Write the plain text to plainFile.
141
plainFile = File.createTempFile("tmp", ".bin", dir);
142         final OutputStream JavaDoc out = new FileOutputStream JavaDoc(plainFile);
143         out.write(data);
144         out.close();
145         assertEquals(data.length, plainFile.length());
146         
147         // Open plainFile for rnd access reading.
148
srof = new SimpleReadOnlyFile(plainFile);
149     }
150     
151     private void createCipherFile(File dir)
152     throws IOException JavaDoc {
153         cipherFile = File.createTempFile("tmp", ".bin.rae", dir);
154         final RaesOutputStream out = RaesOutputStream.getInstance(
155                 new FileOutputStream JavaDoc(cipherFile),
156                 createRaesParameters());
157         
158         // Use Las Vegas algorithm to encrypt the data.
159
int n;
160         for (int off = 0; off < data.length; off += n) {
161             if (rnd.nextBoolean()) {
162                 // Write a byte.
163
n = 1;
164                 out.write(data[off]);
165             } else {
166                 // Write a buffer (maybe zero length).
167
n = rnd.nextInt(data.length / 100);
168                 n = Math.min(n, data.length - off);
169                 out.write(data, off, n);
170             }
171             if (rnd.nextBoolean())
172                 out.flush(); // maybe flush
173
}
174         
175         logger.fine("Encrypted " + data.length + " bytes of random data using PBE/Hmac-SHA-256/AES-" + out.getKeySizeBits() + "/CTR.");
176         out.close();
177         
178         // Open cipherFile for random access decryption.
179
rrof = RaesReadOnlyFile.getInstance(cipherFile, createRaesParameters());
180     }
181     
182     protected void tearDown() throws Exception JavaDoc {
183         boolean deleted;
184         
185         decryptEngine = null;
186         
187         srof.close();
188         srof = null;
189         
190         deleted = plainFile.delete();
191         if (!deleted && plainFile.exists())
192             logger.fine("Warning: " + plainFile + ": Could not delete!");
193         plainFile = null;
194         
195         rrof.close();
196         rrof = null;
197         
198         deleted = cipherFile.delete();
199         if (!deleted && cipherFile.exists())
200             logger.fine("Warning: " + cipherFile + ": Could not delete!");
201         cipherFile = null;
202         
203         data = null;
204     }
205     
206     public void testClose() throws IOException JavaDoc {
207         logger.fine("testClose");
208         
209         rrof.close();
210         
211         try {
212             rrof.length();
213             fail("This should throw an IOException!");
214         } catch (IOException JavaDoc expected) {
215             // This exception is excepted.
216
}
217         
218         try {
219             rrof.getFilePointer();
220             fail("This should throw an IOException!");
221         } catch (IOException JavaDoc expected) {
222             // This exception is excepted.
223
}
224         
225         try {
226             rrof.seek(0);
227             fail("This should throw an IOException!");
228         } catch (IOException JavaDoc expected) {
229             // This exception is excepted.
230
}
231         
232         try {
233             rrof.read();
234             fail("Reading from a closed file should throw an IOException!");
235         } catch (IOException JavaDoc expected) {
236             // This exception is excepted.
237
}
238         
239         assertEquals(0, rrof.read(new byte[0]));
240         
241         try {
242             rrof.read(new byte[1]);
243             fail("Reading from a closed file should throw an IOException!");
244         } catch (IOException JavaDoc expected) {
245             // This exception is excepted.
246
}
247         
248         assertEquals(0, rrof.read(new byte[0], 0, 0));
249         
250         try {
251             rrof.read(new byte[1], 0, 1);
252             fail("Reading from a closed file should throw an IOException!");
253         } catch (IOException JavaDoc expected) {
254             // This exception is excepted.
255
}
256         
257         rrof.readFully(new byte[0]);
258         
259         try {
260             rrof.readFully(new byte[1]);
261             fail("Reading from a closed file should throw an IOException!");
262         } catch (IOException JavaDoc expected) {
263             // This exception is excepted.
264
}
265         
266         rrof.readFully(new byte[0], 0, 0);
267         
268         try {
269             rrof.readFully(new byte[1], 0, 1);
270             fail("Reading from a closed file should throw an IOException!");
271         } catch (IOException JavaDoc expected) {
272             // This exception is excepted.
273
}
274         
275         assertEquals(0, rrof.skipBytes(0));
276         assertEquals(0, rrof.skipBytes(-1));
277         
278         try {
279             rrof.skipBytes(1);
280             fail("Skipping bytes in a closed file should throw an IOException!");
281         } catch (IOException JavaDoc expected) {
282             // This exception is excepted.
283
}
284         
285         rrof.close();
286         
287         srof.close();
288         
289         try {
290             srof.length();
291             fail("This should throw an IOException!");
292         } catch (IOException JavaDoc expected) {
293             // This exception is excepted.
294
}
295         
296         try {
297             srof.getFilePointer();
298             fail("This should throw an IOException!");
299         } catch (IOException JavaDoc expected) {
300             // This exception is excepted.
301
}
302         
303         try {
304             srof.seek(0);
305             fail("This should throw an IOException!");
306         } catch (IOException JavaDoc expected) {
307             // This exception is excepted.
308
}
309         
310         try {
311             srof.read();
312             fail("Reading from a closed file should throw an IOException!");
313         } catch (IOException JavaDoc expected) {
314             // This exception is excepted.
315
}
316         
317         assertEquals(0, srof.read(new byte[0]));
318         
319         try {
320             srof.read(new byte[1]);
321             fail("Reading from a closed file should throw an IOException!");
322         } catch (IOException JavaDoc expected) {
323             // This exception is excepted.
324
}
325         
326         assertEquals(0, srof.read(new byte[0], 0, 0));
327         
328         try {
329             srof.read(new byte[1], 0, 1);
330             fail("Reading from a closed file should throw an IOException!");
331         } catch (IOException JavaDoc expected) {
332             // This exception is excepted.
333
}
334         
335         srof.readFully(new byte[0]);
336         
337         try {
338             srof.readFully(new byte[1]);
339             fail("Reading from a closed file should throw an IOException!");
340         } catch (IOException JavaDoc expected) {
341             // This exception is excepted.
342
}
343         
344         srof.readFully(new byte[0], 0, 0);
345         
346         try {
347             srof.readFully(new byte[1], 0, 1);
348             fail("Reading from a closed file should throw an IOException!");
349         } catch (IOException JavaDoc expected) {
350             // This exception is excepted.
351
}
352         
353         assertEquals(0, srof.skipBytes(0));
354         assertEquals(0, srof.skipBytes(-1));
355         
356         try {
357             srof.skipBytes(1);
358             fail("Skipping bytes in a closed file should throw an IOException!");
359         } catch (IOException JavaDoc expected) {
360             // This exception is excepted.
361
}
362         
363         srof.close();
364     }
365     
366     public void testLength() throws Exception JavaDoc {
367         logger.fine("testLength");
368         
369         for (int i = 10; --i >= 0; ) {
370             final ReadOnlyFile rrof2 = RaesReadOnlyFile.getInstance(
371                     cipherFile, createRaesParameters());
372             
373             assertEquals(data.length, rrof2.length());
374             assertEquals(data.length, srof.length());
375             
376             rrof2.close();
377         }
378     }
379     
380     public void testSeekAndGetFilePointer() throws IOException JavaDoc {
381         logger.fine("testSeekAndGetFilePointer (Monte Carlo algorithm)");
382         
383         assertEquals(0, rrof.getFilePointer());
384         assertEquals(0, srof.getFilePointer());
385         
386         testSeekAndGetFilePointer(rrof, 0);
387         testSeekAndGetFilePointer(srof, 0);
388         
389         final long length = rrof.length();
390         for (int i = 100; --i >= 0; ) {
391             final long tooSmall = rnd.nextLong() | 0x8000000000000000L;
392             try {
393                 testSeekAndGetFilePointer(rrof, tooSmall);
394                 fail("Seeking to a negative position should throw an IOException!");
395             } catch (IOException JavaDoc expected) {
396                 // This exception is excepted.
397
}
398             try {
399                 testSeekAndGetFilePointer(srof, tooSmall);
400                 fail("Seeking to a negative position should throw an IOException!");
401             } catch (IOException JavaDoc expected) {
402                 // This exception is excepted.
403
}
404             
405             final int off = rnd.nextInt((int) length);
406             testSeekAndGetFilePointer(rrof, off);
407             testSeekAndGetFilePointer(srof, off);
408             
409             final long tooLarge = Math.max(
410                     length + 1, rnd.nextLong() & 0x7fffffffffffffffL);
411             try {
412                 testSeekAndGetFilePointer(rrof, tooLarge);
413                 fail("Seeking past the file length should throw an IOException!");
414             } catch (IOException JavaDoc expected) {
415                 // This exception is excepted.
416
}
417             // Seeking past the file length may throw an IOException,
418
// depending on the platform: It works on Windows, it doesn't work
419
// on Linux. If it doesn't we still want to validate that it shows
420
// no after effects.
421
try {
422                 testSeekAndGetFilePointer(srof, tooLarge);
423             } catch (IOException JavaDoc mayHappen) {
424             }
425         }
426         
427         testSeekAndGetFilePointer(rrof, length);
428     }
429     
430     private void testSeekAndGetFilePointer(
431             final ReadOnlyFile rof,
432             final long pos) throws IOException JavaDoc {
433         rof.seek(pos);
434         assertEquals(pos, rof.getFilePointer());
435     }
436     
437     public void testSkipBytes() throws IOException JavaDoc {
438         logger.fine("testSkipBytes (Las Vegas algorithm)");
439         
440         final long length = rrof.length();
441         for (int off = 0; off < (int) length; off++) {
442             assertEquals(data[off], (byte) rrof.read());
443             assertEquals(data[off], (byte) srof.read());
444             int n = rnd.nextInt((int) (length / 100));
445             n = rrof.skipBytes(n);
446             assertEquals(n, srof.skipBytes(n));
447             off += n;
448         }
449         assertEquals(-1, rrof.read());
450         assertEquals(-1, srof.read());
451         assertEquals(0, rrof.skipBytes(1));
452         assertEquals(0, srof.skipBytes(1));
453     }
454     
455     public void testForwardReadBytes() throws IOException JavaDoc {
456         logger.fine("testForwardReadBytes");
457         
458         final long length = rrof.length();
459         for (int off = 0; off < length; off++) {
460             assertEquals(data[off], (byte) rrof.read());
461             assertEquals(data[off], (byte) srof.read());
462         }
463         assertEquals(-1, rrof.read());
464         assertEquals(-1, srof.read());
465     }
466     
467     public void testBackwardReadBytes() throws IOException JavaDoc {
468         logger.fine("testBackwardReadBytes");
469         
470         final long length = rrof.length();
471         testSeekAndGetFilePointer(rrof, length);
472         assertEquals(-1, rrof.read());
473         testSeekAndGetFilePointer(srof, length);
474         assertEquals(-1, srof.read());
475         
476         for (int off = (int) length; --off >= 0; ) {
477             testSeekAndGetFilePointer(rrof, off);
478             assertEquals(data[off], (byte) rrof.read());
479             testSeekAndGetFilePointer(srof, off);
480             assertEquals(data[off], (byte) srof.read());
481         }
482     }
483     
484     public void testRandomReadBytes() throws IOException JavaDoc {
485         logger.fine("testRandomReadBytes (Monte Carlo algorithm)");
486         
487         final long length = rrof.length();
488         for (int i = 100; --i >= 0; ) {
489             int off = rnd.nextInt((int) length);
490             testSeekAndGetFilePointer(rrof, off);
491             assertEquals(data[off], (byte) rrof.read());
492             testSeekAndGetFilePointer(srof, off);
493             assertEquals(data[off], (byte) srof.read());
494         }
495         
496         testSeekAndGetFilePointer(rrof, length);
497         assertEquals(-1, rrof.read());
498         testSeekAndGetFilePointer(srof, length);
499         assertEquals(-1, srof.read());
500     }
501     
502     public void testForwardReadChunks() throws IOException JavaDoc {
503         logger.fine("testForwardReadChunks (Las Vegas algorithm)");
504         
505         final long length = rrof.length();
506         int off = 0;
507         int read;
508         do {
509             final byte[] buf = new byte[rnd.nextInt((int) (length / 100))];
510             read = rrof.read(buf);
511             if (read < 0)
512                 break;
513             if (buf.length > 0) {
514                 assertTrue(read > 0);
515                 assertTrue(Arrays.equals(data, off, buf, 0, read));
516                 assertEquals(read, srof.read(buf));
517                 assertTrue(Arrays.equals(data, off, buf, 0, read));
518             } else {
519                 assertTrue(read == 0);
520                 assertEquals(0, srof.read(buf));
521             }
522             off += read;
523         } while (true);
524         assertEquals(off, length);
525         assertEquals(-1, read);
526         assertEquals(-1, srof.read(new byte[1]));
527         assertEquals( 0, rrof.read(new byte[0]));
528         assertEquals( 0, srof.read(new byte[0]));
529     }
530     
531     public void testRandomReadChunksAndAuthenticate() throws IOException JavaDoc {
532         logger.fine("testRandomReadChunksAndAuthenticate (Monte Carlo algorithm)");
533         
534         final long length = rrof.length();
535         for (int i = 100; --i >= 0; ) {
536             int off = rnd.nextInt((int) length);
537             testSeekAndGetFilePointer(rrof, off);
538             testSeekAndGetFilePointer(srof, off);
539             final byte[] buf = new byte[rnd.nextInt((int) (length / 100))];
540             int read = rrof.read(buf);
541             if (buf.length > 0) {
542                 assertTrue(read > 0);
543                 assertTrue(Arrays.equals(data, off, buf, 0, read));
544                 assertEquals(read, srof.read(buf));
545                 assertTrue(Arrays.equals(data, off, buf, 0, read));
546             } else {
547                 assertTrue(read == 0);
548                 assertEquals(0, srof.read(buf));
549             }
550             // Calling this method all the time is highly inefficient,
551
// but makes a good test.
552
rrof.authenticate();
553         }
554     }
555 }
556
Popular Tags