File: BER.hh

package info (click to toggle)
eclipse-titan 6.1.0-1
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 79,084 kB
  • ctags: 29,092
  • sloc: cpp: 210,764; ansic: 44,862; yacc: 21,034; sh: 12,594; makefile: 12,225; lex: 8,972; xml: 5,348; java: 4,849; perl: 3,780; python: 2,834; php: 175
file content (257 lines) | stat: -rw-r--r-- 9,374 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
/******************************************************************************
 * Copyright (c) 2000-2016 Ericsson Telecom AB
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Balasko, Jeno
 *   Forstner, Matyas
 *   Raduly, Csaba
 *   Szabo, Janos Zoltan – initial implementation
 *
 ******************************************************************************/
#ifndef _BER_HH
#define _BER_HH

/** @name BER encoding subtypes
    @{
*/
/// Canonical Encoding Rules
#define BER_ENCODE_CER 1
/// Distinguished Encoding Rules
#define BER_ENCODE_DER 2
/** @} */

/** @name BER decoding options
    @{
*/
/// Short length form is acceptable
#define BER_ACCEPT_SHORT 0x01
/// Long length form is acceptable
#define BER_ACCEPT_LONG 0x02
/// Indefinite form is acceptable
#define BER_ACCEPT_INDEFINITE 0x04
/// Definite forms (short or long) are acceptable
#define BER_ACCEPT_DEFINITE 0x03
/// All forms are acceptable
#define BER_ACCEPT_ALL 0x07
/** @} */

#include "Types.h"
#include "Encdec.hh"

/**
  * \defgroup BER BER-related stuff.
  *
  *  @{
  */

/** @brief ASN.1 tag */
enum ASN_Tagclass_t {
  ASN_TAG_UNDEF,
  ASN_TAG_UNIV, /**< UNIVERSAL */
  ASN_TAG_APPL, /**< APPLICATION */
  ASN_TAG_CONT, /**< context-specific */
  ASN_TAG_PRIV  /**< PRIVATE */
};

typedef unsigned int ASN_Tagnumber_t;

/** @brief ASN.1 identifier
  *
  * Contains two thirds of the T from a TLV
  */
struct ASN_Tag_t {
  ASN_Tagclass_t tagclass; /**< Tag class */
  ASN_Tagnumber_t tagnumber; /**< Tag value. For UNIVERSAL, the values are predefined */

  /** Creates a user-friendly representation of the tag. After using,
    * you have to Free() this string. */
  char* print() const;
};

/** @brief BER encoding information
 *
 * There is one object for each predefined (UNIVERSAL) type.
 * Also, the compiler writes an object of this type for each user-defined type
 * into the generated code in Common::Type::generate_code_berdescriptor() .
 */
struct ASN_BERdescriptor_t {
  /** Number of tags.
   *
   *  For the UNIVERSAL classes, this is usually 1 (except for CHOICE and ANY)
   */
  size_t n_tags;
  /** This array contains the tags. Index 0 is the innermost tag. */
  const ASN_Tag_t *tags;

  /** Creates a user-friendly representation of tags. After using, you
    * have to Free() this string. */
  char* print_tags() const;
};

struct TTCN_Typedescriptor_t;

extern const ASN_BERdescriptor_t BOOLEAN_ber_;
extern const ASN_BERdescriptor_t INTEGER_ber_;
extern const ASN_BERdescriptor_t BITSTRING_ber_;
extern const ASN_BERdescriptor_t OCTETSTRING_ber_;
extern const ASN_BERdescriptor_t ASN_NULL_ber_;
extern const ASN_BERdescriptor_t OBJID_ber_;
extern const ASN_BERdescriptor_t ObjectDescriptor_ber_;
extern const ASN_BERdescriptor_t FLOAT_ber_;
extern const ASN_BERdescriptor_t ENUMERATED_ber_;
extern const ASN_BERdescriptor_t UTF8String_ber_;
extern const ASN_BERdescriptor_t ASN_ROID_ber_;
extern const ASN_BERdescriptor_t SEQUENCE_ber_;
extern const ASN_BERdescriptor_t SET_ber_;
extern const ASN_BERdescriptor_t CHOICE_ber_;
extern const ASN_BERdescriptor_t ASN_ANY_ber_;
extern const ASN_BERdescriptor_t NumericString_ber_;
extern const ASN_BERdescriptor_t PrintableString_ber_;
extern const ASN_BERdescriptor_t TeletexString_ber_;
extern const ASN_BERdescriptor_t VideotexString_ber_;
extern const ASN_BERdescriptor_t IA5String_ber_;
extern const ASN_BERdescriptor_t ASN_UTCTime_ber_;
extern const ASN_BERdescriptor_t ASN_GeneralizedTime_ber_;
extern const ASN_BERdescriptor_t GraphicString_ber_;
extern const ASN_BERdescriptor_t VisibleString_ber_;
extern const ASN_BERdescriptor_t GeneralString_ber_;
extern const ASN_BERdescriptor_t UniversalString_ber_;
extern const ASN_BERdescriptor_t BMPString_ber_;
extern const ASN_BERdescriptor_t EXTERNAL_ber_;
extern const ASN_BERdescriptor_t EMBEDDED_PDV_ber_;
extern const ASN_BERdescriptor_t CHARACTER_STRING_ber_;

/** An unsigned long long with 7 bits set (0x7F) in the most significant byte.
 *  Used when decoding objid values. */
extern const unsigned long long unsigned_llong_7msb;

/** An unsigned long with 8 bits set (0xFF) in the most significant byte.
 *  Used when decoding integers. */
extern const unsigned long unsigned_long_8msb;

/** How many bits are needed minimally to represent the given
  * (nonnegative integral) value. Returned value is greater than or
  * equal to 1. */
