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

@ -1,8 +1,10 @@
package tls
import (
"crypto/hmac"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"strings"
"sync"
"time"
@ -254,6 +256,19 @@ func (c *Config) parseServerName() string {
return c.ServerName
}
func (c *Config) verifyPeerCert(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
if c.PinnedPeerCertificateChainSha256 != nil {
hashValue := GenerateCertChainHash(rawCerts)
for _, v := range c.PinnedPeerCertificateChainSha256 {
if hmac.Equal(hashValue, v) {
return nil
}
}
return newError("peer cert is unrecognized: ", base64.StdEncoding.EncodeToString(hashValue))
}
return nil
}
// GetTLSConfig converts this Config into tls.Config.
func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
root, err := c.getCertPool()
@ -277,6 +292,7 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config {
InsecureSkipVerify: c.AllowInsecure,
NextProtos: c.NextProtocol,
SessionTicketsDisabled: !c.EnableSessionResumption,
VerifyPeerCertificate: c.verifyPeerCert,
}
for _, opt := range opts {