首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用GeneralName创建pyasn1?

如何使用GeneralName创建pyasn1?
EN

Stack Overflow用户
提问于 2020-02-26 08:21:11
回答 1查看 287关注 0票数 0

作为pyasn1 (pyasn1 0.4.8,pyasn1 1-模块0.2.8)和ASN.1的新手,我正在尝试构建一个GeneralName

代码语言:javascript
复制
>>> from pyasn1.codec.der.encoder import encode
>>> from pyasn1.type import char
>>> from pyasn1_modules import rfc2459
>>> from pyasn1_modules.rfc2459 import (
...     AttributeTypeAndValue, GeneralName, Name, RelativeDistinguishedName, RDNSequence)
>>> 
>>> rdn = RelativeDistinguishedName()
>>> attr_type_and_value = AttributeTypeAndValue()
>>> attr_type_and_value['type'] = rfc2459.id_at_countryName
>>> attr_type_and_value['value'] = encode(char.UTF8String('DE'))
>>> rdn.append(attr_type_and_value)
>>> 
>>> rdn_sequence = RDNSequence()
>>> rdn_sequence.append(rdn)
>>> 
>>> name = Name()
>>> name[0] = rdn_sequence
>>> 
>>> general_name = GeneralName()
>>> general_name['directoryName'] = name
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/pyasn1/type/univ.py", line 2246, in __setitem__
    self.setComponentByName(idx, value)
  File "/usr/lib/python3.6/site-packages/pyasn1/type/univ.py", line 2413, in setComponentByName
    idx, value, verifyConstraints, matchTags, matchConstraints
  File "/usr/lib/python3.6/site-packages/pyasn1/type/univ.py", line 3119, in setComponentByPosition
    Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints)
  File "/usr/lib/python3.6/site-packages/pyasn1/type/univ.py", line 2601, in setComponentByPosition
    raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
pyasn1.error.PyAsn1Error: Component value is tag-incompatible: <Name value object, tagSet=<TagSet object, untagged>, [...]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/site-packages/pyasn1/type/univ.py", line 2250, in __setitem__
    raise KeyError(sys.exc_info()[1])
KeyError: PyAsn1Error('Component value is tag-incompatible: <Name value object, tagSet=<TagSet object, untagged>, [...]

我截断了非常长的异常消息。据我所知,其本质是,所提供的Name对象被取消标记,而某些标记则是预期的。我可以通过使用general_name.setComponentByName('directoryName', name, matchTags=False)来绕过异常,但我不确定这是否只是关闭了所需的/重要的检查,并会在稍后的时候咬我一口。pyasn1 TagTagSet文档并没有启发我,但这可能是因为我还没有真正理解ASN.1中标记的用途。

因此,我的主要问题是:如何使用GeneralName正确地创建pyasn1?分问题:

  • ASN.1中标签的用途是什么?我认为它们是类型说明符(如:“这是整数、布尔值、序列等”),但显然我遗漏了一些东西。
  • 我使用UTF8String。对用OpenSSL创建的时间戳响应进行解码,我发现在GeneralName中使用了PrintableString。我直觉地选择了前者,但这会导致问题(取决于使用的上下文)吗?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-27 11:53:22

我认为这是pyasn1的一个缺陷或限制

我想知道这是否与此有关:https://github.com/etingof/pyasn1/issues/179

等级库

代码语言:javascript
复制
GeneralName ::= CHOICE {
           otherName                       [0]     OtherName,
           rfc822Name                      [1]     IA5String,
           dNSName                         [2]     IA5String,
           x400Address                     [3]     ORAddress,
           directoryName                   [4]     Name,
           ediPartyName                    [5]     EDIPartyName,
           uniformResourceIdentifier       [6]     IA5String,
           iPAddress                       [7]     OCTET STRING,
           registeredID                    [8]     OBJECT IDENTIFIER}

Name            ::=   CHOICE { -- only one possibility for now --
                                 rdnSequence  RDNSequence }

RDNSequence     ::=   SEQUENCE OF RelativeDistinguishedName

对于ASN.1,通常有一个编译步骤来生成一些代码。使用pyasn1,要么自己编写代码,要么包含一些模块。

由于您包括modules.rfc2459,唯一的工作就是使用这些类。

你的写作看上去很合法

代码语言:javascript
复制
>>> rdn_sequence = RDNSequence()
>>> rdn_sequence.append(rdn)
>>> 
>>> name = Name()
>>> name[0] = rdn_sequence
>>> 
>>> general_name = GeneralName()
>>> general_name['directoryName'] = name

但似乎pyasn1只允许速记访问

代码语言:javascript
复制
>>> rdn_sequence = RDNSequence()
>>> rdn_sequence.append(rdn)
>>> 
>>> general_name = GeneralName()
>>> general_name['directoryName'][''] = rdn_sequence

我觉得两者都应该允许..。

至于标签:在使用pyasn1模块时,您不必担心它们。当编码形式为标记/长度/值时,需要它们对消息进行编码(So、BER、CER和DER ASN.1编码规则)。

至于类型(如UTF8String):您不能更改它们,它们必须是从ASN.1规范中读取的类型。它们有一个(所谓的通用)标记与它们相关联,您编码的消息不会被接收方理解。

请注意,名称的实现与规范之间存在细微差异(规范有一个命名类型,而实现没有名称)。这在过去是允许的。

代码语言:javascript
复制
class Name(univ.Choice):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('', RDNSequence())
    )

但我不认为这是个问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60409559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档