001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    package org.apache.geronimo.util.asn1.x509;
020    
021    import java.io.ByteArrayInputStream;
022    import java.io.IOException;
023    import java.util.Enumeration;
024    
025    import org.apache.geronimo.util.asn1.ASN1Encodable;
026    import org.apache.geronimo.util.asn1.ASN1EncodableVector;
027    import org.apache.geronimo.util.asn1.ASN1InputStream;
028    import org.apache.geronimo.util.asn1.ASN1Sequence;
029    import org.apache.geronimo.util.asn1.ASN1TaggedObject;
030    import org.apache.geronimo.util.asn1.DERBitString;
031    import org.apache.geronimo.util.asn1.DEREncodable;
032    import org.apache.geronimo.util.asn1.DERObject;
033    import org.apache.geronimo.util.asn1.DERSequence;
034    
035    /**
036     * The object that contains the public key stored in a certficate.
037     * <p>
038     * The getEncoded() method in the public keys in the JCE produces a DER
039     * encoded one of these.
040     */
041    public class SubjectPublicKeyInfo
042        extends ASN1Encodable
043    {
044        private AlgorithmIdentifier     algId;
045        private DERBitString            keyData;
046    
047        public static SubjectPublicKeyInfo getInstance(
048            ASN1TaggedObject obj,
049            boolean          explicit)
050        {
051            return getInstance(ASN1Sequence.getInstance(obj, explicit));
052        }
053    
054        public static SubjectPublicKeyInfo getInstance(
055            Object  obj)
056        {
057            if (obj instanceof SubjectPublicKeyInfo)
058            {
059                return (SubjectPublicKeyInfo)obj;
060            }
061            else if (obj instanceof ASN1Sequence)
062            {
063                return new SubjectPublicKeyInfo((ASN1Sequence)obj);
064            }
065    
066            throw new IllegalArgumentException("unknown object in factory");
067        }
068    
069        public SubjectPublicKeyInfo(
070            AlgorithmIdentifier algId,
071            DEREncodable        publicKey)
072        {
073            this.keyData = new DERBitString(publicKey);
074            this.algId = algId;
075        }
076    
077        public SubjectPublicKeyInfo(
078            AlgorithmIdentifier algId,
079            byte[]              publicKey)
080        {
081            this.keyData = new DERBitString(publicKey);
082            this.algId = algId;
083        }
084    
085        public SubjectPublicKeyInfo(
086            ASN1Sequence  seq)
087        {
088            Enumeration         e = seq.getObjects();
089    
090            this.algId = AlgorithmIdentifier.getInstance(e.nextElement());
091            this.keyData = (DERBitString)e.nextElement();
092        }
093    
094        public AlgorithmIdentifier getAlgorithmId()
095        {
096            return algId;
097        }
098    
099        /**
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         */
106        public DERObject getPublicKey()
107            throws IOException
108        {
109            ByteArrayInputStream    bIn = new ByteArrayInputStream(keyData.getBytes());
110            ASN1InputStream         aIn = new ASN1InputStream(bIn);
111    
112            return aIn.readObject();
113        }
114    
115        /**
116         * for when the public key is raw bits...
117         */
118        public DERBitString getPublicKeyData()
119        {
120            return keyData;
121        }
122    
123        /**
124         * Produce an object suitable for an ASN1OutputStream.
125         * <pre>
126         * SubjectPublicKeyInfo ::= SEQUENCE {
127         *                          algorithm AlgorithmIdentifier,
128         *                          publicKey BIT STRING }
129         * </pre>
130         */
131        public DERObject toASN1Object()
132        {
133            ASN1EncodableVector  v = new ASN1EncodableVector();
134    
135            v.add(algId);
136            v.add(keyData);
137    
138            return new DERSequence(v);
139        }
140    }