github.com/stffabi/git-lfs@v2.3.5-0.20180214015214-8eeaa8d88902+incompatible/lfsapi/certs_darwin.go (about) 1 package lfsapi 2 3 import ( 4 "crypto/x509" 5 "regexp" 6 "strings" 7 8 "github.com/git-lfs/git-lfs/subprocess" 9 "github.com/rubyist/tracerx" 10 ) 11 12 func appendRootCAsForHostFromPlatform(pool *x509.CertPool, host string) *x509.CertPool { 13 // Go loads only the system root certificates by default 14 // see https://github.com/golang/go/blob/master/src/crypto/x509/root_darwin.go 15 // We want to load certs configured in the System keychain too, this is separate 16 // from the system root certificates. It's also where other tools such as 17 // browsers (e.g. Chrome) will load custom trusted certs from. They often 18 // don't load certs from the login keychain so that's not included here 19 // either, for consistency. 20 21 // find system.keychain for user-added certs (don't assume location) 22 cmd := subprocess.ExecCommand("/usr/bin/security", "list-keychains") 23 kcout, err := cmd.Output() 24 if err != nil { 25 tracerx.Printf("Error listing keychains: %v", err) 26 return nil 27 } 28 29 var systemKeychain string 30 keychains := strings.Split(string(kcout), "\n") 31 for _, keychain := range keychains { 32 lc := strings.ToLower(keychain) 33 if !strings.Contains(lc, "/system.keychain") { 34 continue 35 } 36 systemKeychain = strings.Trim(keychain, " \t\"") 37 break 38 } 39 40 if len(systemKeychain) == 0 { 41 return nil 42 } 43 44 pool = appendRootCAsFromKeychain(pool, host, systemKeychain) 45 46 // Also check host without port 47 portreg := regexp.MustCompile(`([^:]+):\d+`) 48 if match := portreg.FindStringSubmatch(host); match != nil { 49 hostwithoutport := match[1] 50 pool = appendRootCAsFromKeychain(pool, hostwithoutport, systemKeychain) 51 } 52 53 return pool 54 } 55 56 func appendRootCAsFromKeychain(pool *x509.CertPool, name, keychain string) *x509.CertPool { 57 cmd := subprocess.ExecCommand("/usr/bin/security", "find-certificate", "-a", "-p", "-c", name, keychain) 58 data, err := cmd.Output() 59 if err != nil { 60 tracerx.Printf("Error reading keychain %q: %v", keychain, err) 61 return pool 62 } 63 return appendCertsFromPEMData(pool, data) 64 }