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