github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/p2p/secure/secure_connection.go (about) 1 package secure 2 3 import ( 4 "crypto/tls" 5 "crypto/x509" 6 "fmt" 7 "github.com/bigzoro/my_simplechain/p2p/enode" 8 mapset "github.com/deckarep/golang-set" 9 "math/big" 10 "net" 11 "path/filepath" 12 "time" 13 ) 14 15 var defaultDialTimeout = 15 * time.Second 16 17 /* 18 tls相关的目录的根目录 19 20 . 21 ├── crls 22 ├── keystore 23 ├── signcerts 24 ├── tlscacerts 25 └── tlsintermediatecerts 26 */ 27 type ConnectionConfig struct { 28 UseTLS bool 29 Dir string //tls相关的目录的根目录 30 } 31 type SecureConnection struct { 32 config *ConnectionConfig 33 certificate tls.Certificate 34 rootCAs *x509.CertPool 35 secureManager *SecureManager 36 tlsClientConfig *tls.Config 37 tlsServerConfig *tls.Config 38 crlHashes mapset.Set 39 useTLS bool 40 } 41 42 func NewSecureConnection(config *ConnectionConfig) (*SecureConnection, error) { 43 if config.UseTLS { 44 keyPath, err := GetPrivateKeyPath(filepath.Join(config.Dir, KeyFolder)) 45 if err != nil { 46 return nil, err 47 } 48 certificatePath, err := GetCertificatePath(filepath.Join(config.Dir, CertificateFolder)) 49 if err != nil { 50 return nil, err 51 } 52 certificate, err := LoadNodeCertificate(keyPath, certificatePath) 53 if err != nil { 54 return nil, err 55 } 56 secureManager := &SecureManager{} 57 58 secureConfig, err := GetSecureConfig(config.Dir) 59 if err != nil { 60 return nil, err 61 } 62 err = secureManager.setupTLSCAs(secureConfig) 63 if err != nil { 64 return nil, err 65 } 66 err = secureManager.setupCRLs(secureConfig) 67 if err != nil { 68 return nil, err 69 } 70 return &SecureConnection{ 71 config: config, 72 certificate: certificate, 73 secureManager: secureManager, 74 rootCAs: secureManager.opts.Roots, 75 useTLS: config.UseTLS, 76 }, nil 77 } else { 78 return &SecureConnection{ 79 config: config, 80 useTLS: config.UseTLS, 81 }, nil 82 } 83 } 84 85 func (this *SecureConnection) Dial(dest *enode.Node) (net.Conn, error) { 86 addr := &net.TCPAddr{IP: dest.IP(), Port: dest.TCP()} 87 if this.config.UseTLS { 88 //It itself acts as a client to verify the server-side certificate 89 if this.tlsClientConfig == nil { 90 tlsClientConfig := &tls.Config{ 91 Certificates: []tls.Certificate{this.certificate}, 92 RootCAs: this.rootCAs, 93 VerifyPeerCertificate: this.verifyServerCertificate, 94 InsecureSkipVerify: false, 95 } 96 this.tlsClientConfig = tlsClientConfig 97 } 98 netDialer := &net.Dialer{ 99 Timeout: defaultDialTimeout, 100 } 101 dialer := &tls.Dialer{ 102 NetDialer: netDialer, 103 Config: this.tlsClientConfig, 104 } 105 return dialer.Dial("tcp", addr.String()) 106 } else { 107 dialer := &net.Dialer{Timeout: defaultDialTimeout} 108 return dialer.Dial("tcp", addr.String()) 109 } 110 } 111 func (this *SecureConnection) Listen(network, addr string) (net.Listener, error) { 112 if this.config.UseTLS { 113 //It itself acts as a server to verify client certificates 114 if this.tlsServerConfig == nil { 115 config := &tls.Config{ 116 Certificates: []tls.Certificate{this.certificate}, 117 ClientAuth: tls.RequireAndVerifyClientCert, 118 ClientCAs: this.rootCAs, 119 VerifyPeerCertificate: this.verifyClientCertificate, 120 } 121 this.tlsServerConfig = config 122 } 123 return tls.Listen(network, addr, this.tlsServerConfig) 124 } else { 125 return net.Listen(network, addr) 126 } 127 } 128 func (this *SecureConnection) verifyClientCertificate(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { 129 clientCert, err := x509.ParseCertificate(rawCerts[0]) 130 if err != nil { 131 fmt.Println(err) 132 return err 133 } 134 return this.secureManager.validateCertAgainst(clientCert) 135 } 136 func (this *SecureConnection) verifyServerCertificate(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { 137 clientCert, err := x509.ParseCertificate(rawCerts[0]) 138 if err != nil { 139 fmt.Println(err) 140 return err 141 } 142 return this.secureManager.validateCertAgainst(clientCert) 143 } 144 func (this *SecureConnection) SaveCRL(dir string, CRLBytes []byte) ([]*big.Int, error) { 145 if this.useTLS { 146 return this.secureManager.SaveCRL(dir, CRLBytes) 147 } 148 return nil, nil 149 }