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