Home | History | Annotate | Download | only in jsse
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package org.apache.harmony.xnet.provider.jsse;
     18 
     19 import java.math.BigInteger;
     20 import java.security.InvalidKeyException;
     21 import java.security.Key;
     22 import java.security.KeyFactorySpi;
     23 import java.security.PrivateKey;
     24 import java.security.PublicKey;
     25 import java.security.interfaces.RSAPrivateCrtKey;
     26 import java.security.interfaces.RSAPrivateKey;
     27 import java.security.interfaces.RSAPublicKey;
     28 import java.security.spec.InvalidKeySpecException;
     29 import java.security.spec.KeySpec;
     30 import java.security.spec.PKCS8EncodedKeySpec;
     31 import java.security.spec.RSAPrivateCrtKeySpec;
     32 import java.security.spec.RSAPrivateKeySpec;
     33 import java.security.spec.RSAPublicKeySpec;
     34 import java.security.spec.X509EncodedKeySpec;
     35 
     36 public class OpenSSLRSAKeyFactory extends KeyFactorySpi {
     37 
     38     @Override
     39     protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException {
     40         if (keySpec == null) {
     41             throw new InvalidKeySpecException("keySpec == null");
     42         }
     43 
     44         if (keySpec instanceof RSAPublicKeySpec) {
     45             return new OpenSSLRSAPublicKey((RSAPublicKeySpec) keySpec);
     46         } else if (keySpec instanceof X509EncodedKeySpec) {
     47             return OpenSSLKey.getPublicKey((X509EncodedKeySpec) keySpec, NativeCrypto.EVP_PKEY_RSA);
     48         }
     49         throw new InvalidKeySpecException("Must use RSAPublicKeySpec or X509EncodedKeySpec; was "
     50                 + keySpec.getClass().getName());
     51     }
     52 
     53     @Override
     54     protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException {
     55         if (keySpec == null) {
     56             throw new InvalidKeySpecException("keySpec == null");
     57         }
     58 
     59         if (keySpec instanceof RSAPrivateCrtKeySpec) {
     60             return new OpenSSLRSAPrivateCrtKey((RSAPrivateCrtKeySpec) keySpec);
     61         } else if (keySpec instanceof RSAPrivateKeySpec) {
     62             return new OpenSSLRSAPrivateKey((RSAPrivateKeySpec) keySpec);
     63         } else if (keySpec instanceof PKCS8EncodedKeySpec) {
     64             return OpenSSLKey.getPrivateKey((PKCS8EncodedKeySpec) keySpec,
     65                     NativeCrypto.EVP_PKEY_RSA);
     66         }
     67         throw new InvalidKeySpecException("Must use RSAPublicKeySpec or PKCS8EncodedKeySpec; was "
     68                 + keySpec.getClass().getName());
     69     }
     70 
     71     @Override
     72     protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
     73             throws InvalidKeySpecException {
     74         if (key == null) {
     75             throw new InvalidKeySpecException("key == null");
     76         }
     77 
     78         if (keySpec == null) {
     79             throw new InvalidKeySpecException("keySpec == null");
     80         }
     81 
     82         if (!"RSA".equals(key.getAlgorithm())) {
     83             throw new InvalidKeySpecException("Key must be a RSA key");
     84         }
     85 
     86         if (key instanceof RSAPublicKey && RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
     87             RSAPublicKey rsaKey = (RSAPublicKey) key;
     88             return (T) new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent());
     89         } else if (key instanceof PublicKey && RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
     90             final byte[] encoded = key.getEncoded();
     91             if (!"X.509".equals(key.getFormat()) || encoded == null) {
     92                 throw new InvalidKeySpecException("Not a valid X.509 encoding");
     93             }
     94             RSAPublicKey rsaKey =
     95                     (RSAPublicKey) engineGeneratePublic(new X509EncodedKeySpec(encoded));
     96             return (T) new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent());
     97         } else if (key instanceof RSAPrivateCrtKey
     98                 && RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
     99             RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
    100             return (T) new RSAPrivateCrtKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent(),
    101                     rsaKey.getPrivateExponent(), rsaKey.getPrimeP(), rsaKey.getPrimeQ(),
    102                     rsaKey.getPrimeExponentP(), rsaKey.getPrimeExponentQ(),
    103                     rsaKey.getCrtCoefficient());
    104         } else if (key instanceof RSAPrivateCrtKey
    105                 && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
    106             RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
    107             return (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
    108         } else if (key instanceof RSAPrivateKey
    109                 && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
    110             RSAPrivateKey rsaKey = (RSAPrivateKey) key;
    111             return (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
    112         } else if (key instanceof PrivateKey
    113                 && RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
    114             final byte[] encoded = key.getEncoded();
    115             if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
    116                 throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
    117             }
    118             RSAPrivateKey privKey =
    119                     (RSAPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
    120             if (privKey instanceof RSAPrivateCrtKey) {
    121                 RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) privKey;
    122                 return (T) new RSAPrivateCrtKeySpec(rsaKey.getModulus(),
    123                         rsaKey.getPublicExponent(), rsaKey.getPrivateExponent(),
    124                         rsaKey.getPrimeP(), rsaKey.getPrimeQ(), rsaKey.getPrimeExponentP(),
    125                         rsaKey.getPrimeExponentQ(), rsaKey.getCrtCoefficient());
    126             } else {
    127                 throw new InvalidKeySpecException("Encoded key is not an RSAPrivateCrtKey");
    128             }
    129         } else if (key instanceof PrivateKey && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
    130             final byte[] encoded = key.getEncoded();
    131             if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
    132                 throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
    133             }
    134             RSAPrivateKey rsaKey =
    135                     (RSAPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
    136             return (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
    137         } else if (key instanceof PrivateKey
    138                 && PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) {
    139             final byte[] encoded = key.getEncoded();
    140             if (!"PKCS#8".equals(key.getFormat())) {
    141                 throw new InvalidKeySpecException("Encoding type must be PKCS#8; was "
    142                         + key.getFormat());
    143             } else if (encoded == null) {
    144                 throw new InvalidKeySpecException("Key is not encodable");
    145             }
    146             return (T) new PKCS8EncodedKeySpec(encoded);
    147         } else if (key instanceof PublicKey && X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
    148             final byte[] encoded = key.getEncoded();
    149             if (!"X.509".equals(key.getFormat())) {
    150                 throw new InvalidKeySpecException("Encoding type must be X.509; was "
    151                         + key.getFormat());
    152             } else if (encoded == null) {
    153                 throw new InvalidKeySpecException("Key is not encodable");
    154             }
    155             return (T) new X509EncodedKeySpec(encoded);
    156         } else {
    157             throw new InvalidKeySpecException("Unsupported key type and key spec combination; key="
    158                     + key.getClass().getName() + ", keySpec=" + keySpec.getName());
    159         }
    160     }
    161 
    162     @Override
    163     protected Key engineTranslateKey(Key key) throws InvalidKeyException {
    164         if (key == null) {
    165             throw new InvalidKeyException("key == null");
    166         }
    167 
    168         if ((key instanceof OpenSSLRSAPublicKey) || (key instanceof OpenSSLRSAPrivateKey)) {
    169             return key;
    170         } else if (key instanceof RSAPublicKey) {
    171             RSAPublicKey rsaKey = (RSAPublicKey) key;
    172 
    173             try {
    174                 return engineGeneratePublic(new RSAPublicKeySpec(rsaKey.getModulus(),
    175                         rsaKey.getPublicExponent()));
    176             } catch (InvalidKeySpecException e) {
    177                 throw new InvalidKeyException(e);
    178             }
    179         } else if (key instanceof RSAPrivateCrtKey) {
    180             RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
    181             BigInteger modulus = rsaKey.getModulus();
    182             BigInteger publicExponent = rsaKey.getPublicExponent();
    183             BigInteger privateExponent = rsaKey.getPrivateExponent();
    184             BigInteger primeP = rsaKey.getPrimeP();
    185             BigInteger primeQ = rsaKey.getPrimeQ();
    186             BigInteger primeExponentP = rsaKey.getPrimeExponentP();
    187             BigInteger primeExponentQ = rsaKey.getPrimeExponentQ();
    188             BigInteger crtCoefficient = rsaKey.getCrtCoefficient();
    189 
    190             try {
    191                 return engineGeneratePrivate(new RSAPrivateCrtKeySpec(modulus, publicExponent,
    192                         privateExponent, primeP, primeQ, primeExponentP, primeExponentQ,
    193                         crtCoefficient));
    194             } catch (InvalidKeySpecException e) {
    195                 throw new InvalidKeyException(e);
    196             }
    197         } else if (key instanceof RSAPrivateKey) {
    198             RSAPrivateKey rsaKey = (RSAPrivateKey) key;
    199             BigInteger modulus = rsaKey.getModulus();
    200             BigInteger privateExponent = rsaKey.getPrivateExponent();
    201 
    202             try {
    203                 return engineGeneratePrivate(new RSAPrivateKeySpec(modulus, privateExponent));
    204             } catch (InvalidKeySpecException e) {
    205                 throw new InvalidKeyException(e);
    206             }
    207         } else if ((key instanceof PrivateKey) && ("PKCS#8".equals(key.getFormat()))) {
    208             byte[] encoded = key.getEncoded();
    209             if (encoded == null) {
    210                 throw new InvalidKeyException("Key does not support encoding");
    211             }
    212             try {
    213                 return engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
    214             } catch (InvalidKeySpecException e) {
    215                 throw new InvalidKeyException(e);
    216             }
    217         } else if ((key instanceof PublicKey) && ("X.509".equals(key.getFormat()))) {
    218             byte[] encoded = key.getEncoded();
    219             if (encoded == null) {
    220                 throw new InvalidKeyException("Key does not support encoding");
    221             }
    222             try {
    223                 return engineGeneratePublic(new X509EncodedKeySpec(encoded));
    224             } catch (InvalidKeySpecException e) {
    225                 throw new InvalidKeyException(e);
    226             }
    227         } else {
    228             throw new InvalidKeyException("Key must be an RSA public or private key; was "
    229                     + key.getClass().getName());
    230         }
    231     }
    232 }
    233