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