1package org.bouncycastle.asn1.x509;
2
3import java.io.IOException;
4import java.util.Enumeration;
5
6import org.bouncycastle.asn1.ASN1Encodable;
7import org.bouncycastle.asn1.ASN1EncodableVector;
8import org.bouncycastle.asn1.ASN1InputStream;
9import org.bouncycastle.asn1.ASN1Object;
10import org.bouncycastle.asn1.ASN1Primitive;
11import org.bouncycastle.asn1.ASN1Sequence;
12import org.bouncycastle.asn1.ASN1TaggedObject;
13import org.bouncycastle.asn1.DERBitString;
14import org.bouncycastle.asn1.DERSequence;
15
16/**
17 * The object that contains the public key stored in a certficate.
18 * <p>
19 * The getEncoded() method in the public keys in the JCE produces a DER
20 * encoded one of these.
21 */
22public class SubjectPublicKeyInfo
23    extends ASN1Object
24{
25    private AlgorithmIdentifier     algId;
26    private DERBitString            keyData;
27
28    public static SubjectPublicKeyInfo getInstance(
29        ASN1TaggedObject obj,
30        boolean          explicit)
31    {
32        return getInstance(ASN1Sequence.getInstance(obj, explicit));
33    }
34
35    public static SubjectPublicKeyInfo getInstance(
36        Object  obj)
37    {
38        if (obj instanceof SubjectPublicKeyInfo)
39        {
40            return (SubjectPublicKeyInfo)obj;
41        }
42        else if (obj != null)
43        {
44            return new SubjectPublicKeyInfo(ASN1Sequence.getInstance(obj));
45        }
46
47        return null;
48    }
49
50    public SubjectPublicKeyInfo(
51        AlgorithmIdentifier algId,
52        ASN1Encodable       publicKey)
53        throws IOException
54    {
55        this.keyData = new DERBitString(publicKey);
56        this.algId = algId;
57    }
58
59    public SubjectPublicKeyInfo(
60        AlgorithmIdentifier algId,
61        byte[]              publicKey)
62    {
63        this.keyData = new DERBitString(publicKey);
64        this.algId = algId;
65    }
66
67    /**
68     @deprecated use SubjectPublicKeyInfo.getInstance()
69     */
70    public SubjectPublicKeyInfo(
71        ASN1Sequence  seq)
72    {
73        if (seq.size() != 2)
74        {
75            throw new IllegalArgumentException("Bad sequence size: "
76                    + seq.size());
77        }
78
79        Enumeration         e = seq.getObjects();
80
81        this.algId = AlgorithmIdentifier.getInstance(e.nextElement());
82        this.keyData = DERBitString.getInstance(e.nextElement());
83    }
84
85    public AlgorithmIdentifier getAlgorithm()
86    {
87        return algId;
88    }
89
90    /**
91     * @deprecated use getAlgorithm()
92     * @return    alg ID.
93     */
94    public AlgorithmIdentifier getAlgorithmId()
95    {
96        return algId;
97    }
98
99    /**
100     * for when the public key is an encoded object - if the bitstring
101     * can't be decoded this routine throws an IOException.
102     *
103     * @exception IOException - if the bit string doesn't represent a DER
104     * encoded object.
105     * @return the public key as an ASN.1 primitive.
106     */
107    public ASN1Primitive parsePublicKey()
108        throws IOException
109    {
110        ASN1InputStream         aIn = new ASN1InputStream(keyData.getOctets());
111
112        return aIn.readObject();
113    }
114
115    /**
116     * for when the public key is an encoded object - if the bitstring
117     * can't be decoded this routine throws an IOException.
118     *
119     * @exception IOException - if the bit string doesn't represent a DER
120     * encoded object.
121     * @deprecated use parsePublicKey
122     * @return the public key as an ASN.1 primitive.
123     */
124    public ASN1Primitive getPublicKey()
125        throws IOException
126    {
127        ASN1InputStream         aIn = new ASN1InputStream(keyData.getOctets());
128
129        return aIn.readObject();
130    }
131
132    /**
133     * for when the public key is raw bits.
134     *
135     * @return the public key as the raw bit string...
136     */
137    public DERBitString getPublicKeyData()
138    {
139        return keyData;
140    }
141
142    /**
143     * Produce an object suitable for an ASN1OutputStream.
144     * <pre>
145     * SubjectPublicKeyInfo ::= SEQUENCE {
146     *                          algorithm AlgorithmIdentifier,
147     *                          publicKey BIT STRING }
148     * </pre>
149     */
150    public ASN1Primitive toASN1Primitive()
151    {
152        ASN1EncodableVector  v = new ASN1EncodableVector();
153
154        v.add(algId);
155        v.add(keyData);
156
157        return new DERSequence(v);
158    }
159}
160