001package org.apache.commons.ssl.org.bouncycastle.asn1.x509;
002
003import java.io.IOException;
004import java.util.Enumeration;
005
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1InputStream;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
012import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
013import org.apache.commons.ssl.org.bouncycastle.asn1.DERBitString;
014import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
015
016/**
017 * The object that contains the public key stored in a certficate.
018 * <p>
019 * The getEncoded() method in the public keys in the JCE produces a DER
020 * encoded one of these.
021 */
022public class SubjectPublicKeyInfo
023    extends ASN1Object
024{
025    private AlgorithmIdentifier     algId;
026    private DERBitString            keyData;
027
028    public static SubjectPublicKeyInfo getInstance(
029        ASN1TaggedObject obj,
030        boolean          explicit)
031    {
032        return getInstance(ASN1Sequence.getInstance(obj, explicit));
033    }
034
035    public static SubjectPublicKeyInfo getInstance(
036        Object  obj)
037    {
038        if (obj instanceof SubjectPublicKeyInfo)
039        {
040            return (SubjectPublicKeyInfo)obj;
041        }
042        else if (obj != null)
043        {
044            return new SubjectPublicKeyInfo(ASN1Sequence.getInstance(obj));
045        }
046
047        return null;
048    }
049
050    public SubjectPublicKeyInfo(
051        AlgorithmIdentifier algId,
052        ASN1Encodable       publicKey)
053        throws IOException
054    {
055        this.keyData = new DERBitString(publicKey);
056        this.algId = algId;
057    }
058
059    public SubjectPublicKeyInfo(
060        AlgorithmIdentifier algId,
061        byte[]              publicKey)
062    {
063        this.keyData = new DERBitString(publicKey);
064        this.algId = algId;
065    }
066
067    public SubjectPublicKeyInfo(
068        ASN1Sequence  seq)
069    {
070        if (seq.size() != 2)
071        {
072            throw new IllegalArgumentException("Bad sequence size: "
073                    + seq.size());
074        }
075
076        Enumeration         e = seq.getObjects();
077
078        this.algId = AlgorithmIdentifier.getInstance(e.nextElement());
079        this.keyData = DERBitString.getInstance(e.nextElement());
080    }
081
082    public AlgorithmIdentifier getAlgorithm()
083    {
084        return algId;
085    }
086
087    /**
088     * @deprecated use getAlgorithm()
089     * @return    alg ID.
090     */
091    public AlgorithmIdentifier getAlgorithmId()
092    {
093        return algId;
094    }
095
096    /**
097     * for when the public key is an encoded object - if the bitstring
098     * can't be decoded this routine throws an IOException.
099     *
100     * @exception IOException - if the bit string doesn't represent a DER
101     * encoded object.
102     * @return the public key as an ASN.1 primitive.
103     */
104    public ASN1Primitive parsePublicKey()
105        throws IOException
106    {
107        ASN1InputStream         aIn = new ASN1InputStream(keyData.getBytes());
108
109        return aIn.readObject();
110    }
111
112    /**
113     * for when the public key is an encoded object - if the bitstring
114     * can't be decoded this routine throws an IOException.
115     *
116     * @exception IOException - if the bit string doesn't represent a DER
117     * encoded object.
118     * @deprecated use parsePublicKey
119     * @return the public key as an ASN.1 primitive.
120     */
121    public ASN1Primitive getPublicKey()
122        throws IOException
123    {
124        ASN1InputStream         aIn = new ASN1InputStream(keyData.getBytes());
125
126        return aIn.readObject();
127    }
128
129    /**
130     * for when the public key is raw bits.
131     *
132     * @return the public key as the raw bit string...
133     */
134    public DERBitString getPublicKeyData()
135    {
136        return keyData;
137    }
138
139    /**
140     * Produce an object suitable for an ASN1OutputStream.
141     * <pre>
142     * SubjectPublicKeyInfo ::= SEQUENCE {
143     *                          algorithm AlgorithmIdentifier,
144     *                          publicKey BIT STRING }
145     * </pre>
146     */
147    public ASN1Primitive toASN1Primitive()
148    {
149        ASN1EncodableVector  v = new ASN1EncodableVector();
150
151        v.add(algId);
152        v.add(keyData);
153
154        return new DERSequence(v);
155    }
156}