1package org.bouncycastle.jce.provider;
2
3import java.math.BigInteger;
4import java.security.interfaces.DSAParams;
5import java.security.interfaces.DSAPrivateKey;
6import java.security.spec.DSAParameterSpec;
7import java.security.spec.DSAPrivateKeySpec;
8import java.util.Enumeration;
9import java.util.Hashtable;
10import java.util.Vector;
11
12import org.bouncycastle.asn1.ASN1Sequence;
13import org.bouncycastle.asn1.DEREncodable;
14import org.bouncycastle.asn1.DERInteger;
15import org.bouncycastle.asn1.DERObjectIdentifier;
16import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
17import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
18import org.bouncycastle.asn1.x509.DSAParameter;
19import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
20import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
21import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
22
23public class JDKDSAPrivateKey
24    implements DSAPrivateKey, PKCS12BagAttributeCarrier
25{
26    BigInteger          x;
27    DSAParams           dsaSpec;
28
29    private Hashtable   pkcs12Attributes = new Hashtable();
30    private Vector      pkcs12Ordering = new Vector();
31
32    protected JDKDSAPrivateKey()
33    {
34    }
35
36    JDKDSAPrivateKey(
37        DSAPrivateKey    key)
38    {
39        this.x = key.getX();
40        this.dsaSpec = key.getParams();
41    }
42
43    JDKDSAPrivateKey(
44        DSAPrivateKeySpec    spec)
45    {
46        this.x = spec.getX();
47        this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG());
48    }
49
50    JDKDSAPrivateKey(
51        PrivateKeyInfo  info)
52    {
53        DSAParameter    params = new DSAParameter((ASN1Sequence)info.getAlgorithmId().getParameters());
54        DERInteger      derX = (DERInteger)info.getPrivateKey();
55
56        this.x = derX.getValue();
57        this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG());
58    }
59
60    JDKDSAPrivateKey(
61        DSAPrivateKeyParameters  params)
62    {
63        this.x = params.getX();
64        this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
65    }
66
67    public String getAlgorithm()
68    {
69        return "DSA";
70    }
71
72    /**
73     * return the encoding format we produce in getEncoded().
74     *
75     * @return the string "PKCS#8"
76     */
77    public String getFormat()
78    {
79        return "PKCS#8";
80    }
81
82    /**
83     * Return a PKCS8 representation of the key. The sequence returned
84     * represents a full PrivateKeyInfo object.
85     *
86     * @return a PKCS8 representation of the key.
87     */
88    public byte[] getEncoded()
89    {
90        PrivateKeyInfo          info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG()).getDERObject()), new DERInteger(getX()));
91
92        return info.getDEREncoded();
93    }
94
95    public DSAParams getParams()
96    {
97        return dsaSpec;
98    }
99
100    public BigInteger getX()
101    {
102        return x;
103    }
104
105    public boolean equals(
106        Object o)
107    {
108        if (!(o instanceof DSAPrivateKey))
109        {
110            return false;
111        }
112
113        DSAPrivateKey other = (DSAPrivateKey)o;
114
115        return this.getX().equals(other.getX())
116            && this.getParams().getG().equals(other.getParams().getG())
117            && this.getParams().getP().equals(other.getParams().getP())
118            && this.getParams().getQ().equals(other.getParams().getQ());
119    }
120
121    public void setBagAttribute(
122        DERObjectIdentifier oid,
123        DEREncodable        attribute)
124    {
125        pkcs12Attributes.put(oid, attribute);
126        pkcs12Ordering.addElement(oid);
127    }
128
129    public DEREncodable getBagAttribute(
130        DERObjectIdentifier oid)
131    {
132        return (DEREncodable)pkcs12Attributes.get(oid);
133    }
134
135    public Enumeration getBagAttributeKeys()
136    {
137        return pkcs12Ordering.elements();
138    }
139}
140