diff --git a/gmtls/alert.go b/gmtls/alert.go index 5ca584f1..9a475518 100644 --- a/gmtls/alert.go +++ b/gmtls/alert.go @@ -51,12 +51,12 @@ const ( alertNoRenegotiation alert = 100 alertNoApplicationProtocol alert = 120 //GMT0024 - alertUnspporttedSite2Site alert = 200 - alertNoArea alert = 201 - alertUnspportedAreaType alert = 202 - alertBadIBCParam alert = 203 - alertUnspportedIBCParam alert = 204 - alertIdentityNeed alert = 205 + alertUnspporttedSite2Site alert = 200 + alertNoArea alert = 201 + alertUnspportedAreaType alert = 202 + alertBadIBCParam alert = 203 + alertUnspportedIBCParam alert = 204 + alertIdentityNeed alert = 205 ) var alertText = map[alert]string{ @@ -85,12 +85,44 @@ var alertText = map[alert]string{ alertNoRenegotiation: "no renegotiation", alertNoApplicationProtocol: "no application protocol", //GMT0024 - alertUnspporttedSite2Site: "不支持site2site", - alertNoArea : "没有保护域", - alertUnspportedAreaType : "不支持的保护域类型", - alertBadIBCParam : "接收到一个无效的ibc公共参数", - alertUnspportedIBCParam : "不支持ibc参数中定义的信息", - alertIdentityNeed : "缺少对方的ibc标识", + alertUnspporttedSite2Site: "不支持site2site", + alertNoArea: "没有保护域", + alertUnspportedAreaType: "不支持的保护域类型", + alertBadIBCParam: "接收到一个无效的ibc公共参数", + alertUnspportedIBCParam: "不支持ibc参数中定义的信息", + alertIdentityNeed: "缺少对方的ibc标识", +} + +// 错误中文描述 +var alertText_CN = map[alert]string{ + alertCloseNotify: "关闭通知", + alertUnexpectedMessage: "接收到一个不符合上下文关系的消息", + alertBadRecordMAC: "MAC校验错误或解密错误", + alertDecryptionFailed: "解密失败", + alertRecordOverflow: "报文过长", + alertDecompressionFailure: "解压缩失败", + alertHandshakeFailure: "协商失败", + alertBadCertificate: "证书破坏", + alertUnsupportedCertificate: "不支持证书类型", + alertCertificateRevoked: "证书被撤销", + alertCertificateExpired: "证书过期或未生效", + alertCertificateUnknown: "未知证书错误", + alertIllegalParameter: "非法参数", + alertUnknownCA: "根证书不可信", + alertAccessDenied: "拒绝访问", + alertDecodeError: "消息解码失败", + alertDecryptError: "消息解密失败", + alertProtocolVersion: "版本不匹配", + alertInsufficientSecurity: "安全性不足", + alertInternalError: "内部错误", + alertUserCanceled: "用户取消操作", + alertNoRenegotiation: "拒绝重新协商", + alertUnspporttedSite2Site: "不支持 site2site", + alertNoArea: "没有保护域", + alertUnspportedAreaType: "不支持的保护域类型", + alertBadIBCParam: "接收到一个无效的ibc公共参数", + alertUnspportedIBCParam: "不支持ibc公共参数中定义的信息", + alertIdentityNeed: "缺少对方的ibc标识", } func (e alert) String() string { @@ -104,3 +136,12 @@ func (e alert) String() string { func (e alert) Error() string { return e.String() } + +// AlertDespCN 报警消息中文意义 +func AlertDespCN(e uint8) string { + s, ok := alertText_CN[alert(e)] + if ok { + return s + } + return "报警(" + strconv.Itoa(int(e)) + ")" +} diff --git a/gmtls/auto_handshake_server.go b/gmtls/auto_handshake_server.go index eac3ab12..3a3dd8fc 100644 --- a/gmtls/auto_handshake_server.go +++ b/gmtls/auto_handshake_server.go @@ -121,7 +121,7 @@ func processClientHelloGM(c *Conn, hs *serverHandshakeStateGM) (isResume bool, e } // Edit: 根据 GMT 0024 6.4.4.1.1 Client Hello 消息 b) random 描述 // 客户端产生的随机信息,其内容包括时钟和随机数。 - gmtRandom(&(hs.hello.random)) + gmtRandom(hs.hello.random) if len(hs.clientHello.secureRenegotiation) != 0 { _ = c.sendAlert(alertHandshakeFailure) @@ -158,7 +158,7 @@ func processClientHelloGM(c *Conn, hs *serverHandshakeStateGM) (isResume bool, e _ = c.sendAlert(alertInternalError) return false, err } - encCert, err := c.config.GetKECertificate(hs.clientHelloInfo()) + encCert, err := c.config.getEKCertificate(hs.clientHelloInfo()) if err != nil { _ = c.sendAlert(alertInternalError) return false, err @@ -522,12 +522,11 @@ func runServerHandshake(c *Conn, hs *serverHandshakeState, isResume bool) error } // 国密类型的随机数 4 byte unix time 28 byte random -func gmtRandom(raw *[]byte) uint32 { - rd := *raw +func gmtRandom(raw []byte) uint32 { unixTime := time.Now().Unix() - rd[0] = uint8(unixTime >> 24) - rd[1] = uint8(unixTime >> 16) - rd[2] = uint8(unixTime >> 8) - rd[3] = uint8(unixTime) + raw[0] = uint8(unixTime >> 24) + raw[1] = uint8(unixTime >> 16) + raw[2] = uint8(unixTime >> 8) + raw[3] = uint8(unixTime) return uint32(unixTime) } diff --git a/gmtls/common.go b/gmtls/common.go index f02c243a..fdc5333b 100644 --- a/gmtls/common.go +++ b/gmtls/common.go @@ -476,6 +476,9 @@ type Config struct { // This should be used only for testing. InsecureSkipVerify bool + // 跳过证书与域名的验证 + SkipServerNameVerify bool + // CipherSuites is a list of supported cipher suites. If CipherSuites // is nil, TLS uses a list of suites supported by the implementation. CipherSuites []uint16 @@ -613,6 +616,7 @@ func (c *Config) Clone() *Config { Renegotiation: c.Renegotiation, KeyLogWriter: c.KeyLogWriter, sessionTicketKeys: sessionTicketKeys, + SkipServerNameVerify: c.SkipServerNameVerify, } } diff --git a/gmtls/conn.go b/gmtls/conn.go index ac3f99a5..4731b92d 100644 --- a/gmtls/conn.go +++ b/gmtls/conn.go @@ -1080,7 +1080,7 @@ func (c *Conn) Write(b []byte) (int, error) { // https://www.imperialviolet.org/2012/01/15/beastfollowup.html var m int - if len(b) > 1 && c.vers <= VersionTLS10 { + if len(b) > 1 && c.vers <= VersionTLS10 && c.vers != VersionGMSSL { if _, ok := c.out.cipher.(cipher.BlockMode); ok { n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1]) if err != nil { diff --git a/gmtls/gm_handshake_client_double.go b/gmtls/gm_handshake_client_double.go index 34dd887a..6f9c939a 100644 --- a/gmtls/gm_handshake_client_double.go +++ b/gmtls/gm_handshake_client_double.go @@ -232,6 +232,10 @@ func (hs *clientHandshakeStateGM) doFullHandshake() error { DNSName: c.config.ServerName, Intermediates: x509.NewCertPool(), } + if c.config.SkipServerNameVerify { + opts.DNSName = "" + } + if opts.Roots == nil { opts.Roots = x509.NewCertPool() } diff --git a/gmtls/gm_handshake_server_double.go b/gmtls/gm_handshake_server_double.go index 52341537..0f00dad2 100644 --- a/gmtls/gm_handshake_server_double.go +++ b/gmtls/gm_handshake_server_double.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build !single_cert // +build !single_cert package gmtls @@ -135,11 +136,12 @@ func (hs *serverHandshakeStateGM) readClientHello() (isResume bool, err error) { } } - c.vers, ok = c.config.mutualVersion(hs.clientHello.vers) - if !ok { + c.vers = hs.clientHello.vers + if hs.clientHello.vers != VersionGMSSL { c.sendAlert(alertProtocolVersion) - return false, fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers) + return false, fmt.Errorf("tlcp: only support tclp version 0x0101,but get protocol version of %x", hs.clientHello.vers) } + c.haveVers = true hs.hello = new(serverHelloMsg) @@ -165,6 +167,8 @@ func (hs *serverHandshakeStateGM) readClientHello() (isResume bool, err error) { c.sendAlert(alertInternalError) return false, err } + // 客户端产生的随机信息,其内容包括时钟和随机数。 + gmtRandom(hs.hello.random) if len(hs.clientHello.secureRenegotiation) != 0 { c.sendAlert(alertHandshakeFailure) @@ -193,9 +197,24 @@ func (hs *serverHandshakeStateGM) readClientHello() (isResume bool, err error) { } } - // just for test - c.config.getCertificate(hs.clientHelloInfo()) - hs.cert = c.config.Certificates + if len(c.config.Certificates) < 2 { + var sigCert, encCert *Certificate + // 当证书数量不足时,通过配置提供的证书获取方法获取密钥对 + sigCert, err = c.config.getCertificate(hs.clientHelloInfo()) + if err != nil { + _ = c.sendAlert(alertInternalError) + return false, err + } + encCert, err = c.config.getEKCertificate(hs.clientHelloInfo()) + if err != nil { + _ = c.sendAlert(alertInternalError) + return false, err + } + // 第1张证书为 签名证书、第2张为加密证书(用于密钥交换) + hs.cert = []Certificate{*sigCert, *encCert} + } else { + hs.cert = c.config.Certificates + } // GMT0024 if len(hs.cert) < 2 { diff --git a/gmtls/handshake_client.go b/gmtls/handshake_client.go index 414878a2..d4a3de11 100644 --- a/gmtls/handshake_client.go +++ b/gmtls/handshake_client.go @@ -363,6 +363,9 @@ func (hs *clientHandshakeState) doFullHandshake() error { DNSName: c.config.ServerName, Intermediates: x509.NewCertPool(), } + if c.config.SkipServerNameVerify { + opts.DNSName = "" + } for i, cert := range certs { if i == 0 {