OpenSSLDSAKeyFactory.java revision ed7441ebfbc69821598a5bc060518b5c82ffb5c8
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.DSAParams; 26import java.security.interfaces.DSAPrivateKey; 27import java.security.interfaces.DSAPublicKey; 28import java.security.spec.DSAPrivateKeySpec; 29import java.security.spec.DSAPublicKeySpec; 30import java.security.spec.InvalidKeySpecException; 31import java.security.spec.KeySpec; 32import java.security.spec.PKCS8EncodedKeySpec; 33import java.security.spec.X509EncodedKeySpec; 34 35public class OpenSSLDSAKeyFactory extends KeyFactorySpi { 36 37 @Override 38 protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { 39 if (keySpec == null) { 40 throw new InvalidKeySpecException("keySpec == null"); 41 } 42 43 if (keySpec instanceof DSAPublicKeySpec) { 44 return new OpenSSLDSAPublicKey((DSAPublicKeySpec) keySpec); 45 } else if (keySpec instanceof X509EncodedKeySpec) { 46 return OpenSSLKey.getPublicKey((X509EncodedKeySpec) keySpec, NativeCrypto.EVP_PKEY_DSA); 47 } 48 throw new InvalidKeySpecException("Must use DSAPublicKeySpec or X509EncodedKeySpec; was " 49 + keySpec.getClass().getName()); 50 } 51 52 @Override 53 protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { 54 if (keySpec == null) { 55 throw new InvalidKeySpecException("keySpec == null"); 56 } 57 58 if (keySpec instanceof DSAPrivateKeySpec) { 59 return new OpenSSLDSAPrivateKey((DSAPrivateKeySpec) keySpec); 60 } else if (keySpec instanceof PKCS8EncodedKeySpec) { 61 return OpenSSLKey.getPrivateKey((PKCS8EncodedKeySpec) keySpec, 62 NativeCrypto.EVP_PKEY_DSA); 63 } 64 throw new InvalidKeySpecException("Must use DSAPrivateKeySpec or PKCS8EncodedKeySpec; was " 65 + keySpec.getClass().getName()); 66 } 67 68 @Override 69 protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec) 70 throws InvalidKeySpecException { 71 if (key == null) { 72 throw new InvalidKeySpecException("key == null"); 73 } 74 75 if (keySpec == null) { 76 throw new InvalidKeySpecException("keySpec == null"); 77 } 78 79 if (!"DSA".equals(key.getAlgorithm())) { 80 throw new InvalidKeySpecException("Key must be a DSA key"); 81 } 82 83 if (key instanceof DSAPublicKey && DSAPublicKeySpec.class.isAssignableFrom(keySpec)) { 84 DSAPublicKey dsaKey = (DSAPublicKey) key; 85 DSAParams params = dsaKey.getParams(); 86 return (T) new DSAPublicKeySpec(dsaKey.getY(), params.getP(), params.getQ(), 87 params.getG()); 88 } else if (key instanceof PublicKey && DSAPublicKeySpec.class.isAssignableFrom(keySpec)) { 89 final byte[] encoded = key.getEncoded(); 90 if (!"X.509".equals(key.getFormat()) || encoded == null) { 91 throw new InvalidKeySpecException("Not a valid X.509 encoding"); 92 } 93 DSAPublicKey dsaKey = 94 (DSAPublicKey) engineGeneratePublic(new X509EncodedKeySpec(encoded)); 95 DSAParams params = dsaKey.getParams(); 96 return (T) new DSAPublicKeySpec(dsaKey.getY(), params.getP(), params.getQ(), 97 params.getG()); 98 } else if (key instanceof DSAPrivateKey 99 && DSAPrivateKeySpec.class.isAssignableFrom(keySpec)) { 100 DSAPrivateKey dsaKey = (DSAPrivateKey) key; 101 DSAParams params = dsaKey.getParams(); 102 return (T) new DSAPrivateKeySpec(dsaKey.getX(), params.getP(), params.getQ(), 103 params.getG()); 104 } else if (key instanceof PrivateKey && DSAPrivateKeySpec.class.isAssignableFrom(keySpec)) { 105 final byte[] encoded = key.getEncoded(); 106 if (!"PKCS#8".equals(key.getFormat()) || encoded == null) { 107 throw new InvalidKeySpecException("Not a valid PKCS#8 encoding"); 108 } 109 DSAPrivateKey dsaKey = 110 (DSAPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded)); 111 DSAParams params = dsaKey.getParams(); 112 return (T) new DSAPrivateKeySpec(dsaKey.getX(), params.getP(), params.getQ(), 113 params.getG()); 114 } else if (key instanceof PrivateKey 115 && PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) { 116 final byte[] encoded = key.getEncoded(); 117 if (!"PKCS#8".equals(key.getFormat())) { 118 throw new InvalidKeySpecException("Encoding type must be PKCS#8; was " 119 + key.getFormat()); 120 } else if (encoded == null) { 121 throw new InvalidKeySpecException("Key is not encodable"); 122 } 123 return (T) new PKCS8EncodedKeySpec(encoded); 124 } else if (key instanceof PublicKey && X509EncodedKeySpec.class.isAssignableFrom(keySpec)) { 125 final byte[] encoded = key.getEncoded(); 126 if (!"X.509".equals(key.getFormat())) { 127 throw new InvalidKeySpecException("Encoding type must be X.509; was " 128 + key.getFormat()); 129 } else if (encoded == null) { 130 throw new InvalidKeySpecException("Key is not encodable"); 131 } 132 return (T) new X509EncodedKeySpec(encoded); 133 } else { 134 throw new InvalidKeySpecException("Unsupported key type and key spec combination; key=" 135 + key.getClass().getName() + ", keySpec=" + keySpec.getName()); 136 } 137 } 138 139 @Override 140 protected Key engineTranslateKey(Key key) throws InvalidKeyException { 141 if (key == null) { 142 throw new InvalidKeyException("key == null"); 143 } 144 145 if (key instanceof DSAPublicKey) { 146 DSAPublicKey dsaKey = (DSAPublicKey) key; 147 148 BigInteger y = dsaKey.getY(); 149 150 DSAParams params = dsaKey.getParams(); 151 BigInteger p = params.getP(); 152 BigInteger q = params.getQ(); 153 BigInteger g = params.getG(); 154 155 try { 156 return engineGeneratePublic(new DSAPublicKeySpec(y, p, q, g)); 157 } catch (InvalidKeySpecException e) { 158 throw new InvalidKeyException(e); 159 } 160 } else if (key instanceof DSAPrivateKey) { 161 DSAPrivateKey dsaKey = (DSAPrivateKey) key; 162 163 BigInteger x = dsaKey.getX(); 164 165 DSAParams params = dsaKey.getParams(); 166 BigInteger p = params.getP(); 167 BigInteger q = params.getQ(); 168 BigInteger g = params.getG(); 169 170 try { 171 return engineGeneratePrivate(new DSAPrivateKeySpec(x, p, q, g)); 172 } catch (InvalidKeySpecException e) { 173 throw new InvalidKeyException(e); 174 } 175 } else if ("PKCS#8".equals(key.getFormat())) { 176 byte[] encoded = key.getEncoded(); 177 if (encoded == null) { 178 throw new InvalidKeyException("Key does not support encoding"); 179 } 180 try { 181 return engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded)); 182 } catch (InvalidKeySpecException e) { 183 throw new InvalidKeyException(e); 184 } 185 } else if ("X.509".equals(key.getFormat())) { 186 byte[] encoded = key.getEncoded(); 187 if (encoded == null) { 188 throw new InvalidKeyException("Key does not support encoding"); 189 } 190 try { 191 return engineGeneratePublic(new X509EncodedKeySpec(encoded)); 192 } catch (InvalidKeySpecException e) { 193 throw new InvalidKeyException(e); 194 } 195 } else { 196 throw new InvalidKeyException("Key must be DSA public or private key; was " 197 + key.getClass().getName()); 198 } 199 } 200} 201