1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
12 * Szabo, Janos Zoltan – initial implementation
14 ******************************************************************************/
18 /** @name BER encoding subtypes
21 /// Canonical Encoding Rules
22 #define BER_ENCODE_CER 1
23 /// Distinguished Encoding Rules
24 #define BER_ENCODE_DER 2
27 /** @name BER decoding options
30 /// Short length form is acceptable
31 #define BER_ACCEPT_SHORT 0x01
32 /// Long length form is acceptable
33 #define BER_ACCEPT_LONG 0x02
34 /// Indefinite form is acceptable
35 #define BER_ACCEPT_INDEFINITE 0x04
36 /// Definite forms (short or long) are acceptable
37 #define BER_ACCEPT_DEFINITE 0x03
38 /// All forms are acceptable
39 #define BER_ACCEPT_ALL 0x07
46 * \defgroup BER BER-related stuff.
51 /** @brief ASN.1 tag */
54 ASN_TAG_UNIV, /**< UNIVERSAL */
55 ASN_TAG_APPL, /**< APPLICATION */
56 ASN_TAG_CONT, /**< context-specific */
57 ASN_TAG_PRIV /**< PRIVATE */
60 typedef unsigned int ASN_Tagnumber_t;
62 /** @brief ASN.1 identifier
64 * Contains two thirds of the T from a TLV
67 ASN_Tagclass_t tagclass; /**< Tag class */
68 ASN_Tagnumber_t tagnumber; /**< Tag value. For UNIVERSAL, the values are predefined */
70 /** Creates a user-friendly representation of the tag. After using,
71 * you have to Free() this string. */
75 /** @brief BER encoding information
77 * There is one object for each predefined (UNIVERSAL) type.
78 * Also, the compiler writes an object of this type for each user-defined type
79 * into the generated code in Common::Type::generate_code_berdescriptor() .
81 struct ASN_BERdescriptor_t {
84 * For the UNIVERSAL classes, this is usually 1 (except for CHOICE and ANY)
87 /** This array contains the tags. Index 0 is the innermost tag. */
88 const ASN_Tag_t *tags;
90 /** Creates a user-friendly representation of tags. After using, you
91 * have to Free() this string. */
92 char* print_tags() const;
95 struct TTCN_Typedescriptor_t;
97 extern const ASN_BERdescriptor_t BOOLEAN_ber_;
98 extern const ASN_BERdescriptor_t INTEGER_ber_;
99 extern const ASN_BERdescriptor_t BITSTRING_ber_;
100 extern const ASN_BERdescriptor_t OCTETSTRING_ber_;
101 extern const ASN_BERdescriptor_t ASN_NULL_ber_;
102 extern const ASN_BERdescriptor_t OBJID_ber_;
103 extern const ASN_BERdescriptor_t ObjectDescriptor_ber_;
104 extern const ASN_BERdescriptor_t FLOAT_ber_;
105 extern const ASN_BERdescriptor_t ENUMERATED_ber_;
106 extern const ASN_BERdescriptor_t UTF8String_ber_;
107 extern const ASN_BERdescriptor_t ASN_ROID_ber_;
108 extern const ASN_BERdescriptor_t SEQUENCE_ber_;
109 extern const ASN_BERdescriptor_t SET_ber_;
110 extern const ASN_BERdescriptor_t CHOICE_ber_;
111 extern const ASN_BERdescriptor_t ASN_ANY_ber_;
112 extern const ASN_BERdescriptor_t NumericString_ber_;
113 extern const ASN_BERdescriptor_t PrintableString_ber_;
114 extern const ASN_BERdescriptor_t TeletexString_ber_;
115 extern const ASN_BERdescriptor_t VideotexString_ber_;
116 extern const ASN_BERdescriptor_t IA5String_ber_;
117 extern const ASN_BERdescriptor_t ASN_UTCTime_ber_;
118 extern const ASN_BERdescriptor_t ASN_GeneralizedTime_ber_;
119 extern const ASN_BERdescriptor_t GraphicString_ber_;
120 extern const ASN_BERdescriptor_t VisibleString_ber_;
121 extern const ASN_BERdescriptor_t GeneralString_ber_;
122 extern const ASN_BERdescriptor_t UniversalString_ber_;
123 extern const ASN_BERdescriptor_t BMPString_ber_;
124 extern const ASN_BERdescriptor_t EXTERNAL_ber_;
125 extern const ASN_BERdescriptor_t EMBEDDED_PDV_ber_;
126 extern const ASN_BERdescriptor_t CHARACTER_STRING_ber_;
128 /** An unsigned long long with 7 bits set (0x7F) in the most significant byte.
129 * Used when decoding objid values. */
130 extern const unsigned long long unsigned_llong_7msb;
132 /** An unsigned long with 8 bits set (0xFF) in the most significant byte.
133 * Used when decoding integers. */
134 extern const unsigned long unsigned_long_8msb;
136 /** How many bits are needed minimally to represent the given
137 * (nonnegative integral) value. Returned value is greater than or
140 size_t min_needed_bits(T p)
145 while(tmp!=0) n++, tmp/=2;
149 /** This struct represents a BER TLV.
151 * It represents a "deconstructed" (cooked) representation of
153 struct ASN_BER_TLV_t {
154 boolean isConstructed; /**< Primitive/Constructed bit. */
155 boolean V_tlvs_selected; /**< How the data is stored in \p V. */
156 boolean isLenDefinite; /**< \c false for indefinite form */
157 boolean isLenShort; /**< \c true for short form (0-127) */
158 /** Is \p tagclass and \p tagnumber valid.
159 * ASN_BER_str2TLV function sets this. */
160 boolean isTagComplete;
162 ASN_Tagclass_t tagclass; /**< UNIV/APP/context/PRIVATE */
163 ASN_Tagnumber_t tagnumber;
164 size_t Tlen; /** Length of T part. May be >1 for tag values >30 */
165 size_t Llen; /** Length of L part. */
166 unsigned char *Tstr; /** Encoded T part. */
167 unsigned char *Lstr; /** Encoded L part. */
168 union { /* depends on V_tlvs_selected */
172 } str; /**< V_tlvs_selected==FALSE */
175 ASN_BER_TLV_t **tlvs;
176 } tlvs; /**< V_tlvs_selected==TRUE */
179 /** Creates a new constructed TLV which contains one TLV (\a
180 * p_tlv). Or, if the parameter is NULL, then an empty constructed
182 static ASN_BER_TLV_t* construct(ASN_BER_TLV_t *p_tlv);
183 /** Creates a new non-constructed TLV with the given V-part.
184 * Tagclass and -number are set to UNIV-0. If \a p_Vstr is NULL
185 * then allocates a \a p_Vlen size buffer for Vstr.
186 * Takes over ownership of \a p_Vstr */
187 static ASN_BER_TLV_t* construct(size_t p_Vlen, unsigned char *p_Vstr);
188 /** Creates a new non-constructed TLV with empty T, L and V part. */
189 static ASN_BER_TLV_t* construct();
190 /** Frees the given \a p_tlv recursively. Tstr, Lstr and
191 * Vstr/tlvs. If \a no_str is TRUE, then only the tlvs are deleted,
192 * the strings (Tstr, Lstr, Vstr) are not. This is useful during
193 * decoding, when the Xstr points into a buffer.*/
194 static void destruct(ASN_BER_TLV_t *p_tlv, boolean no_str=FALSE);
195 /** Checks the 'constructed' flag. If fails, raises an EncDec
197 void chk_constructed_flag(boolean flag_expected) const;
198 /** Adds \a p_tlv to this (constructed) TLV.
199 * @pre isConstructed is \c true
200 * @pre V_tlvs_selected is \c true */
201 void add_TLV(ASN_BER_TLV_t *p_tlv);
202 /** Adds a new UNIVERSAL 0 TLV to this (constructed) TLV. */
203 void add_UNIV0_TLV();
204 /** Returns the length (in bytes) of the full TLV. */
205 size_t get_len() const;
206 /** Adds T and L part to TLV. It adds trailing UNI-0 TLV (two zero
207 * octets) if the length form is indefinite. Precondition:
208 * isConstructed (and V_tlvs_selected) and V-part are valid. */
209 void add_TL(ASN_Tagclass_t p_tagclass,
210 ASN_Tagnumber_t p_tagnumber,
212 /** Puts the TLV in buffer \a p_buf. */
213 void put_in_buffer(TTCN_Buffer& p_buf);
214 /** Gets the octet in position \a pos. Works also for constructed TLVs. */
215 unsigned char get_pos(size_t pos) const;
217 unsigned char _get_pos(size_t& pos, boolean& success) const;
219 /** Compares the TLVs as described in X.690 11.6. Returns -1 if this
220 * less than, 0 if equal to, 1 if greater than other. */
221 int compare(const ASN_BER_TLV_t *other) const;
222 /** Sorts its TLVs according to their octetstring representation, as
223 * described in X.690 11.6. */
225 /** Compares the TLVs according their tags as described in X.680
226 * 8.6. Returns -1 if this less than, 0 if equal to, 1 if greater
228 int compare_tags(const ASN_BER_TLV_t *other) const;
229 /** Sorts its TLVs according to their tags, as described in X.690
231 void sort_tlvs_tag();
235 * Searches the T, L and V parts of the TLV represented in \a s, and
236 * stores it in \a tlv. Returns FALSE if there isn't a complete
237 * TLV-structure in \a s, TRUE otherwise.
239 boolean ASN_BER_str2TLV(size_t p_len_s,
240 const unsigned char* p_str,
245 * Adds the T and L part of the TLV. If there are multiple tags, then
246 * adds them all. Precondition: the following fields are ready of \a
247 * p_tlv: isConstructed, V_tlvs_selected, isLenDefinite, isLenShort
248 * and V. If tagclass and tagnumber are UNIVERSAL 0, then replaces
249 * them, otherwise 'wraps' p_tlv in a new TLV.
251 ASN_BER_TLV_t* ASN_BER_V2TLV(ASN_BER_TLV_t* p_tlv,
252 const TTCN_Typedescriptor_t& p_td,
255 /** @} end of BER group */