001package org.apache.commons.ssl.org.bouncycastle.asn1.pkcs;
002
003import java.math.BigInteger;
004import java.util.Enumeration;
005
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
012import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
013
014public class RSAPrivateKey
015    extends ASN1Object
016{
017    private BigInteger version;
018    private BigInteger modulus;
019    private BigInteger publicExponent;
020    private BigInteger privateExponent;
021    private BigInteger prime1;
022    private BigInteger prime2;
023    private BigInteger exponent1;
024    private BigInteger exponent2;
025    private BigInteger coefficient;
026    private ASN1Sequence otherPrimeInfos = null;
027
028    public static RSAPrivateKey getInstance(
029        ASN1TaggedObject obj,
030        boolean          explicit)
031    {
032        return getInstance(ASN1Sequence.getInstance(obj, explicit));
033    }
034
035    public static RSAPrivateKey getInstance(
036        Object obj)
037    {
038        if (obj instanceof RSAPrivateKey)
039        {
040            return (RSAPrivateKey)obj;
041        }
042
043        if (obj != null)
044        {
045            return new RSAPrivateKey(ASN1Sequence.getInstance(obj));
046        }
047
048        return null;
049    }
050    
051    public RSAPrivateKey(
052        BigInteger modulus,
053        BigInteger publicExponent,
054        BigInteger privateExponent,
055        BigInteger prime1,
056        BigInteger prime2,
057        BigInteger exponent1,
058        BigInteger exponent2,
059        BigInteger coefficient)
060    {
061        this.version = BigInteger.valueOf(0);
062        this.modulus = modulus;
063        this.publicExponent = publicExponent;
064        this.privateExponent = privateExponent;
065        this.prime1 = prime1;
066        this.prime2 = prime2;
067        this.exponent1 = exponent1;
068        this.exponent2 = exponent2;
069        this.coefficient = coefficient;
070    }
071
072    private RSAPrivateKey(
073        ASN1Sequence seq)
074    {
075        Enumeration e = seq.getObjects();
076
077        BigInteger v = ((ASN1Integer)e.nextElement()).getValue();
078        if (v.intValue() != 0 && v.intValue() != 1)
079        {
080            throw new IllegalArgumentException("wrong version for RSA private key");
081        }
082
083        version = v;
084        modulus = ((ASN1Integer)e.nextElement()).getValue();
085        publicExponent = ((ASN1Integer)e.nextElement()).getValue();
086        privateExponent = ((ASN1Integer)e.nextElement()).getValue();
087        prime1 = ((ASN1Integer)e.nextElement()).getValue();
088        prime2 = ((ASN1Integer)e.nextElement()).getValue();
089        exponent1 = ((ASN1Integer)e.nextElement()).getValue();
090        exponent2 = ((ASN1Integer)e.nextElement()).getValue();
091        coefficient = ((ASN1Integer)e.nextElement()).getValue();
092        
093        if (e.hasMoreElements())
094        {
095            otherPrimeInfos = (ASN1Sequence)e.nextElement();
096        }
097    }
098
099    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}