1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1.x509;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Enumeration;
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Encodable;
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1EncodableVector;
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1InputStream;
94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Object;
104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Primitive;
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Sequence;
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1TaggedObject;
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERBitString;
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERSequence;
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * The object that contains the public key stored in a certficate.
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <p>
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * The getEncoded() method in the public keys in the JCE produces a DER
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * encoded one of these.
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class SubjectPublicKeyInfo
234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    extends ASN1Object
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private AlgorithmIdentifier     algId;
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private DERBitString            keyData;
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static SubjectPublicKeyInfo getInstance(
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject obj,
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean          explicit)
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return getInstance(ASN1Sequence.getInstance(obj, explicit));
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static SubjectPublicKeyInfo getInstance(
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object  obj)
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj instanceof SubjectPublicKeyInfo)
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (SubjectPublicKeyInfo)obj;
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
426e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        else if (obj != null)
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
446e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            return new SubjectPublicKeyInfo(ASN1Sequence.getInstance(obj));
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
476e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        return null;
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public SubjectPublicKeyInfo(
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        AlgorithmIdentifier algId,
524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable       publicKey)
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.keyData = new DERBitString(publicKey);
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.algId = algId;
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public SubjectPublicKeyInfo(
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        AlgorithmIdentifier algId,
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]              publicKey)
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.keyData = new DERBitString(publicKey);
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.algId = algId;
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public SubjectPublicKeyInfo(
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1Sequence  seq)
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (seq.size() != 2)
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("Bad sequence size: "
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    + seq.size());
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Enumeration         e = seq.getObjects();
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.algId = AlgorithmIdentifier.getInstance(e.nextElement());
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.keyData = DERBitString.getInstance(e.nextElement());
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public AlgorithmIdentifier getAlgorithm()
824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return algId;
844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @deprecated use getAlgorithm()
884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @return    alg ID.
894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public AlgorithmIdentifier getAlgorithmId()
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return algId;
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * for when the public key is an encoded object - if the bitstring
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * can't be decoded this routine throws an IOException.
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IOException - if the bit string doesn't represent a DER
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * encoded object.
1014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @return the public key as an ASN.1 primitive.
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Primitive parsePublicKey()
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IOException
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1InputStream         aIn = new ASN1InputStream(keyData.getBytes());
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return aIn.readObject();
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * for when the public key is an encoded object - if the bitstring
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * can't be decoded this routine throws an IOException.
1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     *
1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @exception IOException - if the bit string doesn't represent a DER
1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * encoded object.
1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @deprecated use parsePublicKey
1184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @return the public key as an ASN.1 primitive.
1194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Primitive getPublicKey()
1214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        throws IOException
1224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1InputStream         aIn = new ASN1InputStream(keyData.getBytes());
1244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return aIn.readObject();
1264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * for when the public key is raw bits.
1304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     *
1314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @return the public key as the raw bit string...
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public DERBitString getPublicKeyData()
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return keyData;
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Produce an object suitable for an ASN1OutputStream.
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <pre>
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * SubjectPublicKeyInfo ::= SEQUENCE {
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *                          algorithm AlgorithmIdentifier,
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *                          publicKey BIT STRING }
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * </pre>
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
1464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Primitive toASN1Primitive()
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1EncodableVector  v = new ASN1EncodableVector();
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        v.add(algId);
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        v.add(keyData);
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new DERSequence(v);
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
156