1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1.util;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.IOException;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Enumeration;
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
64c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Encodable;
74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Integer;
84c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1ObjectIdentifier;
9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.ASN1OctetString;
104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Primitive;
11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.ASN1Sequence;
12c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.ASN1Set;
13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.BERApplicationSpecific;
14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.BERConstructedOctetString;
15c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.BERSequence;
16c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.BERSet;
17c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.BERTaggedObject;
184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.BERTags;
19c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERApplicationSpecific;
20c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERBMPString;
21c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERBitString;
22c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERBoolean;
23c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DEREnumerated;
24c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERExternal;
25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERGeneralizedTime;
26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERIA5String;
27c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERNull;
28c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DEROctetString;
29c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERPrintableString;
30c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERSequence;
31c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERSet;
32c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERT61String;
33c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERTaggedObject;
34c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERUTCTime;
35c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERUTF8String;
36c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERVisibleString;
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.util.encoders.Hex;
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class ASN1Dump
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
41c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final String  TAB = "    ";
42c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final int SAMPLE_SIZE = 32;
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * dump a DER object as a formatted string with indentation
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @param obj the ASN1Primitive to be dumped out.
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
49c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    static void _dumpAsString(
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String      indent,
51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        boolean     verbose,
524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Primitive obj,
53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer    buf)
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
55c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        String nl = System.getProperty("line.separator");
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj instanceof ASN1Sequence)
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            Enumeration     e = ((ASN1Sequence)obj).getObjects();
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            String          tab = indent + TAB;
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(indent);
626e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            if (obj instanceof BERSequence)
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("BER Sequence");
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else if (obj instanceof DERSequence)
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("DER Sequence");
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("Sequence");
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(nl);
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            while (e.hasMoreElements())
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                Object  o = e.nextElement();
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                // BEGIN android-changed
82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (o == null || o.equals(DERNull.INSTANCE))
83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                // END android-changed
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append(tab);
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append("NULL");
87c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    buf.append(nl);
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                else if (o instanceof ASN1Primitive)
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    _dumpAsString(tab, verbose, (ASN1Primitive)o, buf);
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    _dumpAsString(tab, verbose, ((ASN1Encodable)o).toASN1Primitive(), buf);
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERTaggedObject)
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            String          tab = indent + TAB;
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(indent);
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (obj instanceof BERTaggedObject)
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("BER Tagged [");
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("Tagged [");
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            DERTaggedObject o = (DERTaggedObject)obj;
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(Integer.toString(o.getTagNo()));
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(']');
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (!o.isExplicit())
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append(" IMPLICIT ");
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
123c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(nl);
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (o.isEmpty())
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append(tab);
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("EMPTY");
129c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
133c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                _dumpAsString(tab, verbose, o.getObject(), buf);
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof BERSet)
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            Enumeration     e = ((ASN1Set)obj).getObjects();
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            String          tab = indent + TAB;
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(indent);
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append("BER Set");
143c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(nl);
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            while (e.hasMoreElements())
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                Object  o = e.nextElement();
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (o == null)
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append(tab);
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append("NULL");
153c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    buf.append(nl);
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
1554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                else if (o instanceof ASN1Primitive)
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
1574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    _dumpAsString(tab, verbose, (ASN1Primitive)o, buf);
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
1614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    _dumpAsString(tab, verbose, ((ASN1Encodable)o).toASN1Primitive(), buf);
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERSet)
166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            Enumeration     e = ((ASN1Set)obj).getObjects();
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            String          tab = indent + TAB;
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(indent);
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append("DER Set");
172c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(nl);
173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            while (e.hasMoreElements())
175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                Object  o = e.nextElement();
177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (o == null)
179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append(tab);
181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append("NULL");
182c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    buf.append(nl);
183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
1844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                else if (o instanceof ASN1Primitive)
185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
1864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    _dumpAsString(tab, verbose, (ASN1Primitive)o, buf);
187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
1904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    _dumpAsString(tab, verbose, ((ASN1Encodable)o).toASN1Primitive(), buf);
191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
1944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof ASN1ObjectIdentifier)
195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
1964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            buf.append(indent + "ObjectIdentifier(" + ((ASN1ObjectIdentifier)obj).getId() + ")" + nl);
197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERBoolean)
199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
200c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "Boolean(" + ((DERBoolean)obj).isTrue() + ")" + nl);
201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
2024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof ASN1Integer)
203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
2044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            buf.append(indent + "Integer(" + ((ASN1Integer)obj).getValue() + ")" + nl);
205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof BERConstructedOctetString)
207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
208c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            ASN1OctetString oct = (ASN1OctetString)obj;
209c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] ");
210c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (verbose)
211c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
212c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(dumpBinaryDataAsString(indent, oct.getOctets()));
213c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
214c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            else{
215c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
216c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DEROctetString)
219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
220c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            ASN1OctetString oct = (ASN1OctetString)obj;
221c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "DER Octet String" + "[" + oct.getOctets().length + "] ");
222c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (verbose)
223c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
224c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(dumpBinaryDataAsString(indent, oct.getOctets()));
225c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
226c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            else{
227c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
228c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERBitString)
231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
232c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            DERBitString bt = (DERBitString)obj;
233c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "DER Bit String" + "[" + bt.getBytes().length + ", " + bt.getPadBits() + "] ");
234c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (verbose)
235c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
236c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(dumpBinaryDataAsString(indent, bt.getBytes()));
237c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
238c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            else{
239c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
240c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERIA5String)
243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
244c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "IA5String(" + ((DERIA5String)obj).getString() + ") " + nl);
245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERUTF8String)
247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
248c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "UTF8String(" + ((DERUTF8String)obj).getString() + ") " + nl);
249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERPrintableString)
251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
252c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "PrintableString(" + ((DERPrintableString)obj).getString() + ") " + nl);
253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERVisibleString)
255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
256c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "VisibleString(" + ((DERVisibleString)obj).getString() + ") " + nl);
257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERBMPString)
259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
260c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "BMPString(" + ((DERBMPString)obj).getString() + ") " + nl);
261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERT61String)
263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
264c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "T61String(" + ((DERT61String)obj).getString() + ") " + nl);
265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERUTCTime)
267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
268c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "UTCTime(" + ((DERUTCTime)obj).getTime() + ") " + nl);
269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERGeneralizedTime)
271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
272c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "GeneralizedTime(" + ((DERGeneralizedTime)obj).getTime() + ") " + nl);
273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
274c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        else if (obj instanceof BERApplicationSpecific)
275c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
276c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(outputApplicationSpecific("BER", indent, verbose, obj, nl));
277c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
278c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        else if (obj instanceof DERApplicationSpecific)
279c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
280c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(outputApplicationSpecific("DER", indent, verbose, obj, nl));
281c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
282c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        else if (obj instanceof DEREnumerated)
283c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
284c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            DEREnumerated en = (DEREnumerated) obj;
285c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "DER Enumerated(" + en.getValue() + ")" + nl);
286c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
287c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        else if (obj instanceof DERExternal)
288c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
289c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            DERExternal ext = (DERExternal) obj;
290c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "External " + nl);
291c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            String          tab = indent + TAB;
292c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (ext.getDirectReference() != null)
293c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
294c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(tab + "Direct Reference: " + ext.getDirectReference().getId() + nl);
295c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
296c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (ext.getIndirectReference() != null)
297c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
298c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(tab + "Indirect Reference: " + ext.getIndirectReference().toString() + nl);
299c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
300c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (ext.getDataValueDescriptor() != null)
301c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
302c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                _dumpAsString(tab, verbose, ext.getDataValueDescriptor(), buf);
303c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
304c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(tab + "Encoding: " + ext.getEncoding() + nl);
305c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            _dumpAsString(tab, verbose, ext.getExternalContent(), buf);
306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
309c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + obj.toString() + nl);
310c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
311c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
312c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
3134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private static String outputApplicationSpecific(String type, String indent, boolean verbose, ASN1Primitive obj, String nl)
314c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
315c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        DERApplicationSpecific app = (DERApplicationSpecific)obj;
316c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer buf = new StringBuffer();
317c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
318c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (app.isConstructed())
319c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
320c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            try
321c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
3224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ASN1Sequence s = ASN1Sequence.getInstance(app.getObject(BERTags.SEQUENCE));
323c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "]" + nl);
324c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                for (Enumeration e = s.getObjects(); e.hasMoreElements();)
325c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
3264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    _dumpAsString(indent + TAB, verbose, (ASN1Primitive)e.nextElement(), buf);
327c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
328c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
329c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            catch (IOException e)
330c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
331c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(e);
332c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
333c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return buf.toString();
334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
335c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
336c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "] (" + new String(Hex.encode(app.getContents())) + ")" + nl;
337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
340c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * dump out a DER object as a formatted string, in non-verbose mode.
341b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
3424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @param obj the ASN1Primitive to be dumped out.
343c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @return  the resulting string.
344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static String dumpAsString(
346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object   obj)
347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
348c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return dumpAsString(obj, false);
349c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
350c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
351c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
352c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * Dump out the object as a string.
353c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     *
354c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @param obj  the object to be dumped
355c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @param verbose  if true, dump out the contents of octet and bit strings.
356c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @return  the resulting string.
357c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
358c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public static String dumpAsString(
359c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        Object   obj,
360c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        boolean  verbose)
361c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
362c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer buf = new StringBuffer();
363c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
3644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (obj instanceof ASN1Primitive)
365b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
3664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            _dumpAsString("", verbose, (ASN1Primitive)obj, buf);
367b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
3684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof ASN1Encodable)
369b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
3704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            _dumpAsString("", verbose, ((ASN1Encodable)obj).toASN1Primitive(), buf);
371c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
372c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        else
373c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
374c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return "unknown object type " + obj.toString();
375c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
376c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
377c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return buf.toString();
378c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
379c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
380c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static String dumpBinaryDataAsString(String indent, byte[] bytes)
381c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
382c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        String nl = System.getProperty("line.separator");
383c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer buf = new StringBuffer();
384c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
385c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        indent += TAB;
386c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
387c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        buf.append(nl);
388c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        for (int i = 0; i < bytes.length; i += SAMPLE_SIZE)
389c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
390c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (bytes.length - i > SAMPLE_SIZE)
391c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
392c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(indent);
393c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(new String(Hex.encode(bytes, i, SAMPLE_SIZE)));
394c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(TAB);
395c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(calculateAscString(bytes, i, SAMPLE_SIZE));
396c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
397c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
398c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            else
399c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
400c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(indent);
401c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(new String(Hex.encode(bytes, i, bytes.length - i)));
402c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                for (int j = bytes.length - i; j != SAMPLE_SIZE; j++)
403c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
404c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    buf.append("  ");
405c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
406c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(TAB);
407c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(calculateAscString(bytes, i, bytes.length - i));
408c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
409c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
410c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
411c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
412c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return buf.toString();
413c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
414c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
415c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static String calculateAscString(byte[] bytes, int off, int len)
416c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
417c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer buf = new StringBuffer();
418c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
419c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        for (int i = off; i != off + len; i++)
420c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
421c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (bytes[i] >= ' ' && bytes[i] <= '~')
422c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
423c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append((char)bytes[i]);
424c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
425b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
426b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
427c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return buf.toString();
428b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
429b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
430