Browse Source

separate client ca and server ca
This is designed to prevent a server from being attacked with a client with a certificate issued by a trusted system CA.
Some commercial CA actually can issue certificate to individual to proof their identity. The server should not accept these certs as a valid client certificates.

Shelikhoo 4 years ago
parent
commit
a53fd35205

+ 4 - 2
infra/conf/transport_internet.go

@@ -301,6 +301,8 @@ func (c *TLSCertConfig) Build() (*tls.Certificate, error) {
 		certificate.Usage = tls.Certificate_ENCIPHERMENT
 		certificate.Usage = tls.Certificate_ENCIPHERMENT
 	case "verify":
 	case "verify":
 		certificate.Usage = tls.Certificate_AUTHORITY_VERIFY
 		certificate.Usage = tls.Certificate_AUTHORITY_VERIFY
+	case "verifyclient":
+		certificate.Usage = tls.Certificate_AUTHORITY_VERIFY_CLIENT
 	case "issue":
 	case "issue":
 		certificate.Usage = tls.Certificate_AUTHORITY_ISSUE
 		certificate.Usage = tls.Certificate_AUTHORITY_ISSUE
 	default:
 	default:
@@ -318,7 +320,7 @@ type TLSConfig struct {
 	EnableSessionResumption          bool                  `json:"enableSessionResumption"`
 	EnableSessionResumption          bool                  `json:"enableSessionResumption"`
 	DisableSystemRoot                bool                  `json:"disableSystemRoot"`
 	DisableSystemRoot                bool                  `json:"disableSystemRoot"`
 	PinnedPeerCertificateChainSha256 *[]string             `json:"pinnedPeerCertificateChainSha256"`
 	PinnedPeerCertificateChainSha256 *[]string             `json:"pinnedPeerCertificateChainSha256"`
-	ClientVerify                     bool                  `json:"clientVerify"`
+	VerifyClientCertificate          bool                  `json:"verifyClientCertificate"`
 }
 }
 
 
 // Build implements Buildable.
 // Build implements Buildable.
@@ -334,7 +336,7 @@ func (c *TLSConfig) Build() (proto.Message, error) {
 	}
 	}
 	serverName := c.ServerName
 	serverName := c.ServerName
 	config.AllowInsecure = c.Insecure
 	config.AllowInsecure = c.Insecure
-	config.ClientVerify = c.ClientVerify
+	config.VerifyClientCertificate = c.VerifyClientCertificate
 	if len(c.ServerName) > 0 {
 	if len(c.ServerName) > 0 {
 		config.ServerName = serverName
 		config.ServerName = serverName
 	}
 	}

+ 32 - 2
transport/internet/tls/config.go

