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