diff --git a/helper/tlsutil/config.go b/helper/tlsutil/config.go index 8db29e088..851316cd4 100644 --- a/helper/tlsutil/config.go +++ b/helper/tlsutil/config.go @@ -147,7 +147,7 @@ func (c *Config) AppendCA(pool *x509.CertPool) error { return fmt.Errorf("Failed to read CA file: %v", err) } - block, _ := pem.Decode(data) + block, rest := pem.Decode(data) if block == nil { return fmt.Errorf("Failed to decode CA file from pem format") } @@ -161,6 +161,27 @@ func (c *Config) AppendCA(pool *x509.CertPool) error { return fmt.Errorf("Failed to add any CA certificates") } + for len(rest) > 0 { + block, rest = pem.Decode(rest) + + if block == nil { + return fmt.Errorf("Failed to decode CA file from pem format") + } + + // Parse the certificate to ensure that it is properly formatted + if _, err := x509.ParseCertificates(block.Bytes); err != nil { + return fmt.Errorf("Failed to parse CA file: %v", err) + } + + if !pool.AppendCertsFromPEM(data) { + return fmt.Errorf("Failed to add any CA certificates") + } + + if len(rest) == 0 { + break + } + } + return nil } diff --git a/helper/tlsutil/config_test.go b/helper/tlsutil/config_test.go index f74d5bd65..f5eb1611f 100644 --- a/helper/tlsutil/config_test.go +++ b/helper/tlsutil/config_test.go @@ -48,6 +48,93 @@ func TestConfig_AppendCA_Valid(t *testing.T) { require.Nil(err) } +func TestConfig_AppendCA_Valid_MultipleCerts(t *testing.T) { + require := require.New(t) + + tmpCAFile, err := ioutil.TempFile("/tmp", "test_ca_file") + require.Nil(err) + defer os.Remove(tmpCAFile.Name()) + + certs := ` +-----BEGIN CERTIFICATE----- +MIICMzCCAdqgAwIBAgIUNZ9L86Xp9EuDH0/qyAesh599LXQwCgYIKoZIzj0EAwIw +eDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh +biBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwGA1UECxMFTm9tYWQx +GDAWBgNVBAMTD25vbWFkLmhhc2hpY29ycDAeFw0xNjExMTAxOTQ4MDBaFw0yMTEx +MDkxOTQ4MDBaMHgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYw +FAYDVQQHEw1TYW4gRnJhbmNpc2NvMRIwEAYDVQQKEwlIYXNoaUNvcnAxDjAMBgNV +BAsTBU5vbWFkMRgwFgYDVQQDEw9ub21hZC5oYXNoaWNvcnAwWTATBgcqhkjOPQIB +BggqhkjOPQMBBwNCAARfJmTdHzYIMPD8SK+kj5Gc79fmpOcg6wnb4JNVwCqWw9O+ +uNdZJZWSi4Q/4HojM5FTSBqYxNgSrmY/o3oQrCPlo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOjVq/BectnhcKn6EHUD4NJFm +/UAwCgYIKoZIzj0EAwIDRwAwRAIgTemDJGSGtcQPXLWKiQNw4SKO9wAPhn/WoKW4 +Ln2ZUe8CIDsQswBQS7URbqnKYDye2Y4befJkr4fmhhmMQb2ex9A4 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICMzCCAdqgAwIBAgIUNZ9L86Xp9EuDH0/qyAesh599LXQwCgYIKoZIzj0EAwIw +eDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh +biBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwGA1UECxMFTm9tYWQx +GDAWBgNVBAMTD25vbWFkLmhhc2hpY29ycDAeFw0xNjExMTAxOTQ4MDBaFw0yMTEx +MDkxOTQ4MDBaMHgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYw +FAYDVQQHEw1TYW4gRnJhbmNpc2NvMRIwEAYDVQQKEwlIYXNoaUNvcnAxDjAMBgNV +BAsTBU5vbWFkMRgwFgYDVQQDEw9ub21hZC5oYXNoaWNvcnAwWTATBgcqhkjOPQIB +BggqhkjOPQMBBwNCAARfJmTdHzYIMPD8SK+kj5Gc79fmpOcg6wnb4JNVwCqWw9O+ +uNdZJZWSi4Q/4HojM5FTSBqYxNgSrmY/o3oQrCPlo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOjVq/BectnhcKn6EHUD4NJFm +/UAwCgYIKoZIzj0EAwIDRwAwRAIgTemDJGSGtcQPXLWKiQNw4SKO9wAPhn/WoKW4 +Ln2ZUe8CIDsQswBQS7URbqnKYDye2Y4befJkr4fmhhmMQb2ex9A4 +-----END CERTIFICATE-----` + + _, err = tmpCAFile.Write([]byte(certs)) + require.Nil(err) + + conf := &Config{ + CAFile: tmpCAFile.Name(), + } + pool := x509.NewCertPool() + err = conf.AppendCA(pool) + + require.Nil(err) +} + +func TestConfig_AppendCA_InValid_MultipleCerts(t *testing.T) { + require := require.New(t) + + tmpCAFile, err := ioutil.TempFile("/tmp", "test_ca_file") + require.Nil(err) + defer os.Remove(tmpCAFile.Name()) + + certs := ` +-----BEGIN CERTIFICATE----- +MIICMzCCAdqgAwIBAgIUNZ9L86Xp9EuDH0/qyAesh599LXQwCgYIKoZIzj0EAwIw +eDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh +biBGcmFuY2lzY28xEjAQBgNVBAoTCUhhc2hpQ29ycDEOMAwGA1UECxMFTm9tYWQx +GDAWBgNVBAMTD25vbWFkLmhhc2hpY29ycDAeFw0xNjExMTAxOTQ4MDBaFw0yMTEx +MDkxOTQ4MDBaMHgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYw +FAYDVQQHEw1TYW4gRnJhbmNpc2NvMRIwEAYDVQQKEwlIYXNoaUNvcnAxDjAMBgNV +BAsTBU5vbWFkMRgwFgYDVQQDEw9ub21hZC5oYXNoaWNvcnAwWTATBgcqhkjOPQIB +BggqhkjOPQMBBwNCAARfJmTdHzYIMPD8SK+kj5Gc79fmpOcg6wnb4JNVwCqWw9O+ +uNdZJZWSi4Q/4HojM5FTSBqYxNgSrmY/o3oQrCPlo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOjVq/BectnhcKn6EHUD4NJFm +/UAwCgYIKoZIzj0EAwIDRwAwRAIgTemDJGSGtcQPXLWKiQNw4SKO9wAPhn/WoKW4 +Ln2ZUe8CIDsQswBQS7URbqnKYDye2Y4befJkr4fmhhmMQb2ex9A4 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +Invalid +-----END CERTIFICATE-----` + + _, err = tmpCAFile.Write([]byte(certs)) + require.Nil(err) + + conf := &Config{ + CAFile: tmpCAFile.Name(), + } + pool := x509.NewCertPool() + err = conf.AppendCA(pool) + + require.NotNil(err) +} + func TestConfig_AppendCA_Invalid(t *testing.T) { require := require.New(t) {