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;
020    
021    import java.io.ByteArrayOutputStream;
022    import java.io.IOException;
023    import java.util.Enumeration;
024    
025    /**
026     * A DER encoded set object
027     */
028    public class DERSet
029        extends ASN1Set
030    {
031        /**
032         * create an empty set
033         */
034        public DERSet()
035        {
036        }
037    
038        /**
039         * @param obj - a single object that makes up the set.
040         */
041        public DERSet(
042            DEREncodable   obj)
043        {
044            this.addObject(obj);
045        }
046    
047        /**
048         * @param v - a vector of objects making up the set.
049         */
050        public DERSet(
051            DEREncodableVector   v)
052        {
053            this(v, true);
054        }
055    
056        /**
057         * create a set from an array of objects.
058         */
059        public DERSet(
060            ASN1Encodable[]   a)
061        {
062            for (int i = 0; i != a.length; i++)
063            {
064                this.addObject(a[i]);
065            }
066    
067            this.sort();
068        }
069    
070        /**
071         * @param v - a vector of objects making up the set.
072         */
073        DERSet(
074            DEREncodableVector   v,
075            boolean              needsSorting)
076        {
077            for (int i = 0; i != v.size(); i++)
078            {
079                this.addObject(v.get(i));
080            }
081    
082            if (needsSorting)
083            {
084                this.sort();
085            }
086        }
087    
088        /*
089         * A note on the implementation:
090         * <p>
091         * As DER requires the constructed, definite-length model to
092         * be used for structured types, this varies slightly from the
093         * ASN.1 descriptions given. Rather than just outputing SET,
094         * we also have to specify CONSTRUCTED, and the objects length.
095         */
096        void encode(
097            DEROutputStream out)
098            throws IOException
099        {
100            ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
101            DEROutputStream         dOut = new DEROutputStream(bOut);
102            Enumeration             e = this.getObjects();
103    
104            while (e.hasMoreElements())
105            {
106                Object    obj = e.nextElement();
107    
108                dOut.writeObject(obj);
109            }
110    
111            dOut.close();
112    
113            byte[]  bytes = bOut.toByteArray();
114    
115            out.writeEncoded(SET | CONSTRUCTED, bytes);
116        }
117    }