如何使用PyASN1为递归ASN.1规范建模?

2024-10-01 09:21:37 发布

您现在位置:Python中文网/ 问答频道 /正文

PKCS#15中,CommonObjectAttributes中有一个结构,它描述了访问对象的规则。令我非常懊恼的是,它是递归的,也就是说,它可以包含自己:

SecurityCondition ::= CHOICE {
    authId Identifier,
    not [0] SecurityCondition,
    and [1] SEQUENCE SIZE (2..pkcs15-ub-securityConditions) OF SecurityCondition,
    or  [2] SEQUENCE SIZE (2..pkcs15-ub-securityConditions) OF SecurityCondition,
    ... -- For future extensions
}

我不知道如何用pyasn1建模。我想我可以强制一个固定级别的递归,让它们相互依赖,但在我看来,这不是一个非常有吸引力的解决方案。有人有更好的主意吗?在

更新

通过省略SecurityCondition的定义来测试Ilya Etingofs方法,首先我得到了这样的结论:

^{pr2}$

使用示例:

# Example usage
inner = univ.SequenceOf()
inner.setComponentByPosition(0, SecurityCondition().setComponentByName("authId", "\x02"))
inner.setComponentByPosition(1, SecurityCondition().setComponentByName("authId", "\x03"))

outer = univ.SequenceOf()
outer.setComponentByPosition(0, SecurityCondition().setComponentByName("authId", "\x01"))
outer.setComponentByPosition(1, SecurityCondition().setComponentByName("or", inner))

wrapper = SecurityCondition().setComponentByName("and", outer)

如果没有使用子类型规范或隐式标记,它似乎可以工作:

>>> print wrapper.prettyPrint()
SecurityCondition:
 and=SequenceOf:
  SecurityCondition:
   authId=0x01
  SecurityCondition:
   or=SequenceOf:
    SecurityCondition:
     authId=0x02
    SecurityCondition:
     authId=0x03

SEQUENCE(2 elem)
    OCTET STRING(2 byte) 01
    SEQUENCE(2 elem)
        OCTET STRING(1 byte) 02
        OCTET STRING(1 byte) 03

如果implicitTag和{}未注释,则错误

PyAsn1Error: Component type error SequenceOf() vs
SequenceOf().setComponentByPosition(0, SecurityCondition().setComponentByPosition(0,
     OctetString(hexValue='02'))).setComponentByPosition(1,
     SecurityCondition().setComponentByPosition(0, OctetString(hexValue='03')))

发生。巧合的是,如果我尝试固定数量的递归,我会得到相同的错误。在


Tags: orandsizestringbyteinnersequenceouter
1条回答
网友
1楼 · 发布于 2024-10-01 09:21:37

好吧,我之前的黑客攻击并没有真正奏效。更新为更具攻击性的黑客攻击:

class SecurityCondition(univ.Choice):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('authId', univ.OctetString().subtype(subtypeSpec=constraint.ValueSizeConstraint(0, 255))),
        namedtype.NamedType('not', univ.Any()),  # just a placeholder
        namedtype.NamedType('and', univ.Any()),  # just a placeholder
        namedtype.NamedType('or', univ.Any())    # just a placeholder
    )

SecurityCondition.componentType[1]._NamedType__type = SecurityCondition().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))
SecurityCondition.componentType[2]._NamedType__type =  univ.SequenceOf(componentType=SecurityCondition()).subtype(implicitTag=tag.Tag(tag.tagClass.ontext, tag.tagFormatSimple, 1), subtypeSpec=constraint.ValueSizeConstraint(2, 255))
SecurityCondition.componentType[3]._NamedType__type =  univ.SequenceOf(componentType=SecurityCondition()).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2), subtypeSpec=constraint.ValueSizeConstraint(2, 255))

# Initialize an instance of SecurityCondition

top = SecurityCondition() # SecurityCondition
top['and'] = None         # SecurityCondition->SequenceOf
top['and'][0] = None      # SecurityCondition->SequenceOf->SecurityCondition
top['and'][0]['authId'] = "\x02"
top['and'][1] = None      # SecurityCondition->SequenceOf->SecurityCondition
top['and'][1]['authId'] = "\x03"

print(top.prettyPrint())

对,这很难看,而且会产生循环引用。从好的方面看,这似乎奏效了。在

相关问题 更多 >