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 17package org.apache.harmony.xnet.provider.jsse; 18 19import java.math.BigInteger; 20import java.security.InvalidKeyException; 21import java.security.Key; 22import java.security.KeyFactorySpi; 23import java.security.PrivateKey; 24import java.security.PublicKey; 25import java.security.interfaces.RSAPrivateCrtKey; 26import java.security.interfaces.RSAPrivateKey; 27import java.security.interfaces.RSAPublicKey; 28import java.security.spec.InvalidKeySpecException; 29import java.security.spec.KeySpec; 30import java.security.spec.PKCS8EncodedKeySpec; 31import java.security.spec.RSAPrivateCrtKeySpec; 32import java.security.spec.RSAPrivateKeySpec; 33import java.security.spec.RSAPublicKeySpec; 34import java.security.spec.X509EncodedKeySpec; 35 36public class OpenSSLRSAKeyFactory<T, S> extends KeyFactorySpi { 37 38 @Override 39 protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { 40 if (keySpec instanceof RSAPublicKeySpec) { 41 RSAPublicKeySpec rsaKeySpec = (RSAPublicKeySpec) keySpec; 42 43 return new OpenSSLRSAPublicKey(rsaKeySpec); 44 } else if (keySpec instanceof X509EncodedKeySpec) { 45 X509EncodedKeySpec x509KeySpec = (X509EncodedKeySpec) keySpec; 46 47 try { 48 final OpenSSLKey key = new OpenSSLKey( 49 NativeCrypto.d2i_PUBKEY(x509KeySpec.getEncoded())); 50 return new OpenSSLRSAPublicKey(key); 51 } catch (Exception e) { 52 throw new InvalidKeySpecException(e); 53 } 54 } 55 throw new InvalidKeySpecException("Must use RSAPublicKeySpec or X509EncodedKeySpec; was " 56 + keySpec.getClass().getName()); 57 } 58 59 @Override 60 protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { 61 if (keySpec instanceof RSAPrivateCrtKeySpec) { 62 RSAPrivateCrtKeySpec rsaKeySpec = (RSAPrivateCrtKeySpec) keySpec; 63 64 return new OpenSSLRSAPrivateCrtKey(rsaKeySpec); 65 } else if (keySpec instanceof RSAPrivateKeySpec) { 66 RSAPrivateKeySpec rsaKeySpec = (RSAPrivateKeySpec) keySpec; 67 68 return new OpenSSLRSAPrivateKey(rsaKeySpec); 69 } else if (keySpec instanceof PKCS8EncodedKeySpec) { 70 PKCS8EncodedKeySpec pkcs8KeySpec = (PKCS8EncodedKeySpec) keySpec; 71 72 try { 73 final OpenSSLKey key = new OpenSSLKey( 74 NativeCrypto.d2i_PKCS8_PRIV_KEY_INFO(pkcs8KeySpec.getEncoded())); 75 return OpenSSLRSAPrivateKey.getInstance(key); 76 } catch (Exception e) { 77 throw new InvalidKeySpecException(e); 78 } 79 } 80 throw new InvalidKeySpecException("Must use RSAPublicKeySpec or PKCS8EncodedKeySpec; was " 81 + keySpec.getClass().getName()); 82 } 83 84 @Override 85 protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec) 86 throws InvalidKeySpecException { 87 if (key == null) { 88 throw new InvalidKeySpecException("key == null"); 89 } 90 91 if (keySpec == null) { 92 throw new InvalidKeySpecException("keySpec == null"); 93 } 94 95 if (key instanceof RSAPublicKey) { 96 RSAPublicKey rsaKey = (RSAPublicKey) key; 97 98 if (RSAPublicKeySpec.class.equals(keySpec)) { 99 BigInteger modulus = rsaKey.getModulus(); 100 BigInteger publicExponent = rsaKey.getPublicExponent(); 101 return (T) new RSAPublicKeySpec(modulus, publicExponent); 102 } else if (X509EncodedKeySpec.class.equals(keySpec)) { 103 return (T) new X509EncodedKeySpec(key.getEncoded()); 104 } else { 105 throw new InvalidKeySpecException("Must be RSAPublicKeySpec or X509EncodedKeySpec"); 106 } 107 } else if (key instanceof RSAPrivateCrtKey) { 108 RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key; 109 110 if (RSAPrivateKeySpec.class.equals(keySpec)) { 111 BigInteger modulus = rsaKey.getModulus(); 112 BigInteger privateExponent = rsaKey.getPrivateExponent(); 113 return (T) new RSAPrivateKeySpec(modulus, privateExponent); 114 } else if (RSAPrivateCrtKeySpec.class.equals(keySpec)) { 115 BigInteger modulus = rsaKey.getModulus(); 116 BigInteger publicExponent = rsaKey.getPublicExponent(); 117 BigInteger privateExponent = rsaKey.getPrivateExponent(); 118 BigInteger primeP = rsaKey.getPrimeP(); 119 BigInteger primeQ = rsaKey.getPrimeQ(); 120 BigInteger primeExponentP = rsaKey.getPrimeExponentP(); 121 BigInteger primeExponentQ = rsaKey.getPrimeExponentQ(); 122 BigInteger crtCoefficient = rsaKey.getCrtCoefficient(); 123 return (T) new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, 124 primeP, primeQ, primeExponentP, primeExponentQ, crtCoefficient); 125 } else if (PKCS8EncodedKeySpec.class.equals(keySpec)) { 126 return (T) new PKCS8EncodedKeySpec(rsaKey.getEncoded()); 127 } else { 128 throw new InvalidKeySpecException( 129 "Must be RSAPrivateKeySpec or or RSAPrivateCrtKeySpec or PKCS8EncodedKeySpec"); 130 } 131 } else if (key instanceof RSAPrivateKey) { 132 RSAPrivateKey rsaKey = (RSAPrivateKey) key; 133 134 if (RSAPrivateKeySpec.class.equals(keySpec)) { 135 BigInteger modulus = rsaKey.getModulus(); 136 BigInteger privateExponent = rsaKey.getPrivateExponent(); 137 return (T) new RSAPrivateKeySpec(modulus, privateExponent); 138 } else if (RSAPrivateCrtKeySpec.class.equals(keySpec)) { 139 BigInteger modulus = rsaKey.getModulus(); 140 BigInteger privateExponent = rsaKey.getPrivateExponent(); 141 return (T) new RSAPrivateCrtKeySpec(modulus, null, privateExponent, null, null, 142 null, null, null); 143 } else if (PKCS8EncodedKeySpec.class.equals(keySpec)) { 144 return (T) new PKCS8EncodedKeySpec(rsaKey.getEncoded()); 145 } else { 146 throw new InvalidKeySpecException( 147 "Must be RSAPrivateKeySpec or PKCS8EncodedKeySpec"); 148 } 149 } else { 150 throw new InvalidKeySpecException("Must be RSAPublicKey or RSAPrivateKey"); 151 } 152 } 153 154 @Override 155 protected Key engineTranslateKey(Key key) throws InvalidKeyException { 156 if (key == null) { 157 throw new InvalidKeyException("key == null"); 158 } 159 160 if (key instanceof RSAPublicKey) { 161 RSAPublicKey rsaKey = (RSAPublicKey) key; 162 163 try { 164 return engineGeneratePublic(new RSAPublicKeySpec(rsaKey.getModulus(), 165 rsaKey.getPublicExponent())); 166 } catch (InvalidKeySpecException e) { 167 throw new InvalidKeyException(e); 168 } 169 } else if (key instanceof RSAPrivateCrtKey) { 170 RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key; 171 BigInteger modulus = rsaKey.getModulus(); 172 BigInteger publicExponent = rsaKey.getPublicExponent(); 173 BigInteger privateExponent = rsaKey.getPrivateExponent(); 174 BigInteger primeP = rsaKey.getPrimeP(); 175 BigInteger primeQ = rsaKey.getPrimeQ(); 176 BigInteger primeExponentP = rsaKey.getPrimeExponentP(); 177 BigInteger primeExponentQ = rsaKey.getPrimeExponentQ(); 178 BigInteger crtCoefficient = rsaKey.getCrtCoefficient(); 179 180 try { 181 return engineGeneratePrivate(new RSAPrivateCrtKeySpec(modulus, publicExponent, 182 privateExponent, primeP, primeQ, primeExponentP, primeExponentQ, 183 crtCoefficient)); 184 } catch (InvalidKeySpecException e) { 185 throw new InvalidKeyException(e); 186 } 187 } else if (key instanceof RSAPrivateKey) { 188 RSAPrivateKey rsaKey = (RSAPrivateKey) key; 189 BigInteger modulus = rsaKey.getModulus(); 190 BigInteger privateExponent = rsaKey.getPrivateExponent(); 191 192 try { 193 return engineGeneratePrivate(new RSAPrivateKeySpec(modulus, privateExponent)); 194 } catch (InvalidKeySpecException e) { 195 throw new InvalidKeyException(e); 196 } 197 } else { 198 throw new InvalidKeyException( 199 "Key must be RSAPublicKey or RSAPrivateCrtKey or RSAPrivateKey"); 200 } 201 } 202} 203