template<typename T>
size_t min_needed_bits(T p)
{
  if(p==0) return 1;
  register size_t n=0;
  register T tmp=p;
  while(tmp!=0) n++, tmp/=2;
  return n;
}

/** This struct represents a BER TLV.
 *
 * It represents a "deconstructed" (cooked) representation of
 * a BER encoding. */
struct ASN_BER_TLV_t {
  boolean isConstructed;   /**< Primitive/Constructed bit. */
  boolean V_tlvs_selected; /**< How the data is stored in \p V. */
  boolean isLenDefinite;   /**< \c false for indefinite form */
  boolean isLenShort;      /**< \c true for short form (0-127) */
  /** Is \p tagclass and \p tagnumber valid.
   *  ASN_BER_str2TLV function sets this. */
  boolean isTagComplete;
  boolean isComplete;
  ASN_Tagclass_t tagclass; /**< UNIV/APP/context/PRIVATE */
  ASN_Tagnumber_t tagnumber;
  size_t Tlen; /** Length of T part. May be >1 for tag values >30 */
  size_t Llen; /** Length of L part. */
  unsigned char *Tstr; /** Encoded T part. */
  unsigned char *Lstr; /** Encoded L part. */
  union { /* depends on V_tlvs_selected */
    struct {
      size_t Vlen;
      unsigned char *Vstr;
    } str; /**< V_tlvs_selected==FALSE */
    struct {
      size_t n_tlvs;
      ASN_BER_TLV_t **tlvs;
    } tlvs; /**< V_tlvs_selected==TRUE */
  } V;

  /** Creates a new constructed TLV which contains one TLV (\a
    * p_tlv). Or, if the parameter is NULL, then an empty constructed
    * TLV is created. */
  static ASN_BER_TLV_t* construct(ASN_BER_TLV_t *p_tlv);
  /** Creates a new non-constructed TLV with the given V-part.
    * Tagclass and -number are set to UNIV-0. If \a p_Vstr is NULL
    * then allocates a \a p_Vlen size buffer for Vstr.
    * Takes over ownership of \a p_Vstr */
  static ASN_BER_TLV_t* construct(size_t p_Vlen, unsigned char *p_Vstr);
  /** Creates a new non-constructed TLV with empty T, L and V part. */
  static ASN_BER_TLV_t* construct();
  /** Frees the given \a p_tlv recursively. Tstr, Lstr and
    * Vstr/tlvs. If \a no_str is TRUE, then only the tlvs are deleted,
    * the strings (Tstr, Lstr, Vstr) are not. This is useful during
    * decoding, when the Xstr points into a buffer.*/
  static void destruct(ASN_BER_TLV_t *p_tlv, boolean no_str=FALSE);
  /** Checks the 'constructed' flag. If fails, raises an EncDec
    * error. */
  void chk_constructed_flag(boolean flag_expected) const;
  /** Adds \a p_tlv to this (constructed) TLV.
   * @pre isConstructed   is \c true
   * @pre V_tlvs_selected is \c true */
  void add_TLV(ASN_BER_TLV_t *p_tlv);
  /** Adds a new UNIVERSAL 0 TLV to this (constructed) TLV. */
  void add_UNIV0_TLV();
  /** Returns the length (in bytes) of the full TLV. */
  size_t get_len() const;
  /** Adds T and L part to TLV. It adds trailing UNI-0 TLV (two zero
    * octets) if the length form is indefinite. Precondition:
    * isConstructed (and V_tlvs_selected) and V-part are valid. */
  void add_TL(ASN_Tagclass_t p_tagclass,
              ASN_Tagnumber_t p_tagnumber,
              unsigned coding);
  /** Puts the TLV in buffer \a p_buf. */
  void put_in_buffer(TTCN_Buffer& p_buf);
  /** Gets the octet in position \a pos. Works also for constructed TLVs. */
  unsigned char get_pos(size_t pos) const;
private:
  unsigned char _get_pos(size_t& pos, boolean& success) const;
public:
  /** Compares the TLVs as described in X.690 11.6. Returns -1 if this
    * less than, 0 if equal to, 1 if greater than other. */
  int compare(const ASN_BER_TLV_t *other) const;
  /** Sorts its TLVs according to their octetstring representation, as
    * described in X.690 11.6. */
  void sort_tlvs();
  /** Compares the TLVs according their tags as described in X.680
    * 8.6. Returns -1 if this less than, 0 if equal to, 1 if greater
    * than other. */
  int compare_tags(const ASN_BER_TLV_t *other) const;
  /** Sorts its TLVs according to their tags, as described in X.690
    * 10.3. */
  void sort_tlvs_tag();
};

/**
  * Searches the T, L and V parts of the TLV represented in \a s, and
  * stores it in \a tlv. Returns FALSE if there isn't a complete
  * TLV-structure in \a s, TRUE otherwise.
  */
boolean ASN_BER_str2TLV(size_t p_len_s,
                        const unsigned char* p_str,
                        ASN_BER_TLV_t& tlv,
                        unsigned L_form);

/**
  * Adds the T and L part of the TLV. If there are multiple tags, then
  * adds them all. Precondition: the following fields are ready of \a
  * p_tlv: isConstructed, V_tlvs_selected, isLenDefinite, isLenShort
  * and V. If tagclass and tagnumber are UNIVERSAL 0, then replaces
  * them, otherwise 'wraps' p_tlv in a new TLV.
  */
ASN_BER_TLV_t* ASN_BER_V2TLV(ASN_BER_TLV_t* p_tlv,
                             const TTCN_Typedescriptor_t& p_td,
                             unsigned coding);

/** @} end of BER group */

#endif // _BER_HH