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
18package org.apache.harmony.security.tests.java.security;
19
20import java.nio.ByteBuffer;
21import java.security.DigestException;
22import java.security.MessageDigest;
23import java.security.MessageDigestSpi;
24import java.security.NoSuchAlgorithmException;
25import java.security.Provider;
26
27import junit.framework.TestCase;
28
29import org.apache.harmony.security.tests.support.MyMessageDigest1;
30
31/**
32 * Tests for <code>MessageDigest</code> constructor and methods
33 */
34public class MessageDigest1Test extends TestCase {
35
36    /**
37     * java.security.MessageDigest#reset()
38     */
39    public void test_reset() {
40        MyMessageDigest1 md = new MyMessageDigest1("ABC");
41        md.reset();
42        assertTrue(md.runEngineReset);
43    }
44
45    /**
46     * java.security.MessageDigest#update(byte)
47     */
48    public void test_updateLB() {
49        MyMessageDigest1 md = new MyMessageDigest1("ABC");
50        md.update((byte) 1);
51        assertTrue(md.runEngineUpdate1);
52    }
53
54    /**
55     * java.security.MessageDigest#update(byte[], int, int)
56     */
57    public void test_updateLB$LILI() {
58        MyMessageDigest1 md = new MyMessageDigest1("ABC");
59        final byte[] bytes = { 1, 2, 3, 4, 5 };
60        md.update(bytes, 1, 2);
61        assertTrue(md.runEngineUpdate2);
62
63        // Regression for HARMONY-1120
64        try {
65            // buf == null
66            md.update(null, 0, 1);
67            fail("No expected IllegalArgumentException");
68        } catch (IllegalArgumentException e) {
69        }
70        try {
71            // offset + len > buf.length
72            md.update(bytes, 0, bytes.length + 1);
73            fail("No expected IllegalArgumentException");
74        } catch (IllegalArgumentException e) {
75        }
76        try {
77            // offset + len > Integer.MAX_VALUE
78            md.update(bytes, Integer.MAX_VALUE, 1);
79            fail("No expected IllegalArgumentException");
80        } catch (IllegalArgumentException e) {
81        }
82        // offset<0 and len<0 are passed to provider
83        final int offset = -1;
84        final int len = -1;
85        md = new MyMessageDigest1("ABC") {
86            @Override
87            public void engineUpdate(byte[] arg0, int arg1, int arg2) {
88                assertSame("buf", bytes, arg0);
89                assertEquals("offset", offset, arg1);
90                assertEquals("len", len, arg2);
91                runEngineUpdate2 = true;
92            }
93        };
94        md.update(bytes, offset, len);
95        assertTrue(md.runEngineUpdate2);
96    }
97
98    /**
99     * java.security.MessageDigest#update(byte[])
100     */
101    public void test_updateLB$() {
102        MyMessageDigest1 md = new MyMessageDigest1("ABC");
103        byte[] b = { 1, 2, 3, 4, 5 };
104        md.update(b);
105        assertTrue(md.runEngineUpdate2);
106    }
107
108    /**
109     * java.security.MessageDigest#update(ByteBuffer)
110     */
111    public void test_updateLjava_nio_ByteBuffer() {
112        MyMessageDigest1 md = new MyMessageDigest1("ABC");
113        byte[] b = { 1, 2, 3, 4, 5 };
114        ByteBuffer byteBuffer = ByteBuffer.wrap(b);
115
116        int limit = byteBuffer.limit();
117        md.update(byteBuffer);
118        assertTrue(md.runEngineUpdate2);
119        assertEquals(byteBuffer.limit(), byteBuffer.position());
120        assertEquals(limit, byteBuffer.limit());
121    }
122
123    /**
124     * java.security.MessageDigest#digest()
125     */
126    public void test_digest() {
127        MyMessageDigest1 md = new MyMessageDigest1("ABC");
128        assertEquals("incorrect result", 0, md.digest().length);
129        assertTrue(md.runEngineDigest);
130    }
131
132    /**
133     * java.security.MessageDigest#digest(byte[])
134     */
135    public void test_digestLB$() {
136        MyMessageDigest1 md = new MyMessageDigest1("ABC");
137        byte[] b = { 1, 2, 3, 4, 5 };
138        assertEquals("incorrect result", 0, md.digest(b).length);
139        assertTrue(md.runEngineDigest);
140    }
141
142    /**
143     * java.security.MessageDigest#digest(byte[], int, int)
144     */
145    public void test_digestLB$LILI() throws Exception {
146        MyMessageDigest1 md = new MyMessageDigest1("ABC");
147        byte[] b = { 1, 2, 3, 4, 5 };
148        assertEquals("incorrect result", 0, md.digest(b, 2, 3));
149        assertTrue("digest failed", md.runEngineDigest);
150
151        // Regression for Harmony-1148
152        md = new MyMessageDigest1();
153        final byte[] bytes = new byte[] { 2, 4, 1 };
154        try {
155            // buf == null
156            md.digest(null, 0, 1);
157            fail("No expected IllegalArgumentException");
158        } catch (IllegalArgumentException e) {
159        }
160        try {
161            // offset + len > buf.length
162            md.digest(bytes, 0, bytes.length + 1);
163            fail("No expected IllegalArgumentException");
164        } catch (IllegalArgumentException e) {
165        }
166        try {
167            // offset + len > Integer.MAX_VALUE
168            md.digest(bytes, Integer.MAX_VALUE, 1);
169            fail("No expected IllegalArgumentException");
170        } catch (IllegalArgumentException e) {
171        }
172        // offset<0 and len<0 are passed to provider
173        final int offset = -1;
174        final int len = -1;
175        final int status = 33;
176        md = new MyMessageDigest1("ABC") {
177            @Override
178            public int engineDigest(byte[] arg0, int arg1, int arg2) {
179                assertSame("buf", bytes, arg0);
180                assertEquals("offset", offset, arg1);
181                assertEquals("len", len, arg2);
182                return status;
183            }
184        };
185        assertEquals("returned status", status, md.digest(bytes, offset, len));
186
187        try {
188            MessageDigest digest = MessageDigest.getInstance("TestDigest", new TestProvider());
189            digest.digest(new byte[5], 0, 5);
190            fail("expected DigestException");
191        } catch (DigestException e) {
192            // ok
193        }
194    }
195
196    /**
197     * java.security.MessageDigest#isEqual(byte[],byte[])
198     */
199    public void test_isEqualLB$LB$() {
200        byte[] b1 = { 1, 2, 3, 4 };
201        byte[] b2 = { 1, 2, 3, 4, 5 };
202        byte[] b3 = { 1, 3, 3, 4 };
203        byte[] b4 = { 1, 2, 3, 4 };
204
205        assertTrue(MessageDigest.isEqual(b1, b4));
206        assertFalse(MessageDigest.isEqual(b1, b2));
207        assertFalse(MessageDigest.isEqual(b1, b3));
208    }
209
210    /**
211     * java.security.MessageDigest#getAlgorithm()
212     */
213    public void test_getAlgorithm() {
214        MyMessageDigest1 md = new MyMessageDigest1("ABC");
215        assertEquals("ABC", md.getAlgorithm());
216    }
217
218    /**
219     * java.security.MessageDigest#getProvider()
220     */
221    public void test_getProvider() {
222        MyMessageDigest1 md = new MyMessageDigest1("ABC");
223        assertNull(md.getProvider());
224    }
225
226    /**
227     * java.security.MessageDigest#getDigestLength()
228     */
229    public void test_getDigestLength() {
230        MyMessageDigest1 md = new MyMessageDigest1("ABC");
231        assertEquals(0, md.getDigestLength());
232    }
233
234    /**
235     * Tests SHA MessageDigest provider
236     */
237    public void testSHAProvider() {
238        MessageDigest md = null;
239        try {
240            md = MessageDigest.getInstance("SHA");
241        } catch (NoSuchAlgorithmException e) {
242            fail("unexpected exception: " + e);
243        }
244        byte[] bytes = new byte[] { 1, 1, 1, 1, 1 };
245
246        // Regression for HARMONY-1120
247        // testing combination with provider
248        try {
249            // offset < 0
250            md.update(bytes, -1, 1);
251            fail("No expected IndexOutOfBoundsException");
252        } catch (IndexOutOfBoundsException e) {
253        }
254        try {
255            md.update(bytes, 1, -1);
256            fail("No expected IndexOutOfBoundsException");
257        } catch (IndexOutOfBoundsException e) {
258        }
259
260        //Regression for Harmony-1148
261        try {
262            md = MessageDigest.getInstance("SHA");
263        } catch (NoSuchAlgorithmException e) {
264            fail("unexpected exception: " + e);
265        }
266        try {
267            // offset < 0
268            md.digest(bytes, 0, -1);
269            fail("No expected DigestException");
270        } catch (DigestException e) {
271        }
272        try {
273            // len < 0
274            md.digest(bytes, -1, 0);
275            fail("No expected DigestException");
276        } catch (DigestException e) {
277        }
278
279
280        try {
281            md = MessageDigest.getInstance("UnknownDigest");
282            fail("expected NoSuchAlgorithmException");
283        } catch (NoSuchAlgorithmException e) {
284            // ok
285        }
286
287    }
288
289    class TestProvider extends Provider {
290        public TestProvider() {
291            super("TestProvider", 1.0, "info");
292            put("MessageDigest.TestDigest", TestMessageDigestSpi.class.getName());
293        }
294    }
295
296    public static class TestMessageDigestSpi extends MessageDigestSpi {
297
298        public TestMessageDigestSpi() {
299        }
300
301        @Override
302        protected byte[] engineDigest() {
303            return new byte[]{3,4,5,6,7,8,9,3,45,6,7,};
304        }
305
306        @Override
307        protected void engineReset() {
308
309        }
310
311        @Override
312        protected void engineUpdate(byte input) {
313
314        }
315
316        @Override
317        protected void engineUpdate(byte[] input, int offset, int len) {
318
319        }
320
321        @Override
322        protected int engineGetDigestLength() {
323            return 42;
324        }
325    }
326}
327