github.com/lestrrat-go/jwx/v2@v2.0.21/cert/cert.go (about)

     1  package cert
     2  
     3  import (
     4  	"crypto/x509"
     5  	stdlibb64 "encoding/base64"
     6  	"fmt"
     7  	"io"
     8  
     9  	"github.com/lestrrat-go/jwx/v2/internal/base64"
    10  )
    11  
    12  // Create is a wrapper around x509.CreateCertificate, but it additionally
    13  // encodes it in base64 so that it can be easily added to `x5c` fields
    14  func Create(rand io.Reader, template, parent *x509.Certificate, pub, priv interface{}) ([]byte, error) {
    15  	der, err := x509.CreateCertificate(rand, template, parent, pub, priv)
    16  	if err != nil {
    17  		return nil, fmt.Errorf(`failed to create x509 certificate: %w`, err)
    18  	}
    19  	return EncodeBase64(der)
    20  }
    21  
    22  // EncodeBase64 is a utility function to encode ASN.1 DER certificates
    23  // using base64 encoding. This operation is normally done by `pem.Encode`
    24  // but since PEM would include the markers (`-----BEGIN`, and the like)
    25  // while `x5c` fields do not need this, this function can be used to
    26  // shave off a few lines
    27  func EncodeBase64(der []byte) ([]byte, error) {
    28  	enc := stdlibb64.StdEncoding
    29  	dst := make([]byte, enc.EncodedLen(len(der)))
    30  	enc.Encode(dst, der)
    31  	return dst, nil
    32  }
    33  
    34  // Parse is a utility function to decode a base64 encoded
    35  // ASN.1 DER format certificate, and to parse the byte sequence.
    36  // The certificate must be in PKIX format, and it must not contain PEM markers
    37  func Parse(src []byte) (*x509.Certificate, error) {
    38  	dst, err := base64.Decode(src)
    39  	if err != nil {
    40  		return nil, fmt.Errorf(`failed to base64 decode the certificate: %w`, err)
    41  	}
    42  
    43  	cert, err := x509.ParseCertificate(dst)
    44  	if err != nil {
    45  		return nil, fmt.Errorf(`failed to parse x509 certificate: %w`, err)
    46  	}
    47  	return cert, nil
    48  }