Home | History | Annotate | Download | only in doc
      1 <html>
      2 <title>
      3 PyASN1 data model and scalar types
      4 </title>
      5 <head>
      6 </head>
      7 <body>
      8 <center>
      9 <table width=60%>
     10 <tr>
     11 <td>
     12 
     13 <h3>
     14 1. Data model for ASN.1 types
     15 </h3>
     16 
     17 <p>
     18 All ASN.1 types could be categorized into two groups: scalar (also called
     19 simple or primitive) and constructed. The first group is populated by
     20 well-known types like Integer or String. Members of constructed group
     21 hold other types (simple or constructed) as their inner components, thus
     22 they are semantically close to a programming language records or lists.
     23 </p>
     24 
     25 <p>
     26 In pyasn1, all ASN.1 types and values are implemented as Python objects.
     27 The same pyasn1 object can represent either ASN.1 type and/or value
     28 depending of the presense of value initializer on object instantiation.
     29 We will further refer to these as <i>pyasn1 type object</i> versus <i>pyasn1
     30 value object</i>.
     31 </p>
     32 
     33 <p>
     34 Primitive ASN.1 types are implemented as immutable scalar objects. There values
     35 could be used just like corresponding native Python values (integers,
     36 strings/bytes etc) and freely mixed with them in expressions.
     37 </p>
     38 
     39 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
     40 <pre>
     41 >>> from pyasn1.type import univ
     42 >>> asn1IntegerValue = univ.Integer(12)
     43 >>> asn1IntegerValue - 2
     44 10
     45 >>> univ.OctetString('abc') == 'abc'
     46 True   # Python 2
     47 >>> univ.OctetString(b'abc') == b'abc'
     48 True   # Python 3
     49 </pre>
     50 </td></tr></table>
     51 
     52 <p>
     53 It would be an error to perform an operation on a pyasn1 type object
     54 as it holds no value to deal with:
     55 </p>
     56 
     57 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
     58 <pre>
     59 >>> from pyasn1.type import univ
     60 >>> asn1IntegerType = univ.Integer()
     61 >>> asn1IntegerType - 2
     62 ...
     63 pyasn1.error.PyAsn1Error: No value for __coerce__()
     64 </pre>
     65 </td></tr></table>
     66 
     67 <a name="1.1"></a>
     68 <h4>
     69 1.1 Scalar types
     70 </h4>
     71 
     72 <p>
     73 In the sub-sections that follow we will explain pyasn1 mapping to those
     74 primitive ASN.1 types. Both, ASN.1 notation and corresponding pyasn1
     75 syntax will be given in each case.
     76 </p>
     77 
     78 <a name="1.1.1"></a>
     79 <h4>
     80 1.1.1 Boolean type
     81 </h4>
     82 
     83 <p>
     84 This is the simplest type those values could be either True or False.
     85 </p>
     86 
     87 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
     88 <pre>
     89 ;; type specification
     90 FunFactorPresent ::= BOOLEAN
     91 
     92 ;; values declaration and assignment
     93 pythonFunFactor FunFactorPresent ::= TRUE
     94 cobolFunFactor FunFactorPresent :: FALSE
     95 </pre>
     96 </td></tr></table>
     97 
     98 <p>
     99 And here's pyasn1 version of it:
    100 </p>
    101 
    102 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    103 <pre>
    104 >>> from pyasn1.type import univ
    105 >>> class FunFactorPresent(univ.Boolean): pass
    106 ... 
    107 >>> pythonFunFactor = FunFactorPresent(True)
    108 >>> cobolFunFactor = FunFactorPresent(False)
    109 >>> pythonFunFactor
    110 FunFactorPresent('True(1)')
    111 >>> cobolFunFactor
    112 FunFactorPresent('False(0)')
    113 >>> pythonFunFactor == cobolFunFactor
    114 False
    115 >>>
    116 </pre>
    117 </td></tr></table>
    118 
    119 <a name="1.1.2"></a>
    120 <h4>
    121 1.1.2 Null type
    122 </h4>
    123 
    124 <p>
    125 The NULL type is sometimes used to express the absense of any information.
    126 </p>
    127 
    128 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    129 <pre>
    130 ;; type specification
    131 Vote ::= CHOICE {
    132   agreed BOOLEAN,
    133   skip NULL
    134 }
    135 </td></tr></table>
    136 
    137 ;; value declaration and assignment
    138 myVote Vote ::= skip:NULL
    139 </pre>
    140 
    141 <p>
    142 We will explain the CHOICE type later in this paper, meanwhile the NULL
    143 type:
    144 </p>
    145 
    146 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    147 <pre>
    148 >>> from pyasn1.type import univ
    149 >>> skip = univ.Null()
    150 >>> skip
    151 Null('')
    152 >>>
    153 </pre>
    154 </td></tr></table>
    155 
    156 <a name="1.1.3"></a>
    157 <h4>
    158 1.1.3 Integer type
    159 </h4>
    160 
    161 <p>
    162 ASN.1 defines the values of Integer type as negative or positive of whatever
    163 length. This definition plays nicely with Python as the latter places no
    164 limit on Integers. However, some ASN.1 implementations may impose certain
    165 limits of integer value ranges. Keep that in mind when designing new
    166 data structures.
    167 </p>
    168 
    169 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    170 <pre>
    171 ;; values specification
    172 age-of-universe INTEGER ::= 13750000000
    173 mean-martian-surface-temperature INTEGER ::= -63
    174 </pre>
    175 </td></tr></table>
    176 
    177 <p>
    178 A rather strigntforward mapping into pyasn1:
    179 </p>
    180 
    181 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    182 <pre>
    183 >>> from pyasn1.type import univ
    184 >>> ageOfUniverse = univ.Integer(13750000000)
    185 >>> ageOfUniverse
    186 Integer(13750000000)
    187 >>>
    188 >>> meanMartianSurfaceTemperature = univ.Integer(-63)
    189 >>> meanMartianSurfaceTemperature
    190 Integer(-63)
    191 >>>
    192 </pre>
    193 </td></tr></table>
    194 
    195 <p>
    196 ASN.1 allows to assign human-friendly names to particular values of
    197 an INTEGER type.
    198 </p>
    199 
    200 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    201 <pre>
    202 Temperature ::= INTEGER {
    203   freezing(0),
    204   boiling(100) 
    205 }
    206 </pre>
    207 </td></tr></table>
    208 
    209 <p>
    210 The Temperature type expressed in pyasn1:
    211 </p>
    212 
    213 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    214 <pre>
    215 >>> from pyasn1.type import univ, namedval
    216 >>> class Temperature(univ.Integer):
    217 ...   namedValues = namedval.NamedValues(('freezing', 0), ('boiling', 100))
    218 ...
    219 >>> t = Temperature(0)
    220 >>> t
    221 Temperature('freezing(0)')
    222 >>> t + 1
    223 Temperature(1)
    224 >>> t + 100
    225 Temperature('boiling(100)')
    226 >>> t = Temperature('boiling')
    227 >>> t
    228 Temperature('boiling(100)')
    229 >>> Temperature('boiling') / 2
    230 Temperature(50)
    231 >>> -1 < Temperature('freezing')
    232 True
    233 >>> 47 > Temperature('boiling')
    234 False
    235 >>>
    236 </pre>
    237 </td></tr></table>
    238 
    239 <p>
    240 These values labels have no effect on Integer type operations, any value
    241 still could be assigned to a type (information on value constraints will
    242 follow further in this paper).
    243 </p>
    244 
    245 <a name="1.1.4"></a>
    246 <h4>
    247 1.1.4 Enumerated type
    248 </h4>
    249 
    250 <p>
    251 ASN.1 Enumerated type differs from an Integer type in a number of ways.
    252 Most important is that its instance can only hold a value that belongs
    253 to a set of values specified on type declaration.
    254 </p>
    255 
    256 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    257 <pre>
    258 error-status ::= ENUMERATED {
    259   no-error(0),
    260   authentication-error(10),
    261   authorization-error(20),
    262   general-failure(51)
    263 }
    264 </pre>
    265 </td></tr></table>
    266 
    267 <p>
    268 When constructing Enumerated type we will use two pyasn1 features: values
    269 labels (as mentioned above) and value constraint (will be described in
    270 more details later on).
    271 </p>
    272 
    273 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    274 <pre>
    275 >>> from pyasn1.type import univ, namedval, constraint
    276 >>> class ErrorStatus(univ.Enumerated):
    277 ...   namedValues = namedval.NamedValues(
    278 ...        ('no-error', 0),
    279 ...        ('authentication-error', 10),
    280 ...        ('authorization-error', 20),
    281 ...        ('general-failure', 51)
    282 ...   )
    283 ...   subtypeSpec = univ.Enumerated.subtypeSpec + \
    284 ...                    constraint.SingleValueConstraint(0, 10, 20, 51)
    285 ...
    286 >>> errorStatus = univ.ErrorStatus('no-error')
    287 >>> errorStatus
    288 ErrorStatus('no-error(0)')
    289 >>> errorStatus == univ.ErrorStatus('general-failure')
    290 False
    291 >>> univ.ErrorStatus('non-existing-state')
    292 Traceback (most recent call last):
    293 ...
    294 pyasn1.error.PyAsn1Error: Can't coerce non-existing-state into integer
    295 >>>
    296 </pre>
    297 </td></tr></table>
    298 
    299 <p>
    300 Particular integer values associated with Enumerated value states
    301 have no meaning. They should not be used as such or in any kind of
    302 math operation. Those integer values are only used by codecs to
    303 transfer state from one entity to another.
    304 </p>
    305 
    306 <a name="1.1.5"></a>
    307 <h4>
    308 1.1.5 Real type
    309 </h4>
    310 
    311 <p>
    312 Values of the Real type are a three-component tuple of mantissa, base and 
    313 exponent. All three are integers.
    314 </p>
    315 
    316 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    317 <pre>
    318 pi ::= REAL { mantissa 314159, base 10, exponent -5 }
    319 </pre>
    320 </td></tr></table>
    321 
    322 <p>
    323 Corresponding pyasn1 objects can be initialized with either a three-component
    324 tuple or a Python float. Infinite values could be expressed in a way, 
    325 compatible with Python float type.
    326 
    327 </p>
    328 
    329 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    330 <pre>
    331 >>> from pyasn1.type import univ
    332 >>> pi = univ.Real((314159, 10, -5))
    333 >>> pi
    334 Real((314159, 10,-5))
    335 >>> float(pi)
    336 3.14159
    337 >>> pi == univ.Real(3.14159)
    338 True
    339 >>> univ.Real('inf')
    340 Real('inf')
    341 >>> univ.Real('-inf') == float('-inf')
    342 True
    343 >>>
    344 </pre>
    345 </td></tr></table>
    346 
    347 <p>
    348 If a Real object is initialized from a Python float or yielded by a math
    349 operation, the base is set to decimal 10 (what affects encoding).
    350 </p>
    351 
    352 <a name="1.1.6"></a>
    353 <h4>
    354 1.1.6 Bit string type
    355 </h4>
    356 
    357 <p>
    358 ASN.1 BIT STRING type holds opaque binary data of an arbitrarily length.
    359 A BIT STRING value could be initialized by either a binary (base 2) or 
    360 hex (base 16) value.
    361 </p>
    362 
    363 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    364 <pre>
    365 public-key BIT STRING ::= '1010111011110001010110101101101
    366                            1011000101010000010110101100010
    367                            0110101010000111101010111111110'B
    368 
    369 signature  BIT STRING ::= 'AF01330CD932093392100B39FF00DE0'H
    370 </pre>
    371 </td></tr></table>
    372 
    373 <p>
    374 The pyasn1 BitString objects can initialize from native ASN.1 notation
    375 (base 2 or base 16 strings) or from a Python tuple of binary components.
    376 </p>
    377 
    378 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    379 <pre>
    380 >>> from pyasn1.type import univ
    381 >>> publicKey = univ.BitString(
    382 ...          "'1010111011110001010110101101101"
    383 ...          "1011000101010000010110101100010"
    384 ...          "0110101010000111101010111111110'B"
    385 )
    386 >>> publicKey
    387 BitString("'10101110111100010101101011011011011000101010000010110101100010\
    388 0110101010000111101010111111110'B")
    389 >>> signature = univ.BitString(
    390 ...          "'AF01330CD932093392100B39FF00DE0'H"
    391 ... )
    392 >>> signature
    393 BitString("'101011110000000100110011000011001101100100110010000010010011001\
    394 1100100100001000000001011001110011111111100000000110111100000'B")
    395 >>> fingerprint = univ.BitString(
    396 ...          (1, 0, 1, 1 ,0, 1, 1, 1, 0, 1, 0, 1)
    397 ... )
    398 >>> fingerprint
    399 BitString("'101101110101'B")
    400 >>>
    401 </pre>
    402 </td></tr></table>
    403 
    404 <p>
    405 Another BIT STRING initialization method supported by ASN.1 notation
    406 is to specify only 1-th bits along with their human-friendly label
    407 and bit offset relative to the beginning of the bit string. With this 
    408 method, all not explicitly mentioned bits are doomed to be zeros.
    409 </p>
    410 
    411 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    412 <pre>
    413 bit-mask  BIT STRING ::= {
    414   read-flag(0),
    415   write-flag(2),
    416   run-flag(4)
    417 }
    418 </pre>
    419 </td></tr></table>
    420 
    421 <p>
    422 To express this in pyasn1, we will employ the named values feature (as with
    423 Enumeration type).
    424 </p>
    425 
    426 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    427 <pre>
    428 >>> from pyasn1.type import univ, namedval
    429 >>> class BitMask(univ.BitString):
    430 ...   namedValues = namedval.NamedValues(
    431 ...        ('read-flag', 0),
    432 ...        ('write-flag', 2),
    433 ...        ('run-flag', 4)
    434 ... )
    435 >>> bitMask = BitMask('read-flag,run-flag')
    436 >>> bitMask
    437 BitMask("'10001'B")
    438 >>> tuple(bitMask)
    439 (1, 0, 0, 0, 1)
    440 >>> bitMask[4]
    441 1
    442 >>>
    443 </pre>
    444 </td></tr></table>
    445 
    446 <p>
    447 The BitString objects mimic the properties of Python tuple type in part
    448 of immutable sequence object protocol support.
    449 </p>
    450 
    451 <a name="1.1.7"></a>
    452 <h4>
    453 1.1.7 OctetString type
    454 </h4>
    455 
    456 <p>
    457 The OCTET STRING type is a confusing subject. According to ASN.1
    458 specification, this type is similar to BIT STRING, the major difference
    459 is that the former operates in 8-bit chunks of data. What is important
    460 to note, is that OCTET STRING was NOT designed to handle text strings - the
    461 standard provides many other types specialized for text content. For that
    462 reason, ASN.1 forbids to initialize OCTET STRING values with "quoted text
    463 strings", only binary or hex initializers, similar to BIT STRING ones,
    464 are allowed.
    465 </p>
    466 
    467 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    468 <pre>
    469 thumbnail OCTET STRING ::= '1000010111101110101111000000111011'B
    470 thumbnail OCTET STRING ::= 'FA9823C43E43510DE3422'H
    471 </pre>
    472 </td></tr></table>
    473 
    474 <p>
    475 However, ASN.1 users (e.g. protocols designers) seem to ignore the original
    476 purpose of the OCTET STRING type - they used it for handling all kinds of
    477 data, including text strings.
    478 </p>
    479 
    480 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    481 <pre>
    482 welcome-message OCTET STRING ::= "Welcome to ASN.1 wilderness!"
    483 </pre>
    484 </td></tr></table>
    485 
    486 <p>
    487 In pyasn1, we have taken a liberal approach and allowed both BIT STRING
    488 style and quoted text initializers for the OctetString objects. To avoid
    489 possible collisions, quoted text is the default initialization syntax.
    490 </p>
    491 
    492 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    493 <pre>
    494 >>> from pyasn1.type import univ
    495 >>> thumbnail = univ.OctetString(
    496 ...    binValue='1000010111101110101111000000111011'
    497 ... )
    498 >>> thumbnail
    499 OctetString(hexValue='85eebcec0')
    500 >>> thumbnail = univ.OctetString(
    501 ...    hexValue='FA9823C43E43510DE3422'
    502 ... )
    503 >>> thumbnail
    504 OctetString(hexValue='fa9823c43e4351de34220')
    505 >>>
    506 </pre>
    507 </td></tr></table>
    508 
    509 <p>
    510 Most frequent usage of the OctetString class is to instantiate it with
    511 a text string.
    512 </p>
    513 
    514 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    515 <pre>
    516 >>> from pyasn1.type import univ
    517 >>> welcomeMessage = univ.OctetString('Welcome to ASN.1 wilderness!')
    518 >>> welcomeMessage
    519 OctetString(b'Welcome to ASN.1 wilderness!')
    520 >>> print('%s' % welcomeMessage)
    521 Welcome to ASN.1 wilderness!
    522 >>> welcomeMessage[11:16]
    523 OctetString(b'ASN.1')
    524 >>> 
    525 </pre>
    526 </td></tr></table>
    527 
    528 <p>
    529 OctetString objects support the immutable sequence object protocol.
    530 In other words, they behave like Python 3 bytes (or Python 2 strings).
    531 </p>
    532 
    533 <p>
    534 When running pyasn1 on Python 3, it's better to use the bytes objects for
    535 OctetString instantiation, as it's more reliable and efficient.
    536 </p>
    537 
    538 <p>
    539 Additionally, OctetString's can also be instantiated with a sequence of
    540 8-bit integers (ASCII codes).
    541 </p>
    542 
    543 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    544 <pre>
    545 >>> univ.OctetString((77, 101, 101, 103, 111))
    546 OctetString(b'Meego')
    547 </pre>
    548 </td></tr></table>
    549 
    550 <p>
    551 It is sometimes convenient to express OctetString instances as 8-bit
    552 characters (Python 3 bytes or Python 2 strings) or 8-bit integers.
    553 </p>
    554 
    555 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    556 <pre>
    557 >>> octetString = univ.OctetString('ABCDEF')
    558 >>> octetString.asNumbers()
    559 (65, 66, 67, 68, 69, 70)
    560 >>> octetString.asOctets()
    561 b'ABCDEF'
    562 </pre>
    563 </td></tr></table>
    564 
    565 <a name="1.1.8"></a>
    566 <h4>
    567 1.1.8 ObjectIdentifier type
    568 </h4>
    569 
    570 <p>
    571 Values of the OBJECT IDENTIFIER type are sequences of integers that could
    572 be used to identify virtually anything in the world. Various ASN.1-based
    573 protocols employ OBJECT IDENTIFIERs for their own identification needs.
    574 </p>
    575 
    576 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    577 <pre>
    578 internet-id OBJECT IDENTIFIER ::= {
    579   iso(1) identified-organization(3) dod(6) internet(1)
    580 }
    581 </pre>
    582 </td></tr></table>
    583 
    584 <p>
    585 One of the natural ways to map OBJECT IDENTIFIER type into a Python
    586 one is to use Python tuples of integers. So this approach is taken by
    587 pyasn1.
    588 </p>
    589 
    590 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    591 <pre>
    592 >>> from pyasn1.type import univ
    593 >>> internetId = univ.ObjectIdentifier((1, 3, 6, 1))
    594 >>> internetId
    595 ObjectIdentifier('1.3.6.1')
    596 >>> internetId[2]
    597 6
    598 >>> internetId[1:3]
    599 ObjectIdentifier('3.6')
    600 </pre>
    601 </td></tr></table>
    602 
    603 <p>
    604 A more human-friendly "dotted" notation is also supported.
    605 </p>
    606 
    607 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    608 <pre>
    609 >>> from pyasn1.type import univ
    610 >>> univ.ObjectIdentifier('1.3.6.1')
    611 ObjectIdentifier('1.3.6.1')
    612 </pre>
    613 </td></tr></table>
    614 
    615 <p>
    616 Symbolic names of the arcs of object identifier, sometimes present in
    617 ASN.1 specifications, are not preserved and used in pyasn1 objects.
    618 </p>
    619 
    620 <p>
    621 The ObjectIdentifier objects mimic the properties of Python tuple type in
    622 part of immutable sequence object protocol support.
    623 </p>
    624 
    625 <a name="1.1.9"></a>
    626 <h4>
    627 1.1.9 Character string types
    628 </h4>
    629 
    630 <p>
    631 ASN.1 standard introduces a diverse set of text-specific types. All of them
    632 were designed to handle various types of characters. Some of these types seem
    633 be obsolete nowdays, as their target technologies are gone. Another issue
    634 to be aware of is that raw OCTET STRING type is sometimes used in practice
    635 by ASN.1 users instead of specialized character string types, despite
    636 explicit prohibition imposed by ASN.1 specification.
    637 </p>
    638 
    639 <p>
    640 The two types are specific to ASN.1 are NumericString and PrintableString.
    641 </p>
    642 
    643 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    644 <pre>
    645 welcome-message ::= PrintableString {
    646   "Welcome to ASN.1 text types"
    647 }
    648 
    649 dial-pad-numbers ::= NumericString {
    650   "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
    651 }
    652 </pre>
    653 </td></tr></table>
    654 
    655 <p>
    656 Their pyasn1 implementations are:
    657 </p>
    658 
    659 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    660 <pre>
    661 >>> from pyasn1.type import char
    662 >>> '%s' % char.PrintableString("Welcome to ASN.1 text types")
    663 'Welcome to ASN.1 text types'
    664 >>> dialPadNumbers = char.NumericString(
    665       "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
    666 )
    667 >>> dialPadNumbers
    668 NumericString(b'0123456789')
    669 >>>
    670 </pre>
    671 </td></tr></table>
    672 
    673 <p>
    674 The following types came to ASN.1 from ISO standards on character sets.
    675 </p>
    676 
    677 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    678 <pre>
    679 >>> from pyasn1.type import char
    680 >>> char.VisibleString("abc")
    681 VisibleString(b'abc')
    682 >>> char.IA5String('abc')
    683 IA5String(b'abc')
    684 >>> char.TeletexString('abc')
    685 TeletexString(b'abc')
    686 >>> char.VideotexString('abc')
    687 VideotexString(b'abc')
    688 >>> char.GraphicString('abc')
    689 GraphicString(b'abc')
    690 >>> char.GeneralString('abc')
    691 GeneralString(b'abc')
    692 >>>
    693 </pre>
    694 </td></tr></table>
    695 
    696 <p>
    697 The last three types are relatively recent addition to the family of
    698 character string types: UniversalString, BMPString, UTF8String.
    699 </p>
    700 
    701 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    702 <pre>
    703 >>> from pyasn1.type import char
    704 >>> char.UniversalString("abc")
    705 UniversalString(b'abc')
    706 >>> char.BMPString('abc')
    707 BMPString(b'abc')
    708 >>> char.UTF8String('abc')
    709 UTF8String(b'abc')
    710 >>> utf8String = char.UTF8String('   ')
    711 >>> utf8String
    712 UTF8String(b'\xd0\xa3 \xd0\xbf\xd0\xbe\xd0\xbf\xd0\xb0 \xd0\xb1\xd1\x8b\xd0\xbb\xd0\xb0 \
    713 \xd1\x81\xd0\xbe\xd0\xb1\xd0\xb0\xd0\xba\xd0\xb0')
    714 >>> print(utf8String)
    715    
    716 >>>
    717 </pre>
    718 </td></tr></table>
    719 
    720 <p>
    721 In pyasn1, all character type objects behave like Python strings. None of
    722 them is currently constrained in terms of valid alphabet so it's up to
    723 the data source to keep an eye on data validation for these types.
    724 </p>
    725 
    726 <a name="1.1.10"></a>
    727 <h4>
    728 1.1.10 Useful types
    729 </h4>
    730 
    731 <p>
    732 There are three so-called useful types defined in the standard:
    733 ObjectDescriptor, GeneralizedTime, UTCTime. They all are subtypes
    734 of GraphicString or VisibleString types therefore useful types are
    735 character string types.
    736 </p>
    737 
    738 <p>
    739 It's advised by the ASN.1 standard to have an instance of ObjectDescriptor
    740 type holding a human-readable description of corresponding instance of
    741 OBJECT IDENTIFIER type. There are no formal linkage between these instances
    742 and provision for ObjectDescriptor uniqueness in the standard.
    743 </p>
    744 
    745 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    746 <pre>
    747 >>> from pyasn1.type import useful
    748 >>> descrBER = useful.ObjectDescriptor(
    749       "Basic encoding of a single ASN.1 type"
    750 )
    751 >>> 
    752 </pre>
    753 </td></tr></table>
    754 
    755 <p>
    756 GeneralizedTime and UTCTime types are designed to hold a human-readable
    757 timestamp in a universal and unambiguous form. The former provides
    758 more flexibility in notation while the latter is more strict but has
    759 Y2K issues.
    760 </p>
    761 
    762 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    763 <pre>
    764 ;; Mar 8 2010 12:00:00 MSK
    765 moscow-time GeneralizedTime ::= "20110308120000.0"
    766 ;; Mar 8 2010 12:00:00 UTC
    767 utc-time GeneralizedTime ::= "201103081200Z"
    768 ;; Mar 8 1999 12:00:00 UTC
    769 utc-time UTCTime ::= "9803081200Z"
    770 </pre>
    771 </td></tr></table>
    772 
    773 <table bgcolor="lightgray" border=0 width=100%><TR><TD>
    774 <pre>
    775 >>> from pyasn1.type import useful
    776 >>> moscowTime = useful.GeneralizedTime("20110308120000.0")
    777 >>> utcTime = useful.UTCTime("9803081200Z")
    778 >>> 
    779 </pre>
    780 </td></tr></table>
    781 
    782 <p>
    783 Despite their intended use, these types possess no special, time-related,
    784 handling in pyasn1. They are just printable strings.
    785 </p>
    786 
    787 <hr>
    788 
    789 </td>
    790 </tr>
    791 </table>
    792 </center>
    793 </body>
    794 </html>
    795