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  /*
     19   * TODO
     20   * 1. The class extends the PrivateKeyImpl class in "org.apache.harmony.security" package.
     21   *
     22   * 2. See a compatibility with RI comments
     23   *    in the below "DSAPrivateKeyImpl(PKCS8EncodedKeySpec keySpec)" constructor.
     24   */
     25 
     26 
     27 package org.apache.harmony.security.provider.crypto;
     28 
     29 import java.io.IOException;
     30 import java.io.NotActiveException;
     31 import java.math.BigInteger;
     32 import java.security.interfaces.DSAParams;
     33 import java.security.interfaces.DSAPrivateKey;
     34 import java.security.spec.DSAParameterSpec;
     35 import java.security.spec.DSAPrivateKeySpec;
     36 import java.security.spec.InvalidKeySpecException;
     37 import java.security.spec.PKCS8EncodedKeySpec;
     38 import org.apache.harmony.security.PrivateKeyImpl;
     39 import org.apache.harmony.security.asn1.ASN1Integer;
     40 import org.apache.harmony.security.pkcs8.PrivateKeyInfo;
     41 import org.apache.harmony.security.utils.AlgNameMapper;
     42 import org.apache.harmony.security.x509.AlgorithmIdentifier;
     43 
     44 /**
     45  * The class provides DSAPrivateKey functionality by extending a class implementing PrivateKey
     46  * and implementing methods defined in both interfaces, DSAKey and DSAPrivateKey
     47  */
     48 public class DSAPrivateKeyImpl extends PrivateKeyImpl implements DSAPrivateKey {
     49 
     50     /**
     51      * @serial
     52      */
     53     private static final long serialVersionUID = -4716227614104950081L;
     54 
     55     private BigInteger x, g, p, q;
     56 
     57     private transient DSAParams params;
     58 
     59     /**
     60      * Creates object from DSAPrivateKeySpec.
     61      *
     62      * @param keySpec - a DSAPrivateKeySpec object
     63      */
     64     public DSAPrivateKeyImpl(DSAPrivateKeySpec keySpec) {
     65 
     66         super("DSA");
     67 
     68         PrivateKeyInfo pki;
     69 
     70         g = keySpec.getG();
     71         p = keySpec.getP();
     72         q = keySpec.getQ();
     73 
     74         ThreeIntegerSequence threeInts = new ThreeIntegerSequence(p
     75                 .toByteArray(), q.toByteArray(), g.toByteArray());
     76 
     77         AlgorithmIdentifier ai = new AlgorithmIdentifier(AlgNameMapper
     78                 .map2OID("DSA"),
     79                 threeInts.getEncoded());
     80         x = keySpec.getX();
     81 
     82         pki = new PrivateKeyInfo(0, ai, ASN1Integer.getInstance().encode(
     83                 x.toByteArray()), null);
     84 
     85         setEncoding(pki.getEncoded());
     86 
     87         params = new DSAParameterSpec(p, q, g);
     88     }
     89 
     90     /**
     91      * Creates object from PKCS8EncodedKeySpec.
     92      *
     93      * @param keySpec - a XPKCS8EncodedKeySpec object
     94      *
     95      * @throws InvalidKeySpecException - if key data cannot be obtain from encoded format
     96      */
     97     public DSAPrivateKeyImpl(PKCS8EncodedKeySpec keySpec)
     98             throws InvalidKeySpecException {
     99 
    100         super("DSA");
    101 
    102         AlgorithmIdentifier ai;
    103         ThreeIntegerSequence threeInts = null;
    104 
    105         String alg, algName;
    106 
    107         byte[] encoding = keySpec.getEncoded();
    108 
    109         PrivateKeyInfo privateKeyInfo = null;
    110 
    111         try {
    112             privateKeyInfo = (PrivateKeyInfo) PrivateKeyInfo.ASN1
    113                     .decode(encoding);
    114         } catch (IOException e) {
    115             throw new InvalidKeySpecException("Failed to decode keySpec encoding: " + e);
    116         }
    117 
    118         try {
    119             x = new BigInteger((byte[]) ASN1Integer.getInstance().decode(
    120                     privateKeyInfo.getPrivateKey()));
    121         } catch (IOException e) {
    122             throw new InvalidKeySpecException("Failed to decode parameters: " + e);
    123         }
    124 
    125         ai = privateKeyInfo.getAlgorithmIdentifier();
    126         try {
    127             threeInts = (ThreeIntegerSequence) ThreeIntegerSequence.ASN1
    128                     .decode(ai.getParameters());
    129         } catch (IOException e) {
    130             throw new InvalidKeySpecException("Failed to decode parameters: " + e);
    131         }
    132         p = new BigInteger(threeInts.p);
    133         q = new BigInteger(threeInts.q);
    134         g = new BigInteger(threeInts.g);
    135         params = new DSAParameterSpec(p, q, g);
    136         setEncoding(encoding);
    137 
    138         /*
    139          * the following code implements RI behavior
    140          */
    141         alg = ai.getAlgorithm();
    142         algName = AlgNameMapper.map2AlgName(alg);
    143         setAlgorithm(algName == null ? alg : algName);
    144     }
    145 
    146     public BigInteger getX() {
    147         return x;
    148     }
    149 
    150     public DSAParams getParams() {
    151         return params;
    152     }
    153 
    154     private void readObject(java.io.ObjectInputStream in) throws NotActiveException, IOException, ClassNotFoundException {
    155         in.defaultReadObject();
    156         params = new DSAParameterSpec(p, q, g);
    157     }
    158 
    159 }
    160