trpc.group/trpc-go/trpc-go@v1.0.3/internal/tls/tls.go (about) 1 // 2 // 3 // Tencent is pleased to support the open source community by making tRPC available. 4 // 5 // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 // All rights reserved. 7 // 8 // If you have downloaded a copy of the tRPC source code from Tencent, 9 // please note that tRPC source code is licensed under the Apache 2.0 License, 10 // A copy of the Apache 2.0 License is included in this file. 11 // 12 // 13 14 // Package tls provides some utility functions to get TLS config. 15 package tls 16 17 import ( 18 "crypto/tls" 19 "crypto/x509" 20 "errors" 21 "fmt" 22 "os" 23 ) 24 25 // GetServerConfig gets TLS config for server. 26 // If you do not need to verify the client's certificate, set the caCertFile to empty. 27 // CertFile and keyFile should not be empty. 28 func GetServerConfig(caCertFile, certFile, keyFile string) (*tls.Config, error) { 29 tlsConf := &tls.Config{} 30 cert, err := tls.LoadX509KeyPair(certFile, keyFile) 31 if err != nil { 32 return nil, fmt.Errorf("server load cert file error: %w", err) 33 } 34 tlsConf.Certificates = []tls.Certificate{cert} 35 36 if caCertFile == "" { // no need to verify client certificate. 37 return tlsConf, nil 38 } 39 tlsConf.ClientAuth = tls.RequireAndVerifyClientCert 40 pool, err := GetCertPool(caCertFile) 41 if err != nil { 42 return nil, err 43 } 44 tlsConf.ClientCAs = pool 45 return tlsConf, nil 46 } 47 48 // GetClientConfig gets TLS config for client. 49 // If you do not need to verify the server's certificate, set the caCertFile to "none". 50 // If only one-way authentication, set the certFile and keyFile to empty. 51 func GetClientConfig(serverName, caCertFile, certFile, keyFile string) (*tls.Config, error) { 52 tlsConf := &tls.Config{} 53 if caCertFile == "none" { // no need to verify server certificate. 54 tlsConf.InsecureSkipVerify = true 55 return tlsConf, nil 56 } 57 // need to verify server certification. 58 tlsConf.ServerName = serverName 59 certPool, err := GetCertPool(caCertFile) 60 if err != nil { 61 return nil, err 62 } 63 tlsConf.RootCAs = certPool 64 if certFile == "" { 65 return tlsConf, nil 66 } 67 // enable two-way authentication and needs to send the 68 // client's own certificate to the server. 69 cert, err := tls.LoadX509KeyPair(certFile, keyFile) 70 if err != nil { 71 return nil, fmt.Errorf("client load cert file error: %w", err) 72 } 73 tlsConf.Certificates = []tls.Certificate{cert} 74 return tlsConf, nil 75 } 76 77 // GetCertPool gets CertPool information. 78 func GetCertPool(caCertFile string) (*x509.CertPool, error) { 79 // root means to use the root ca certificate installed on the machine to 80 // verify the peer, if not root, use the input ca file to verify peer. 81 if caCertFile == "root" { 82 return nil, nil 83 } 84 ca, err := os.ReadFile(caCertFile) 85 if err != nil { 86 return nil, fmt.Errorf("read ca file error: %w", err) 87 } 88 certPool := x509.NewCertPool() 89 if !certPool.AppendCertsFromPEM(ca) { 90 return nil, errors.New("AppendCertsFromPEM fail") 91 } 92 return certPool, nil 93 }