Skip to content

Commit

Permalink
feat: add support for loading PEM certificates as string as well as f…
Browse files Browse the repository at this point in the history
…ile path (#221)

* feat: add support to add PEM certificates as string instead of path references to files
closes: #171
* chore: fix linting
* Address comments from review

---------

Co-authored-by: Mostafa Moradian <[email protected]>
  • Loading branch information
doxsch and mostafa authored Jun 1, 2023
1 parent de6c4d5 commit 912ba4d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 36 deletions.
84 changes: 48 additions & 36 deletions auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,53 +140,65 @@ func GetTLSConfig(tlsConfig TLSConfig) (*tls.Config, *Xk6KafkaError) {
}

if tlsConfig.ClientCertPem != "" && tlsConfig.ClientKeyPem != "" {
// Load the client certificate and key if provided
if err := fileExists(tlsConfig.ClientCertPem); err != nil {
return nil, err
// Try to load the certificates from string
cert, err := tls.X509KeyPair([]byte(tlsConfig.ClientCertPem), []byte(tlsConfig.ClientKeyPem))
if err != nil && err.Error() == "tls: failed to find any PEM data in certificate input" {
// Fall back to loading the client certificate and key from the file
if err := fileExists(tlsConfig.ClientCertPem); err != nil {
return nil, err
}

if err := fileExists(tlsConfig.ClientKeyPem); err != nil {
return nil, err
}

cert, err = tls.LoadX509KeyPair(tlsConfig.ClientCertPem, tlsConfig.ClientKeyPem)
if err != nil {
return nil, NewXk6KafkaError(
failedLoadX509KeyPair,
fmt.Sprintf(
"Error creating x509 key pair from \"%s\" and \"%s\".",
tlsConfig.ClientCertPem,
tlsConfig.ClientKeyPem),
err)
}
} else if err != nil {
return nil, NewXk6KafkaError(
failedLoadX509KeyPair,
"Error creating x509 key pair from passed content.", err)
}

if err := fileExists(tlsConfig.ClientKeyPem); err != nil {
tlsObject.Certificates = []tls.Certificate{cert}
}

caCertPool := x509.NewCertPool()

// Load the CA certificate as string if provided
if ok := caCertPool.AppendCertsFromPEM([]byte(tlsConfig.ServerCaPem)); !ok {
// Fall back if file path is provided
if err := fileExists(tlsConfig.ServerCaPem); err != nil {
return nil, err
}

cert, err := tls.LoadX509KeyPair(tlsConfig.ClientCertPem, tlsConfig.ClientKeyPem)
caCert, err := os.ReadFile(tlsConfig.ServerCaPem)
if err != nil {
// This might happen on permissions issues or if the file is unreadable somehow
return nil, NewXk6KafkaError(
failedLoadX509KeyPair,
failedReadCaCertFile,
fmt.Sprintf(
"Error creating x509 key pair from \"%s\" and \"%s\".",
tlsConfig.ClientCertPem,
tlsConfig.ClientKeyPem),
"Error reading CA certificate file \"%s\".",
tlsConfig.ServerCaPem),
err)
}

tlsObject.Certificates = []tls.Certificate{cert}
}

// Load the CA certificate if provided
if err := fileExists(tlsConfig.ServerCaPem); err != nil {
return nil, err
}

caCert, err := os.ReadFile(tlsConfig.ServerCaPem)
if err != nil {
// This might happen on permissions issues or if the file is unreadable somehow
return nil, NewXk6KafkaError(
failedReadCaCertFile,
fmt.Sprintf(
"Error reading CA certificate file \"%s\".",
tlsConfig.ServerCaPem),
err)
}

caCertPool := x509.NewCertPool()
if ok := caCertPool.AppendCertsFromPEM(caCert); !ok {
return nil, NewXk6KafkaError(
failedAppendCaCertFile,
fmt.Sprintf(
"Error appending CA certificate file \"%s\".",
tlsConfig.ServerCaPem),
nil)
if ok := caCertPool.AppendCertsFromPEM(caCert); !ok {
return nil, NewXk6KafkaError(
failedAppendCaCertFile,
fmt.Sprintf(
"Error appending CA certificate file \"%s\".",
tlsConfig.ServerCaPem),
nil)
}
}

tlsObject.RootCAs = caCertPool
Expand Down
23 changes: 23 additions & 0 deletions auth_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kafka

import (
"os"
"testing"
"time"

Expand Down Expand Up @@ -225,3 +226,25 @@ func TestTlsConfigFails(t *testing.T) {
assert.Nil(t, tlsObject)
}
}

// TestTlsConfigFromContent tests the creation of a TLS config.
func TestTlsConfigFromContent(t *testing.T) {
paths := []string{"fixtures/client.cer", "fixtures/client.pem", "fixtures/caroot.cer"}
files := make([]string, len(paths))

for i, path := range paths {
file, _ := os.ReadFile(path)
files[i] = string(file)
}

tlsConfig := TLSConfig{
EnableTLS: true,
ClientCertPem: files[0],
ClientKeyPem: files[1],
ServerCaPem: files[2],
}
tlsObject, err := GetTLSConfig(tlsConfig)

assert.Nil(t, err)
assert.NotNil(t, tlsObject)
}

0 comments on commit 912ba4d

Please sign in to comment.