EncodedKeyFactory.java [plain text]
package gnu.java.security.provider;
import gnu.java.security.OID;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import java.io.IOException;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactorySpi;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.DSAParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.spec.DHParameterSpec;
public class EncodedKeyFactory extends KeyFactorySpi
{
private static final OID ID_DSA = new OID("1.2.840.10040.4.1");
private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1");
private static final OID ID_DH = new OID("1.2.840.10046.2.1");
public PublicKey engineGeneratePublic(KeySpec spec)
throws InvalidKeySpecException
{
if (!(spec instanceof X509EncodedKeySpec))
throw new InvalidKeySpecException("only supports X.509 key specs");
DERReader der = new DERReader(((X509EncodedKeySpec) spec).getEncoded());
try
{
DERValue spki = der.read();
if (!spki.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue alg = der.read();
if (!alg.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue val = der.read();
if (!(val.getValue() instanceof OID))
{
throw new InvalidKeySpecException("malformed encoded key");
}
OID algId = (OID) val.getValue();
byte[] algParams = null;
if (alg.getLength() > val.getEncodedLength())
{
val = der.read();
algParams = val.getEncoded();
if (val.isConstructed())
der.skip(val.getLength());
}
val = der.read();
if (!(val.getValue() instanceof BitString))
{
throw new InvalidKeySpecException("malformed encoded key");
}
byte[] publicKey = ((BitString) val.getValue()).toByteArray();
if (algId.equals(ID_DSA))
{
BigInteger p = null, g = null, q = null, Y;
if (algParams != null)
{
DERReader dsaParams = new DERReader(algParams);
val = dsaParams.read();
if (!val.isConstructed())
throw new InvalidKeySpecException("malformed DSA parameters");
val = dsaParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
p = (BigInteger) val.getValue();
val = dsaParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
q = (BigInteger) val.getValue();
val = dsaParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
g = (BigInteger) val.getValue();
}
DERReader dsaPub = new DERReader(publicKey);
val = dsaPub.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
Y = (BigInteger) val.getValue();
return new GnuDSAPublicKey(Y, p, q, g);
}
else if (algId.equals(ID_RSA))
{
DERReader rsaParams = new DERReader(publicKey);
if (!rsaParams.read().isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
return new GnuRSAPublicKey(new RSAPublicKeySpec(
(BigInteger) rsaParams.read().getValue(),
(BigInteger) rsaParams.read().getValue()));
}
else if (algId.equals(ID_DH))
{
if (algParams == null)
throw new InvalidKeySpecException("missing DH parameters");
DERReader dhParams = new DERReader(algParams);
val = dhParams.read();
BigInteger p, g, q, Y;
if (!val.isConstructed())
throw new InvalidKeySpecException("malformed DH parameters");
val = dhParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
p = (BigInteger) val.getValue();
val = dhParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
g = (BigInteger) val.getValue();
val = dhParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
q = (BigInteger) val.getValue();
DERReader dhPub = new DERReader(publicKey);
val = dhPub.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
Y = (BigInteger) val.getValue();
return (PublicKey) new GnuDHPublicKey(new DHParameterSpec(p, g), Y, q);
}
else
throw new InvalidKeySpecException("unknown algorithm: " + algId);
}
catch (IOException ioe)
{
throw new InvalidKeySpecException(ioe.getMessage());
}
}
public PrivateKey engineGeneratePrivate(KeySpec spec)
throws InvalidKeySpecException
{
if (!(spec instanceof PKCS8EncodedKeySpec))
{
throw new InvalidKeySpecException("only supports PKCS8 key specs");
}
DERReader der = new DERReader(((PKCS8EncodedKeySpec) spec).getEncoded());
try
{
DERValue pki = der.read();
if (!pki.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue val = der.read();
if (!(val.getValue() instanceof BigInteger))
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue alg = der.read();
if (!alg.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
val = der.read();
if (!(val.getValue() instanceof OID))
{
throw new InvalidKeySpecException("malformed encoded key");
}
OID algId = (OID) val.getValue();
byte[] algParams = null;
if (alg.getLength() > val.getEncodedLength())
{
val = der.read();
algParams = val.getEncoded();
if (val.isConstructed())
der.skip(val.getLength());
}
byte[] privateKey = (byte[]) der.read().getValue();
if (algId.equals(ID_DSA))
{
if (algParams == null)
{
throw new InvalidKeySpecException("missing DSA parameters");
}
AlgorithmParameters params = AlgorithmParameters.getInstance("DSA");
params.init(algParams);
DSAParameterSpec dsaSpec = (DSAParameterSpec)
params.getParameterSpec(DSAParameterSpec.class);
DERReader dsaPriv = new DERReader(privateKey);
return new GnuDSAPrivateKey((BigInteger) dsaPriv.read().getValue(),
dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG());
}
else if (algId.equals(ID_RSA))
{
DERReader rsaParams = new DERReader(privateKey);
if (!rsaParams.read().isConstructed())
throw new InvalidKeySpecException("malformed encoded key");
return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
(BigInteger) rsaParams.read().getValue(), (BigInteger) rsaParams.read().getValue(), (BigInteger) rsaParams.read().getValue(), (BigInteger) rsaParams.read().getValue(), (BigInteger) rsaParams.read().getValue(), (BigInteger) rsaParams.read().getValue(), (BigInteger) rsaParams.read().getValue(), (BigInteger) rsaParams.read().getValue())); }
else
throw new InvalidKeySpecException("unknown algorithm: " + algId);
}
catch (InvalidParameterSpecException iapse)
{
throw new InvalidKeySpecException(iapse.getMessage());
}
catch (NoSuchAlgorithmException nsae)
{
throw new InvalidKeySpecException(nsae.getMessage());
}
catch (IOException ioe)
{
throw new InvalidKeySpecException(ioe.getMessage());
}
}
public KeySpec engineGetKeySpec(Key key, Class speClass)
throws InvalidKeySpecException
{
if ((key instanceof PrivateKey) && key.getFormat().equals("PKCS#8")
&& speClass.isAssignableFrom(PKCS8EncodedKeySpec.class))
return new PKCS8EncodedKeySpec(key.getEncoded());
else if ((key instanceof PublicKey) && key.getFormat().equals("X.509")
&& speClass.isAssignableFrom(X509EncodedKeySpec.class))
return new X509EncodedKeySpec(key.getEncoded());
else
throw new InvalidKeySpecException();
}
public Key engineTranslateKey(Key key) throws InvalidKeyException
{
throw new InvalidKeyException("translating keys not supported");
}
}