go crypto/x509:内部和外部签名算法标识符不匹配

axkjgtzd  于 6个月前  发布在  Go
关注(0)|答案(6)|浏览(201)

你正在使用的Go版本是什么( go version )?

go version go1.17rc2 darwin/arm64

这个问题在最新版本的发布中是否重现?

go version go1.16.6 darwin/arm64 中不重现

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

$ go env

GO111MODULE=""

GOARCH="arm64"

GOBIN=""

GOCACHE="/Users/vvrantchan/Library/Caches/go-build"

GOENV="/Users/vvrantchan/Library/Application Support/go/env"

GOEXE=""

GOFLAGS=""

GOHOSTARCH="arm64"

GOHOSTOS="darwin"

GOINSECURE=""

GOMODCACHE="/Users/vvrantchan/go/pkg/mod"

GONOPROXY=""

GONOSUMDB=""

GOOS="darwin"

GOPATH="/Users/vvrantchan/go"

GOPRIVATE=""

GOPROXY=" [https://proxy.golang.org,direct](https://proxy.golang.org,direct) "

GOROOT="/opt/homebrew/Cellar/go/1.16.6/libexec"

GOSUMDB="sum.golang.org"

GOTMPDIR=""

GOTOOLDIR="/opt/homebrew/Cellar/go/1.16.6/libexec/pkg/tool/darwin_arm64"

GOVCS=""

GOVERSION="go1.16.6"

GCCGO="gccgo"

AR="ar"

CC="clang"

CXX="clang++"

CGO_ENABLED="1"

GOMOD="/Users/vvrantchan/code/x/b196191547/go.mod"

CGO_CFLAGS="-g -O2"

CGO_CPPFLAGS=""

CGO_CXXFLAGS="-g -O2"

CGO_FFLAGS="-g -O2"

CGO_LDFLAGS="-g -O2"

PKG_CONFIG="pkg-config"

GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/kq/g8xycx_95j54cxffqtx0s_xm00lql0/T/go-build1627430943=/tmp/go-build -gno-record-gcc-switches -fno-common"

你做了什么?

https://play.golang.org/p/-rDc14aTqgV
com.apple.systemdefault证书是苹果在macOS设置过程中生成的自签名根证书。它存在于大多数(所有?)macOS用户密钥链中。我最近发现,go.17rc2无法解析一些(但不是全部)的Apple系统密钥链证书。示例中的证书是在2015年颁发的。有可能苹果错误地颁发了这些证书,并在后续版本中修复了不匹配的问题。
我只在大约10万台macOS设备中检测到了这个问题,但我们的环境对设备有快速刷新周期。对于使用Go解析macOS系统密钥链的其他用户来说,这个问题可能更广泛。

你期望看到什么?

com.apple.systemdefault
2015-03-25 21:10:26 +0000 UTC

你看到了什么?

2021/08/13 10:01:51 x509: inner and outer signature algorithm identifiers don't match
exit status 1
j7dteeu8

j7dteeu81#

cc @FiloSottile@rolandshoemaker
related #44237 (?)

k3bvogb1

k3bvogb12#

SEQUENCE (1 elem)
    OBJECT IDENTIFIER 1.2.840.113549.1.1.5 sha1WithRSAEncryption (PKCS #1)

vs

SEQUENCE (2 elem)
    OBJECT IDENTIFIER 1.2.840.113549.1.1.5 sha1WithRSAEncryption (PKCS #1)
    NULL

叹气。我们可能不得不容忍一个空参数不匹配吗?@rolandshoemaker
顺便说一下,证书可以修补以正确解析,因为外部签名算法没有签名。

szqfcxe2

szqfcxe23#

我们已经尽量减少了特殊例外情况,对于损坏的证书,我不太愿意增加更多。这种情况相对罕见,除非我们开始看到大量的损坏(无法合理解决)的情况,我认为我们应该接受不能解析一些格式错误的证书。

r55awzrz

r55awzrz4#

根据规范(https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.1.2),"parameter"字段是可选的,所以你应该将这两种表示形式(带或不带可选的"NULL"字段)视为等效。
我刚遇到这个问题,因为Kubernetes的certmanager无法接受我的根CA证书(所有浏览器都能正确接受该证书),原因是缺少了"NULL"(该证书是使用OpenSSL创建的,所以这可能并不罕见...)。

insrf1ej

insrf1ej5#

我刚刚遇到了这个错误。它与我无法控制的第三方证书有关,因此无法更改。
Firefox在加载证书方面没有问题(除了通常的自签名警告)。它“正常工作”。然而,我在go中完全无法建立TLS连接,因为它拒绝解析证书。从可用性的Angular 来看,这似乎不太理想。我甚至没有一种方法可以覆盖(例如使用InsecureSkipVerify或VerifyPeerCertificate)。到目前为止,我认为我根本无法从golang连接到这个特定的主机。
编辑,22天后:由于我无法在核心模块上使用replace指令(参见#35283 - TLDR;功能被拒绝),我不得不:

  • 分叉go代码库
  • crypto/tlscrypto/x509拆分出来
  • 还分叉了我正在使用的利用crypto/tls的库
  • 编辑分叉的库以引用我的crypto/tls分支
  • 编辑我的crypto/tls分支以引用我的crypto/x509分支
  • 注解掉/src/crypto/x509/parser.go中的第867-869行

现在我的TLS连接可以正常工作了!
为了接受一个非理想的证书,我不得不花费大量的时间,而Web浏览器却毫不费力地做到了这一点。我支持标准合规性——但是如果有一个tls.config标志允许在这方面变得宽松,那将节省我数小时的时间(现在,对我的项目来说,构建过程变得更加困难)。

kwvwclae

kwvwclae6#

TL;DR

不同的ASN1值可以表示相同的算法,而golang错误地比较ASN1字节以检查这种相似性。

为什么

我认为这个问题源于RFC 5280中的歧义:

AlgorithmIdentifier  ::=  SEQUENCE  {
        algorithm               OBJECT IDENTIFIER,
        parameters              ANY DEFINED BY algorithm OPTIONAL  }

第4.1.1.2节:
此字段必须包含与tbsCertificate序列中的signature字段相同的算法标识符。
第4.1.2.3节:
此字段必须包含与Certificate序列中的signatureAlgorithm字段相同的算法标识符。
根据所识别的算法,可选参数字段的内容将有所不同。
如您所见,它并不清楚是否指的是整个序列,包括参数,还是仅指OBJECT IDENTIFIER指定的算法本身。
无论存在这种歧义,RFC并未定义“相同”,我可以假设相似性检查取决于算法类型。
例如,在RFC 3279中定义:sha1WithRSAEncryption的第2.2.1节中,您可以读到:
当这些三个OID中的任何一个出现在ASN.1类型AlgorithmIdentifier中时,该类型的参数部分应为ASN.1类型NULL。
上述内容意味着

18:d=2  hl=2 l=  11 cons: SEQUENCE          
   20:d=3  hl=2 l=   9 prim: OBJECT            :sha1WithRSAEncryption

471:d=1  hl=2 l=  13 cons: SEQUENCE          
  473:d=2  hl=2 l=   9 prim: OBJECT            :sha1WithRSAEncryption
  484:d=2  hl=2 l=   0 prim: NULL

满足第4.1.1.2节和第4.1.2.3节的要求。
这也适用于根据RFC 4055的第2.1节定义的sha1sha224sha256sha384sha512:
所有实现都必须接受NULL和缺失参数作为合法且等效的编码。
总之,似乎不同的ASN1值可以表示相同的算法,而golang错误地比较ASN1字节以检查这种相似性。
感谢您的所有帮助和努力。

相关问题