@@ -36,6 +36,31 @@ func ParseCertificate(c *cert.Certificate) *Certificate {
 func (c *Config) loadSelfCertPool() (*x509.CertPool, error) {
 func (c *Config) loadSelfCertPool() (*x509.CertPool, error) {
 	root := x509.NewCertPool()
 	root := x509.NewCertPool()
 	for _, cert := range c.Certificate {
 	for _, cert := range c.Certificate {
+		/* Do not treat client certificate authority as a peer certificate authority.
+		   This is designed to prevent a client certificate with a permissive key usage from being used to attacker server.
+		   In next release, the certificate usage will be enforced strictly.
+		   Only a certificate with AUTHORITY_VERIFY usage will be accepted.
+		*/
+		if cert.Usage == Certificate_AUTHORITY_VERIFY_CLIENT {
+			continue
+		}
+		if !root.AppendCertsFromPEM(cert.Certificate) {
+			return nil, newError("failed to append cert").AtWarning()
+		}
+	}
+	return root, nil
+}
+func (c *Config) loadSelfCertPoolClientCA() (*x509.CertPool, error) {
+	root := x509.NewCertPool()
+	for _, cert := range c.Certificate {
+		/* Do not treat client certificate authority as a peer certificate authority.
+		   This is designed to prevent a client certificate with a permissive key usage from being used to attacker server.
+		   In next release, the certificate usage will be enforced strictly.
+		   Only a certificate with AUTHORITY_VERIFY usage will be accepted.
+		*/
+		if cert.Usage != Certificate_AUTHORITY_VERIFY_CLIENT {
+			continue
+		}
 		if !root.AppendCertsFromPEM(cert.Certificate) {
 		if !root.AppendCertsFromPEM(cert.Certificate) {
 			return nil, newError("failed to append cert").AtWarning()
 			return nil, newError("failed to append cert").AtWarning()
 		}
 		}
@@ -202,6 +227,11 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
 		newError("failed to load system root certificate").AtError().Base(err).WriteToLog()
 		newError("failed to load system root certificate").AtError().Base(err).WriteToLog()
 	}
 	}
 
 
+	clientRoot, err := c.loadSelfCertPoolClientCA()
+	if err != nil {
+		newError("failed to load client root certificate").AtError().Base(err).WriteToLog()
+	}
+
 	if c == nil {
 	if c == nil {
 		return &tls.Config{
 		return &tls.Config{
 			ClientSessionCache:     globalSessionCache,
 			ClientSessionCache:     globalSessionCache,
@@ -218,13 +248,13 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
 		NextProtos:             c.NextProtocol,
 		NextProtos:             c.NextProtocol,
 		SessionTicketsDisabled: !c.EnableSessionResumption,
 		SessionTicketsDisabled: !c.EnableSessionResumption,
 		VerifyPeerCertificate:  c.verifyPeerCert,
 		VerifyPeerCertificate:  c.verifyPeerCert,
-		ClientCAs:              root,
+		ClientCAs:              clientRoot,
 	}
 	}
 
 
 	for _, opt := range opts {
 	for _, opt := range opts {
 		opt(config)
 		opt(config)
 	}
 	}
-	if c.ClientVerify {
+	if c.VerifyClientCertificate {
 		config.ClientAuth = tls.RequireAndVerifyClientCert
 		config.ClientAuth = tls.RequireAndVerifyClientCert
 	}
 	}
 	config.Certificates = c.BuildCertificates()
 	config.Certificates = c.BuildCertificates()

+ 55 - 49
transport/internet/tls/config.pb.go

@@ -23,9 +23,10 @@ const (
 type Certificate_Usage int32
 type Certificate_Usage int32
 
 
 const (
 const (
-	Certificate_ENCIPHERMENT     Certificate_Usage = 0
-	Certificate_AUTHORITY_VERIFY Certificate_Usage = 1
-	Certificate_AUTHORITY_ISSUE  Certificate_Usage = 2
+	Certificate_ENCIPHERMENT            Certificate_Usage = 0
+	Certificate_AUTHORITY_VERIFY        Certificate_Usage = 1
+	Certificate_AUTHORITY_ISSUE         Certificate_Usage = 2
+	Certificate_AUTHORITY_VERIFY_CLIENT Certificate_Usage = 3
 )
 )
 
 
 // Enum value maps for Certificate_Usage.
 // Enum value maps for Certificate_Usage.
@@ -34,11 +35,13 @@ var (
 		0: "ENCIPHERMENT",
 		0: "ENCIPHERMENT",
 		1: "AUTHORITY_VERIFY",
 		1: "AUTHORITY_VERIFY",
 		2: "AUTHORITY_ISSUE",
 		2: "AUTHORITY_ISSUE",
+		3: "AUTHORITY_VERIFY_CLIENT",
 	}
 	}
 	Certificate_Usage_value = map[string]int32{
 	Certificate_Usage_value = map[string]int32{
-		"ENCIPHERMENT":     0,
-		"AUTHORITY_VERIFY": 1,
-		"AUTHORITY_ISSUE":  2,
+		"ENCIPHERMENT":            0,
+		"AUTHORITY_VERIFY":        1,
+		"AUTHORITY_ISSUE":         2,
+		"AUTHORITY_VERIFY_CLIENT": 3,
 	}
 	}
 )
 )
 
 
@@ -157,8 +160,8 @@ type Config struct {
 	//@Document This value replace allow_insecure.
 	//@Document This value replace allow_insecure.
 	//@Critical
 	//@Critical
 	PinnedPeerCertificateChainSha256 [][]byte `protobuf:"bytes,7,rep,name=pinned_peer_certificate_chain_sha256,json=pinnedPeerCertificateChainSha256,proto3" json:"pinned_peer_certificate_chain_sha256,omitempty"`
 	PinnedPeerCertificateChainSha256 [][]byte `protobuf:"bytes,7,rep,name=pinned_peer_certificate_chain_sha256,json=pinnedPeerCertificateChainSha256,proto3" json:"pinned_peer_certificate_chain_sha256,omitempty"`
-	// Whether or not server verify client cert
-	ClientVerify bool `protobuf:"varint,8,opt,name=client_verify,json=clientVerify,proto3" json:"client_verify,omitempty"`
+	// If true, the client is required to present a certificate.
+	VerifyClientCertificate bool `protobuf:"varint,8,opt,name=verify_client_certificate,json=verifyClientCertificate,proto3" json:"verify_client_certificate,omitempty"`
 }
 }
 
 
 func (x *Config) Reset() {
 func (x *Config) Reset() {
@@ -242,9 +245,9 @@ func (x *Config) GetPinnedPeerCertificateChainSha256() [][]byte {
 	return nil
 	return nil
 }
 }
 
 
-func (x *Config) GetClientVerify() bool {
+func (x *Config) GetVerifyClientCertificate() bool {
 	if x != nil {
 	if x != nil {
-		return x.ClientVerify
+		return x.VerifyClientCertificate
 	}
 	}
 	return false
 	return false
 }
 }
@@ -256,7 +259,7 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{
 	0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
 	0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
 	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x21, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72,
 	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x21, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72,
 	0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65,
 	0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65,
-	0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x22, 0xd3, 0x01, 0x0a, 0x0b, 0x43, 0x65, 0x72,
+	0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x22, 0xf0, 0x01, 0x0a, 0x0b, 0x43, 0x65, 0x72,
 	0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x65, 0x72, 0x74,
 	0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x65, 0x72, 0x74,
 	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x43,
 	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x43,
 	0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65,
 	0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65,
@@ -265,47 +268,50 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{
 	0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f,
 	0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f,
 	0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x2e,
 	0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x2e,
 	0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x73, 0x61, 0x67,
 	0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x73, 0x61, 0x67,
-	0x65, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x22, 0x44, 0x0a, 0x05, 0x55, 0x73, 0x61, 0x67,
+	0x65, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x22, 0x61, 0x0a, 0x05, 0x55, 0x73, 0x61, 0x67,
 	0x65, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x4e, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e,
 	0x65, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x4e, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e,
 	0x54, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59,
 	0x54, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59,
 	0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54,
 	0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54,
-	0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xa8,
-	0x03, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c,
-	0x6f, 0x77, 0x5f, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65,
-	0x12, 0x50, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18,
-	0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f,
-	0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74,
-	0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
-	0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
-	0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e,
-	0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x65, 0x78, 0x74,
-	0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x3a, 0x0a, 0x19, 0x65, 0x6e, 0x61, 0x62,
-	0x6c, 0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d,
-	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x65, 0x6e, 0x61,
-	0x62, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f,
-	0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28,
-	0x08, 0x52, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d,
-	0x52, 0x6f, 0x6f, 0x74, 0x12, 0x4e, 0x0a, 0x24, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70,
-	0x65, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f,
-	0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x07, 0x20, 0x03,
-	0x28, 0x0c, 0x52, 0x20, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65,
-	0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x68,
-	0x61, 0x32, 0x35, 0x36, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x76,
-	0x65, 0x72, 0x69, 0x66, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x6c, 0x69,
-	0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x42, 0x84, 0x01, 0x0a, 0x25, 0x63, 0x6f,
-	0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61,
-	0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e,
-	0x74, 0x6c, 0x73, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
-	0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f,
-	0x72, 0x65, 0x2f, 0x76, 0x34, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f,
-	0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x21, 0x56,
-	0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70,
-	0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x6c, 0x73,
-	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x12, 0x1b,
+	0x0a, 0x17, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x49,
+	0x46, 0x59, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x22, 0xbf, 0x03, 0x0a, 0x06,
+	0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f,
+	0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d,
+	0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x50, 0x0a,
+	0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
+	0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
+	0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+	0x74, 0x65, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12,
+	0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65,
+	0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
+	0x6c, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x72, 0x6f,
+	0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x3a, 0x0a, 0x19, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f,
+	0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69,
+	0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65,
+	0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f,
+	0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x79, 0x73,
+	0x74, 0x65, 0x6d, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11,
+	0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x6f, 0x6f,
+	0x74, 0x12, 0x4e, 0x0a, 0x24, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72,
+	0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61,
+	0x69, 0x6e, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0c, 0x52,
+	0x20, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69,
+	0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x68, 0x61, 0x32, 0x35,
+	0x36, 0x12, 0x3a, 0x0a, 0x19, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x63, 0x6c, 0x69, 0x65,
+	0x6e, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x08,
+	0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6c, 0x69, 0x65,
+	0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x42, 0x84, 0x01,
+	0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65,
+	0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72,
+	0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75,
+	0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76, 0x32, 0x72, 0x61,
+	0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x34, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70,
+	0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73,
+	0xaa, 0x02, 0x21, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72,
+	0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
+	0x2e, 0x54, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 }
 
 
 var (
 var (

+ 3 - 2
transport/internet/tls/config.proto

@@ -17,6 +17,7 @@ message Certificate {
     ENCIPHERMENT = 0;
     ENCIPHERMENT = 0;
     AUTHORITY_VERIFY = 1;
     AUTHORITY_VERIFY = 1;
     AUTHORITY_ISSUE = 2;
     AUTHORITY_ISSUE = 2;
+    AUTHORITY_VERIFY_CLIENT = 3;
   }
   }
 
 
   Usage usage = 3;
   Usage usage = 3;
@@ -49,6 +50,6 @@ message Config {
   */
   */
   repeated bytes pinned_peer_certificate_chain_sha256 = 7;
   repeated bytes pinned_peer_certificate_chain_sha256 = 7;
 
 
-  // Whether or not server verify client cert
-  bool client_verify = 8;
+  // If true, the client is required to present a certificate.
+  bool verify_client_certificate = 8;
 }
 }

+ 9 - 0
transport/internet/tls/config_other.go

@@ -45,6 +45,15 @@ func (c *Config) getCertPool() (*x509.CertPool, error) {
 		return nil, newError("system root").AtWarning().Base(err)
 		return nil, newError("system root").AtWarning().Base(err)
 	}
 	}
 	for _, cert := range c.Certificate {
 	for _, cert := range c.Certificate {
+		/* Do not treat client certificate authority as a peer certificate authority.
+		   This is designed to prevent a client certificate with a permissive key usage from being used to attacker server.
+		   In next release, the certificate usage will be enforced strictly.
+		   Only a certificate with AUTHORITY_VERIFY usage will be accepted.
+		*/
+		if cert.Usage == Certificate_AUTHORITY_VERIFY_CLIENT {
+			continue
+		}
+
 		if !pool.AppendCertsFromPEM(cert.Certificate) {
 		if !pool.AppendCertsFromPEM(cert.Certificate) {
 			return nil, newError("append cert to root").AtWarning().Base(err)
 			return nil, newError("append cert to root").AtWarning().Base(err)
 		}
 		}