Skip to content

Commit

Permalink
Update pki issuer target secret output to include ca cert and chain
Browse files Browse the repository at this point in the history
  • Loading branch information
dangtony98 committed Sep 10, 2024
1 parent c2030ef commit af1cecd
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 31 deletions.
14 changes: 1 addition & 13 deletions build/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,6 @@ spec:
description: IssuerSpec defines the desired state of Issuer
properties:
authentication:
description: |-
A reference to a Secret in the same namespace as the referent. If the
referent is a ClusterIssuer, the reference instead refers to the resource
with the given name in the configured 'cluster resource namespace', which
is set as a flag on the controller component (and defaults to the
namespace that the controller runs in).
properties:
universalAuth:
properties:
Expand Down Expand Up @@ -182,12 +176,6 @@ spec:
description: IssuerSpec defines the desired state of Issuer
properties:
authentication:
description: |-
A reference to a Secret in the same namespace as the referent. If the
referent is a ClusterIssuer, the reference instead refers to the resource
with the given name in the configured 'cluster resource namespace', which
is set as a flag on the controller component (and defaults to the
namespace that the controller runs in).
properties:
universalAuth:
properties:
Expand Down Expand Up @@ -600,7 +588,7 @@ spec:
- --health-probe-bind-address=:8081
command:
- /manager
image: docker.io/infisical/pki-issuer:v0.1.1-2-gb384f71
image: docker.io/infisical/pki-issuer:v0.1.1-3-gc2030ef
livenessProbe:
httpGet:
path: /healthz
Expand Down
2 changes: 1 addition & 1 deletion build/kustomize/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ resources:
images:
- name: controller
newName: docker.io/infisical/pki-issuer
newTag: v0.1.1-2-gb384f71
newTag: v0.1.1-3-gc2030ef
5 changes: 3 additions & 2 deletions internal/controller/certificaterequest_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,13 @@ func (r *CertificateRequestReconciler) Reconcile(ctx context.Context, req ctrl.R
return ctrl.Result{}, fmt.Errorf("%w: %v", errSignerBuilder, err)
}

signed, err := signer.Sign(certificateRequest)
pem, ca, err := signer.Sign(certificateRequest)
if err != nil {
return ctrl.Result{}, fmt.Errorf("%w: %v", errSignerSign, err)
}

certificateRequest.Status.Certificate = signed
certificateRequest.Status.Certificate = pem
certificateRequest.Status.CA = ca

report(cmapi.CertificateRequestReasonIssued, "Signed", nil)
return ctrl.Result{}, nil
Expand Down
49 changes: 34 additions & 15 deletions internal/issuer/signer/signer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package signer

import (
"bytes"
"encoding/pem"
"fmt"
"time"
Expand All @@ -17,7 +18,7 @@ type HealthChecker interface {
type HealthCheckerBuilder func(*v1alpha1.IssuerSpec, map[string][]byte) (HealthChecker, error)

type Signer interface {
Sign(certmanager.CertificateRequest) ([]byte, error)
Sign(certmanager.CertificateRequest) ([]byte, []byte, error)
}

type SignerBuilder func(*v1alpha1.IssuerSpec, map[string][]byte) (Signer, error)
Expand Down Expand Up @@ -82,7 +83,6 @@ type AuthResponse struct {
TokenType string `json:"tokenType"`
}

// NOTE (dangtony98): Add support for certificate template in the future
type SignCertificateRequest struct {
CaId string `json:"caId,omitempty"`
CertificateTemplateId string `json:"certificateTemplateId,omitempty"`
Expand All @@ -97,11 +97,11 @@ type SignCertificateResponse struct {
SerialNumber string `json:"serialNumber"`
}

func (o *signer) Sign(cr certmanager.CertificateRequest) ([]byte, error) {
func (o *signer) Sign(cr certmanager.CertificateRequest) ([]byte, []byte, error) {

// Ensure either caId or certificateTemplateId is provided
if o.caId == "" && o.certificateTemplateId == "" {
return nil, fmt.Errorf("Either caId or certificateTemplateId must be provided")
return nil, nil, fmt.Errorf("Either caId or certificateTemplateId must be provided")
}

csrBytes := cr.Spec.Request
Expand All @@ -127,7 +127,7 @@ func (o *signer) Sign(cr certmanager.CertificateRequest) ([]byte, error) {

// Check for errors
if err != nil {
return nil, err
return nil, nil, err
}

// Define the request body based on your CSR
Expand Down Expand Up @@ -155,16 +155,35 @@ func (o *signer) Sign(cr certmanager.CertificateRequest) ([]byte, error) {
SetResult(&signCertificateResponse).
Post(o.siteUrl + "/api/v1/pki/certificates/sign-certificate")

certificate := signCertificateResponse.Certificate
certificate := signCertificateResponse.Certificate // Leaf certificate
chainPem := signCertificateResponse.CertificateChain // Full chain (intermediate certs + root cert)

block, _ := pem.Decode([]byte(certificate))
pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: block.Bytes,
})
caChainCerts, rootCACert, err := splitRootCACertificate([]byte(chainPem))
certPem := []byte(certificate + "\n")
certPem = append(certPem, caChainCerts...)

return pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: block.Bytes,
}), nil
return certPem, rootCACert, nil
}

func splitRootCACertificate(caCertChainPem []byte) ([]byte, []byte, error) {
var caChainCerts []byte
var rootCACert []byte
for {
block, rest := pem.Decode(caCertChainPem)
if block == nil || block.Type != "CERTIFICATE" {
return nil, nil, fmt.Errorf("failed to read certificate")
}
var encBuf bytes.Buffer
if err := pem.Encode(&encBuf, block); err != nil {
return nil, nil, err
}
if len(rest) > 0 {
caChainCerts = append(caChainCerts, encBuf.Bytes()...)
caCertChainPem = rest
} else {
rootCACert = append(rootCACert, encBuf.Bytes()...)
break
}
}
return caChainCerts, rootCACert, nil
}

0 comments on commit af1cecd

Please sign in to comment.