Path: blob/master/src/java.base/share/classes/sun/security/provider/DSAKeyFactory.java
41159 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.provider;2627import java.security.Key;28import java.security.PublicKey;29import java.security.PrivateKey;30import java.security.KeyFactorySpi;31import java.security.InvalidKeyException;32import java.security.interfaces.DSAParams;33import java.security.spec.DSAPublicKeySpec;34import java.security.spec.DSAPrivateKeySpec;35import java.security.spec.KeySpec;36import java.security.spec.InvalidKeySpecException;37import java.security.spec.X509EncodedKeySpec;38import java.security.spec.PKCS8EncodedKeySpec;39import java.util.Arrays;4041/**42* This class implements the DSA key factory of the Sun provider.43*44* @author Jan Luehe45*46*47* @since 1.248*/4950public class DSAKeyFactory extends KeyFactorySpi {51/**52* Generates a public key object from the provided key specification53* (key material).54*55* @param keySpec the specification (key material) of the public key56*57* @return the public key58*59* @exception InvalidKeySpecException if the given key specification60* is inappropriate for this key factory to produce a public key.61*/62protected PublicKey engineGeneratePublic(KeySpec keySpec)63throws InvalidKeySpecException {64try {65if (keySpec instanceof DSAPublicKeySpec) {66DSAPublicKeySpec dsaPubKeySpec = (DSAPublicKeySpec)keySpec;67return new DSAPublicKeyImpl(dsaPubKeySpec.getY(),68dsaPubKeySpec.getP(),69dsaPubKeySpec.getQ(),70dsaPubKeySpec.getG());71} else if (keySpec instanceof X509EncodedKeySpec) {72return new DSAPublicKeyImpl73(((X509EncodedKeySpec)keySpec).getEncoded());74} else {75throw new InvalidKeySpecException76("Inappropriate key specification");77}78} catch (InvalidKeyException e) {79throw new InvalidKeySpecException80("Inappropriate key specification: " + e.getMessage());81}82}8384/**85* Generates a private key object from the provided key specification86* (key material).87*88* @param keySpec the specification (key material) of the private key89*90* @return the private key91*92* @exception InvalidKeySpecException if the given key specification93* is inappropriate for this key factory to produce a private key.94*/95protected PrivateKey engineGeneratePrivate(KeySpec keySpec)96throws InvalidKeySpecException {97try {98if (keySpec instanceof DSAPrivateKeySpec) {99DSAPrivateKeySpec dsaPrivKeySpec = (DSAPrivateKeySpec)keySpec;100return new DSAPrivateKey(dsaPrivKeySpec.getX(),101dsaPrivKeySpec.getP(),102dsaPrivKeySpec.getQ(),103dsaPrivKeySpec.getG());104105} else if (keySpec instanceof PKCS8EncodedKeySpec) {106byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();107try {108return new DSAPrivateKey(encoded);109} finally {110Arrays.fill(encoded, (byte) 0);111}112} else {113throw new InvalidKeySpecException114("Inappropriate key specification");115}116} catch (InvalidKeyException e) {117throw new InvalidKeySpecException118("Inappropriate key specification: " + e.getMessage());119}120}121122/**123* Returns a specification (key material) of the given key object124* in the requested format.125*126* @param key the key127*128* @param keySpec the requested format in which the key material shall be129* returned130*131* @return the underlying key specification (key material) in the132* requested format133*134* @exception InvalidKeySpecException if the requested key specification is135* inappropriate for the given key, or the given key cannot be processed136* (e.g., the given key has an unrecognized algorithm or format).137*/138protected <T extends KeySpec>139T engineGetKeySpec(Key key, Class<T> keySpec)140throws InvalidKeySpecException {141142DSAParams params;143144try {145146if (key instanceof java.security.interfaces.DSAPublicKey) {147148// Determine valid key specs149Class<?> dsaPubKeySpec = Class.forName150("java.security.spec.DSAPublicKeySpec");151Class<?> x509KeySpec = Class.forName152("java.security.spec.X509EncodedKeySpec");153154if (keySpec.isAssignableFrom(dsaPubKeySpec)) {155java.security.interfaces.DSAPublicKey dsaPubKey156= (java.security.interfaces.DSAPublicKey)key;157params = dsaPubKey.getParams();158return keySpec.cast(new DSAPublicKeySpec(dsaPubKey.getY(),159params.getP(),160params.getQ(),161params.getG()));162163} else if (keySpec.isAssignableFrom(x509KeySpec)) {164return keySpec.cast(new X509EncodedKeySpec(key.getEncoded()));165166} else {167throw new InvalidKeySpecException168("Inappropriate key specification");169}170171} else if (key instanceof java.security.interfaces.DSAPrivateKey) {172173// Determine valid key specs174Class<?> dsaPrivKeySpec = Class.forName175("java.security.spec.DSAPrivateKeySpec");176Class<?> pkcs8KeySpec = Class.forName177("java.security.spec.PKCS8EncodedKeySpec");178179if (keySpec.isAssignableFrom(dsaPrivKeySpec)) {180java.security.interfaces.DSAPrivateKey dsaPrivKey181= (java.security.interfaces.DSAPrivateKey)key;182params = dsaPrivKey.getParams();183return keySpec.cast(new DSAPrivateKeySpec(dsaPrivKey.getX(),184params.getP(),185params.getQ(),186params.getG()));187188} else if (keySpec.isAssignableFrom(pkcs8KeySpec)) {189byte[] encoded = key.getEncoded();190try {191return keySpec.cast(new PKCS8EncodedKeySpec(encoded));192} finally {193Arrays.fill(encoded, (byte)0);194}195} else {196throw new InvalidKeySpecException197("Inappropriate key specification");198}199200} else {201throw new InvalidKeySpecException("Inappropriate key type");202}203204} catch (ClassNotFoundException e) {205throw new InvalidKeySpecException206("Unsupported key specification: " + e.getMessage());207}208}209210/**211* Translates a key object, whose provider may be unknown or potentially212* untrusted, into a corresponding key object of this key factory.213*214* @param key the key whose provider is unknown or untrusted215*216* @return the translated key217*218* @exception InvalidKeyException if the given key cannot be processed by219* this key factory.220*/221protected Key engineTranslateKey(Key key) throws InvalidKeyException {222223try {224225if (key instanceof java.security.interfaces.DSAPublicKey) {226// Check if key originates from this factory227if (key instanceof sun.security.provider.DSAPublicKey) {228return key;229}230// Convert key to spec231DSAPublicKeySpec dsaPubKeySpec232= engineGetKeySpec(key, DSAPublicKeySpec.class);233// Create key from spec, and return it234return engineGeneratePublic(dsaPubKeySpec);235236} else if (key instanceof java.security.interfaces.DSAPrivateKey) {237// Check if key originates from this factory238if (key instanceof sun.security.provider.DSAPrivateKey) {239return key;240}241// Convert key to spec242DSAPrivateKeySpec dsaPrivKeySpec243= engineGetKeySpec(key, DSAPrivateKeySpec.class);244// Create key from spec, and return it245return engineGeneratePrivate(dsaPrivKeySpec);246247} else {248throw new InvalidKeyException("Wrong algorithm type");249}250251} catch (InvalidKeySpecException e) {252throw new InvalidKeyException("Cannot translate key: "253+ e.getMessage());254}255}256}257258259