refactor(commands): x509 bundling (#4942)

This adds another bundling mode to the certificate command.
pull/4945/head
James Elliott 2023-02-17 14:29:07 +11:00 committed by GitHub
parent 98e6fdc69f
commit 891f1de9f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 387 additions and 140 deletions

View File

@ -35,7 +35,7 @@ authelia crypto certificate ecdsa generate --help
### Options ### Options
``` ```
--bundle enables generating the certificate bundle if the --path.ca flag is set --bundles strings enables generating bundles options are 'chain' and 'privkey-chain'
--ca create the certificate as a certificate authority certificate --ca create the certificate as a certificate authority certificate
-n, --common-name string certificate common name -n, --common-name string certificate common name
--country strings certificate country --country strings certificate country
@ -43,10 +43,11 @@ authelia crypto certificate ecdsa generate --help
-d, --directory string directory where the generated keys, certificates, etc will be stored -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") --duration string duration of time the certificate is valid for (default "1y")
--extended-usage strings specify the extended usage types of the certificate --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-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.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 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") --file.private-key string name of the file to export the private key data to (default "private.pem")
-h, --help help for generate -h, --help help for generate
-l, --locality strings certificate locality -l, --locality strings certificate locality

View File

@ -35,17 +35,18 @@ authelia crypto certificate ed25519 request --help
### Options ### Options
``` ```
--bundle enables generating the certificate bundle if the --path.ca flag is set --bundles strings enables generating bundles options are 'chain' and 'privkey-chain'
--ca create the certificate as a certificate authority certificate --ca create the certificate as a certificate authority certificate
-n, --common-name string certificate common name -n, --common-name string certificate common name
--country strings certificate country --country strings certificate country
-d, --directory string directory where the generated keys, certificates, etc will be stored -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") --duration string duration of time the certificate is valid for (default "1y")
--extended-usage strings specify the extended usage types of the certificate --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-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.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 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") --file.private-key string name of the file to export the private key data to (default "private.pem")
-h, --help help for generate -h, --help help for generate
-l, --locality strings certificate locality -l, --locality strings certificate locality

View File

@ -36,17 +36,18 @@ authelia crypto certificate rsa generate --help
``` ```
-b, --bits int number of RSA bits for the certificate (default 2048) -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 --bundles strings enables generating bundles options are 'chain' and 'privkey-chain'
--ca create the certificate as a certificate authority certificate --ca create the certificate as a certificate authority certificate
-n, --common-name string certificate common name -n, --common-name string certificate common name
--country strings certificate country --country strings certificate country
-d, --directory string directory where the generated keys, certificates, etc will be stored -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") --duration string duration of time the certificate is valid for (default "1y")
--extended-usage strings specify the extended usage types of the certificate --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-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.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 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") --file.private-key string name of the file to export the private key data to (default "private.pem")
-h, --help help for generate -h, --help help for generate
-l, --locality strings certificate locality -l, --locality strings certificate locality

View File

@ -537,12 +537,13 @@ const (
cmdFlagNameDirectory = "directory" cmdFlagNameDirectory = "directory"
cmdFlagNamePathCA = "path.ca" cmdFlagNamePathCA = "path.ca"
cmdFlagNameBundle = "bundle" cmdFlagNameBundles = "bundles"
cmdFlagNameFilePrivateKey = "file.private-key" cmdFlagNameFilePrivateKey = "file.private-key"
cmdFlagNameFilePublicKey = "file.public-key" cmdFlagNameFilePublicKey = "file.public-key"
cmdFlagNameFileCertificate = "file.certificate" cmdFlagNameFileCertificate = "file.certificate"
cmdFlagNameFileCertificateBundle = "file.certificate-bundle" cmdFlagNameFileBundleChain = "file.bundle.chain"
cmdFlagNameFileBundlePrivKeyChain = "file.bundle.priv-chain"
cmdFlagNameFileCAPrivateKey = "file.ca-private-key" cmdFlagNameFileCAPrivateKey = "file.ca-private-key"
cmdFlagNameFileCACertificate = "file.ca-certificate" cmdFlagNameFileCACertificate = "file.ca-certificate"
cmdFlagNameFileCSR = "file.csr" cmdFlagNameFileCSR = "file.csr"

View File

@ -365,7 +365,7 @@ func (ctx *CmdCtx) CryptoCertificateGenerateRunE(cmd *cobra.Command, _ []string,
return err return err
} }
b := strings.Builder{} b := &strings.Builder{}
b.WriteString("Generating Certificate\n\n") 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), ", "))) b.WriteString(fmt.Sprintf("\n\tSubject Alternative Names: %s\n\n", strings.Join(cryptoSANsToString(template.DNSNames, template.IPAddresses), ", ")))
var ( var (
dir, privateKeyPath, certificatePath, certificateBundlePath string dir, privateKeyPath, certificatePath string
bundle bool
certificate []byte certificate []byte
) )
@ -412,10 +411,6 @@ func (ctx *CmdCtx) CryptoCertificateGenerateRunE(cmd *cobra.Command, _ []string,
return err return err
} }
if bundle, certificateBundlePath, err = cryptoGetCertificateBundleFromCmd(cmd, dir, caCertificate); err != nil {
return err
}
b.WriteString("Output Paths:\n") b.WriteString("Output Paths:\n")
b.WriteString(fmt.Sprintf("\tPrivate Key: %s\n", privateKeyPath)) b.WriteString(fmt.Sprintf("\tPrivate Key: %s\n", privateKeyPath))
b.WriteString(fmt.Sprintf("\tCertificate: %s\n", certificatePath)) b.WriteString(fmt.Sprintf("\tCertificate: %s\n", certificatePath))
@ -432,10 +427,8 @@ func (ctx *CmdCtx) CryptoCertificateGenerateRunE(cmd *cobra.Command, _ []string,
return err return err
} }
if bundle { if cmd.Flags().Changed(cmdFlagNameBundles) {
b.WriteString(fmt.Sprintf("\tCertificate (bundle): %s\n", certificateBundlePath)) if err = cryptoGenerateCertificateBundlesFromCmd(cmd, b, dir, caCertificate, certificate, privateKey); err != nil {
if err = utils.WriteCertificateBytesToPEM(certificateBundlePath, false, certificate, caCertificate.Raw); err != nil {
return err return err
} }
} }

