1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18/**
19* @author Alexander Y. Kleymenov
20* @version $Revision$
21*/
22
23package org.apache.harmony.crypto.tests.javax.crypto;
24
25import java.io.BufferedOutputStream;
26import java.io.ByteArrayInputStream;
27import java.io.ByteArrayOutputStream;
28import java.io.OutputStream;
29import java.security.InvalidKeyException;
30import java.security.Key;
31import java.security.NoSuchAlgorithmException;
32import java.security.SecureRandom;
33import java.util.Arrays;
34
35import javax.crypto.KeyGenerator;
36import javax.crypto.NoSuchPaddingException;
37import javax.crypto.NullCipher;
38import javax.crypto.CipherOutputStream;
39import javax.crypto.Cipher;
40
41import junit.framework.TestCase;
42
43/**
44 */
45public class CipherOutputStream1Test extends TestCase {
46
47    private static class TestOutputStream extends ByteArrayOutputStream {
48        private boolean closed = false;
49
50        public void close() {
51            closed = true;
52        }
53
54        public boolean wasClosed() {
55            return closed;
56        }
57    }
58
59    /**
60     * CipherOutputStream(OutputStream os) method testing. Tests that
61     * CipherOutputStream uses NullCipher if Cipher is not specified
62     * in the constructor.
63     */
64    public void testCipherOutputStream() throws Exception {
65        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
66        TestOutputStream tos = new TestOutputStream();
67        CipherOutputStream cos = new CipherOutputStream(tos){};
68        cos.write(data);
69        cos.flush();
70        byte[] result = tos.toByteArray();
71        if (!Arrays.equals(result, data)) {
72            fail("NullCipher should be used " + "if Cipher is not specified.");
73        }
74    }
75
76    /**
77     * write(int b) method testing. Tests that method writes correct values to
78     * the underlying output stream.
79     */
80    public void testWrite1() throws Exception {
81        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
82        TestOutputStream tos = new TestOutputStream();
83        CipherOutputStream cos = new CipherOutputStream(tos, new NullCipher());
84        for (int i = 0; i < data.length; i++) {
85            cos.write(data[i]);
86        }
87        cos.flush();
88        byte[] result = tos.toByteArray();
89        if (!Arrays.equals(result, data)) {
90            fail("CipherOutputStream wrote incorrect data.");
91        }
92    }
93
94    /**
95     * write(byte[] b) method testing. Tests that method writes correct values
96     * to the underlying output stream.
97     */
98    public void testWrite2() throws Exception {
99        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
100        TestOutputStream tos = new TestOutputStream();
101        CipherOutputStream cos = new CipherOutputStream(tos, new NullCipher());
102        cos.write(data);
103        cos.flush();
104        byte[] result = tos.toByteArray();
105        if (!Arrays.equals(result, data)) {
106            fail("CipherOutputStream wrote incorrect data.");
107        }
108
109        try {
110            cos.write(null);
111            fail("NullPointerException expected");
112        } catch (NullPointerException e) {
113            //expected
114        }
115    }
116
117    /**
118     * write(byte[] b, int off, int len) method testing.
119     */
120    public void testWrite3() throws Exception {
121        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
122        TestOutputStream tos = new TestOutputStream();
123        CipherOutputStream cos = new CipherOutputStream(tos, new NullCipher());
124        for (int i = 0; i < data.length; i++) {
125            cos.write(data, i, 1);
126        }
127        cos.flush();
128        byte[] result = tos.toByteArray();
129        if (!Arrays.equals(result, data)) {
130            fail("CipherOutputStream wrote incorrect data.");
131        }
132    }
133
134    /**
135     * write(byte[] b, int off, int len)
136     */
137    public void testWrite4() throws Exception {
138        //Regression for HARMONY-758
139        try {
140            new CipherOutputStream(new BufferedOutputStream((OutputStream) null), new NullCipher()).write(new byte[] {0}, 1, Integer.MAX_VALUE);
141        } catch (IllegalArgumentException e) {
142        }
143    }
144
145    /**
146     * write(byte[] b, int off, int len)
147     */
148    public void testWrite5() throws Exception {
149        //Regression for HARMONY-758
150        Cipher cf = Cipher.getInstance("DES/CBC/PKCS5Padding");
151        NullCipher nc = new NullCipher();
152        CipherOutputStream stream1 = new CipherOutputStream(new BufferedOutputStream((OutputStream) null), nc);
153        CipherOutputStream stream2 = new CipherOutputStream(stream1, cf);
154        CipherOutputStream stream3 = new CipherOutputStream(stream2, nc);
155        stream3.write(new byte[] {0}, 0, 0);
156           //no exception expected
157    }
158
159    /**
160     * flush() method testing. Tests that method flushes the data to the
161     * underlying output stream.
162     */
163    public void testFlush() throws Exception {
164        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
165        TestOutputStream tos = new TestOutputStream();
166        CipherOutputStream cos = new CipherOutputStream(tos){};
167        cos.write(data);
168        cos.flush();
169        byte[] result = tos.toByteArray();
170        if (!Arrays.equals(result, data)) {
171            fail("CipherOutputStream did not flush the data.");
172        }
173    }
174
175    /**
176     * close() method testing. Tests that the method calls the close() method of
177     * the underlying input stream.
178     */
179    public void testClose() throws Exception {
180        byte[] data = new byte[] { -127, -100, -50, -10, -1, 0, 1, 10, 50, 127 };
181        TestOutputStream tos = new TestOutputStream();
182        CipherOutputStream cos = new CipherOutputStream(tos){};
183        cos.write(data);
184        cos.close();
185        byte[] result = tos.toByteArray();
186        if (!Arrays.equals(result, data)) {
187            fail("CipherOutputStream did not flush the data.");
188        }
189        assertTrue("The close() method should call the close() method "
190                + "of its underlying output stream.", tos.wasClosed());
191    }
192
193    public void test_ConstructorLjava_io_OutputStreamLjavax_crypto_Cipher() throws
194    NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
195        ByteArrayOutputStream baos = new ByteArrayOutputStream();
196
197        KeyGenerator kg = KeyGenerator.getInstance("DES");
198        kg.init(56, new SecureRandom());
199        Key key = kg.generateKey();
200
201        Cipher c = Cipher.getInstance("DES/CBC/NoPadding");
202        c.init(Cipher.ENCRYPT_MODE, key);
203
204        CipherOutputStream cos = new CipherOutputStream(baos, c);
205
206        assertNotNull(cos);
207    }
208}
209
210