在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方法我得到了这个:
class SecurityCondition(univ.Choice):
pass
securityConditionComponentType = namedtype.NamedTypes(
namedtype.NamedType('authId', univ.OctetString().subtype(
subtypeSpec=constraint.ValueSizeConstraint(0, univ.Integer(255)))
),
namedtype.NamedType('not', SecurityCondition().subtype(
implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)
)
),
namedtype.NamedType('and', univ.SequenceOf(componentType=SecurityCondition).subtype(
#implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1),
#subtypeSpec=constraint.ValueSizeConstraint(2, univ.Integer(255))
)
),
namedtype.NamedType('or', univ.SequenceOf(componentType=SecurityCondition).subtype(
#implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2),
#subtypeSpec=constraint.ValueSizeConstraint(2, univ.Integer(255))
)
)
)
SecurityCondition.componentType = securityConditionComponentType
使用示例:
# 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
和subtypeSpec
取消注释错误
PyAsn1Error: Component type error SequenceOf() vs
SequenceOf().setComponentByPosition(0, SecurityCondition().setComponentByPosition(0,
OctetString(hexValue='02'))).setComponentByPosition(1,
SecurityCondition().setComponentByPosition(0, OctetString(hexValue='03')))
发生。巧合的是,如果尝试固定数量的递归,我会得到同样的错误。
答案 0 :(得分:1)
好的,我以前的黑客并没有真正奏效。更新为更激进的黑客攻击:
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())
是的,这很难看,并创建了循环引用。好的一面似乎有效。