websvr

package
v1.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2021 License: Apache-2.0 Imports: 5 Imported by: 0

README

TLS/GMSSL 服务端协议自适应

目录结构说明:

├─certs        // 证书以及密钥
├─websvr_test   //HTTP服务端/客户端测试Demo
└─websvr          //协议自适应实现

服务端 GMTLS/TLS 工作逻辑

autoswitchlogic

通过配置gmtls.Config 对象提供自动切换相关的配置,创建gmtls.Conn

在对gmtls.ConnRead/Wirte时将会触发握手行为HandShake

HandShake会根据用户配置参数,判断需要使用 GMSSL、TLS、GMSSL/TLS 三种工作模式中的哪一种, 然后进入到相应的工作模式中运行。

  • TLS工作模式:
    • 运行serverHandshake 进入TLS握手。
    • 创建TLS握手上下文serverHandshakeState
    • 读取并处理 来自于客户端的ClientHello 消息。
    • 进入 TLS握手流程。
  • GMSSL工作模式:
    • 运行serverHandshakeGM 进入GMSSL握手。
    • 创建TLS握手上下文serverHandshakeStateGM
    • 读取并处理 来自于客户端的ClientHello 消息。
    • 进入 GMSSL握手流程。
  • GMSSL/TLS工作模式:
    • 运行serverHandshakeAutoSwitch 进入自动切换的握手模式。
    • 读取来自于客户端的ClientHello 消息。
    • 分析处理ClientHello,根据客户端协议版本。
    • 根据协议版本,选择使用具体握手方式:
      • GMSSL: 创建上下文serverHandshakeStateGM,进入GMSSL握手流程。
      • TLS: 创建上下文serverHandshakeState,进入TLS握手流程。

在GMSSL/TLS模式的服务端运行过程中,如何根据客户端版本选择需要使用的证书以及密钥?

自动切换模式,同时需要为服务端提供2份证书与密钥对(一份用于标准的TLS、一份用于GMSSL), 在运行过程需要使用到gmtls.Config#GetCertificate方法来根据客户端的版本选择出合适的 证书密钥对,即在客户端版本是GMSSL的时候返回SM2签名证书密钥对;在客户端版本是标准的TLS时 返还RSA/ECC的证书密钥对,以次来动态适应不同客户端的连接需求。 针对于GMSSL特殊的双证书需求,特别为gmtls.Config增加了一个方法gmtls.Config#GetKECertificate 通过该方法来提供GMSSL密钥交换过程中使用密钥对。

更多细节实现见: auto_handshake_server

GMSSL/TLS 自动切换模式

快速开始:

  1. 准备 RSA、SM2签名、SM2加密,证书以及密钥对。
  2. 调用gmtls.NewBasicAutoSwitchConfig构造基础的配置对象。
  3. Use it.
func main() {
	config, err := gmtls.NewBasicAutoSwitchConfig(&sigCert, &encCert, &rsaKeypair)
	if err != nil {
		panic(err)
	}

	ln, err := gmtls.Listen("tcp", ":443", config)
	if err != nil {
		panic(err)
	}
	defer ln.Close()

	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
		fmt.Fprintf(writer, "hello\n")
	})
	err = http.Serve(ln, nil)
	if err != nil {
		panic(err)
	}
}	

详细服务端的配置流程如下:

  1. 准备:
    • SM2签名密钥对、证书:sigCert
    • SM2加密密钥对、证书:encCert
    • RSA/ECC加密密钥对、证书:rsaKeypair
  2. 创建一个实现gmtls.Config#GetCertificate方法签名的方法,方法需要根据支持的签名类型:
    • 含有GMSSL版本:返回SM2签名证书密钥对(sigCert)。
    • 不含有GMSSL版本:返回RSA签名证书密钥对(rsaKeypair)。
  3. 创建一个实现gmtls.Config#GetKECertificate方法签名的方法,固定返回SM2加密证书密钥对(encCert)。
  4. 创建GMSupport并启用,自动切换模式。
  5. 创建gmtls.Config对象,接下就可以启动服务端实现自动切换功能。
// Step 1:
fncGetSignCertKeypair := func(info *gmtls.ClientHelloInfo) (*gmtls.Certificate, error) {
    gmFlag := false
    // 检查支持协议中是否包含GMSSL
    for _, v := range info.SupportedVersions {
        if v == gmtls.VersionGMSSL {
        gmFlag = true
        break
        }
    }
    if gmFlag {
        return &sigCert, nil
    } else {
        return &rsaKeypair, nil
    }
}

fncGetEncCertKeypair := func(info *gmtls.ClientHelloInfo) (*gmtls.Certificate, error) {
    return &encCert, nil
}
support := gmtls.NewGMSupport()
support.EnableMixMode()
config := &gmtls.Config{
    GMSupport:        support,
    GetCertificate:   fncGetSignCertKeypair,
    GetKECertificate: fncGetEncCertKeypair,
}

更多细节请参考: HTTP over GMTLS/TLS Server Demo

双向身份认证

服务端开启双向身份认证,需要配置而外参数ClientAuth

建议使用gmtls.RequireAndVerifyClientCert表明服务端需要客户端证书请求且需要验证客户端证书。

config, err := gmtls.NewBasicAutoSwitchConfig(&sigCert, &encCert, &rsaKeypair)
if err != nil {
	panic(err)
}

// 开启客户端的身份认证
config.ClientAuth = gmtls.RequireAndVerifyClientCert

更多细节请参考:

客户端的启用双向身份认证也需要配置,只需要提供认证所使用的证书密钥对就可以。

例如:

config ,err = &gmtls.Config{
		GMSupport:          &gmtls.GMSupport{},
		RootCAs:            certPool,
		Certificates:       []gmtls.Certificate{authKeypair},
		InsecureSkipVerify: false,
}

更多细节请参考:

Documentation

Index

Constants

View Source
const (
	RSACaCertPath   = "./certs/RSA_CA.cer"
	RSAAuthCertPath = "./certs/rsa_auth_cert.cer"
	RSAAuthKeyPath  = "./certs/rsa_auth_key.pem"
	SM2CaCertPath   = "./certs/SM2_CA.cer"
	SM2AuthCertPath = "./certs/sm2_auth_cert.cer"
	SM2AuthKeyPath  = "./certs/sm2_auth_key.pem"
)

Variables

This section is empty.

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL