Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental FIPS support #864

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Binary file added charts/pega/config/certs/pegakeystore.bcfks
Binary file not shown.
2 changes: 0 additions & 2 deletions charts/pega/config/deploy/java.security.overwrite

This file was deleted.

20 changes: 20 additions & 0 deletions charts/pega/config/deploy/java.security.overwrite.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#Force the jvm to frequently requery dns
networkaddress.cache.ttl=30

{{ if .Env.FIPS_140_3_MODE }}
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
security.provider.3=SUN
security.provider.4=SunRsaSign
security.provider.5=SunEC
security.provider.6=SunJSSE
security.provider.7=SunJCE
security.provider.8=SunJGSS
security.provider.9=SunSASL
security.provider.10=XMLDSig
security.provider.11=SunPCSC
security.provider.12=JdkLDAP
security.provider.13=JdkSASL
security.provider.14=SunPKCS11
ssl.KeyManagerFactory.algorithm=PKIX
{{ end }}
18 changes: 17 additions & 1 deletion charts/pega/config/deploy/server.xml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,14 @@
<SSLHostConfig certificateVerification="none" sslProtocol="TLS">
{{ if ( and (exists .Env.TOMCAT_KEYSTORE_CONTENT) .Env.TOMCAT_KEYSTORE_PASSWORD ) }}

{{ if .Env.FIPS_140_3_MODE }}
<Certificate certificateKeystoreType="BCFKS"
certificateKeystoreFile="{{ .Env.TOMCAT_KEYSTORE_CONTENT }}"
certificateKeystorePassword="{{ .Env.TOMCAT_KEYSTORE_PASSWORD }}" />
{{ else }}
<Certificate certificateKeystoreFile="{{ .Env.TOMCAT_KEYSTORE_CONTENT }}"
certificateKeystorePassword="{{ .Env.TOMCAT_KEYSTORE_PASSWORD }}" />
{{ end }}

{{ else }}

Expand Down Expand Up @@ -197,6 +203,16 @@
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="false">

{{ if .Env.FIPS_140_3_MODE }}

<Context path="">
<Manager className="org.apache.catalina.session.StandardManager"
secureRandomProvider="BCFIPS"
secureRandomAlgorithm="DEFAULT"/>
</Context>

{{ end }}

<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
Expand Down Expand Up @@ -224,4 +240,4 @@
</Host>
</Engine>
</Service>
</Server>
</Server>
9 changes: 9 additions & 0 deletions charts/pega/templates/_pega-config.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ data:
{{ .root.Files.Get "config/deploy/web.xml" | indent 6 }}
{{- end }}
{{- end }}

# java security overwrite file
java.security.overwrite.tmpl: |-
{{- if $custom_config.javaSecurity }}
{{ $custom_config.javaSecurity | indent 6 }}
{{ else }}
{{ .root.Files.Get "config/deploy/java.security.overwrite.tmpl" | indent 6 }}
{{- end }}

{{- end }}
{{- end }}
---
Expand Down
6 changes: 5 additions & 1 deletion charts/pega/templates/_pega-tomcat-keystore-secret.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ data:
{{- if .node.service.tls.keystore }}
TOMCAT_KEYSTORE_CONTENT: {{ .node.service.tls.keystore | quote -}}
{{- else }}
TOMCAT_KEYSTORE_CONTENT: {{ .root.Files.Get "config/certs/pegakeystore.jks" | b64enc | indent 2 }}
{{- $default_keystore := "config/certs/pegakeystore.jks" -}}
{{- if .root.Values.global.fips140_3Mode -}}
{{- $default_keystore = "config/certs/pegakeystore.bcfks" -}}
{{- end }}
TOMCAT_KEYSTORE_CONTENT: {{ .root.Files.Get $default_keystore | b64enc | indent 2 }}
{{- end }}
# this field is used for traefik, it expects the root CA certificate in a secret under the field ca.crt
{{- if .node.service.tls.cacertificate }}
Expand Down
3 changes: 3 additions & 0 deletions charts/pega/templates/pega-environment-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,7 @@ data:
STREAM_NAME_PATTERN: "{{ .Values.stream.streamNamePattern }}"
STREAM_REPLICATION_FACTOR: "{{ .Values.stream.replicationFactor }}"
{{- end }}
{{- if .Values.global.fips140_3Mode }}
FIPS_140_3_MODE: "{{ .Values.global.fips140_3Mode }}"
{{- end }}
{{ end }}
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,14 @@
<SSLHostConfig certificateVerification="none" sslProtocol="TLS">
{{ if ( and (exists .Env.TOMCAT_KEYSTORE_CONTENT) .Env.TOMCAT_KEYSTORE_PASSWORD ) }}

