001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2008 Sun Microsystems, Inc.
025 *      Portions copyright 2012-2015 ForgeRock AS.
026 */
027package org.forgerock.opendj.io;
028
029import java.io.InputStream;
030import java.io.OutputStream;
031
032import org.forgerock.opendj.ldap.ByteSequence;
033import org.forgerock.opendj.ldap.ByteSequenceReader;
034import org.forgerock.opendj.ldap.ByteString;
035import org.forgerock.opendj.ldap.ByteStringBuilder;
036
037/**
038 * This class contains various static factory methods for creating ASN.1 readers
039 * and writers.
040 *
041 * @see ASN1Reader
042 * @see ASN1Writer
043 */
044public final class ASN1 {
045
046    /**
047     * Maximum buffer size when reading ASN1. Buffers above this threshold will
048     * be discarded for garbage collection to avoid OutOfMemoryErrors.
049     */
050    private static final int DEFAULT_MAX_BUFFER_SIZE = 32 * 1024;
051
052    /**
053     * The byte array containing the pre-encoded ASN.1 encoding for a boolean
054     * value of "false".
055     */
056    public static final byte BOOLEAN_VALUE_FALSE = 0x00;
057
058    /**
059     * The byte array containing the pre-encoded ASN.1 encoding for a boolean
060     * value of "false".
061     */
062    public static final byte BOOLEAN_VALUE_TRUE = (byte) 0xFF;
063
064    /**
065     * The BER type that is assigned to the universal Boolean element.
066     */
067    public static final byte UNIVERSAL_BOOLEAN_TYPE = 0x01;
068
069    /**
070     * The BER type that is assigned to the universal integer type.
071     */
072    public static final byte UNIVERSAL_INTEGER_TYPE = 0x02;
073    /**
074     * The BER type that is assigned to the universal bit string type.
075     */
076    public static final byte UNIVERSAL_BIT_STRING_TYPE = 0x03;
077
078    /**
079     * The BER type that is assigned to the universal octet string type.
080     */
081    public static final byte UNIVERSAL_OCTET_STRING_TYPE = 0x04;
082
083    /**
084     * The BER type that is assigned to the universal null type.
085     */
086    public static final byte UNIVERSAL_NULL_TYPE = 0x05;
087
088    /**
089     * The BER type that is assigned to the universal enumerated type.
090     */
091    public static final byte UNIVERSAL_ENUMERATED_TYPE = 0x0A;
092
093    /**
094     * The BER type that is assigned to the universal sequence type.
095     */
096    public static final byte UNIVERSAL_SEQUENCE_TYPE = 0x30;
097
098    /**
099     * The BER type that is assigned to the universal set type.
100     */
101    public static final byte UNIVERSAL_SET_TYPE = 0x31;
102
103    /**
104     * The ASN.1 element decoding state that indicates that the next byte read
105     * should be additional bytes of a multi-byte length.
106     */
107    public static final int ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES = 2;
108
109    /**
110     * The ASN.1 element decoding state that indicates that the next byte read
111     * should be the first byte for the element length.
112     */
113    public static final int ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE = 1;
114
115    /**
116     * The ASN.1 element decoding state that indicates that the next byte read
117     * should be the BER type for a new element.
118     */
119    public static final int ELEMENT_READ_STATE_NEED_TYPE = 0;
120
121    /**
122     * The ASN.1 element decoding state that indicates that the next byte read
123     * should be applied to the value of the element.
124     */
125
126    public static final int ELEMENT_READ_STATE_NEED_VALUE_BYTES = 3;
127    /**
128     * The byte array that will be used for ASN.1 elements with no value.
129     */
130    static final byte[] NO_VALUE = new byte[0];
131
132    /**
133     * The bitmask that can be ANDed with the BER type to zero out all bits
134     * except those used in the class.
135     */
136    static final byte TYPE_MASK_ALL_BUT_CLASS = (byte) 0xC0;
137    /**
138     * The bitmask that can be ANDed with the BER type to zero out all bits
139     * except the primitive/constructed bit.
140     */
141    static final byte TYPE_MASK_ALL_BUT_PC = 0x20;
142    /**
143     * The bitmask that can be ANDed with the BER type to determine if the
144     * element is in the application-specific class.
145     */
146    static final byte TYPE_MASK_APPLICATION = 0x40;
147    /**
148     * The bitmask that can be ANDed with the BER type to determine if the
149     * element is constructed.
150     */
151    public static final byte TYPE_MASK_CONSTRUCTED = 0x20;
152    /**
153     * The bitmask that can be ANDed with the BER type to determine if the
154     * element is in the context-specific class.
155     */
156    public static final byte TYPE_MASK_CONTEXT = (byte) 0x80;
157    /**
158     * The bitmask that can be ANDed with the BER type to determine if the
159     * element is a primitive.
160     */
161    static final byte TYPE_MASK_PRIMITIVE = 0x00;
162    /**
163     * The bitmask that can be ANDed with the BER type to determine if the
164     * element is in the private class.
165     */
166    static final byte TYPE_MASK_PRIVATE = (byte) 0xC0;
167    /**
168     * The bitmask that can be ANDed with the BER type to determine if the
169     * element is in the universal class.
170     */
171    static final byte TYPE_MASK_UNIVERSAL = 0x00;
172
173    /**
174     * Returns an ASN.1 reader whose source is the provided byte array and
175     * having an unlimited maximum BER element size.
176     *
177     * @param array
178     *            The byte array to use.
179     * @return The new ASN.1 reader.
180     */
181    public static ASN1Reader getReader(final byte[] array) {
182        return getReader(array, 0);
183    }
184
185    /**
186     * Returns an ASN.1 reader whose source is the provided byte array and
187     * having a user defined maximum BER element size.
188     *
189     * @param array
190     *            The byte array to use.
191     * @param maxElementSize
192     *            The maximum BER element size, or {@code 0} to indicate that
193     *            there is no limit.
194     * @return The new ASN.1 reader.
195     */
196    public static ASN1Reader getReader(final byte[] array, final int maxElementSize) {
197        return getReader(ByteString.wrap(array), maxElementSize);
198    }
199
200    /**
201     * Returns an ASN.1 reader whose source is the provided byte sequence and
202     * having an unlimited maximum BER element size.
203     *
204     * @param sequence
205     *            The byte sequence to use.
206     * @return The new ASN.1 reader.
207     */
208    public static ASN1Reader getReader(final ByteSequence sequence) {
209        return getReader(sequence, 0);
210    }
211
212    /**
213     * Returns an ASN.1 reader whose source is the provided byte sequence and
214     * having a user defined maximum BER element size.
215     *
216     * @param sequence
217     *            The byte sequence to use.
218     * @param maxElementSize
219     *            The maximum BER element size, or {@code 0} to indicate that
220     *            there is no limit.
221     * @return The new ASN.1 reader.
222     */
223    public static ASN1Reader getReader(final ByteSequence sequence, final int maxElementSize) {
224        return new ASN1ByteSequenceReader(sequence.asReader(), maxElementSize);
225    }
226
227    /**
228     * Returns an ASN.1 reader whose source is the provided byte sequence reader
229     * and having an unlimited maximum BER element size.
230     *
231     * @param reader
232     *            The byte sequence reader to use.
233     * @return The new ASN.1 reader.
234     */
235    public static ASN1Reader getReader(final ByteSequenceReader reader) {
236        return getReader(reader, 0);
237    }
238
239    /**
240     * Returns an ASN.1 reader whose source is the provided byte sequence reader
241     * and having a user defined maximum BER element size.
242     *
243     * @param reader
244     *            The byte sequence reader to use.
245     * @param maxElementSize
246     *            The maximum BER element size, or {@code 0} to indicate that
247     *            there is no limit.
248     * @return The new ASN.1 reader.
249     */
250    public static ASN1Reader getReader(final ByteSequenceReader reader, final int maxElementSize) {
251        return new ASN1ByteSequenceReader(reader, maxElementSize);
252    }
253
254    /**
255     * Returns an ASN.1 reader whose source is the provided input stream and
256     * having an unlimited maximum BER element size.
257     *
258     * @param stream
259     *            The input stream to use.
260     * @return The new ASN.1 reader.
261     */
262    public static ASN1Reader getReader(final InputStream stream) {
263        return getReader(stream, 0);
264    }
265
266    /**
267     * Returns an ASN.1 reader whose source is the provided input stream and
268     * having a user defined maximum BER element size.
269     *
270     * @param stream
271     *            The input stream to use.
272     * @param maxElementSize
273     *            The maximum BER element size, or {@code 0} to indicate that
274     *            there is no limit.
275     * @return The new ASN.1 reader.
276     */
277    public static ASN1Reader getReader(final InputStream stream, final int maxElementSize) {
278        return new ASN1InputStreamReader(stream, maxElementSize);
279    }
280
281    /**
282     * Returns an ASN.1 writer whose destination is the provided byte string
283     * builder.
284     *
285     * @param builder
286     *            The byte string builder to use.
287     * @return The new ASN.1 writer.
288     */
289    public static ASN1Writer getWriter(final ByteStringBuilder builder) {
290        return getWriter(builder.asOutputStream(), DEFAULT_MAX_BUFFER_SIZE);
291    }
292
293    /**
294     * Returns an ASN.1 writer whose destination is the provided byte string
295     * builder.
296     *
297     * @param builder
298     *            The output stream to use.
299     * @param maxBufferSize
300     *          The threshold capacity beyond which internal cached buffers used
301     *          for encoding and decoding ASN1 will be trimmed after use.
302     * @return The new ASN.1 writer.
303     */
304    public static ASN1Writer getWriter(final ByteStringBuilder builder, final int maxBufferSize) {
305        return getWriter(builder.asOutputStream(), maxBufferSize);
306    }
307
308    /**
309     * Returns an ASN.1 writer whose destination is the provided output stream.
310     *
311     * @param stream
312     *            The output stream to use.
313     * @return The new ASN.1 writer.
314     */
315    public static ASN1Writer getWriter(final OutputStream stream) {
316        return getWriter(stream, DEFAULT_MAX_BUFFER_SIZE);
317    }
318
319    /**
320     * Returns an ASN.1 writer whose destination is the provided output stream.
321     *
322     * @param stream
323     *            The output stream to use.
324     * @param maxBufferSize
325     *          The threshold capacity beyond which internal cached buffers used
326     *          for encoding and decoding ASN1 will be trimmed after use.
327     * @return The new ASN.1 writer.
328     */
329    public static ASN1Writer getWriter(final OutputStream stream, final int maxBufferSize) {
330        return new ASN1OutputStreamWriter(stream, maxBufferSize);
331    }
332
333    /** Prevent instantiation. */
334    private ASN1() {
335        // Nothing to do.
336    }
337}