Merge pull request #83 from eadrkir/master
[deliverable/titan.core.git] / core / BER.hh
CommitLineData
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 */
52enum 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
60typedef unsigned int ASN_Tagnumber_t;
61
62/** @brief ASN.1 identifier
63 *
64 * Contains two thirds of the T from a TLV
65 */
66struct 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 */
81struct 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
95struct TTCN_Typedescriptor_t;
96
97extern const ASN_BERdescriptor_t BOOLEAN_ber_;
98extern const ASN_BERdescriptor_t INTEGER_ber_;
99extern const ASN_BERdescriptor_t BITSTRING_ber_;
100extern const ASN_BERdescriptor_t OCTETSTRING_ber_;
101extern const ASN_BERdescriptor_t ASN_NULL_ber_;
102extern const ASN_BERdescriptor_t OBJID_ber_;
103extern const ASN_BERdescriptor_t ObjectDescriptor_ber_;
104extern const ASN_BERdescriptor_t FLOAT_ber_;
105extern const ASN_BERdescriptor_t ENUMERATED_ber_;
106extern const ASN_BERdescriptor_t UTF8String_ber_;
107extern const ASN_BERdescriptor_t ASN_ROID_ber_;
108extern const ASN_BERdescriptor_t SEQUENCE_ber_;
109extern const ASN_BERdescriptor_t SET_ber_;
110extern const ASN_BERdescriptor_t CHOICE_ber_;
111extern const ASN_BERdescriptor_t ASN_ANY_ber_;
112extern const ASN_BERdescriptor_t NumericString_ber_;
113extern const ASN_BERdescriptor_t PrintableString_ber_;
114extern const ASN_BERdescriptor_t TeletexString_ber_;
115extern const ASN_BERdescriptor_t VideotexString_ber_;
116extern const ASN_BERdescriptor_t IA5String_ber_;
117extern const ASN_BERdescriptor_t ASN_UTCTime_ber_;
118extern const ASN_BERdescriptor_t ASN_GeneralizedTime_ber_;
119extern const ASN_BERdescriptor_t GraphicString_ber_;
120extern const ASN_BERdescriptor_t VisibleString_ber_;
121extern const ASN_BERdescriptor_t GeneralString_ber_;
122extern const ASN_BERdescriptor_t UniversalString_ber_;
123extern const ASN_BERdescriptor_t BMPString_ber_;
124extern const ASN_BERdescriptor_t EXTERNAL_ber_;
125extern const ASN_BERdescriptor_t EMBEDDED_PDV_ber_;
126extern 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. */
130extern 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. */
134extern 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. */
139template<typename T>
140size_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. */
153struct 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;
216private:
217 unsigned char _get_pos(size_t& pos, boolean& success) const;
218public:
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 */
239boolean 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 */
251ASN_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
This page took 0.033116 seconds and 5 git commands to generate.