JDKDSAPublicKey.java revision e1142c149e244797ce73b0e7fad40816e447a817
1package org.bouncycastle.jce.provider;
2
3import java.io.IOException;
4import java.io.ObjectInputStream;
5import java.io.ObjectOutputStream;
6import java.math.BigInteger;
7import java.security.interfaces.DSAParams;
8import java.security.interfaces.DSAPublicKey;
9import java.security.spec.DSAParameterSpec;
10import java.security.spec.DSAPublicKeySpec;
11
12import org.bouncycastle.asn1.ASN1Encodable;
13import org.bouncycastle.asn1.ASN1Encoding;
14import org.bouncycastle.asn1.ASN1Sequence;
15import org.bouncycastle.asn1.DERInteger;
16import org.bouncycastle.asn1.DERNull;
17import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
18import org.bouncycastle.asn1.x509.DSAParameter;
19import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
20import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
21import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
22
23public class JDKDSAPublicKey
24    implements DSAPublicKey
25{
26    private static final long serialVersionUID = 1752452449903495175L;
27
28    private BigInteger      y;
29    private DSAParams       dsaSpec;
30
31    JDKDSAPublicKey(
32        DSAPublicKeySpec    spec)
33    {
34        this.y = spec.getY();
35        this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG());
36    }
37
38    JDKDSAPublicKey(
39        DSAPublicKey    key)
40    {
41        this.y = key.getY();
42        this.dsaSpec = key.getParams();
43    }
44
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
52    JDKDSAPublicKey(
53        BigInteger        y,
54        DSAParameterSpec  dsaSpec)
55    {
56        this.y = y;
57        this.dsaSpec = dsaSpec;
58    }
59
60    JDKDSAPublicKey(
61        SubjectPublicKeyInfo    info)
62    {
63
64        DERInteger              derY;
65
66        try
67        {
68            derY = (DERInteger)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
85    private boolean isNotNull(ASN1Encodable parameters)
86    {
87        return parameters != null && !DERNull.INSTANCE.equals(parameters);
88    }
89
90    public String getAlgorithm()
91    {
92        return "DSA";
93    }
94
95    public String getFormat()
96    {
97        return "X.509";
98    }
99
100    public byte[] getEncoded()
101    {
102        try
103        {
104            if (dsaSpec == null)
105            {
106                return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), new DERInteger(y)).getEncoded(ASN1Encoding.DER);
107            }
108
109            return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG())), new DERInteger(y)).getEncoded(ASN1Encoding.DER);
110        }
111        catch (IOException e)
112        {
113            return null;
114        }
115    }
116
117    public DSAParams getParams()
118    {
119        return dsaSpec;
120    }
121
122    public BigInteger getY()
123    {
124        return y;
125    }
126
127    public String toString()
128    {
129        StringBuffer    buf = new StringBuffer();
130        String          nl = System.getProperty("line.separator");
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
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
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
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
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