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