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