Home | History | Annotate | Download | only in security
      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 package org.apache.harmony.security.tests.java.security;
     19 
     20 import java.security.InvalidKeyException;
     21 import java.security.Key;
     22 import java.security.KeyFactory;
     23 import java.security.KeyFactorySpi;
     24 import java.security.KeyPair;
     25 import java.security.KeyPairGenerator;
     26 import java.security.NoSuchAlgorithmException;
     27 import java.security.NoSuchProviderException;
     28 import java.security.PrivateKey;
     29 import java.security.Provider;
     30 import java.security.PublicKey;
     31 import java.security.SecureRandom;
     32 import java.security.Security;
     33 import java.security.spec.InvalidKeySpecException;
     34 import java.security.spec.KeySpec;
     35 import java.security.spec.PKCS8EncodedKeySpec;
     36 import java.security.spec.X509EncodedKeySpec;
     37 import java.util.Arrays;
     38 import java.util.Enumeration;
     39 import java.util.Vector;
     40 import libcore.java.security.StandardNames;
     41 
     42 public class KeyFactory2Test extends junit.framework.TestCase {
     43 
     44     private static final String KEYFACTORY_ID = "KeyFactory.";
     45 
     46     private String[] keyfactAlgs = null;
     47 
     48     private String providerName = null;
     49 
     50     static class KeepAlive extends Thread {
     51         int sleepTime, iterations;
     52 
     53         public KeepAlive(int sleepTime, int iterations) {
     54             this.sleepTime = sleepTime;
     55             this.iterations = iterations;
     56         }
     57 
     58         public void run() {
     59             synchronized (this) {
     60                 this.notify();
     61             }
     62             for (int i = 0; i < iterations; i++) {
     63                 try {
     64                     Thread.sleep(sleepTime);
     65                 } catch (InterruptedException e) {
     66                     break;
     67                 }
     68             }
     69         }
     70     }
     71 
     72     private KeepAlive createKeepAlive(String alg) {
     73         if (alg.equals("RSA")) {
     74             // 32 minutes
     75             KeepAlive keepalive = new KeepAlive(240000, 8);
     76             synchronized (keepalive) {
     77                 keepalive.start();
     78                 try {
     79                     keepalive.wait();
     80                 } catch (InterruptedException e) {
     81                     // ignore
     82                 }
     83             }
     84             return keepalive;
     85         }
     86         return null;
     87     }
     88 
     89     public void test_constructor() throws Exception {
     90         KeyFactorySpi kfs = new KeyFactorySpiStub();
     91 
     92         new KeyFactoryStub(null, null, null);
     93 
     94         Provider[] providers = Security.getProviders("KeyFactory.DSA");
     95         if (providers != null) {
     96             for (int i = 0; i < providers.length; i++) {
     97                 KeyFactoryStub kf = new KeyFactoryStub(kfs, providers[i],
     98                         "algorithm name");
     99                 assertEquals("algorithm name", kf.getAlgorithm());
    100                 assertEquals(providers[i], kf.getProvider());
    101             }
    102         } else {
    103             fail("No providers support KeyFactory.DSA");
    104         }
    105     }
    106 
    107     public void test_generatePrivateLjava_security_spec_KeySpec() throws Exception {
    108         // Test for method java.security.PrivateKey
    109         // java.security.KeyFactory.generatePrivate(java.security.spec.KeySpec)
    110         for (int i = 0; i < keyfactAlgs.length; i++) {
    111             KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i], providerName);
    112             KeyPairGenerator keyGen = KeyPairGenerator.getInstance(keyfactAlgs[i]);
    113             SecureRandom random = new SecureRandom(); // We don't use
    114             // getInstance
    115             keyGen.initialize(StandardNames.getMinimumKeySize(keyfactAlgs[i]), random);
    116             KeepAlive keepalive = createKeepAlive(keyfactAlgs[i]);
    117             KeyPair keys = keyGen.generateKeyPair();
    118             if (keepalive != null) {
    119                 keepalive.interrupt();
    120             }
    121 
    122             KeySpec privateKeySpec = fact.getKeySpec(keys.getPrivate(),
    123                     StandardNames.getPrivateKeySpecClass(keyfactAlgs[i]));
    124             PrivateKey privateKey = fact.generatePrivate(privateKeySpec);
    125             assertEquals("generatePrivate generated different key for algorithm " + keyfactAlgs[i],
    126                     Arrays.toString(keys.getPrivate().getEncoded()),
    127                     Arrays.toString(privateKey.getEncoded()));
    128             privateKey = fact.generatePrivate(new PKCS8EncodedKeySpec(keys.getPrivate().getEncoded()));
    129             assertEquals("generatePrivate generated different key for algorithm " + keyfactAlgs[i],
    130                     Arrays.toString(keys.getPrivate().getEncoded()),
    131                     Arrays.toString(privateKey.getEncoded()));
    132         }
    133     }
    134 
    135     public void test_generatePublicLjava_security_spec_KeySpec() throws Exception {
    136         // Test for method java.security.PublicKey
    137         // java.security.KeyFactory.generatePublic(java.security.spec.KeySpec)
    138         for (int i = 0; i < keyfactAlgs.length; i++) {
    139             KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i],
    140                     providerName);
    141             KeyPairGenerator keyGen = KeyPairGenerator
    142                     .getInstance(keyfactAlgs[i]);
    143             // We don't use getInstance
    144             SecureRandom random = new SecureRandom();
    145             keyGen.initialize(StandardNames.getMinimumKeySize(keyfactAlgs[i]), random);
    146             KeepAlive keepalive = createKeepAlive(keyfactAlgs[i]);
    147             KeyPair keys = keyGen.generateKeyPair();
    148             if (keepalive != null) {
    149                 keepalive.interrupt();
    150             }
    151             KeySpec publicKeySpec = fact.getKeySpec(keys.getPublic(),
    152                     StandardNames.getPublicKeySpecClass(keyfactAlgs[i]));
    153             PublicKey publicKey = fact.generatePublic(publicKeySpec);
    154             assertEquals(
    155                     "generatePublic generated different key for algorithm "
    156                             + keyfactAlgs[i] + " (provider="
    157                             + fact.getProvider().getName() + ")",
    158                             Arrays.toString(keys.getPublic().getEncoded()),
    159                             Arrays.toString(publicKey.getEncoded()));
    160         }
    161     }
    162 
    163     public void test_getAlgorithm() throws Exception {
    164         // Test for method java.lang.String
    165         // java.security.KeyFactory.getAlgorithm()
    166         for (int i = 0; i < keyfactAlgs.length; i++) {
    167             KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i],
    168                     providerName);
    169             assertTrue("getAlgorithm ok for algorithm " + keyfactAlgs[i],
    170                     fact.getAlgorithm().equals(keyfactAlgs[i]));
    171         }
    172     }
    173 
    174     public void test_getInstanceLjava_lang_String() throws Exception {
    175         // Test for method java.security.KeyFactory
    176         // java.security.KeyFactory.getInstance(java.lang.String)
    177         for (int i = 0; i < keyfactAlgs.length; i++) {
    178             assertNotNull(KeyFactory.getInstance(keyfactAlgs[i]));
    179         }
    180     }
    181 
    182     public void test_getInstanceLjava_lang_StringLjava_lang_String() throws Exception {
    183         // Test1: Test for method java.security.KeyFactory
    184         // java.security.KeyFactory.getInstance(java.lang.String,
    185         // java.lang.String)
    186         Provider[] providers = Security.getProviders("KeyFactory.DSA");
    187         assertNotNull(providers);
    188 
    189         for (int i = 0; i < providers.length; i++) {
    190             KeyFactory.getInstance("DSA", providers[i].getName());
    191         }
    192 
    193 
    194         // Test2: Test with null provider name
    195         try {
    196             KeyFactory.getInstance("DSA", (String) null);
    197             fail("Expected IllegalArgumentException");
    198         } catch (IllegalArgumentException expected) {
    199         } catch (Exception e) {
    200             fail("Expected IllegalArgumentException, got " + e);
    201         }
    202     }
    203 
    204     public void test_getInstanceLjava_lang_StringLjava_security_Provider() throws Exception {
    205         // Test1: Test for method java.security.KeyFactory
    206         // java.security.KeyFactory.getInstance(java.lang.String,
    207         // java.security.Provider)
    208         Provider[] providers = Security.getProviders("KeyFactory.DSA");
    209         assertNotNull(providers);
    210 
    211         for (int i = 0; i < providers.length; i++) {
    212             KeyFactory.getInstance("DSA", providers[i]);
    213         }
    214 
    215         // Test2: Test with null provider name
    216         try {
    217             KeyFactory.getInstance("DSA", (Provider) null);
    218             fail("Expected IllegalArgumentException");
    219         } catch (IllegalArgumentException expected) {
    220         } catch (Exception e) {
    221             fail("Expected IllegalArgumentException, got " + e);
    222         }
    223     }
    224 
    225     public void test_getKeySpecLjava_security_KeyLjava_lang_Class() throws Exception {
    226         // Test for method java.security.spec.KeySpec
    227         // java.security.KeyFactory.getKeySpec(java.security.Key,
    228         // java.lang.Class)
    229         for (int i = 0; i < keyfactAlgs.length; i++) {
    230             KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i],
    231                     providerName);
    232             KeyPairGenerator keyGen = KeyPairGenerator
    233                     .getInstance(keyfactAlgs[i]);
    234 
    235             // We don't use getInstance
    236             SecureRandom random = new SecureRandom();
    237             keyGen.initialize(StandardNames.getMinimumKeySize(keyfactAlgs[i]), random);
    238             KeepAlive keepalive = createKeepAlive(keyfactAlgs[i]);
    239             KeyPair keys = keyGen.generateKeyPair();
    240             if (keepalive != null) {
    241                 keepalive.interrupt();
    242             }
    243             KeySpec privateKeySpec = fact.getKeySpec(keys.getPrivate(),
    244                     StandardNames.getPrivateKeySpecClass(keyfactAlgs[i]));
    245             KeySpec publicKeySpec = fact.getKeySpec(keys.getPublic(),
    246                     StandardNames.getPublicKeySpecClass(keyfactAlgs[i]));
    247             PrivateKey privateKey = fact.generatePrivate(privateKeySpec);
    248             PublicKey publicKey = fact.generatePublic(publicKeySpec);
    249             assertEquals(
    250                     "generatePrivate generated different key for algorithm "
    251                             + keyfactAlgs[i] + " (provider="
    252                             + fact.getProvider().getName() + ")",
    253                             Arrays.toString(keys.getPrivate().getEncoded()),
    254                             Arrays.toString(privateKey.getEncoded()));
    255             assertEquals(
    256                     "generatePublic generated different key for algorithm "
    257                             + keyfactAlgs[i] + " (provider="
    258                             + fact.getProvider().getName() + ")",
    259                             Arrays.toString(keys.getPublic().getEncoded()),
    260                             Arrays.toString(publicKey.getEncoded()));
    261             KeySpec encodedSpec = fact.getKeySpec(keys.getPublic(),
    262                     X509EncodedKeySpec.class);
    263             assertTrue("improper key spec for encoded public key",
    264                     encodedSpec.getClass().equals(X509EncodedKeySpec.class));
    265             encodedSpec = fact.getKeySpec(keys.getPrivate(),
    266                     PKCS8EncodedKeySpec.class);
    267             assertTrue("improper key spec for encoded private key",
    268                     encodedSpec.getClass()
    269                             .equals(PKCS8EncodedKeySpec.class));
    270         }
    271     }
    272 
    273     public void test_getProvider() throws Exception {
    274         // Test for method java.security.Provider
    275         // java.security.KeyFactory.getProvider()
    276         for (int i = 0; i < keyfactAlgs.length; i++) {
    277             KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i]);
    278             Provider p = fact.getProvider();
    279             assertNotNull("provider is null for algorithm " + keyfactAlgs[i], p);
    280         }
    281     }
    282 
    283     public void test_translateKeyLjava_security_Key() throws Exception {
    284         // Test for method java.security.Key
    285         // java.security.KeyFactory.translateKey(java.security.Key)
    286         for (int i = 0; i < keyfactAlgs.length; i++) {
    287             KeyFactory fact = KeyFactory.getInstance(keyfactAlgs[i],
    288                     providerName);
    289             KeyPairGenerator keyGen = KeyPairGenerator
    290                     .getInstance(keyfactAlgs[i]);
    291 
    292             // We don't use getInstance
    293             SecureRandom random = new SecureRandom();
    294             keyGen.initialize(StandardNames.getMinimumKeySize(keyfactAlgs[i]), random);
    295             KeepAlive keepalive = createKeepAlive(keyfactAlgs[i]);
    296             KeyPair keys = keyGen.generateKeyPair();
    297             if (keepalive != null) {
    298                 keepalive.interrupt();
    299             }
    300             fact.translateKey(keys.getPrivate());
    301         }
    302     }
    303 
    304     protected void setUp() {
    305         if (keyfactAlgs == null) {
    306             Provider[] providers = Security.getProviders();
    307             // Arbitrarily use the first provider that supports
    308             // KeyFactory algorithms
    309             for (Provider provider : providers) {
    310                 providerName = provider.getName();
    311                 keyfactAlgs = getKeyFactoryAlgorithms(providerName);
    312                 if (keyfactAlgs.length != 0) {
    313                     break;
    314                 }
    315             }
    316         }
    317     }
    318 
    319     /*
    320      * Returns the key algorithms that the given provider supports.
    321      */
    322     private String[] getKeyFactoryAlgorithms(String providerName) {
    323         Vector<String> algs = new Vector<String>();
    324 
    325         Provider provider = Security.getProvider(providerName);
    326         if (provider == null)
    327             return new String[0];
    328         Enumeration<Object> e = provider.keys();
    329         while (e.hasMoreElements()) {
    330             String algorithm = (String) e.nextElement();
    331             if (algorithm.startsWith(KEYFACTORY_ID) && !algorithm.contains(" ")) {
    332                 algs.addElement(algorithm.substring(KEYFACTORY_ID.length()));
    333             }
    334         }
    335 
    336         return algs.toArray(new String[algs.size()]);
    337     }
    338 
    339     public class KeyFactoryStub extends KeyFactory {
    340         public KeyFactoryStub(KeyFactorySpi keyFacSpi, Provider provider,
    341                 String algorithm) {
    342             super(keyFacSpi, provider, algorithm);
    343         }
    344     }
    345 
    346     public class KeyFactorySpiStub extends KeyFactorySpi {
    347         public KeyFactorySpiStub() {
    348             super();
    349         }
    350 
    351         public PrivateKey engineGeneratePrivate(KeySpec keySpec) {
    352             return null;
    353         }
    354 
    355         public PublicKey engineGeneratePublic(KeySpec keySpec) {
    356             return null;
    357         }
    358 
    359         public <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec) {
    360             return null;
    361         }
    362 
    363         public Key engineTranslateKey(Key key) {
    364             return null;
    365         }
    366     }
    367 }
    368