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 Vera Y. Petrashkova
20* @version $Revision$
21*/
22
23package org.apache.harmony.security.tests.java.security;
24
25import java.security.KeyStore;
26import java.security.PrivateKey;
27import java.security.cert.Certificate;
28import java.util.Collections;
29import java.util.HashSet;
30import java.util.Set;
31
32import org.apache.harmony.security.tests.support.cert.MyCertificate;
33
34import junit.framework.TestCase;
35
36import junit.framework.Test;
37import junit.framework.TestSuite;
38
39/**
40 * Tests for <code>KeyStore.PrivateKeyEntry</code>  class constructor and methods
41 *
42 */
43public class KSPrivateKeyEntryTest extends TestCase {
44
45    private PrivateKey testPrivateKey;
46    private Certificate [] testChain;
47
48    private void createParams(boolean diffCerts, boolean diffKeys) {
49        byte[] encoded = {(byte)0, (byte)1, (byte)2, (byte)3};
50        testChain = new Certificate[5];
51        for (int i = 0; i < testChain.length; i++) {
52            String s = (diffCerts ? Integer.toString(i) : "NEW");
53            testChain[i] = new MyCertificate("MY_TEST_CERTIFICATE_"
54                    .concat(s), encoded);
55        }
56        testPrivateKey = (diffKeys ? (PrivateKey)new tmpPrivateKey() :
57            (PrivateKey)new tmpPrivateKey(testChain[0].getPublicKey().getAlgorithm()));
58    }
59
60    /**
61     * Test for <code>PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain)</code>
62     * constructor
63     * Assertion: throws NullPointerException when privateKey is null
64     */
65    public void testPrivateKeyEntry01() {
66        Certificate[] certs = new MyCertificate[1];//new Certificate[1];
67        PrivateKey pk = null;
68        try {
69            new KeyStore.PrivateKeyEntry(pk, certs);
70            fail("NullPointerException must be thrown when privateKey is null");
71        } catch (NullPointerException e) {
72        }
73    }
74
75    /**
76     * Test for <code>PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain)</code>
77     * constructor
78     * Assertion: throws NullPointerException when chain is null
79     * and throws IllegalArgumentException when chain length is 0
80     */
81    public void testPrivateKeyEntry02() {
82        Certificate[] chain = null;
83        PrivateKey pk = new tmpPrivateKey();
84        try {
85            new KeyStore.PrivateKeyEntry(pk, chain);
86            fail("NullPointerException must be thrown when chain is null");
87        } catch (NullPointerException e) {
88        }
89        try {
90            chain = new Certificate[0];
91            new KeyStore.PrivateKeyEntry(pk, chain);
92            fail("IllegalArgumentException must be thrown when chain length is 0");
93        } catch (IllegalArgumentException e) {
94        }
95    }
96    /**
97     * Test for <code>PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain)</code>
98     * constructor
99     * Assertion: throws IllegalArgumentException when chain contains certificates
100     * of different types
101     */
102    public void testPrivateKeyEntry03() {
103        createParams(true, false);
104        try {
105            new KeyStore.PrivateKeyEntry(testPrivateKey, testChain);
106            fail("IllegalArgumentException must be thrown when chain contains certificates of different types");
107        } catch (IllegalArgumentException e) {
108        }
109    }
110
111    /**
112     * Test for <code>PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain)</code>
113     * constructor
114     * Assertion: throws IllegalArgumentException when algorithm of privateKey
115     * does not match the algorithm of PublicKey in the end certificate (with 0 index)
116     */
117    public void testPrivateKeyEntry04() {
118        createParams(false, true);
119        try {
120            new KeyStore.PrivateKeyEntry(testPrivateKey, testChain);
121            fail("IllegalArgumentException must be thrown when key algorithms do not match");
122        } catch (IllegalArgumentException e) {
123        }
124    }
125
126    /**
127     * Test for
128     * <code>PrivateKeyEntry(
129     *         PrivateKey privateKey, Certificate[] chain, Set<Attribute> attributes)</code>
130     * constructor
131     * Assertion: throws NullPointerException when attributes is null
132     */
133    public void testPrivateKeyEntry05() {
134        createParams(false, true);
135        try {
136            new KeyStore.PrivateKeyEntry(testPrivateKey, testChain, null /* attributes */);
137            fail("NullPointerException must be thrown when attributes is null");
138        } catch (NullPointerException expected) {
139        }
140    }
141
142    /**
143     * Test for <code>getPrivateKey()</code> method
144     * Assertion: returns PrivateKey object
145     */
146    public void testGetPrivateKey() {
147        createParams(false, false);
148        KeyStore.PrivateKeyEntry ksPKE = new KeyStore.PrivateKeyEntry(
149                testPrivateKey, testChain);
150        assertEquals("Incorrect PrivateKey", testPrivateKey, ksPKE
151                .getPrivateKey());
152    }
153
154    /**
155     * Test for <code>getCertificateChain()</code> method Assertion: returns
156     * array of the Certificates corresponding to chain
157     */
158    public void testGetCertificateChain() {
159        createParams(false, false);
160        KeyStore.PrivateKeyEntry ksPKE = new KeyStore.PrivateKeyEntry(
161                testPrivateKey, testChain);
162        Certificate[] res = ksPKE.getCertificateChain();
163        assertEquals("Incorrect chain length", testChain.length, res.length);
164        for (int i = 0; i < res.length; i++) {
165            assertEquals("Incorrect chain element: "
166                    .concat(Integer.toString(i)), testChain[i], res[i]);
167        }
168    }
169
170    /**
171     * Test for <code>getCertificate()</code> method
172     * Assertion: returns end Certificate (with 0 index in chain)
173     */
174    public void testGetCertificate() {
175        createParams(false, false);
176        KeyStore.PrivateKeyEntry ksPKE = new KeyStore.PrivateKeyEntry(
177                testPrivateKey, testChain);
178        Certificate res = ksPKE.getCertificate();
179        assertEquals("Incorrect end certificate (number 0)", testChain[0], res);
180    }
181
182    /**
183     * Test for <code>getAttributes()</code> method
184     * Assertion: returns attributes specified in the constructor, as an unmodifiable set.
185     */
186    public void testGetAttributes() {
187        createParams(false, false);
188        final String attributeName = "theAttributeName";
189        KeyStore.Entry.Attribute myAttribute = new KeyStore.Entry.Attribute() {
190            @Override
191            public String getName() {
192                return attributeName;
193            }
194
195            @Override
196            public String getValue() {
197                return null;
198            }
199        };
200        Set<KeyStore.Entry.Attribute> attributeSet = new HashSet<KeyStore.Entry.Attribute>();
201        attributeSet.add(myAttribute);
202
203        KeyStore.PrivateKeyEntry ksPKE = new KeyStore.PrivateKeyEntry(
204                testPrivateKey, testChain, attributeSet);
205        Set<KeyStore.Entry.Attribute> returnedAttributeSet = ksPKE.getAttributes();
206        assertEquals(attributeSet, returnedAttributeSet);
207        // Adding an element to the original set is OK.
208        attributeSet.add(myAttribute);
209        // The returned set is unmodifiabled.
210        try {
211            returnedAttributeSet.add(myAttribute);
212            fail("The returned set of attributed should be unmodifiable");
213        } catch (UnsupportedOperationException expected) {
214        }
215    }
216
217    /**
218     * Test for <code>toString()</code> method
219     * Assertion: returns non null String
220     */
221    public void testToString() {
222        createParams(false, false);
223        KeyStore.PrivateKeyEntry ksPKE = new KeyStore.PrivateKeyEntry(
224                testPrivateKey, testChain);
225        String res = ksPKE.toString();
226        assertNotNull("toString() returns null", res);
227    }
228
229    public static Test suite() {
230        return new TestSuite(KSPrivateKeyEntryTest.class);
231    }
232
233    private static class tmpPrivateKey implements PrivateKey {
234        private String alg = "My algorithm";
235
236        public String getAlgorithm() {
237            return alg;
238        }
239
240        public String getFormat() {
241            return "My Format";
242        }
243
244        public byte[] getEncoded() {
245            return new byte[1];
246        }
247
248        public tmpPrivateKey() {
249        }
250
251        public tmpPrivateKey(String algorithm) {
252            super();
253            alg = algorithm;
254        }
255    }
256}
257