1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1.pkcs;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
36e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.io.IOException;
46e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.math.BigInteger;
56e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.util.Enumeration;
66e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Encodable;
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1EncodableVector;
94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Encoding;
104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Integer;
114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Object;
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1OctetString;
134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Primitive;
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Sequence;
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Set;
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1TaggedObject;
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DEROctetString;
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERSequence;
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERTaggedObject;
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.x509.AlgorithmIdentifier;
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class PrivateKeyInfo
234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    extends ASN1Object
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private ASN1OctetString         privKey;
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private AlgorithmIdentifier     algId;
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private ASN1Set                 attributes;
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static PrivateKeyInfo getInstance(
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject obj,
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean          explicit)
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return getInstance(ASN1Sequence.getInstance(obj, explicit));
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static PrivateKeyInfo getInstance(
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object  obj)
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj instanceof PrivateKeyInfo)
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (PrivateKeyInfo)obj;
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
436e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        else if (obj != null)
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
456e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            return new PrivateKeyInfo(ASN1Sequence.getInstance(obj));
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
486e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        return null;
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public PrivateKeyInfo(
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        AlgorithmIdentifier algId,
534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable       privateKey)
544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws IOException
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        this(algId, privateKey, null);
57c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
59c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public PrivateKeyInfo(
60c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        AlgorithmIdentifier algId,
614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable       privateKey,
62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ASN1Set             attributes)
634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws IOException
64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.privKey = new DEROctetString(privateKey.toASN1Primitive().getEncoded(ASN1Encoding.DER));
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.algId = algId;
67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        this.attributes = attributes;
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public PrivateKeyInfo(
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1Sequence  seq)
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Enumeration e = seq.getObjects();
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        BigInteger  version = ((ASN1Integer)e.nextElement()).getValue();
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (version.intValue() != 0)
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("wrong version for private key info");
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        algId = AlgorithmIdentifier.getInstance(e.nextElement());
824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        privKey = ASN1OctetString.getInstance(e.nextElement());
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (e.hasMoreElements())
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam           attributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false);
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public AlgorithmIdentifier getPrivateKeyAlgorithm()
914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return algId;
934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        /**
954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom          * @deprecated use getPrivateKeyAlgorithm()
964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public AlgorithmIdentifier getAlgorithmId()
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return algId;
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
1024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Encodable parsePrivateKey()
1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws IOException
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
1054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return ASN1Primitive.fromByteArray(privKey.getOctets());
1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom          * @deprecated use parsePrivateKey()
1104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Primitive getPrivateKey()
1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        try
1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return parsePrivateKey().toASN1Primitive();
1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        catch (IOException e)
1184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            throw new IllegalStateException("unable to parse private key");
1204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public ASN1Set getAttributes()
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return attributes;
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
129c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * write out an RSA private key with its associated information
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * as described in PKCS8.
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <pre>
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *      PrivateKeyInfo ::= SEQUENCE {
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *                              version Version,
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *                              privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}},
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *                              privateKey PrivateKey,
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *                              attributes [0] IMPLICIT Attributes OPTIONAL
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *                          }
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *      Version ::= INTEGER {v1(0)} (v1,...)
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *      PrivateKey ::= OCTET STRING
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *      Attributes ::= SET OF Attribute
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * </pre>
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
1454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Primitive toASN1Primitive()
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1EncodableVector v = new ASN1EncodableVector();
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
1494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        v.add(new ASN1Integer(0));
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        v.add(algId);
1514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        v.add(privKey);
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (attributes != null)
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            v.add(new DERTaggedObject(false, 0, attributes));
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new DERSequence(v);
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
161