From dc4e3331cfd7236548a41934d6cc75af7e317b37 Mon Sep 17 00:00:00 2001 From: zhengyangliu Date: Tue, 17 Dec 2024 21:50:29 +0000 Subject: [PATCH] serverca: expand signed cert and cert chain PEMs with multiple cert blocks inside --- security/pkg/server/ca/server.go | 16 +++++++++++++--- security/pkg/server/ca/server_test.go | 12 ++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/security/pkg/server/ca/server.go b/security/pkg/server/ca/server.go index 89b96b190954..0c9bdd6cfc53 100644 --- a/security/pkg/server/ca/server.go +++ b/security/pkg/server/ca/server.go @@ -16,6 +16,7 @@ package ca import ( "context" + "strings" "time" "google.golang.org/grpc" @@ -140,11 +141,20 @@ func (s *Server) CreateCertificate(ctx context.Context, request *pb.IstioCertifi if len(rootCertBytes) != 0 { respCertChain = append(respCertChain, string(rootCertBytes)) } - response := &pb.IstioCertificateResponse{ - CertChain: respCertChain, + + // expanded `respCertChain` since each element might be a concatenated multi-cert PEM + // the expanded structure (one cert per `string` in `certChain`) is specifically expected by `ztunnel` + response := &pb.IstioCertificateResponse{} + for _, pem := range respCertChain { + for _, cert := range strings.SplitAfter(pem, "-----END CERTIFICATE-----") { + if trimmed := strings.TrimSpace(cert); trimmed != "" { + response.CertChain = append(response.CertChain, trimmed) + } + } } + serverCaLog.Debugf("Responding with cert chain, %q", response.CertChain) s.monitoring.Success.Increment() - serverCaLog.Debugf("CSR successfully signed, sans %v.", caller.Identities) + serverCaLog.Debugf("CSR successfully signed, sans %v.", sans) return response, nil } diff --git a/security/pkg/server/ca/server_test.go b/security/pkg/server/ca/server_test.go index 21d0711c1bdd..6eb853f7775e 100644 --- a/security/pkg/server/ca/server_test.go +++ b/security/pkg/server/ca/server_test.go @@ -243,6 +243,18 @@ func TestCreateCertificate(t *testing.T) { certChain: []string{"cert", "cert_chain", "root_cert"}, code: codes.OK, }, + "Successful signing w/ multi-cert chain": { + authenticators: []security.Authenticator{&mockAuthenticator{identities: []string{"test-identity"}}}, + ca: &mockca.FakeCA{ + SignedCert: []byte("cert"), + KeyCertBundle: util.NewKeyCertBundleFromPem(nil, nil, + []byte("cert_chain1-----END CERTIFICATE-----\ncert_chain2-----END CERTIFICATE-----\n"), + []byte("root_cert"), + ), + }, + certChain: []string{"cert", "cert_chain1-----END CERTIFICATE-----", "cert_chain2-----END CERTIFICATE-----", "root_cert"}, + code: codes.OK, + }, } p := &peer.Peer{Addr: &net.IPAddr{IP: net.IPv4(192, 168, 1, 1)}, AuthInfo: credentials.TLSInfo{}}