1 /**
2  * yateasn.h
3  * This file is part of the YATE Project http://YATE.null.ro
4  *
5  * ASN.1 Library
6  *
7  * Yet Another Telephony Engine - a fully featured software PBX and IVR
8  * Copyright (C) 2004-2014 Null Team
9  *
10  * This software is distributed under multiple licenses;
11  * see the COPYING file in the main directory for licensing
12  * information for this specific distribution.
13  *
14  * This use of this software may be subject to additional restrictions.
15  * See the LEGAL file in the main directory for details.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  */
21 
22 #ifndef __YATEASN_H
23 #define __YATEASN_H
24 
25 #include <yateclass.h>
26 
27 #ifdef _WINDOWS
28 
29 #ifdef LIBYASN_EXPORTS
30 #define YASN_API __declspec(dllexport)
31 #else
32 #ifndef LIBYASN_STATIC
33 #define YASN_API __declspec(dllimport)
34 #endif
35 #endif
36 
37 #endif /* _WINDOWS */
38 
39 #ifndef YASN_API
40 #define YASN_API
41 #endif
42 
43 namespace TelEngine {
44 
45 #define ASN_LONG_LENGTH 	0x80
46 #define ASN_BIT8		0x80
47 #define ASN_EXTENSION_ID	31
48 #define IS_EXTENSION_ID(byte) (((byte) & ASN_EXTENSION_ID) == ASN_EXTENSION_ID)
49 
50 class AsnObject;
51 class AsnValue;
52 class ASNObjId;
53 class ASNLib;
54 class ASNError;
55 
56 /**
57  * Helper class for operations with octet strings. Helps with conversions from String to/from DataBlock
58  * @short Helper class for operations with octet strings
59  */
60 class YASN_API OctetString : public DataBlock
61 {
62 public:
63     /**
64      * Get the String contained in this buffer
65      * @return String containing the internal data
66      */
getString()67     inline String getString()
68     {
69 	String str((const char*)data(),length());
70 	return str;
71     }
72     inline DataBlock& operator=(const String& value)
73     {
74 	clear();
75 	append(value);
76 	return *this;
77     }
78     inline DataBlock& operator=(const DataBlock& value)
79     {
80 	clear();
81 	append(value);
82 	return *this;
83     }
84     /**
85      * Get the content of the buffer in form of a hexified string
86      * @return Hexified string
87      */
toHexString()88     inline const String toHexString() const
89     {
90 	String str;
91 	str = str.hexify(data(),length());
92 	return str;
93     }
94     /**
95      * Builed this DataBlock from a hexified string
96      * @return The DataBlock built from the given hexified string
97      */
fromHexString(const String & value)98     inline DataBlock& fromHexString(const String& value)
99     {
100 	unHexify(value);
101 	return *this;
102     }
103 };
104 
105 /**
106  * Abstract class implemented by all ASN.1 type objects
107  * @short Base Class for ASN.1 objects
108  */
109 class YASN_API AsnObject : public GenObject {
YCLASS(AsnObject,GenObject)110     YCLASS(AsnObject, GenObject)
111 public:
112     /**
113      * Constructor
114      */
115     inline AsnObject()
116 	{}
117 
118     /**
119      * Copy constructor
120      * @param original Value object to copy
121      */
AsnObject(const AsnObject & original)122     inline AsnObject(const AsnObject& original)
123 	{}
124 
125     /**
126      * Destructor
127      */
~AsnObject()128     virtual inline ~AsnObject()
129 	{}
130 
131     /**
132      * Function to decode the parameters of this object from given data
133      * @param data DataBlock from which the object is decoded
134      */
135     virtual int decode(DataBlock& data) = 0;
136 
137     /**
138      * Function to encode this object into a datablock
139      * @param data The DataBlock in which the object should be encoded
140      */
141     virtual int encode(DataBlock& data) = 0;
142 
143     /**
144      * Function for obtaining this object's data
145      * @param params NamedList in which this object's data should be put
146      */
147     virtual void getParams(NamedList* params) = 0;
148 
149     /**
150      * Function for setting this object's data
151      * @param params NamedList containing the values to which this object's data should be set
152      */
153     virtual void setParams(NamedList* params) = 0;
154 };
155 
156 /**
157  * Class wrapper for different types of ASN.1 values
158  * @short An ASN.1 value
159  */
160 class YASN_API AsnValue : public GenObject {
161     YCLASS(AsnValue, GenObject)
162 public:
163     /**
164      * Type of value
165      */
166     enum ValType {
167 	INTEGER			= 1,
168 	STRING			= 2,
169 	OBJECT_ID		= 3,
170 	IPADDRESS		= 4,
171 	COUNTER			= 5,
172 	TIMETICKS		= 6,
173 	ARBITRARY		= 7,
174 	BIG_COUNTER		= 8,
175 	UNSIGNED_INTEGER	= 9
176     };
177 
178     /**
179      * Constructor
180      */
AsnValue()181     inline AsnValue()
182 	: m_type(0), m_data("")
183 	{}
184 
185     /**
186      * Copy constructor
187      * @param original Value object to copy
188      */
AsnValue(const AsnValue & original)189     inline AsnValue(const AsnValue& original)
190 	: m_type(original.m_type), m_data(original.m_data)
191 	{ }
192 
193     /**
194      * Constructor
195      * @param value Object value
196      * @param type AsnValue type, default is String
197      */
198     inline AsnValue(const String& value, int type = STRING)
m_type(type)199 	: m_type(type), m_data(value)
200 	{ }
201 
202     /**
203      * Destructor
204      */
~AsnValue()205     virtual inline ~AsnValue()
206 	{}
207 
208     /**
209      * Get the value in the form of a string
210      * @return String containing the internal data
211      */
getValue()212     inline const String& getValue()
213 	{ return m_data; }
214 
215     /**
216      * Get the type of the data so that we know how to interpret it
217      * @return The type of the data
218      */
type()219     inline int type()
220 	{ return m_type;}
221 
222     /**
223      * Assign operator
224      */
225     inline AsnValue& operator=( AsnValue* val)
226     {
227 	if (!val)
228 	    return *this;
229 	m_data = val->getValue();
230 	m_type = val->type();
231 	return *this;
232     }
233 
234     /**
235      * Assign operator
236      */
237     inline AsnValue& operator=( AsnValue val)
238     {
239 	m_data = val.getValue();
240 	m_type = val.type();
241 	return *this;
242     }
243 
244     /**
245      * Set data
246      * @param data The data to which the internal data will be set
247      */
setValue(const String & data)248     inline void setValue(const String& data)
249 	{ m_data.clear();m_data = data; }
250 
251     /**
252      * Set data type
253      * @param type The type assigned
254      */
setType(int type)255     inline void setType(int type)
256 	{ m_type = type; }
257 
258 private:
259     int m_type;
260     String m_data;
261 };
262 
263 /**
264  * Class describing an ASN.1 OID
265  */
266 class YASN_API AsnMib : public GenObject {
267     YCLASS(AsnMib, GenObject)
268 public:
269     /**
270      * Access levels
271      */
272     enum Access {
273 	notAccessible = 0,
274 	accessibleForNotify = 1,
275 	readOnly = 2,
276 	readWrite = 3,
277 	readCreate = 4
278     };
279     /**
280      * Constructor
281      */
AsnMib()282     inline AsnMib()
283 	: m_access(""), m_accessVal(0), m_index(0)
284 	{}
285 
286     /**
287      * Constructor
288      * @param params NamedList containing data for building this object, it should contain name, access level, value type
289      */
290     AsnMib(NamedList& params);
291 
292     /**
293      * Destructor
294      */
~AsnMib()295     inline ~AsnMib()
296 	{}
297 
298     /**
299      * Get OID access level in string form
300      * @return String containing the access level for this OID. It's one of the following values : not-accessible, read-only, read-write,
301 	read-create, accessible-for-notify.
302      */
getAccess()303     inline String& getAccess()
304 	{ return m_access;}
305 
306     /**
307      * Get OID access level
308      * @return String containing the access level for this OID. It's one of the following values : not-accessible, read-only, read-write,
309 	read-create, accessible-for-notify.
310      */
getAccessValue()311     inline int getAccessValue()
312 	{ return m_accessVal;}
313 
314     /**
315      * Get the name of this OID
316      * @return Name of the OID
317      */
getName()318     inline String& getName()
319 	{ return m_name;}
320 
321     /**
322      * Get the oid
323      * @return The OID
324      */
getOID()325     inline String getOID()
326 	{ String str = ".";
327 	  str += m_index;
328 	  return m_oid + str;}
329 
330     /**
331      * Get the type of the value of this OID
332      * @return String containing the type of value
333      */
getType()334     inline String& getType()
335 	{ return m_type;}
336 
337     /**
338      * Get the revision of this OID
339      * @return String containing the revision string
340      */
getRevision()341     inline String& getRevision()
342 	{ return m_revision; }
343 
344     /**
345      * Get the string representation of this OID
346      * @return String representation of this OID
347      */
toString()348     inline const String& toString() const
349 	{ return m_oid;}
350 
351     /**
352      * Set the index of an OID in case this OID is part of a table.
353      * @param ind Given index
354      */
setIndex(unsigned int ind)355     inline void setIndex(unsigned int ind)
356 	{ m_index = ind;}
357 
358     /**
359      * Obtain the index of this OID
360      * @return This OID's index in the OID table
361      */
index()362     inline unsigned int index()
363 	{ return m_index;}
364 
365     /**
366      * Compare this object ID with another
367      * @param mib The object ID with which this object should be compared
368      * @return 0 if they're equal, -1 if this object is less lexicographically then the given parameter, 1 if it's greater
369      */
370     int compareTo(AsnMib* mib);
371 
372     /**
373      * Get the parent object ID of this object
374      * @return String version of the parent ID
375      */
getParent()376     inline String getParent()
377     {
378 	int pos = m_oid.rfind('.');
379 	return m_oid.substr(0,pos);
380     }
381 
382 private:
383     String m_name;
384     String m_oid;
385     String m_access;
386     int m_accessVal;
387     String m_type;
388     String m_revision;
389     int size;
390     int maxVal;
391     int minVal;
392     unsigned int m_index;
393 
394     static TokenDict s_access[];
395 };
396 
397 /**
398  * Class for holding only an OID
399  */
400 class YASN_API ASNObjId : public GenObject {
401     YCLASS(ASNObjId, GenObject)
402 public:
403     /**
404      * Constructor
405      */
406     ASNObjId();
407 
408     /**
409      * Copy constructor
410      * @param original OID object to copy
411      */
ASNObjId(const ASNObjId & original)412     inline ASNObjId(const ASNObjId& original)
413 	: m_value(original.m_value), m_name(original.m_name)
414 	{ }
415 
416     /**
417      * Constructor
418      * @param val OID value in string format
419      */
420     ASNObjId(const String& val);
421 
422     /**
423      * Constructor
424      * @param name Name of the OID
425      * @param val OID value in string format
426      */
427     ASNObjId(const String& name, const String& val);
428 
429     /**
430      * Constructor
431      * @param mib Mib used for creating this OID
432      */
433     ASNObjId(AsnMib* mib);
434 
435     /**
436      * Destructor
437      */
438     ~ASNObjId();
439 
440     /**
441      * Assignment operator from OID
442      */
443     inline ASNObjId& operator=(const ASNObjId& original)
444 	{ m_value = original.toString(); return *this; }
445 
446     /**
447      * Assign operator from a string value
448      */
449     inline ASNObjId& operator=(const String& val)
450 	{ m_value = val; return *this; }
451 
452     /**
453      * Assign operator from a const char* value
454      */
455     inline ASNObjId& operator=(const char* val)
456 	{ m_value = val; return *this; }
457 
458     /**
459      * Transform the value of this OID from a string value to a sequence of numbers
460      */
461     void toDataBlock();
462 
463     /**
464      * Get the sequence form of the OID
465      * @return Datablock sequence of ids
466      */
467     DataBlock getIds();
468 
469     /**
470      * String representation of the OID
471      */
toString()472     inline const String& toString() const
473 	{ return m_value; }
474 
475     /**
476      * Get the name of the OID
477      * @return String representation of the name
478      */
getName()479     inline const String& getName() const
480 	{ return m_name; }
481 
482     /**
483      * Set the OID value
484      * @param value OID value
485      */
setValue(const String & value)486     inline void setValue(const String& value)
487 	{ m_value = value; toDataBlock();}
488 
489 private:
490     String m_value;
491     String m_name;
492     DataBlock m_ids;
493 };
494 
495 /**
496  * Class AsnTag
497  * @short Class for ASN.1 tags
498  */
499 class AsnTag {
500 public:
501     /**
502      * ASN.1 Tag class types enum
503      */
504     enum Class {
505 	Universal   = 0x00,
506 	Application = 0x40,
507 	Context     = 0x80,
508 	Private     = 0xc0,
509     };
510 
511     /**
512      * ASN.1  Type of tag enum
513      */
514     enum Type {
515 	Primitive   = 0x00,
516 	Constructor = 0x20,
517     };
518 
519     /**
520      * Constructor
521      */
AsnTag()522     inline AsnTag()
523         : m_class(Universal), m_type(Primitive), m_code(0)
524     { }
525 
526     /**
527      * Constructor
528      * @param clas Class of the ASN.1 Tag
529      * @param type Type of the ASN.1 Tag
530      * @param code Code ot the ASN.1 Tag
531      */
AsnTag(Class clas,Type type,unsigned int code)532     inline AsnTag(Class clas, Type type, unsigned int code)
533         : m_class(clas), m_type(type), m_code(code)
534     {
535 	encode();
536     }
537 
538     /**
539      * Destructor
540      */
~AsnTag()541     inline ~AsnTag()
542     {}
543 
544     /**
545      * Decode an ASN.1 tag from the given data
546      * @param tag Tag to fill
547      * @param data Data from which the tag should be filled
548      */
549     static void decode(AsnTag& tag, DataBlock& data);
550 
551     /**
552      * Encode an ASN.1 tag and put the encoded form into the given data
553      * @param clas Class of the tag
554      * @param type Type of the tag
555      * @param code Tag code
556      * @param data DataBlock into which to insert the encoded tag
557      */
558     static void encode(Class clas, Type type, unsigned int code, DataBlock& data);
559 
560     /**
561      * Encode self
562      */
encode()563     inline void encode()
564 	{ AsnTag::encode(m_class,m_type,m_code,m_coding); }
565 
566     /**
567      * Equality operator
568      */
569     inline bool operator==(const AsnTag& tag) const
570     {
571 	return (m_class == tag.classType() && m_type == tag.type() && m_code == tag.code());
572     }
573 
574     /**
575      * Inequality operator
576      */
577     inline bool operator!=(const AsnTag& tag) const
578     {
579 	return !(m_class == tag.classType() && m_type == tag.type() && m_code == tag.code());
580     }
581 
582     /**
583      * Assignment operator
584      */
585     inline AsnTag& operator=(const AsnTag& value)
586     {
587 	m_class = value.classType();
588 	m_type = value.type();
589 	m_code = value.code();
590 	encode();
591 	return *this;
592     }
593 
594     /**
595      * Get the tag class
596      * @return The class of the tag
597      */
classType()598     inline const Class classType() const
599 	{ return m_class; }
600 
601     /**
602      * Set the tag class
603      * @param clas The clas to set for the  tag
604      */
classType(Class clas)605     inline void classType(Class clas)
606 	{ m_class = clas; }
607 
608     /**
609      * Get the tag type
610      * @return The type of the tag
611      */
type()612     inline const Type type() const
613 	{ return m_type; }
614 
615     /**
616      * Set the tag type
617      * @param type The type to set for the  tag
618      */
type(Type type)619     inline void type(Type type)
620 	{ m_type = type; }
621 
622     /**
623      * Get the tag code
624      * @return The code of the tag
625      */
code()626     inline const unsigned int code() const
627 	{ return m_code; }
628 
629     /**
630      * Set the tag code
631      * @param code The code to set for the  tag
632      */
code(unsigned int code)633     inline void code(unsigned int code)
634 	{ m_code = code; }
635 
636     /**
637      * Get the tag encoding
638      * @return The DataBlock containing the encoding for the tag
639      */
coding()640     inline const DataBlock& coding() const
641 	{ return m_coding; }
642 
643 private:
644     Class m_class;
645     Type m_type;
646     unsigned int m_code;
647     DataBlock m_coding;
648 };
649 
650 /**
651  * Class ASNLib
652  * @short Class containing functions for decoding/encoding ASN.1 basic data types
653  */
654 class YASN_API ASNLib {
655 public:
656     /**
657      * ASN.1 Type tags
658      */
659     enum TypeTag {
660 	UNIVERSAL	= 0x00,
661 	BOOLEAN		= 0x01,
662 	INTEGER 	= 0x02,
663 	BIT_STRING	= 0x03,
664 	OCTET_STRING 	= 0x04,
665 	NULL_ID		= 0x05,
666 	OBJECT_ID	= 0x06,
667 	REAL		= 0x09, //not implemented
668 	UTF8_STR	= 0x0c,
669 	SEQUENCE	= 0x30,
670 	SET		= 0x31,
671 	NUMERIC_STR	= 0x12,
672 	PRINTABLE_STR	= 0x13,
673 	IA5_STR		= 0x16,
674 	UTC_TIME	= 0x17,
675 	GENERALIZED_TIME = 0x18,
676 	VISIBLE_STR	= 0x1a,
677 	GENERAL_STR	= 0x1b, // not implemented
678 	UNIVERSAL_STR	= 0x1c, // not implemented
679 	CHARACTER_STR	= 0x1d, // not implemented
680 	BMP_STR		= 0x1e, // not implemented
681 	CHOICE		= 0x1f, // does not have a value
682 	DEFINED		= 0x2d
683     };
684 	// values not implemented
685 	// 10 	ENUMERATED
686 	// 11 	EMBEDDED PDV
687 	// 13 	RELATIVE-OID
688 	// 20 	TeletexString, T61String
689 	// 21 	VideotexString
690 	// 25 	GraphicString
691 	// 27 	GeneralString
692 	// 28 	UniversalString
693 	// 29 	CHARACTER STRING
694 	// 30 	BMPString
695     /**
696      * Error types
697      */
698     enum Error {
699 	InvalidLengthOrTag = -1,
700 	ConstraintBreakError = -2,
701 	ParseError = -3,
702 	InvalidContentsError = -4,
703 	IndefiniteForm = -5,
704     };
705 
706     /**
707      * Constructor
708      */
709     ASNLib();
710 
711     /**
712      * Destructor
713      */
714     ~ASNLib();
715 
716     /**
717      * Decode the length of the block data containing the ASN.1 type data
718      * @param data Input block from which to extract the length
719      * @return The length of the data block containing data, -1 if it couldn't be decoded
720      */
721     static int decodeLength(DataBlock& data);
722 
723     /**
724      * Decode a boolean value from the encoded data
725      * @param data Input block from which the boolean value should be extracted
726      * @param val Pointer to a boolean to be filled with the decoded value
727      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for boolean (0x01) should be verified
728      * @return Length of data consumed from the input data it the decoding was successful, -1 if the boolean value could not be decoded
729      */
730     static int decodeBoolean(DataBlock& data, bool* val, bool tagCheck);
731 
732     /**
733      * Decode an integer value from the encoded data
734      * @param data Input block from which the integer value should be extracted
735      * @param intVal Integer to be filled with the decoded value
736      * @param bytes Width of the decoded integer field
737      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x02) should be verified
738      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
739      */
740     static int decodeInteger(DataBlock& data, u_int64_t& intVal, unsigned int bytes, bool tagCheck);
741 
742     /**
743      * Decode an unsigned integer value from the encoded data - helper function for casting from u_int64_t to u_int8_t in case of size constraints
744      * @param data Input block from which the integer value should be extracted
745      * @param intVal Integer to be filled with the decoded value
746      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x02) should be verified
747      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
748      */
749     static int decodeUINT8(DataBlock& data, u_int8_t* intVal, bool tagCheck);
750 
751     /**
752      * Decode an unsigned integer value from the encoded data - helper function for casting from u_int64_t to u_int16_t in case of size constraints
753      * @param data Input block from which the integer value should be extracted
754      * @param intVal Integer to be filled with the decoded value
755      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x02) should be verified
756      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
757      */
758     static int decodeUINT16(DataBlock& data, u_int16_t* intVal, bool tagCheck);
759 
760     /**
761      * Decode an unsigned integer value from the encoded data - helper function for casting from u_int64_t to u_int32_t in case of size constraints
762      * @param data Input block from which the integer value should be extracted
763      * @param intVal Integer to be filled with the decoded value
764      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x02) should be verified
765      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
766      */
767     static int decodeUINT32(DataBlock& data, u_int32_t* intVal, bool tagCheck);
768 
769     /**
770      * Decode an unsigned integer value from the encoded data - helper function for casting in case of size constraints
771      * @param data Input block from which the integer value should be extracted
772      * @param intVal Integer to be filled with the decoded value
773      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x02) should be verified
774      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
775      */
776     static int decodeUINT64(DataBlock& data, u_int64_t* intVal, bool tagCheck);
777 
778     /**
779      * Decode an integer value from the encoded data - helper function for casting from u_int64_t to int8_t in case of size constraints
780      * @param data Input block from which the integer value should be extracted
781      * @param intVal Integer to be filled with the decoded value
782      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x02) should be verified
783      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
784      */
785     static int decodeINT8(DataBlock& data, int8_t* intVal, bool tagCheck);
786 
787     /**
788      * Decode an integer value from the encoded data - helper function for casting from u_int64_t to int16_t in case of size constraints
789      * @param data Input block from which the integer value should be extracted
790      * @param intVal Integer to be filled with the decoded value
791      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x02) should be verified
792      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
793      */
794     static int decodeINT16(DataBlock& data, int16_t* intVal, bool tagCheck);
795 
796     /**
797      * Decode an integer value from the encoded data - helper function for casting from u_int64_t to int32_t in case of size constraints
798      * @param data Input block from which the integer value should be extracted
799      * @param intVal Integer to be filled with the decoded value
800      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x02) should be verified
801      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
802      */
803     static int decodeINT32(DataBlock& data, int32_t* intVal, bool tagCheck);
804 
805     /**
806      * Decode an integer value from the encoded data - helper function for casting in case of size constraints
807      * @param data Input block from which the integer value should be extracted
808      * @param intVal Integer to be filled with the decoded value
809      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x02) should be verified
810      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
811      */
812     static int decodeINT64(DataBlock& data, int64_t* intVal, bool tagCheck);
813 
814     /**
815      * Decode a bitstring value from the encoded data
816      * @param data Input block from which the bitstring value should be extracted
817      * @param val String to be filled with the decoded value
818      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x03) should be verified
819      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
820      */
821     static int decodeBitString(DataBlock& data, String* val, bool tagCheck);
822 
823     /**
824      * Decode a string value from the encoded data
825      * @param data Input block from which the octet string value should be extracted
826      * @param strVal String to be filled with the decoded value
827      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x04) should be verified
828      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
829      */
830     static int decodeOctetString(DataBlock& data, OctetString* strVal, bool tagCheck);
831 
832     /**
833      * Decode a null value from the encoded data
834      * @param data Input block from which the null value should be extracted
835      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x05) should be verified
836      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
837      */
838     static int decodeNull(DataBlock& data, bool tagCheck);
839 
840     /**
841      * Decode an object id value from the encoded data
842      * @param data Input block from which the OID value should be extracted
843      * @param obj ASNObjId to be filled with the decoded value
844      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x06) should be verified
845      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
846      */
847     static int decodeOID(DataBlock& data, ASNObjId* obj, bool tagCheck);
848 
849     /**
850      * Decode a real value from the encoded data - not implemented
851      * @param data Input block from which the real value should be extracted
852      * @param realVal Float to be filled with the decoded value
853      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag for integer (0x09) should be verified
854      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
855      */
856     static int decodeReal(DataBlock& data, float* realVal, bool tagCheck);
857 
858     /**
859      * Decode other types of ASN.1 strings from the encoded data (NumericString, PrintableString, VisibleString, IA5String)
860      * @param data Input block from which the string value should be extracted
861      * @param str String to be filled with the decoded value
862      * @param type Integer to be filled with the value indicating which type of string has been decoded
863      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag should be verified
864      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
865      */
866     static int decodeString(DataBlock& data, String* str, int* type, bool tagCheck);
867 
868     /**
869      * Decode an UTF8 string from the encoded data
870      * @param data Input block from which the string value should be extracted
871      * @param str String to be filled with the decoded value
872      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag (0x0c) should be verified
873      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
874      */
875     static int decodeUtf8(DataBlock& data, String* str, bool tagCheck);
876 
877     /**
878      * Decode a GeneralizedTime value from the encoded data
879      * @param data Input block from which the value should be extracted
880      * @param time Integer to be filled with time in seconds since epoch
881      * @param fractions Integer to be filled with fractions of a second
882      * @param utc Flag indicating if the decode time value represent local time or UTC time
883      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag (0x18) should be verified
884      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
885      */
886     static int decodeGenTime(DataBlock& data, unsigned int* time, unsigned int* fractions, bool* utc, bool tagCheck);
887 
888     /**
889      * Decode a UTC time value from the encoded data
890      * @param data Input block from which the value should be extracted
891      * @param time Integer to be filled with time in seconds since epoch
892      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 tag (0x17) should be verified
893      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
894      */
895     static int decodeUTCTime(DataBlock& data, unsigned int* time, bool tagCheck);
896 
897     /**
898      * Decode a block of arbitrary data
899      * @param data Input block from which the value should be extracted
900      * @param val DataBlock in which the data shoulb be copied
901      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 should be verified
902      * @return Length of data consumed from the input data it the decoding was successful, -1 if the integer value could not be decoded
903      */
904     static int decodeAny(DataBlock data, DataBlock* val, bool tagCheck);
905 
906     /**
907      * Decode the header of an ASN.1 sequence ( decodes the tag and the length of the sequence)
908      * @param data Input block from which the header should be extracted
909      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 (0x30) should be verified
910      * @return Length of data consumed from the input data it the decoding was succesful, -1 if the integer value could not be decoded
911      */
912     static int decodeSequence(DataBlock& data, bool tagCheck);
913 
914     /**
915      * Decode the header of an ASN.1 set ( decodes the tag and the length of the sequence)
916      * @param data Input block from which the header should be extracted
917      * @param tagCheck Flag for indicating if in the process of decoding the value the presence of the ASN.1 (0x31) should be verified
918      * @return Length of data consumed from the input data it the decoding was succesful, -1 if the integer value could not be decoded
919      */
920     static int decodeSet(DataBlock& data, bool tagCheck);
921 
922     /**
923      * Encode the length of the given data
924      * @param data The data for which the length should be encoded
925      * @return The data block which now contains the length encoding
926      */
927     static DataBlock buildLength(DataBlock& data);
928 
929     /**
930      * Encode the given boolean value
931      * @param val The boolean value to encode
932      * @param tagCheck Flag to specify if the boolean type tag should be inserted in the encoding
933      * @return The data block encoding of the value
934      */
935     static DataBlock encodeBoolean(bool val, bool tagCheck);
936 
937     /**
938      * Encode the given integer value
939      * @param intVal The integer value to encode
940      * @param tagCheck Flag to specify if the integer type tag should be inserted in the encoding
941      * @return The data block encoding of the value
942      */
943     static DataBlock encodeInteger(u_int64_t intVal, bool tagCheck);
944 
945     /**
946      * Encode the given octet string value
947      * @param strVal The octet string value to encode
948      * @param tagCheck Flag to specify if the octet string type tag should be inserted in the encoding
949      * @return The data block encoding of the value
950      */
951     static DataBlock encodeOctetString(OctetString strVal, bool tagCheck);
952 
953     /**
954      * Encode a null value
955      * @param tagCheck Flag to specify if the null tag should be inserted in the encoding
956      * @return The data block encoding of the value
957      */
958     static DataBlock encodeNull(bool tagCheck);
959 
960     /**
961      * Encode the given bitstring value
962      * @param val The bitstring value to encode
963      * @param tagCheck Flag to specify if the type tag should be inserted in the encoding
964      * @return The data block encoding of the value
965      */
966     static DataBlock encodeBitString(String val, bool tagCheck);
967 
968     /**
969      * Encode the given OID value
970      * @param obj The OID value to encode
971      * @param tagCheck Flag to specify if the type tag should be inserted in the encoding
972      * @return The data block encoding of the value
973      */
974     static DataBlock encodeOID(ASNObjId obj, bool tagCheck);
975 
976     /**
977      * Encode the given real value - not implemented
978      * @param val The real value to encode
979      * @param tagCheck Flag to specify if the type tag should be inserted in the encoding
980      * @return The data block encoding of the value
981      */
982     static DataBlock encodeReal(float val, bool tagCheck);
983 
984     /**
985      * Encode the given string value to NumericString, PrintableString, IA5String, VisibleString
986      * @param str The string value to encode
987      * @param type The type of the encoding
988      * @param tagCheck Flag to specify if the type tag should be inserted in the encoding
989      * @return The data block encoding of the value
990      */
991     static DataBlock encodeString(String str, int type, bool tagCheck);
992 
993     /**
994      * Encode the UTF8 string value
995      * @param str The string value to encode
996      * @param tagCheck Flag to specify if the type tag should be inserted in the encoding
997      * @return The data block encoding of the value
998      */
999     static DataBlock encodeUtf8(String str, bool tagCheck);
1000 
1001     /**
1002      * Encode the given time value into a GeneralizedTime format
1003      * @param time Time in seconds since epoch to encode
1004      * @param fractions Fractions of a seconds to encode
1005      * @param tagCheck Flag to specify if the type tag should be inserted in the encoding
1006      * @return The data block encoding of the value
1007      */
1008     static DataBlock encodeGenTime(unsigned int time, unsigned int fractions, bool tagCheck);
1009 
1010     /**
1011      * Encode the given time value into an UTCTime format
1012      * @param time Time in seconds since epoch to encode
1013      * @param tagCheck Flag to specify if the type tag should be inserted in the encoding
1014      * @return The data block encoding of the value
1015      */
1016     static DataBlock encodeUTCTime(unsigned int time, bool tagCheck);
1017 
1018     /**
1019      * Encode an arbitrary block a data
1020      * @param data data
1021      * @param tagCheck Flag to specify if the type tag should be inserted in the encoding
1022      * @return The data block encoding of the value
1023      */
1024     static DataBlock encodeAny(DataBlock data, bool tagCheck);
1025 
1026     /**
1027      * Encode the header for a sequence
1028      * @param data Sequence data for which the header is encoded
1029      * @param tagCheck Flag to specify if the ype tag should be inserted in the encoding
1030      * @return The length of the data block length encoding
1031      */
1032     static int encodeSequence(DataBlock& data, bool tagCheck);
1033 
1034     /**
1035      * Encode the header for a set
1036      * @param data Sequence data for which the header is encoded
1037      * @param tagCheck Flag to specify if the type tag should be inserted in the encoding
1038      * @return The length of the data block length encoding
1039      */
1040     static int encodeSet(DataBlock& data, bool tagCheck);
1041 
1042     /**
1043      * Verify the data for End Of Contents presence
1044      * @param  data Input block to verify
1045      * @return Length of data consumed from the input data it the decoding was succesful, it should be 2 in case of success, -1 if the data doesn't match EoC
1046      */
1047     static int matchEOC(DataBlock& data);
1048 
1049     /**
1050      * Extract length until a End Of Contents is found.
1051      * @param data Input block for which to determine the length to End Of Contents
1052      * @param length Length to which to add determined length
1053      * @return Length until End Of Contents
1054      */
1055     static int parseUntilEoC(DataBlock& data, int length = 0);
1056 };
1057 
1058 }
1059 
1060 #endif /* __YATEASN_H */
1061 
1062 /* vi: set ts=8 sw=4 sts=4 noet: */
1063