github.com/vchain-us/vcn@v0.9.11-0.20210921212052-a2484d23c0b3/pkg/api/lc_client.go (about) 1 /* 2 * Copyright (c) 2018-2020 vChain, Inc. All Rights Reserved. 3 * This software is released under GPL3. 4 * The full license information can be found under: 5 * https://www.gnu.org/licenses/gpl-3.0.en.html 6 * 7 */ 8 9 package api 10 11 import ( 12 "crypto/ecdsa" 13 "crypto/tls" 14 "crypto/x509" 15 "errors" 16 "fmt" 17 "io/ioutil" 18 "strconv" 19 "time" 20 21 sdk "github.com/vchain-us/ledger-compliance-go/grpcclient" 22 "github.com/vchain-us/vcn/pkg/meta" 23 "github.com/vchain-us/vcn/pkg/store" 24 "google.golang.org/grpc" 25 "google.golang.org/grpc/credentials" 26 "google.golang.org/grpc/keepalive" 27 ) 28 29 func NewLcClientByContext(context store.CurrentContext, lcApiKey string, lcLedger string, signingPubKey *ecdsa.PublicKey) (*sdk.LcClient, error) { 30 return NewLcClient(lcApiKey, lcLedger, context.LcHost, context.LcPort, context.LcCert, context.LcSkipTlsVerify, context.LcNoTls, signingPubKey) 31 } 32 33 func NewLcClient(lcApiKey, lcLedger, host, port, lcCertPath string, skipTlsVerify, noTls bool, signingPubKey *ecdsa.PublicKey) (*sdk.LcClient, error) { 34 if skipTlsVerify && noTls { 35 return nil, errors.New("illegal parameters submitted: lc-skip-tls-verify and lc-no-tls arguments are both provided") 36 } 37 38 p, err := strconv.Atoi(port) 39 if err != nil { 40 return nil, errors.New("ledger compliance port is invalid") 41 } 42 defaultOptions := []grpc.DialOption{ 43 grpc.WithKeepaliveParams(keepalive.ClientParameters{ 44 Time: 20 * time.Second, 45 Timeout: 10 * time.Second, 46 PermitWithoutStream: true, 47 }), 48 } 49 50 currentOptions := []grpc.DialOption{} 51 currentOptions = append(currentOptions, defaultOptions...) 52 if !skipTlsVerify { 53 if lcCertPath != "" { 54 tlsCredentials, err := loadTLSCertificate(lcCertPath) 55 if err != nil { 56 return nil, fmt.Errorf("cannot load TLS credentials: %s", err) 57 } 58 currentOptions = append(currentOptions, grpc.WithTransportCredentials(tlsCredentials)) 59 } else { 60 // automatic loading of local CA in os 61 currentOptions = append(currentOptions, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))) 62 } 63 } else { 64 currentOptions = append(currentOptions, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true}))) 65 } 66 67 if noTls { 68 currentOptions = []grpc.DialOption{grpc.WithInsecure()} 69 currentOptions = append(currentOptions, defaultOptions...) 70 } 71 72 return sdk.NewLcClient( 73 sdk.ApiKey(lcApiKey), 74 sdk.MetadataPairs([]string{ 75 meta.VcnLCLedgerHeaderName, lcLedger, 76 meta.VcnLCVersionHeaderName, meta.Version(), 77 }), 78 sdk.Host(host), 79 sdk.Port(p), 80 sdk.Dir(store.CurrentConfigFilePath()), 81 sdk.DialOptions(currentOptions), 82 sdk.ServerSigningPubKey(signingPubKey), 83 ), nil 84 } 85 86 func loadTLSCertificate(certPath string) (credentials.TransportCredentials, error) { 87 cert, err := ioutil.ReadFile(certPath) 88 if err != nil { 89 return nil, err 90 } 91 certPool := x509.NewCertPool() 92 if !certPool.AppendCertsFromPEM(cert) { 93 return nil, fmt.Errorf("failed to add server CA's certificate") 94 } 95 config := &tls.Config{ 96 RootCAs: certPool, 97 } 98 return credentials.NewTLS(config), nil 99 }