CICO_PBE_SKIP_Test.java revision 12794:c9b4bc199dca
1/*
2 * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23import java.io.IOException;
24import java.security.GeneralSecurityException;
25import javax.crypto.CipherInputStream;
26
27/**
28 * CICO PBE SKIP functional test.
29 *
30 * Verifies for the given PBE algorithm if the encrypt/decrypt mechanism is
31 * performed correctly for CipherInputStream when skip() method is used.
32 *
33 * Test scenario:
34 * 1. initializes plain text with random generated data with length TEXT_SIZE.
35 * 2. for the given PBE algorithm instantiates encrypt and decrypt Ciphers.
36 * 3. instantiates CipherInputStream 1 with the encrypt Cipher.
37 * 4. instantiates CipherInputStream 2 with the CipherInputStream 1 and decrypt
38 *    Cipher.
39 * 5. the plain text is divided on TEXT_SIZE/BLOCK blocks. Reading from
40 *    CipherInputStream 2 one block at time. The last BLOCK - SAVE bytes are
41 *    skipping for each block. Therefor the plain text data go through
42 *    CipherInputStream 1 (encrypting) and CipherInputStream 2 (decrypting).
43 *    As a result the output should equal to the original text except DISCARD
44 *    byte for each block are skipped.
45 * 6. get the standard output.
46 * 7. compares the expected standard output with the output of the
47 *    CipherInputStream 2. If it is the same the test passed. Otherwise it
48 *    failed. Any uncaught exceptions should be considered as an error.
49 * The test implements 2 test cases in accordance with a buffering type:
50 * 1. byte array buffering
51 * 2. int buffering
52 */
53public class CICO_PBE_SKIP_Test extends CICO_PBE_Test {
54    /**
55     * Block size.
56     */
57    private static final int BLOCK = 50;
58
59    /**
60     * Valid reading byte size.
61     */
62    private static final int SAVE = 45;
63
64    /**
65     * Skip reading byte size. This should be same to BLOCK - SAVE
66     */
67    private static final int DISCARD = BLOCK - SAVE;
68
69    /**
70     * Number of blocks.
71     */
72    private static final int NUMBER_OF_BLOCKS = TEXT_SIZE / BLOCK;
73
74    private final byte[] outputText;
75    /**
76     * CICO PBE Skip test constructor
77     *
78     * @param pbeAlgo the PBE algorithm to test.
79     * @throws java.security.GeneralSecurityException
80     */
81    public CICO_PBE_SKIP_Test(PBEAlgorithm pbeAlgo)
82            throws GeneralSecurityException {
83        super(pbeAlgo);
84        outputText = new byte[NUMBER_OF_BLOCKS * SAVE];
85    }
86
87    /**
88     * Implements byte array buffering type test case of the CICO SKIP test.
89     *
90     * @param blockNum block number to read.
91     */
92    private void proceedSkipTestUsingByteArrayBufferingType(
93            CipherInputStream ciIn2, int blockNum) throws IOException {
94        int index = blockNum * SAVE;
95        int len1 = ciIn2.read(outputText, index, SAVE);
96        // read more until SAVE bytes
97        index += len1;
98        int len2 = 0;
99        int totalRead = len1;
100        while (len1 != SAVE && len2 != -1) {
101            len2 = ciIn2.read(outputText, index, SAVE - len1);
102            len1 += len2;
103            index += len2;
104            totalRead += len2;
105        }
106        if (totalRead != SAVE) {
107            throw new RuntimeException("Read bytes number " + totalRead
108                    + " does not equal to given number " + SAVE);
109        }
110    }
111
112    /**
113     * Implements int buffering type test case of the CICO SKIP test.
114     *
115     * @param blockNum block number to read.
116     */
117    private void proceedSkipTestUsingIntBufferingType(CipherInputStream ciIn2,
118            int blockNum) throws IOException {
119        int index = blockNum * SAVE;
120        int totalRead = 0;
121        for (int j = 0; j < SAVE; j++, index++) {
122            int buffer0 = ciIn2.read();
123            if (buffer0 != -1) {
124                outputText[index] = (byte) buffer0;
125                totalRead++;
126            } else {
127                break;
128            }
129        }
130        if (totalRead != SAVE) {
131            throw new RuntimeException("Read bytes number " + totalRead
132                    + " does not equal to given number " + SAVE);
133        }
134    }
135
136    /**
137     * The CICO PBE SKIP test specific part of the super.doTest(). Implements
138     * the scenario in accordance to the class description.
139     * @throws java.io.IOException any I/O failed.
140     */
141    @Override
142    public void proceedTest(String type) throws IOException {
143        System.out.println("Test type: " + type);
144        // init second input stream with decrypt Cipher
145        try (CipherInputStream ciIn2 = new CipherInputStream(getCiInput(),
146                getDecryptCipher())) {
147            for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
148                if (type.equals(CICO_PBE_Test.BYTE_ARR_BUFFER)) {
149                    proceedSkipTestUsingByteArrayBufferingType(ciIn2, i);
150                } else {
151                    proceedSkipTestUsingIntBufferingType(ciIn2, i);
152                }
153                if (ciIn2.available() >= DISCARD) {
154                    ciIn2.skip(DISCARD);
155                } else {
156                    for (int k = 0; k < DISCARD; k++) {
157                        ciIn2.read();
158                    }
159                }
160            }
161        }
162        if (!TestUtilities.equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) {
163            throw new RuntimeException("outputText not same with expectedText"
164                    + " when test " + type);
165        }
166    }
167
168}
169