Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions mgradm/shared/podman/ssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ func prepareThirdPartyCertificate(

// Create secrets for CA
return shared_podman.CreateTLSSecrets(
caSecretName, path.Join(tempDir, "ca.crt"),
certSecretName, path.Join(tempDir, "server.crt"),
caSecretName, caPath,
certSecretName, serverCertPath,
keySecretName, pair.Key,
)
}
Expand Down Expand Up @@ -468,6 +468,7 @@ func reuseExistingCertificatesFromMounts(
log.Info().Msgf(L("Certificate file %s not found."), crtCheckPath)
return false, nil
}
cert = ssl.StripTextFromCertificate(string(cert))
if err = os.WriteFile(serverCert, cert, 0444); err != nil {
return true, utils.Error(err, L("cannot write existing server certificate"))
}
Expand Down
69 changes: 46 additions & 23 deletions shared/ssl/ssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,28 +112,58 @@ func findServerCert(certs []certificate) (*certificate, error) {
return nil, errors.New(L("expected to find a certificate, got none"))
}

func readCertificates(path string) ([]certificate, error) {
fd, err := os.Open(path)
// processOpenSSL is the generic core that handles the piping logic.
func processOpenSSL(r io.Reader) ([][]byte, error) {
data, err := io.ReadAll(r)
if err != nil {
return []certificate{}, utils.Errorf(err, L("Failed to read certificate file %s"), path)
return nil, err
}

certs := []certificate{}
var results [][]byte
rest := data

for {
log.Debug().Msgf("Running openssl x509 on %s", path)
var block *pem.Block
block, rest = pem.Decode(rest)
if block == nil {
break // No more PEM blocks found
}

// Re-encode just this one block to pass to OpenSSL
singleCert := pem.EncodeToMemory(block)

cmd := exec.Command("openssl", "x509")
cmd.Stdin = fd
cmd.Stdin = bytes.NewReader(singleCert)
out, err := cmd.Output()
if err == nil && len(out) > 0 {
results = append(results, out)
}

if err != nil {
// openssl got an invalid certificate or the end of the file
if len(rest) == 0 {
break
}
}

return results, nil
}

// Extract data from the certificate
cert, err := extractCertificateData(out)
func readCertificates(path string) ([]certificate, error) {
fd, err := os.Open(path)
if err != nil {
return []certificate{}, utils.Errorf(err, L("Failed to read certificate file %s"), path)
}
defer fd.Close()

rawCerts, err := processOpenSSL(fd)
if err != nil {
return nil, err
}

var certs []certificate
for _, raw := range rawCerts {
cert, err := extractCertificateData(raw)
if err != nil {
return []certificate{}, err
return nil, err
}
certs = append(certs, cert)
}
Expand Down Expand Up @@ -336,19 +366,12 @@ func GetRsaKey(keyContent string, password string) []byte {

// StripTextFromCertificate removes the optional text part of an x509 certificate.
func StripTextFromCertificate(certContent string) []byte {
cmd := exec.Command("openssl", "x509")
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatal().Err(err).Msg(L("Failed to open openssl x509 process input stream"))
reader := bytes.NewBufferString(certContent)
rawCerts, err := processOpenSSL(reader)
if err != nil || len(rawCerts) == 0 {
return nil
}
if _, err := io.WriteString(stdin, certContent); err != nil {
log.Fatal().Err(err).Msg(L("Failed to write SSL certificate to input stream"))
}
out, err := cmd.Output()
if err != nil {
log.Fatal().Err(err).Msg(L("failed to strip text part from CA certificate"))
}
return out
return bytes.Join(rawCerts, []byte(""))
}

var newRunner = utils.NewRunner
Expand Down
11 changes: 11 additions & 0 deletions shared/ssl/ssl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package ssl

import (
"bytes"
"fmt"
"os"
"path"
Expand Down Expand Up @@ -247,3 +248,13 @@ func TestSHA256Fingerprints(t *testing.T) {
"7C:30:C7:12:03:64:D0:B3:FF:AA:B2:7C:1E:F1:E9:60:75:C8:A7:81:63:F0:6D:E9:EB:88:D6:2E:F2:32:B2:69",
fingerprints[1])
}

func TestStripTextFromCertificate(t *testing.T) {
cert := testutils.ReadFile(t, "testdata/chain2/spacewalk.crt")
actual := StripTextFromCertificate(cert)
testutils.AssertEquals(t, "Unexpected number of certificates starts",
3, bytes.Count(actual, []byte("-----BEGIN CERTIFICATE-----\n")))
testutils.AssertEquals(t, "Unexpected number of certificates ends",
3, bytes.Count(actual, []byte("\n-----END CERTIFICATE-----\n")))
testutils.AssertTrue(t, "The stripped cert shouldn't contain text", !bytes.Contains(actual, []byte("Data:")))
}
2 changes: 2 additions & 0 deletions uyuni-tools.changes.cbosdo.5.1-cert-cleanup
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Strip text from x509 certs before creating the secret
(bsc#1259720)
Loading