Commit | Line | Data |
---|---|---|
d44e3c4f | 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 | |
7 | * | |
8 | * Contributors: | |
9 | * Balasko, Jeno | |
10 | * Forstner, Matyas | |
11 | * Raduly, Csaba | |
12 | * Szabo, Janos Zoltan – initial implementation | |
13 | * | |
14 | ******************************************************************************/ | |
970ed795 EL |
15 | #ifndef _BER_HH |
16 | #define _BER_HH | |
17 | ||
18 | /** @name BER encoding subtypes | |
19 | @{ | |
20 | */ | |
21 | /// Canonical Encoding Rules | |
22 | #define BER_ENCODE_CER 1 | |
23 | /// Distinguished Encoding Rules | |
24 | #define BER_ENCODE_DER 2 | |
25 | /** @} */ | |
26 | ||
27 | /** @name BER decoding options | |
28 | @{ | |
29 | */ | |
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 | |
40 | /** @} */ | |
41 | ||
42 | #include "Types.h" | |
43 | #include "Encdec.hh" | |
44 | ||
45 | /** | |
46 | * \defgroup BER BER-related stuff. | |
47 | * | |
48 | * @{ | |
49 | */ | |
50 | ||
51 | /** @brief ASN.1 tag */ | |
52 | enum ASN_Tagclass_t { | |
53 | ASN_TAG_UNDEF, | |
54 | ASN_TAG_UNIV, /**< UNIVERSAL */ | |
55 | ASN_TAG_APPL, /**< APPLICATION */ | |
56 | ASN_TAG_CONT, /**< context-specific */ | |
57 | ASN_TAG_PRIV /**< PRIVATE */ | |
58 | }; | |
59 | ||
60 | typedef unsigned int ASN_Tagnumber_t; | |
61 | ||
62 | /** @brief ASN.1 identifier | |
63 | * | |
64 | * Contains two thirds of the T from a TLV | |
65 | */ | |
66 | struct ASN_Tag_t { | |
67 | ASN_Tagclass_t tagclass; /**< Tag class */ | |
68 | ASN_Tagnumber_t tagnumber; /**< Tag value. For UNIVERSAL, the values are predefined */ | |
69 | ||
70 | /** Creates a user-friendly representation of the tag. After using, | |
71 | * you have to Free() this string. */ | |
72 | char* print() const; | |
73 | }; | |
74 | ||
75 | /** @brief BER encoding information | |
76 | * | |
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() . | |
80 | */ | |
81 | struct ASN_BERdescriptor_t { | |
82 | /** Number of tags. | |
83 | * | |
84 | * For the UNIVERSAL classes, this is usually 1 (except for CHOICE and ANY) | |
85 | */ | |
86 | size_t n_tags; | |
87 | /** This array contains the tags. Index 0 is the innermost tag. */ | |
88 | const ASN_Tag_t *tags; | |
89 | ||
90 | /** Creates a user-friendly representation of tags. After using, you | |
91 | * have to Free() this string. */ | |
92 | char* print_tags() const; | |
93 | }; | |
94 | ||
95 | struct TTCN_Typedescriptor_t; | |
96 | ||
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_; | |
127 | ||
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; | |
131 | ||
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; | |
135 | ||
136 | /** How many bits are needed minimally to represent the given | |
137 | * (nonnegative integral) value. Returned value is greater than or | |
138 | * equal to 1. */ | |
139 | template<typename T> | |
140 | size_t min_needed_bits(T p) | |
141 | { | |
142 | if(p==0) return 1; | |
143 | register size_t n=0; | |
144 | register T tmp=p; | |
145 | while(tmp!=0) n++, tmp/=2; | |
146 | return n; | |
147 | } | |
148 | ||
149 | /** This struct represents a BER TLV. | |
150 | * | |
151 | * It represents a "deconstructed" (cooked) representation of | |
152 | * a BER encoding. */ | |
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; | |
161 | boolean isComplete; | |
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 */ | |
169 | struct { | |
170 | size_t Vlen; | |
171 | unsigned char *Vstr; | |
172 | } str; /**< V_tlvs_selected==FALSE */ | |
173 | struct { | |
174 | size_t n_tlvs; | |
175 | ASN_BER_TLV_t **tlvs; | |
176 | } tlvs; /**< V_tlvs_selected==TRUE */ | |
177 | } V; | |
178 | ||
179 | /** Creates a new constructed TLV which contains one TLV (\a | |
180 | * p_tlv). Or, if the parameter is NULL, then an empty constructed | |
181 | * TLV is created. */ | |
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 | |
196 | * error. */ | |
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, | |
211 | unsigned coding); | |
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; | |
216 | private: | |
217 | unsigned char _get_pos(size_t& pos, boolean& success) const; | |
218 | public: | |
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. */ | |
224 | void sort_tlvs(); | |
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 | |
227 | * than other. */ | |
228 | int compare_tags(const ASN_BER_TLV_t *other) const; | |
229 | /** Sorts its TLVs according to their tags, as described in X.690 | |
230 | * 10.3. */ | |
231 | void sort_tlvs_tag(); | |
232 | }; | |
233 | ||
234 | /** | |
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. | |
238 | */ | |
239 | boolean ASN_BER_str2TLV(size_t p_len_s, | |
240 | const unsigned char* p_str, | |
241 | ASN_BER_TLV_t& tlv, | |
242 | unsigned L_form); | |
243 | ||
244 | /** | |
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. | |
250 | */ | |
251 | ASN_BER_TLV_t* ASN_BER_V2TLV(ASN_BER_TLV_t* p_tlv, | |
252 | const TTCN_Typedescriptor_t& p_td, | |
253 | unsigned coding); | |
254 | ||
255 | /** @} end of BER group */ | |
256 | ||
257 | #endif // _BER_HH |