uTLS PinnedPeerCertificateChainSha256 (#1556)

* Add tests for utls PinnedPeerCertificateChain

* Fix utls not checking PinnedPeerCertificate

Co-authored-by: ahmadi <ahmadi@meshkan.com>
This commit is contained in:
mra9776 2023-01-27 07:49:49 +03:30 committed by GitHub
parent fb212905bd
commit f571aa72df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 317 additions and 3 deletions

View file

@ -928,3 +928,316 @@ func TestSimpleTLSConnectionPinned(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
} }
func TestSimpleTLSConnectionPinnedWrongCert(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})
certHash[1] += 1
userID := protocol.NewID(uuid.New())
serverPort := tcp.PickPort()
serverConfig := &core.Config{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortList: &net.PortList{Range: []*net.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{
PortList: &net.PortList{Range: []*net.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*20)(); err == nil {
t.Fatal(err)
}
}
func TestUTLSConnectionPinned(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{
PortList: &net.PortList{Range: []*net.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{
PortList: &net.PortList{Range: []*net.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{
Fingerprint: "random",
AllowInsecure: true,
PinnedPeerCertificateChainSha256: [][]byte{certHash},
}),
},
},
}),
},
},
}
servers, err := InitializeServerConfigs(serverConfig, clientConfig)
common.Must(err)
defer CloseAllServers(servers)
if err := testTCPConn(clientPort, 1024, time.Second*20)(); err != nil {
t.Fatal(err)
}
}
func TestUTLSConnectionPinnedWrongCert(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})
certHash[1] += 1
userID := protocol.NewID(uuid.New())
serverPort := tcp.PickPort()
serverConfig := &core.Config{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortList: &net.PortList{Range: []*net.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{
PortList: &net.PortList{Range: []*net.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{
Fingerprint: "random",
AllowInsecure: true,
PinnedPeerCertificateChainSha256: [][]byte{certHash},
}),
},
},
}),
},
},
}
servers, err := InitializeServerConfigs(serverConfig, clientConfig)
common.Must(err)
defer CloseAllServers(servers)
if err := testTCPConn(clientPort, 1024, time.Second*20)(); err == nil {
t.Fatal(err)
}
}

View file

@ -111,9 +111,10 @@ func UClient(c net.Conn, config *tls.Config, fingerprint *utls.ClientHelloID) ne
func copyConfig(c *tls.Config) *utls.Config { func copyConfig(c *tls.Config) *utls.Config {
return &utls.Config{ return &utls.Config{
RootCAs: c.RootCAs, RootCAs: c.RootCAs,
ServerName: c.ServerName, ServerName: c.ServerName,
InsecureSkipVerify: c.InsecureSkipVerify, InsecureSkipVerify: c.InsecureSkipVerify,
VerifyPeerCertificate: c.VerifyPeerCertificate,
} }
} }