001package org.apache.commons.ssl.asn1;
002
003import java.io.ByteArrayOutputStream;
004import 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 */
011public 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}