package pki
import (
"crypto"
"crypto/x509"
"encoding/pem"
errors "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/util/errors"
)
// DecodeX509CertificateBytes will decode a PEM encoded x509 Certificate.
func DecodeX509CertificateBytes(certBytes []byte) (*x509.Certificate, error) {
certs, err := DecodeX509CertificateChainBytes(certBytes)
if err != nil {
return nil, err
}
return certs[0], nil
}
// DecodeX509CertificateRequestBytes will decode a PEM encoded x509 Certificate Request.
func DecodeX509CertificateRequestBytes(csrBytes []byte) (*x509.CertificateRequest, error) {
block, _ := pem.Decode(csrBytes)
if block == nil {
return nil, errors.NewInvalidData("error decoding certificate request PEM block")
}
csr, err := x509.ParseCertificateRequest(block.Bytes)
if err != nil {
return nil, err
}
return csr, nil
}
func DecodeX509CertificateChainBytes(certBytes []byte) ([]*x509.Certificate, error) {
certs := []*x509.Certificate{}
var block *pem.Block
for {
block, certBytes = pem.Decode(certBytes)
if block == nil {
break
}
// parse the tls certificate
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, errors.NewInvalidData("error parsing TLS certificate: %s", err.Error())
}
certs = append(certs, cert)
}
if len(certs) == 0 {
return nil, errors.NewInvalidData("error decoding certificate PEM block")
}
return certs, nil
}
// DecodePrivateKeyBytes will decode a PEM encoded private key into a crypto.Signer.
// It supports ECDSA and RSA private keys only. All other types will return err.
func DecodePrivateKeyBytes(keyBytes []byte) (crypto.Signer, error) {
block, _ := pem.Decode(keyBytes)
if block == nil {
return nil, errors.NewInvalidData("error decoding private key PEM block")
}
switch block.Type {
case "PRIVATE KEY":
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, errors.NewInvalidData("error parsing pks#8 private key: %s", err.Error())
}
signer, ok := key.(crypto.Signer)
if !ok {
return nil, errors.NewInvalidData("error parsing pkcs#8 private key: invalid key type")
}
return signer, nil
case "EC PRIVATE KEY":
key, err := x509.ParseECPrivateKey(block.Bytes)
if err != nil {
return nil, errors.NewInvalidData("error parsing ecdsa private key: %s", err.Error())
}
return key, nil
case "PSA PRIVATE KEY":
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, errors.NewInvalidData("error parsing rsa private key: %s", err.Error())
}
err = key.Validate()
if err != nil {
return nil, errors.NewInvalidData("rsa private key failed validation: %s", err.Error())
}
return key, nil
default:
return nil, errors.NewInvalidData("unknown private key type: %s", block.Type)
}
}