Home | History | Annotate | Download | only in crypto
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package org.apache.harmony.security.provider.crypto;
     19 
     20 import java.math.BigInteger;
     21 import java.security.InvalidKeyException;
     22 import java.security.Key;
     23 import java.security.KeyFactorySpi;
     24 import java.security.PrivateKey;
     25 import java.security.PublicKey;
     26 import java.security.interfaces.DSAParams;
     27 import java.security.interfaces.DSAPrivateKey;
     28 import java.security.interfaces.DSAPublicKey;
     29 import java.security.spec.DSAPrivateKeySpec;
     30 import java.security.spec.DSAPublicKeySpec;
     31 import java.security.spec.InvalidKeySpecException;
     32 import java.security.spec.KeySpec;
     33 import java.security.spec.PKCS8EncodedKeySpec;
     34 import java.security.spec.X509EncodedKeySpec;
     35 
     36 public class DSAKeyFactoryImpl extends KeyFactorySpi {
     37 
     38     /**
     39      * This method generates a DSAPrivateKey object from the provided key specification.
     40      *
     41      * @param
     42      *    keySpec - the specification (key material) for the DSAPrivateKey.
     43      *
     44      * @return
     45      *    a DSAPrivateKey object
     46      *
     47      * @throws InvalidKeySpecException
     48      *     if "keySpec" is neither DSAPrivateKeySpec nor PKCS8EncodedKeySpec
     49      */
     50     protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
     51             throws InvalidKeySpecException {
     52 
     53         if (keySpec != null) {
     54             if (keySpec instanceof DSAPrivateKeySpec) {
     55 
     56                 return new DSAPrivateKeyImpl((DSAPrivateKeySpec) keySpec);
     57             }
     58             if (keySpec instanceof PKCS8EncodedKeySpec) {
     59 
     60                 return new DSAPrivateKeyImpl((PKCS8EncodedKeySpec) keySpec);
     61             }
     62         }
     63         throw new InvalidKeySpecException("'keySpec' is neither DSAPrivateKeySpec nor PKCS8EncodedKeySpec");
     64     }
     65 
     66     /**
     67      * This method generates a DSAPublicKey object from the provided key specification.
     68      *
     69      * @param
     70      *    keySpec - the specification (key material) for the DSAPublicKey.
     71      *
     72      * @return
     73      *    a DSAPublicKey object
     74      *
     75      * @throws InvalidKeySpecException
     76      *     if "keySpec" is neither DSAPublicKeySpec nor X509EncodedKeySpec
     77      */
     78     protected PublicKey engineGeneratePublic(KeySpec keySpec)
     79             throws InvalidKeySpecException {
     80 
     81         if (keySpec != null) {
     82             if (keySpec instanceof DSAPublicKeySpec) {
     83 
     84                 return new DSAPublicKeyImpl((DSAPublicKeySpec) keySpec);
     85             }
     86             if (keySpec instanceof X509EncodedKeySpec) {
     87 
     88                 return new DSAPublicKeyImpl((X509EncodedKeySpec) keySpec);
     89             }
     90         }
     91         throw new InvalidKeySpecException("'keySpec' is neither DSAPublicKeySpec nor X509EncodedKeySpec");
     92     }
     93 
     94     /**
     95      * This method returns a specification for the supplied key.
     96      *
     97      * The specification will be returned in the form of an object of the type
     98      * specified by keySpec.
     99      *
    100      * @param key -
    101      *            either DSAPrivateKey or DSAPublicKey
    102      * @param keySpec -
    103      *            either DSAPrivateKeySpec.class or DSAPublicKeySpec.class
    104      *
    105      * @return either a DSAPrivateKeySpec or a DSAPublicKeySpec
    106      *
    107      * @throws InvalidKeySpecException
    108      *             if "keySpec" is not a specification for DSAPublicKey or
    109      *             DSAPrivateKey
    110      */
    111     protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
    112             throws InvalidKeySpecException {
    113 
    114         BigInteger p, q, g, x, y;
    115 
    116         if (key != null) {
    117             if (keySpec == null) {
    118                 throw new NullPointerException("keySpec == null");
    119             }
    120             if (key instanceof DSAPrivateKey) {
    121                 DSAPrivateKey privateKey = (DSAPrivateKey) key;
    122 
    123                 if (keySpec.equals(DSAPrivateKeySpec.class)) {
    124 
    125                     x = privateKey.getX();
    126 
    127                     DSAParams params = privateKey.getParams();
    128 
    129                     p = params.getP();
    130                     q = params.getQ();
    131                     g = params.getG();
    132 
    133                     return (T) (new DSAPrivateKeySpec(x, p, q, g));
    134                 }
    135 
    136                 if (keySpec.equals(PKCS8EncodedKeySpec.class)) {
    137                     return (T) (new PKCS8EncodedKeySpec(key.getEncoded()));
    138                 }
    139 
    140                 throw new InvalidKeySpecException("'keySpec' is neither DSAPrivateKeySpec nor PKCS8EncodedKeySpec");
    141             }
    142 
    143             if (key instanceof DSAPublicKey) {
    144                 DSAPublicKey publicKey = (DSAPublicKey) key;
    145 
    146                 if (keySpec.equals(DSAPublicKeySpec.class)) {
    147 
    148                     y = publicKey.getY();
    149 
    150                     DSAParams params = publicKey.getParams();
    151 
    152                     p = params.getP();
    153                     q = params.getQ();
    154                     g = params.getG();
    155 
    156                     return (T) (new DSAPublicKeySpec(y, p, q, g));
    157                 }
    158 
    159                 if (keySpec.equals(X509EncodedKeySpec.class)) {
    160                     return (T) (new X509EncodedKeySpec(key.getEncoded()));
    161                 }
    162 
    163                 throw new InvalidKeySpecException("'keySpec' is neither DSAPublicKeySpec nor X509EncodedKeySpec");
    164             }
    165         }
    166         throw new InvalidKeySpecException("'key' is neither DSAPublicKey nor DSAPrivateKey");
    167     }
    168 
    169     /**
    170      * The method generates a DSAPublicKey object from the provided key.
    171      *
    172      * @param
    173      *    key - a DSAPublicKey object or DSAPrivateKey object.
    174      *
    175      * @return
    176      *    object of the same type as the "key" argument
    177      *
    178      * @throws InvalidKeyException
    179      *     if "key" is neither DSAPublicKey nor DSAPrivateKey
    180      */
    181     protected Key engineTranslateKey(Key key) throws InvalidKeyException {
    182 
    183         if (key != null) {
    184             if (key instanceof DSAPrivateKey) {
    185 
    186                 DSAPrivateKey privateKey = (DSAPrivateKey) key;
    187                 DSAParams params = privateKey.getParams();
    188 
    189                 try {
    190                     return engineGeneratePrivate(new DSAPrivateKeySpec(
    191                             privateKey.getX(), params.getP(), params.getQ(),
    192                             params.getG()));
    193                 } catch (InvalidKeySpecException e) {
    194                     // Actually this exception shouldn't be thrown
    195                     throw new InvalidKeyException("ATTENTION: InvalidKeySpecException: " + e);
    196                 }
    197             }
    198 
    199             if (key instanceof DSAPublicKey) {
    200 
    201                 DSAPublicKey publicKey = (DSAPublicKey) key;
    202                 DSAParams params = publicKey.getParams();
    203 
    204                 try {
    205                     return engineGeneratePublic(new DSAPublicKeySpec(publicKey
    206                             .getY(), params.getP(), params.getQ(), params
    207                             .getG()));
    208                 } catch (InvalidKeySpecException e) {
    209                     // Actually this exception shouldn't be thrown
    210                     throw new InvalidKeyException("ATTENTION: InvalidKeySpecException: " + e);
    211                 }
    212             }
    213         }
    214         throw new InvalidKeyException("'key' is neither DSAPublicKey nor DSAPrivateKey");
    215     }
    216 
    217 }
    218