| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
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.AccessController;  | 
 | 
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 sun.security.action.GetPropertyAction;  | 
 | 
 | 
 | 
/**  | 
 | 
 * This class implements the DSA key factory of the Sun provider.  | 
 | 
 *  | 
 | 
 * @author Jan Luehe  | 
 | 
 *  | 
 | 
 *  | 
 | 
 * @since 1.2  | 
 | 
 */  | 
 | 
 | 
 | 
public class DSAKeyFactory extends KeyFactorySpi { | 
 | 
 | 
 | 
      | 
 | 
    static final boolean SERIAL_INTEROP;  | 
 | 
    private static final String SERIAL_PROP = "sun.security.key.serial.interop";  | 
 | 
 | 
 | 
    static { | 
 | 
 | 
 | 
          | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
         */  | 
 | 
        String prop = AccessController.doPrivileged  | 
 | 
                (new GetPropertyAction(SERIAL_PROP, null));  | 
 | 
        SERIAL_INTEROP = "true".equalsIgnoreCase(prop);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    protected PublicKey engineGeneratePublic(KeySpec keySpec)  | 
 | 
    throws InvalidKeySpecException { | 
 | 
        try { | 
 | 
            if (keySpec instanceof DSAPublicKeySpec) { | 
 | 
                DSAPublicKeySpec dsaPubKeySpec = (DSAPublicKeySpec)keySpec;  | 
 | 
                if (SERIAL_INTEROP) { | 
 | 
                    return new DSAPublicKey(dsaPubKeySpec.getY(),  | 
 | 
                                        dsaPubKeySpec.getP(),  | 
 | 
                                        dsaPubKeySpec.getQ(),  | 
 | 
                                        dsaPubKeySpec.getG());  | 
 | 
                } else { | 
 | 
                    return new DSAPublicKeyImpl(dsaPubKeySpec.getY(),  | 
 | 
                                        dsaPubKeySpec.getP(),  | 
 | 
                                        dsaPubKeySpec.getQ(),  | 
 | 
                                        dsaPubKeySpec.getG());  | 
 | 
                }  | 
 | 
            } else if (keySpec instanceof X509EncodedKeySpec) { | 
 | 
                if (SERIAL_INTEROP) { | 
 | 
                    return new DSAPublicKey  | 
 | 
                        (((X509EncodedKeySpec)keySpec).getEncoded());  | 
 | 
                } else { | 
 | 
                    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) { | 
 | 
                return new DSAPrivateKey  | 
 | 
                    (((PKCS8EncodedKeySpec)keySpec).getEncoded());  | 
 | 
 | 
 | 
            } 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 (dsaPubKeySpec.isAssignableFrom(keySpec)) { | 
 | 
                    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 (x509KeySpec.isAssignableFrom(keySpec)) { | 
 | 
                    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 (dsaPrivKeySpec.isAssignableFrom(keySpec)) { | 
 | 
                    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 (pkcs8KeySpec.isAssignableFrom(keySpec)) { | 
 | 
                    return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded()));  | 
 | 
 | 
 | 
                } 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());  | 
 | 
        }  | 
 | 
    }  | 
 | 
}  |