1package org.apache.harmony.security.tests.java.security;
2
3import junit.framework.TestCase;
4
5import java.nio.ByteBuffer;
6import java.security.AlgorithmParameters;
7import java.security.InvalidAlgorithmParameterException;
8import java.security.InvalidKeyException;
9import java.security.InvalidParameterException;
10import java.security.PrivateKey;
11import java.security.PublicKey;
12import java.security.SecureRandom;
13import java.security.Signature;
14import java.security.SignatureException;
15import java.security.SignatureSpi;
16import java.security.spec.AlgorithmParameterSpec;
17import java.util.HashSet;
18import java.util.Set;
19
20public class SignatureSpiTest extends TestCase {
21
22    protected void setUp() throws Exception {
23        super.setUp();
24    }
25
26    protected void tearDown() throws Exception {
27        super.tearDown();
28    }
29
30    @SuppressWarnings("cast")
31    public void testSignatureSpi() {
32        try {
33            MySignatureSpi1 ss1 = new MySignatureSpi1();
34            assertNotNull(ss1);
35            assertTrue(ss1 instanceof SignatureSpi);
36        } catch (Exception e) {
37            fail("Unexpected exception " + e.getMessage());
38        }
39    }
40
41    public void testClone() {
42        MySignatureSpi1 ss1 = new MySignatureSpi1();
43        try {
44            MySignatureSpi1 ssc1 = (MySignatureSpi1) ss1.clone();
45            assertTrue(ss1 != ssc1);
46        } catch (CloneNotSupportedException e) {
47            fail("Unexpected CloneNotSupportedException " + e.getMessage());
48        }
49
50        MySignatureSpi2 ss2 = new MySignatureSpi2();
51        try {
52            ss2.clone();
53            fail("CloneNotSupportedException expected ");
54        } catch (CloneNotSupportedException e) {
55            // expected
56        }
57    }
58
59    public void testAbstractMethods() {
60        MySignatureSpi1 ss1 = new MySignatureSpi1();
61        byte[] b = {0, 1, 2, 3, 4, 5};
62        try {
63            ss1.engineGetParameter("test");
64            ss1.engineInitSign(null);
65            ss1.engineInitVerify(null);
66            ss1.engineSetParameter("test", null);
67            ss1.engineSign();
68            ss1.engineUpdate(b[1]);
69            ss1.engineUpdate(b, 0, b.length);
70            ss1.engineVerify(b);
71        } catch (Exception e) {
72            fail("Unexpected exception " + e.getMessage());
73        }
74    }
75
76    private boolean engineGetParametersCalled = false;
77    private boolean engineGetParametersExceptionOcurred = false;
78
79    public void testEngineGetParameters() {
80        // or rather test that no UnsupportedOperationException is thrown?
81
82        @SuppressWarnings("unused")
83        Signature s = new Signature("dummy") {
84            protected AlgorithmParameters engineGetParameters() {
85                engineGetParametersCalled = true;
86                try {
87                    super.engineGetParameters();
88                } catch (UnsupportedOperationException e) {
89                    engineGetParametersExceptionOcurred = true;
90                }
91                return null;
92            }
93
94            @Override
95            protected Object engineGetParameter(String param)
96                    throws InvalidParameterException {
97                return null;
98            }
99
100            @Override
101            protected void engineInitSign(PrivateKey privateKey)
102                    throws InvalidKeyException {
103
104            }
105
106            @Override
107            protected void engineInitVerify(PublicKey publicKey)
108                    throws InvalidKeyException {
109
110            }
111
112            @Override
113            protected void engineSetParameter(String param, Object value)
114                    throws InvalidParameterException {
115
116            }
117
118            @Override
119            protected byte[] engineSign() throws SignatureException {
120                return null;
121            }
122
123            @Override
124            protected void engineUpdate(byte b) throws SignatureException {
125
126            }
127
128            @Override
129            protected void engineUpdate(byte[] b, int off, int len)
130                    throws SignatureException {
131
132            }
133
134            @Override
135            protected boolean engineVerify(byte[] sigBytes)
136                    throws SignatureException {
137                return false;
138            }
139        };
140        // must call engineGetParameters
141        s.getParameters();
142        assertTrue(engineGetParametersCalled);
143        assertTrue(engineGetParametersExceptionOcurred);
144    }
145
146    class MySignatureSpi1 extends SignatureSpi implements Cloneable {
147
148        public Object engineGetParameter(String param) {
149            return null;
150        }
151
152        public Object clone() throws CloneNotSupportedException {
153            return super.clone();
154        }
155
156        public void engineInitSign(PrivateKey privateKey) {
157        }
158
159        public void engineInitVerify(PublicKey publicKey) {
160        }
161
162        public void engineSetParameter(String param, Object value) {
163        }
164
165        public byte[] engineSign() {
166            return null;
167        }
168
169        public void engineUpdate(byte b) {
170        }
171
172        public void engineUpdate(byte[] b, int off, int len) {
173        }
174
175        public boolean engineVerify(byte[] sigBytes) {
176            return false;
177        }
178
179    }
180
181    class MySignatureSpi2 extends SignatureSpi {
182        public Object engineGetParameter(String param) {
183            return null;
184        }
185
186        public Object clone() throws CloneNotSupportedException {
187            return super.clone();
188        }
189
190        public void engineInitSign(PrivateKey privateKey) {
191        }
192
193        public void engineInitVerify(PublicKey publicKey) {
194        }
195
196        public void engineSetParameter(String param, Object value) {
197        }
198
199        public byte[] engineSign() {
200            return null;
201        }
202
203        public void engineUpdate(byte b) {
204        }
205
206        public void engineUpdate(byte[] b, int off, int len) {
207        }
208
209        public boolean engineVerify(byte[] sigBytes) {
210            return false;
211        }
212    }
213
214    @SuppressWarnings("unused")
215    class MySignature extends Signature {
216
217        Set<String> calledMethods = new HashSet<String>();
218        protected MySignature(String algorithm) {
219            super(algorithm);
220        }
221
222        @Override
223        protected Object engineGetParameter(String param)
224                throws InvalidParameterException {
225            methodCalled("engineGetParameter_String");
226            return null;
227        }
228
229
230        @Override
231        protected void engineInitSign(PrivateKey privateKey)
232                throws InvalidKeyException {
233            methodCalled("engineInitSign_PrivateKey");
234        }
235
236        @Override
237        protected void engineInitVerify(PublicKey publicKey)
238                throws InvalidKeyException {
239            methodCalled("engineInitVerify_PublicKey");
240        }
241
242        @Override
243        protected void engineSetParameter(String param, Object value)
244                throws InvalidParameterException {
245            methodCalled("engineSetParameter_String_Object");
246        }
247
248        @Override
249        protected byte[] engineSign() throws SignatureException {
250            methodCalled("engineSign");
251            return null;
252        }
253
254        @Override
255        protected void engineUpdate(byte b) throws SignatureException {
256            methodCalled("engineUpdate_[B");
257        }
258
259        @Override
260        protected void engineUpdate(byte[] b, int off, int len)
261                throws SignatureException {
262            methodCalled("engineUpdate_[BII");
263        }
264
265        @Override
266        protected boolean engineVerify(byte[] sigBytes)
267                throws SignatureException {
268            methodCalled("engineVerify_[B");
269            return false;
270        }
271
272        @Override
273        protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
274                throws InvalidKeyException {
275            methodCalled("engineInitSign_PrivateKey_SecureRandom");
276        }
277
278        @Override
279        protected void engineSetParameter(AlgorithmParameterSpec params)
280                throws InvalidAlgorithmParameterException {
281            methodCalled("engineSetParameter_AlgorithmParameterSpec");
282        }
283
284        @Override
285        protected int engineSign(byte[] outbuf, int offset, int len)
286                throws SignatureException {
287            methodCalled("engineSign_[BII");
288            return 0;
289        }
290
291        @Override
292        protected void engineUpdate(ByteBuffer input) {
293            methodCalled("engineUpdate_ByteBuffer");
294        }
295
296        @Override
297        protected boolean engineVerify(byte[] sigBytes, int offset, int length)
298                throws SignatureException {
299            methodCalled("engineVerify_[BII");
300            return false;
301        }
302
303        boolean wasMethodCalled(String methodName) {
304            return calledMethods.contains(methodName);
305        }
306
307        void methodCalled(String methodName) {
308            calledMethods.add(methodName);
309        }
310    }
311
312    public void testEngineInitSign_PrivateKey_SecureRandom() {
313        MySignature signature = new MySignature("dummy");
314
315        try {
316            signature.initSign(null, null);
317            assertTrue("SPI method not called", signature
318                    .wasMethodCalled("engineInitSign_PrivateKey_SecureRandom"));
319        } catch (InvalidKeyException e) {
320            fail("unexpected exception: " + e);
321        }
322    }
323
324    public void testEngineSetParameter()
325    {
326        MySignature signature = new MySignature("dummy");
327
328        try {
329            signature.setParameter(null);
330            assertTrue(
331                    "SPI method not called",
332                    signature
333                            .wasMethodCalled("engineSetParameter_AlgorithmParameterSpec"));
334        } catch (InvalidAlgorithmParameterException e) {
335            fail("unexpected exception: " + e);
336        }
337    }
338
339    public void testEngineSign_BII() {
340        MySignature signature = new MySignature("dummy");
341        try {
342            signature.initSign(new PrivateKey() {
343
344                public String getFormat() {
345                    return null;
346                }
347
348                public byte[] getEncoded() {
349                    return null;
350                }
351
352                public String getAlgorithm() {
353                    return null;
354                }
355            });
356        } catch (InvalidKeyException e) {
357            fail("unexpected exception: " + e);
358        }
359        byte[] buf = new byte[10];
360        try {
361            signature.sign(buf, 2, 1);
362            assertTrue("SPI method not called", signature
363                    .wasMethodCalled("engineSign_[BII"));
364        } catch (SignatureException e) {
365            fail("unexpected exception: " + e);
366        }
367    }
368
369    public void testEngineUpdate_ByteBuffer() {
370        MySignature signature = new MySignature("dummy");
371        try {
372            signature.initSign(new PrivateKey() {
373
374                public String getFormat() {
375                    return null;
376                }
377
378                public byte[] getEncoded() {
379                    return null;
380                }
381
382                public String getAlgorithm() {
383                    return null;
384                }
385            });
386        } catch (InvalidKeyException e) {
387            fail("unexpected exception: " + e);
388        }
389
390        try {
391            signature.update(ByteBuffer.wrap("Hello".getBytes()));
392            assertTrue("SPI method not called", signature
393                    .wasMethodCalled("engineUpdate_ByteBuffer"));
394        } catch (SignatureException e) {
395            fail("unexpected exception");
396        }
397    }
398
399    public void testEngineVerify_BII() {
400        MySignature signature = new MySignature("dummy");
401
402        try {
403            signature.initVerify(new PublicKey() {
404
405                public String getFormat() {
406                    return null;
407                }
408
409                public byte[] getEncoded() {
410                    return null;
411                }
412
413                public String getAlgorithm() {
414                    return null;
415                }
416            });
417        } catch (InvalidKeyException e) {
418            fail("unexpected exception");
419        }
420
421        byte[] buf = new byte[10];
422
423        try {
424            signature.verify(buf, 2, 5);
425            signature.wasMethodCalled("engineVerify_[BII");
426        } catch (SignatureException e) {
427            fail("unexpected exception");
428        }
429    }
430
431}
432