go 编码/ASN.1:解组SEQUENCE OF SET时出错

but5z9lq  于 2个月前  发布在  Go
关注(0)|答案(8)|浏览(34)

你正在使用的Go版本是什么(go version)?
go1.11 windows/amd64
这个问题在最新版本的发布中是否会重现?
是的
你正在使用什么操作系统和处理器架构(go env)?

set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\xxx\AppData\Local\go-build
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\dev;C:\gopath
set GOPROXY=
set GORACE=
set GOROOT=C:\Go
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\xxx\AppData\Local\Temp\go-build551125774=/tmp/go-build -gno-rec
ord-gcc-switches

你做了什么?

package main

import (
	"encoding/asn1"
	"fmt"
)

//` schema:
//
//	World-Schema DEFINITIONS AUTOMATIC TAGS ::=
//	BEGIN
//	SomeStruct ::= SEQUENCE
//	{
//		id      INTEGER,
//		field1  SEQUENCE OF SomeSet
//	}
//	SomeSet ::= SET
//	{
//		field2 INTEGER
//	}
//	END
//`

// data
//	{
//		"id":1,
//		"field1": [{"field2": 1}, {"field2": 2}]
//	}

// encode with http://asn1-playground.oss.com/
const encodedDer = "\x30\x0F\x80\x01\x01\xA1\x0A\x31\x03\x80\x01\x01\x31\x03\x80\x01\x02"

type SomeStruct struct {
	ID int `asn1:"tag:0"`
	SomeSetSlice []SomeSet `asn1:"tag:1,set"`
}

type SomeSet struct {
	Field2 int `asn1:"tag:0"`
}

func main() {
	var b SomeStruct
	_, err := asn1.Unmarshal([]byte(encodedDer), &b)
	if err != nil {
		panic(err)
	}
	fmt.Println(b)
}

播放链接:
https://play.golang.org/p/V-za5Cu1wkr
你期望看到什么?
SEQUENCE OF SET 应该被正确地解组到结构体切片中。文档说SET可以被解组到结构体中。所以我相信一个SEQUENCE OF SET应该被正确地解组到结构体切片中。
你实际上看到了什么?
asn1:结构错误:序列标签不匹配。
问题可能出在从parseSequenceOf调用getUniversalTag函数时。例如,

case reflect.Struct:
		return false, TagSequence, true, true

当结构体是切片元素时,无法将结构体标记为SET(17),它总是被标记为SEQUENCE(16)。

ubby3x7f

ubby3x7f2#

我遇到了类似的问题。

dgenwo3n

dgenwo3n3#

https://golang.org/cl/160819提到了这个问题:encoding/asn1: fix unmarshalling SEQUENCE OF SET. Fixes #27426

vom3gejh

vom3gejh4#

已恢复,因为它导致了加密/TLS故障。
当Go 1.15开发树在2月开放时,您可以再次尝试。

zzwlnbp8

zzwlnbp85#

如何使用Go 1.15开发版本来查看此问题是否已修复?
当我尝试使用tls.loadx509keypair读取证书时,我遇到了类似的问题。

2fjabf4q

2fjabf4q6#

你好,
@bradfitz 我在尝试解析一组集合时遇到了类似的问题,我使用的是golang 1.11.4。这个问题解决了吗?
@bragi92 你在这个错误上找到了任何解决方法吗?我也有一个复合扩展,也遇到了这个问题。

4si2a6ki

4si2a6ki7#

对于我的场景,我是一个使用dotnet core可执行文件生成自签名证书的人。当我从生成的证书中删除以下代码行时:

//certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false,
 // new AuthorityKeyIdentifier(
 // new GeneralNames(new GeneralName(certName)), serialNumber));

错误得到了修复,我能够使用tls.loadx509keypair读取证书。所以我找到了一个解决方法,但我仍然不确定问题到底是什么! :(

yzckvree

yzckvree8#

这是一个有趣的问题,encoding/asn1似乎支持SET的SEQUENCE(通过在typed slices上使用SET后缀,即从crypto/x509/pkixtype RelativeDistinguishedNameSET []AttributeTypeAndValue),但不支持SET的SEQUENCE(其中SET是一个结构体,而不是嵌套的SET OF...),这是文档建议的内容:
如果slice元素的类型名称以“SET”结尾,那么它被视为设置了“set”标签。
这里的困惑之处是it指的是什么,是元素的类型还是slice。它似乎暗示的是前者,但实际上是后者(后缀是在slice类型上检查的,而不是在元素上,结果是SET of ...而不是SEQUENCE of SET)。
这种行为目前是依赖于的,例如对于之前提到的pkix.RelativeDistinguishedNameSET,生成SET of SEQUENCE,所以看起来文档应该修复一下。
为了支持SET的SEQUENCE,似乎在CL 160819中建议的方法是合适的。导致更改失败的主要原因是由于在crypto/x509中为x509.AttributeTypeAndValueSET使用的现有SET后缀最终被编组为SET而不是SEQUENCE。RFC 2986将此结构定义为SEQUENCE,因此命名约定似乎是错误的(或者可能曾经引用过一些过去已经丢失的上下文)。为了在CL 160819世界中工作,这种类型需要在内部重新别名,以便asn1.Marshal不会尝试将其转换为SET,这可以正常工作,但有点hack,并引发其他非标准库代码可能正在使用此命名方案并期望获得SEQUENCE而不是SET的问题。
我能想到的解决这个问题的唯一其他方法是为此类型的切片添加一个新的asn1字段参数,该参数将传递给makeBody,表示slice的元素应该是SET,而不是slice本身,比如elements-set或其他什么...(这将与文档当前描述的内容相匹配)。

相关问题