|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.security.provider; |
|
|
|
import java.security.Key; |
|
import java.security.PublicKey; |
|
import java.security.PrivateKey; |
|
import java.security.KeyFactorySpi; |
|
import java.security.InvalidKeyException; |
|
import java.security.interfaces.DSAParams; |
|
import java.security.spec.DSAPublicKeySpec; |
|
import java.security.spec.DSAPrivateKeySpec; |
|
import java.security.spec.KeySpec; |
|
import java.security.spec.InvalidKeySpecException; |
|
import java.security.spec.X509EncodedKeySpec; |
|
import java.security.spec.PKCS8EncodedKeySpec; |
|
import java.util.Arrays; |
|
|
|
/** |
|
* This class implements the DSA key factory of the Sun provider. |
|
* |
|
* @author Jan Luehe |
|
* |
|
* |
|
* @since 1.2 |
|
*/ |
|
|
|
public class DSAKeyFactory extends KeyFactorySpi { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected PublicKey engineGeneratePublic(KeySpec keySpec) |
|
throws InvalidKeySpecException { |
|
try { |
|
if (keySpec instanceof DSAPublicKeySpec) { |
|
DSAPublicKeySpec dsaPubKeySpec = (DSAPublicKeySpec)keySpec; |
|
return new DSAPublicKeyImpl(dsaPubKeySpec.getY(), |
|
dsaPubKeySpec.getP(), |
|
dsaPubKeySpec.getQ(), |
|
dsaPubKeySpec.getG()); |
|
} else if (keySpec instanceof X509EncodedKeySpec) { |
|
return new DSAPublicKeyImpl |
|
(((X509EncodedKeySpec)keySpec).getEncoded()); |
|
} else { |
|
throw new InvalidKeySpecException |
|
("Inappropriate key specification"); |
|
} |
|
} catch (InvalidKeyException e) { |
|
throw new InvalidKeySpecException |
|
("Inappropriate key specification: " + e.getMessage()); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected PrivateKey engineGeneratePrivate(KeySpec keySpec) |
|
throws InvalidKeySpecException { |
|
try { |
|
if (keySpec instanceof DSAPrivateKeySpec) { |
|
DSAPrivateKeySpec dsaPrivKeySpec = (DSAPrivateKeySpec)keySpec; |
|
return new DSAPrivateKey(dsaPrivKeySpec.getX(), |
|
dsaPrivKeySpec.getP(), |
|
dsaPrivKeySpec.getQ(), |
|
dsaPrivKeySpec.getG()); |
|
|
|
} else if (keySpec instanceof PKCS8EncodedKeySpec) { |
|
byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded(); |
|
try { |
|
return new DSAPrivateKey(encoded); |
|
} finally { |
|
Arrays.fill(encoded, (byte) 0); |
|
} |
|
} else { |
|
throw new InvalidKeySpecException |
|
("Inappropriate key specification"); |
|
} |
|
} catch (InvalidKeyException e) { |
|
throw new InvalidKeySpecException |
|
("Inappropriate key specification: " + e.getMessage()); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected <T extends KeySpec> |
|
T engineGetKeySpec(Key key, Class<T> keySpec) |
|
throws InvalidKeySpecException { |
|
|
|
DSAParams params; |
|
|
|
try { |
|
|
|
if (key instanceof java.security.interfaces.DSAPublicKey) { |
|
|
|
|
|
Class<?> dsaPubKeySpec = Class.forName |
|
("java.security.spec.DSAPublicKeySpec"); |
|
Class<?> x509KeySpec = Class.forName |
|
("java.security.spec.X509EncodedKeySpec"); |
|
|
|
if (keySpec.isAssignableFrom(dsaPubKeySpec)) { |
|
java.security.interfaces.DSAPublicKey dsaPubKey |
|
= (java.security.interfaces.DSAPublicKey)key; |
|
params = dsaPubKey.getParams(); |
|
return keySpec.cast(new DSAPublicKeySpec(dsaPubKey.getY(), |
|
params.getP(), |
|
params.getQ(), |
|
params.getG())); |
|
|
|
} else if (keySpec.isAssignableFrom(x509KeySpec)) { |
|
return keySpec.cast(new X509EncodedKeySpec(key.getEncoded())); |
|
|
|
} else { |
|
throw new InvalidKeySpecException |
|
("Inappropriate key specification"); |
|
} |
|
|
|
} else if (key instanceof java.security.interfaces.DSAPrivateKey) { |
|
|
|
|
|
Class<?> dsaPrivKeySpec = Class.forName |
|
("java.security.spec.DSAPrivateKeySpec"); |
|
Class<?> pkcs8KeySpec = Class.forName |
|
("java.security.spec.PKCS8EncodedKeySpec"); |
|
|
|
if (keySpec.isAssignableFrom(dsaPrivKeySpec)) { |
|
java.security.interfaces.DSAPrivateKey dsaPrivKey |
|
= (java.security.interfaces.DSAPrivateKey)key; |
|
params = dsaPrivKey.getParams(); |
|
return keySpec.cast(new DSAPrivateKeySpec(dsaPrivKey.getX(), |
|
params.getP(), |
|
params.getQ(), |
|
params.getG())); |
|
|
|
} else if (keySpec.isAssignableFrom(pkcs8KeySpec)) { |
|
byte[] encoded = key.getEncoded(); |
|
try { |
|
return keySpec.cast(new PKCS8EncodedKeySpec(encoded)); |
|
} finally { |
|
Arrays.fill(encoded, (byte)0); |
|
} |
|
} else { |
|
throw new InvalidKeySpecException |
|
("Inappropriate key specification"); |
|
} |
|
|
|
} else { |
|
throw new InvalidKeySpecException("Inappropriate key type"); |
|
} |
|
|
|
} catch (ClassNotFoundException e) { |
|
throw new InvalidKeySpecException |
|
("Unsupported key specification: " + e.getMessage()); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
protected Key engineTranslateKey(Key key) throws InvalidKeyException { |
|
|
|
try { |
|
|
|
if (key instanceof java.security.interfaces.DSAPublicKey) { |
|
|
|
if (key instanceof sun.security.provider.DSAPublicKey) { |
|
return key; |
|
} |
|
|
|
DSAPublicKeySpec dsaPubKeySpec |
|
= engineGetKeySpec(key, DSAPublicKeySpec.class); |
|
|
|
return engineGeneratePublic(dsaPubKeySpec); |
|
|
|
} else if (key instanceof java.security.interfaces.DSAPrivateKey) { |
|
|
|
if (key instanceof sun.security.provider.DSAPrivateKey) { |
|
return key; |
|
} |
|
|
|
DSAPrivateKeySpec dsaPrivKeySpec |
|
= engineGetKeySpec(key, DSAPrivateKeySpec.class); |
|
|
|
return engineGeneratePrivate(dsaPrivKeySpec); |
|
|
|
} else { |
|
throw new InvalidKeyException("Wrong algorithm type"); |
|
} |
|
|
|
} catch (InvalidKeySpecException e) { |
|
throw new InvalidKeyException("Cannot translate key: " |
|
+ e.getMessage()); |
|
} |
|
} |
|
} |