• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.asn1;
2 
3 import java.io.IOException;
4 
5 /**
6  * DER TaggedObject - in ASN.1 notation this is any object preceded by
7  * a [n] where n is some number - these are assumed to follow the construction
8  * rules (as with sequences).
9  */
10 public class DERTaggedObject
11     extends ASN1TaggedObject
12 {
13     private static final byte[] ZERO_BYTES = new byte[0];
14 
15     /**
16      * @param explicit true if an explicitly tagged object.
17      * @param tagNo the tag number for this object.
18      * @param obj the tagged object.
19      */
DERTaggedObject( boolean explicit, int tagNo, ASN1Encodable obj)20     public DERTaggedObject(
21         boolean       explicit,
22         int           tagNo,
23         ASN1Encodable obj)
24     {
25         super(explicit, tagNo, obj);
26     }
27 
DERTaggedObject(int tagNo, ASN1Encodable encodable)28     public DERTaggedObject(int tagNo, ASN1Encodable encodable)
29     {
30         super(true, tagNo, encodable);
31     }
32 
isConstructed()33     boolean isConstructed()
34     {
35         if (!empty)
36         {
37             if (explicit)
38             {
39                 return true;
40             }
41             else
42             {
43                 ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
44 
45                 return primitive.isConstructed();
46             }
47         }
48         else
49         {
50             return true;
51         }
52     }
53 
encodedLength()54     int encodedLength()
55         throws IOException
56     {
57         if (!empty)
58         {
59             ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
60             int length = primitive.encodedLength();
61 
62             if (explicit)
63             {
64                 return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
65             }
66             else
67             {
68                 // header length already in calculation
69                 length = length - 1;
70 
71                 return StreamUtil.calculateTagLength(tagNo) + length;
72             }
73         }
74         else
75         {
76             return StreamUtil.calculateTagLength(tagNo) + 1;
77         }
78     }
79 
encode( ASN1OutputStream out)80     void encode(
81         ASN1OutputStream out)
82         throws IOException
83     {
84         if (!empty)
85         {
86             ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
87 
88             if (explicit)
89             {
90                 out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
91                 out.writeLength(primitive.encodedLength());
92                 out.writeObject(primitive);
93             }
94             else
95             {
96                 //
97                 // need to mark constructed types...
98                 //
99                 int flags;
100                 if (primitive.isConstructed())
101                 {
102                     flags = BERTags.CONSTRUCTED | BERTags.TAGGED;
103                 }
104                 else
105                 {
106                     flags = BERTags.TAGGED;
107                 }
108 
109                 out.writeTag(flags, tagNo);
110                 out.writeImplicitObject(primitive);
111             }
112         }
113         else
114         {
115             out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES);
116         }
117     }
118 }
119