18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (C) 2012 The Android Open Source Project
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Licensed under the Apache License, Version 2.0 (the "License");
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * you may not use this file except in compliance with the License.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * You may obtain a copy of the License at
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *      http://www.apache.org/licenses/LICENSE-2.0
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Unless required by applicable law or agreed to in writing, software
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * distributed under the License is distributed on an "AS IS" BASIS,
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See the License for the specific language governing permissions and
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * limitations under the License.
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpackage android.content.pm;
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport android.test.AndroidTestCase;
2064f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport java.io.ByteArrayInputStream;
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtimport java.util.Arrays;
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2464f47c5c24428834677459e048420f86e3514c20Dmitry Shmidtimport javax.crypto.Mac;
2564f47c5c24428834677459e048420f86e3514c20Dmitry Shmidtimport javax.crypto.SecretKey;
2664f47c5c24428834677459e048420f86e3514c20Dmitry Shmidtimport javax.crypto.spec.SecretKeySpec;
2764f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt
2864f47c5c24428834677459e048420f86e3514c20Dmitry Shmidtimport libcore.io.Streams;
2964f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic class MacAuthenticatedInputStreamTest extends AndroidTestCase {
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    private static final SecretKey HMAC_KEY_1 = new SecretKeySpec("test_key_1".getBytes(), "HMAC");
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    private static final byte[] TEST_STRING_1 = "Hello, World!".getBytes();
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /**
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt     * Generated with:
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt     *
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt     * echo -n 'Hello, World!' | openssl dgst -hmac 'test_key_1' -binary -sha1 | recode ..//x1 |
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt     *   sed 's/0x/(byte) 0x/g'
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt     */
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    private static final byte[] TEST_STRING_1_MAC = {
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            (byte) 0x29, (byte) 0xB1, (byte) 0x87, (byte) 0x6B, (byte) 0xFE, (byte) 0x83,
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            (byte) 0x96, (byte) 0x51, (byte) 0x61, (byte) 0x02, (byte) 0xAF, (byte) 0x7B,
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            (byte) 0xBA, (byte) 0x05, (byte) 0xE6, (byte) 0xA4, (byte) 0xAB, (byte) 0x36,
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            (byte) 0x18, (byte) 0x02
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    };
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /**
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt     * Same as TEST_STRING_1_MAC but with the first byte as 0x28 instead of
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt     * 0x29.
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt     */
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    private static final byte[] TEST_STRING_1_MAC_BROKEN = {
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            (byte) 0x28, (byte) 0xB1, (byte) 0x87, (byte) 0x6B, (byte) 0xFE, (byte) 0x83,
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            (byte) 0x96, (byte) 0x51, (byte) 0x61, (byte) 0x02, (byte) 0xAF, (byte) 0x7B,
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            (byte) 0xBA, (byte) 0x05, (byte) 0xE6, (byte) 0xA4, (byte) 0xAB, (byte) 0x36,
57            (byte) 0x18, (byte) 0x02
58    };
59
60    private ByteArrayInputStream mTestStream1;
61
62    @Override
63    protected void setUp() throws Exception {
64        super.setUp();
65
66        mTestStream1 = new ByteArrayInputStream(TEST_STRING_1);
67    }
68
69    public void testString1Authenticate_Success() throws Exception {
70        Mac mac = Mac.getInstance("HMAC-SHA1");
71        mac.init(HMAC_KEY_1);
72
73        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
74
75        assertTrue(Arrays.equals(TEST_STRING_1, Streams.readFully(is)));
76
77        assertTrue(is.isTagEqual(TEST_STRING_1_MAC));
78    }
79
80    public void testString1Authenticate_WrongTag_Failure() throws Exception {
81        Mac mac = Mac.getInstance("HMAC-SHA1");
82        mac.init(HMAC_KEY_1);
83
84        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
85
86        assertTrue(Arrays.equals(TEST_STRING_1, Streams.readFully(is)));
87
88        assertFalse(is.isTagEqual(TEST_STRING_1_MAC_BROKEN));
89    }
90
91    public void testString1Authenticate_NullTag_Failure() throws Exception {
92        Mac mac = Mac.getInstance("HMAC-SHA1");
93        mac.init(HMAC_KEY_1);
94
95        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
96
97        assertTrue(Arrays.equals(TEST_STRING_1, Streams.readFully(is)));
98
99        assertFalse(is.isTagEqual(null));
100    }
101
102    public void testString1Authenticate_ReadSingleByte_Success() throws Exception {
103        Mac mac = Mac.getInstance("HMAC-SHA1");
104        mac.init(HMAC_KEY_1);
105
106        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
107
108        int numRead = 0;
109        while (is.read() != -1) {
110            numRead++;
111
112            if (numRead > TEST_STRING_1.length) {
113                fail("read too many bytes");
114            }
115        }
116        assertEquals(TEST_STRING_1.length, numRead);
117
118        assertTrue(is.isTagEqual(TEST_STRING_1_MAC));
119    }
120}
121