Commit | Line | Data |
---|---|---|
970ed795 | 1 | /////////////////////////////////////////////////////////////////////////////// |
3abe9331 | 2 | // Copyright (c) 2000-2015 Ericsson Telecom AB |
970ed795 EL |
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 | #ifndef _BER_HH | |
9 | #define _BER_HH | |
10 | ||
11 | /** @name BER encoding subtypes | |
12 | @{ | |
13 | */ | |
14 | /// Canonical Encoding Rules | |
15 | #define BER_ENCODE_CER 1 | |
16 | /// Distinguished Encoding Rules | |
17 | #define BER_ENCODE_DER 2 | |
18 | /** @} */ | |
19 | ||
20 | /** @name BER decoding options | |
21 | @{ | |
22 | */ | |
23 | /// Short length form is acceptable | |
24 | #define BER_ACCEPT_SHORT 0x01 | |
25 | /// Long length form is acceptable | |
26 | #define BER_ACCEPT_LONG 0x02 | |
27 | /// Indefinite form is acceptable | |
28 | #define BER_ACCEPT_INDEFINITE 0x04 | |
29 | /// Definite forms (short or long) are acceptable | |
30 | #define BER_ACCEPT_DEFINITE 0x03 | |
31 | /// All forms are acceptable | |
32 | #define BER_ACCEPT_ALL 0x07 | |
33 | /** @} */ | |
34 | ||
35 | #include "Types.h" | |
36 | #include "Encdec.hh" | |
37 | ||
38 | /** | |
39 | * \defgroup BER BER-related stuff. | |
40 | * | |
41 | * @{ | |
42 | */ | |
43 | ||
44 | /** @brief ASN.1 tag */ | |
45 | enum ASN_Tagclass_t { | |
46 | ASN_TAG_UNDEF, | |
47 | ASN_TAG_UNIV, /**< UNIVERSAL */ | |
48 | ASN_TAG_APPL, /**< APPLICATION */ | |
49 | ASN_TAG_CONT, /**< context-specific */ | |
50 | ASN_TAG_PRIV /**< PRIVATE */ | |
51 | }; | |
52 | ||
53 | typedef unsigned int ASN_Tagnumber_t; | |
54 | ||
55 | /** @brief ASN.1 identifier | |
56 | * | |
57 | * Contains two thirds of the T from a TLV | |
58 | */ | |
59 | struct ASN_Tag_t { | |
60 | ASN_Tagclass_t tagclass; /**< Tag class */ | |
61 | ASN_Tagnumber_t tagnumber; /**< Tag value. For UNIVERSAL, the values are predefined */ | |
62 | ||
63 | /** Creates a user-friendly representation of the tag. After using, | |
64 | * you have to Free() this string. */ | |
65 | char* print() const; | |
66 | }; | |
67 | ||
68 | /** @brief BER encoding information | |
69 | * | |
70 | * There is one object for each predefined (UNIVERSAL) type. | |
71 | * Also, the compiler writes an object of this type for each user-defined type | |
72 | * into the generated code in Common::Type::generate_code_berdescriptor() . | |
73 | */ | |
74 | struct ASN_BERdescriptor_t { | |
75 | /** Number of tags. | |
76 | * | |
77 | * For the UNIVERSAL classes, this is usually 1 (except for CHOICE and ANY) | |
78 | */ | |
79 | size_t n_tags; | |
80 | /** This array contains the tags. Index 0 is the innermost tag. */ | |
81 | const ASN_Tag_t *tags; | |
82 | ||
83 | /** Creates a user-friendly representation of tags. After using, you | |
84 | * have to Free() this string. */ | |
85 | char* print_tags() const; | |
86 | }; | |
87 | ||
88 | struct TTCN_Typedescriptor_t; | |
89 | ||
90 | extern const ASN_BERdescriptor_t BOOLEAN_ber_; | |
91 | extern const ASN_BERdescriptor_t INTEGER_ber_; | |
92 | extern const ASN_BERdescriptor_t BITSTRING_ber_; | |
93 | extern const ASN_BERdescriptor_t OCTETSTRING_ber_; | |
94 | extern const ASN_BERdescriptor_t ASN_NULL_ber_; | |
95 | extern const ASN_BERdescriptor_t OBJID_ber_; | |
96 | extern const ASN_BERdescriptor_t ObjectDescriptor_ber_; | |
97 | extern const ASN_BERdescriptor_t FLOAT_ber_; | |
98 | extern const ASN_BERdescriptor_t ENUMERATED_ber_; | |
99 | extern const ASN_BERdescriptor_t UTF8String_ber_; | |
100 | extern const ASN_BERdescriptor_t ASN_ROID_ber_; | |
101 | extern const ASN_BERdescriptor_t SEQUENCE_ber_; | |
102 | extern const ASN_BERdescriptor_t SET_ber_; | |
103 | extern const ASN_BERdescriptor_t CHOICE_ber_; | |
104 | extern const ASN_BERdescriptor_t ASN_ANY_ber_; | |
105 | extern const ASN_BERdescriptor_t NumericString_ber_; | |
106 | extern const ASN_BERdescriptor_t PrintableString_ber_; | |
107 | extern const ASN_BERdescriptor_t TeletexString_ber_; | |
108 | extern const ASN_BERdescriptor_t VideotexString_ber_; | |
109 | extern const ASN_BERdescriptor_t IA5String_ber_; | |
110 | extern const ASN_BERdescriptor_t ASN_UTCTime_ber_; | |
111 | extern const ASN_BERdescriptor_t ASN_GeneralizedTime_ber_; | |
112 | extern const ASN_BERdescriptor_t GraphicString_ber_; | |
113 | extern const ASN_BERdescriptor_t VisibleString_ber_; | |
114 | extern const ASN_BERdescriptor_t GeneralString_ber_; | |
115 | extern const ASN_BERdescriptor_t UniversalString_ber_; | |
116 | extern const ASN_BERdescriptor_t BMPString_ber_; | |
117 | extern const ASN_BERdescriptor_t EXTERNAL_ber_; | |
118 | extern const ASN_BERdescriptor_t EMBEDDED_PDV_ber_; | |
119 | extern const ASN_BERdescriptor_t CHARACTER_STRING_ber_; | |
120 | ||
121 | /** An unsigned long long with 7 bits set (0x7F) in the most significant byte. | |
122 | * Used when decoding objid values. */ | |
123 | extern const unsigned long long unsigned_llong_7msb; | |
124 | ||
125 | /** An unsigned long with 8 bits set (0xFF) in the most significant byte. | |
126 | * Used when decoding integers. */ | |
127 | extern const unsigned long unsigned_long_8msb; | |
128 | ||
129 | /** How many bits are needed minimally to represent the given | |
130 | * (nonnegative integral) value. Returned value is greater than or | |
131 | * equal to 1. */ | |
132 | template<typename T> | |
133 | size_t min_needed_bits(T p) | |
134 | { | |
135 | if(p==0) return 1; | |
136 | register size_t n=0; | |
137 | register T tmp=p; | |
138 | while(tmp!=0) n++, tmp/=2; | |
139 | return n; | |
140 | } | |
141 | ||
142 | /** This struct represents a BER TLV. | |
143 | * | |
144 | * It represents a "deconstructed" (cooked) representation of | |
145 | * a BER encoding. */ | |
146 | struct ASN_BER_TLV_t { | |
147 | boolean isConstructed; /**< Primitive/Constructed bit. */ | |
148 | boolean V_tlvs_selected; /**< How the data is stored in \p V. */ | |
149 | boolean isLenDefinite; /**< \c false for indefinite form */ | |
150 | boolean isLenShort; /**< \c true for short form (0-127) */ | |
151 | /** Is \p tagclass and \p tagnumber valid. | |
152 | * ASN_BER_str2TLV function sets this. */ | |
153 | boolean isTagComplete; | |
154 | boolean isComplete; | |
155 | ASN_Tagclass_t tagclass; /**< UNIV/APP/context/PRIVATE */ | |
156 | ASN_Tagnumber_t tagnumber; | |
157 | size_t Tlen; /** Length of T part. May be >1 for tag values >30 */ | |
158 | size_t Llen; /** Length of L part. */ | |
159 | unsigned char *Tstr; /** Encoded T part. */ | |
160 | unsigned char *Lstr; /** Encoded L part. */ | |
161 | union { /* depends on V_tlvs_selected */ | |
162 | struct { | |
163 | size_t Vlen; | |
164 | unsigned char *Vstr; | |
165 | } str; /**< V_tlvs_selected==FALSE */ | |
166 | struct { | |
167 | size_t n_tlvs; | |
168 | ASN_BER_TLV_t **tlvs; | |
169 | } tlvs; /**< V_tlvs_selected==TRUE */ | |
170 | } V; | |
171 | ||
172 | /** Creates a new constructed TLV which contains one TLV (\a | |
173 | * p_tlv). Or, if the parameter is NULL, then an empty constructed | |
174 | * TLV is created. */ | |
175 | static ASN_BER_TLV_t* construct(ASN_BER_TLV_t *p_tlv); | |
176 | /** Creates a new non-constructed TLV with the given V-part. | |
177 | * Tagclass and -number are set to UNIV-0. If \a p_Vstr is NULL | |
178 | * then allocates a \a p_Vlen size buffer for Vstr. | |
179 | * Takes over ownership of \a p_Vstr */ | |
180 | static ASN_BER_TLV_t* construct(size_t p_Vlen, unsigned char *p_Vstr); | |
181 | /** Creates a new non-constructed TLV with empty T, L and V part. */ | |
182 | static ASN_BER_TLV_t* construct(); | |
183 | /** Frees the given \a p_tlv recursively. Tstr, Lstr and | |
184 | * Vstr/tlvs. If \a no_str is TRUE, then only the tlvs are deleted, | |
185 | * the strings (Tstr, Lstr, Vstr) are not. This is useful during | |
186 | * decoding, when the Xstr points into a buffer.*/ | |
187 | static void destruct(ASN_BER_TLV_t *p_tlv, boolean no_str=FALSE); | |
188 | /** Checks the 'constructed' flag. If fails, raises an EncDec | |
189 | * error. */ | |
190 | void chk_constructed_flag(boolean flag_expected) const; | |
191 | /** Adds \a p_tlv to this (constructed) TLV. | |
192 | * @pre isConstructed is \c true | |
193 | * @pre V_tlvs_selected is \c true */ | |
194 | void add_TLV(ASN_BER_TLV_t *p_tlv); | |
195 | /** Adds a new UNIVERSAL 0 TLV to this (constructed) TLV. */ | |
196 | void add_UNIV0_TLV(); | |
197 | /** Returns the length (in bytes) of the full TLV. */ | |
198 | size_t get_len() const; | |
199 | /** Adds T and L part to TLV. It adds trailing UNI-0 TLV (two zero | |
200 | * octets) if the length form is indefinite. Precondition: | |
201 | * isConstructed (and V_tlvs_selected) and V-part are valid. */ | |
202 | void add_TL(ASN_Tagclass_t p_tagclass, | |
203 | ASN_Tagnumber_t p_tagnumber, | |
204 | unsigned coding); | |
205 | /** Puts the TLV in buffer \a p_buf. */ | |
206 | void put_in_buffer(TTCN_Buffer& p_buf); | |
207 | /** Gets the octet in position \a pos. Works also for constructed TLVs. */ | |
208 | unsigned char get_pos(size_t pos) const; | |
209 | private: | |
210 | unsigned char _get_pos(size_t& pos, boolean& success) const; | |
211 | public: | |
212 | /** Compares the TLVs as described in X.690 11.6. Returns -1 if this | |
213 | * less than, 0 if equal to, 1 if greater than other. */ | |
214 | int compare(const ASN_BER_TLV_t *other) const; | |
215 | /** Sorts its TLVs according to their octetstring representation, as | |
216 | * described in X.690 11.6. */ | |
217 | void sort_tlvs(); | |
218 | /** Compares the TLVs according their tags as described in X.680 | |
219 | * 8.6. Returns -1 if this less than, 0 if equal to, 1 if greater | |
220 | * than other. */ | |
221 | int compare_tags(const ASN_BER_TLV_t *other) const; | |
222 | /** Sorts its TLVs according to their tags, as described in X.690 | |
223 | * 10.3. */ | |
224 | void sort_tlvs_tag(); | |
225 | }; | |
226 | ||
227 | /** | |
228 | * Searches the T, L and V parts of the TLV represented in \a s, and | |
229 | * stores it in \a tlv. Returns FALSE if there isn't a complete | |
230 | * TLV-structure in \a s, TRUE otherwise. | |
231 | */ | |
232 | boolean ASN_BER_str2TLV(size_t p_len_s, | |
233 | const unsigned char* p_str, | |
234 | ASN_BER_TLV_t& tlv, | |
235 | unsigned L_form); | |
236 | ||
237 | /** | |
238 | * Adds the T and L part of the TLV. If there are multiple tags, then | |
239 | * adds them all. Precondition: the following fields are ready of \a | |
240 | * p_tlv: isConstructed, V_tlvs_selected, isLenDefinite, isLenShort | |
241 | * and V. If tagclass and tagnumber are UNIVERSAL 0, then replaces | |
242 | * them, otherwise 'wraps' p_tlv in a new TLV. | |
243 | */ | |
244 | ASN_BER_TLV_t* ASN_BER_V2TLV(ASN_BER_TLV_t* p_tlv, | |
245 | const TTCN_Typedescriptor_t& p_td, | |
246 | unsigned coding); | |
247 | ||
248 | /** @} end of BER group */ | |
249 | ||
250 | #endif // _BER_HH |