diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md index 324c96ed2..d95e5a400 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md @@ -35,31 +35,32 @@ authelia crypto certificate ecdsa generate --help ### Options ``` - --bundle enables generating the certificate bundle if the --path.ca flag is set - --ca create the certificate as a certificate authority certificate - -n, --common-name string certificate common name - --country strings certificate country - -b, --curve string Sets the elliptic curve which can be P224, P256, P384, or P521 (default "P256") - -d, --directory string directory where the generated keys, certificates, etc will be stored - --duration string duration of time the certificate is valid for (default "1y") - --extended-usage strings specify the extended usage types of the certificate - --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") - --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") - --file.certificate string name of the file to export the certificate data to (default "public.crt") - --file.certificate-bundle string name of the file to export the certificate bundle data to when the --bundle flag is set (default "public.bundle.crt") - --file.private-key string name of the file to export the private key data to (default "private.pem") - -h, --help help for generate - -l, --locality strings certificate locality - --not-after string latest date and time the certificate is considered valid in various formats - --not-before string earliest date and time the certificate is considered valid in various formats (default is now) - -o, --organization strings certificate organization (default [Authelia]) - --organizational-unit strings certificate organizational unit - --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed - -p, --postcode strings certificate postcode - --province strings certificate province - --sans strings subject alternative names - --signature string signature algorithm for the certificate (default "SHA256") - -s, --street-address strings certificate street address + --bundles strings enables generating bundles options are 'chain' and 'privkey-chain' + --ca create the certificate as a certificate authority certificate + -n, --common-name string certificate common name + --country strings certificate country + -b, --curve string Sets the elliptic curve which can be P224, P256, P384, or P521 (default "P256") + -d, --directory string directory where the generated keys, certificates, etc will be stored + --duration string duration of time the certificate is valid for (default "1y") + --extended-usage strings specify the extended usage types of the certificate + --file.bundle.chain string name of the file to export the certificate chain PEM bundle to when the --bundles flag includes 'chain' (default "public.chain.pem") + --file.bundle.priv-chain string name of the file to export the certificate chain and private key PEM bundle to when the --bundles flag includes 'priv-chain' (default "private.chain.pem") + --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") + --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") + --file.certificate string name of the file to export the certificate data to (default "public.crt") + --file.private-key string name of the file to export the private key data to (default "private.pem") + -h, --help help for generate + -l, --locality strings certificate locality + --not-after string latest date and time the certificate is considered valid in various formats + --not-before string earliest date and time the certificate is considered valid in various formats (default is now) + -o, --organization strings certificate organization (default [Authelia]) + --organizational-unit strings certificate organizational unit + --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed + -p, --postcode strings certificate postcode + --province strings certificate province + --sans strings subject alternative names + --signature string signature algorithm for the certificate (default "SHA256") + -s, --street-address strings certificate street address ``` ### Options inherited from parent commands diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md index 7afaf5a9b..f246998a9 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md @@ -35,30 +35,31 @@ authelia crypto certificate ed25519 request --help ### Options ``` - --bundle enables generating the certificate bundle if the --path.ca flag is set - --ca create the certificate as a certificate authority certificate - -n, --common-name string certificate common name - --country strings certificate country - -d, --directory string directory where the generated keys, certificates, etc will be stored - --duration string duration of time the certificate is valid for (default "1y") - --extended-usage strings specify the extended usage types of the certificate - --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") - --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") - --file.certificate string name of the file to export the certificate data to (default "public.crt") - --file.certificate-bundle string name of the file to export the certificate bundle data to when the --bundle flag is set (default "public.bundle.crt") - --file.private-key string name of the file to export the private key data to (default "private.pem") - -h, --help help for generate - -l, --locality strings certificate locality - --not-after string latest date and time the certificate is considered valid in various formats - --not-before string earliest date and time the certificate is considered valid in various formats (default is now) - -o, --organization strings certificate organization (default [Authelia]) - --organizational-unit strings certificate organizational unit - --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed - -p, --postcode strings certificate postcode - --province strings certificate province - --sans strings subject alternative names - --signature string signature algorithm for the certificate (default "SHA256") - -s, --street-address strings certificate street address + --bundles strings enables generating bundles options are 'chain' and 'privkey-chain' + --ca create the certificate as a certificate authority certificate + -n, --common-name string certificate common name + --country strings certificate country + -d, --directory string directory where the generated keys, certificates, etc will be stored + --duration string duration of time the certificate is valid for (default "1y") + --extended-usage strings specify the extended usage types of the certificate + --file.bundle.chain string name of the file to export the certificate chain PEM bundle to when the --bundles flag includes 'chain' (default "public.chain.pem") + --file.bundle.priv-chain string name of the file to export the certificate chain and private key PEM bundle to when the --bundles flag includes 'priv-chain' (default "private.chain.pem") + --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") + --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") + --file.certificate string name of the file to export the certificate data to (default "public.crt") + --file.private-key string name of the file to export the private key data to (default "private.pem") + -h, --help help for generate + -l, --locality strings certificate locality + --not-after string latest date and time the certificate is considered valid in various formats + --not-before string earliest date and time the certificate is considered valid in various formats (default is now) + -o, --organization strings certificate organization (default [Authelia]) + --organizational-unit strings certificate organizational unit + --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed + -p, --postcode strings certificate postcode + --province strings certificate province + --sans strings subject alternative names + --signature string signature algorithm for the certificate (default "SHA256") + -s, --street-address strings certificate street address ``` ### Options inherited from parent commands diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md index 9b89fba34..03d4979ae 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md @@ -35,31 +35,32 @@ authelia crypto certificate rsa generate --help ### Options ``` - -b, --bits int number of RSA bits for the certificate (default 2048) - --bundle enables generating the certificate bundle if the --path.ca flag is set - --ca create the certificate as a certificate authority certificate - -n, --common-name string certificate common name - --country strings certificate country - -d, --directory string directory where the generated keys, certificates, etc will be stored - --duration string duration of time the certificate is valid for (default "1y") - --extended-usage strings specify the extended usage types of the certificate - --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") - --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") - --file.certificate string name of the file to export the certificate data to (default "public.crt") - --file.certificate-bundle string name of the file to export the certificate bundle data to when the --bundle flag is set (default "public.bundle.crt") - --file.private-key string name of the file to export the private key data to (default "private.pem") - -h, --help help for generate - -l, --locality strings certificate locality - --not-after string latest date and time the certificate is considered valid in various formats - --not-before string earliest date and time the certificate is considered valid in various formats (default is now) - -o, --organization strings certificate organization (default [Authelia]) - --organizational-unit strings certificate organizational unit - --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed - -p, --postcode strings certificate postcode - --province strings certificate province - --sans strings subject alternative names - --signature string signature algorithm for the certificate (default "SHA256") - -s, --street-address strings certificate street address + -b, --bits int number of RSA bits for the certificate (default 2048) + --bundles strings enables generating bundles options are 'chain' and 'privkey-chain' + --ca create the certificate as a certificate authority certificate + -n, --common-name string certificate common name + --country strings certificate country + -d, --directory string directory where the generated keys, certificates, etc will be stored + --duration string duration of time the certificate is valid for (default "1y") + --extended-usage strings specify the extended usage types of the certificate + --file.bundle.chain string name of the file to export the certificate chain PEM bundle to when the --bundles flag includes 'chain' (default "public.chain.pem") + --file.bundle.priv-chain string name of the file to export the certificate chain and private key PEM bundle to when the --bundles flag includes 'priv-chain' (default "private.chain.pem") + --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") + --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") + --file.certificate string name of the file to export the certificate data to (default "public.crt") + --file.private-key string name of the file to export the private key data to (default "private.pem") + -h, --help help for generate + -l, --locality strings certificate locality + --not-after string latest date and time the certificate is considered valid in various formats + --not-before string earliest date and time the certificate is considered valid in various formats (default is now) + -o, --organization strings certificate organization (default [Authelia]) + --organizational-unit strings certificate organizational unit + --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed + -p, --postcode strings certificate postcode + --province strings certificate province + --sans strings subject alternative names + --signature string signature algorithm for the certificate (default "SHA256") + -s, --street-address strings certificate street address ``` ### Options inherited from parent commands diff --git a/internal/commands/const.go b/internal/commands/const.go index 2e322a2c4..1e0f8e320 100644 --- a/internal/commands/const.go +++ b/internal/commands/const.go @@ -536,16 +536,17 @@ const ( const ( cmdFlagNameDirectory = "directory" - cmdFlagNamePathCA = "path.ca" - cmdFlagNameBundle = "bundle" + cmdFlagNamePathCA = "path.ca" + cmdFlagNameBundles = "bundles" - cmdFlagNameFilePrivateKey = "file.private-key" - cmdFlagNameFilePublicKey = "file.public-key" - cmdFlagNameFileCertificate = "file.certificate" - cmdFlagNameFileCertificateBundle = "file.certificate-bundle" - cmdFlagNameFileCAPrivateKey = "file.ca-private-key" - cmdFlagNameFileCACertificate = "file.ca-certificate" - cmdFlagNameFileCSR = "file.csr" + cmdFlagNameFilePrivateKey = "file.private-key" + cmdFlagNameFilePublicKey = "file.public-key" + cmdFlagNameFileCertificate = "file.certificate" + cmdFlagNameFileBundleChain = "file.bundle.chain" + cmdFlagNameFileBundlePrivKeyChain = "file.bundle.priv-chain" + cmdFlagNameFileCAPrivateKey = "file.ca-private-key" + cmdFlagNameFileCACertificate = "file.ca-certificate" + cmdFlagNameFileCSR = "file.csr" cmdFlagNameExtendedUsage = "extended-usage" cmdFlagNameSignature = "signature" diff --git a/internal/commands/crypto.go b/internal/commands/crypto.go index fffec510c..f8b934026 100644 --- a/internal/commands/crypto.go +++ b/internal/commands/crypto.go @@ -365,7 +365,7 @@ func (ctx *CmdCtx) CryptoCertificateGenerateRunE(cmd *cobra.Command, _ []string, return err } - b := strings.Builder{} + b := &strings.Builder{} b.WriteString("Generating Certificate\n\n") @@ -402,9 +402,8 @@ func (ctx *CmdCtx) CryptoCertificateGenerateRunE(cmd *cobra.Command, _ []string, b.WriteString(fmt.Sprintf("\n\tSubject Alternative Names: %s\n\n", strings.Join(cryptoSANsToString(template.DNSNames, template.IPAddresses), ", "))) var ( - dir, privateKeyPath, certificatePath, certificateBundlePath string + dir, privateKeyPath, certificatePath string - bundle bool certificate []byte ) @@ -412,10 +411,6 @@ func (ctx *CmdCtx) CryptoCertificateGenerateRunE(cmd *cobra.Command, _ []string, return err } - if bundle, certificateBundlePath, err = cryptoGetCertificateBundleFromCmd(cmd, dir, caCertificate); err != nil { - return err - } - b.WriteString("Output Paths:\n") b.WriteString(fmt.Sprintf("\tPrivate Key: %s\n", privateKeyPath)) b.WriteString(fmt.Sprintf("\tCertificate: %s\n", certificatePath)) @@ -432,10 +427,8 @@ func (ctx *CmdCtx) CryptoCertificateGenerateRunE(cmd *cobra.Command, _ []string, return err } - if bundle { - b.WriteString(fmt.Sprintf("\tCertificate (bundle): %s\n", certificateBundlePath)) - - if err = utils.WriteCertificateBytesToPEM(certificateBundlePath, false, certificate, caCertificate.Raw); err != nil { + if cmd.Flags().Changed(cmdFlagNameBundles) { + if err = cryptoGenerateCertificateBundlesFromCmd(cmd, b, dir, caCertificate, certificate, privateKey); err != nil { return err } } diff --git a/internal/commands/crypto_helper.go b/internal/commands/crypto_helper.go index 774c19548..eb29b31a6 100644 --- a/internal/commands/crypto_helper.go +++ b/internal/commands/crypto_helper.go @@ -7,6 +7,7 @@ import ( "crypto/rsa" "crypto/x509" "crypto/x509/pkix" + "encoding/pem" "fmt" "math/big" "net" @@ -43,8 +44,9 @@ func cmdFlagsCryptoCertificateGenerate(cmd *cobra.Command) { cmd.Flags().String(cmdFlagNameFileCAPrivateKey, "ca.private.pem", "certificate authority private key to use to signing this certificate") cmd.Flags().String(cmdFlagNameFileCACertificate, "ca.public.crt", "certificate authority certificate to use when signing this certificate") cmd.Flags().String(cmdFlagNameFileCertificate, "public.crt", "name of the file to export the certificate data to") - cmd.Flags().String(cmdFlagNameFileCertificateBundle, "public.bundle.crt", fmt.Sprintf("name of the file to export the certificate bundle data to when the --%s flag is set", cmdFlagNameBundle)) - cmd.Flags().Bool(cmdFlagNameBundle, false, fmt.Sprintf("enables generating the certificate bundle if the --%s flag is set", cmdFlagNamePathCA)) + cmd.Flags().String(cmdFlagNameFileBundleChain, "public.chain.pem", fmt.Sprintf("name of the file to export the certificate chain PEM bundle to when the --%s flag includes 'chain'", cmdFlagNameBundles)) + cmd.Flags().String(cmdFlagNameFileBundlePrivKeyChain, "private.chain.pem", fmt.Sprintf("name of the file to export the certificate chain and private key PEM bundle to when the --%s flag includes 'priv-chain'", cmdFlagNameBundles)) + cmd.Flags().StringSlice(cmdFlagNameBundles, nil, "enables generating bundles options are 'chain' and 'privkey-chain'") cmd.Flags().StringSlice(cmdFlagNameExtendedUsage, nil, "specify the extended usage types of the certificate") @@ -170,26 +172,60 @@ func (ctx *CmdCtx) cryptoGenPrivateKeyFromCmd(cmd *cobra.Command) (privateKey an return privateKey, nil } -func cryptoGetCertificateBundleFromCmd(cmd *cobra.Command, dir string, caCertificate *x509.Certificate) (bundle bool, bundlePath string, err error) { - if bundle, err = cmd.Flags().GetBool(cmdFlagNameBundle); err != nil { - return false, "", err +func cryptoGenerateCertificateBundlesFromCmd(cmd *cobra.Command, b *strings.Builder, dir string, ca *x509.Certificate, certificate []byte, privkey any) (err error) { + var bundles []string + + if bundles, err = cmd.Flags().GetStringSlice(cmdFlagNameBundles); err != nil { + return err } - if !bundle { - return bundle, bundlePath, err + blocks := []*pem.Block{ + {Type: utils.BlockTypeCertificate, Bytes: certificate}, } - if caCertificate == nil { - return false, "", fmt.Errorf("the --%s flag can't be used with self-signed certificates, you can specify the authority path using the --%s flag", cmdFlagNameBundle, cmdFlagNamePathCA) + if ca != nil { + blocks = append(blocks, &pem.Block{Type: utils.BlockTypeCertificate, Bytes: ca.Raw}) } - if bundlePath, err = cmd.Flags().GetString(cmdFlagNameFileCertificateBundle); err != nil { - return false, "", err + var name string + + if utils.IsStringInSliceFold("chain", bundles) { + if name, err = cmd.Flags().GetString(cmdFlagNameFileBundleChain); err != nil { + return err + } + + pathPEM := filepath.Join(dir, name) + + b.WriteString(fmt.Sprintf("\tCertificate (chain): %s\n", pathPEM)) + + if err = utils.WritePEM(pathPEM, blocks...); err != nil { + return err + } } - bundlePath = filepath.Join(dir, bundlePath) + if utils.IsStringInSliceFold("priv-chain", bundles) { + if name, err = cmd.Flags().GetString(cmdFlagNameFileBundlePrivKeyChain); err != nil { + return err + } - return bundle, bundlePath, err + var block *pem.Block + + if block, err = utils.PEMBlockFromX509Key(privkey, false); err != nil { + return err + } + + blocks = append([]*pem.Block{block}, blocks...) + + pathPEM := filepath.Join(dir, name) + + b.WriteString(fmt.Sprintf("\tCertificate (priv-chain): %s\n", pathPEM)) + + if err = utils.WritePEM(pathPEM, blocks...); err != nil { + return err + } + } + + return nil } func cryptoGetCAFromCmd(cmd *cobra.Command) (privateKey any, cert *x509.Certificate, err error) { diff --git a/internal/suites/OIDC/docker-compose.yml b/internal/suites/OIDC/docker-compose.yml index 7f545a02a..a078d190a 100644 --- a/internal/suites/OIDC/docker-compose.yml +++ b/internal/suites/OIDC/docker-compose.yml @@ -3,7 +3,7 @@ version: '3' services: authelia-backend: environment: - AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_CERTIFICATE_CHAIN_FILE: /pki/public.oidc.bundle.crt + AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_CERTIFICATE_CHAIN_FILE: /pki/public.oidc.chain.pem AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE: /pki/private.oidc.pem volumes: - './OIDC/configuration.yml:/config/configuration.yml:ro' diff --git a/internal/suites/OIDCTraefik/docker-compose.yml b/internal/suites/OIDCTraefik/docker-compose.yml index 4ffae1fda..1af5fd9b3 100644 --- a/internal/suites/OIDCTraefik/docker-compose.yml +++ b/internal/suites/OIDCTraefik/docker-compose.yml @@ -3,7 +3,7 @@ version: '3' services: authelia-backend: environment: - AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_CERTIFICATE_CHAIN_FILE: /pki/public.oidc.bundle.crt + AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_CERTIFICATE_CHAIN_FILE: /pki/public.oidc.chain.pem AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE: /pki/private.oidc.pem volumes: - './OIDCTraefik/configuration.yml:/config/configuration.yml:ro' diff --git a/internal/suites/common/pki/gen.sh b/internal/suites/common/pki/gen.sh index 5f85ba711..b95b27352 100755 --- a/internal/suites/common/pki/gen.sh +++ b/internal/suites/common/pki/gen.sh @@ -2,6 +2,6 @@ # go run ./cmd/authelia crypto certificate rsa generate --directory ./internal/suites/common/pki/ca -n 'Authelia Development Standalone Root CA' --not-before 'Jan 1 00:00:00 2000' --not-after 'Jan 1 00:00:00 2100' -o 'Authelia' --organizational-unit 'Development' --ca # cp ./internal/suites/common/pki/ca/ca.public.crt ./internal/suites/common/pki/ca.public.crt -go run ./cmd/authelia crypto certificate rsa generate --directory ./internal/suites/common/pki --path.ca ./internal/suites/common/pki/ca -n '*.example.com' --sans '*.example.com,example.com,*.example1.com,example1.com,*.example2.com,example2.com,*.example3.com,example3.com' --not-before 'Jan 1 00:00:00 2000' --not-after 'Jan 1 00:00:00 2100' -o 'Authelia' --organizational-unit 'Development' --bundle -go run ./cmd/authelia crypto certificate rsa generate --directory ./internal/suites/common/pki --path.ca ./internal/suites/common/pki/ca --file.certificate public.backend.crt --file.certificate-bundle public.backend.bundle.crt --file.private-key private.backend.pem -n 'login.example.com' --sans 'login.example.com,authelia' --not-before 'Jan 1 00:00:00 2000' --not-after 'Jan 1 00:00:00 2100' -o 'Authelia' --organizational-unit 'Development' --bundle -go run ./cmd/authelia crypto certificate rsa generate --directory ./internal/suites/common/pki --path.ca ./internal/suites/common/pki/ca --file.certificate public.oidc.crt --file.certificate-bundle public.oidc.bundle.crt --file.private-key private.oidc.pem -n 'login.example.com' --sans 'login.example.com,login.example1.com,login.example2.com,login.example3,com' --not-before 'Jan 1 00:00:00 2000' --not-after 'Jan 1 00:00:00 2100' -o 'Authelia' --organizational-unit 'Development' --bundle +go run ./cmd/authelia crypto certificate rsa generate --directory ./internal/suites/common/pki --path.ca ./internal/suites/common/pki/ca --bundles 'chain,priv-chain' -n '*.example.com' --sans '*.example.com,example.com,*.example1.com,example1.com,*.example2.com,example2.com,*.example3.com,example3.com' --not-before 'Jan 1 00:00:00 2000' --not-after 'Jan 1 00:00:00 2100' -o 'Authelia' --organizational-unit 'Development' +go run ./cmd/authelia crypto certificate rsa generate --directory ./internal/suites/common/pki --path.ca ./internal/suites/common/pki/ca --bundles 'chain,priv-chain' --file.certificate public.backend.crt --file.private-key private.backend.pem --file.bundle.chain public.backend.chain.pem --file.bundle.priv-chain private.backend.chain.pem -n 'login.example.com' --sans 'login.example.com,authelia' --not-before 'Jan 1 00:00:00 2000' --not-after 'Jan 1 00:00:00 2100' -o 'Authelia' --organizational-unit 'Development' +go run ./cmd/authelia crypto certificate rsa generate --directory ./internal/suites/common/pki --path.ca ./internal/suites/common/pki/ca --bundles 'chain,priv-chain' --file.certificate public.oidc.crt --file.private-key private.oidc.pem --file.bundle.chain public.oidc.chain.pem --file.bundle.priv-chain private.oidc.chain.pem -n 'login.example.com' --sans 'login.example.com,login.example1.com,login.example2.com,login.example3,com' --not-before 'Jan 1 00:00:00 2000' --not-after 'Jan 1 00:00:00 2100' -o 'Authelia' --organizational-unit 'Development' diff --git a/internal/suites/common/pki/private.backend.chain.pem b/internal/suites/common/pki/private.backend.chain.pem new file mode 100644 index 000000000..fd194c953 --- /dev/null +++ b/internal/suites/common/pki/private.backend.chain.pem @@ -0,0 +1,70 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA9sWvS9YsIUlm4w3ikVUjsCg1hbwyb/BSEGpRsVG8Oox0t62R +MEIG70lPfMg2IeJZDDdFreLru3WXjHgo4ovp6bcyDtSkE7sRMhw8sATmmHNI0/Mz +ImDS4r87LP5JqYY4iS6c24j41HaKBMhTEk2oQ0fXGOP4/q6Pzu4JClaF0ZGrQbdp +dL+5aPL/0UX2Y3Ybq08vRQ8X5LUrKdEnrBeChrbfybjhOyNtllt49CmUsRYQVro5 +A2VTfroWSU7UfVUBPlI9UrATNvBmX+5fbctM6Go30dWsRXnlk4IcZHoUaA+6satK +HoWqzY9T4cQuNDSCTMe3TVT8VgYjrGWe9tQYRQIDAQABAoIBAGzgTXZFOVU6YHWf +I66BhOxs4ShvH0W6H0r0zbRRXp3qaHi90IgdKZgbnUFtyExs5GL6Y/jTXLRproKg +ZVGG755ZYHGgqf+2kmCsiq4Si3cJrkEtVQs+8uxt+Prh+rgb6wfDlBtcNITxA/YW +OGij8LA2mxV1R99+Px7KcRypjgMmx0Dp3NDoYE9Hj2VRVRLTo06WpZ7Mo9zfXtx6 +MHeJwmSerWzERvUHmrX4hG8Do3cygYnd8EartBjCIa/qambXlz7uG1ip3/v05VJi +w28VUVEERASy2W/OJjwe8QSmUQ/1HzKz+Vv/WCEvVINQr/o4TwJeZrASQ6bj1JCa +CVR8mCUCgYEA+lZhEYnmuypNhJsBwQJJIvqIIF4zrRqojax5kWAiRDJY2AYAxozG +K/WP3NWrR+k+Q+wdzad9QBddLru1ykhBSPLGbvU2cupyiSDMg6R5vL4xcdWSD1Ej +VKSUxSgP0ue7GeMsTgr8vT59UG7R6Mc6+H5ZLt6q3DsOwqs8He6NSa8CgYEA/Fqp +HhaOSz85GWPtMUdsXJC14WiKmKDaCYxiQ9QUP8l7M8xPSiarhh9xc2EZDjSOR/SU +jmDSCFUvQHE0H9xdWp69W15bxnD6Z4uSrAFWThsRdp9kRckcKLUDuumoeOL3WI3x +gS49YS5uEP08oSPpsD4P98Llw+l/UimFI4RDHksCgYEAvpC86d4BL59fTT+2URgN +VrxCnek4C2FMyDRwgpMc4q805JWFR5/oR5RyRFi/P0m15Xy7n08N0Jk4jRfFpkvk +rsRo/BRcs5P3Rp4aMWgmZ+CcwRwkSNaqP4fd3EvH5/QRgP5nPq2sgd8tA+qojjwD +jyCXgU9t36JxdQ1nAR4Une8CgYEAx+7APGFcfUtq3q3n13oh5TiVkS+1VvVhqdz6 +YYjePidQIBrH2xTGIm45AVO1eSa0b1fcdu1Immd7F1BZHsEFiW1o0sHwbklGatEO +9I3epeUWMehYll2enLXFbcn/uz7+/r7+zv0mjh8t/vHTnkuIsySInCBiz5PoVt0k +aZ45Wv8CgYAGj1ojQXs3SWQ+YY+rWrcMJ8atz9M4e7s8gEFiSp68ooi1kiVEKA2S +h4O79oksTAS1mgHiG237X6mJMkENpbPh8FR0hTcXbSyd7Ruki6h0LQnyXPGoV6KF +sojGWnJVDAtDMIT/z+tY4aeJbcicIgwS9oZ+dXQ/eQZiGKGOVexzwQ== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIRAMThBFxQ+GQhzdihMNsQxgEwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMEUxETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEaMBgGA1UEAxMRbG9naW4uZXhhbXBs +ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD2xa9L1iwhSWbj +DeKRVSOwKDWFvDJv8FIQalGxUbw6jHS3rZEwQgbvSU98yDYh4lkMN0Wt4uu7dZeM +eCjii+nptzIO1KQTuxEyHDywBOaYc0jT8zMiYNLivzss/kmphjiJLpzbiPjUdooE +yFMSTahDR9cY4/j+ro/O7gkKVoXRkatBt2l0v7lo8v/RRfZjdhurTy9FDxfktSsp +0SesF4KGtt/JuOE7I22WW3j0KZSxFhBWujkDZVN+uhZJTtR9VQE+Uj1SsBM28GZf +7l9ty0zoajfR1axFeeWTghxkehRoD7qxq0oeharNj1PhxC40NIJMx7dNVPxWBiOs +ZZ721BhFAgMBAAGjfjB8MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEF +BQcDATAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFJawVbck1iUFkYpi3mV69pqz +s8toMCYGA1UdEQQfMB2CEWxvZ2luLmV4YW1wbGUuY29tgghhdXRoZWxpYTANBgkq +hkiG9w0BAQsFAAOCAQEALqCLqIAM8wi0M12hMs4dARRtEEAZm/ff8B18SgBuES79 +qeas6pggPRmpfM3Ogjk+t8qG02yQeAF9zqAFXaI46kQxQohKcCrfW96pX91Tvuwc +x+3xsnHWj+FoI99uUGldDjVJoePXXB7wKB3/26o7dlcWry7y04cURvD3v/v/zABw +hPB5+t+5lB+kGSZg7ChnCDBLJx8/y9JTHKbZL3kHenvPHOn+T6aRQKNmAGpGwqV4 +Eq+lB/YKU9JADarOF5FCTux677JO1XdDcnooGZmbUrKbjzO/NnbREjBRZYfqJiV6 +uTz/I2MJ7IUiYh18xT3ZL2oUbnWly+TnR9oWnwSqLg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIRAPl83YWFsuwIwxBRmdJyLLQwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMFsxETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEwMC4GA1UEAxMnQXV0aGVsaWEgRGV2 +ZWxvcG1lbnQgU3RhbmRhbG9uZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA2RtD74ISXHruAIIkIRTLGf5VK0b7iN5+CPW8qWjg74PCnid1 +3DOqVCZ3HSXMP0iaH5rd+WAYojQo5Z1uZ75tXgzYjt6tyXG5H1nN1fkmjkHyNORP +abOZtngVaixvlT/hsONXszFdqogXhhI4DtEo0lvxJcnOHER4QVylM4YgDMF85jXi +VD893Y6Luik9B6FXLVK9iAJ5MfvD/r8kEPLsDTl2u/Ye0q4igVDJq9tOtb2enhlz +HtipYhzzNwEzQwy3tjzP9xpQG6XE6/JW20gQaBvoRBN64DMgRlh1/8ZVyYE8v/B1 +vRVpSgmyCdDJeaRYZ6J+hO3LXBXU20CVZsM5VQIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUlrBVtyTWJQWRimLeZXr2 +mrOzy2gwDQYJKoZIhvcNAQELBQADggEBAKXjAw5v8VTM6EDiUvR8XdiikYkycAG/ +hcEt+QLkkBb72+tUNYbr57YJeJuqQcaPTBUQrIXsID8JV5dQJFfyIG2s3G0iuN70 +W4fSRPqsSBIcyOK+2APLjkYV8qwLdh03Lyll4SZo7PCK8ItemsIK1NWhd74N49fm ++a8eyY5bgfA0FMkjY/ts4gAnYExGRoLOQRu/CgOvBlj2KQUrSNptze1rNlP32b63 +eUv1wf/ajK2TxI1pQgkeu2lM3Tyu7q7J4UVn0UY0wtZvHtw2+UBGKZB3ok6ejBy2 +HMjgLGuayGjhyUN8zRkuSvBynuI2wGhIlHklEbaQW5oFKbniXRqdzc4= +-----END CERTIFICATE----- diff --git a/internal/suites/common/pki/private.chain.pem b/internal/suites/common/pki/private.chain.pem new file mode 100644 index 000000000..d6d671df8 --- /dev/null +++ b/internal/suites/common/pki/private.chain.pem @@ -0,0 +1,72 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA6iddZfII40v7nj01EmJNkzWvTZJm2WskbPi+hFlXquYeltt6 +JZsrttfatYYcraAM5weD6irYzNIBEuQQQ7mtjKlZQmgFtrTcA4xGMpjjQhOI0LJs +LhGMGYDw5ZFRTHuHjhAAUsBQi8gEEwCoqt2sC/sh1TlirLiGqPCA6lQsFeoYmUDs +4OC6bBMKn0ceS1jRODB845kpv37NQN3fEqR6z3ErmCoSVUNL9IGwfM2MeeDg2X1W +0eJ3I4ojLpdG7nYhnwO3guV0XxHWqQQ7yLEjEiffiv8GFPqigPf+qVJDhBzBdYmQ +5tGfRZjafNXmI987Nlho08eGZ12E6sJJdQjjmQIDAQABAoIBAQDm/7rGbgaSpk0v +CNcosc4yIk41Su8oIukmkCbzzmgMc0VOMmvIWdLAaSac2hfEuhbAfMuI4ohLWAoz +Jsdc6Prrv84NEy4/1yEOZv6BwA7DCx54NO1AbZM3PdtpvvjjaSKL5gFLoepUXBiY +3peHKXUnxLLV9e0A1HIUjF/BzRRI8GwBjgUgljJQXCdBk7bHKkep8U4SGScQI6bK +fUcwt4dL7nLObSqRNQYSZJYT8CXw1XbfK51mZFCsPIQ8TE+M6B1ato1umYFk3gr9 +CaEVeTpYc9R4HDmmXJT7r5kzQQ/Yciqksgv4pVyAsKGclVyhYN57pCyj82xnHvAL +NJaZ2yt5AoGBAPGaQXLOeGildhdEsDBF7rNGecJOCZEB4f2WTiun8rUP/75fIbn3 +NW5kBU2oicMyZSrj9EZ4nho07CoPFl5GCqgK4iwwqzdgPi50oxavW6YMS2OBgrmS +2EXVyHqSwuAEJBn5kYYdd7uCLcw54lrXkokHMbXJC/dzbfUDaGVWMSXDAoGBAPgb +eZADZUZi0KXZ1l47IiMfVO2d+2Ly/gGaeDC8dsZ4eSsoi5F6cheZAxqAjSQhg30M +1NbZJ0GV2PHTjK1a4q4D9vBjSA6cpfbsgutXPHLvbQMOu68hVJxyqCzpW2M9kd5D +1/uqkHy4Wcp6MuprR+/tXWMtcxr50Hmie/3M349zAoGBAMdJ8ZCs5T+UtItO+nJn +TRWOHaN8UYHOZsaRtBtopthZwSAcQqquUuGjGYjMbA6aRD8T14xFtExzuRacaVwM +NIAWsie3YZQFDGWvilONBHE8lPcYfmdqzIEWbg9Fff/hCpJufW5+YiRGplZerOs4 +BMSJLaUAmKFeEqZXUEa+yT2XAoGAXRlyNCgSCKdrw9BKMHHgDW3kYIW3nxmvVsqv +7xnJOBBc52T/ekeIKHKyR2+VhslMndACzdwObv3bumK3lxVTmhjCwNGAaHs/i7iU +J9tEQ5y0O0F8C+tl5I7hrHikYkjoQ48RrM4ECcjjaKcSFATNqapYMK8NUkILiJkA +DeyityECgYAmvQrY8IBU94NVxx5hYzUC72JMApkc6D7PhU/UfGjm3EL55/EyNGcs +aIHwarqdvdUeOSnouuhhfHLoyyyUSx3g4KyRpZpM+yPWMFAm+dZkz1I0qctbFvRO ++YnNDdU6s2cIJ9wAYtr84QtYSpmtiBDwloP04P3w8TT3q1YMfij93Q== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIEAjCCAuqgAwIBAgIRANNLpYRP6sc/Inl85QPEXJcwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMEExETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEWMBQGA1UEAwwNKi5leGFtcGxlLmNv +bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOonXWXyCONL+549NRJi +TZM1r02SZtlrJGz4voRZV6rmHpbbeiWbK7bX2rWGHK2gDOcHg+oq2MzSARLkEEO5 +rYypWUJoBba03AOMRjKY40ITiNCybC4RjBmA8OWRUUx7h44QAFLAUIvIBBMAqKrd +rAv7IdU5Yqy4hqjwgOpULBXqGJlA7ODgumwTCp9HHktY0TgwfOOZKb9+zUDd3xKk +es9xK5gqElVDS/SBsHzNjHng4Nl9VtHidyOKIy6XRu52IZ8Dt4LldF8R1qkEO8ix +IxIn34r/BhT6ooD3/qlSQ4QcwXWJkObRn0WY2nzV5iPfOzZYaNPHhmddhOrCSXUI +45kCAwEAAaOB2DCB1TAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH +AwEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSWsFW3JNYlBZGKYt5levaas7PL +aDB/BgNVHREEeDB2gg0qLmV4YW1wbGUuY29tggtleGFtcGxlLmNvbYIOKi5leGFt +cGxlMS5jb22CDGV4YW1wbGUxLmNvbYIOKi5leGFtcGxlMi5jb22CDGV4YW1wbGUy +LmNvbYIOKi5leGFtcGxlMy5jb22CDGV4YW1wbGUzLmNvbTANBgkqhkiG9w0BAQsF +AAOCAQEAmUscEh131hh0MR6xsu4oIJO0SDTL43UNdsaZI5jarXEfmfVz18uSdjp1 +tYVe7UJoi0iLMGzwIYcvnGv+HD91R7V0VFF78R+jHeAMtzGX/YDpUqjLBXXcPQ57 +vUZIPxTE1V/qCd3MX1CHjfZEK2NbKvB3ciqBcryarbbAET65jCMtn1xk7KIFWEH7 +Y2TuYMMi6QRYmep6u0LF2l61ZM7Awog31PBMrXRFQCVb8fS9KHnKthyS3BtdD2EU +xgxqkXnywhDQ2jTXGxKoQUIJnB/Niw38uQZAsLuyluncgjGKjYJ9eSacCZ+UJWeG +wVRoE07p3GTJAdnyPgeQqGG1gJP4lA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIRAPl83YWFsuwIwxBRmdJyLLQwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMFsxETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEwMC4GA1UEAxMnQXV0aGVsaWEgRGV2 +ZWxvcG1lbnQgU3RhbmRhbG9uZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA2RtD74ISXHruAIIkIRTLGf5VK0b7iN5+CPW8qWjg74PCnid1 +3DOqVCZ3HSXMP0iaH5rd+WAYojQo5Z1uZ75tXgzYjt6tyXG5H1nN1fkmjkHyNORP +abOZtngVaixvlT/hsONXszFdqogXhhI4DtEo0lvxJcnOHER4QVylM4YgDMF85jXi +VD893Y6Luik9B6FXLVK9iAJ5MfvD/r8kEPLsDTl2u/Ye0q4igVDJq9tOtb2enhlz +HtipYhzzNwEzQwy3tjzP9xpQG6XE6/JW20gQaBvoRBN64DMgRlh1/8ZVyYE8v/B1 +vRVpSgmyCdDJeaRYZ6J+hO3LXBXU20CVZsM5VQIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUlrBVtyTWJQWRimLeZXr2 +mrOzy2gwDQYJKoZIhvcNAQELBQADggEBAKXjAw5v8VTM6EDiUvR8XdiikYkycAG/ +hcEt+QLkkBb72+tUNYbr57YJeJuqQcaPTBUQrIXsID8JV5dQJFfyIG2s3G0iuN70 +W4fSRPqsSBIcyOK+2APLjkYV8qwLdh03Lyll4SZo7PCK8ItemsIK1NWhd74N49fm ++a8eyY5bgfA0FMkjY/ts4gAnYExGRoLOQRu/CgOvBlj2KQUrSNptze1rNlP32b63 +eUv1wf/ajK2TxI1pQgkeu2lM3Tyu7q7J4UVn0UY0wtZvHtw2+UBGKZB3ok6ejBy2 +HMjgLGuayGjhyUN8zRkuSvBynuI2wGhIlHklEbaQW5oFKbniXRqdzc4= +-----END CERTIFICATE----- diff --git a/internal/suites/common/pki/private.oidc.chain.pem b/internal/suites/common/pki/private.oidc.chain.pem new file mode 100644 index 000000000..81d3250fc --- /dev/null +++ b/internal/suites/common/pki/private.oidc.chain.pem @@ -0,0 +1,71 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA0x+u2Kkd1VZGkj7FDwgoXQp0fx1mx5VXd2VEJN9yYTXzlNRZ +Taw8WrOcud7hsBPw3DkhbCjEzvw0Ee+DjwtSCotKbtsBwjyLCegjluPHKUvsVNYZ +m19TxYY2erx7gohdEcmCGnpWSPRUAKBasIfpM0q6LXG70o8vTuKS82Ub++Sgl1Pa +kRL/e/KBUYFZksGEMK1oiPiOtRoJF+vUhRf46ZBg3aZ/HLNvcT5TAMgRRws+K3ek +C5+h5oXFexUosj2DCxcjTbsL7C5nqfR3jwmjrBaGN8KnloEDvC84+OsN/nE2PLa5 +c1kTlRCvKd0gmRuucOKsJ6zvYf/hAqp/WCj1MQIDAQABAoIBAAOHCP3XvYbd/Sne +YJ6CrWH4lb+19wyooyB8kanoDdov85TuA1v3375IN/snDTBK9QBI+BT9jWRD9H7E +OLeAIevJLgIyKJJdPpl4xndz8NTwzs8QELd23Uh0mJ5uXcXtj1iHvGPC3YQ0iN7F +zx4Z9zyDKB8wQkofWFQCFyB39QK9ZGDW4ZstVb57fS62SuqFPW/rO2qSpsuUUwgy +Z2P2NqoqtqLIyw3qbsJCArzGoHuMCtjKDYenf8wJxORAsAGAREj71w2bQ20cMMIA +w30jgoXtEC9zS2BOb3mUBHiDOKnn4vwlNd7wiLPdZIGP75G4EkI4AHLhJQ1a5YuF +8E6V9AECgYEA1LSQVdWggvHTQnj5PHr5k7+YkL/MeIvOkLW5s0r7Lt3x45bAFaQh +XVZIXrynv62IZmTzCPwOwrXGJJieT0Ctom0XHgtp8nu7Okxk4AISRfjy7J03EXsJ +cS508IJ1B3HZepGvVwp+geJ0r9JmQ19JqZsJ7VENYoPKtYRZ9aV7CUECgYEA/hi1 +Yw2FcSBk/kXVlcWvKtohY6NISgI5U1Kp7T16ZH3anpew6WwQ3GfueVet714BdwaZ +knqiiMvaTAOG66KYHCzRBSeXOozT/0N9AfKqS1y7xW+mR2nUrAiWCL95uZpB9SxE +3gylWULV4/+wlF006tEcJ5qiXymAAYv+wEg+f/ECgYBu2XLm6J/v3esFF1p8RHJQ +p2bw+KOspt+N1sbiQ09IC26F9wg/vvuMUu0AQj0BzYPqKO3nXsSqgGS0qbzG/KQA +o+2KQNSEBCt8pFdlzm6LfMPMv9n1CDPRgi57MOGgcZqvH8FLETMAqW26O2ID9mLD +OwMfZEAfeSNpGYJwXD8UgQKBgQC+0k1+Csx47YwKzOUeqivncZL7occLFWp5oa3N +ZYsB5uYEjgSk96wd6ctUwzzzc1SET6eLMp/XPcg9p7RuR1gWaK28QkQ3C0W2ALfj +e5raJ9U366YjIV4+p+AMx8chVLBN8CXz3+lZBHFe3Ul90hWIduu+7kkcUC06fCkf +u+F78QKBgFajhBPESe344ixG/fASpsVe2Yg14SgYCeWkinOe856zABY8dkfWWBIq +KX2eq1WJXErHWDuuNPP3Jol1CouqqHseqYQ+SaOhlHdoGws70bsIvBHrtj7NiEQZ +HFLhEk+OnnG+wJ1jQ5cseA4kbTuPjEL0NNVk7OSndiuxnnDbe91R +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIID3zCCAsegAwIBAgIQZjmlbZI+QaeqQpApxA2eDjANBgkqhkiG9w0BAQsFADBb +MREwDwYDVQQKEwhBdXRoZWxpYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxMDAuBgNV +BAMTJ0F1dGhlbGlhIERldmVsb3BtZW50IFN0YW5kYWxvbmUgUm9vdCBDQTAgFw0w +MDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowRTERMA8GA1UEChMIQXV0aGVs +aWExFDASBgNVBAsTC0RldmVsb3BtZW50MRowGAYDVQQDExFsb2dpbi5leGFtcGxl +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANMfrtipHdVWRpI+ +xQ8IKF0KdH8dZseVV3dlRCTfcmE185TUWU2sPFqznLne4bAT8Nw5IWwoxM78NBHv +g48LUgqLSm7bAcI8iwnoI5bjxylL7FTWGZtfU8WGNnq8e4KIXRHJghp6Vkj0VACg +WrCH6TNKui1xu9KPL07ikvNlG/vkoJdT2pES/3vygVGBWZLBhDCtaIj4jrUaCRfr +1IUX+OmQYN2mfxyzb3E+UwDIEUcLPit3pAufoeaFxXsVKLI9gwsXI027C+wuZ6n0 +d48Jo6wWhjfCp5aBA7wvOPjrDf5xNjy2uXNZE5UQryndIJkbrnDirCes72H/4QKq +f1go9TECAwEAAaOBsjCBrzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYB +BQUHAwEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSWsFW3JNYlBZGKYt5levaa +s7PLaDBZBgNVHREEUjBQghFsb2dpbi5leGFtcGxlLmNvbYISbG9naW4uZXhhbXBs +ZTEuY29tghJsb2dpbi5leGFtcGxlMi5jb22CDmxvZ2luLmV4YW1wbGUzggNjb20w +DQYJKoZIhvcNAQELBQADggEBAH46LB6fFF+5dbFhEa8rsDX17oZPVsIMHi+vhmMh +aS5IACOpmc3q/yyhZelNwB/MRzlPziQwpqwr9B5SQ9UOBvZDuv9ESXYHlVHSIGo9 ++3Ax9fvxLVpF3E62whr+d8YHjXE85UgUKaDAWYCAVB7fkY7WfyS3t8IxgJVa+oMZ +sLeI4YmheKdgRZsE+83VcNUVuGhsh3R5NKFo46tonpbdx13Eg2k3IInKAkZmTA5D +YoPfPTDbd1BOC+h2C0s+guUyoG1Fi5DzS/x8xNoRcZ7/fkdcboAXa8dlVZeqGRky +ddYggjZYnqGaD9qKFAox4EqkCYB1XwNeUPUapdvGICC7UGc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIRAPl83YWFsuwIwxBRmdJyLLQwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMFsxETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEwMC4GA1UEAxMnQXV0aGVsaWEgRGV2 +ZWxvcG1lbnQgU3RhbmRhbG9uZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA2RtD74ISXHruAIIkIRTLGf5VK0b7iN5+CPW8qWjg74PCnid1 +3DOqVCZ3HSXMP0iaH5rd+WAYojQo5Z1uZ75tXgzYjt6tyXG5H1nN1fkmjkHyNORP +abOZtngVaixvlT/hsONXszFdqogXhhI4DtEo0lvxJcnOHER4QVylM4YgDMF85jXi +VD893Y6Luik9B6FXLVK9iAJ5MfvD/r8kEPLsDTl2u/Ye0q4igVDJq9tOtb2enhlz +HtipYhzzNwEzQwy3tjzP9xpQG6XE6/JW20gQaBvoRBN64DMgRlh1/8ZVyYE8v/B1 +vRVpSgmyCdDJeaRYZ6J+hO3LXBXU20CVZsM5VQIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUlrBVtyTWJQWRimLeZXr2 +mrOzy2gwDQYJKoZIhvcNAQELBQADggEBAKXjAw5v8VTM6EDiUvR8XdiikYkycAG/ +hcEt+QLkkBb72+tUNYbr57YJeJuqQcaPTBUQrIXsID8JV5dQJFfyIG2s3G0iuN70 +W4fSRPqsSBIcyOK+2APLjkYV8qwLdh03Lyll4SZo7PCK8ItemsIK1NWhd74N49fm ++a8eyY5bgfA0FMkjY/ts4gAnYExGRoLOQRu/CgOvBlj2KQUrSNptze1rNlP32b63 +eUv1wf/ajK2TxI1pQgkeu2lM3Tyu7q7J4UVn0UY0wtZvHtw2+UBGKZB3ok6ejBy2 +HMjgLGuayGjhyUN8zRkuSvBynuI2wGhIlHklEbaQW5oFKbniXRqdzc4= +-----END CERTIFICATE----- diff --git a/internal/suites/common/pki/public.backend.bundle.crt b/internal/suites/common/pki/public.backend.chain.pem similarity index 100% rename from internal/suites/common/pki/public.backend.bundle.crt rename to internal/suites/common/pki/public.backend.chain.pem diff --git a/internal/suites/common/pki/public.bundle.crt b/internal/suites/common/pki/public.chain.pem similarity index 100% rename from internal/suites/common/pki/public.bundle.crt rename to internal/suites/common/pki/public.chain.pem diff --git a/internal/suites/common/pki/public.oidc.bundle.crt b/internal/suites/common/pki/public.oidc.chain.pem similarity index 100% rename from internal/suites/common/pki/public.oidc.bundle.crt rename to internal/suites/common/pki/public.oidc.chain.pem diff --git a/internal/suites/example/compose/envoy/envoy.yaml b/internal/suites/example/compose/envoy/envoy.yaml index 7af1e2e90..2e7248e7f 100644 --- a/internal/suites/example/compose/envoy/envoy.yaml +++ b/internal/suites/example/compose/envoy/envoy.yaml @@ -125,7 +125,7 @@ static_resources: common_tls_context: tls_certificates: - certificate_chain: - filename: /pki/public.bundle.crt + filename: /pki/public.chain.pem private_key: filename: /pki/private.pem clusters: diff --git a/internal/suites/example/compose/nginx/portal/nginx.conf b/internal/suites/example/compose/nginx/portal/nginx.conf index 3d97aeebc..a6986fe06 100644 --- a/internal/suites/example/compose/nginx/portal/nginx.conf +++ b/internal/suites/example/compose/nginx/portal/nginx.conf @@ -16,7 +16,7 @@ http { set $backend_endpoint https://authelia-backend:9091; set $metrics_endpoint http://authelia-backend:9959; - ssl_certificate /pki/public.bundle.crt; + ssl_certificate /pki/public.chain.pem; ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; @@ -128,7 +128,7 @@ http { resolver 127.0.0.11 ipv6=off; set $upstream_endpoint http://nginx-backend; - ssl_certificate /pki/public.bundle.crt; + ssl_certificate /pki/public.chain.pem; ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; @@ -152,7 +152,7 @@ http { set $upstream_endpoint http://nginx-backend; set $upstream_headers http://httpbin:8000/headers; - ssl_certificate /pki/public.bundle.crt; + ssl_certificate /pki/public.chain.pem; ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; @@ -295,7 +295,7 @@ http { set $upstream_authelia https://authelia-backend:9091/api/authz/auth-request; set $upstream_endpoint http://oidc-client:8080; - ssl_certificate /pki/public.bundle.crt; + ssl_certificate /pki/public.chain.pem; ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; @@ -393,7 +393,7 @@ http { resolver 127.0.0.11 ipv6=off; set $upstream_endpoint http://smtp:1080; - ssl_certificate /pki/public.bundle.crt; + ssl_certificate /pki/public.chain.pem; ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; @@ -415,7 +415,7 @@ http { resolver 127.0.0.11 ipv6=off; set $upstream_endpoint http://duo-api:3000; - ssl_certificate /pki/public.bundle.crt; + ssl_certificate /pki/public.chain.pem; ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; @@ -434,7 +434,7 @@ http { listen 8080 ssl; server_name _; - ssl_certificate /pki/public.bundle.crt; + ssl_certificate /pki/public.chain.pem; ssl_certificate_key /pki/private.pem; return 301 https://home.example.com:8080/; diff --git a/internal/utils/crypto.go b/internal/utils/crypto.go index 425b5f10b..3f177fb1e 100644 --- a/internal/utils/crypto.go +++ b/internal/utils/crypto.go @@ -308,18 +308,30 @@ func NewX509CertPool(directory string) (certPool *x509.CertPool, warnings []erro // WriteCertificateBytesToPEM writes a certificate/csr to a file in the PEM format. func WriteCertificateBytesToPEM(path string, csr bool, certs ...[]byte) (err error) { - out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - return fmt.Errorf("failed to open %s for writing: %w", path, err) - } - blockType := BlockTypeCertificate if csr { blockType = BlockTypeCertificateRequest } - for _, cert := range certs { - if err = pem.Encode(out, &pem.Block{Bytes: cert, Type: blockType}); err != nil { + blocks := make([]*pem.Block, len(certs)) + + for i, cert := range certs { + blocks[i] = &pem.Block{Type: blockType, Bytes: cert} + } + + return WritePEM(path, blocks...) +} + +// WritePEM writes a set of *pem.Blocks to a file. +func WritePEM(path string, blocks ...*pem.Block) (err error) { + var out *os.File + + if out, err = os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600); err != nil { + return err + } + + for _, block := range blocks { + if err = pem.Encode(out, block); err != nil { _ = out.Close() return err @@ -331,23 +343,12 @@ func WriteCertificateBytesToPEM(path string, csr bool, certs ...[]byte) (err err // WriteKeyToPEM writes a key that can be encoded as a PEM to a file in the PEM format. func WriteKeyToPEM(key any, path string, pkcs8 bool) (err error) { - pemBlock, err := PEMBlockFromX509Key(key, pkcs8) + block, err := PEMBlockFromX509Key(key, pkcs8) if err != nil { return err } - out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - return fmt.Errorf("failed to open %s for writing: %w", path, err) - } - - if err = pem.Encode(out, pemBlock); err != nil { - _ = out.Close() - - return err - } - - return out.Close() + return WritePEM(path, block) } // PEMBlockFromX509Key turns a PublicKey or PrivateKey into a pem.Block.