Home | History | Annotate | Download | only in dsa
      1 package org.bouncycastle.jcajce.provider.asymmetric.dsa;
      2 
      3 import java.io.IOException;
      4 import java.io.ObjectInputStream;
      5 import java.io.ObjectOutputStream;
      6 import java.math.BigInteger;
      7 import java.security.interfaces.DSAParams;
      8 import java.security.interfaces.DSAPublicKey;
      9 import java.security.spec.DSAParameterSpec;
     10 import java.security.spec.DSAPublicKeySpec;
     11 
     12 import org.bouncycastle.asn1.ASN1Encodable;
     13 import org.bouncycastle.asn1.ASN1Integer;
     14 import org.bouncycastle.asn1.DERNull;
     15 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
     16 import org.bouncycastle.asn1.x509.DSAParameter;
     17 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
     18 import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
     19 import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
     20 import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
     21 import org.bouncycastle.util.Strings;
     22 
     23 public class BCDSAPublicKey
     24     implements DSAPublicKey
     25 {
     26     private static final long serialVersionUID = 1752452449903495175L;
     27     private static BigInteger ZERO = BigInteger.valueOf(0);
     28 
     29     private BigInteger      y;
     30 
     31     private transient DSAPublicKeyParameters lwKeyParams;
     32     private transient DSAParams              dsaSpec;
     33 
     34     BCDSAPublicKey(
     35         DSAPublicKeySpec spec)
     36     {
     37         this.y = spec.getY();
     38         this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG());
     39         this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
     40     }
     41 
     42     BCDSAPublicKey(
     43         DSAPublicKey key)
     44     {
     45         this.y = key.getY();
     46         this.dsaSpec = key.getParams();
     47         this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
     48     }
     49 
     50     BCDSAPublicKey(
     51         DSAPublicKeyParameters params)
     52     {
     53         this.y = params.getY();
     54         if (params != null)
     55         {
     56             this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
     57         }
     58         else
     59         {
     60             this.dsaSpec = null;
     61         }
     62         this.lwKeyParams = params;
     63     }
     64 
     65     public BCDSAPublicKey(
     66         SubjectPublicKeyInfo info)
     67     {
     68         ASN1Integer              derY;
     69 
     70         try
     71         {
     72             derY = (ASN1Integer)info.parsePublicKey();
     73         }
     74         catch (IOException e)
     75         {
     76             throw new IllegalArgumentException("invalid info structure in DSA public key");
     77         }
     78 
     79         this.y = derY.getValue();
     80 
     81         if (isNotNull(info.getAlgorithm().getParameters()))
     82         {
     83             DSAParameter params = DSAParameter.getInstance(info.getAlgorithm().getParameters());
     84 
     85             this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG());
     86         }
     87         else
     88         {
     89             this.dsaSpec = null;
     90         }
     91 
     92         this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
     93     }
     94 
     95     private boolean isNotNull(ASN1Encodable parameters)
     96     {
     97         return parameters != null && !DERNull.INSTANCE.equals(parameters.toASN1Primitive());
     98     }
     99 
    100     public String getAlgorithm()
    101     {
    102         return "DSA";
    103     }
    104 
    105     public String getFormat()
    106     {
    107         return "X.509";
    108     }
    109 
    110     DSAPublicKeyParameters engineGetKeyParameters()
    111     {
    112         return lwKeyParams;
    113     }
    114 
    115     public byte[] getEncoded()
    116     {
    117         if (dsaSpec == null)
    118         {
    119             return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), new ASN1Integer(y));
    120         }
    121 
    122         return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG()).toASN1Primitive()), new ASN1Integer(y));
    123     }
    124 
    125     public DSAParams getParams()
    126     {
    127         return dsaSpec;
    128     }
    129 
    130     public BigInteger getY()
    131     {
    132         return y;
    133     }
    134 
    135     public String toString()
    136     {
    137         StringBuffer    buf = new StringBuffer();
    138         String          nl = Strings.lineSeparator();
    139 
    140         buf.append("DSA Public Key").append(nl);
    141         buf.append("            y: ").append(this.getY().toString(16)).append(nl);
    142 
    143         return buf.toString();
    144     }
    145 
    146     public int hashCode()
    147     {
    148         if (dsaSpec != null)
    149         {
    150             return this.getY().hashCode() ^ this.getParams().getG().hashCode()
    151                 ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode();
    152         }
    153         else
    154         {
    155             return this.getY().hashCode();
    156         }
    157     }
    158 
    159     public boolean equals(
    160         Object o)
    161     {
    162         if (!(o instanceof DSAPublicKey))
    163         {
    164             return false;
    165         }
    166 
    167         DSAPublicKey other = (DSAPublicKey)o;
    168 
    169         if (this.dsaSpec != null)
    170         {
    171             return this.getY().equals(other.getY())
    172                 && other.getParams() != null
    173                 && this.getParams().getG().equals(other.getParams().getG())
    174                 && this.getParams().getP().equals(other.getParams().getP())
    175                 && this.getParams().getQ().equals(other.getParams().getQ());
    176         }
    177         else
    178         {
    179             return this.getY().equals(other.getY()) && other.getParams() == null;
    180         }
    181     }
    182 
    183     private void readObject(
    184         ObjectInputStream in)
    185         throws IOException, ClassNotFoundException
    186     {
    187         in.defaultReadObject();
    188 
    189         BigInteger p = (BigInteger)in.readObject();
    190         if (p.equals(ZERO))
    191         {
    192             this.dsaSpec = null;
    193         }
    194         else
    195         {
    196             this.dsaSpec = new DSAParameterSpec(p, (BigInteger)in.readObject(), (BigInteger)in.readObject());
    197         }
    198         this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
    199     }
    200 
    201     private void writeObject(
    202         ObjectOutputStream out)
    203         throws IOException
    204     {
    205         out.defaultWriteObject();
    206 
    207         if (dsaSpec == null)
    208         {
    209             out.writeObject(ZERO);
    210         }
    211         else
    212         {
    213             out.writeObject(dsaSpec.getP());
    214             out.writeObject(dsaSpec.getQ());
    215             out.writeObject(dsaSpec.getG());
    216         }
    217     }
    218 }
    219