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 }