// decodeCACert parses x509 pem-encoded certificate and checks it is a CA cert.
//
// Returns the decoded cert, as well as its der-encoded representation.
187139
func decodeCACert(certPem string) (cert *x509.Certificate, certDer []byte, err error) {
	certDer, err = utils.ParsePEM(certPem, "CERTIFICATE")
	if err != nil {
		return nil, nil, fmt.Errorf("bad PEM - %s", err)
	}
	switch cert, err = x509.ParseCertificate(certDer); {
	case err != nil:
		return nil, nil, fmt.Errorf("bad cert - %s", err)
	case !cert.IsCA:
		return nil, nil, fmt.Errorf("not a CA cert")
	default:
		return cert, certDer, nil
	}
}
762573
func validateCertificatePEM(certPEM string, options *x509.VerifyOptions) ([]*x509.Certificate, error) {
	certs, err := cert.ParseCertsPEM([]byte(certPEM))
	if err != nil {
		return nil, err
	}

	if len(certs) < 1 {
		return nil, fmt.Errorf("invalid/empty certificate data")
	}

	if options != nil {
		// Ensure we don't report errors for expired certs or if
		// the validity is in the future.
		// Not that this can be for the actual certificate or any
		// intermediates in the CA chain. This allows the router to
		// still serve an expired/valid-in-the-future certificate
		// and lets the client to control if it can tolerate that
		// (just like for self-signed certs).
		_, err = certs[0].Verify(*options)
		if err != nil {
			if invalidErr, ok := err.(x509.CertificateInvalidError); !ok || invalidErr.Reason != x509.Expired {
				return certs, fmt.Errorf("error verifying certificate: %s", err.Error())
			}
		}
	}

	return certs, nil
}
1170442
func GetPublicKeyFromCert(cert []byte, cs core.CryptoSuite) (core.Key, error) {

	dcert, _ := pem.Decode(cert)
	if dcert == nil {
		return nil, errors.Errorf("Unable to decode cert bytes [%v]", cert)
	}

	x509Cert, err := x509.ParseCertificate(dcert.Bytes)
	if err != nil {
		return nil, errors.Errorf("Unable to parse cert from decoded bytes: %s", err)
	}

	// get the public key in the right format
	key, err := cs.KeyImport(x509Cert, factory.GetX509PublicKeyImportOpts(true))
	if err != nil {
		return nil, errors.WithMessage(err, "Failed to import certificate's public key")
	}

	return key, nil
}
240171
func (a *State) CACert() (string, error) {
	var result params.BytesResult
	err := a.facade.FacadeCall("CACert", nil, &result)
	if err != nil {
		return "", err
	}
	return string(result.Result), nil
}
525131
func LoadCert(path string) (cert []byte, err error) {
	if path == "" {
		err = errors.New("Issuer certificate was not provided in config.")
		return
	}
	pemBytes, err := ioutil.ReadFile(path)
	if err != nil {
		return
	}

	block, _ := pem.Decode(pemBytes)
	if block == nil || block.Type != "CERTIFICATE" {
		err = errors.New("Invalid certificate value returned")
		return
	}

	cert = block.Bytes
	return
}
565963
func Decode(pfxData []byte, password string) (privateKey interface{}, certificate *x509.Certificate, err error) {
	encodedPassword, err := bmpString(password)
	if err != nil {
		return nil, nil, err
	}

	bags, encodedPassword, err := getSafeContents(pfxData, encodedPassword)
	if err != nil {
		return nil, nil, err
	}

	if len(bags) != 2 {
		err = errors.New("pkcs12: expected exactly two safe bags in the PFX PDU")
		return
	}

	for _, bag := range bags {
		switch {
		case bag.Id.Equal(oidCertBag):
			if certificate != nil {
				err = errors.New("pkcs12: expected exactly one certificate bag")
			}

			certsData, err := decodeCertBag(bag.Value.Bytes)
			if err != nil {
				return nil, nil, err
			}
			certs, err := x509.ParseCertificates(certsData)
			if err != nil {
				return nil, nil, err
			}
			if len(certs) != 1 {
				err = errors.New("pkcs12: expected exactly one certificate in the certBag")
				return nil, nil, err
			}
			certificate = certs[0]

		case bag.Id.Equal(oidPKCS8ShroudedKeyBag):
			if privateKey != nil {
				err = errors.New("pkcs12: expected exactly one key bag")
			}
			if privateKey, err = decodePkcs8ShroudedKeyBag(bag.Value.Bytes, encodedPassword); err != nil {
				return nil, nil, err
			}
		}
	}

	if certificate == nil {
		return nil, nil, errors.New("pkcs12: certificate missing")
	}
	if privateKey == nil {
		return nil, nil, errors.New("pkcs12: private key missing")
	}

	return
}
417708
func ReadCertificateChain(certificateChainBytes []byte) ([]*x509.Certificate, error) {
	// build the certificate chain next
	var certificateBlock *pem.Block
	var remainingBytes []byte = bytes.TrimSpace(certificateChainBytes)
	var certificateChain [][]byte

	for {
		certificateBlock, remainingBytes = pem.Decode(remainingBytes)
		if certificateBlock == nil || certificateBlock.Type != pemBlockCertificate {
			return nil, trace.NotFound("no PEM data found")
		}
		certificateChain = append(certificateChain, certificateBlock.Bytes)

		if len(remainingBytes) == 0 {
			break
		}
	}

	// build a concatenated certificate chain
	var buf bytes.Buffer
	for _, cc := range certificateChain {
		_, err := buf.Write(cc)
		if err != nil {
			return nil, trace.Wrap(err)
		}
	}

	// parse the chain and get a slice of x509.Certificates.
	x509Chain, err := x509.ParseCertificates(buf.Bytes())
	if err != nil {
		return nil, trace.Wrap(err)
	}

	return x509Chain, nil
}
790710
func ReadCertificate(in []byte) (cert *x509.Certificate, rest []byte, err error) {
	if len(in) == 0 {
		err = errors.New("lib: empty certificate")
		return
	}

	if in[0] == '-' {
		p, remaining := pem.Decode(in)
		if p == nil {
			err = errors.New("lib: invalid PEM file")
			return
		}

		rest = remaining
		if p.Type != "CERTIFICATE" {
			err = fmt.Errorf("lib: expected a CERTIFICATE PEM file, but have %s", p.Type)
			return
		}

		in = p.Bytes
	}

	cert, err = x509.ParseCertificate(in)
	return
}
828531
func ParseCSR(obj *CertificateSigningRequest) (*x509.CertificateRequest, error) {
	// extract PEM from request object
	pemBytes := obj.Spec.Request
	block, _ := pem.Decode(pemBytes)
	if block == nil || block.Type != "CERTIFICATE REQUEST" {
		return nil, errors.New("PEM block type must be CERTIFICATE REQUEST")
	}
	csr, err := x509.ParseCertificateRequest(block.Bytes)
	if err != nil {
		return nil, err
	}
	return csr, nil
}
301732
func DecodeUint(b []byte) ([]byte, uint64, error) {
	if len(b) < 8 {
		return nil, 0, errors.New("insufficient bytes to decode value")
	}

	v := binary.BigEndian.Uint64(b[:8])
	b = b[8:]
	return b, v, nil
}
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
}
903589
func ParsePEMCertificate(cert []byte) (*x509.Certificate, error) {
	pemBlock, err := pemDecode(cert)
	if pemBlock == nil {
		return nil, err
	}

	// from a DER encoded certificate
	return x509.ParseCertificate(pemBlock.Bytes)
}
755099
func (dec *Decoder) DecodeUint64(v *uint64) error {
	if dec.isPooled == 1 {
		panic(InvalidUsagePooledDecoderError("Invalid usage of pooled decoder"))
	}
	return dec.decodeUint64(v)
}
363333
func pemToX509Certs(pemCerts []byte) ([]*x509.Certificate, []string, error) {

	//it's possible that multiple certs are encoded
	certs := []*x509.Certificate{}
	subjects := []string{}
	for len(pemCerts) > 0 {
		var block *pem.Block
		block, pemCerts = pem.Decode(pemCerts)
		if block == nil {
			break
		}
		/** TODO: check why msp does not add type to PEM header
		if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
			continue
		}
		*/

		cert, err := x509.ParseCertificate(block.Bytes)
		if err != nil {
			return nil, subjects, err
		} else {
			certs = append(certs, cert)
			//extract and append the subject
			subjects = append(subjects, string(cert.RawSubject))
		}
	}
	return certs, subjects, nil
}
459412
func ParseCertificatePEM(certPEM []byte) (*Certificate, error) {
	cert, err := helpers.ParseCertificatePEM(certPEM)
	if err != nil {
		return nil, err
	}

	return ParseCertificate(cert), nil
}
1052677
func PrintCert(key, csrBytes, cert []byte) {
	out := map[string]string{}
	if cert != nil {
		out["cert"] = string(cert)
	}

	if key != nil {
		out["key"] = string(key)
	}

	if csrBytes != nil {
		out["csr"] = string(csrBytes)
	}

	jsonOut, err := json.Marshal(out)
	if err != nil {
		return
	}
	fmt.Printf("%s\n", jsonOut)
}
1205994
func (cp *Connect) Decode(src []byte) (int, error) {
	total := 0

	// decode header
	hl, _, _, err := headerDecode(src[total:], CONNECT)
	total += hl
	if err != nil {
		return total, err
	}

	// read protocol string
	protoName, n, err := readLPBytes(src[total:], false, cp.Type())
	total += n
	if err != nil {
		return total, err
	}

	// check buffer length
	if len(src) < total+1 {
		return total, makeError(cp.Type(), "insufficient buffer size, expected %d, got %d", total+1, len(src))
	}

	// read version
	versionByte := src[total]
	total++

	// check protocol string and version
	if versionByte != Version311 && versionByte != Version31 {
		return total, makeError(cp.Type(), "invalid protocol version (%d)", versionByte)
	}

	// set version
	cp.Version = versionByte

	// check protocol version string
	if !bytes.Equal(protoName, version311Name) && !bytes.Equal(protoName, version31Name) {
		return total, makeError(cp.Type(), "invalid protocol version description (%s)", protoName)
	}

	// check buffer length
	if len(src) < total+1 {
		return total, makeError(cp.Type(), "insufficient buffer size, expected %d, got %d", total+1, len(src))
	}

	// read connect flags
	connectFlags := src[total]
	total++

	// read flags
	usernameFlag := ((connectFlags >> 7) & 0x1) == 1
	passwordFlag := ((connectFlags >> 6) & 0x1) == 1
	willFlag := ((connectFlags >> 2) & 0x1) == 1
	willRetain := ((connectFlags >> 5) & 0x1) == 1
	willQOS := QOS((connectFlags >> 3) & 0x3)
	cp.CleanSession = ((connectFlags >> 1) & 0x1) == 1

	// check reserved bit
	if connectFlags&0x1 != 0 {
		return total, makeError(cp.Type(), "reserved bit 0 is not 0")
	}

	// check will qos
	if !willQOS.Successful() {
		return total, makeError(cp.Type(), "invalid QOS level (%d) for will message", willQOS)
	}

	// check will flags
	if !willFlag && (willRetain || willQOS != 0) {
		return total, makeError(cp.Type(), "if the will flag is set to 0 the will qos and will retain fields must be set to zero")
	}

	// create will if present
	if willFlag {
		cp.Will = &Message{QOS: willQOS, Retain: willRetain}
	}

	// check auth flags
	if !usernameFlag && passwordFlag {
		return total, makeError(cp.Type(), "password flag is set but username flag is not set")
	}

	// check buffer length
	if len(src) < total+2 {
		return total, makeError(cp.Type(), "insufficient buffer size, expected %d, got %d", total+2, len(src))
	}

	// read keep alive
	cp.KeepAlive = binary.BigEndian.Uint16(src[total:])
	total += 2

	// read client id
	cp.ClientID, n, err = readLPString(src[total:], cp.Type())
	total += n
	if err != nil {
		return total, err
	}

	// if the client supplies a zero-byte clientID, the client must also set CleanSession to 1
	if len(cp.ClientID) == 0 && !cp.CleanSession {
		return total, makeError(cp.Type(), "clean session must be 1 if client id is zero length")
	}

	// read will topic and payload
	if cp.Will != nil {
		cp.Will.Topic, n, err = readLPString(src[total:], cp.Type())
		total += n
		if err != nil {
			return total, err
		}

		cp.Will.Payload, n, err = readLPBytes(src[total:], true, cp.Type())
		total += n
		if err != nil {
			return total, err
		}
	}

	// read username
	if usernameFlag {
		cp.Username, n, err = readLPString(src[total:], cp.Type())
		total += n
		if err != nil {
			return total, err
		}
	}

	// read password
	if passwordFlag {
		cp.Password, n, err = readLPString(src[total:], cp.Type())
		total += n
		if err != nil {
			return total, err
		}
	}

	return total, nil
}