001package org.apache.commons.ssl.org.bouncycastle.asn1.pkcs;
002
003import java.io.IOException;
004import java.math.BigInteger;
005import java.util.Enumeration;
006
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encoding;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer;
011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
012import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1OctetString;
013import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
014import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
015import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Set;
016import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
017import org.apache.commons.ssl.org.bouncycastle.asn1.DEROctetString;
018import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
019import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
020import org.apache.commons.ssl.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
021
022public class PrivateKeyInfo
023    extends ASN1Object
024{
025    private ASN1OctetString         privKey;
026    private AlgorithmIdentifier     algId;
027    private ASN1Set                 attributes;
028
029    public static PrivateKeyInfo getInstance(
030        ASN1TaggedObject obj,
031        boolean          explicit)
032    {
033        return getInstance(ASN1Sequence.getInstance(obj, explicit));
034    }
035
036    public static PrivateKeyInfo getInstance(
037        Object  obj)
038    {
039        if (obj instanceof PrivateKeyInfo)
040        {
041            return (PrivateKeyInfo)obj;
042        }
043        else if (obj != null)
044        {
045            return new PrivateKeyInfo(ASN1Sequence.getInstance(obj));
046        }
047
048        return null;
049    }
050        
051    public PrivateKeyInfo(
052        AlgorithmIdentifier algId,
053        ASN1Encodable       privateKey)
054        throws IOException
055    {
056        this(algId, privateKey, null);
057    }
058
059    public PrivateKeyInfo(
060        AlgorithmIdentifier algId,
061        ASN1Encodable       privateKey,
062        ASN1Set             attributes)
063        throws IOException
064    {
065        this.privKey = new DEROctetString(privateKey.toASN1Primitive().getEncoded(ASN1Encoding.DER));
066        this.algId = algId;
067        this.attributes = attributes;
068    }
069
070    /**
071     * @deprecated use PrivateKeyInfo.getInstance()
072     * @param seq
073     */
074    public PrivateKeyInfo(
075        ASN1Sequence  seq)
076    {
077        Enumeration e = seq.getObjects();
078
079        BigInteger  version = ((ASN1Integer)e.nextElement()).getValue();
080        if (version.intValue() != 0)
081        {
082            throw new IllegalArgumentException("wrong version for private key info");
083        }
084
085        algId = AlgorithmIdentifier.getInstance(e.nextElement());
086        privKey = ASN1OctetString.getInstance(e.nextElement());
087        
088        if (e.hasMoreElements())
089        {
090           attributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false);
091        }
092    }
093
094    public AlgorithmIdentifier getPrivateKeyAlgorithm()
095    {
096        return algId;
097    }
098        /**
099          * @deprecated use getPrivateKeyAlgorithm()
100     */
101    public AlgorithmIdentifier getAlgorithmId()
102    {
103        return algId;
104    }
105
106    public ASN1Encodable parsePrivateKey()
107        throws IOException
108    {
109        return ASN1Primitive.fromByteArray(privKey.getOctets());
110    }
111
112    /**
113          * @deprecated use parsePrivateKey()
114     */
115    public ASN1Primitive getPrivateKey()
116    {
117        try
118        {
119            return parsePrivateKey().toASN1Primitive();
120        }
121        catch (IOException e)
122        {
123            throw new IllegalStateException("unable to parse private key");
124        }
125    }
126    
127    public ASN1Set getAttributes()
128    {
129        return attributes;
130    }
131
132    /**
133     * write out an RSA private key with its associated information
134     * as described in PKCS8.
135     * <pre>
136     *      PrivateKeyInfo ::= SEQUENCE {
137     *                              version Version,
138     *                              privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
139     *                              privateKey PrivateKey,
140     *                              attributes [0] IMPLICIT Attributes OPTIONAL 
141     *                          }
142     *      Version ::= INTEGER {v1(0)} (v1,...)
143     *
144     *      PrivateKey ::= OCTET STRING
145     *
146     *      Attributes ::= SET OF Attribute
147     * </pre>
148     */
149    public ASN1Primitive toASN1Primitive()
150    {
151        ASN1EncodableVector v = new ASN1EncodableVector();
152
153        v.add(new ASN1Integer(0));
154        v.add(algId);
155        v.add(privKey);
156
157        if (attributes != null)
158        {
159            v.add(new DERTaggedObject(false, 0, attributes));
160        }
161        
162        return new DERSequence(v);
163    }
164}