• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.asn1;
2 
3 import java.io.IOException;
4 import java.io.OutputStream;
5 
6 /**
7  * Stream that produces output based on the default encoding for the passed in objects.
8  */
9 public class ASN1OutputStream
10 {
11     private OutputStream os;
12 
ASN1OutputStream( OutputStream os)13     public ASN1OutputStream(
14         OutputStream    os)
15     {
16         this.os = os;
17     }
18 
writeLength( int length)19     void writeLength(
20         int length)
21         throws IOException
22     {
23         if (length > 127)
24         {
25             int size = 1;
26             int val = length;
27 
28             while ((val >>>= 8) != 0)
29             {
30                 size++;
31             }
32 
33             write((byte)(size | 0x80));
34 
35             for (int i = (size - 1) * 8; i >= 0; i -= 8)
36             {
37                 write((byte)(length >> i));
38             }
39         }
40         else
41         {
42             write((byte)length);
43         }
44     }
45 
write(int b)46     void write(int b)
47         throws IOException
48     {
49         os.write(b);
50     }
51 
write(byte[] bytes)52     void write(byte[] bytes)
53         throws IOException
54     {
55         os.write(bytes);
56     }
57 
write(byte[] bytes, int off, int len)58     void write(byte[] bytes, int off, int len)
59         throws IOException
60     {
61         os.write(bytes, off, len);
62     }
63 
writeEncoded( int tag, byte[] bytes)64     void writeEncoded(
65         int     tag,
66         byte[]  bytes)
67         throws IOException
68     {
69         write(tag);
70         writeLength(bytes.length);
71         write(bytes);
72     }
73 
writeTag(int flags, int tagNo)74     void writeTag(int flags, int tagNo)
75         throws IOException
76     {
77         if (tagNo < 31)
78         {
79             write(flags | tagNo);
80         }
81         else
82         {
83             write(flags | 0x1f);
84             if (tagNo < 128)
85             {
86                 write(tagNo);
87             }
88             else
89             {
90                 byte[] stack = new byte[5];
91                 int pos = stack.length;
92 
93                 stack[--pos] = (byte)(tagNo & 0x7F);
94 
95                 do
96                 {
97                     tagNo >>= 7;
98                     stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
99                 }
100                 while (tagNo > 127);
101 
102                 write(stack, pos, stack.length - pos);
103             }
104         }
105     }
106 
writeEncoded(int flags, int tagNo, byte[] bytes)107     void writeEncoded(int flags, int tagNo, byte[] bytes)
108         throws IOException
109     {
110         writeTag(flags, tagNo);
111         writeLength(bytes.length);
112         write(bytes);
113     }
114 
writeNull()115     protected void writeNull()
116         throws IOException
117     {
118         os.write(BERTags.NULL);
119         os.write(0x00);
120     }
121 
writeObject( ASN1Encodable obj)122     public void writeObject(
123         ASN1Encodable obj)
124         throws IOException
125     {
126         if (obj != null)
127         {
128             obj.toASN1Primitive().encode(this);
129         }
130         else
131         {
132             throw new IOException("null object detected");
133         }
134     }
135 
writeImplicitObject(ASN1Primitive obj)136     void writeImplicitObject(ASN1Primitive obj)
137         throws IOException
138     {
139         if (obj != null)
140         {
141             obj.encode(new ImplicitOutputStream(os));
142         }
143         else
144         {
145             throw new IOException("null object detected");
146         }
147     }
148 
close()149     public void close()
150         throws IOException
151     {
152         os.close();
153     }
154 
flush()155     public void flush()
156         throws IOException
157     {
158         os.flush();
159     }
160 
getDERSubStream()161     ASN1OutputStream getDERSubStream()
162     {
163         return new DEROutputStream(os);
164     }
165 
getDLSubStream()166     ASN1OutputStream getDLSubStream()
167     {
168         return new DLOutputStream(os);
169     }
170 
171     private class ImplicitOutputStream
172         extends ASN1OutputStream
173     {
174         private boolean first = true;
175 
ImplicitOutputStream(OutputStream os)176         public ImplicitOutputStream(OutputStream os)
177         {
178             super(os);
179         }
180 
write(int b)181         public void write(int b)
182             throws IOException
183         {
184             if (first)
185             {
186                 first = false;
187             }
188             else
189             {
190                 super.write(b);
191             }
192         }
193     }
194 }
195