{{ if .Env.FIPS_140_3_MODE }}
<Certificate certificateKeystoreType="BCFKS"
certificateKeystoreFile="{{ .Env.TOMCAT_KEYSTORE_CONTENT }}"
certificateKeystorePassword="{{ .Env.TOMCAT_KEYSTORE_PASSWORD }}" />
{{ else }}
<Certificate certificateKeystoreFile="{{ .Env.TOMCAT_KEYSTORE_CONTENT }}"
certificateKeystorePassword="{{ .Env.TOMCAT_KEYSTORE_PASSWORD }}" />
{{ end }}

{{ else }}

Expand Down Expand Up @@ -197,6 +203,16 @@
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="false">

{{ if .Env.FIPS_140_3_MODE }}

<Context path="">
<Manager className="org.apache.catalina.session.StandardManager"
secureRandomProvider="BCFIPS"
secureRandomAlgorithm="DEFAULT"/>
</Context>

{{ end }}

<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#Force the jvm to frequently requery dns
networkaddress.cache.ttl=30

{{ if .Env.FIPS_140_3_MODE }}
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
security.provider.3=SUN
security.provider.4=SunRsaSign
security.provider.5=SunEC
security.provider.6=SunJSSE
security.provider.7=SunJCE
security.provider.8=SunJGSS
security.provider.9=SunSASL
security.provider.10=XMLDSig
security.provider.11=SunPCSC
security.provider.12=JdkLDAP
security.provider.13=JdkSASL
security.provider.14=SunPKCS11
ssl.KeyManagerFactory.algorithm=PKIX
{{ end }}
42 changes: 39 additions & 3 deletions terratest/src/test/pega/pega-environment-config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package pega

import (
"fmt"
"path/filepath"
"testing"

"github.com/gruntwork-io/terratest/modules/helm"
"github.com/stretchr/testify/require"
k8score "k8s.io/api/core/v1"
"path/filepath"
"testing"
)

