From 318a36fe581ac7cab329a3a23624f99e43333d60 Mon Sep 17 00:00:00 2001 From: Darien Raymond <admin@v2ray.com> Date: Tue, 10 Apr 2018 12:42:02 +0200 Subject: [PATCH] automatic issuing certificates from provided CA --- common/protocol/tls/cert/cert.go | 71 +++++++++--- testing/scenarios/tls_test.go | 143 +++++++++++++++++++++++- transport/internet/http/http_test.go | 4 +- transport/internet/tls/config.go | 97 ++++++++++++++++ transport/internet/tls/config.pb.go | 78 +++++++++---- transport/internet/tls/config.proto | 10 +- transport/internet/websocket/ws_test.go | 8 +- 7 files changed, 366 insertions(+), 45 deletions(-) diff --git a/common/protocol/tls/cert/cert.go b/common/protocol/tls/cert/cert.go index bd568da3..818a093b 100644 --- a/common/protocol/tls/cert/cert.go +++ b/common/protocol/tls/cert/cert.go @@ -7,17 +7,39 @@ import ( "encoding/pem" "math/big" "time" + + "v2ray.com/core/common" ) //go:generate go run $GOPATH/src/v2ray.com/core/common/errors/errorgen/main.go -pkg cert -path Protocol,TLS,Cert type Certificate struct { - // Cerificate in x509 format + // Cerificate in ASN.1 DER format Certificate []byte - // Private key in x509 format + // Private key in ASN.1 DER format PrivateKey []byte } +func ParseCertificate(certPEM []byte, keyPEM []byte) (*Certificate, error) { + certBlock, _ := pem.Decode(certPEM) + if certBlock == nil { + return nil, newError("failed to decode certificate") + } + keyBlock, _ := pem.Decode(keyPEM) + if keyBlock == nil { + return nil, newError("failed to decode key") + } + return &Certificate{ + Certificate: certBlock.Bytes, + PrivateKey: keyBlock.Bytes, + }, nil +} + +func (c *Certificate) ToPEM() ([]byte, []byte) { + return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: c.Certificate}), + pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: c.PrivateKey}) +} + type Option func(*x509.Certificate) func Authority(isCA bool) Option { @@ -50,10 +72,31 @@ func CommonName(name string) Option { } } -func Generate(parent *x509.Certificate, opts ...Option) (*Certificate, error) { - priv, err := rsa.GenerateKey(rand.Reader, 2048) +func KeyUsage(usage x509.KeyUsage) Option { + return func(c *x509.Certificate) { + c.KeyUsage = usage + } +} + +func MustGenerate(parent *Certificate, opts ...Option) *Certificate { + cert, err := Generate(parent, opts...) + common.Must(err) + return cert +} + +func Generate(parent *Certificate, opts ...Option) (*Certificate, error) { + selfKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { - return nil, newError("failed to generate RSA private key").Base(err) + return nil, newError("failed to generate self private key").Base(err) + } + + parentKey := selfKey + if parent != nil { + pKey, err := x509.ParsePKCS1PrivateKey(parent.PrivateKey) + if err != nil { + return nil, newError("failed to parse parent private key").Base(err) + } + parentKey = pKey } serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) @@ -75,20 +118,22 @@ func Generate(parent *x509.Certificate, opts ...Option) (*Certificate, error) { opt(template) } - if parent == nil { - parent = template + parentCert := template + if parent != nil { + pCert, err := x509.ParseCertificate(parent.Certificate) + if err != nil { + return nil, newError("failed to parse parent certificate").Base(err) + } + parentCert = pCert } - derBytes, err := x509.CreateCertificate(rand.Reader, template, parent, priv.Public(), priv) + derBytes, err := x509.CreateCertificate(rand.Reader, template, parentCert, selfKey.Public(), parentKey) if err != nil { return nil, newError("failed to create certificate").Base(err) } - certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) - keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) - return &Certificate{ - Certificate: certPEM, - PrivateKey: keyPEM, + Certificate: derBytes, + PrivateKey: x509.MarshalPKCS1PrivateKey(selfKey), }, nil } diff --git a/testing/scenarios/tls_test.go b/testing/scenarios/tls_test.go index e8eb69e3..3f90d5a7 100644 --- a/testing/scenarios/tls_test.go +++ b/testing/scenarios/tls_test.go @@ -2,6 +2,8 @@ package scenarios import ( "crypto/rand" + "crypto/x509" + "runtime" "sync" "testing" "time" @@ -10,6 +12,7 @@ import ( "v2ray.com/core/app/proxyman" "v2ray.com/core/common/net" "v2ray.com/core/common/protocol" + "v2ray.com/core/common/protocol/tls/cert" "v2ray.com/core/common/serial" "v2ray.com/core/common/uuid" "v2ray.com/core/proxy/dokodemo" @@ -19,7 +22,6 @@ import ( "v2ray.com/core/proxy/vmess/outbound" "v2ray.com/core/testing/servers/tcp" "v2ray.com/core/testing/servers/udp" - tlsgen "v2ray.com/core/testing/tls" "v2ray.com/core/transport/internet" "v2ray.com/core/transport/internet/http" "v2ray.com/core/transport/internet/tls" @@ -49,7 +51,7 @@ func TestSimpleTLSConnection(t *testing.T) { SecurityType: serial.GetMessageType(&tls.Config{}), SecuritySettings: []*serial.TypedMessage{ serial.ToTypedMessage(&tls.Config{ - Certificate: []*tls.Certificate{tlsgen.GenerateCertificateForTest()}, + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))}, }), }, }, @@ -141,6 +143,137 @@ func TestSimpleTLSConnection(t *testing.T) { CloseAllServers(servers) } +func TestAutoIssuingCertificate(t *testing.T) { + if runtime.GOOS == "windows" { + // Not supported on Windows yet. + return + } + + assert := With(t) + + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + assert(err, IsNil) + defer tcpServer.Close() + + caCert, err := cert.Generate(nil, cert.Authority(true), cert.KeyUsage(x509.KeyUsageDigitalSignature|x509.KeyUsageKeyEncipherment|x509.KeyUsageCertSign)) + assert(err, IsNil) + certPEM, keyPEM := caCert.ToPEM() + + userID := protocol.NewID(uuid.New()) + serverPort := tcp.PickPort() + serverConfig := &core.Config{ + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + StreamSettings: &internet.StreamConfig{ + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*serial.TypedMessage{ + serial.ToTypedMessage(&tls.Config{ + Certificate: []*tls.Certificate{{ + Certificate: certPEM, + Key: keyPEM, + Usage: tls.Certificate_AUTHORITY_ISSUE, + }}, + }), + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{ + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + }), + }, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := tcp.PickPort() + clientConfig := &core.Config{ + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(clientPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&dokodemo.Config{ + Address: net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &net.NetworkList{ + Network: []net.Network{net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&outbound.Config{ + Receiver: []*protocol.ServerEndpoint{ + { + Address: net.NewIPOrDomain(net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + }), + }, + }, + }, + }, + }), + SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{ + StreamSettings: &internet.StreamConfig{ + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*serial.TypedMessage{ + serial.ToTypedMessage(&tls.Config{ + ServerName: "v2ray.com", + Certificate: []*tls.Certificate{{ + Certificate: certPEM, + Usage: tls.Certificate_AUTHORITY_VERIFY, + }}, + }), + }, + }, + }), + }, + }, + } + + servers, err := InitializeServerConfigs(serverConfig, clientConfig) + assert(err, IsNil) + + conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ + IP: []byte{127, 0, 0, 1}, + Port: int(clientPort), + }) + assert(err, IsNil) + + payload := "dokodemo request." + nBytes, err := conn.Write([]byte(payload)) + assert(err, IsNil) + assert(nBytes, Equals, len(payload)) + + response := readFrom(conn, time.Second*2, len(payload)) + assert(response, Equals, xor([]byte(payload))) + assert(conn.Close(), IsNil) + + CloseAllServers(servers) +} + func TestTLSOverKCP(t *testing.T) { assert := With(t) @@ -164,7 +297,7 @@ func TestTLSOverKCP(t *testing.T) { SecurityType: serial.GetMessageType(&tls.Config{}), SecuritySettings: []*serial.TypedMessage{ serial.ToTypedMessage(&tls.Config{ - Certificate: []*tls.Certificate{tlsgen.GenerateCertificateForTest()}, + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))}, }), }, }, @@ -280,7 +413,7 @@ func TestTLSOverWebSocket(t *testing.T) { SecurityType: serial.GetMessageType(&tls.Config{}), SecuritySettings: []*serial.TypedMessage{ serial.ToTypedMessage(&tls.Config{ - Certificate: []*tls.Certificate{tlsgen.GenerateCertificateForTest()}, + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))}, }), }, }, @@ -412,7 +545,7 @@ func TestHTTP2(t *testing.T) { SecurityType: serial.GetMessageType(&tls.Config{}), SecuritySettings: []*serial.TypedMessage{ serial.ToTypedMessage(&tls.Config{ - Certificate: []*tls.Certificate{tlsgen.GenerateCertificateForTest()}, + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))}, }), }, }, diff --git a/transport/internet/http/http_test.go b/transport/internet/http/http_test.go index c0809fff..516bdc15 100644 --- a/transport/internet/http/http_test.go +++ b/transport/internet/http/http_test.go @@ -9,8 +9,8 @@ import ( "v2ray.com/core/common" "v2ray.com/core/common/buf" "v2ray.com/core/common/net" + "v2ray.com/core/common/protocol/tls/cert" "v2ray.com/core/testing/servers/tcp" - tlsgen "v2ray.com/core/testing/tls" "v2ray.com/core/transport/internet" . "v2ray.com/core/transport/internet/http" "v2ray.com/core/transport/internet/tls" @@ -24,7 +24,7 @@ func TestHTTPConnection(t *testing.T) { lctx := context.Background() lctx = internet.ContextWithSecuritySettings(lctx, &tls.Config{ - Certificate: []*tls.Certificate{tlsgen.GenerateCertificateForTest()}, + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil, cert.CommonName("www.v2ray.com")))}, }) lctx = internet.ContextWithTransportSettings(lctx, &Config{}) diff --git a/transport/internet/tls/config.go b/transport/internet/tls/config.go index eb4bc34f..9481b225 100644 --- a/transport/internet/tls/config.go +++ b/transport/internet/tls/config.go @@ -3,8 +3,11 @@ package tls import ( "context" "crypto/tls" + "crypto/x509" + "time" "v2ray.com/core/common/net" + "v2ray.com/core/common/protocol/tls/cert" "v2ray.com/core/transport/internet" ) @@ -12,9 +15,36 @@ var ( globalSessionCache = tls.NewLRUClientSessionCache(128) ) +func ParseCertificate(c *cert.Certificate) *Certificate { + certPEM, keyPEM := c.ToPEM() + return &Certificate{ + Certificate: certPEM, + Key: keyPEM, + } +} + +func (c *Config) GetCertPool() *x509.CertPool { + pool, err := x509.SystemCertPool() + if err != nil { + newError("failed to get system cert pool.").Base(err).WriteToLog() + return nil + } + if pool != nil { + for _, cert := range c.Certificate { + if cert.Usage == Certificate_AUTHORITY_VERIFY { + pool.AppendCertsFromPEM(cert.Certificate) + } + } + } + return pool +} + func (c *Config) BuildCertificates() []tls.Certificate { certs := make([]tls.Certificate, 0, len(c.Certificate)) for _, entry := range c.Certificate { + if entry.Usage != Certificate_ENCIPHERMENT { + continue + } keyPair, err := tls.X509KeyPair(entry.Certificate, entry.Key) if err != nil { newError("ignoring invalid X509 key pair").Base(err).AtWarning().WriteToLog() @@ -25,9 +55,29 @@ func (c *Config) BuildCertificates() []tls.Certificate { return certs } +func isCertificateExpired(c *tls.Certificate) bool { + // If leaf is not there, the certificate is probably not used yet. We trust user to provide a valid certificate. + return c.Leaf != nil && c.Leaf.NotAfter.After(time.Now().Add(-time.Minute)) +} + +func issueCertificate(rawCA *Certificate, domain string) (*tls.Certificate, error) { + parent, err := cert.ParseCertificate(rawCA.Certificate, rawCA.Key) + if err != nil { + return nil, newError("failed to parse raw certificate").Base(err) + } + newCert, err := cert.Generate(parent, cert.CommonName(domain), cert.DNSNames(domain)) + if err != nil { + return nil, newError("failed to generate new certificate for ", domain).Base(err) + } + newCertPEM, newKeyPEM := newCert.ToPEM() + cert, err := tls.X509KeyPair(newCertPEM, newKeyPEM) + return &cert, err +} + func (c *Config) GetTLSConfig(opts ...Option) *tls.Config { config := &tls.Config{ ClientSessionCache: globalSessionCache, + RootCAs: c.GetCertPool(), } if c == nil { return config @@ -40,6 +90,53 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config { config.InsecureSkipVerify = c.AllowInsecure config.Certificates = c.BuildCertificates() config.BuildNameToCertificate() + config.GetCertificate = func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) { + domain := hello.ServerName + certExpired := false + if certificate, found := config.NameToCertificate[domain]; found { + if !isCertificateExpired(certificate) { + return certificate, nil + } + certExpired = true + } + + if certExpired { + newCerts := make([]tls.Certificate, 0, len(config.Certificates)) + + for _, certificate := range config.Certificates { + if !isCertificateExpired(&certificate) { + newCerts = append(newCerts, certificate) + } + } + + config.Certificates = newCerts + } + + var issuedCertificate *tls.Certificate + + // Create a new certificate from existing CA if possible + for _, rawCert := range c.Certificate { + if rawCert.Usage == Certificate_AUTHORITY_ISSUE { + newCert, err := issueCertificate(rawCert, domain) + if err != nil { + newError("failed to issue new certificate for ", domain).Base(err).WriteToLog() + continue + } + + config.Certificates = append(config.Certificates, *newCert) + issuedCertificate = &config.Certificates[len(config.Certificates)-1] + break + } + } + + if issuedCertificate == nil { + return nil, newError("failed to create a new certificate for ", domain) + } + + config.BuildNameToCertificate() + + return issuedCertificate, nil + } if len(c.ServerName) > 0 { config.ServerName = c.ServerName } diff --git a/transport/internet/tls/config.pb.go b/transport/internet/tls/config.pb.go index dfcba4cc..7c8dc4e0 100644 --- a/transport/internet/tls/config.pb.go +++ b/transport/internet/tls/config.pb.go @@ -15,11 +15,36 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +type Certificate_Usage int32 + +const ( + Certificate_ENCIPHERMENT Certificate_Usage = 0 + Certificate_AUTHORITY_VERIFY Certificate_Usage = 1 + Certificate_AUTHORITY_ISSUE Certificate_Usage = 2 +) + +var Certificate_Usage_name = map[int32]string{ + 0: "ENCIPHERMENT", + 1: "AUTHORITY_VERIFY", + 2: "AUTHORITY_ISSUE", +} +var Certificate_Usage_value = map[string]int32{ + "ENCIPHERMENT": 0, + "AUTHORITY_VERIFY": 1, + "AUTHORITY_ISSUE": 2, +} + +func (x Certificate_Usage) String() string { + return proto.EnumName(Certificate_Usage_name, int32(x)) +} +func (Certificate_Usage) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } + type Certificate struct { // TLS certificate in x509 format. Certificate []byte `protobuf:"bytes,1,opt,name=Certificate,proto3" json:"Certificate,omitempty"` // TLS key in x509 format. - Key []byte `protobuf:"bytes,2,opt,name=Key,proto3" json:"Key,omitempty"` + Key []byte `protobuf:"bytes,2,opt,name=Key,proto3" json:"Key,omitempty"` + Usage Certificate_Usage `protobuf:"varint,3,opt,name=usage,enum=v2ray.core.transport.internet.tls.Certificate_Usage" json:"usage,omitempty"` } func (m *Certificate) Reset() { *m = Certificate{} } @@ -41,6 +66,13 @@ func (m *Certificate) GetKey() []byte { return nil } +func (m *Certificate) GetUsage() Certificate_Usage { + if m != nil { + return m.Usage + } + return Certificate_ENCIPHERMENT +} + type Config struct { // Whether or not to allow self-signed certificates. AllowInsecure bool `protobuf:"varint,1,opt,name=allow_insecure,json=allowInsecure" json:"allow_insecure,omitempty"` @@ -88,28 +120,34 @@ func (m *Config) GetNextProtocol() []string { func init() { proto.RegisterType((*Certificate)(nil), "v2ray.core.transport.internet.tls.Certificate") proto.RegisterType((*Config)(nil), "v2ray.core.transport.internet.tls.Config") + proto.RegisterEnum("v2ray.core.transport.internet.tls.Certificate_Usage", Certificate_Usage_name, Certificate_Usage_value) } func init() { proto.RegisterFile("v2ray.com/core/transport/internet/tls/config.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 278 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x90, 0x41, 0x6a, 0xeb, 0x30, - 0x10, 0x86, 0x71, 0xfc, 0x08, 0x2f, 0x72, 0x52, 0x8a, 0x56, 0xde, 0xd5, 0x49, 0x09, 0x78, 0x25, - 0x83, 0x7b, 0x82, 0xd6, 0xab, 0x50, 0x28, 0x46, 0x84, 0x2e, 0xba, 0x31, 0xaa, 0x98, 0x14, 0x83, - 0x2c, 0x85, 0xd1, 0x34, 0xad, 0xaf, 0xd4, 0x8b, 0xf4, 0x5a, 0xc5, 0x4e, 0x1c, 0x9c, 0x55, 0x76, - 0xd2, 0xa7, 0x4f, 0xf3, 0xff, 0x0c, 0xcb, 0x0f, 0x39, 0xaa, 0x56, 0x68, 0xd7, 0x64, 0xda, 0x21, - 0x64, 0x84, 0xca, 0xfa, 0xbd, 0x43, 0xca, 0x6a, 0x4b, 0x80, 0x16, 0x28, 0x23, 0xe3, 0x33, 0xed, - 0xec, 0xae, 0xfe, 0x10, 0x7b, 0x74, 0xe4, 0xf8, 0x72, 0xf8, 0x83, 0x20, 0xce, 0xbe, 0x18, 0x7c, - 0x41, 0xc6, 0xaf, 0x1e, 0x59, 0x54, 0x00, 0x52, 0xbd, 0xab, 0xb5, 0x22, 0xe0, 0xc9, 0xc5, 0x35, - 0x0e, 0x92, 0x20, 0x9d, 0xcb, 0x0b, 0xe3, 0x96, 0x85, 0xcf, 0xd0, 0xc6, 0x93, 0xfe, 0xa5, 0x3b, - 0xae, 0x7e, 0x03, 0x36, 0x2d, 0xfa, 0x58, 0xbe, 0x66, 0x37, 0xca, 0x18, 0xf7, 0x55, 0xd5, 0xd6, - 0x83, 0xfe, 0xc4, 0xe3, 0x84, 0xff, 0x72, 0xd1, 0xd3, 0xcd, 0x09, 0xf2, 0x92, 0x45, 0x7a, 0x94, - 0x32, 0x49, 0xc2, 0x34, 0xca, 0x85, 0xb8, 0xda, 0x56, 0x8c, 0x8a, 0xc8, 0xf1, 0x08, 0x7e, 0xc7, - 0x22, 0x0f, 0x78, 0x00, 0xac, 0xac, 0x6a, 0x20, 0x0e, 0x93, 0x20, 0x9d, 0x49, 0x76, 0x44, 0x2f, - 0xaa, 0x01, 0x7e, 0xcf, 0x16, 0x16, 0xbe, 0xa9, 0xea, 0x17, 0xa3, 0x9d, 0x89, 0xff, 0x25, 0x61, - 0x3a, 0x93, 0xf3, 0x0e, 0x96, 0x27, 0xf6, 0x24, 0xd9, 0x5a, 0xbb, 0xe6, 0x7a, 0x8f, 0x32, 0x78, - 0x0b, 0xc9, 0xf8, 0x9f, 0xc9, 0xf2, 0x35, 0x97, 0xaa, 0x15, 0x45, 0xa7, 0x6e, 0xcf, 0xea, 0x66, - 0x50, 0xb7, 0xc6, 0xbf, 0x4f, 0xfb, 0xc4, 0x87, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x84, - 0xfb, 0x07, 0xc0, 0x01, 0x00, 0x00, + // 358 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0xd1, 0x6e, 0xda, 0x30, + 0x14, 0x40, 0x97, 0x64, 0xa0, 0xe1, 0x00, 0x8b, 0xbc, 0x3d, 0xe4, 0x6d, 0x81, 0x09, 0x29, 0x4f, + 0x8e, 0x94, 0xed, 0x07, 0xb6, 0x34, 0x15, 0x69, 0x55, 0x1a, 0x99, 0x80, 0x44, 0x5f, 0x22, 0xd7, + 0x32, 0x28, 0x52, 0x12, 0x23, 0xdb, 0xd0, 0xf2, 0x4b, 0xfd, 0x91, 0x7e, 0x40, 0x7f, 0xa8, 0x4a, + 0x02, 0x14, 0x9e, 0x50, 0xdf, 0x7c, 0x8f, 0xcf, 0xbd, 0xd7, 0xf7, 0x1a, 0xf8, 0x5b, 0x5f, 0x90, + 0x1d, 0xa2, 0xbc, 0xf0, 0x28, 0x17, 0xcc, 0x53, 0x82, 0x94, 0x72, 0xcd, 0x85, 0xf2, 0xb2, 0x52, + 0x31, 0x51, 0x32, 0xe5, 0xa9, 0x5c, 0x7a, 0x94, 0x97, 0xcb, 0x6c, 0x85, 0xd6, 0x82, 0x2b, 0x0e, + 0x07, 0x87, 0x1c, 0xc1, 0xd0, 0xd1, 0x47, 0x07, 0x1f, 0xa9, 0x5c, 0x0e, 0xdf, 0x34, 0x60, 0x06, + 0x4c, 0xa8, 0x6c, 0x99, 0x51, 0xa2, 0x18, 0x74, 0xce, 0x42, 0x5b, 0x73, 0x34, 0xb7, 0x8b, 0xcf, + 0x0c, 0x0b, 0x18, 0xb7, 0x6c, 0x67, 0xeb, 0xf5, 0x4d, 0x75, 0x84, 0x37, 0xa0, 0xb5, 0x91, 0x64, + 0xc5, 0x6c, 0xc3, 0xd1, 0xdc, 0xbe, 0xff, 0x17, 0x5d, 0x6c, 0x8b, 0x4e, 0x0a, 0xa2, 0x59, 0x95, + 0x8b, 0x9b, 0x12, 0xc3, 0x2b, 0xd0, 0xaa, 0x63, 0x68, 0x81, 0x6e, 0x38, 0x09, 0xa2, 0x78, 0x1c, + 0xe2, 0xbb, 0x70, 0x92, 0x58, 0x5f, 0xe0, 0x4f, 0x60, 0xfd, 0x9b, 0x25, 0xe3, 0x7b, 0x1c, 0x25, + 0x8b, 0x74, 0x1e, 0xe2, 0xe8, 0x7a, 0x61, 0x69, 0xf0, 0x07, 0xf8, 0xfe, 0x41, 0xa3, 0xe9, 0x74, + 0x16, 0x5a, 0xfa, 0xf0, 0x55, 0x03, 0xed, 0xa0, 0xde, 0x04, 0x1c, 0x81, 0x3e, 0xc9, 0x73, 0xfe, + 0x94, 0x66, 0xa5, 0x64, 0x74, 0x23, 0x9a, 0x99, 0xbe, 0xe1, 0x5e, 0x4d, 0xa3, 0x3d, 0x84, 0x31, + 0x30, 0xe9, 0xc9, 0xdc, 0xba, 0x63, 0xb8, 0xa6, 0x8f, 0x3e, 0x37, 0x09, 0x3e, 0x2d, 0x01, 0x7f, + 0x01, 0x53, 0x32, 0xb1, 0x65, 0x22, 0x2d, 0x49, 0xd1, 0xec, 0xa6, 0x83, 0x41, 0x83, 0x26, 0xa4, + 0x60, 0xf0, 0x37, 0xe8, 0x95, 0xec, 0x59, 0xa5, 0xf5, 0x5f, 0x51, 0x9e, 0xdb, 0x5f, 0x1d, 0xc3, + 0xed, 0xe0, 0x6e, 0x05, 0xe3, 0x3d, 0xfb, 0x8f, 0xc1, 0x88, 0xf2, 0xe2, 0xf2, 0x3b, 0x62, 0xed, + 0xc1, 0x50, 0xb9, 0x7c, 0xd1, 0x07, 0x73, 0x1f, 0x93, 0x1d, 0x0a, 0x2a, 0x35, 0x39, 0xaa, 0xd1, + 0x41, 0x4d, 0x72, 0xf9, 0xd8, 0xae, 0x3b, 0xfe, 0x79, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x0b, 0xcd, + 0x2a, 0x68, 0x53, 0x02, 0x00, 0x00, } diff --git a/transport/internet/tls/config.proto b/transport/internet/tls/config.proto index fa923689..6919e77c 100644 --- a/transport/internet/tls/config.proto +++ b/transport/internet/tls/config.proto @@ -12,6 +12,14 @@ message Certificate { // TLS key in x509 format. bytes Key = 2; + + enum Usage { + ENCIPHERMENT = 0; + AUTHORITY_VERIFY = 1; + AUTHORITY_ISSUE = 2; + } + + Usage usage = 3; } message Config { @@ -26,4 +34,4 @@ message Config { // Lists of string as ALPN values. repeated string next_protocol = 4; -} \ No newline at end of file +} diff --git a/transport/internet/websocket/ws_test.go b/transport/internet/websocket/ws_test.go index 1cb985b6..a0939f6c 100644 --- a/transport/internet/websocket/ws_test.go +++ b/transport/internet/websocket/ws_test.go @@ -7,9 +7,9 @@ import ( "time" "v2ray.com/core/common/net" - tlsgen "v2ray.com/core/testing/tls" + "v2ray.com/core/common/protocol/tls/cert" "v2ray.com/core/transport/internet" - v2tls "v2ray.com/core/transport/internet/tls" + "v2ray.com/core/transport/internet/tls" . "v2ray.com/core/transport/internet/websocket" . "v2ray.com/ext/assert" ) @@ -109,9 +109,9 @@ func Test_listenWSAndDial_TLS(t *testing.T) { ctx := internet.ContextWithTransportSettings(context.Background(), &Config{ Path: "wss", }) - ctx = internet.ContextWithSecuritySettings(ctx, &v2tls.Config{ + ctx = internet.ContextWithSecuritySettings(ctx, &tls.Config{ AllowInsecure: true, - Certificate: []*v2tls.Certificate{tlsgen.GenerateCertificateForTest()}, + Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil, cert.CommonName("localhost")))}, }) listen, err := ListenWS(ctx, net.DomainAddress("localhost"), 13143, func(conn internet.Connection) { go func() {