1    package org.bouncycastle.asn1.x509;
2    
3    import java.io.*;
4    import java.util.Enumeration;
5    import java.math.BigInteger;
6    
7    import org.bouncycastle.asn1.*;
8    import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
9    
10   /**
11    * The object that contains the public key stored in a certficate.
12    * <p>
13    * The getEncoded() method in the public keys in the JCE produces a DER
14    * encoded one of these.
15    */
16   public class SubjectPublicKeyInfo
17       implements DEREncodable
18   {
19       private AlgorithmIdentifier     algId;
20       private DERBitString            keyData;
21   
22       public static SubjectPublicKeyInfo getInstance(
23           ASN1TaggedObject obj,
24           boolean          explicit)
25       {
26           return getInstance(ASN1Sequence.getInstance(obj, explicit));
27       }
28   
29       public static SubjectPublicKeyInfo getInstance(
30           Object  obj)
31       {
32           if (obj instanceof SubjectPublicKeyInfo)
33           {
34               return (SubjectPublicKeyInfo)obj;
35           }
36           else if (obj instanceof ASN1Sequence)
37           {
38               return new SubjectPublicKeyInfo((ASN1Sequence)obj);
39           }
40   
41           throw new IllegalArgumentException("unknown object in factory");
42       }
43   
44       public SubjectPublicKeyInfo(
45           AlgorithmIdentifier algId,
46           DEREncodable        publicKey)
47       {
48           this.keyData = new DERBitString(publicKey);
49           this.algId = algId;
50       }
51   
52       public SubjectPublicKeyInfo(
53           AlgorithmIdentifier algId,
54           byte[]              publicKey)
55       {
56           this.keyData = new DERBitString(publicKey);
57           this.algId = algId;
58       }
59   
60       public SubjectPublicKeyInfo(
61           ASN1Sequence  seq)
62       {
63           Enumeration         e = seq.getObjects();
64   
65           this.algId = AlgorithmIdentifier.getInstance(e.nextElement());
66           this.keyData = (DERBitString)e.nextElement();
67       }
68   
69       public AlgorithmIdentifier getAlgorithmId()
70       {
71           return algId;
72       }
73   
74       /**
75        * for when the public key is an encoded object - if the bitstring
76        * can't be decoded this routine throws an IOException.
77        *
78        * @exception IOException - if the bit string doesn't represent a DER
79        * encoded object.
80        */
81       public DERObject getPublicKey()
82           throws IOException
83       {
84           ByteArrayInputStream    bIn = new ByteArrayInputStream(keyData.getBytes());
85           DERInputStream          dIn = new DERInputStream(bIn);
86   
87           return dIn.readObject();
88       }
89   
90       /**
91        * for when the public key is raw bits...
92        */
93       public DERBitString getPublicKeyData()
94       {
95           return keyData;
96       }
97   
98       /**
99        * <pre>
100       * SubjectPublicKeyInfo ::= SEQUENCE {
101       *                          algorithm AlgorithmIdentifier,
102       *                          publicKey BIT STRING }
103       * </pre>
104       */
105      public DERObject getDERObject()
106      {
107          DERConstructedSequence  seq = new DERConstructedSequence();
108  
109          seq.addObject(algId);
110          seq.addObject(keyData);
111  
112          return seq;
113      }
114  }
115