// CERT returns a listener which contans tls.Config with the provided certificate, use for ssl.
162187
func CERT(addr string, cert tls.Certificate) (net.Listener, error) {
	l, err := net.Listen("tcp", addr)
	if err != nil {
		return nil, err
	}
	tlsConfig := &tls.Config{
		Certificates:             []tls.Certificate{cert},
		PreferServerCipherSuites: true,
	}
	return tls.NewListener(l, tlsConfig), nil
}
1124336
func sslClientCertificates(tlsConf *tls.Config, o values) {
	sslkey := o.Get("sslkey")
	sslcert := o.Get("sslcert")

	var cinfo, kinfo os.FileInfo
	var err error

	if sslcert != "" && sslkey != "" {
		// Check that both files exist. Note that we don't do any more extensive
		// checks than this (such as checking that the paths aren't directories);
		// LoadX509KeyPair() will take care of the rest.
		cinfo, err = os.Stat(sslcert)
		if err != nil {
			panic(err)
		}

		kinfo, err = os.Stat(sslkey)
		if err != nil {
			panic(err)
		}
	} else {
		// Automatically find certificates from ~/.postgresql
		sslcert, sslkey, cinfo, kinfo = sslHomeCertificates()

		if cinfo == nil || kinfo == nil {
			// No certificates to load
			return
		}
	}

	// The files must also have the correct permissions
	sslCertificatePermissions(cinfo, kinfo)

	cert, err := tls.LoadX509KeyPair(sslcert, sslkey)
	if err != nil {
		panic(err)
	}
	tlsConf.Certificates = []tls.Certificate{cert}
}
263273
func (cfg *TLSConfig) TLSCert() (*x509.Certificate, bool, error) {

	block, _ := pem.Decode(cfg.bytes)

	if block != nil {
		pub, err := x509.ParseCertificate(block.Bytes)
		if err != nil {
			return nil, false, errors.Wrap(err, "certificate parsing failed")
		}

		return pub, true, nil
	}

	//no cert found and there is no error
	return nil, false, nil
}
508680
func (srv *Server) ListenTLS(certFile, keyFile string) (net.Listener, error) {
	// Create the listener ourselves so we can control its lifetime
	addr := srv.Addr
	if addr == "" {
		addr = ":https"
	}

	config := &tls.Config{}
	if srv.TLSConfig != nil {
		*config = *srv.TLSConfig
	}

	var err error
	if certFile != "" && keyFile != "" {
		config.Certificates = make([]tls.Certificate, 1)
		config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
		if err != nil {
			return nil, err
		}
	}

	// Enable http2
	enableHTTP2ForTLSConfig(config)

	conn, err := srv.newTCPListener(addr)
	if err != nil {
		return nil, err
	}

	srv.TLSConfig = config

	tlsListener := tls.NewListener(conn, config)
	return tlsListener, nil
}
850497
func CertInfo(cert *x509.Certificate) string {
	return fmt.Sprintf("cert(%v issued by %v:%v)", cert.Subject.CommonName, cert.Issuer.CommonName, cert.Issuer.SerialNumber)
}
126158
func (c *Certificate) Type() string {
	algo, ok := certAlgoNames[c.Key.Type()]
	if !ok {
		panic("unknown cert key type")
	}
	return algo
}
126792
func TLSConfig(cert *x509.Certificate, serverName string, config fab.EndpointConfig) (*tls.Config, error) {

	if cert != nil {
		config.TLSCACertPool().Add(cert)
	}

	certPool, err := config.TLSCACertPool().Get()
	if err != nil {
		return nil, err
	}
	return &tls.Config{RootCAs: certPool, Certificates: config.TLSClientCerts(), ServerName: serverName}, nil
}
877010
func (c *Certificate) Validate() error {
	if len(c.CertPEM) == 0 {
		return errors.NotValidf("missing cert PEM")
	}
	if len(c.KeyPEM) == 0 {
		return errors.NotValidf("missing key PEM")
	}
	return nil
}
1140354
func CertAdd(cert, key, commonName, sans string) error {
	c, err := client.New()

	if err != nil {
		return err
	}

	fmt.Print("Adding SSL endpoint... ")
	quit := progress()
	err = processCertsAdd(c, cert, key, commonName, sans)
	quit <- true
	<-quit

	if err != nil {
		return err
	}

	fmt.Println("done")
	return nil
}
1123232
func (c *Endpoint) tlsConfig() (*tls.Config, error) {
	if c.TLSData == nil && !c.SkipTLSVerify {
		// there is no specific tls config
		return nil, nil
	}
	var tlsOpts []func(*tls.Config)
	if c.TLSData != nil && c.TLSData.CA != nil {
		certPool := x509.NewCertPool()
		if !certPool.AppendCertsFromPEM(c.TLSData.CA) {
			return nil, errors.New("failed to retrieve context tls info: ca.pem seems invalid")
		}
		tlsOpts = append(tlsOpts, func(cfg *tls.Config) {
			cfg.RootCAs = certPool
		})
	}
	if c.TLSData != nil && c.TLSData.Key != nil && c.TLSData.Cert != nil {
		keyBytes := c.TLSData.Key
		pemBlock, _ := pem.Decode(keyBytes)
		if pemBlock == nil {
			return nil, fmt.Errorf("no valid private key found")
		}

		var err error
		if x509.IsEncryptedPEMBlock(pemBlock) {
			keyBytes, err = x509.DecryptPEMBlock(pemBlock, []byte(c.TLSPassword))
			if err != nil {
				return nil, errors.Wrap(err, "private key is encrypted, but could not decrypt it")
			}
			keyBytes = pem.EncodeToMemory(&pem.Block{Type: pemBlock.Type, Bytes: keyBytes})
		}

		x509cert, err := tls.X509KeyPair(c.TLSData.Cert, keyBytes)
		if err != nil {
			return nil, errors.Wrap(err, "failed to retrieve context tls info")
		}
		tlsOpts = append(tlsOpts, func(cfg *tls.Config) {
			cfg.Certificates = []tls.Certificate{x509cert}
		})
	}
	if c.SkipTLSVerify {
		tlsOpts = append(tlsOpts, func(cfg *tls.Config) {
			cfg.InsecureSkipVerify = true
		})
	}
	return tlsconfig.ClientDefault(tlsOpts...), nil
}
334543
func initSelfSignedHTTPSCert(cfg *Config) (err error) {
	log.Warningf("No TLS Keys provided, using self signed certificate.")

	keyPath := filepath.Join(cfg.DataDir, defaults.SelfSignedKeyPath)
	certPath := filepath.Join(cfg.DataDir, defaults.SelfSignedCertPath)

	cfg.Proxy.TLSKey = keyPath
	cfg.Proxy.TLSCert = certPath

	// return the existing pair if they have already been generated:
	_, err = tls.LoadX509KeyPair(certPath, keyPath)
	if err == nil {
		return nil
	}
	if !os.IsNotExist(err) {
		return trace.Wrap(err, "unrecognized error reading certs")
	}
	log.Warningf("Generating self signed key and cert to %v %v.", keyPath, certPath)

	creds, err := utils.GenerateSelfSignedCert([]string{cfg.Hostname, "localhost"})
	if err != nil {
		return trace.Wrap(err)
	}

	if err := ioutil.WriteFile(keyPath, creds.PrivateKey, 0600); err != nil {
		return trace.Wrap(err, "error writing key PEM")
	}
	if err := ioutil.WriteFile(certPath, creds.Cert, 0600); err != nil {
		return trace.Wrap(err, "error writing key PEM")
	}
	return nil
}
944977
func (wfe *WebFrontEndImpl) Certificate(ctx context.Context, logEvent *web.RequestEvent, response http.ResponseWriter, request *http.Request) {
	var requesterAccount *core.Registration
	// Any POSTs to the Certificate endpoint should be POST-as-GET requests. There are
	// no POSTs with a body allowed for this endpoint.
	if request.Method == "POST" {
		acct, prob := wfe.validPOSTAsGETForAccount(request, ctx, logEvent)
		if prob != nil {
			wfe.sendError(response, logEvent, prob, nil)
			return
		}
		requesterAccount = acct
	}

	serial := request.URL.Path
	// Certificate paths consist of the CertBase path, plus exactly sixteen hex
	// digits.
	if !core.ValidSerial(serial) {
		wfe.sendError(
			response,
			logEvent,
			probs.NotFound("Certificate not found"),
			fmt.Errorf("certificate serial provided was not valid: %s", serial),
		)
		return
	}
	logEvent.Extra["RequestedSerial"] = serial

	cert, err := wfe.SA.GetCertificate(ctx, serial)
	// TODO(#991): handle db errors
	if err != nil {
		ierr := fmt.Errorf("unable to get certificate by serial id %#v: %s", serial, err)
		if strings.HasPrefix(err.Error(), "gorp: multiple rows returned") {
			wfe.sendError(response, logEvent, probs.Conflict("Multiple certificates with same short serial"), ierr)
		} else {
			wfe.sendError(response, logEvent, probs.NotFound("Certificate not found"), ierr)
		}
		return
	}

	// If there was a requesterAccount (e.g. because it was a POST-as-GET request)
	// then the requesting account must be the owner of the certificate, otherwise
	// return an unauthorized error.
	if requesterAccount != nil && requesterAccount.ID != cert.RegistrationID {
		wfe.sendError(response, logEvent, probs.Unauthorized("Account in use did not issue specified certificate"), nil)
		return
	}

	leafPEM := pem.EncodeToMemory(&pem.Block{
		Type:  "CERTIFICATE",
		Bytes: cert.DER,
	})

	var responsePEM []byte

	// If the WFE is configured with certificateChains, construct a chain for this
	// certificate using its AIA Issuer URL.
	if len(wfe.certificateChains) > 0 {
		parsedCert, err := x509.ParseCertificate(cert.DER)
		if err != nil {
			// If we can't parse one of our own certs there's a serious problem
			wfe.sendError(response, logEvent, probs.ServerInternal(
				fmt.Sprintf(
					"unable to parse Boulder issued certificate with serial %#v",
					serial),
			), err)
			return
		}

		// NOTE(@cpu): Boulder assumes there will only be **ONE** AIA issuer URL
		// configured in the CA signing profile. At present this is not enforced by
		// the CA, but should be. See
		//  https://github.com/letsencrypt/boulder/issues/3374
		aiaIssuerURL := parsedCert.IssuingCertificateURL[0]
		if chain, ok := wfe.certificateChains[aiaIssuerURL]; ok {
			// Prepend the chain with the leaf certificate
			responsePEM = append(leafPEM, chain...)
		} else {
			// If there is no wfe.certificateChains entry for the AIA Issuer URL there
			// is probably a misconfiguration and we should treat it as an internal
			// server error.
			wfe.sendError(response, logEvent, probs.ServerInternal(
				fmt.Sprintf(
					"Certificate serial %#v has an unknown AIA Issuer URL %q"+
						"- no PEM certificate chain associated.",
					serial,
					aiaIssuerURL),
			), nil)
			return
		}
	} else {
		// Otherwise, with no configured certificateChains just serve the leaf
		// certificate.
		responsePEM = leafPEM
	}

	// NOTE(@cpu): We must explicitly set the Content-Length header here. The Go
	// HTTP library will only add this header if the body is below a certain size
	// and with the addition of a PEM encoded certificate chain the body size of
	// this endpoint will exceed this threshold. Since we know the length we can
	// reliably set it ourselves and not worry.
	response.Header().Set("Content-Length", strconv.Itoa(len(responsePEM)))
	response.Header().Set("Content-Type", "application/pem-certificate-chain")
	response.WriteHeader(http.StatusOK)
	if _, err = response.Write(responsePEM); err != nil {
		wfe.log.Warningf("Could not write response: %s", err)
	}
	return
}
790487
func Listen(network, laddr string, config *Config) (net.Listener, error) {
	if config == nil || !config.ValidForServer() {
		return nil, errors.New("tls: neither Certificates nor GetCertificate set in Config")
	}
	l, err := net.Listen(network, laddr)
	if err != nil {
		return nil, err
	}
	return NewListener(l, config)
}
1340024
func (c *Config) KeyPair() (*tls.Certificate, error) {
	return loadKeyPair(c.CertFile, c.KeyFile)
}
1194615
func (ec *Envcfg) CertWait() time.Duration {
	if d := ec.GetDuration(ec.certWaitKey); d != 0 {
		return d
	}
	return DefaultCertWait
}
997988
func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) {
	if c.GetCertificate != nil &&
		(len(c.Certificates) == 0 || len(clientHello.ServerName) > 0) {
		cert, err := c.GetCertificate(clientHello)
		if cert != nil || err != nil {
			return cert, err
		}
	}

	if len(c.Certificates) == 0 {
		return nil, errors.New("crypto/tls: no certificates configured")
	}

	if len(c.Certificates) == 1 || c.NameToCertificate == nil {
		// There's only one choice, so no point doing any work.
		return &c.Certificates[0], nil
	}

	name := strings.ToLower(clientHello.ServerName)
	for len(name) > 0 && name[len(name)-1] == '.' {
		name = name[:len(name)-1]
	}

	if cert, ok := c.NameToCertificate[name]; ok {
		return cert, nil
	}

	// try replacing labels in the name with wildcards until we get a
	// match.
	labels := strings.Split(name, ".")
	for i := range labels {
		labels[i] = "*"
		candidate := strings.Join(labels, ".")
		if cert, ok := c.NameToCertificate[candidate]; ok {
			return cert, nil
		}
	}

	// If nothing matches, return the first certificate.
	return &c.Certificates[0], nil
}
797216
func partialVerify(certs []*x509.Certificate) bool {
	n := len(certs)
	if n == 0 {
		return false
	}
	for i := 0; i < n-1; i++ {
		if certs[i].CheckSignatureFrom(certs[i+1]) != nil {
			return false
		}
	}
	return true
}