github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/p2p/secure/certificate_loader.go (about)

     1  package secure
     2  
     3  import (
     4  	"crypto/tls"
     5  	"encoding/pem"
     6  	"errors"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  	"strings"
    12  )
    13  
    14  const (
    15  	CRLsFolder                 = "crls"
    16  	TLSCACertsFolder           = "tlscacerts"
    17  	TLSIntermediateCertsFolder = "tlsintermediatecerts"
    18  	KeyFolder                  = "keystore"
    19  	CertificateFolder          = "signcerts"
    20  )
    21  
    22  func GetRootCAPath(dir string) ([]string, error) {
    23  	result := make([]string, 0)
    24  	_, err := os.Stat(dir)
    25  	if os.IsNotExist(err) {
    26  		return nil, err
    27  	}
    28  	files, err := ioutil.ReadDir(dir)
    29  	if err != nil {
    30  		return nil, errors.New(fmt.Sprintf("%v could not read directory %s", err, dir))
    31  	}
    32  	for _, f := range files {
    33  		fullName := filepath.Join(dir, f.Name())
    34  		f, err := os.Stat(fullName)
    35  		if err != nil {
    36  			fmt.Printf("Failed to stat %s: %s\n", fullName, err)
    37  			continue
    38  		}
    39  		if f.IsDir() {
    40  			continue
    41  		}
    42  		result = append(result, fullName)
    43  	}
    44  	return result, nil
    45  }
    46  
    47  func GetPrivateKeyPath(key string) (string, error) {
    48  	var filename string
    49  	walkFunc := func(path string, info os.FileInfo, pathErr error) error {
    50  		if !strings.HasSuffix(path, "_sk") {
    51  			return nil
    52  		}
    53  		filename = path
    54  		return nil
    55  	}
    56  	err := filepath.Walk(key, walkFunc)
    57  	if err != nil {
    58  		return "", err
    59  	}
    60  	return filename, err
    61  }
    62  func GetCertificatePath(certificate string) (string, error) {
    63  	var filename string
    64  	walkFunc := func(path string, info os.FileInfo, pathErr error) error {
    65  		if !strings.HasSuffix(path, "pem") {
    66  			return nil
    67  		}
    68  		filename = path
    69  		return nil
    70  	}
    71  	err := filepath.Walk(certificate, walkFunc)
    72  	if err != nil {
    73  		return "", err
    74  	}
    75  	return filename, err
    76  }
    77  
    78  func GetSecureConfig(dir string) (*SecureConfig, error) {
    79  	TLSCACertsDir := filepath.Join(dir, TLSCACertsFolder)
    80  	TLSIntermediateCertsDir := filepath.Join(dir, TLSIntermediateCertsFolder)
    81  	TLSCACerts, err := getPemMaterialFromDir(TLSCACertsDir)
    82  	var TLSIntermediateCerts [][]byte
    83  	if os.IsNotExist(err) {
    84  		fmt.Printf("TLS CA certs folder not found at [%s]. Skipping and ignoring TLS intermediate CA folder. [%s] [%s]\n", TLSCACerts, TLSIntermediateCertsDir, err.Error())
    85  	} else if err != nil {
    86  		return nil, errors.New(fmt.Sprintf("%v failed loading TLS ca certs at [%s]", err, TLSCACertsDir))
    87  	} else if len(TLSCACerts) != 0 {
    88  		TLSIntermediateCerts, err = getPemMaterialFromDir(TLSIntermediateCertsDir)
    89  		if os.IsNotExist(err) {
    90  			fmt.Printf("TLS intermediate certs folder not found at [%s]. Skipping. [%s]\n", TLSIntermediateCertsDir, err.Error())
    91  		} else if err != nil {
    92  			return nil, errors.New(fmt.Sprintf("failed loading TLS intermediate ca certs at [%s];error :%s", TLSIntermediateCertsDir, err.Error()))
    93  		}
    94  	} else {
    95  		fmt.Printf("TLS CA certs folder at [%s] is empty. Skipping.\n", TLSCACertsDir)
    96  	}
    97  
    98  	//Certificate Revocation List
    99  	CRLsDir := filepath.Join(dir, CRLsFolder)
   100  	CRLs, err := getPemMaterialFromDir(CRLsDir)
   101  	if os.IsNotExist(err) {
   102  		fmt.Printf("crls folder not found at [%s]. Skipping. [%s]\n", CRLsDir, err)
   103  	} else if err != nil {
   104  		return nil, errors.New(fmt.Sprintf(" %v failed loading crls at [%s]", err, CRLsDir))
   105  	}
   106  	config := &SecureConfig{
   107  		RevocationList:       CRLs,
   108  		TlsRootCerts:         TLSCACerts,
   109  		TlsIntermediateCerts: TLSIntermediateCerts,
   110  	}
   111  	return config, nil
   112  }
   113  
   114  // get the keyPair from the file system
   115  
   116  func LoadNodeCertificate(keyPath, certPath string) (tls.Certificate, error) {
   117  	cert := tls.Certificate{}
   118  
   119  	clientKey, err := ioutil.ReadFile(keyPath)
   120  	if err != nil {
   121  		return cert, errors.New(fmt.Sprintf("%v error loading node TLS key", err))
   122  	}
   123  	clientCert, err := ioutil.ReadFile(certPath)
   124  	if err != nil {
   125  		return cert, errors.New(fmt.Sprintf("%v error loading node TLS certificate", err))
   126  	}
   127  	cert, err = tls.X509KeyPair(clientCert, clientKey)
   128  	if err != nil {
   129  		return cert, errors.New(fmt.Sprintf("%v error parsing node TLS key pair", err))
   130  	}
   131  	return cert, nil
   132  }
   133  func getPemMaterialFromDir(dir string) ([][]byte, error) {
   134  	_, err := os.Stat(dir)
   135  	if os.IsNotExist(err) {
   136  		return nil, err
   137  	}
   138  	content := make([][]byte, 0)
   139  	files, err := ioutil.ReadDir(dir)
   140  	if err != nil {
   141  		return nil, errors.New(fmt.Sprintf("%v could not read directory %s", err, dir))
   142  	}
   143  
   144  	for _, f := range files {
   145  
   146  		fullName := filepath.Join(dir, f.Name())
   147  
   148  		f, err := os.Stat(fullName)
   149  		if err != nil {
   150  			fmt.Printf("Failed to stat %s: %s\n", fullName, err)
   151  			continue
   152  		}
   153  		if f.IsDir() {
   154  			continue
   155  		}
   156  		item, err := readPemFile(fullName)
   157  		if err != nil {
   158  			fmt.Printf("Failed reading file %s: %s\n", fullName, err)
   159  			continue
   160  		}
   161  		content = append(content, item)
   162  	}
   163  
   164  	return content, nil
   165  }
   166  func readPemFile(file string) ([]byte, error) {
   167  	bytes, err := readFile(file)
   168  	if err != nil {
   169  		return nil, errors.New(fmt.Sprintf("%v reading from file %s failed", err, file))
   170  	}
   171  	b, _ := pem.Decode(bytes)
   172  	if b == nil {
   173  		return nil, errors.New(fmt.Sprintf("no pem content for file %s", file))
   174  	}
   175  	return bytes, nil
   176  }
   177  func readFile(file string) ([]byte, error) {
   178  	fileCont, err := ioutil.ReadFile(file)
   179  	if err != nil {
   180  		return nil, errors.New(fmt.Sprintf("%v could not read file %s", err, file))
   181  	}
   182  	return fileCont, nil
   183  }