1 2[//000000001]: # (asn \- ASN\.1 processing) 3[//000000002]: # (Generated from file 'asn\.man' by tcllib/doctools with format 'markdown') 4[//000000003]: # (Copyright © 2004 Andreas Kupries <andreas\_kupries@users\.sourceforge\.net>) 5[//000000004]: # (Copyright © 2004 Jochen Loewer <loewerj@web\.de>) 6[//000000005]: # (Copyright © 2004\-2011 Michael Schlenker <mic42@users\.sourceforge\.net>) 7[//000000006]: # (asn\(n\) 0\.8 tcllib "ASN\.1 processing") 8 9<hr> [ <a href="../../../../toc.md">Main Table Of Contents</a> | <a 10href="../../../toc.md">Table Of Contents</a> | <a 11href="../../../../index.md">Keyword Index</a> | <a 12href="../../../../toc0.md">Categories</a> | <a 13href="../../../../toc1.md">Modules</a> | <a 14href="../../../../toc2.md">Applications</a> ] <hr> 15 16# NAME 17 18asn \- ASN\.1 BER encoder/decoder 19 20# <a name='toc'></a>Table Of Contents 21 22 - [Table Of Contents](#toc) 23 24 - [Synopsis](#synopsis) 25 26 - [Description](#section1) 27 28 - [PUBLIC API](#section2) 29 30 - [ENCODER](#subsection1) 31 32 - [DECODER](#subsection2) 33 34 - [HANDLING TAGS](#subsection3) 35 36 - [EXAMPLES](#section3) 37 38 - [Bugs, Ideas, Feedback](#section4) 39 40 - [Keywords](#keywords) 41 42 - [Category](#category) 43 44 - [Copyright](#copyright) 45 46# <a name='synopsis'></a>SYNOPSIS 47 48package require Tcl 8\.4 49package require asn ?0\.8\.4? 50 51[__::asn::asnSequence__ *evalue*\.\.\.](#1) 52[__::asn::asnSequenceFromList__ *elist*](#2) 53[__::asn::asnSet__ *evalue*\.\.\.](#3) 54[__::asn::asnSetFromList__ *elist*](#4) 55[__::asn::asnApplicationConstr__ *appNumber* *evalue*\.\.\.](#5) 56[__::asn::asnApplication__ *appNumber* *data*](#6) 57[__::asn::asnChoice__ *appNumber* *evalue*\.\.\.](#7) 58[__::asn::asnChoiceConstr__ *appNumber* *evalue*\.\.\.](#8) 59[__::asn::asnInteger__ *number*](#9) 60[__::asn::asnEnumeration__ *number*](#10) 61[__::asn::asnBoolean__ *bool*](#11) 62[__::asn::asnContext__ *context* *data*](#12) 63[__::asn::asnContextConstr__ *context* *evalue*\.\.\.](#13) 64[__::asn::asnObjectIdentifier__ *idlist*](#14) 65[__::asn::asnUTCTime__ *utcstring*](#15) 66[__::asn::asnNull__](#16) 67[__::asn::asnBitString__ *string*](#17) 68[__::asn::asnOctetString__ *string*](#18) 69[__::asn::asnNumericString__ *string*](#19) 70[__::asn::asnPrintableString__ *string*](#20) 71[__::asn::asnIA5String__ *string*](#21) 72[__::asn::asnBMPString__ *string*](#22) 73[__::asn::asnUTF8String__ *string*](#23) 74[__::asn::asnString__ *string*](#24) 75[__::asn::defaultStringType__ ?*type*?](#25) 76[__::asn::asnPeekByte__ *data\_var* *byte\_var*](#26) 77[__::asn::asnGetLength__ *data\_var* *length\_var*](#27) 78[__::asn::asnGetResponse__ *chan* *data\_var*](#28) 79[__::asn::asnGetInteger__ *data\_var* *int\_var*](#29) 80[__::asn::asnGetEnumeration__ *data\_var* *enum\_var*](#30) 81[__::asn::asnGetOctetString__ *data\_var* *string\_var*](#31) 82[__::asn::asnGetString__ *data\_var* *string\_var* ?*type\_var*?](#32) 83[__::asn::asnGetNumericString__ *data\_var* *string\_var*](#33) 84[__::asn::asnGetPrintableString__ *data\_var* *string\_var*](#34) 85[__::asn::asnGetIA5String__ *data\_var* *string\_var*](#35) 86[__::asn::asnGetBMPString__ *data\_var* *string\_var*](#36) 87[__::asn::asnGetUTF8String__ *data\_var* *string\_var*](#37) 88[__::asn::asnGetUTCTime__ *data\_var* *utc\_var*](#38) 89[__::asn::asnGetBitString__ *data\_var* *bits\_var*](#39) 90[__::asn::asnGetObjectIdentifier__ *data\_var* *oid\_var*](#40) 91[__::asn::asnGetBoolean__ *data\_var* *bool\_var*](#41) 92[__::asn::asnGetNull__ *data\_var*](#42) 93[__::asn::asnGetSequence__ *data\_var* *sequence\_var*](#43) 94[__::asn::asnGetSet__ *data\_var* *set\_var*](#44) 95[__::asn::asnGetApplication__ *data\_var* *appNumber\_var* ?*content\_var*? ?*encodingType\_var*?](#45) 96[__::asn::asnGetContext__ *data\_var* *contextNumber\_var* ?*content\_var*? ?*encodingType\_var*?](#46) 97[__::asn::asnPeekTag__ *data\_var* *tag\_var* *tagtype\_var* *constr\_var*](#47) 98[__::asn::asnTag__ *tagnumber* ?*class*? ?*tagstyle*?](#48) 99[__::asn::asnRetag__ *data\_var* *newTag*](#49) 100 101# <a name='description'></a>DESCRIPTION 102 103The __asn__ package provides *partial* de\- and encoder commands for BER 104encoded ASN\.1 data\. It can also be used for decoding DER, which is a restricted 105subset of BER\. 106 107ASN\.1 is a standard *Abstract Syntax Notation*, and BER are its *Basic 108Encoding Rules*\. 109 110See 111[http://asn1\.elibel\.tm\.fr/en/standards/index\.htm](http://asn1\.elibel\.tm\.fr/en/standards/index\.htm) 112for more information about the standard\. 113 114Also see 115[http://luca\.ntop\.org/Teaching/Appunti/asn1\.html](http://luca\.ntop\.org/Teaching/Appunti/asn1\.html) 116for *A Layman's Guide to a Subset of ASN\.1, BER, and DER*, an RSA Laboratories 117Technical Note by Burton S\. Kaliski Jr\. \(Revised November 1, 1993\)\. A text 118version of this note is part of the module sources and should be read by any 119implementor\. 120 121# <a name='section2'></a>PUBLIC API 122 123## <a name='subsection1'></a>ENCODER 124 125 - <a name='1'></a>__::asn::asnSequence__ *evalue*\.\.\. 126 127 Takes zero or more encoded values, packs them into an ASN sequence and 128 returns its encoded binary form\. 129 130 - <a name='2'></a>__::asn::asnSequenceFromList__ *elist* 131 132 Takes a list of encoded values, packs them into an ASN sequence and returns 133 its encoded binary form\. 134 135 - <a name='3'></a>__::asn::asnSet__ *evalue*\.\.\. 136 137 Takes zero or more encoded values, packs them into an ASN set and returns 138 its encoded binary form\. 139 140 - <a name='4'></a>__::asn::asnSetFromList__ *elist* 141 142 Takes a list of encoded values, packs them into an ASN set and returns its 143 encoded binary form\. 144 145 - <a name='5'></a>__::asn::asnApplicationConstr__ *appNumber* *evalue*\.\.\. 146 147 Takes zero or more encoded values, packs them into an ASN application 148 construct and returns its encoded binary form\. 149 150 - <a name='6'></a>__::asn::asnApplication__ *appNumber* *data* 151 152 Takes a single encoded value *data*, packs it into an ASN application 153 construct and returns its encoded binary form\. 154 155 - <a name='7'></a>__::asn::asnChoice__ *appNumber* *evalue*\.\.\. 156 157 Takes zero or more encoded values, packs them into an ASN choice construct 158 and returns its encoded binary form\. 159 160 - <a name='8'></a>__::asn::asnChoiceConstr__ *appNumber* *evalue*\.\.\. 161 162 Takes zero or more encoded values, packs them into an ASN choice construct 163 and returns its encoded binary form\. 164 165 - <a name='9'></a>__::asn::asnInteger__ *number* 166 167 Returns the encoded form of the specified integer *number*\. 168 169 - <a name='10'></a>__::asn::asnEnumeration__ *number* 170 171 Returns the encoded form of the specified enumeration id *number*\. 172 173 - <a name='11'></a>__::asn::asnBoolean__ *bool* 174 175 Returns the encoded form of the specified boolean value *bool*\. 176 177 - <a name='12'></a>__::asn::asnContext__ *context* *data* 178 179 Takes an encoded value and packs it into a constructed value with 180 application tag, the *context* number\. 181 182 - <a name='13'></a>__::asn::asnContextConstr__ *context* *evalue*\.\.\. 183 184 Takes zero or more encoded values and packs them into a constructed value 185 with application tag, the *context* number\. 186 187 - <a name='14'></a>__::asn::asnObjectIdentifier__ *idlist* 188 189 Takes a list of at least 2 integers describing an object identifier \(OID\) 190 value, and returns the encoded value\. 191 192 - <a name='15'></a>__::asn::asnUTCTime__ *utcstring* 193 194 Returns the encoded form of the specified UTC time string\. 195 196 - <a name='16'></a>__::asn::asnNull__ 197 198 Returns the NULL encoding\. 199 200 - <a name='17'></a>__::asn::asnBitString__ *string* 201 202 Returns the encoded form of the specified *string*\. 203 204 - <a name='18'></a>__::asn::asnOctetString__ *string* 205 206 Returns the encoded form of the specified *string*\. 207 208 - <a name='19'></a>__::asn::asnNumericString__ *string* 209 210 Returns the *string* encoded as ASN\.1 NumericString\. Raises an error if 211 the *string* contains characters other than decimal numbers and space\. 212 213 - <a name='20'></a>__::asn::asnPrintableString__ *string* 214 215 Returns the *string* encoding as ASN\.1 PrintableString\. Raises an error if 216 the *string* contains characters which are not allowed by the Printable 217 String datatype\. The allowed characters are A\-Z, a\-z, 0\-9, space, 218 apostrophe, colon, parentheses, plus, minus, comma, period, forward slash, 219 question mark, and the equals sign\. 220 221 - <a name='21'></a>__::asn::asnIA5String__ *string* 222 223 Returns the *string* encoded as ASN\.1 IA5String\. Raises an error if the 224 *string* contains any characters outside of the US\-ASCII range\. 225 226 - <a name='22'></a>__::asn::asnBMPString__ *string* 227 228 Returns the *string* encoded as ASN\.1 Basic Multilingual Plane string 229 \(Which is essentialy big\-endian UCS2\)\. 230 231 - <a name='23'></a>__::asn::asnUTF8String__ *string* 232 233 Returns the *string* encoded as UTF8 String\. Note that some legacy 234 applications such as Windows CryptoAPI do not like UTF8 strings\. Use 235 BMPStrings if you are not sure\. 236 237 - <a name='24'></a>__::asn::asnString__ *string* 238 239 Returns an encoded form of *string*, choosing the most restricted ASN\.1 240 string type possible\. If the string contains non\-ASCII characters, then 241 there is more than one string type which can be used\. See 242 __::asn::defaultStringType__\. 243 244 - <a name='25'></a>__::asn::defaultStringType__ ?*type*? 245 246 Selects the string type to use for the encoding of non\-ASCII strings\. 247 Returns current default when called without argument\. If the argument 248 *type* is supplied, it should be either __UTF8__ or __BMP__ to 249 choose UTF8String or BMPString respectively\. 250 251## <a name='subsection2'></a>DECODER 252 253General notes: 254 255 1. Nearly all decoder commands take two arguments\. These arguments are 256 variable names, except for __::asn::asnGetResponse__\. The first 257 variable contains the encoded ASN value to decode at the beginning, and 258 more, and the second variable is where the value is stored to\. The 259 remainder of the input after the decoded value is stored back into the 260 datavariable\. 261 262 1. After extraction the data variable is always modified first, before by 263 writing the extracted value to its variable\. This means that if both 264 arguments refer to the same variable, it will always contain the extracted 265 value after the call, and not the remainder of the input\. 266 267 - <a name='26'></a>__::asn::asnPeekByte__ *data\_var* *byte\_var* 268 269 Retrieve the first byte of the data, without modifing *data\_var*\. This can 270 be used to check for implicit tags\. 271 272 - <a name='27'></a>__::asn::asnGetLength__ *data\_var* *length\_var* 273 274 Decode the length information for a block of BER data\. The tag has already 275 to be removed from the data\. 276 277 - <a name='28'></a>__::asn::asnGetResponse__ *chan* *data\_var* 278 279 Reads an encoded ASN *sequence* from the channel *chan* and stores it 280 into the variable named by *data\_var*\. 281 282 - <a name='29'></a>__::asn::asnGetInteger__ *data\_var* *int\_var* 283 284 Assumes that an encoded integer value is at the front of the data stored in 285 the variable named *data\_var*, extracts and stores it into the variable 286 named by *int\_var*\. Additionally removes all bytes associated with the 287 value from the data for further processing by the following decoder 288 commands\. 289 290 - <a name='30'></a>__::asn::asnGetEnumeration__ *data\_var* *enum\_var* 291 292 Assumes that an enumeration id is at the front of the data stored in the 293 variable named *data\_var*, and stores it into the variable named by 294 *enum\_var*\. Additionally removes all bytes associated with the value from 295 the data for further processing by the following decoder commands\. 296 297 - <a name='31'></a>__::asn::asnGetOctetString__ *data\_var* *string\_var* 298 299 Assumes that a string is at the front of the data stored in the variable 300 named *data\_var*, and stores it into the variable named by *string\_var*\. 301 Additionally removes all bytes associated with the value from the data for 302 further processing by the following decoder commands\. 303 304 - <a name='32'></a>__::asn::asnGetString__ *data\_var* *string\_var* ?*type\_var*? 305 306 Decodes a user\-readable string\. This is a convenience function which is able 307 to automatically distinguish all supported ASN\.1 string types and convert 308 the input value appropriately\. See __::asn::asnGetPrintableString__, 309 __::asnGetIA5String__, etc\. below for the type\-specific conversion 310 commands\. 311 312 If the optional third argument *type\_var* is supplied, then the type of 313 the incoming string is stored in the variable named by it\. 314 315 The function throws the error "Invalid command name 316 asnGetSome__UnsupportedString__" if the unsupported string type 317 __Unsupported__ is encountered\. You can create the appropriate function 318 "asn::asnGetSome__UnsupportedString__" in your application if 319 neccessary\. 320 321 - <a name='33'></a>__::asn::asnGetNumericString__ *data\_var* *string\_var* 322 323 Assumes that a numeric string value is at the front of the data stored in 324 the variable named *data\_var*, and stores it into the variable named by 325 *string\_var*\. Additionally removes all bytes associated with the value 326 from the data for further processing by the following decoder commands\. 327 328 - <a name='34'></a>__::asn::asnGetPrintableString__ *data\_var* *string\_var* 329 330 Assumes that a printable string value is at the front of the data stored in 331 the variable named *data\_var*, and stores it into the variable named by 332 *string\_var*\. Additionally removes all bytes associated with the value 333 from the data for further processing by the following decoder commands\. 334 335 - <a name='35'></a>__::asn::asnGetIA5String__ *data\_var* *string\_var* 336 337 Assumes that a IA5 \(ASCII\) string value is at the front of the data stored 338 in the variable named *data\_var*, and stores it into the variable named by 339 *string\_var*\. Additionally removes all bytes associated with the value 340 from the data for further processing by the following decoder commands\. 341 342 - <a name='36'></a>__::asn::asnGetBMPString__ *data\_var* *string\_var* 343 344 Assumes that a BMP \(two\-byte unicode\) string value is at the front of the 345 data stored in the variable named *data\_var*, and stores it into the 346 variable named by *string\_var*, converting it into a proper Tcl string\. 347 Additionally removes all bytes associated with the value from the data for 348 further processing by the following decoder commands\. 349 350 - <a name='37'></a>__::asn::asnGetUTF8String__ *data\_var* *string\_var* 351 352 Assumes that a UTF8 string value is at the front of the data stored in the 353 variable named *data\_var*, and stores it into the variable named by 354 *string\_var*, converting it into a proper Tcl string\. Additionally removes 355 all bytes associated with the value from the data for further processing by 356 the following decoder commands\. 357 358 - <a name='38'></a>__::asn::asnGetUTCTime__ *data\_var* *utc\_var* 359 360 Assumes that a UTC time value is at the front of the data stored in the 361 variable named *data\_var*, and stores it into the variable named by 362 *utc\_var*\. The UTC time value is stored as a string, which has to be 363 decoded with the usual clock scan commands\. Additionally removes all bytes 364 associated with the value from the data for further processing by the 365 following decoder commands\. 366 367 - <a name='39'></a>__::asn::asnGetBitString__ *data\_var* *bits\_var* 368 369 Assumes that a bit string value is at the front of the data stored in the 370 variable named *data\_var*, and stores it into the variable named by 371 *bits\_var* as a string containing only 0 and 1\. Additionally removes all 372 bytes associated with the value from the data for further processing by the 373 following decoder commands\. 374 375 - <a name='40'></a>__::asn::asnGetObjectIdentifier__ *data\_var* *oid\_var* 376 377 Assumes that a object identifier \(OID\) value is at the front of the data 378 stored in the variable named *data\_var*, and stores it into the variable 379 named by *oid\_var* as a list of integers\. Additionally removes all bytes 380 associated with the value from the data for further processing by the 381 following decoder commands\. 382 383 - <a name='41'></a>__::asn::asnGetBoolean__ *data\_var* *bool\_var* 384 385 Assumes that a boolean value is at the front of the data stored in the 386 variable named *data\_var*, and stores it into the variable named by 387 *bool\_var*\. Additionally removes all bytes associated with the value from 388 the data for further processing by the following decoder commands\. 389 390 - <a name='42'></a>__::asn::asnGetNull__ *data\_var* 391 392 Assumes that a NULL value is at the front of the data stored in the variable 393 named *data\_var* and removes the bytes used to encode it from the data\. 394 395 - <a name='43'></a>__::asn::asnGetSequence__ *data\_var* *sequence\_var* 396 397 Assumes that an ASN sequence is at the front of the data stored in the 398 variable named *data\_var*, and stores it into the variable named by 399 *sequence\_var*\. Additionally removes all bytes associated with the value 400 from the data for further processing by the following decoder commands\. 401 402 The data in *sequence\_var* is encoded binary and has to be further decoded 403 according to the definition of the sequence, using the decoder commands 404 here\. 405 406 - <a name='44'></a>__::asn::asnGetSet__ *data\_var* *set\_var* 407 408 Assumes that an ASN set is at the front of the data stored in the variable 409 named *data\_var*, and stores it into the variable named by *set\_var*\. 410 Additionally removes all bytes associated with the value from the data for 411 further processing by the following decoder commands\. 412 413 The data in *set\_var* is encoded binary and has to be further decoded 414 according to the definition of the set, using the decoder commands here\. 415 416 - <a name='45'></a>__::asn::asnGetApplication__ *data\_var* *appNumber\_var* ?*content\_var*? ?*encodingType\_var*? 417 418 Assumes that an ASN application construct is at the front of the data stored 419 in the variable named *data\_var*, and stores its id into the variable 420 named by *appNumber\_var*\. Additionally removes all bytes associated with 421 the value from the data for further processing by the following decoder 422 commands\. If a *content\_var* is specified, then the command places all 423 data associated with it into the named variable, in the binary form which 424 can be processed using the decoder commands of this package\. If a 425 *encodingType\_var* is specified, then that var is set to 1 if the encoding 426 is constructed and 0 if it is primitive\. 427 428 Otherwise it is the responsibility of the caller to decode the remainder of 429 the application construct based on the id retrieved by this command, using 430 the decoder commands of this package\. 431 432 - <a name='46'></a>__::asn::asnGetContext__ *data\_var* *contextNumber\_var* ?*content\_var*? ?*encodingType\_var*? 433 434 Assumes that an ASN context tag construct is at the front of the data stored 435 in the variable named *data\_var*, and stores its id into the variable 436 named by *contextNumber\_var*\. Additionally removes all bytes associated 437 with the value from the data for further processing by the following decoder 438 commands\. If a *content\_var* is specified, then the command places all 439 data associated with it into the named variable, in the binary form which 440 can be processed using the decoder commands of this package\. If a 441 *encodingType\_var* is specified, then that var is set to 1 if the encoding 442 is constructed and 0 if it is primitive\. 443 444 Otherwise it is the responsibility of the caller to decode the remainder of 445 the construct based on the id retrieved by this command, using the decoder 446 commands of this package\. 447 448## <a name='subsection3'></a>HANDLING TAGS 449 450Working with ASN\.1 you often need to decode tagged values, which use a tag thats 451different from the universal tag for a type\. In those cases you have to replace 452the tag with the universal tag used for the type, to decode the value\. To decode 453a tagged value use the __::asn::asnRetag__ to change the tag to the 454appropriate type to use one of the decoders for primitive values\. To help with 455this the module contains three functions: 456 457 - <a name='47'></a>__::asn::asnPeekTag__ *data\_var* *tag\_var* *tagtype\_var* *constr\_var* 458 459 The __::asn::asnPeekTag__ command can be used to take a peek at the data 460 and decode the tag value, without removing it from the data\. The *tag\_var* 461 gets set to the tag number, while the *tagtype\_var* gets set to the class 462 of the tag\. \(Either UNIVERSAL, CONTEXT, APPLICATION or PRIVATE\)\. The 463 *constr\_var* is set to 1 if the tag is for a constructed value, and to 0 464 for not constructed\. It returns the length of the tag\. 465 466 - <a name='48'></a>__::asn::asnTag__ *tagnumber* ?*class*? ?*tagstyle*? 467 468 The __::asn::asnTag__ can be used to create a tag value\. The 469 *tagnumber* gives the number of the tag, while the *class* gives one of 470 the classes \(UNIVERSAL,CONTEXT,APPLICATION or PRIVATE\)\. The class may be 471 abbreviated to just the first letter \(U,C,A,P\), default is UNIVERSAL\. The 472 *tagstyle* is either C for Constructed encoding, or P for primitve 473 encoding\. It defaults to P\. You can also use 1 instead of C and 0 instead of 474 P for direct use of the values returned by __::asn::asnPeekTag__\. 475 476 - <a name='49'></a>__::asn::asnRetag__ *data\_var* *newTag* 477 478 Replaces the tag in front of the data in *data\_var* with *newTag*\. The 479 new Tag can be created using the __::asn::asnTag__ command\. 480 481# <a name='section3'></a>EXAMPLES 482 483Examples for the usage of this package can be found in the implementation of 484package __[ldap](\.\./ldap/ldap\.md)__\. 485 486# <a name='section4'></a>Bugs, Ideas, Feedback 487 488This document, and the package it describes, will undoubtedly contain bugs and 489other problems\. Please report such in the category *asn* of the [Tcllib 490Trackers](http://core\.tcl\.tk/tcllib/reportlist)\. Please also report any ideas 491for enhancements you may have for either package and/or documentation\. 492 493When proposing code changes, please provide *unified diffs*, i\.e the output of 494__diff \-u__\. 495 496Note further that *attachments* are strongly preferred over inlined patches\. 497Attachments can be made by going to the __Edit__ form of the ticket 498immediately after its creation, and then using the left\-most button in the 499secondary navigation bar\. 500 501# <a name='keywords'></a>KEYWORDS 502 503[asn](\.\./\.\./\.\./\.\./index\.md\#asn), [ber](\.\./\.\./\.\./\.\./index\.md\#ber), 504[cer](\.\./\.\./\.\./\.\./index\.md\#cer), [der](\.\./\.\./\.\./\.\./index\.md\#der), 505[internet](\.\./\.\./\.\./\.\./index\.md\#internet), 506[protocol](\.\./\.\./\.\./\.\./index\.md\#protocol), 507[x\.208](\.\./\.\./\.\./\.\./index\.md\#x\_208), [x\.209](\.\./\.\./\.\./\.\./index\.md\#x\_209) 508 509# <a name='category'></a>CATEGORY 510 511Networking 512 513# <a name='copyright'></a>COPYRIGHT 514 515Copyright © 2004 Andreas Kupries <andreas\_kupries@users\.sourceforge\.net> 516Copyright © 2004 Jochen Loewer <loewerj@web\.de> 517Copyright © 2004\-2011 Michael Schlenker <mic42@users\.sourceforge\.net> 518