1package org.bouncycastle.jce.provider;
2
3import java.io.ByteArrayOutputStream;
4import java.io.IOException;
5import java.io.ObjectInputStream;
6import java.io.ObjectOutputStream;
7import java.math.BigInteger;
8import java.security.interfaces.RSAPrivateKey;
9import java.security.spec.RSAPrivateKeySpec;
10import java.util.Enumeration;
11import java.util.Hashtable;
12import java.util.Vector;
13
14import org.bouncycastle.asn1.ASN1InputStream;
15import org.bouncycastle.asn1.ASN1OutputStream;
16import org.bouncycastle.asn1.DEREncodable;
17import org.bouncycastle.asn1.DERObjectIdentifier;
18import org.bouncycastle.crypto.params.RSAKeyParameters;
19import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
20
21public class JCERSAPrivateKey
22    implements RSAPrivateKey, PKCS12BagAttributeCarrier
23{
24    protected BigInteger modulus;
25    protected BigInteger privateExponent;
26
27    private Hashtable   pkcs12Attributes = new Hashtable();
28    private Vector      pkcs12Ordering = new Vector();
29
30    protected JCERSAPrivateKey()
31    {
32    }
33
34    JCERSAPrivateKey(
35        RSAKeyParameters key)
36    {
37        this.modulus = key.getModulus();
38        this.privateExponent = key.getExponent();
39    }
40
41    JCERSAPrivateKey(
42        RSAPrivateKeySpec spec)
43    {
44        this.modulus = spec.getModulus();
45        this.privateExponent = spec.getPrivateExponent();
46    }
47
48    JCERSAPrivateKey(
49        RSAPrivateKey key)
50    {
51        this.modulus = key.getModulus();
52        this.privateExponent = key.getPrivateExponent();
53    }
54
55    public BigInteger getModulus()
56    {
57        return modulus;
58    }
59
60    public BigInteger getPrivateExponent()
61    {
62        return privateExponent;
63    }
64
65    public String getAlgorithm()
66    {
67        return "RSA";
68    }
69
70    public String getFormat()
71    {
72        return "NULL";
73    }
74
75    public byte[] getEncoded()
76    {
77        return null;
78    }
79
80    public boolean equals(Object o)
81    {
82        if (!(o instanceof RSAPrivateKey))
83        {
84            return false;
85        }
86
87        if (o == this)
88        {
89            return true;
90        }
91
92        RSAPrivateKey key = (RSAPrivateKey)o;
93
94        return getModulus().equals(key.getModulus())
95            && getPrivateExponent().equals(key.getPrivateExponent());
96    }
97
98    public int hashCode()
99    {
100        return getModulus().hashCode() ^ getPrivateExponent().hashCode();
101    }
102
103    public void setBagAttribute(
104        DERObjectIdentifier oid,
105        DEREncodable        attribute)
106    {
107        pkcs12Attributes.put(oid, attribute);
108        pkcs12Ordering.addElement(oid);
109    }
110
111    public DEREncodable getBagAttribute(
112        DERObjectIdentifier oid)
113    {
114        return (DEREncodable)pkcs12Attributes.get(oid);
115    }
116
117    public Enumeration getBagAttributeKeys()
118    {
119        return pkcs12Ordering.elements();
120    }
121
122    private void readObject(
123        ObjectInputStream   in)
124        throws IOException, ClassNotFoundException
125    {
126        this.modulus = (BigInteger)in.readObject();
127
128        Object  obj = in.readObject();
129
130        if (obj instanceof Hashtable)
131        {
132            this.pkcs12Attributes = (Hashtable)obj;
133            this.pkcs12Ordering = (Vector)in.readObject();
134        }
135        else
136        {
137            this.pkcs12Attributes = new Hashtable();
138            this.pkcs12Ordering = new Vector();
139
140            ASN1InputStream         aIn = new ASN1InputStream((byte[])obj);
141
142            DERObjectIdentifier    oid;
143
144            while ((oid = (DERObjectIdentifier)aIn.readObject()) != null)
145            {
146                this.setBagAttribute(oid, aIn.readObject());
147            }
148        }
149
150        this.privateExponent = (BigInteger)in.readObject();
151    }
152
153    private void writeObject(
154        ObjectOutputStream  out)
155        throws IOException
156    {
157        out.writeObject(modulus);
158
159        if (pkcs12Ordering.size() == 0)
160        {
161            out.writeObject(pkcs12Attributes);
162            out.writeObject(pkcs12Ordering);
163        }
164        else
165        {
166            ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
167            ASN1OutputStream        aOut = new ASN1OutputStream(bOut);
168
169            Enumeration             e = this.getBagAttributeKeys();
170
171            while (e.hasMoreElements())
172            {
173                DEREncodable    oid = (DEREncodable)e.nextElement();
174
175                aOut.writeObject(oid);
176                aOut.writeObject(pkcs12Attributes.get(oid));
177            }
178
179            out.writeObject(bOut.toByteArray());
180        }
181
182        out.writeObject(privateExponent);
183    }
184}
185