11package signer
22
33import (
4+ "bytes"
45 "encoding/pem"
56 "fmt"
67 "time"
@@ -17,7 +18,7 @@ type HealthChecker interface {
1718type HealthCheckerBuilder func (* v1alpha1.IssuerSpec , map [string ][]byte ) (HealthChecker , error )
1819
1920type Signer interface {
20- Sign (certmanager.CertificateRequest ) ([]byte , error )
21+ Sign (certmanager.CertificateRequest ) ([]byte , [] byte , error )
2122}
2223
2324type SignerBuilder func (* v1alpha1.IssuerSpec , map [string ][]byte ) (Signer , error )
@@ -82,7 +83,6 @@ type AuthResponse struct {
8283 TokenType string `json:"tokenType"`
8384}
8485
85- // NOTE (dangtony98): Add support for certificate template in the future
8686type SignCertificateRequest struct {
8787 CaId string `json:"caId,omitempty"`
8888 CertificateTemplateId string `json:"certificateTemplateId,omitempty"`
@@ -97,11 +97,11 @@ type SignCertificateResponse struct {
9797 SerialNumber string `json:"serialNumber"`
9898}
9999
100- func (o * signer ) Sign (cr certmanager.CertificateRequest ) ([]byte , error ) {
100+ func (o * signer ) Sign (cr certmanager.CertificateRequest ) ([]byte , [] byte , error ) {
101101
102102 // Ensure either caId or certificateTemplateId is provided
103103 if o .caId == "" && o .certificateTemplateId == "" {
104- return nil , fmt .Errorf ("Either caId or certificateTemplateId must be provided" )
104+ return nil , nil , fmt .Errorf ("Either caId or certificateTemplateId must be provided" )
105105 }
106106
107107 csrBytes := cr .Spec .Request
@@ -127,7 +127,7 @@ func (o *signer) Sign(cr certmanager.CertificateRequest) ([]byte, error) {
127127
128128 // Check for errors
129129 if err != nil {
130- return nil , err
130+ return nil , nil , err
131131 }
132132
133133 // Define the request body based on your CSR
@@ -155,16 +155,35 @@ func (o *signer) Sign(cr certmanager.CertificateRequest) ([]byte, error) {
155155 SetResult (& signCertificateResponse ).
156156 Post (o .siteUrl + "/api/v1/pki/certificates/sign-certificate" )
157157
158- certificate := signCertificateResponse .Certificate
158+ certificate := signCertificateResponse .Certificate // Leaf certificate
159+ chainPem := signCertificateResponse .CertificateChain // Full chain (intermediate certs + root cert)
159160
160- block , _ := pem .Decode ([]byte (certificate ))
161- pem .EncodeToMemory (& pem.Block {
162- Type : "CERTIFICATE" ,
163- Bytes : block .Bytes ,
164- })
161+ caChainCerts , rootCACert , err := splitRootCACertificate ([]byte (chainPem ))
162+ certPem := []byte (certificate + "\n " )
163+ certPem = append (certPem , caChainCerts ... )
165164
166- return pem .EncodeToMemory (& pem.Block {
167- Type : "CERTIFICATE" ,
168- Bytes : block .Bytes ,
169- }), nil
165+ return certPem , rootCACert , nil
166+ }
167+
168+ func splitRootCACertificate (caCertChainPem []byte ) ([]byte , []byte , error ) {
169+ var caChainCerts []byte
170+ var rootCACert []byte
171+ for {
172+ block , rest := pem .Decode (caCertChainPem )
173+ if block == nil || block .Type != "CERTIFICATE" {
174+ return nil , nil , fmt .Errorf ("failed to read certificate" )
175+ }
176+ var encBuf bytes.Buffer
177+ if err := pem .Encode (& encBuf , block ); err != nil {
178+ return nil , nil , err
179+ }
180+ if len (rest ) > 0 {
181+ caChainCerts = append (caChainCerts , encBuf .Bytes ()... )
182+ caCertChainPem = rest
183+ } else {
184+ rootCACert = append (rootCACert , encBuf .Bytes ()... )
185+ break
186+ }
187+ }
188+ return caChainCerts , rootCACert , nil
170189}
0 commit comments