Verify peer cert function for better man in the middle prevention (#746)

* verify peer cert function for better man in the middle prevention

* publish cert chain hash generation algorithm

* added calculation of certificate hash as separate command and tlsping, use base64 to represent fingerprint to align with jsonPb

* apply coding style

* added test case for pinned certificates

* refactored cert pin

* pinned cert test

* added json loading of the PinnedPeerCertificateChainSha256

* removed tool to prepare for v5

* Add server cert pinning for Xtls

Change command "xray tls certChainHash" to xray style

Co-authored-by: Shelikhoo <xiaokangwang@outlook.com>
This commit is contained in:
yuhan6665 2021-10-22 00:04:06 -04:00 committed by 世界
parent 6a60332700
commit acb81ebe3d
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
13 changed files with 447 additions and 35 deletions

View file

@ -826,3 +826,106 @@ func TestGRPCMultiMode(t *testing.T) {
t.Error(err)
}
}
func TestSimpleTLSConnectionPinned(t *testing.T) {
tcpServer := tcp.Server{
MsgProcessor: xor,
}
dest, err := tcpServer.Start()
common.Must(err)
defer tcpServer.Close()
certificateDer := cert.MustGenerate(nil)
certificate := tls.ParseCertificate(certificateDer)
certHash := tls.GenerateCertChainHash([][]byte{certificateDer.Certificate})
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},
}),
},
},
}),
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{
AllowInsecure: true,
PinnedPeerCertificateChainSha256: [][]byte{certHash},
}),
},
},
}),
},
},
}
servers, err := InitializeServerConfigs(serverConfig, clientConfig)
common.Must(err)
defer CloseAllServers(servers)
if err := testTCPConn(clientPort, 1024, time.Second*2)(); err != nil {
t.Fatal(err)
}
}