View File

@ -7,6 +7,7 @@ import (
"crypto/rsa" "crypto/rsa"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
"encoding/pem"
"fmt" "fmt"
"math/big" "math/big"
"net" "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(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(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(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().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().Bool(cmdFlagNameBundle, false, fmt.Sprintf("enables generating the certificate bundle if the --%s flag is set", cmdFlagNamePathCA)) 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") 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 return privateKey, nil
} }
func cryptoGetCertificateBundleFromCmd(cmd *cobra.Command, dir string, caCertificate *x509.Certificate) (bundle bool, bundlePath string, err error) { func cryptoGenerateCertificateBundlesFromCmd(cmd *cobra.Command, b *strings.Builder, dir string, ca *x509.Certificate, certificate []byte, privkey any) (err error) {
if bundle, err = cmd.Flags().GetBool(cmdFlagNameBundle); err != nil { var bundles []string
return false, "", err
if bundles, err = cmd.Flags().GetStringSlice(cmdFlagNameBundles); err != nil {
return err
} }
if !bundle { blocks := []*pem.Block{
return bundle, bundlePath, err {Type: utils.BlockTypeCertificate, Bytes: certificate},
} }
if caCertificate == nil { if ca != 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) blocks = append(blocks, &pem.Block{Type: utils.BlockTypeCertificate, Bytes: ca.Raw})
} }
if bundlePath, err = cmd.Flags().GetString(cmdFlagNameFileCertificateBundle); err != nil { var name string
return false, "", err
if utils.IsStringInSliceFold("chain", bundles) {
if name, err = cmd.Flags().GetString(cmdFlagNameFileBundleChain); err != nil {
return err
} }
bundlePath = filepath.Join(dir, bundlePath) pathPEM := filepath.Join(dir, name)
return bundle, bundlePath, err b.WriteString(fmt.Sprintf("\tCertificate (chain): %s\n", pathPEM))
if err = utils.WritePEM(pathPEM, blocks...); err != nil {
return err
}
}
if utils.IsStringInSliceFold("priv-chain", bundles) {
if name, err = cmd.Flags().GetString(cmdFlagNameFileBundlePrivKeyChain); err != nil {
return 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) { func cryptoGetCAFromCmd(cmd *cobra.Command) (privateKey any, cert *x509.Certificate, err error) {

View File

@ -3,7 +3,7 @@ version: '3'
services: services:
authelia-backend: authelia-backend:
environment: 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 AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE: /pki/private.oidc.pem
volumes: volumes:
- './OIDC/configuration.yml:/config/configuration.yml:ro' - './OIDC/configuration.yml:/config/configuration.yml:ro'

View File

@ -3,7 +3,7 @@ version: '3'
services: services:
authelia-backend: authelia-backend:
environment: 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 AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE: /pki/private.oidc.pem
volumes: volumes:
- './OIDCTraefik/configuration.yml:/config/configuration.yml:ro' - './OIDCTraefik/configuration.yml:/config/configuration.yml:ro'

View File

@ -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 # 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 # 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 --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 --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 --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 --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' --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'

View File

@ -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-----

View File

@ -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-----

View File

@ -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-----

View File

@ -125,7 +125,7 @@ static_resources:
common_tls_context: common_tls_context:
tls_certificates: tls_certificates:
- certificate_chain: - certificate_chain:
filename: /pki/public.bundle.crt filename: /pki/public.chain.pem
private_key: private_key:
filename: /pki/private.pem filename: /pki/private.pem
clusters: clusters:

View File

@ -16,7 +16,7 @@ http {
set $backend_endpoint https://authelia-backend:9091; set $backend_endpoint https://authelia-backend:9091;
set $metrics_endpoint http://authelia-backend:9959; 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; ssl_certificate_key /pki/private.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
@ -128,7 +128,7 @@ http {
resolver 127.0.0.11 ipv6=off; resolver 127.0.0.11 ipv6=off;
set $upstream_endpoint http://nginx-backend; set $upstream_endpoint http://nginx-backend;
ssl_certificate /pki/public.bundle.crt; ssl_certificate /pki/public.chain.pem;
ssl_certificate_key /pki/private.pem; ssl_certificate_key /pki/private.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
@ -152,7 +152,7 @@ http {
set $upstream_endpoint http://nginx-backend; set $upstream_endpoint http://nginx-backend;
set $upstream_headers http://httpbin:8000/headers; 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; ssl_certificate_key /pki/private.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; 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_authelia https://authelia-backend:9091/api/authz/auth-request;
set $upstream_endpoint http://oidc-client:8080; 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; ssl_certificate_key /pki/private.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
@ -393,7 +393,7 @@ http {
resolver 127.0.0.11 ipv6=off; resolver 127.0.0.11 ipv6=off;
set $upstream_endpoint http://smtp:1080; set $upstream_endpoint http://smtp:1080;
ssl_certificate /pki/public.bundle.crt; ssl_certificate /pki/public.chain.pem;
ssl_certificate_key /pki/private.pem; ssl_certificate_key /pki/private.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
@ -415,7 +415,7 @@ http {
resolver 127.0.0.11 ipv6=off; resolver 127.0.0.11 ipv6=off;
set $upstream_endpoint http://duo-api:3000; 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; ssl_certificate_key /pki/private.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
@ -434,7 +434,7 @@ http {
listen 8080 ssl; listen 8080 ssl;
server_name _; server_name _;
ssl_certificate /pki/public.bundle.crt; ssl_certificate /pki/public.chain.pem;
ssl_certificate_key /pki/private.pem; ssl_certificate_key /pki/private.pem;
return 301 https://home.example.com:8080/; return 301 https://home.example.com:8080/;

View File

@ -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. // WriteCertificateBytesToPEM writes a certificate/csr to a file in the PEM format.
func WriteCertificateBytesToPEM(path string, csr bool, certs ...[]byte) (err error) { 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 blockType := BlockTypeCertificate
if csr { if csr {
blockType = BlockTypeCertificateRequest blockType = BlockTypeCertificateRequest
} }
for _, cert := range certs { blocks := make([]*pem.Block, len(certs))
if err = pem.Encode(out, &pem.Block{Bytes: cert, Type: blockType}); err != nil {
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() _ = out.Close()
return err 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. // 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) { func WriteKeyToPEM(key any, path string, pkcs8 bool) (err error) {
pemBlock, err := PEMBlockFromX509Key(key, pkcs8) block, err := PEMBlockFromX509Key(key, pkcs8)
if err != nil { if err != nil {
return err return err
} }
out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) return WritePEM(path, block)
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()
} }
// PEMBlockFromX509Key turns a PublicKey or PrivateKey into a pem.Block. // PEMBlockFromX509Key turns a PublicKey or PrivateKey into a pem.Block.