001    package org.apache.commons.ssl.asn1;
002    
003    import java.io.ByteArrayOutputStream;
004    import java.io.IOException;
005    
006    /**
007     * DER TaggedObject - in ASN.1 nottation this is any object proceeded by
008     * a [n] where n is some number - these are assume to follow the construction
009     * rules (as with sequences).
010     */
011    public class DERTaggedObject
012        extends ASN1TaggedObject {
013        /**
014         * @param tagNo the tag number for this object.
015         * @param obj   the tagged object.
016         */
017        public DERTaggedObject(
018            int tagNo,
019            DEREncodable obj) {
020            super(tagNo, obj);
021        }
022    
023        /**
024         * @param explicit true if an explicitly tagged object.
025         * @param tagNo    the tag number for this object.
026         * @param obj      the tagged object.
027         */
028        public DERTaggedObject(
029            boolean explicit,
030            int tagNo,
031            DEREncodable obj) {
032            super(explicit, tagNo, obj);
033        }
034    
035        /**
036         * create an implicitly tagged object that contains a zero
037         * length sequence.
038         */
039        public DERTaggedObject(
040            int tagNo) {
041            super(false, tagNo, new DERSequence());
042        }
043    
044        void encode(
045            DEROutputStream out)
046            throws IOException {
047            if (!empty) {
048                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
049                DEROutputStream dOut = new DEROutputStream(bOut);
050    
051                dOut.writeObject(obj);
052                dOut.close();
053    
054                byte[] bytes = bOut.toByteArray();
055    
056                if (explicit) {
057                    out.writeEncoded(CONSTRUCTED | TAGGED | tagNo, bytes);
058                } else {
059                    //
060                    // need to mark constructed types...
061                    //
062                    if ((bytes[0] & CONSTRUCTED) != 0) {
063                        bytes[0] = (byte) (CONSTRUCTED | TAGGED | tagNo);
064                    } else {
065                        bytes[0] = (byte) (TAGGED | tagNo);
066                    }
067    
068                    out.write(bytes);
069                }
070            } else {
071                out.writeEncoded(CONSTRUCTED | TAGGED | tagNo, new byte[0]);
072            }
073        }
074    }