func TestPegaEnvironmentConfig(t *testing.T) {
Expand Down Expand Up @@ -100,7 +101,7 @@ func TestPegaHighlySecureCryptoModeEnabledEnvConfigParam(t *testing.T) {

yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-environment-config.yaml"})
VerifyEnvNotPresent(t, yamlContent, "HIGHLY_SECURE_CRYPTO_MODE_ENABLED")

options.SetValues["global.highlySecureCryptoModeEnabled"] = "true"
yamlContent = RenderTemplate(t, options, helmChartPath, []string{"templates/pega-environment-config.yaml"})
VerifyEnvValue(t, yamlContent, "HIGHLY_SECURE_CRYPTO_MODE_ENABLED", "true")
Expand All @@ -109,6 +110,41 @@ func TestPegaHighlySecureCryptoModeEnabledEnvConfigParam(t *testing.T) {
}
}

func TestFipsModeParam(t *testing.T) {
var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"}
var supportedOperations = []string{"deploy", "install-deploy"}

helmChartPath, err := filepath.Abs(PegaHelmChartPath)
require.NoError(t, err)

for _, vendor := range supportedVendors {

for _, operation := range supportedOperations {

fmt.Println(vendor + "-" + operation)

var options = &helm.Options{
SetValues: map[string]string{
"global.provider": vendor,
"global.actions.execute": operation,
},
}

yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-environment-config.yaml"})
VerifyEnvNotPresent(t, yamlContent, "FIPS_140_3_MODE")

options.SetValues["global.fips140_3Mode"] = "false"
yamlContent = RenderTemplate(t, options, helmChartPath, []string{"templates/pega-environment-config.yaml"})
VerifyEnvNotPresent(t, yamlContent, "FIPS_140_3_MODE")

options.SetValues["global.fips140_3Mode"] = "true"
yamlContent = RenderTemplate(t, options, helmChartPath, []string{"templates/pega-environment-config.yaml"})
VerifyEnvValue(t, yamlContent, "FIPS_140_3_MODE", "true")

}
}
}

func VerifyEnvNotPresent(t *testing.T, yamlContent string, entry string) {
var envConfigMap k8score.ConfigMap
UnmarshalK8SYaml(t, yamlContent, &envConfigMap)
Expand Down
116 changes: 61 additions & 55 deletions terratest/src/test/pega/pega-tier-config_test.go
Original file line number Diff line number Diff line change
@@ -1,74 +1,80 @@
package pega

import (
"fmt"
"github.com/gruntwork-io/terratest/modules/helm"
"github.com/stretchr/testify/require"
k8score "k8s.io/api/core/v1"
"path/filepath"
"strings"
"testing"
"fmt"
"path/filepath"
"strings"
"testing"

"github.com/gruntwork-io/terratest/modules/helm"
"github.com/stretchr/testify/require"
k8score "k8s.io/api/core/v1"
)

func TestPegaTierConfig(t *testing.T) {
var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"}
var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"}
var deploymentNames = []string{"pega", "myapp-dev"}
var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"}
var supportedOperations = []string{"deploy", "install-deploy", "upgrade-deploy"}
var deploymentNames = []string{"pega", "myapp-dev"}

helmChartPath, err := filepath.Abs(PegaHelmChartPath)
require.NoError(t, err)

helmChartPath, err := filepath.Abs(PegaHelmChartPath)
require.NoError(t, err)
for _, vendor := range supportedVendors {

for _, vendor := range supportedVendors {
for _, operation := range supportedOperations {

for _, operation := range supportedOperations {
for _, depName := range deploymentNames {

for _, depName := range deploymentNames {
fmt.Println(vendor + "-" + operation)

fmt.Println(vendor + "-" + operation)
var options = &helm.Options{
SetValues: map[string]string{
"global.deployment.name": depName,
"global.provider": vendor,
"global.actions.execute": operation,
"installer.upgrade.upgradeType": "zero-downtime",
},
}

var options = &helm.Options{
SetValues: map[string]string{
"global.deployment.name": depName,
"global.provider": vendor,
"global.actions.execute": operation,
"installer.upgrade.upgradeType": "zero-downtime",
},
}
yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-config.yaml"})
VerifyTierConfig(t, yamlContent, options)

yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-config.yaml"})
VerifyTierConfig(t, yamlContent, options)
}
}
}
options.SetValues["global.fips140_3Mode"] = "true"
yamlContent = RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-config.yaml"})
VerifyTierConfig(t, yamlContent, options)
}
}
}

}

// VerifyTierConfig - Performs the tier specific configuration assertions with the values as provided in default values.yaml
func VerifyTierConfig(t *testing.T, yamlContent string, options *helm.Options) {
var pegaConfigMap k8score.ConfigMap
configSlice := strings.Split(yamlContent, "---")
for index, configData := range configSlice {
if index >= 1 && index <= 3 {
var tierName string
switch index {
case 1:
tierName = "-web"
case 2:
tierName = "-batch"
case 3:
tierName = "-stream"
}

UnmarshalK8SYaml(t, configData, &pegaConfigMap)

require.Equal(t, pegaConfigMap.ObjectMeta.Name, getObjName(options, tierName))

pegaConfigMapData := pegaConfigMap.Data
compareConfigMapData(t, pegaConfigMapData["prconfig.xml"], "data/expectedInstallDeployPrconfig.xml")
compareConfigMapData(t, pegaConfigMapData["context.xml.tmpl"], "data/expectedInstallDeployContext.xml.tmpl")
compareConfigMapData(t, pegaConfigMapData["prlog4j2.xml"], "data/expectedInstallDeployPRlog4j2.xml")
compareConfigMapData(t, pegaConfigMapData["server.xml.tmpl"], "data/expectedInstallDeployServer.xml.tmpl")
require.Equal(t, "", pegaConfigMapData["web.xml"])
}
}
var pegaConfigMap k8score.ConfigMap
configSlice := strings.Split(yamlContent, "---")
for index, configData := range configSlice {
if index >= 1 && index <= 3 {
var tierName string
switch index {
case 1:
tierName = "-web"
case 2:
tierName = "-batch"
case 3:
tierName = "-stream"
}

UnmarshalK8SYaml(t, configData, &pegaConfigMap)

require.Equal(t, pegaConfigMap.ObjectMeta.Name, getObjName(options, tierName))

pegaConfigMapData := pegaConfigMap.Data
compareConfigMapData(t, pegaConfigMapData["prconfig.xml"], "data/expectedInstallDeployPrconfig.xml")
compareConfigMapData(t, pegaConfigMapData["context.xml.tmpl"], "data/expectedInstallDeployContext.xml.tmpl")
compareConfigMapData(t, pegaConfigMapData["prlog4j2.xml"], "data/expectedInstallDeployPRlog4j2.xml")
compareConfigMapData(t, pegaConfigMapData["server.xml.tmpl"], "data/expectedInstallDeployServer.xml.tmpl")
require.Equal(t, "", pegaConfigMapData["web.xml"])
compareConfigMapData(t, pegaConfigMapData["java.security.overwrite.tmpl"], "data/expectedJava.security.overwrite.tmpl")
}
}
}