This is an automated email from the ASF dual-hosted git repository. astefanutti pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 8515b4dc11993157e2c084b871706142bdf55068 Author: Antonin Stefanutti <anto...@stefanutti.fr> AuthorDate: Fri Mar 26 15:07:34 2021 +0100 feat(build): Manage truststore password --- pkg/builder/project.go | 3 ++- pkg/builder/quarkus.go | 15 +++++++++------ pkg/builder/types.go | 1 + pkg/trait/openapi.go | 8 ++++++-- pkg/util/camel/catalog.go | 8 ++++++-- pkg/util/jvm/keystore.go | 47 ++++++++++++++++++++++++++++++++++++++++++----- 6 files changed, 66 insertions(+), 16 deletions(-) diff --git a/pkg/builder/project.go b/pkg/builder/project.go index 8f77ecc..e7b59b6 100644 --- a/pkg/builder/project.go +++ b/pkg/builder/project.go @@ -77,8 +77,9 @@ func generateJavaKeystore(ctx *builderContext) error { } ctx.Maven.TrustStoreName = "trust.jks" + ctx.Maven.TrustStorePass = jvm.NewKeystorePassword() - return jvm.GenerateJavaKeystore(ctx.C, ctx.Path, ctx.Maven.TrustStoreName, certData) + return jvm.GenerateKeystore(ctx.C, ctx.Path, ctx.Maven.TrustStoreName, ctx.Maven.TrustStorePass, certData) } func generateProjectSettings(ctx *builderContext) error { diff --git a/pkg/builder/quarkus.go b/pkg/builder/quarkus.go index 7e02255..6eae256 100644 --- a/pkg/builder/quarkus.go +++ b/pkg/builder/quarkus.go @@ -148,7 +148,10 @@ func buildQuarkusRunner(ctx *builderContext) error { mc.Timeout = ctx.Build.Maven.GetTimeout().Duration if ctx.Maven.TrustStoreName != "" { - mc.ExtraMavenOpts = append(mc.ExtraMavenOpts, "-Djavax.net.ssl.trustStore="+path.Join(ctx.Path, ctx.Maven.TrustStoreName)) + mc.ExtraMavenOpts = append(mc.ExtraMavenOpts, + "-Djavax.net.ssl.trustStore="+path.Join(ctx.Path, ctx.Maven.TrustStoreName), + "-Djavax.net.ssl.trustStorePassword="+ctx.Maven.TrustStorePass, + ) } err := BuildQuarkusRunnerCommon(mc) @@ -165,18 +168,18 @@ func BuildQuarkusRunnerCommon(mc maven.Context) error { return errors.Wrap(err, "failure while creating resource folder") } - // generate an empty application.properties so that there will be something in + // Generate an empty application.properties so that there will be something in // target/classes as if such directory does not exist, the quarkus maven plugin - // may fail the build - // - // in the future there should be a way to provide build information from secrets, + // may fail the build. + // In the future there should be a way to provide build information from secrets, // configmap, etc. if _, err := os.Create(path.Join(resourcesPath, "application.properties")); err != nil { return errors.Wrap(err, "failure while creating application.properties") } - // Build the project mc.AddArgument("package") + + // Build the project if err := maven.Run(mc); err != nil { return errors.Wrap(err, "failure while building project") } diff --git a/pkg/builder/types.go b/pkg/builder/types.go index 55354f6..20e1f34 100644 --- a/pkg/builder/types.go +++ b/pkg/builder/types.go @@ -91,5 +91,6 @@ type builderContext struct { Project maven.Project SettingsData []byte TrustStoreName string + TrustStorePass string } } diff --git a/pkg/trait/openapi.go b/pkg/trait/openapi.go index b0880b7..d652599 100644 --- a/pkg/trait/openapi.go +++ b/pkg/trait/openapi.go @@ -221,11 +221,15 @@ func (t *openAPITrait) createNewOpenAPIConfigMap(e *Environment, resource v1.Res return err } trustStoreName := "trust.jks" - err = jvm.GenerateJavaKeystore(e.C, tmpDir, trustStoreName, certData) + trustStorePass := jvm.NewKeystorePassword() + err = jvm.GenerateKeystore(e.C, tmpDir, trustStoreName, trustStorePass, certData) if err != nil { return err } - mc.ExtraMavenOpts = append(mc.ExtraMavenOpts, "-Djavax.net.ssl.trustStore="+trustStoreName) + mc.ExtraMavenOpts = append(mc.ExtraMavenOpts, + "-Djavax.net.ssl.trustStore="+trustStoreName, + "-Djavax.net.ssl.trustStorePassword="+trustStorePass, + ) } err = maven.Run(mc) diff --git a/pkg/util/camel/catalog.go b/pkg/util/camel/catalog.go index 014eefd..6b8ee38 100644 --- a/pkg/util/camel/catalog.go +++ b/pkg/util/camel/catalog.go @@ -121,11 +121,15 @@ func GenerateCatalogCommon( if caCert != nil { trustStoreName := "trust.jks" - err := jvm.GenerateJavaKeystore(context.Background(), tmpDir, trustStoreName, caCert) + trustStorePass := jvm.NewKeystorePassword() + err := jvm.GenerateKeystore(context.Background(), tmpDir, trustStoreName, trustStorePass, caCert) if err != nil { return nil, err } - mc.ExtraMavenOpts = append(mc.ExtraMavenOpts, "-Djavax.net.ssl.trustStore="+trustStoreName) + mc.ExtraMavenOpts = append(mc.ExtraMavenOpts, + "-Djavax.net.ssl.trustStore="+trustStoreName, + "-Djavax.net.ssl.trustStorePassword="+trustStorePass, + ) } err = maven.Run(mc) diff --git a/pkg/util/jvm/keystore.go b/pkg/util/jvm/keystore.go index 60003d2..7a8e753 100644 --- a/pkg/util/jvm/keystore.go +++ b/pkg/util/jvm/keystore.go @@ -20,28 +20,31 @@ package jvm import ( "context" "fmt" + "math/rand" "os" "os/exec" "path" "strings" + "time" "github.com/apache/camel-k/pkg/util" ) -func GenerateJavaKeystore(ctx context.Context, keystoreDir, keystoreName string, data []byte) error { +func GenerateKeystore(ctx context.Context, keystoreDir, keystoreName, keystorePass string, data []byte) error { tmpFile := "ca-cert.tmp" - if err := util.WriteFileWithContent(keystoreDir, tmpFile, data); err != nil { + err := util.WriteFileWithContent(keystoreDir, tmpFile, data) + if err != nil { return err } defer os.Remove(path.Join(keystoreDir, tmpFile)) - args := strings.Fields(fmt.Sprintf("-importcert -noprompt -alias maven -file %s -keystore %s", tmpFile, keystoreName)) + args := strings.Fields(fmt.Sprintf("-importcert -noprompt -alias maven -storepass %s -file %s -keystore %s", keystorePass, tmpFile, keystoreName)) cmd := exec.CommandContext(ctx, "keytool", args...) cmd.Dir = keystoreDir cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout - err := cmd.Run() + err = cmd.Run() if err != nil { return err } @@ -52,7 +55,7 @@ func GenerateJavaKeystore(ctx context.Context, keystoreDir, keystoreName string, javaHome, ok := os.LookupEnv("JAVA_HOME") if ok { caCertsPath := path.Join(javaHome, "lib/security/cacerts") - args := strings.Fields(fmt.Sprintf("-importkeystore -noprompt -srckeystore %s -srcstorepass %s -destkeystore %s", caCertsPath, "changeit", keystoreName)) + args := strings.Fields(fmt.Sprintf("-importkeystore -noprompt -srckeystore %s -srcstorepass %s -destkeystore %s -deststorepass %s", caCertsPath, "changeit", keystoreName, keystorePass)) cmd := exec.CommandContext(ctx, "keytool", args...) cmd.Dir = keystoreDir cmd.Stderr = os.Stderr @@ -66,3 +69,37 @@ func GenerateJavaKeystore(ctx context.Context, keystoreDir, keystoreName string, return nil } + +// The keytool CLI mandates a password at least 6 characters long +// to access any key stores. +func NewKeystorePassword() string { + return randString(10) +} + +const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +const ( + letterIdxBits = 6 // 6 bits to represent a letter index + letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits + letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits +) + +var src = rand.NewSource(time.Now().UnixNano()) + +func randString(n int) string { + sb := strings.Builder{} + sb.Grow(n) + for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; { + if remain == 0 { + cache, remain = src.Int63(), letterIdxMax + } + if idx := int(cache & letterIdxMask); idx < len(letterBytes) { + sb.WriteByte(letterBytes[idx]) + i-- + } + cache >>= letterIdxBits + remain-- + } + + return sb.String() +}