Last sync 2016.04.01
[deliverable/titan.core.git] / core / BER.cc
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 * Feher, Csaba
11 * Forstner, Matyas
12 * Raduly, Csaba
13 * Szabados, Kristof
14 * Szabo, Janos Zoltan – initial implementation
15 * Szalai, Gabor
16 *
17 ******************************************************************************/
970ed795
EL
18#include <stdio.h>
19#include <limits.h>
20#include <string.h>
21#include <stdlib.h>
22
23#include "../common/memory.h"
24#include "Basetype.hh"
25#include "BER.hh"
26#include "Error.hh"
27#include "Logger.hh"
28
29/** An \c ASN_Tagnumber_t with 7 bits set in the most significant byte */
30static const ASN_Tagnumber_t ASN_Tagnumber_t_7msb
31=static_cast<ASN_Tagnumber_t>(0x7F)<<(sizeof(ASN_Tagnumber_t)*8-8);
32
33/** A \c size_t value with 8 bits set (0xFF) in the most significant byte */
34static const size_t size_t_8msb
35=static_cast<size_t>(0xFF)<<(sizeof(size_t)*8-8);
36
37const unsigned long long unsigned_llong_7msb
38=static_cast<unsigned long long>(0x7F)<<(sizeof(unsigned long long)*8-8);
39
40const unsigned long unsigned_long_8msb
41=static_cast<unsigned long>(0xFF)<<(sizeof(unsigned long)*8-8);
42
43char* ASN_Tag_t::print() const
44{
45 const char *prefix;
46 switch (tagclass) {
47 case ASN_TAG_UNDEF:
48 prefix = "<UNDEF> ";
49 break;
50 case ASN_TAG_UNIV:
51 prefix = "UNIVERSAL ";
52 break;
53 case ASN_TAG_APPL:
54 prefix = "APPLICATION ";
55 break;
56 case ASN_TAG_CONT:
57 prefix = "";
58 break;
59 case ASN_TAG_PRIV:
60 prefix = "PRIVATE ";
61 break;
62 default:
63 prefix = "<ERROR> ";
64 break;
65 } // switch
66 return mprintf("[%s%u]", prefix, tagnumber);
67}
68
69char* ASN_BERdescriptor_t::print_tags() const
70{
71 if (n_tags == 0) return mcopystr("<no tags>");
72 else {
73 char *s = NULL;
74 for (size_t i = n_tags; i > 0; i--) {
75 char *tagstr = tags[i - 1].print();
76 s = mputstr(s, tagstr);
77 Free(tagstr);
78 if (i != 1) s = mputc(s, ' ');
79 } // for i
80 return s;
81 }
82}
83
84static const ASN_Tag_t BOOLEAN_tag_[]={{ASN_TAG_UNIV, 1u}};
85const ASN_BERdescriptor_t BOOLEAN_ber_={1u, BOOLEAN_tag_};
86
87static const ASN_Tag_t INTEGER_tag_[]={{ASN_TAG_UNIV, 2u}};
88const ASN_BERdescriptor_t INTEGER_ber_={1u, INTEGER_tag_};
89
90static const ASN_Tag_t BITSTRING_tag_[]={{ASN_TAG_UNIV, 3u}};
91const ASN_BERdescriptor_t BITSTRING_ber_={1u, BITSTRING_tag_};
92
93static const ASN_Tag_t OCTETSTRING_tag_[]={{ASN_TAG_UNIV, 4u}};
94const ASN_BERdescriptor_t OCTETSTRING_ber_={1u, OCTETSTRING_tag_};
95
96static const ASN_Tag_t ASN_NULL_tag_[]={{ASN_TAG_UNIV, 5u}};
97const ASN_BERdescriptor_t ASN_NULL_ber_={1u, ASN_NULL_tag_};
98
99static const ASN_Tag_t OBJID_tag_[]={{ASN_TAG_UNIV, 6u}};
100const ASN_BERdescriptor_t OBJID_ber_={1u, OBJID_tag_};
101
102static const ASN_Tag_t ObjectDescriptor_tag_[]={{ASN_TAG_UNIV, 7u}};
103const ASN_BERdescriptor_t ObjectDescriptor_ber_={1u, ObjectDescriptor_tag_};
104
105static const ASN_Tag_t EXTERNAL_tag_[]={{ASN_TAG_UNIV, 8u}};
106const ASN_BERdescriptor_t EXTERNAL_ber_={1u, EXTERNAL_tag_};
107
108static const ASN_Tag_t REAL_tag_[]={{ASN_TAG_UNIV, 9u}};
109const ASN_BERdescriptor_t FLOAT_ber_={1u, REAL_tag_};
110
111static const ASN_Tag_t ENUMERATED_tag_[]={{ASN_TAG_UNIV, 10u}};
112const ASN_BERdescriptor_t ENUMERATED_ber_={1u, ENUMERATED_tag_};
113
114static const ASN_Tag_t EMBEDDED_PDV_tag_[]={{ASN_TAG_UNIV, 11u}};
115const ASN_BERdescriptor_t EMBEDDED_PDV_ber_={1u, EMBEDDED_PDV_tag_};
116
117static const ASN_Tag_t UTF8String_tag_[]={{ASN_TAG_UNIV, 12u}};
118const ASN_BERdescriptor_t UTF8String_ber_={1u, UTF8String_tag_};
119
120static const ASN_Tag_t ASN_ROID_tag_[]={{ASN_TAG_UNIV, 13u}};
121const ASN_BERdescriptor_t ASN_ROID_ber_={1u, ASN_ROID_tag_};
122
123static const ASN_Tag_t SEQUENCE_tag_[]={{ASN_TAG_UNIV, 16u}};
124const ASN_BERdescriptor_t SEQUENCE_ber_={1u, SEQUENCE_tag_};
125
126static const ASN_Tag_t SET_tag_[]={{ASN_TAG_UNIV, 17u}};
127const ASN_BERdescriptor_t SET_ber_={1u, SET_tag_};
128
129const ASN_BERdescriptor_t CHOICE_ber_={0u, NULL};
130
131const ASN_BERdescriptor_t ASN_ANY_ber_={0u, NULL};
132
133static const ASN_Tag_t NumericString_tag_[]={{ASN_TAG_UNIV, 18u}};
134const ASN_BERdescriptor_t NumericString_ber_={1u, NumericString_tag_};
135
136static const ASN_Tag_t PrintableString_tag_[]={{ASN_TAG_UNIV, 19u}};
137const ASN_BERdescriptor_t PrintableString_ber_={1u, PrintableString_tag_};
138
139static const ASN_Tag_t TeletexString_tag_[]={{ASN_TAG_UNIV, 20u}};
140const ASN_BERdescriptor_t TeletexString_ber_={1u, TeletexString_tag_};
141
142static const ASN_Tag_t VideotexString_tag_[]={{ASN_TAG_UNIV, 21u}};
143const ASN_BERdescriptor_t VideotexString_ber_={1u, VideotexString_tag_};
144
145static const ASN_Tag_t IA5String_tag_[]={{ASN_TAG_UNIV, 22u}};
146const ASN_BERdescriptor_t IA5String_ber_={1u, IA5String_tag_};
147
148static const ASN_Tag_t ASN_UTCTime_tag_[]={{ASN_TAG_UNIV, 23u}};
149const ASN_BERdescriptor_t ASN_UTCTime_ber_={1u, ASN_UTCTime_tag_};
150
151static const ASN_Tag_t ASN_GeneralizedTime_tag_[]={{ASN_TAG_UNIV, 24u}};
152const ASN_BERdescriptor_t ASN_GeneralizedTime_ber_={1u, ASN_GeneralizedTime_tag_};
153
154static const ASN_Tag_t GraphicString_tag_[]={{ASN_TAG_UNIV, 25u}};
155const ASN_BERdescriptor_t GraphicString_ber_={1u, GraphicString_tag_};
156
157static const ASN_Tag_t VisibleString_tag_[]={{ASN_TAG_UNIV, 26u}};
158const ASN_BERdescriptor_t VisibleString_ber_={1u, VisibleString_tag_};
159
160const ASN_Tag_t GeneralString_tag_[]={{ASN_TAG_UNIV, 27u}};
161const ASN_BERdescriptor_t GeneralString_ber_={1u, GeneralString_tag_};
162
163static const ASN_Tag_t UniversalString_tag_[]={{ASN_TAG_UNIV, 28u}};
164const ASN_BERdescriptor_t UniversalString_ber_={1u, UniversalString_tag_};
165
166static const ASN_Tag_t CHARACTER_STRING_tag_[]={{ASN_TAG_UNIV, 29u}};
167const ASN_BERdescriptor_t CHARACTER_STRING_ber_={1u, CHARACTER_STRING_tag_};
168
169static const ASN_Tag_t BMPString_tag_[]={{ASN_TAG_UNIV, 30u}};
170const ASN_BERdescriptor_t BMPString_ber_={1u, BMPString_tag_};
171
172ASN_BER_TLV_t* ASN_BER_TLV_t::construct(ASN_BER_TLV_t *p_tlv)
173{
174 ASN_BER_TLV_t *new_tlv = (ASN_BER_TLV_t*)Malloc(sizeof(*new_tlv));
175 new_tlv->isConstructed = TRUE;
176 new_tlv->V_tlvs_selected = TRUE;
177 new_tlv->isLenDefinite = FALSE;
178 new_tlv->isLenShort = FALSE;
179 new_tlv->isTagComplete = FALSE;
180 new_tlv->isComplete = FALSE;
181 new_tlv->tagclass = ASN_TAG_UNIV;
182 new_tlv->tagnumber = 0;
183 new_tlv->Tlen = 0;
184 new_tlv->Llen = 0;
185 new_tlv->Tstr = NULL;
186 new_tlv->Lstr = NULL;
187 if (p_tlv != NULL) {
188 new_tlv->V.tlvs.n_tlvs = 1;
189 new_tlv->V.tlvs.tlvs = (ASN_BER_TLV_t**)
190 Malloc(sizeof(*new_tlv->V.tlvs.tlvs));
191 new_tlv->V.tlvs.tlvs[0] = p_tlv;
192 } else {
193 new_tlv->V.tlvs.n_tlvs = 0;
194 new_tlv->V.tlvs.tlvs = NULL;
195 }
196 return new_tlv;
197}
198
199ASN_BER_TLV_t* ASN_BER_TLV_t::construct(size_t p_Vlen, unsigned char *p_Vstr)
200{
201 ASN_BER_TLV_t *new_tlv = (ASN_BER_TLV_t*)Malloc(sizeof(*new_tlv));
202 new_tlv->isConstructed = FALSE;
203 new_tlv->V_tlvs_selected = FALSE;
204 new_tlv->isLenDefinite = FALSE;
205 new_tlv->isLenShort = FALSE;
206 new_tlv->isTagComplete = FALSE;
207 new_tlv->isComplete = FALSE;
208 new_tlv->tagclass = ASN_TAG_UNIV;
209 new_tlv->tagnumber = 0;
210 new_tlv->Tlen = 0;
211 new_tlv->Llen = 0;
212 new_tlv->Tstr = NULL;
213 new_tlv->Lstr = NULL;
214 new_tlv->V.str.Vlen = p_Vlen;
215 if (p_Vstr != NULL) new_tlv->V.str.Vstr = p_Vstr;
216 else new_tlv->V.str.Vstr = (unsigned char*)Malloc(p_Vlen);
217 return new_tlv;
218}
219
220ASN_BER_TLV_t* ASN_BER_TLV_t::construct()
221{
222 ASN_BER_TLV_t *new_tlv = (ASN_BER_TLV_t*)Malloc(sizeof(*new_tlv));
223 new_tlv->isConstructed = FALSE;
224 new_tlv->V_tlvs_selected = FALSE;
225 new_tlv->isLenDefinite = FALSE;
226 new_tlv->isLenShort = FALSE;
227 new_tlv->isTagComplete = FALSE;
228 new_tlv->isComplete = FALSE;
229 new_tlv->tagclass = ASN_TAG_UNIV;
230 new_tlv->tagnumber = 0;
231 new_tlv->Tlen = 0;
232 new_tlv->Llen = 0;
233 new_tlv->Tstr = NULL;
234 new_tlv->Lstr = NULL;
235 new_tlv->V.str.Vlen = 0;
236 new_tlv->V.str.Vstr = NULL;
237 return new_tlv;
238}
239
240void ASN_BER_TLV_t::destruct(ASN_BER_TLV_t *p_tlv, boolean no_str)
241{
242 if (p_tlv == NULL) return;
243 if(!no_str) {
244 Free(p_tlv->Tstr);
245 Free(p_tlv->Lstr);
246 }
247 if(p_tlv->V_tlvs_selected) {
248 for(size_t i=0; i<p_tlv->V.tlvs.n_tlvs; i++)
249 ASN_BER_TLV_t::destruct(p_tlv->V.tlvs.tlvs[i], no_str);
250 Free(p_tlv->V.tlvs.tlvs);
251 }
252 else {
253 if(!no_str)
254 Free(p_tlv->V.str.Vstr);
255 }
256 Free(p_tlv);
257}
258
259void ASN_BER_TLV_t::chk_constructed_flag(boolean flag_expected) const
260{
261 if (Tlen > 0 && isConstructed != flag_expected)
262 TTCN_EncDec_ErrorContext::error
263 (TTCN_EncDec::ET_INVAL_MSG,
264 "Invalid 'constructed' flag (must be %sset).",
265 flag_expected?"":"un");
266
267}
268
269void ASN_BER_TLV_t::add_TLV(ASN_BER_TLV_t *p_tlv)
270{
271 if(!isConstructed || !V_tlvs_selected)
272 TTCN_EncDec_ErrorContext::error_internal
273 ("ASN_BER_TLV_t::add_TLV() invoked for a non-constructed TLV.");
274 V.tlvs.n_tlvs++;
275 V.tlvs.tlvs=(ASN_BER_TLV_t**)
276 Realloc(V.tlvs.tlvs, V.tlvs.n_tlvs*sizeof(*V.tlvs.tlvs));
277 V.tlvs.tlvs[V.tlvs.n_tlvs-1]=p_tlv;
278}
279
280void ASN_BER_TLV_t::add_UNIV0_TLV()
281{
282 ASN_BER_TLV_t *new_tlv=(ASN_BER_TLV_t*)Malloc(sizeof(*new_tlv));
283 new_tlv->isConstructed=FALSE;
284 new_tlv->V_tlvs_selected=FALSE;
285 new_tlv->isLenDefinite=TRUE;
286 new_tlv->isLenShort=TRUE;
287 new_tlv->tagclass=ASN_TAG_UNIV;
288 new_tlv->tagnumber=0;
289 new_tlv->Tlen=1;
290 new_tlv->Tstr=(unsigned char*)Malloc(1);
291 new_tlv->Tstr[0]=0x00;
292 new_tlv->Llen=1;
293 new_tlv->Lstr=(unsigned char*)Malloc(1);
294 new_tlv->Lstr[0]=0x00;
295 new_tlv->V.str.Vlen=0;
296 new_tlv->V.str.Vstr=NULL;
297 add_TLV(new_tlv);
298}
299
300size_t ASN_BER_TLV_t::get_len() const
301{
302 size_t len=Tlen+Llen;
303 if(!V_tlvs_selected)
304 len+=V.str.Vlen;
305 else
306 for(size_t i=0; i<V.tlvs.n_tlvs; i++)
307 len+=V.tlvs.tlvs[i]->get_len();
308 return len;
309}
310
311void ASN_BER_TLV_t::add_TL(ASN_Tagclass_t p_tagclass,
312 ASN_Tagnumber_t p_tagnumber,
313 unsigned coding)
314{
315 TTCN_EncDec_ErrorContext ec("ASN_BER_TLV_t::add_TL(): ");
316 tagclass=p_tagclass;
317 tagnumber=p_tagnumber;
318 /* L-part */
319 if(coding==BER_ENCODE_CER && isConstructed) {
320 isLenDefinite=FALSE;
321 add_UNIV0_TLV();
322 }
323 else {
324 isLenDefinite=TRUE;
325 }
326 size_t Vlen=0;
327 if(isLenDefinite) {
328 Tlen=Llen=0;
329 Vlen=get_len();
330 if(Vlen>127) {
331 isLenShort=FALSE;
332 Llen=1+(min_needed_bits(Vlen)+7)/8;
333 }
334 else {
335 isLenShort=TRUE;
336 Llen=1;
337 }
338 }
339 else Llen=1;
340 Lstr=(unsigned char*)Malloc(Llen);
341 if(isLenDefinite) {
342 if(isLenShort) Lstr[0]=(unsigned char)Vlen;
343 else { // long form
344 size_t i=Llen-1; // number of needed octets
345 Lstr[0]=(i & 0x7F) | 0x80;
346 size_t tmp=Vlen;
347 while(i) {
348 Lstr[i]=tmp & 0xFF;
349 i--;
350 tmp>>=8;
351 }
352 }
353 } // isLenDefinite
354 else { // indefinite form
355 Lstr[0]=0x80;
356 }
357 /* T-part */
358 if(tagnumber>30) Tlen=1+(min_needed_bits(tagnumber)+6)/7;
359 else Tlen=1;
360 Tstr=(unsigned char*)Malloc(Tlen);
361
362 switch(tagclass) {
363 case ASN_TAG_UNIV: Tstr[0]=0x00; break;
364 case ASN_TAG_APPL: Tstr[0]=0x40; break;
365 case ASN_TAG_CONT: Tstr[0]=0x80; break;
366 case ASN_TAG_PRIV: Tstr[0]=0xC0; break;
367 case ASN_TAG_UNDEF:
368 default:
369 ec.error_internal("Unhandled case or undefined tagclass.");
370 break;
371 }
372 if(isConstructed) Tstr[0]|=0x20;
373 if(tagnumber<=30) Tstr[0]|=(unsigned char)tagnumber;
374 else {
375 Tstr[0]|=0x1F;
376 size_t tmp=tagnumber;
377 size_t i=Tlen-1; // number of needed octets
378 while(i) {
379 Tstr[i]=(tmp & 0x7F) | 0x80;
380 i--;
381 tmp>>=7;
382 }
383 Tstr[Tlen-1]&=0x7F;
384 }
385 isComplete = TRUE;
386 isTagComplete = TRUE;
387}
388
389void ASN_BER_TLV_t::put_in_buffer(TTCN_Buffer& p_buf)
390{
391 p_buf.put_s(Tlen, Tstr);
392 p_buf.put_s(Llen, Lstr);
393
394 if(!V_tlvs_selected)
395 p_buf.put_s(V.str.Vlen, V.str.Vstr);
396 else
397 for(size_t i=0; i<V.tlvs.n_tlvs; i++)
398 V.tlvs.tlvs[i]->put_in_buffer(p_buf);
399}
400
401unsigned char ASN_BER_TLV_t::get_pos(size_t p_pos) const
402{
403 size_t pos=p_pos;
404 boolean success=FALSE;
405 unsigned char c=_get_pos(pos, success);
406 if(!success)
407 TTCN_EncDec_ErrorContext::error_internal
408 ("Index overflow in ASN_BER_TLV_t::get_pos()");
409 return c;
410}
411
412unsigned char ASN_BER_TLV_t::_get_pos(size_t& pos, boolean& success) const
413{
414 if(pos<Tlen) {success=TRUE; return Tstr[pos];}
415 pos-=Tlen;
416 if(pos<Llen) {success=TRUE; return Lstr[pos];}
417 pos-=Llen;
418
419 if(!V_tlvs_selected) {
420 if(pos<V.str.Vlen) {success=TRUE; return V.str.Vstr[pos];}
421 pos-=V.str.Vlen;
422 }
423 else { // V_tlvs_selected
424 for(size_t i=0; i<V.tlvs.n_tlvs; i++) {
425 unsigned char c=V.tlvs.tlvs[i]->_get_pos(pos, success);
426 if(success) return c;
427 }
428 }
429 success=FALSE; return 0;
430}
431
432int ASN_BER_TLV_t::compare(const ASN_BER_TLV_t *other) const
433{
434 size_t pos=0, pos1, pos2;
435 boolean success1;
436 boolean success2;
437 unsigned char c1, c2;
438 do {
439 pos1=pos2=pos;
440 c1=_get_pos(pos1, success1);
441 c2=other->_get_pos(pos2, success2);
442 if(!success1 && !success2) return 0;
443 if(c1<c2) return -1;
444 if(c1>c2) return 1;
445 pos++;
446 } while(1);
447}
448
449/** This functions is used by qsort() in
450 * ASN_BER_TLV_t::sort_tlvs(). */
451int ASN_BER_compare_TLVs(const void *p1, const void *p2)
452{
453 const ASN_BER_TLV_t *left=*((ASN_BER_TLV_t const* const*)p1);
454 const ASN_BER_TLV_t *right=*((ASN_BER_TLV_t const* const*)p2);
455 return left->compare(right);
456}
457
458void ASN_BER_TLV_t::sort_tlvs()
459{
460 if(!V_tlvs_selected)
461 TTCN_EncDec_ErrorContext::error_internal
462 ("ASN_BER_TLV_t::sort_tlvs() called but !V_tlvs_selected");
463 qsort(V.tlvs.tlvs, V.tlvs.n_tlvs, sizeof(ASN_BER_TLV_t*),
464 ASN_BER_compare_TLVs);
465}
466
467int ASN_BER_TLV_t::compare_tags(const ASN_BER_TLV_t *other) const
468{
469 if(tagclass<other->tagclass) return -1;
470 if(tagclass>other->tagclass) return 1;
471 if(tagnumber<other->tagnumber) return -1;
472 if(tagnumber>other->tagnumber) return 1;
473 return 0;
474}
475
476/** This functions is used by qsort() in
477 * ASN_BER_TLV_t::sort_tlvs_tag(). */
478int ASN_BER_compare_TLVs_tag(const void *p1, const void *p2)
479{
480 const ASN_BER_TLV_t *left=*((ASN_BER_TLV_t const* const*)p1);
481 const ASN_BER_TLV_t *right=*((ASN_BER_TLV_t const* const*)p2);
482 return left->compare_tags(right);
483}
484
485void ASN_BER_TLV_t::sort_tlvs_tag()
486{
487 if(!V_tlvs_selected)
488 TTCN_EncDec_ErrorContext::error_internal
489 ("ASN_BER_TLV_t::sort_tlvs_tag() called but !V_tlvs_selected");
490 qsort(V.tlvs.tlvs, V.tlvs.n_tlvs, sizeof(ASN_BER_TLV_t*),
491 ASN_BER_compare_TLVs_tag);
492}
493
494boolean ASN_BER_str2TLV(size_t p_len_s,
495 const unsigned char* p_str,
496 ASN_BER_TLV_t& tlv,
497 unsigned L_form)
498{
499 size_t curr_pos=0;
500 unsigned char c, c2;
501 boolean doit;
502 TTCN_EncDec_ErrorContext ec("While splitting TLV: ");
503
504 tlv.isConstructed=FALSE;
505 tlv.V_tlvs_selected=FALSE;
506 tlv.isLenDefinite=TRUE;
507 tlv.isLenShort=TRUE;
508 tlv.isTagComplete=FALSE;
509 tlv.isComplete=FALSE;
510 tlv.tagclass=ASN_TAG_UNIV;
511 tlv.tagnumber=0;
512 tlv.Tlen=0;
513 tlv.Llen=0;
514 tlv.V.str.Vlen=0;
515 tlv.Tstr=NULL;
516 tlv.Lstr=NULL;
517 tlv.V.str.Vstr=NULL;
518
519 if(p_len_s==0)
520 goto incomplete;
521 tlv.Tstr=const_cast<unsigned char*>(p_str);
522 c=p_str[0];
523 switch((c & 0xC0) >> 6) {
524 case 0: tlv.tagclass=ASN_TAG_UNIV; break;
525 case 1: tlv.tagclass=ASN_TAG_APPL; break;
526 case 2: tlv.tagclass=ASN_TAG_CONT; break;
527 case 3: tlv.tagclass=ASN_TAG_PRIV; break;
528 }
529 if(c & 0x20) tlv.isConstructed=TRUE;
530 else tlv.isConstructed=FALSE;
531 c2=c & 0x1F;
532 if(c2 != 0x1F) // low tag number
533 tlv.tagnumber=c2;
534 else { // high tag number
535 tlv.tagnumber=0; doit=TRUE;
536 boolean err_repr=FALSE;
537 while(doit) {
538 curr_pos++;
539 if(curr_pos>=p_len_s)
540 goto incomplete;
541 c=p_str[curr_pos];
542 if(!err_repr) {
543 if(tlv.tagnumber & ASN_Tagnumber_t_7msb) {
544 err_repr=TRUE;
545 ec.error(TTCN_EncDec::ET_REPR, "Tag number is too big.");
546 tlv.tagnumber=~(ASN_Tagnumber_t)0;
547 } // if 7msb on
548 else {
549 tlv.tagnumber<<=7;
550 tlv.tagnumber|=c & 0x7F;
551 }
552 } // !err_repr
553 if(!(c & 0x80)) doit=FALSE;
554 }
555 } // high tag number
556 tlv.isTagComplete=TRUE;
557 curr_pos++;
558 if(curr_pos>=p_len_s)
559 goto incomplete;
560
561 tlv.Lstr=const_cast<unsigned char*>(p_str+curr_pos);
562 tlv.Tlen=tlv.Lstr-tlv.Tstr;
563 tlv.isLenDefinite=TRUE;
564 tlv.isLenShort=FALSE;
565 c=p_str[curr_pos];
566 if(!(c & 0x80)) { // short form
567 tlv.Llen=1;
568 tlv.V.str.Vlen=c;
569 tlv.isLenShort=TRUE;
570 if(!(L_form & BER_ACCEPT_SHORT)) {
571 ec.error(TTCN_EncDec::ET_LEN_FORM,
572 "Short length form is not acceptable.");
573 } // if wrong L_form
574 }
575 else {
576 if(c==0x80) { // indefinite len
577 tlv.Llen=1;
578 tlv.isLenDefinite=FALSE;
579 if(!(L_form & BER_ACCEPT_INDEFINITE)) {
580 ec.error(TTCN_EncDec::ET_LEN_FORM,
581 "Indefinite length form is not acceptable.");
582 } // if wrong L_form
583 }
584 else if(c==0xFF) { // reserved len
585 ec.error(TTCN_EncDec::ET_INVAL_MSG,
586 "Error in L: In the long form, the value 0xFF shall"
587 " not be used (see X.690 clause 8.1.3.5.c)).");
588 // using as normal long form
589 } // if reserved len
590 else { // long form
591 if(!(L_form & BER_ACCEPT_LONG)) {
592 ec.error(TTCN_EncDec::ET_LEN_FORM,
593 "Long length form is not acceptable.");
594 } // if wrong L_form
595 tlv.Llen=(c & 0x7F)+1;
596 if(tlv.Tlen+tlv.Llen>p_len_s) {
597 tlv.Llen=p_len_s-tlv.Tlen;
598 goto incomplete;
599 }
600 tlv.V.str.Vlen=0;
601 boolean err_repr=FALSE;
602 for(size_t i=tlv.Llen-1; i; i--) {
603 if(!err_repr) {
604 if(tlv.V.str.Vlen & size_t_8msb) {
605 err_repr=TRUE;
606 ec.error(TTCN_EncDec::ET_REPR,
607 "In long form L: Length of V is too big.");
608 tlv.V.str.Vlen=~(size_t)0;
609 } // if 8msb on
610 else
611 tlv.V.str.Vlen<<=8;
612 } // if !err_repr
613 curr_pos++;
614 if(!err_repr) {
615 c=p_str[curr_pos];
616 tlv.V.str.Vlen|=c;
617 } // if !err_repr
618 } // for i
619 } // if long form
620 }
621 curr_pos++;
622 tlv.V.str.Vstr=const_cast<unsigned char*>(p_str+curr_pos);
623 if(tlv.isLenDefinite) {
624 if(tlv.V.str.Vlen>p_len_s-tlv.Tlen-tlv.Llen) {
625 goto incomplete;
626 }
627 } // definite len
628 else { // indefinite len for V
629 if(!tlv.isConstructed) {
630 ec.error(TTCN_EncDec::ET_INVAL_MSG,
631 "A sender can use the indefinite form only if the"
632 " encoding is constructed (see X.690 clause 8.1.3.2.a).");
633 } // if !isConstructed
634
635 TTCN_EncDec_ErrorContext tmp_ec;
636 ASN_BER_TLV_t tmp_tlv;
637 size_t tmp_len;
638 size_t i=1;
639 doit=TRUE;
640 while(doit) {
641 tmp_ec.set_msg("While checking constructed V part #%lu: ",
642 (unsigned long) i);
643 if(!ASN_BER_str2TLV(p_len_s-curr_pos, &p_str[curr_pos],
644 tmp_tlv, BER_ACCEPT_ALL))
645 goto incomplete;
646 tmp_len=tmp_tlv.get_len();
647 curr_pos+=tmp_len;
648 tlv.V.str.Vlen+=tmp_len;
649 if(tmp_tlv.tagclass==ASN_TAG_UNIV && tmp_tlv.tagnumber==0)
650 doit=FALSE; // End-of-contents
651 i++;
652 } // while doit
653 // tlv.V.str.Vlen=&p_str[curr_pos]-tlv.V.str.Vstr;
654 } // if indefinite len for V
655 tlv.isComplete=TRUE;
656 return TRUE;
657 incomplete:
658 if(tlv.Tlen==0) tlv.Tlen=p_len_s;
659 if(tlv.V.str.Vstr!=NULL && tlv.V.str.Vstr>tlv.Lstr+tlv.Llen)
660 tlv.Llen=tlv.V.str.Vstr-tlv.Lstr;
661 if(tlv.Tlen+tlv.Llen+tlv.V.str.Vlen>p_len_s)
662 tlv.V.str.Vlen=p_len_s-tlv.Tlen-tlv.Llen;
663 return FALSE;
664}
665
666ASN_BER_TLV_t* ASN_BER_V2TLV(ASN_BER_TLV_t* p_tlv,
667 const TTCN_Typedescriptor_t& p_td,
668 unsigned coding)
669{
670 if(p_td.ber->n_tags==0) return p_tlv;
671 ASN_BER_TLV_t *tlv2;
672 if(!(p_tlv->tagclass==ASN_TAG_UNIV && p_tlv->tagnumber==0))
673 tlv2=ASN_BER_TLV_t::construct(p_tlv);
674 else tlv2=p_tlv;
675 const ASN_BERdescriptor_t *ber=p_td.ber;
676 for(size_t i=0; i<ber->n_tags; i++) {
677 const ASN_Tag_t *tag=ber->tags+i;
678 tlv2->add_TL(tag->tagclass, tag->tagnumber, coding);
679 if(i!=ber->n_tags-1)
680 tlv2=ASN_BER_TLV_t::construct(tlv2);
681 } // for i
682 return tlv2;
683}
This page took 0.051336 seconds and 5 git commands to generate.