1ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward/*
2ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * Copyright (C) 2012 The Android Open Source Project
3ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward *
4ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * Licensed under the Apache License, Version 2.0 (the "License");
5ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * you may not use this file except in compliance with the License.
6ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * You may obtain a copy of the License at
7ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward *
8ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward *      http://www.apache.org/licenses/LICENSE-2.0
9ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward *
10ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * Unless required by applicable law or agreed to in writing, software
11ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * distributed under the License is distributed on an "AS IS" BASIS,
12ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * See the License for the specific language governing permissions and
14ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward * limitations under the License.
15ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward */
16ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
17ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardpackage android.content.pm;
18ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
19ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport android.test.AndroidTestCase;
20ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
21ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport java.io.ByteArrayInputStream;
22ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport java.util.Arrays;
23ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
24ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport javax.crypto.Mac;
25ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport javax.crypto.SecretKey;
26ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport javax.crypto.spec.SecretKeySpec;
27ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
28ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardimport libcore.io.Streams;
29ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
30ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Cowardpublic class MacAuthenticatedInputStreamTest extends AndroidTestCase {
31ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
32ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private static final SecretKey HMAC_KEY_1 = new SecretKeySpec("test_key_1".getBytes(), "HMAC");
33ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
34ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private static final byte[] TEST_STRING_1 = "Hello, World!".getBytes();
35ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
36ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /**
37ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * Generated with:
38ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     *
39ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * echo -n 'Hello, World!' | openssl dgst -hmac 'test_key_1' -binary -sha1 | recode ..//x1 |
40ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     *   sed 's/0x/(byte) 0x/g'
41ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     */
42ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private static final byte[] TEST_STRING_1_MAC = {
43ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            (byte) 0x29, (byte) 0xB1, (byte) 0x87, (byte) 0x6B, (byte) 0xFE, (byte) 0x83,
44ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            (byte) 0x96, (byte) 0x51, (byte) 0x61, (byte) 0x02, (byte) 0xAF, (byte) 0x7B,
45ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            (byte) 0xBA, (byte) 0x05, (byte) 0xE6, (byte) 0xA4, (byte) 0xAB, (byte) 0x36,
46ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            (byte) 0x18, (byte) 0x02
47ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    };
48ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
49ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    /**
50ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * Same as TEST_STRING_1_MAC but with the first byte as 0x28 instead of
51ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     * 0x29.
52ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward     */
53ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private static final byte[] TEST_STRING_1_MAC_BROKEN = {
54ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            (byte) 0x28, (byte) 0xB1, (byte) 0x87, (byte) 0x6B, (byte) 0xFE, (byte) 0x83,
55ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            (byte) 0x96, (byte) 0x51, (byte) 0x61, (byte) 0x02, (byte) 0xAF, (byte) 0x7B,
56ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            (byte) 0xBA, (byte) 0x05, (byte) 0xE6, (byte) 0xA4, (byte) 0xAB, (byte) 0x36,
57ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            (byte) 0x18, (byte) 0x02
58ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    };
59ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
60ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    private ByteArrayInputStream mTestStream1;
61ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
62ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    @Override
63ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    protected void setUp() throws Exception {
64ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        super.setUp();
65ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
66ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mTestStream1 = new ByteArrayInputStream(TEST_STRING_1);
67ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
68ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
69ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public void testString1Authenticate_Success() throws Exception {
70ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        Mac mac = Mac.getInstance("HMAC-SHA1");
71ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mac.init(HMAC_KEY_1);
72ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
73ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
74ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
75ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        assertTrue(Arrays.equals(TEST_STRING_1, Streams.readFully(is)));
76ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
77ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        assertTrue(is.isTagEqual(TEST_STRING_1_MAC));
78ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
79ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
80ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public void testString1Authenticate_WrongTag_Failure() throws Exception {
81ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        Mac mac = Mac.getInstance("HMAC-SHA1");
82ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mac.init(HMAC_KEY_1);
83ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
84ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
85ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
86ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        assertTrue(Arrays.equals(TEST_STRING_1, Streams.readFully(is)));
87ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
88ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        assertFalse(is.isTagEqual(TEST_STRING_1_MAC_BROKEN));
89ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
90ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
91ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public void testString1Authenticate_NullTag_Failure() throws Exception {
92ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        Mac mac = Mac.getInstance("HMAC-SHA1");
93ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mac.init(HMAC_KEY_1);
94ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
95ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
96ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
97ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        assertTrue(Arrays.equals(TEST_STRING_1, Streams.readFully(is)));
98ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
99ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        assertFalse(is.isTagEqual(null));
100ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
101ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
102ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    public void testString1Authenticate_ReadSingleByte_Success() throws Exception {
103ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        Mac mac = Mac.getInstance("HMAC-SHA1");
104ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        mac.init(HMAC_KEY_1);
105ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
106ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
107ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
108ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        int numRead = 0;
109ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        while (is.read() != -1) {
110ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            numRead++;
111ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
112ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            if (numRead > TEST_STRING_1.length) {
113ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward                fail("read too many bytes");
114ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward            }
115ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        }
116ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        assertEquals(TEST_STRING_1.length, numRead);
117ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward
118ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward        assertTrue(is.isTagEqual(TEST_STRING_1_MAC));
119ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward    }
120ceb1b0bfaea56251796b08c07b963de7403d84ebAnonymous Coward}
121