| 403 | |
| 404 | |
| 405 | class ObjectIdentifierPayloadDecoder(AbstractSimplePayloadDecoder): |
| 406 | protoComponent = univ.ObjectIdentifier(()) |
| 407 | |
| 408 | def valueDecoder(self, substrate, asn1Spec, |
| 409 | tagSet=None, length=None, state=None, |
| 410 | decodeFun=None, substrateFun=None, |
| 411 | **options): |
| 412 | if tagSet[0].tagFormat != tag.tagFormatSimple: |
| 413 | raise error.PyAsn1Error('Simple tag format expected') |
| 414 | |
| 415 | for chunk in readFromStream(substrate, length, options): |
| 416 | if isinstance(chunk, SubstrateUnderrunError): |
| 417 | yield chunk |
| 418 | |
| 419 | if not chunk: |
| 420 | raise error.PyAsn1Error('Empty substrate') |
| 421 | |
| 422 | oid = () |
| 423 | index = 0 |
| 424 | substrateLen = len(chunk) |
| 425 | while index < substrateLen: |
| 426 | subId = chunk[index] |
| 427 | index += 1 |
| 428 | if subId < 128: |
| 429 | oid += (subId,) |
| 430 | elif subId > 128: |
| 431 | # Construct subid from a number of octets |
| 432 | nextSubId = subId |
| 433 | subId = 0 |
| 434 | continuationOctetCount = 0 |
| 435 | while nextSubId >= 128: |
| 436 | continuationOctetCount += 1 |
| 437 | if continuationOctetCount > MAX_OID_ARC_CONTINUATION_OCTETS: |
| 438 | raise error.PyAsn1Error( |
| 439 | 'OID arc exceeds maximum continuation octets limit (%d) ' |
| 440 | 'at position %d' % (MAX_OID_ARC_CONTINUATION_OCTETS, index) |
| 441 | ) |
| 442 | subId = (subId << 7) + (nextSubId & 0x7F) |
| 443 | if index >= substrateLen: |
| 444 | raise error.SubstrateUnderrunError( |
| 445 | 'Short substrate for sub-OID past %s' % (oid,) |
| 446 | ) |
| 447 | nextSubId = chunk[index] |
| 448 | index += 1 |
| 449 | oid += ((subId << 7) + nextSubId,) |
| 450 | elif subId == 128: |
| 451 | # ASN.1 spec forbids leading zeros (0x80) in OID |
| 452 | # encoding, tolerating it opens a vulnerability. See |
| 453 | # https://www.esat.kuleuven.be/cosic/publications/article-1432.pdf |
| 454 | # page 7 |
| 455 | raise error.PyAsn1Error('Invalid octet 0x80 in OID encoding') |
| 456 | |
| 457 | # Decode two leading arcs |
| 458 | if 0 <= oid[0] <= 39: |
| 459 | oid = (0,) + oid |
| 460 | elif 40 <= oid[0] <= 79: |
| 461 | oid = (1, oid[0] - 40) + oid[1:] |
| 462 | elif oid[0] >= 80: |