1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.jce.provider;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.IOException;
4c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.ObjectInputStream;
5c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.ObjectOutputStream;
6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.math.BigInteger;
7c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.security.interfaces.DSAParams;
8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.security.interfaces.DSAPublicKey;
9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.security.spec.DSAParameterSpec;
10c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.security.spec.DSAPublicKeySpec;
11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Encodable;
134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Encoding;
14d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Rootimport org.bouncycastle.asn1.ASN1Integer;
154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.DERNull;
164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x509.AlgorithmIdentifier;
174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x509.DSAParameter;
184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.crypto.params.DSAPublicKeyParameters;
214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class JDKDSAPublicKey
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    implements DSAPublicKey
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final long serialVersionUID = 1752452449903495175L;
26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private BigInteger      y;
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private DSAParams       dsaSpec;
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    JDKDSAPublicKey(
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DSAPublicKeySpec    spec)
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.y = spec.getY();
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG());
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    JDKDSAPublicKey(
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DSAPublicKey    key)
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.y = key.getY();
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.dsaSpec = key.getParams();
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    JDKDSAPublicKey(
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DSAPublicKeyParameters  params)
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.y = params.getY();
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    JDKDSAPublicKey(
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        BigInteger        y,
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DSAParameterSpec  dsaSpec)
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.y = y;
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.dsaSpec = dsaSpec;
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    JDKDSAPublicKey(
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        SubjectPublicKeyInfo    info)
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
63d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root        ASN1Integer              derY;
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        try
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
67d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            derY = (ASN1Integer)info.parsePublicKey();
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        catch (IOException e)
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("invalid info structure in DSA public key");
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.y = derY.getValue();
75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
7670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom        if (isNotNull(info.getAlgorithm().getParameters()))
77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
7870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom            DSAParameter params = DSAParameter.getInstance(info.getAlgorithm().getParameters());
79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
80c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG());
81c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private boolean isNotNull(ASN1Encodable parameters)
85c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
86c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return parameters != null && !DERNull.INSTANCE.equals(parameters);
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String getAlgorithm()
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "DSA";
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String getFormat()
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "X.509";
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public byte[] getEncoded()
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
1014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        try
102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (dsaSpec == null)
1044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
105d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root                return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa), new ASN1Integer(y)).getEncoded(ASN1Encoding.DER);
1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
108d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG())), new ASN1Integer(y)).getEncoded(ASN1Encoding.DER);
1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        catch (IOException e)
1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return null;
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public DSAParams getParams()
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return dsaSpec;
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public BigInteger getY()
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return y;
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String toString()
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        StringBuffer    buf = new StringBuffer();
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String          nl = System.getProperty("line.separator");
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        buf.append("DSA Public Key").append(nl);
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        buf.append("            y: ").append(this.getY().toString(16)).append(nl);
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return buf.toString();
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
136c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
137c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public int hashCode()
138c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
139c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return this.getY().hashCode() ^ this.getParams().getG().hashCode()
140c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                ^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode();
141c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
142c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public boolean equals(
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object o)
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (!(o instanceof DSAPublicKey))
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DSAPublicKey other = (DSAPublicKey)o;
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return this.getY().equals(other.getY())
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            && this.getParams().getG().equals(other.getParams().getG())
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            && this.getParams().getP().equals(other.getParams().getP())
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            && this.getParams().getQ().equals(other.getParams().getQ());
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
158c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
159c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private void readObject(
160c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ObjectInputStream in)
161c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException, ClassNotFoundException
162c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
163c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        this.y = (BigInteger)in.readObject();
164c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject());
165c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
166c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
167c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private void writeObject(
168c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ObjectOutputStream out)
169c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException
170c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
171c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        out.writeObject(y);
172c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        out.writeObject(dsaSpec.getP());
173c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        out.writeObject(dsaSpec.getQ());
174c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        out.writeObject(dsaSpec.getG());
175c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
177