github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/x509/root_unix.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris 6 // +build aix dragonfly freebsd js,wasm linux netbsd openbsd solaris 7 8 package x509 9 10 import ( 11 "io/fs" 12 "os" 13 "path/filepath" 14 "strings" 15 ) 16 17 const ( 18 // certFileEnv is the environment variable which identifies where to locate 19 // the SSL certificate file. If set this overrides the system default. 20 certFileEnv = "SSL_CERT_FILE" 21 22 // certDirEnv is the environment variable which identifies which directory 23 // to check for SSL certificate files. If set this overrides the system default. 24 // It is a colon separated list of directories. 25 // See https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html. 26 certDirEnv = "SSL_CERT_DIR" 27 ) 28 29 //goland:noinspection GoUnusedParameter 30 func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { 31 return nil, nil 32 } 33 34 func loadSystemRoots() (*CertPool, error) { 35 roots := NewCertPool() 36 37 files := certFiles 38 if f := os.Getenv(certFileEnv); f != "" { 39 files = []string{f} 40 } 41 42 var firstErr error 43 for _, file := range files { 44 data, err := os.ReadFile(file) 45 if err == nil { 46 roots.AppendCertsFromPEM(data) 47 break 48 } 49 if firstErr == nil && !os.IsNotExist(err) { 50 firstErr = err 51 } 52 } 53 54 dirs := certDirectories 55 if d := os.Getenv(certDirEnv); d != "" { 56 // OpenSSL and BoringSSL both use ":" as the SSL_CERT_DIR separator. 57 // See: 58 // * https://golang.org/issue/35325 59 // * https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html 60 dirs = strings.Split(d, ":") 61 } 62 63 for _, directory := range dirs { 64 fis, err := readUniqueDirectoryEntries(directory) 65 if err != nil { 66 if firstErr == nil && !os.IsNotExist(err) { 67 firstErr = err 68 } 69 continue 70 } 71 for _, fi := range fis { 72 data, err := os.ReadFile(directory + "/" + fi.Name()) 73 if err == nil { 74 roots.AppendCertsFromPEM(data) 75 } 76 } 77 } 78 79 if roots.len() > 0 || firstErr == nil { 80 return roots, nil 81 } 82 83 return nil, firstErr 84 } 85 86 // readUniqueDirectoryEntries is like os.ReadDir but omits 87 // symlinks that point within the directory. 88 func readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) { 89 files, err := os.ReadDir(dir) 90 if err != nil { 91 return nil, err 92 } 93 uniq := files[:0] 94 for _, f := range files { 95 if !isSameDirSymlink(f, dir) { 96 uniq = append(uniq, f) 97 } 98 } 99 return uniq, nil 100 } 101 102 // isSameDirSymlink reports whether fi in dir is a symlink with a 103 // target not containing a slash. 104 func isSameDirSymlink(f fs.DirEntry, dir string) bool { 105 if f.Type()&fs.ModeSymlink == 0 { 106 return false 107 } 108 target, err := os.Readlink(filepath.Join(dir, f.Name())) 109 return err == nil && !strings.Contains(target, "/") 110 }