diff --git a/testing/scenarios/tls_test.go b/testing/scenarios/tls_test.go index 2bc477681..67e9e62bb 100644 --- a/testing/scenarios/tls_test.go +++ b/testing/scenarios/tls_test.go @@ -2,12 +2,8 @@ package scenarios import ( "net" - "path/filepath" "testing" - "io/ioutil" - "os" - "time" "v2ray.com/core" @@ -22,18 +18,11 @@ import ( "v2ray.com/core/proxy/vmess/outbound" "v2ray.com/core/testing/assert" "v2ray.com/core/testing/servers/tcp" + tlsgen "v2ray.com/core/testing/tls" "v2ray.com/core/transport/internet" "v2ray.com/core/transport/internet/tls" ) -func mustReadFile(name string) []byte { - content, err := ioutil.ReadFile(name) - if err != nil { - panic(err) - } - return content -} - func TestSimpleTLSConnection(t *testing.T) { assert := assert.On(t) @@ -64,12 +53,7 @@ func TestSimpleTLSConnection(t *testing.T) { SecurityType: serial.GetMessageType(&tls.Config{}), SecuritySettings: []*serial.TypedMessage{ serial.ToTypedMessage(&tls.Config{ - Certificate: []*tls.Certificate{ - { - Certificate: mustReadFile(filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", "testing", "tls", "cert.pem")), - Key: mustReadFile(filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", "testing", "tls", "key.pem")), - }, - }, + Certificate: []*tls.Certificate{tlsgen.GenerateCertificateForTest()}, }), }, }, @@ -147,6 +131,116 @@ func TestSimpleTLSConnection(t *testing.T) { CloseAllServers() } +func TestTLSOverKCP(t *testing.T) { + assert := assert.On(t) + + tcpServer := tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + assert.Error(err).IsNil() + defer tcpServer.Close() + + userID := protocol.NewID(uuid.New()) + serverPort := pickPort() + serverConfig := &core.Config{ + Inbound: []*core.InboundConnectionConfig{ + { + PortRange: v2net.SinglePortRange(serverPort), + ListenOn: v2net.NewIPOrDomain(v2net.LocalHostIP), + Settings: serial.ToTypedMessage(&inbound.Config{ + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + }), + }, + }, + }), + StreamSettings: &internet.StreamConfig{ + Protocol: internet.TransportProtocol_MKCP, + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*serial.TypedMessage{ + serial.ToTypedMessage(&tls.Config{ + Certificate: []*tls.Certificate{tlsgen.GenerateCertificateForTest()}, + }), + }, + }, + }, + }, + Outbound: []*core.OutboundConnectionConfig{ + { + Settings: serial.ToTypedMessage(&freedom.Config{}), + }, + }, + } + + clientPort := pickPort() + clientConfig := &core.Config{ + Inbound: []*core.InboundConnectionConfig{ + { + PortRange: v2net.SinglePortRange(clientPort), + ListenOn: v2net.NewIPOrDomain(v2net.LocalHostIP), + Settings: serial.ToTypedMessage(&dokodemo.Config{ + Address: v2net.NewIPOrDomain(dest.Address), + Port: uint32(dest.Port), + NetworkList: &v2net.NetworkList{ + Network: []v2net.Network{v2net.Network_TCP}, + }, + }), + }, + }, + Outbound: []*core.OutboundConnectionConfig{ + { + Settings: serial.ToTypedMessage(&outbound.Config{ + Receiver: []*protocol.ServerEndpoint{ + { + Address: v2net.NewIPOrDomain(v2net.LocalHostIP), + Port: uint32(serverPort), + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + }), + }, + }, + }, + }, + }), + StreamSettings: &internet.StreamConfig{ + Protocol: internet.TransportProtocol_MKCP, + SecurityType: serial.GetMessageType(&tls.Config{}), + SecuritySettings: []*serial.TypedMessage{ + serial.ToTypedMessage(&tls.Config{ + AllowInsecure: true, + }), + }, + }, + }, + }, + } + + assert.Error(InitializeServerConfig(serverConfig)).IsNil() + assert.Error(InitializeServerConfig(clientConfig)).IsNil() + + conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ + IP: []byte{127, 0, 0, 1}, + Port: int(clientPort), + }) + assert.Error(err).IsNil() + + payload := "dokodemo request." + nBytes, err := conn.Write([]byte(payload)) + assert.Error(err).IsNil() + assert.Int(nBytes).Equals(len(payload)) + + response := readFrom(conn, time.Second*2, len(payload)) + assert.Bytes(response).Equals(xor([]byte(payload))) + assert.Error(conn.Close()).IsNil() + + CloseAllServers() +} + func TestTLSConnectionReuse(t *testing.T) { assert := assert.On(t) @@ -177,12 +271,7 @@ func TestTLSConnectionReuse(t *testing.T) { SecurityType: serial.GetMessageType(&tls.Config{}), SecuritySettings: []*serial.TypedMessage{ serial.ToTypedMessage(&tls.Config{ - Certificate: []*tls.Certificate{ - { - Certificate: mustReadFile(filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", "testing", "tls", "cert.pem")), - Key: mustReadFile(filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", "testing", "tls", "key.pem")), - }, - }, + Certificate: []*tls.Certificate{tlsgen.GenerateCertificateForTest()}, }), }, }, diff --git a/testing/tls/cert.pem b/testing/tls/cert.pem deleted file mode 100644 index 5468aa541..000000000 --- a/testing/tls/cert.pem +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICSTCCAfOgAwIBAgIJAKvQIEezrxBNMA0GCSqGSIb3DQEBCwUAMH8xCzAJBgNV -BAYTAlYyMRAwDgYDVQQIDAdURVNUSU5HMRAwDgYDVQQHDAdURVNUSU5HMRAwDgYD -VQQKDAdURVNUSU5HMRAwDgYDVQQLDAdURVNUSU5HMRAwDgYDVQQDDAdURVNUSU5H -MRYwFAYJKoZIhvcNAQkBFgdURVNUSU5HMCAXDTE2MDgxNTEyNTAwNFoYDzY0ODcw -NTA3MTI1MDA0WjB/MQswCQYDVQQGEwJWMjEQMA4GA1UECAwHVEVTVElORzEQMA4G -A1UEBwwHVEVTVElORzEQMA4GA1UECgwHVEVTVElORzEQMA4GA1UECwwHVEVTVElO -RzEQMA4GA1UEAwwHVEVTVElORzEWMBQGCSqGSIb3DQEJARYHVEVTVElORzBcMA0G -CSqGSIb3DQEBAQUAA0sAMEgCQQDFGeGTGepVDwgLm5rFx8khAhbod6g3Xg7vU3M9 -lzowBeAOS6bpN8lnBEXo3U2brxB+okbRhNuSj3VQ4raX0iL1AgMBAAGjUDBOMB0G -A1UdDgQWBBRE81DrJv6nBXAF3JP4a3LTtwkp8TAfBgNVHSMEGDAWgBRE81DrJv6n -BXAF3JP4a3LTtwkp8TAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA0EAkGX6 -sQvwHqNOdwise45dU8NvXwZsoqSQ2tdxrkB+SnKqEsMnRh/yPCSgzFkQVt53sYuf -HK8gD/wifGC5z39YlQ== ------END CERTIFICATE----- diff --git a/testing/tls/key.pem b/testing/tls/key.pem deleted file mode 100644 index e9abfef7a..000000000 --- a/testing/tls/key.pem +++ /dev/null @@ -1,10 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAxRnhkxnqVQ8IC5ua -xcfJIQIW6HeoN14O71NzPZc6MAXgDkum6TfJZwRF6N1Nm68QfqJG0YTbko91UOK2 -l9Ii9QIDAQABAkEAgumaywKWgyJ1vIgAt8bnzxW9M3BueT/u+YTa8Ril3EiOtxDl -/aRtVJ/62r64Ymtq8BvYcEiopFKrUUKPaTfIrQIhAPkd9nDq7B4WepF8+pB0CyR0 -dpT0imCXooN4+utosrdDAiEAyowAwGcYULWiALgSi78gt7fRgp0GwTf80evFy/k0 -DWcCIQC9+IxrVarT0v6LHgyRxfyNQ0b+lnFD8b6bldF7Xa8TswIgA/Ptg9O/Prv8 -uGTfP8jwG4XD2fe0jQrJrVMbnhpz8JsCIHkkbC3ez+iPieasr8a+zEpreE8NjrEV -xs4xp6WZPsGp ------END PRIVATE KEY----- diff --git a/testing/tls/tls.go b/testing/tls/tls.go new file mode 100644 index 000000000..22f81df93 --- /dev/null +++ b/testing/tls/tls.go @@ -0,0 +1,50 @@ +package tls + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "log" + "math/big" + "time" + + "v2ray.com/core/common" + v2tls "v2ray.com/core/transport/internet/tls" +) + +func GenerateCertificateForTest() *v2tls.Certificate { + priv, err := rsa.GenerateKey(rand.Reader, 2048) + common.Must(err) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + log.Fatalf("failed to generate serial number: %s", err) + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"V2Ray Inc"}, + }, + NotBefore: time.Now(), + NotAfter: time.Now().Add(time.Hour), + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + DNSNames: []string{"www.v2ray.com"}, + } + + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) + common.Must(err) + + certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) + + return &v2tls.Certificate{ + Certificate: certPEM, + Key: keyPEM, + } +} diff --git a/transport/internet/websocket/ws_test.go b/transport/internet/websocket/ws_test.go index ed84840d8..8572bd606 100644 --- a/transport/internet/websocket/ws_test.go +++ b/transport/internet/websocket/ws_test.go @@ -1,9 +1,6 @@ package websocket_test import ( - "io/ioutil" - "os" - "path/filepath" "testing" "time" @@ -12,6 +9,7 @@ import ( v2net "v2ray.com/core/common/net" "v2ray.com/core/common/serial" "v2ray.com/core/testing/assert" + tlsgen "v2ray.com/core/testing/tls" "v2ray.com/core/transport/internet" v2tls "v2ray.com/core/transport/internet/tls" . "v2ray.com/core/transport/internet/websocket" @@ -131,21 +129,14 @@ func Test_listenWSAndDial_TLS(t *testing.T) { <-time.After(time.Second * 5) assert.Fail("Too slow") }() - tlsSettings := &v2tls.Config{ - AllowInsecure: true, - Certificate: []*v2tls.Certificate{ - { - Certificate: ReadFile(filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", "testing", "tls", "cert.pem"), assert), - Key: ReadFile(filepath.Join(os.Getenv("GOPATH"), "src", "v2ray.com", "core", "testing", "tls", "key.pem"), assert), - }, - }, - } listen, err := ListenWS(v2net.DomainAddress("localhost"), 13143, internet.ListenOptions{ Stream: &internet.StreamConfig{ - SecurityType: serial.GetMessageType(new(v2tls.Config)), - SecuritySettings: []*serial.TypedMessage{serial.ToTypedMessage(tlsSettings)}, - Protocol: internet.TransportProtocol_WebSocket, + SecurityType: serial.GetMessageType(new(v2tls.Config)), + SecuritySettings: []*serial.TypedMessage{serial.ToTypedMessage(&v2tls.Config{ + Certificate: []*v2tls.Certificate{tlsgen.GenerateCertificateForTest()}, + })}, + Protocol: internet.TransportProtocol_WebSocket, TransportSettings: []*internet.TransportSettings{ { Protocol: internet.TransportProtocol_WebSocket, @@ -168,9 +159,11 @@ func Test_listenWSAndDial_TLS(t *testing.T) { }() conn, err := Dial(v2net.AnyIP, v2net.TCPDestination(v2net.DomainAddress("localhost"), 13143), internet.DialerOptions{ Stream: &internet.StreamConfig{ - SecurityType: serial.GetMessageType(new(v2tls.Config)), - SecuritySettings: []*serial.TypedMessage{serial.ToTypedMessage(tlsSettings)}, - Protocol: internet.TransportProtocol_WebSocket, + SecurityType: serial.GetMessageType(new(v2tls.Config)), + SecuritySettings: []*serial.TypedMessage{serial.ToTypedMessage(&v2tls.Config{ + AllowInsecure: true, + })}, + Protocol: internet.TransportProtocol_WebSocket, TransportSettings: []*internet.TransportSettings{ { Protocol: internet.TransportProtocol_WebSocket, @@ -187,9 +180,3 @@ func Test_listenWSAndDial_TLS(t *testing.T) { assert.Error(err).IsNil() conn.Close() } - -func ReadFile(file string, assert *assert.Assert) []byte { - b, err := ioutil.ReadFile(file) - assert.Error(err).IsNil() - return b -}