Skip to content

Commit 4fb23db

Browse files
authored
Merge pull request #14 from easyops-cn/gmsm
Using sm2 sm3 smx509 from github.com/emmansun/gmsm
2 parents fb574a2 + 3c56ced commit 4fb23db

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+216
-8768
lines changed

gmtls/auth.go

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
"errors"
2424
"fmt"
2525

26-
"github.com/tjfoc/gmsm/sm2"
26+
"github.com/emmansun/gmsm/sm2"
2727
)
2828

2929
// pickSignatureAlgorithm selects a signature algorithm that is compatible with
@@ -40,17 +40,19 @@ func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []S
4040
// For TLS 1.2, if the client didn't send signature_algorithms
4141
// extension then we can assume that it supports SHA1. See
4242
// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
43-
switch pubkey.(type) {
43+
switch pubKey := pubkey.(type) {
4444
case *rsa.PublicKey:
4545
if tlsVersion < VersionTLS12 {
4646
return 0, signaturePKCS1v15, crypto.MD5SHA1, nil
4747
} else {
4848
return PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1, nil
4949
}
5050
case *ecdsa.PublicKey:
51-
return ECDSAWithSHA1, signatureECDSA, crypto.SHA1, nil
52-
case *sm2.PublicKey:
53-
return SM2WITHSM3, signatureSM2, crypto.SHA1, nil
51+
if pubKey.Curve == sm2.P256() {
52+
return SM2WITHSM3, signatureSM2, crypto.SHA1, nil
53+
} else {
54+
return ECDSAWithSHA1, signatureECDSA, crypto.SHA1, nil
55+
}
5456
default:
5557
return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey)
5658
}
@@ -73,10 +75,6 @@ func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []S
7375
if sigType == signatureECDSA {
7476
return sigAlg, sigType, hashAlg, nil
7577
}
76-
case *sm2.PublicKey:
77-
if sigType == signatureECDSA {
78-
return sigAlg, sigType, hashAlg, nil
79-
}
8078
default:
8179
return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey)
8280
}
@@ -100,18 +98,21 @@ func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc c
10098
if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
10199
return errors.New("tls: ECDSA signature contained zero or negative values")
102100
}
103-
if pubKey.Curve == sm2.P256Sm2() {
104-
sm2Public := sm2.PublicKey{
105-
Curve: pubKey.Curve,
106-
X: pubKey.X,
107-
Y: pubKey.Y,
108-
}
109-
if !sm2Public.Verify(digest, sig) {
101+
if pubKey.Curve == sm2.P256() {
102+
if !sm2.VerifyWithSM2(pubKey, nil, digest, ecdsaSig.R, ecdsaSig.S) {
110103
return errors.New("tls: SM2 verification failure")
111104
}
112105
} else if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
113106
return errors.New("tls: ECDSA verification failure")
114107
}
108+
case signatureSM2:
109+
pubKey, ok := pubkey.(*ecdsa.PublicKey)
110+
if !ok {
111+
return errors.New("tls: SM2 signing requires a SM2 public key")
112+
}
113+
if ok := sm2.VerifyASN1WithSM2(pubKey, nil, digest, sig); !ok {
114+
return errors.New("verify sm2 signature error")
115+
}
115116
case signaturePKCS1v15:
116117
pubKey, ok := pubkey.(*rsa.PublicKey)
117118
if !ok {
@@ -129,14 +130,6 @@ func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc c
129130
if err := rsa.VerifyPSS(pubKey, hashFunc, digest, sig, signOpts); err != nil {
130131
return err
131132
}
132-
case signatureSM2:
133-
pubKey, ok := pubkey.(*sm2.PublicKey)
134-
if !ok {
135-
return errors.New("tls: SM2 signing requires a SM2 public key")
136-
}
137-
if ok := pubKey.Verify(digest, sig); !ok {
138-
return errors.New("verify sm2 signature error")
139-
}
140133
default:
141134
return errors.New("tls: unknown signature algorithm")
142135
}

gmtls/cipher_suites.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ import (
2525
"crypto/sha256"
2626
"hash"
2727

28-
"github.com/tjfoc/gmsm/x509"
29-
3028
"golang.org/x/crypto/chacha20poly1305"
29+
30+
"github.com/emmansun/gmsm/smx509"
3131
)
3232

3333
// a keyAgreement implements the client and server side of a TLS key agreement
@@ -45,8 +45,8 @@ type keyAgreement interface {
4545

4646
// This method may not be called if the server doesn't send a
4747
// ServerKeyExchange message.
48-
processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
49-
generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
48+
processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *smx509.Certificate, *serverKeyExchangeMsg) error
49+
generateClientKeyExchange(*Config, *clientHelloMsg, *smx509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
5050
}
5151

5252
const (

gmtls/common.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
"sync"
2929
"time"
3030

31-
"github.com/tjfoc/gmsm/x509"
31+
"github.com/emmansun/gmsm/smx509"
3232
)
3333

3434
const (
@@ -163,17 +163,17 @@ var supportedSignatureAlgorithms = []SignatureScheme{
163163

164164
// ConnectionState records basic TLS details about the connection.
165165
type ConnectionState struct {
166-
Version uint16 // TLS version used by the connection (e.g. VersionTLS12)
167-
HandshakeComplete bool // TLS handshake is complete
168-
DidResume bool // connection resumes a previous TLS connection
169-
CipherSuite uint16 // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...)
170-
NegotiatedProtocol string // negotiated next protocol (not guaranteed to be from Config.NextProtos)
171-
NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server (client side only)
172-
ServerName string // server name requested by client, if any (server side only)
173-
PeerCertificates []*x509.Certificate // certificate chain presented by remote peer
174-
VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates
175-
SignedCertificateTimestamps [][]byte // SCTs from the server, if any
176-
OCSPResponse []byte // stapled OCSP response from server, if any
166+
Version uint16 // TLS version used by the connection (e.g. VersionTLS12)
167+
HandshakeComplete bool // TLS handshake is complete
168+
DidResume bool // connection resumes a previous TLS connection
169+
CipherSuite uint16 // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...)
170+
NegotiatedProtocol string // negotiated next protocol (not guaranteed to be from Config.NextProtos)
171+
NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server (client side only)
172+
ServerName string // server name requested by client, if any (server side only)
173+
PeerCertificates []*smx509.Certificate // certificate chain presented by remote peer
174+
VerifiedChains [][]*smx509.Certificate // verified chains built from PeerCertificates
175+
SignedCertificateTimestamps [][]byte // SCTs from the server, if any
176+
OCSPResponse []byte // stapled OCSP response from server, if any
177177

178178
// ekm is a closure exposed via ExportKeyingMaterial.
179179
ekm func(label string, context []byte, length int) ([]byte, error)
@@ -210,12 +210,12 @@ const (
210210
// ClientSessionState contains the state needed by clients to resume TLS
211211
// sessions.
212212
type ClientSessionState struct {
213-
sessionTicket []uint8 // Encrypted ticket used for session resumption with server
214-
vers uint16 // SSL/TLS version negotiated for the session
215-
cipherSuite uint16 // Ciphersuite negotiated for the session
216-
masterSecret []byte // MasterSecret generated by client on a full handshake
217-
serverCertificates []*x509.Certificate // Certificate chain presented by the server
218-
verifiedChains [][]*x509.Certificate // Certificate chains we built for verification
213+
sessionTicket []uint8 // Encrypted ticket used for session resumption with server
214+
vers uint16 // SSL/TLS version negotiated for the session
215+
cipherSuite uint16 // Ciphersuite negotiated for the session
216+
masterSecret []byte // MasterSecret generated by client on a full handshake
217+
serverCertificates []*smx509.Certificate // Certificate chain presented by the server
218+
verifiedChains [][]*smx509.Certificate // Certificate chains we built for verification
219219
}
220220

221221
// ClientSessionCache is a cache of ClientSessionState objects that can be used
@@ -443,12 +443,12 @@ type Config struct {
443443
// setting InsecureSkipVerify, or (for a server) when ClientAuth is
444444
// RequestClientCert or RequireAnyClientCert, then this callback will
445445
// be considered but the verifiedChains argument will always be nil.
446-
VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
446+
VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*smx509.Certificate) error
447447

448448
// RootCAs defines the set of root certificate authorities
449449
// that clients use when verifying server certificates.
450450
// If RootCAs is nil, TLS uses the host's root CA set.
451-
RootCAs *x509.CertPool
451+
RootCAs *smx509.CertPool
452452

453453
// NextProtos is a list of supported, application level protocols.
454454
NextProtos []string
@@ -466,7 +466,7 @@ type Config struct {
466466
// ClientCAs defines the set of root certificate authorities
467467
// that servers use if required to verify a client certificate
468468
// by the policy in ClientAuth.
469-
ClientCAs *x509.CertPool
469+
ClientCAs *smx509.CertPool
470470

471471
// InsecureSkipVerify controls whether a client verifies the
472472
// server's certificate chain and host name.
@@ -809,7 +809,7 @@ func (c *Config) BuildNameToCertificate() {
809809
c.NameToCertificate = make(map[string]*Certificate)
810810
for i := range c.Certificates {
811811
cert := &c.Certificates[i]
812-
x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
812+
x509Cert, err := smx509.ParseCertificate(cert.Certificate[0])
813813
if err != nil {
814814
continue
815815
}
@@ -861,7 +861,7 @@ type Certificate struct {
861861
// initialized using x509.ParseCertificate to reduce per-handshake
862862
// processing for TLS clients doing client authentication. If nil, the
863863
// leaf certificate will be parsed as needed.
864-
Leaf *x509.Certificate
864+
Leaf *smx509.Certificate
865865
}
866866

867867
type handshakeMessage interface {

gmtls/conn.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
"sync/atomic"
2727
"time"
2828

29-
"github.com/tjfoc/gmsm/x509"
29+
"github.com/emmansun/gmsm/smx509"
3030
)
3131

3232
// A Conn represents a secured connection.
@@ -54,10 +54,10 @@ type Conn struct {
5454
cipherSuite uint16
5555
ocspResponse []byte // stapled OCSP response
5656
scts [][]byte // signed certificate timestamps from server
57-
peerCertificates []*x509.Certificate
57+
peerCertificates []*smx509.Certificate
5858
// verifiedChains contains the certificate chains that we built, as
5959
// opposed to the ones presented by the server.
60-
verifiedChains [][]*x509.Certificate
60+
verifiedChains [][]*smx509.Certificate
6161
// serverName contains the server name indicated by the client, if any.
6262
serverName string
6363
// secureRenegotiation is true if the server echoed the secure

gmtls/gm_handshake_client.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import (
1919
"strconv"
2020
"sync/atomic"
2121

22-
"github.com/tjfoc/gmsm/sm2"
23-
"github.com/tjfoc/gmsm/x509"
22+
"github.com/emmansun/gmsm/sm2"
23+
"github.com/emmansun/gmsm/smx509"
2424
)
2525

2626
type clientHandshakeStateGM struct {
@@ -195,9 +195,9 @@ func (hs *clientHandshakeStateGM) doFullHandshake() error {
195195
if c.handshakes == 0 {
196196
// If this is the first handshake on a connection, process and
197197
// (optionally) verify the server's certificates.
198-
certs := make([]*x509.Certificate, len(certMsg.certificates))
198+
certs := make([]*smx509.Certificate, len(certMsg.certificates))
199199
for i, asn1Data := range certMsg.certificates {
200-
cert, err := x509.ParseCertificate(asn1Data)
200+
cert, err := smx509.ParseCertificate(asn1Data)
201201
if err != nil {
202202
c.sendAlert(alertBadCertificate)
203203
return errors.New("tls: failed to parse certificate from server: " + err.Error())
@@ -231,14 +231,14 @@ func (hs *clientHandshakeStateGM) doFullHandshake() error {
231231
}
232232

233233
if !c.config.InsecureSkipVerify {
234-
opts := x509.VerifyOptions{
234+
opts := smx509.VerifyOptions{
235235
Roots: c.config.RootCAs,
236236
CurrentTime: c.config.time(),
237237
DNSName: c.config.ServerName,
238-
Intermediates: x509.NewCertPool(),
238+
Intermediates: smx509.NewCertPool(),
239239
}
240240
if opts.Roots == nil {
241-
opts.Roots = x509.NewCertPool()
241+
opts.Roots = smx509.NewCertPool()
242242
}
243243

244244
for _, rootca := range getCAs() {
@@ -636,14 +636,14 @@ findCert:
636636
// node, or if chain.Leaf was nil
637637
if j != 0 || x509Cert == nil {
638638
var err error
639-
if x509Cert, err = x509.ParseCertificate(cert); err != nil {
639+
if x509Cert, err = smx509.ParseCertificate(cert); err != nil {
640640
c.sendAlert(alertInternalError)
641641
return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
642642
}
643643
}
644644

645645
switch {
646-
case x509Cert.PublicKeyAlgorithm == x509.SM2:
646+
case x509Cert.PublicKeyAlgorithm == smx509.SM2:
647647
default:
648648
continue findCert
649649
}

gmtls/gm_handshake_client_double.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import (
1616
"strconv"
1717
"sync/atomic"
1818

19-
"github.com/tjfoc/gmsm/sm2"
20-
"github.com/tjfoc/gmsm/x509"
19+
"github.com/emmansun/gmsm/sm2"
20+
"github.com/emmansun/gmsm/smx509"
2121
)
2222

2323
type clientHandshakeStateGM struct {
@@ -193,16 +193,16 @@ func (hs *clientHandshakeStateGM) doFullHandshake() error {
193193
if c.handshakes == 0 {
194194
// If this is the first handshake on a connection, process and
195195
// (optionally) verify the server's certificates.
196-
certs := make([]*x509.Certificate, len(certMsg.certificates))
196+
certs := make([]*smx509.Certificate, len(certMsg.certificates))
197197
for i, asn1Data := range certMsg.certificates {
198-
cert, err := x509.ParseCertificate(asn1Data)
198+
cert, err := smx509.ParseCertificate(asn1Data)
199199
if err != nil {
200200
c.sendAlert(alertBadCertificate)
201201
return errors.New("tls: failed to parse certificate from server: " + err.Error())
202202
}
203203

204204
pubKey, _ := cert.PublicKey.(*ecdsa.PublicKey)
205-
if pubKey.Curve != sm2.P256Sm2() {
205+
if pubKey.Curve != sm2.P256() {
206206
c.sendAlert(alertUnsupportedCertificate)
207207
return fmt.Errorf("tls: pubkey type of cert is error, expect sm2.publicKey")
208208
}
@@ -211,12 +211,12 @@ func (hs *clientHandshakeStateGM) doFullHandshake() error {
211211
//check key usage
212212
switch i {
213213
case 0:
214-
if cert.KeyUsage == 0 || (cert.KeyUsage&(x509.KeyUsageDigitalSignature|cert.KeyUsage&x509.KeyUsageContentCommitment)) == 0 {
214+
if cert.KeyUsage == 0 || (cert.KeyUsage&(smx509.KeyUsageDigitalSignature|cert.KeyUsage&smx509.KeyUsageContentCommitment)) == 0 {
215215
c.sendAlert(alertInsufficientSecurity)
216216
return fmt.Errorf("tls: the keyusage of cert[0] does not exist or is not for KeyUsageDigitalSignature/KeyUsageContentCommitment, value:%d", cert.KeyUsage)
217217
}
218218
case 1:
219-
if cert.KeyUsage == 0 || (cert.KeyUsage&(x509.KeyUsageDataEncipherment|x509.KeyUsageKeyEncipherment|x509.KeyUsageKeyAgreement)) == 0 {
219+
if cert.KeyUsage == 0 || (cert.KeyUsage&(smx509.KeyUsageDataEncipherment|smx509.KeyUsageKeyEncipherment|smx509.KeyUsageKeyAgreement)) == 0 {
220220
c.sendAlert(alertInsufficientSecurity)
221221
return fmt.Errorf("tls: the keyusage of cert[1] does not exist or is not for KeyUsageDataEncipherment/KeyUsageKeyEncipherment/KeyUsageKeyAgreement, value:%d", cert.KeyUsage)
222222
}
@@ -226,14 +226,14 @@ func (hs *clientHandshakeStateGM) doFullHandshake() error {
226226
}
227227

228228
if !c.config.InsecureSkipVerify {
229-
opts := x509.VerifyOptions{
229+
opts := smx509.VerifyOptions{
230230
Roots: c.config.RootCAs,
231231
CurrentTime: c.config.time(),
232232
DNSName: c.config.ServerName,
233-
Intermediates: x509.NewCertPool(),
233+
Intermediates: smx509.NewCertPool(),
234234
}
235235
if opts.Roots == nil {
236-
opts.Roots = x509.NewCertPool()
236+
opts.Roots = smx509.NewCertPool()
237237
}
238238

239239
for _, rootca := range getCAs() {
@@ -263,7 +263,7 @@ func (hs *clientHandshakeStateGM) doFullHandshake() error {
263263
}
264264

265265
switch certs[0].PublicKey.(type) {
266-
case *sm2.PublicKey, *ecdsa.PublicKey, *rsa.PublicKey:
266+
case *ecdsa.PublicKey, *rsa.PublicKey:
267267
break
268268
default:
269269
c.sendAlert(alertUnsupportedCertificate)
@@ -369,7 +369,9 @@ func (hs *clientHandshakeStateGM) doFullHandshake() error {
369369

370370
digest := hs.finishedHash.client.Sum(nil)
371371

372-
certVerify.signature, err = key.Sign(c.config.rand(), digest, nil)
372+
// TODO: SignerOpts
373+
signOpts := sm2.NewSM2SignerOption(true, nil)
374+
certVerify.signature, err = key.Sign(c.config.rand(), digest, signOpts)
373375
if err != nil {
374376
c.sendAlert(alertInternalError)
375377
return err
@@ -629,17 +631,17 @@ findCert:
629631
// node, or if chain.Leaf was nil
630632
if j != 0 || x509Cert == nil {
631633
var err error
632-
if x509Cert, err = x509.ParseCertificate(cert); err != nil {
634+
if x509Cert, err = smx509.ParseCertificate(cert); err != nil {
633635
c.sendAlert(alertInternalError)
634636
return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
635637
}
636638
}
637639

638640
var isGMCert bool
639641

640-
if x509Cert.PublicKeyAlgorithm == x509.ECDSA {
642+
if x509Cert.PublicKeyAlgorithm == smx509.ECDSA {
641643
pubKey, ok := x509Cert.PublicKey.(*ecdsa.PublicKey)
642-
if ok && pubKey.Curve == sm2.P256Sm2() {
644+
if ok && pubKey.Curve == sm2.P256() {
643645
isGMCert = true
644646
}
645647
}

0 commit comments

Comments
 (0)