Conversation
kernel/network/p2p/util.go
Outdated
| ) | ||
|
|
||
| // serverName 为key,缓存 creds | ||
| var serverNameMap = make(map[string]credentials.TransportCredentials) |
kernel/network/p2p/util.go
Outdated
| } | ||
|
|
||
| //如果缓存中有值 | ||
| if creds, ok := serverNameMap[serviceName]; ok { |
There was a problem hiding this comment.
serverNameMap 对应性能等没有实质性的作用,反而增加了代码的复杂度。
TransportCredentials 的使用包括两种场景
- 服务端: Accept 完成 TCP 三次握手之后,调用 Server 对象上的 opts.creds 完成SSL 握手中的服务端部分,不会重复加载TransportCredentials
- 客户端: 底层采用 HTTP2 长链接,同一个服务端只有一个连接,不需要重复加载TransportCredentials,serverNameMap 缓存 基本处于缓存不命中的情况,对性能等没有实质性的帮助
kernel/network/p2p/util.go
Outdated
|
|
||
| func NewTLS(path, serviceName string) (credentials.TransportCredentials, error) { | ||
|
|
||
| if len(serviceName) < 1 { |
There was a problem hiding this comment.
去掉 ServerName 为空的判断,标准库TLS 是允许ServerName 为空的
ServerName 为空时,标准库中 SSL 握手的证书为
- 客户端: 根据连接时根据 dial 的 addr 判断自动推断 ServerName
- 服务端: 不需要 ServerName 字段
gmtls 的逻辑应该也类似,可以进一步确认
kernel/network/p2p/util.go
Outdated
| if !ok { | ||
| return nil, err | ||
| } | ||
| certificate, err := tls.LoadX509KeyPair(filepath.Join(path, "cert.pem"), filepath.Join(path, "private.key")) |
There was a problem hiding this comment.
gmtls 中的 x509 证书兼容标准的 RSA x509 解析,同一个证书只需要加载和解析一次,可以参考官方示例
https://github.com/tjfoc/gmsm/blob/fdaa5ff368db5ce62bb672fc424b23f8923858dc/gmtls/websvr/websvr.go#L52
kernel/network/p2p/util.go
Outdated
| ClientAuth: tls.RequireAndVerifyClientCert, | ||
| }) | ||
| return creds, nil | ||
| if strings.Contains(strings.ToLower(x509cert.SignatureAlgorithm.String()), "sm") { //国密 |
There was a problem hiding this comment.
修改判断是否使用国密的逻辑,区分客户端和服务端
客户端通过配置项选择是否使用国密,或者通过本地证书判断支持的密码学套件
服务端支持支持加载多个证书,根据 SSL 握手时协商的结果选择对应的密码学套件
理由如下
其中,ClientHello 结构中包含了客户端支持的加密套件,服务端根据自身的支持的加密套件和客户端支持的加密套件返回对应的加密套件协商结果。
客户端是否使用国密可以通过以下方案判断
- 通过配置项来判断是否使用国密
- 通过判断证书类型确定是否使用国密。
值得注意的是,在商用密码系列算法中,SM2为公钥加密, SM3 为哈希算法,SM4 为分组加密。gmtls 支持SM2,SM3,SM4 其中只有SM2 可能出现在证书的 PublicKeyAlgorithm 字段,而不必要使字符串比较。
服务端通过如下方案
服务端在收到 Client 服务端在 ClientHello 信息之后,会通过 ClientHelloHello 信息之后,会通过 ClientHello 中的 SupportedVersions 字段决定是否使用国密。
kernel/network/p2p/util.go
Outdated
| certPool := x509.NewCertPool() | ||
| ok := certPool.AppendCertsFromPEM(bs) | ||
| if !ok { | ||
| cacert, err := ioutil.ReadFile(filepath.Join(path, "cacert.pem")) |
There was a problem hiding this comment.
bs 和 cacert 是同样的内容,不需要重复读取
Codecov Report
@@ Coverage Diff @@
## master #290 +/- ##
==========================================
- Coverage 45.81% 45.65% -0.16%
==========================================
Files 138 138
Lines 12284 12307 +23
==========================================
- Hits 5628 5619 -9
- Misses 5504 5534 +30
- Partials 1152 1154 +2
Continue to review full report at Codecov.
|
kernel/network/p2p/util.go
Outdated
| return nil, err | ||
| } | ||
|
|
||
| certificate, err := defaulttls.LoadX509KeyPair(filepath.Join(path, "cert.pem"), filepath.Join(path, "private.key")) |


Description
What is the purpose of the change?
基于 github.com/tjfoc/gmsm 实现TLS传输加密,使用双证书模式,实际是一个证书对象,slice里放了两次,简化操作
Fixes # (issue)
Type of change
Please delete options that are not relevant.
Brief of your solution
基于 github.com/tjfoc/gmsm 实现TLS传输加密,使用双证书模式,实际是一个证书对象,slice里放了两次,简化操作