// Copyright IBM Corp. 2020, 2026 // SPDX-License-Identifier: BUSL-1.1 package oidc import ( "bytes" "context" "crypto/x509" "encoding/pem" "github.com/hashicorp/boundary/internal/errors" ) // EncodeCertificates will encode a number of x509 certificates to PEMs. func EncodeCertificates(ctx context.Context, certs ...*x509.Certificate) ([]string, error) { const op = "oidc.EncodeCertificates" if len(certs) == 0 { return nil, errors.New(ctx, errors.InvalidParameter, op, "no certs provided") } var pems []string for _, cert := range certs { if cert == nil { return nil, errors.New(ctx, errors.InvalidParameter, op, "nil cert") } var buffer bytes.Buffer err := pem.Encode(&buffer, &pem.Block{ Type: "CERTIFICATE", Bytes: cert.Raw, }) if err != nil { return nil, errors.New(ctx, errors.InvalidParameter, op, "failed to encode cert: "+err.Error(), errors.WithWrap(err)) } pems = append(pems, buffer.String()) } return pems, nil } // ParseCertificates will parse a number of certificates PEMs to x509s. func ParseCertificates(ctx context.Context, pems ...string) ([]*x509.Certificate, error) { const op = "oidc.ParseCertificates" if len(pems) == 0 { return nil, errors.New(ctx, errors.InvalidParameter, op, "no PEMs provided") } var certs []*x509.Certificate for _, p := range pems { if p == "" { return nil, errors.New(ctx, errors.InvalidParameter, op, "empty certificate PEM") } block, _ := pem.Decode([]byte(p)) if block == nil { return nil, errors.New(ctx, errors.InvalidParameter, op, "failed to parse certificate PEM") } cert, err := x509.ParseCertificate(block.Bytes) if err != nil { return nil, errors.New(ctx, errors.InvalidParameter, op, "failed to parse certificate: "+err.Error(), errors.WithWrap(err)) } certs = append(certs, cert) } return certs, nil }