1 package org.bouncycastle.jce.provider;
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.ASN1Encoding;
14 import org.bouncycastle.asn1.ASN1Integer;
15 import org.bouncycastle.asn1.DERNull;
16 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
17 import org.bouncycastle.asn1.x509.DSAParameter;
18 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
19 import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
20 import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
21 import org.bouncycastle.util.Strings;
22 
23 public class JDKDSAPublicKey
24     implements DSAPublicKey
25 {
26     private static final long serialVersionUID = 1752452449903495175L;
27 
28     private BigInteger      y;
29     private DSAParams       dsaSpec;
30 
JDKDSAPublicKey( DSAPublicKeySpec spec)31     JDKDSAPublicKey(
32         DSAPublicKeySpec    spec)
33     {
34         this.y = spec.getY();
35         this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG());
36     }
37 
JDKDSAPublicKey( DSAPublicKey key)38     JDKDSAPublicKey(
39         DSAPublicKey    key)
40     {
41         this.y = key.getY();
42         this.dsaSpec = key.getParams();
43     }
44 
JDKDSAPublicKey( DSAPublicKeyParameters params)45     JDKDSAPublicKey(
46         DSAPublicKeyParameters  params)
47     {
48         this.y = params.getY();
49         this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
50     }
51 
JDKDSAPublicKey( BigInteger y, DSAParameterSpec dsaSpec)52     JDKDSAPublicKey(
53         BigInteger        y,
54         DSAParameterSpec  dsaSpec)
55     {
56         this.y = y;
57         this.dsaSpec = dsaSpec;
58     }
59 
JDKDSAPublicKey( SubjectPublicKeyInfo info)60     JDKDSAPublicKey(
61         SubjectPublicKeyInfo    info)
62     {
63 
64         ASN1Integer              derY;
65 
66         try
67         {
68             derY = (ASN1Integer)info.parsePublicKey();
69         }
70         catch (IOException e)
71         {
72             throw new IllegalArgumentException("invalid info structure in DSA public key");
73         }
74 
75         this.y = derY.getValue();
76 
77         if (isNotNull(info.getAlgorithm().getParameters()))
78         {
79             DSAParameter params = DSAParameter.getInstance(info.getAlgorithm().getParameters());
80 
81             this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG());
82         }
83     }
84 
isNotNull(ASN1Encodable parameters)85     private boolean isNotNull(ASN1Encodable parameters)
86     {
87         return parameters != null && !DERNull.INSTANCE.equals(parameters);
88     }
89 
getAlgorithm()90     public String getAlgorithm()
91     {
92         return "DSA";
93     }
94 
getFormat()95     public String getFormat()
96     {
97         return "X.509";
98     }
99 
getEncoded()100     public byte[] getEncoded()
101     {
102         try
103         {
104             if (dsaSpec == null)
105             {
106                 return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), new ASN1Integer(y)).getEncoded(ASN1Encoding.DER);
107             }
108 
109             return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG())), new ASN1Integer(y)).getEncoded(ASN1Encoding.DER);
110         }
111         catch (IOException e)
112         {
113             return null;
114         }
115     }
116 
getParams()117     public DSAParams getParams()
118     {
119         return dsaSpec;
120     }
121 
getY()122     public BigInteger getY()
123     {
124         return y;
125     }
126 
toString()127     public String toString()
128     {
129         StringBuffer    buf = new StringBuffer();
130         String          nl = Strings.lineSeparator();
131 
132         buf.append("DSA Public Key").append(nl);
133         buf.append("            y: ").append(this.getY().toString(16)).append(nl);
134 
135         return buf.toString();
136     }
137 
hashCode()138     public int hashCode()
139     {
140         return this.getY().hashCode() ^ this.getParams().getG().hashCode()
141                 ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode();
142     }
143 
equals( Object o)144     public boolean equals(
145         Object o)
146     {
147         if (!(o instanceof DSAPublicKey))
148         {
149             return false;
150         }
151 
152         DSAPublicKey other = (DSAPublicKey)o;
153 
154         return this.getY().equals(other.getY())
155             && this.getParams().getG().equals(other.getParams().getG())
156             && this.getParams().getP().equals(other.getParams().getP())
157             && this.getParams().getQ().equals(other.getParams().getQ());
158     }
159 
readObject( ObjectInputStream in)160     private void readObject(
161         ObjectInputStream in)
162         throws IOException, ClassNotFoundException
163     {
164         this.y = (BigInteger)in.readObject();
165         this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject());
166     }
167 
writeObject( ObjectOutputStream out)168     private void writeObject(
169         ObjectOutputStream out)
170         throws IOException
171     {
172         out.writeObject(y);
173         out.writeObject(dsaSpec.getP());
174         out.writeObject(dsaSpec.getQ());
175         out.writeObject(dsaSpec.getG());
176     }
177 }
178