Beispiel #1
0
func (repo CloudControllerBuildpackBitsRepository) downloadBuildpack(url string, cb func(*os.File, error)) {
	fileutils.TempFile("buildpack-download", func(tempfile *os.File, err error) {
		if err != nil {
			cb(nil, err)
			return
		}

		var certPool *x509.CertPool
		if len(repo.TrustedCerts) > 0 {
			certPool = x509.NewCertPool()
			for _, tlsCert := range repo.TrustedCerts {
				cert, _ := x509.ParseCertificate(tlsCert.Certificate[0])
				certPool.AddCert(cert)
			}
		}

		client := &http.Client{
			Transport: &http.Transport{
				TLSClientConfig: &tls.Config{RootCAs: certPool},
				Proxy:           http.ProxyFromEnvironment,
			},
		}

		response, err := client.Get(url)
		if err != nil {
			cb(nil, err)
			return
		}

		io.Copy(tempfile, response.Body)
		tempfile.Seek(0, 0)
		cb(tempfile, nil)
	})
}
func loadPEMCertificate(certPool *x509.CertPool, pemCerts []byte) (ok bool) {
	for len(pemCerts) > 0 {
		var block *pem.Block
		block, pemCerts = pem.Decode(pemCerts)
		if block == nil {
			break
		}
		if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
			continue
		}

		cert, err := x509.ParseCertificate(block.Bytes)
		if err != nil {
			continue
		}

		// Assumption: CA is self-signed. Not recommended
		// for production environments.
		cert.IsCA = true
		certPool.AddCert(cert)
		ok = true
	}

	return
}
Beispiel #3
0
func loadStore(roots *x509.CertPool, name string) {
	store, errno := syscall.CertOpenSystemStore(syscall.InvalidHandle, syscall.StringToUTF16Ptr(name))
	if errno != 0 {
		return
	}

	var cert *syscall.CertContext
	for {
		cert = syscall.CertEnumCertificatesInStore(store, cert)
		if cert == nil {
			break
		}

		var asn1Slice []byte
		hdrp := (*reflect.SliceHeader)(unsafe.Pointer(&asn1Slice))
		hdrp.Data = cert.EncodedCert
		hdrp.Len = int(cert.Length)
		hdrp.Cap = int(cert.Length)

		buf := make([]byte, len(asn1Slice))
		copy(buf, asn1Slice)

		if cert, err := x509.ParseCertificate(buf); err == nil {
			roots.AddCert(cert)
		}
	}

	syscall.CertCloseStore(store, 0)
}
Beispiel #4
0
func appendCerts(pool *x509.CertPool, certs []*x509.Certificate) *x509.CertPool {
	if len(certs) == 0 {
		// important to return unmodified (may be nil)
		return pool
	}

	if pool == nil {
		pool = x509.NewCertPool()
	}

	for _, cert := range certs {
		pool.AddCert(cert)
	}

	return pool
}
Beispiel #5
0
func (c *CLI) GetTLSConfig(ctx *cli.Context) *tls.Config {
	var pool *x509.CertPool
	caCert, err := c.Config.Cluster.GetCertificateAuthority()
	if err != nil {
		// warn user
	} else {
		if caCert != nil {
			pool = x509.NewCertPool()
			pool.AddCert(caCert)
		}
	}
	return &tls.Config{
		RootCAs:            pool,
		InsecureSkipVerify: c.Config.Cluster.InsecureSkipVerify,
	}
}
Beispiel #6
0
func loadStore(roots *x509.CertPool, name string) {
	store, err := syscall.CertOpenSystemStore(syscall.InvalidHandle, syscall.StringToUTF16Ptr(name))
	if err != nil {
		return
	}
	defer syscall.CertCloseStore(store, 0)

	var cert *syscall.CertContext
	for {
		cert, err = syscall.CertEnumCertificatesInStore(store, cert)
		if err != nil {
			return
		}

		buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:]
		// ParseCertificate requires its own copy of certificate data to keep.
		buf2 := make([]byte, cert.Length)
		copy(buf2, buf)
		if c, err := x509.ParseCertificate(buf2); err == nil {
			roots.AddCert(c)
		}
	}
}
Beispiel #7
0
// processCertDir iterates through the certDir looking for *.pem files.
// Each pem file is read in turn and added to the pool.  A count of the number
// of successful certificates processed is returned.
func processCertDir(pool *x509.CertPool) (count int) {
	fileInfo, err := os.Stat(certDir)
	if os.IsNotExist(err) {
		logger.Tracef("cert dir %q does not exist", certDir)
		return -1
	}
	if err != nil {
		logger.Infof("unexpected error reading cert dir: %s", err)
		return -1
	}
	if !fileInfo.IsDir() {
		logger.Infof("cert dir %q is not a directory", certDir)
		return -1
	}

	matches, err := filepath.Glob(filepath.Join(certDir, "*.pem"))
	if err != nil {
		logger.Infof("globbing files failed: %s", err)
		return -1
	}

	for _, match := range matches {
		data, err := ioutil.ReadFile(match)
		if err != nil {
			logger.Infof("error reading %q: %v", match, err)
			continue
		}
		certificate, err := cert.ParseCert(string(data))
		if err != nil {
			logger.Infof("error parsing cert %q: %v", match, err)
			continue
		}
		pool.AddCert(certificate)
		count++
	}
	return count
}
Beispiel #8
0
func main() {
	var caFile, intFile string
	var forceIntermediateBundle, revexp, verbose bool
	flag.StringVar(&caFile, "ca", "", "CA certificate `bundle`")
	flag.StringVar(&intFile, "i", "", "intermediate `bundle`")
	flag.BoolVar(&forceIntermediateBundle, "f", false,
		"force the use of the intermediate bundle, ignoring any intermediates bundled with certificate")
	flag.BoolVar(&revexp, "r", false, "print revocation and expiry information")
	flag.BoolVar(&verbose, "v", false, "verbose")
	flag.Parse()

	var roots *x509.CertPool
	if caFile != "" {
		var err error
		if verbose {
			fmt.Println("[+] loading root certificates from", caFile)
		}
		roots, err = helpers.LoadPEMCertPool(caFile)
		die.If(err)
	}

	var ints *x509.CertPool
	if intFile != "" {
		var err error
		if verbose {
			fmt.Println("[+] loading intermediate certificates from", intFile)
		}
		ints, err = helpers.LoadPEMCertPool(caFile)
		die.If(err)
	} else {
		ints = x509.NewCertPool()
	}

	if flag.NArg() != 1 {
		fmt.Fprintf(os.Stderr, "Usage: %s [-ca bundle] [-i bundle] cert",
			lib.ProgName())
	}

	fileData, err := ioutil.ReadFile(flag.Arg(0))
	die.If(err)

	chain, err := helpers.ParseCertificatesPEM(fileData)
	die.If(err)
	if verbose {
		fmt.Printf("[+] %s has %d certificates\n", flag.Arg(0), len(chain))
	}

	cert := chain[0]
	if len(chain) > 1 {
		if !forceIntermediateBundle {
			for _, intermediate := range chain[1:] {
				if verbose {
					fmt.Printf("[+] adding intermediate with SKI %x\n", intermediate.SubjectKeyId)
				}

				ints.AddCert(intermediate)
			}
		}
	}

	opts := x509.VerifyOptions{
		Intermediates: ints,
		Roots:         roots,
		KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
	}

	_, err = cert.Verify(opts)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Verification failed: %v\n", err)
		os.Exit(1)
	}

	if verbose {
		fmt.Println("OK")
	}

	if revexp {
		printRevocation(cert)
	}
}
Beispiel #9
0
func (conf *config) validCert(cert *x509.Certificate, intermediates *x509.CertPool) bool {
	_, err := cert.Verify(x509.VerifyOptions{Intermediates: intermediates})
	if err == nil {
		return true
	}
	if _, ok := err.(x509.UnknownAuthorityError); !ok {
		// There was an error, but not because the certificate wasn't signed
		// by a recognized CA. So we go ahead and use the cert and let
		// the client experience the same error.
		return true
	}

	if conf.ExtraRootCerts != nil {
		_, err = cert.Verify(x509.VerifyOptions{Roots: conf.ExtraRootCerts, Intermediates: intermediates})
		if err == nil {
			return true
		}
		if _, ok := err.(x509.UnknownAuthorityError); !ok {
			return true
		}
	}

	// Before we give up, we'll try fetching some intermediate certificates.
	if len(cert.IssuingCertificateURL) == 0 {
		return false
	}

	toFetch := cert.IssuingCertificateURL
	fetched := make(map[string]bool)

	for i := 0; i < len(toFetch); i++ {
		certURL := toFetch[i]
		if fetched[certURL] {
			continue
		}
		resp, err := http.Get(certURL)
		if err == nil {
			defer resp.Body.Close()
		}
		if err != nil || resp.StatusCode != 200 {
			continue
		}
		fetchedCert, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			continue
		}

		// The fetched certificate might be in either DER or PEM format.
		if bytes.Contains(fetchedCert, []byte("-----BEGIN CERTIFICATE-----")) {
			// It's PEM.
			var certDER *pem.Block
			for {
				certDER, fetchedCert = pem.Decode(fetchedCert)
				if certDER == nil {
					break
				}
				if certDER.Type != "CERTIFICATE" {
					continue
				}
				thisCert, err := x509.ParseCertificate(certDER.Bytes)
				if err != nil {
					continue
				}
				intermediates.AddCert(thisCert)
				toFetch = append(toFetch, thisCert.IssuingCertificateURL...)
			}
		} else {
			// Hopefully it's DER.
			thisCert, err := x509.ParseCertificate(fetchedCert)
			if err != nil {
				continue
			}
			intermediates.AddCert(thisCert)
			toFetch = append(toFetch, thisCert.IssuingCertificateURL...)
		}
	}

	_, err = cert.Verify(x509.VerifyOptions{Intermediates: intermediates})
	if err == nil {
		return true
	}
	if _, ok := err.(x509.UnknownAuthorityError); !ok {
		// There was an error, but not because the certificate wasn't signed
		// by a recognized CA. So we go ahead and use the cert and let
		// the client experience the same error.
		return true
	}
	return false
}