1package org.bouncycastle.asn1.pkcs;
2
3import java.math.BigInteger;
4import java.util.Enumeration;
5
6import org.bouncycastle.asn1.ASN1EncodableVector;
7import org.bouncycastle.asn1.ASN1Integer;
8import org.bouncycastle.asn1.ASN1Object;
9import org.bouncycastle.asn1.ASN1Primitive;
10import org.bouncycastle.asn1.ASN1Sequence;
11import org.bouncycastle.asn1.ASN1TaggedObject;
12import org.bouncycastle.asn1.DERSequence;
13
14public class RSAPrivateKey
15    extends ASN1Object
16{
17    private BigInteger version;
18    private BigInteger modulus;
19    private BigInteger publicExponent;
20    private BigInteger privateExponent;
21    private BigInteger prime1;
22    private BigInteger prime2;
23    private BigInteger exponent1;
24    private BigInteger exponent2;
25    private BigInteger coefficient;
26    private ASN1Sequence otherPrimeInfos = null;
27
28    public static RSAPrivateKey getInstance(
29        ASN1TaggedObject obj,
30        boolean          explicit)
31    {
32        return getInstance(ASN1Sequence.getInstance(obj, explicit));
33    }
34
35    public static RSAPrivateKey getInstance(
36        Object obj)
37    {
38        if (obj instanceof RSAPrivateKey)
39        {
40            return (RSAPrivateKey)obj;
41        }
42
43        if (obj != null)
44        {
45            return new RSAPrivateKey(ASN1Sequence.getInstance(obj));
46        }
47
48        return null;
49    }
50
51    public RSAPrivateKey(
52        BigInteger modulus,
53        BigInteger publicExponent,
54        BigInteger privateExponent,
55        BigInteger prime1,
56        BigInteger prime2,
57        BigInteger exponent1,
58        BigInteger exponent2,
59        BigInteger coefficient)
60    {
61        this.version = BigInteger.valueOf(0);
62        this.modulus = modulus;
63        this.publicExponent = publicExponent;
64        this.privateExponent = privateExponent;
65        this.prime1 = prime1;
66        this.prime2 = prime2;
67        this.exponent1 = exponent1;
68        this.exponent2 = exponent2;
69        this.coefficient = coefficient;
70    }
71
72    private RSAPrivateKey(
73        ASN1Sequence seq)
74    {
75        Enumeration e = seq.getObjects();
76
77        BigInteger v = ((ASN1Integer)e.nextElement()).getValue();
78        if (v.intValue() != 0 && v.intValue() != 1)
79        {
80            throw new IllegalArgumentException("wrong version for RSA private key");
81        }
82
83        version = v;
84        modulus = ((ASN1Integer)e.nextElement()).getValue();
85        publicExponent = ((ASN1Integer)e.nextElement()).getValue();
86        privateExponent = ((ASN1Integer)e.nextElement()).getValue();
87        prime1 = ((ASN1Integer)e.nextElement()).getValue();
88        prime2 = ((ASN1Integer)e.nextElement()).getValue();
89        exponent1 = ((ASN1Integer)e.nextElement()).getValue();
90        exponent2 = ((ASN1Integer)e.nextElement()).getValue();
91        coefficient = ((ASN1Integer)e.nextElement()).getValue();
92
93        if (e.hasMoreElements())
94        {
95            otherPrimeInfos = (ASN1Sequence)e.nextElement();
96        }
97    }
98
99    public BigInteger getVersion()
100    {
101        return version;
102    }
103
104    public BigInteger getModulus()
105    {
106        return modulus;
107    }
108
109    public BigInteger getPublicExponent()
110    {
111        return publicExponent;
112    }
113
114    public BigInteger getPrivateExponent()
115    {
116        return privateExponent;
117    }
118
119    public BigInteger getPrime1()
120    {
121        return prime1;
122    }
123
124    public BigInteger getPrime2()
125    {
126        return prime2;
127    }
128
129    public BigInteger getExponent1()
130    {
131        return exponent1;
132    }
133
134    public BigInteger getExponent2()
135    {
136        return exponent2;
137    }
138
139    public BigInteger getCoefficient()
140    {
141        return coefficient;
142    }
143
144    /**
145     * This outputs the key in PKCS1v2 format.
146     * <pre>
147     *      RSAPrivateKey ::= SEQUENCE {
148     *                          version Version,
149     *                          modulus INTEGER, -- n
150     *                          publicExponent INTEGER, -- e
151     *                          privateExponent INTEGER, -- d
152     *                          prime1 INTEGER, -- p
153     *                          prime2 INTEGER, -- q
154     *                          exponent1 INTEGER, -- d mod (p-1)
155     *                          exponent2 INTEGER, -- d mod (q-1)
156     *                          coefficient INTEGER, -- (inverse of q) mod p
157     *                          otherPrimeInfos OtherPrimeInfos OPTIONAL
158     *                      }
159     *
160     *      Version ::= INTEGER { two-prime(0), multi(1) }
161     *        (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})
162     * </pre>
163     * <p>
164     * This routine is written to output PKCS1 version 2.1, private keys.
165     */
166    public ASN1Primitive toASN1Primitive()
167    {
168        ASN1EncodableVector v = new ASN1EncodableVector();
169
170        v.add(new ASN1Integer(version));                       // version
171        v.add(new ASN1Integer(getModulus()));
172        v.add(new ASN1Integer(getPublicExponent()));
173        v.add(new ASN1Integer(getPrivateExponent()));
174        v.add(new ASN1Integer(getPrime1()));
175        v.add(new ASN1Integer(getPrime2()));
176        v.add(new ASN1Integer(getExponent1()));
177        v.add(new ASN1Integer(getExponent2()));
178        v.add(new ASN1Integer(getCoefficient()));
179
180        if (otherPrimeInfos != null)
181        {
182            v.add(otherPrimeInfos);
183        }
184
185        return new DERSequence(v);
186    }
187}
188