Adding custom certificate to the virtual clusters (#409)

* Adding custom certificate to the virtual clusters

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* wsl

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* wsl

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* fix tests

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* Fix tests

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* wsl

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* wsl

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* wsl

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* docs update

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* integrate cert-manager

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* Add individual cert tests

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* wsl

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* docs

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* docs

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* wsl

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* wsl

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

* Fixes

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>

---------

Signed-off-by: galal-hussein <hussein.galal.ahmed.11@gmail.com>
This commit is contained in:
Hussein Galal
2025-07-21 19:23:11 +03:00
committed by GitHub
parent 1048e3f82d
commit a98c49b59a
33 changed files with 1472 additions and 5 deletions

View File

@@ -223,6 +223,89 @@ spec:
x-kubernetes-validations:
- message: clusterDNS is immutable
rule: self == oldSelf
customCAs:
description: CustomCAs specifies the cert/key pairs for custom CA
certificates.
properties:
enabled:
description: Enabled toggles this feature on or off.
type: boolean
sources:
description: Sources defines the sources for all required custom
CA certificates.
properties:
clientCA:
description: ClientCA specifies the client-ca cert/key pair.
properties:
secretName:
description: |-
SecretName specifies the name of an existing secret to use.
The controller expects specific keys inside based on the credential type:
- For TLS pairs (e.g., ServerCA): 'tls.crt' and 'tls.key'.
- For ServiceAccountTokenKey: 'tls.key'.
type: string
type: object
etcdPeerCA:
description: ETCDPeerCA specifies the etcd-peer-ca cert/key
pair.
properties:
secretName:
description: |-
SecretName specifies the name of an existing secret to use.
The controller expects specific keys inside based on the credential type:
- For TLS pairs (e.g., ServerCA): 'tls.crt' and 'tls.key'.
- For ServiceAccountTokenKey: 'tls.key'.
type: string
type: object
etcdServerCA:
description: ETCDServerCA specifies the etcd-server-ca cert/key
pair.
properties:
secretName:
description: |-
SecretName specifies the name of an existing secret to use.
The controller expects specific keys inside based on the credential type:
- For TLS pairs (e.g., ServerCA): 'tls.crt' and 'tls.key'.
- For ServiceAccountTokenKey: 'tls.key'.
type: string
type: object
requestHeaderCA:
description: RequestHeaderCA specifies the request-header-ca
cert/key pair.
properties:
secretName:
description: |-
SecretName specifies the name of an existing secret to use.
The controller expects specific keys inside based on the credential type:
- For TLS pairs (e.g., ServerCA): 'tls.crt' and 'tls.key'.
- For ServiceAccountTokenKey: 'tls.key'.
type: string
type: object
serverCA:
description: ServerCA specifies the server-ca cert/key pair.
properties:
secretName:
description: |-
SecretName specifies the name of an existing secret to use.
The controller expects specific keys inside based on the credential type:
- For TLS pairs (e.g., ServerCA): 'tls.crt' and 'tls.key'.
- For ServiceAccountTokenKey: 'tls.key'.
type: string
type: object
serviceAccountToken:
description: ServiceAccountToken specifies the service-account-token
key.
properties:
secretName:
description: |-
SecretName specifies the name of an existing secret to use.
The controller expects specific keys inside based on the credential type:
- For TLS pairs (e.g., ServerCA): 'tls.crt' and 'tls.key'.
- For ServiceAccountTokenKey: 'tls.key'.
type: string
type: object
type: object
type: object
expose:
description: |-
Expose specifies options for exposing the API server.

View File

@@ -5,10 +5,12 @@ import (
"errors"
"fmt"
"net/url"
"os"
"strings"
"time"
"github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1"
"github.com/rancher/k3k/pkg/controller"
k3kcluster "github.com/rancher/k3k/pkg/controller/cluster"
"github.com/rancher/k3k/pkg/controller/kubeconfig"
"github.com/sirupsen/logrus"
@@ -42,6 +44,7 @@ type CreateConfig struct {
kubeconfigServerHost string
policy string
mirrorHostNodes bool
customCertsPath string
}
func NewClusterCreateCmd(appCtx *AppContext) *cli.Command {
@@ -101,6 +104,12 @@ func createAction(appCtx *AppContext, config *CreateConfig) cli.ActionFunc {
}
}
if config.customCertsPath != "" {
if err := CreateCustomCertsSecrets(ctx, name, namespace, config.customCertsPath, client); err != nil {
return err
}
}
logrus.Infof("Creating cluster [%s] in namespace [%s]", name, namespace)
cluster := newCluster(name, namespace, config)
@@ -200,6 +209,32 @@ func newCluster(name, namespace string, config *CreateConfig) *v1alpha1.Cluster
}
}
if config.customCertsPath != "" {
cluster.Spec.CustomCAs = v1alpha1.CustomCAs{
Enabled: true,
Sources: v1alpha1.CredentialSources{
ClientCA: v1alpha1.CredentialSource{
SecretName: controller.SafeConcatNameWithPrefix(cluster.Name, "client-ca"),
},
ServerCA: v1alpha1.CredentialSource{
SecretName: controller.SafeConcatNameWithPrefix(cluster.Name, "server-ca"),
},
ETCDServerCA: v1alpha1.CredentialSource{
SecretName: controller.SafeConcatNameWithPrefix(cluster.Name, "etcd-server-ca"),
},
ETCDPeerCA: v1alpha1.CredentialSource{
SecretName: controller.SafeConcatNameWithPrefix(cluster.Name, "etcd-peer-ca"),
},
RequestHeaderCA: v1alpha1.CredentialSource{
SecretName: controller.SafeConcatNameWithPrefix(cluster.Name, "request-header-ca"),
},
ServiceAccountToken: v1alpha1.CredentialSource{
SecretName: controller.SafeConcatNameWithPrefix(cluster.Name, "service-account-token"),
},
},
}
}
return cluster
}
@@ -245,3 +280,64 @@ func waitForCluster(ctx context.Context, client client.Client, cluster *v1alpha1
return false, nil
})
}
func CreateCustomCertsSecrets(ctx context.Context, name, namespace, customCertsPath string, client client.Client) error {
customCAsMap := map[string]string{
"etcd-peer-ca": "/etcd/peer-ca",
"etcd-server-ca": "/etcd/server-ca",
"server-ca": "/server-ca",
"client-ca": "/client-ca",
"request-header-ca": "/request-header-ca",
"service-account-token": "/service",
}
for certName, fileName := range customCAsMap {
var (
certFilePath, keyFilePath string
cert, key []byte
err error
)
if certName != "service-account-token" {
certFilePath = customCertsPath + fileName + ".crt"
cert, err = os.ReadFile(certFilePath)
if err != nil {
return err
}
}
keyFilePath = customCertsPath + fileName + ".key"
key, err = os.ReadFile(keyFilePath)
if err != nil {
return err
}
certSecret := caCertSecret(certName, name, namespace, cert, key)
if err := client.Create(ctx, certSecret); err != nil {
return ctrl.IgnoreAlreadyExists(err)
}
}
return nil
}
func caCertSecret(certName, clusterName, clusterNamespace string, cert, key []byte) *v1.Secret {
return &v1.Secret{
TypeMeta: metav1.TypeMeta{
Kind: "Secret",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: controller.SafeConcatNameWithPrefix(clusterName, certName),
Namespace: clusterNamespace,
},
Type: v1.SecretTypeTLS,
Data: map[string][]byte{
v1.TLSCertKey: cert,
v1.TLSPrivateKeyKey: key,
},
}
}

View File

@@ -126,5 +126,10 @@ func newCreateFlags(config *CreateConfig) []cli.Flag {
Usage: "The policy to create the cluster in",
Destination: &config.policy,
},
&cli.StringFlag{
Name: "custom-certs",
Usage: "The path for custom certificate directory",
Destination: &config.customCertsPath,
},
}
}

View File

@@ -44,6 +44,8 @@ Create new cluster
**--cluster-cidr**="": cluster CIDR
**--custom-certs**="": The path for custom certificate directory
**--debug**: Turn on debug logs
**--kubeconfig**="": kubeconfig path (default: $HOME/.kube/config or $KUBECONFIG if set)

View File

@@ -133,10 +133,67 @@ _Appears in:_
| `serverLimit` _[ResourceList](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#resourcelist-v1-core)_ | ServerLimit specifies resource limits for server nodes. | | |
| `workerLimit` _[ResourceList](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#resourcelist-v1-core)_ | WorkerLimit specifies resource limits for agent nodes. | | |
| `mirrorHostNodes` _boolean_ | MirrorHostNodes controls whether node objects from the host cluster<br />are mirrored into the virtual cluster. | | |
| `customCAs` _[CustomCAs](#customcas)_ | CustomCAs specifies the cert/key pairs for custom CA certificates. | | |
#### CredentialSource
CredentialSource defines where to get a credential from.
It can represent either a TLS key pair or a single private key.
_Appears in:_
- [CredentialSources](#credentialsources)
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `secretName` _string_ | SecretName specifies the name of an existing secret to use.<br />The controller expects specific keys inside based on the credential type:<br />- For TLS pairs (e.g., ServerCA): 'tls.crt' and 'tls.key'.<br />- For ServiceAccountTokenKey: 'tls.key'. | | |
#### CredentialSources
CredentialSources lists all the required credentials, including both
TLS key pairs and single signing keys.
_Appears in:_
- [CustomCAs](#customcas)
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `serverCA` _[CredentialSource](#credentialsource)_ | ServerCA specifies the server-ca cert/key pair. | | |
| `clientCA` _[CredentialSource](#credentialsource)_ | ClientCA specifies the client-ca cert/key pair. | | |
| `requestHeaderCA` _[CredentialSource](#credentialsource)_ | RequestHeaderCA specifies the request-header-ca cert/key pair. | | |
| `etcdServerCA` _[CredentialSource](#credentialsource)_ | ETCDServerCA specifies the etcd-server-ca cert/key pair. | | |
| `etcdPeerCA` _[CredentialSource](#credentialsource)_ | ETCDPeerCA specifies the etcd-peer-ca cert/key pair. | | |
| `serviceAccountToken` _[CredentialSource](#credentialsource)_ | ServiceAccountToken specifies the service-account-token key. | | |
#### CustomCAs
CustomCAs specifies the cert/key pairs for custom CA certificates.
_Appears in:_
- [ClusterSpec](#clusterspec)
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `enabled` _boolean_ | Enabled toggles this feature on or off. | | |
| `sources` _[CredentialSources](#credentialsources)_ | Sources defines the sources for all required custom CA certificates. | | |
#### ExposeConfig

View File

@@ -171,6 +171,11 @@ type ClusterSpec struct {
//
// +optional
MirrorHostNodes bool `json:"mirrorHostNodes,omitempty"`
// CustomCAs specifies the cert/key pairs for custom CA certificates.
//
// +optional
CustomCAs CustomCAs `json:"customCAs,omitempty"`
}
// ClusterMode is the possible provisioning mode of a Cluster.
@@ -295,6 +300,48 @@ type NodePortConfig struct {
ETCDPort *int32 `json:"etcdPort,omitempty"`
}
// CustomCAs specifies the cert/key pairs for custom CA certificates.
type CustomCAs struct {
// Enabled toggles this feature on or off.
Enabled bool `json:"enabled,omitempty"`
// Sources defines the sources for all required custom CA certificates.
Sources CredentialSources `json:"sources,omitempty"`
}
// CredentialSources lists all the required credentials, including both
// TLS key pairs and single signing keys.
type CredentialSources struct {
// ServerCA specifies the server-ca cert/key pair.
ServerCA CredentialSource `json:"serverCA,omitempty"`
// ClientCA specifies the client-ca cert/key pair.
ClientCA CredentialSource `json:"clientCA,omitempty"`
// RequestHeaderCA specifies the request-header-ca cert/key pair.
RequestHeaderCA CredentialSource `json:"requestHeaderCA,omitempty"`
// ETCDServerCA specifies the etcd-server-ca cert/key pair.
ETCDServerCA CredentialSource `json:"etcdServerCA,omitempty"`
// ETCDPeerCA specifies the etcd-peer-ca cert/key pair.
ETCDPeerCA CredentialSource `json:"etcdPeerCA,omitempty"`
// ServiceAccountToken specifies the service-account-token key.
ServiceAccountToken CredentialSource `json:"serviceAccountToken,omitempty"`
}
// CredentialSource defines where to get a credential from.
// It can represent either a TLS key pair or a single private key.
type CredentialSource struct {
// SecretName specifies the name of an existing secret to use.
// The controller expects specific keys inside based on the credential type:
// - For TLS pairs (e.g., ServerCA): 'tls.crt' and 'tls.key'.
// - For ServiceAccountTokenKey: 'tls.key'.
// +optional
SecretName string `json:"secretName,omitempty"`
}
// ClusterStatus reflects the observed state of a Cluster.
type ClusterStatus struct {
// HostVersion is the Kubernetes version of the host node.

View File

@@ -163,6 +163,7 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
(*out)[key] = val.DeepCopy()
}
}
out.CustomCAs = in.CustomCAs
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec.
@@ -202,6 +203,58 @@ func (in *ClusterStatus) DeepCopy() *ClusterStatus {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialSource) DeepCopyInto(out *CredentialSource) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialSource.
func (in *CredentialSource) DeepCopy() *CredentialSource {
if in == nil {
return nil
}
out := new(CredentialSource)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CredentialSources) DeepCopyInto(out *CredentialSources) {
*out = *in
out.ServerCA = in.ServerCA
out.ClientCA = in.ClientCA
out.RequestHeaderCA = in.RequestHeaderCA
out.ETCDServerCA = in.ETCDServerCA
out.ETCDPeerCA = in.ETCDPeerCA
out.ServiceAccountToken = in.ServiceAccountToken
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialSources.
func (in *CredentialSources) DeepCopy() *CredentialSources {
if in == nil {
return nil
}
out := new(CredentialSources)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CustomCAs) DeepCopyInto(out *CustomCAs) {
*out = *in
out.Sources = in.Sources
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomCAs.
func (in *CustomCAs) DeepCopy() *CustomCAs {
if in == nil {
return nil
}
out := new(CustomCAs)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExposeConfig) DeepCopyInto(out *ExposeConfig) {
*out = *in

View File

@@ -58,7 +58,10 @@ const (
memberRemovalTimeout = time.Minute * 1
)
var ErrClusterValidation = errors.New("cluster validation error")
var (
ErrClusterValidation = errors.New("cluster validation error")
ErrCustomCACertSecretMissing = errors.New("custom CA certificate secret is missing")
)
type ClusterReconciler struct {
DiscoveryClient *discovery.DiscoveryClient
@@ -265,7 +268,7 @@ func (c *ClusterReconciler) reconcile(ctx context.Context, cluster *v1alpha1.Clu
return err
}
s := server.New(cluster, c.Client, token, string(cluster.Spec.Mode), c.K3SImage, c.K3SImagePullPolicy)
s := server.New(cluster, c.Client, token, c.K3SImage, c.K3SImagePullPolicy)
cluster.Status.ClusterCIDR = cluster.Spec.ClusterCIDR
if cluster.Status.ClusterCIDR == "" {
@@ -712,6 +715,12 @@ func (c *ClusterReconciler) validate(cluster *v1alpha1.Cluster, policy v1alpha1.
return fmt.Errorf("%w: mode %q is not allowed by the policy %q", ErrClusterValidation, cluster.Spec.Mode, policy.Name)
}
if cluster.Spec.CustomCAs.Enabled {
if err := c.validateCustomCACerts(cluster); err != nil {
return fmt.Errorf("%w: %w", ErrClusterValidation, err)
}
}
return nil
}
@@ -791,3 +800,18 @@ func (c *ClusterReconciler) lookupServiceCIDR(ctx context.Context) (string, erro
return "", nil
}
// validateCustomCACerts will make sure that all the cert secrets exists
func (c *ClusterReconciler) validateCustomCACerts(cluster *v1alpha1.Cluster) error {
credentialSources := cluster.Spec.CustomCAs.Sources
if credentialSources.ClientCA.SecretName == "" ||
credentialSources.ServerCA.SecretName == "" ||
credentialSources.ETCDPeerCA.SecretName == "" ||
credentialSources.ETCDServerCA.SecretName == "" ||
credentialSources.RequestHeaderCA.SecretName == "" ||
credentialSources.ServiceAccountToken.SecretName == "" {
return ErrCustomCACertSecretMissing
}
return nil
}

View File

@@ -3,6 +3,8 @@ package server
import (
"bytes"
"context"
"fmt"
"sort"
"strings"
"text/template"
@@ -36,12 +38,12 @@ type Server struct {
k3SImagePullPolicy string
}
func New(cluster *v1alpha1.Cluster, client client.Client, token, mode string, k3SImage string, k3SImagePullPolicy string) *Server {
func New(cluster *v1alpha1.Cluster, client client.Client, token string, k3SImage string, k3SImagePullPolicy string) *Server {
return &Server{
cluster: cluster,
client: client,
token: token,
mode: mode,
mode: string(cluster.Spec.Mode),
k3SImage: k3SImage,
k3SImagePullPolicy: k3SImagePullPolicy,
}
@@ -319,6 +321,17 @@ func (s *Server) StatefulServer(ctx context.Context) (*apps.StatefulSet, error)
volumeMounts = append(volumeMounts, volumeMount)
}
if s.cluster.Spec.CustomCAs.Enabled {
vols, mounts, err := s.loadCACertBundle(ctx)
if err != nil {
return nil, err
}
volumes = append(volumes, vols...)
volumeMounts = append(volumeMounts, mounts...)
}
selector := metav1.LabelSelector{
MatchLabels: map[string]string{
"cluster": s.cluster.Name,
@@ -410,3 +423,103 @@ func (s *Server) setupStartCommand() (string, error) {
return output.String(), nil
}
func (s *Server) loadCACertBundle(ctx context.Context) ([]v1.Volume, []v1.VolumeMount, error) {
customCerts := s.cluster.Spec.CustomCAs.Sources
caCertMap := map[string]string{
"server-ca": customCerts.ServerCA.SecretName,
"client-ca": customCerts.ClientCA.SecretName,
"request-header-ca": customCerts.RequestHeaderCA.SecretName,
"etcd-peer-ca": customCerts.ETCDPeerCA.SecretName,
"etcd-server-ca": customCerts.ETCDServerCA.SecretName,
"service": customCerts.ServiceAccountToken.SecretName,
}
var (
volumes []v1.Volume
mounts []v1.VolumeMount
sortedCertIDs = sortedKeys(caCertMap)
)
for _, certName := range sortedCertIDs {
var certSecret v1.Secret
secretName := string(caCertMap[certName])
key := types.NamespacedName{Name: secretName, Namespace: s.cluster.Namespace}
if err := s.client.Get(ctx, key, &certSecret); err != nil {
return nil, nil, err
}
cert := certSecret.Data["tls.crt"]
keyData := certSecret.Data["tls.key"]
// Service account token secret is an exception (may not contain crt/key).
if certName != "service" && (len(cert) == 0 || len(keyData) == 0) {
return nil, nil, fmt.Errorf("cert or key is not found in secret %s", certName)
}
volumeName := certName + "-vol"
vol, certMounts := s.mountCACert(volumeName, certName, secretName, "tls")
volumes = append(volumes, *vol)
mounts = append(mounts, certMounts...)
}
return volumes, mounts, nil
}
func (s *Server) mountCACert(volumeName, certName, secretName string, subPathMount string) (*v1.Volume, []v1.VolumeMount) {
var (
volume *v1.Volume
mounts []v1.VolumeMount
)
// avoid re-adding secretName in case of combined secret
volume = &v1.Volume{
Name: volumeName,
VolumeSource: v1.VolumeSource{
Secret: &v1.SecretVolumeSource{SecretName: secretName},
},
}
etcdPrefix := ""
mountFile := certName
if strings.HasPrefix(certName, "etcd-") {
etcdPrefix = "/etcd"
mountFile = strings.TrimPrefix(certName, "etcd-")
}
// add the mount for the cert except for the service account token
if certName != "service" {
mounts = append(mounts, v1.VolumeMount{
Name: volumeName,
MountPath: fmt.Sprintf("/var/lib/rancher/k3s/server/tls%s/%s.crt", etcdPrefix, mountFile),
SubPath: subPathMount + ".crt",
})
}
// add the mount for the key
mounts = append(mounts, v1.VolumeMount{
Name: volumeName,
MountPath: fmt.Sprintf("/var/lib/rancher/k3s/server/tls%s/%s.key", etcdPrefix, mountFile),
SubPath: subPathMount + ".key",
})
return volume, mounts
}
func sortedKeys(keyMap map[string]string) []string {
keys := make([]string, 0, len(keyMap))
for k := range keyMap {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}

View File

@@ -5,6 +5,8 @@ import (
"crypto/x509"
"errors"
"fmt"
"os"
"strings"
"time"
. "github.com/onsi/ginkgo/v2"
@@ -182,3 +184,94 @@ var _ = When("a dynamic cluster is installed", func() {
Should(BeNil())
})
})
var _ = When("a cluster with custom certificates is installed with individual cert secrets", Label("e2e"), func() {
ctx := context.Background()
var virtualCluster *VirtualCluster
BeforeEach(func() {
namespace := NewNamespace()
// create custom cert secret
customCertDir := "testdata/customcerts/"
certList := []string{
"server-ca",
"client-ca",
"request-header-ca",
"service",
"etcd-peer-ca",
"etcd-server-ca",
}
for _, certName := range certList {
var cert, key []byte
var err error
filePathPrefix := ""
certfile := certName
if strings.HasPrefix(certName, "etcd") {
filePathPrefix = "etcd/"
certfile = strings.TrimPrefix(certName, "etcd-")
}
if !strings.Contains(certName, "service") {
cert, err = os.ReadFile(customCertDir + filePathPrefix + certfile + ".crt")
Expect(err).To(Not(HaveOccurred()))
}
key, err = os.ReadFile(customCertDir + filePathPrefix + certfile + ".key")
Expect(err).To(Not(HaveOccurred()))
certSecret := caCertSecret(certName, namespace.Name, cert, key)
err = k8sClient.Create(ctx, certSecret)
Expect(err).To(Not(HaveOccurred()))
}
cluster := NewCluster(namespace.Name)
cluster.Spec.CustomCAs = v1alpha1.CustomCAs{
Enabled: true,
Sources: v1alpha1.CredentialSources{
ServerCA: v1alpha1.CredentialSource{
SecretName: "server-ca",
},
ClientCA: v1alpha1.CredentialSource{
SecretName: "client-ca",
},
ETCDServerCA: v1alpha1.CredentialSource{
SecretName: "etcd-server-ca",
},
ETCDPeerCA: v1alpha1.CredentialSource{
SecretName: "etcd-peer-ca",
},
RequestHeaderCA: v1alpha1.CredentialSource{
SecretName: "request-header-ca",
},
ServiceAccountToken: v1alpha1.CredentialSource{
SecretName: "service",
},
},
}
CreateCluster(cluster)
client, restConfig := NewVirtualK8sClientAndConfig(cluster)
virtualCluster = &VirtualCluster{
Cluster: cluster,
RestConfig: restConfig,
Client: client,
}
})
It("will load the custom certs in the server pod", func() {
_, _ = virtualCluster.NewNginxPod("")
labelSelector := "cluster=" + virtualCluster.Cluster.Name + ",role=server"
serverPods, err := k8s.CoreV1().Pods(virtualCluster.Cluster.Namespace).List(ctx, v1.ListOptions{LabelSelector: labelSelector})
Expect(err).To(Not(HaveOccurred()))
Expect(len(serverPods.Items)).To(Equal(1))
serverPod := serverPods.Items[0]
// check server-ca.crt
serverCACrtPath := "/var/lib/rancher/k3s/server/tls/server-ca.crt"
serverCACrt, err := readFileWithinPod(ctx, k8s, restcfg, serverPod.Name, serverPod.Namespace, serverCACrtPath)
Expect(err).To(Not(HaveOccurred()))
serverCACrtTestFile, err := os.ReadFile("testdata/customcerts/server-ca.crt")
Expect(err).To(Not(HaveOccurred()))
Expect(serverCACrt).To(Equal(serverCACrtTestFile))
})
})

View File

@@ -0,0 +1,81 @@
-----BEGIN CERTIFICATE-----
MIIDZjCCAU6gAwIBAgIIXrx+TJOdkuMwDQYJKoZIhvcNAQELBQAwKTEnMCUGA1UE
AwweazNzLWludGVybWVkaWF0ZS1jYUAxNzUxOTY1MTAwMB4XDTI1MDcwODA4NTgy
M1oXDTM1MDgyNTA4NTgyM1owIzEhMB8GA1UEAwwYazNzLWNsaWVudC1jYUAxNzUx
OTY1MTAwMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE90bIIKEOMnIQ926Jf5rC
7/I1GYjOpbFZ+6jVCuBpG06RIhlrlGFx/4Xmz5X+Wwm+JlZOwueW+Z5oNWTSN/pS
vKNjMGEwHQYDVR0OBBYEFAYyQJEmofE3Socg5OBg/vBQwu44MB8GA1UdIwQYMBaA
FJlWOM0MjJgK2OweAyu1eVn/fUi6MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
BAQDAgKkMA0GCSqGSIb3DQEBCwUAA4ICAQAxi9riQZ2/3RCrbXtuvHCXKWEJXNID
z0Ubd1T61m6bXPrDUiRMwyB11pwVMQhSpOTuwVuP0tDcz95Gj4KOy4cWYBgN56hs
wAVPAKwsfbinxXBcZ16B6qnTNnPRhDbIqFHuezuzs40+RmR9wYAoyv34Cuw11oCe
h55w+0pnB9zGgpYGGm7uIwq5DVBOcMC36IGj/un5w+jniguGgxrgx2nxcZqab5aB
TVnrqA7vLpZPFrJ0m4QWDez+D9fYi53qI7JBZu7ixyN5Bo8mRxHjRvVMrZCotrzB
eBEbJNFEC5B49/R5GFLWvpyBpvAwE3ArxI/pvt2p1aoxwMl7hKcyDgWSRZQfpqZ/
Kk+9BUE2lka4xIx3WMXFsf8Ts/7h7bH91CAGmILHc2iDtF/whBNJuAT80MDQ2gfV
1482KHV6nRsX/l73bJRmqUvoM2DEZDWgdHvNNKi3+SLkMsuAIwdNE7RkuKYLxiC1
go39t5qLfwahGzOkkj7703MsbFObsB9zwY9bnYLjhei0uPk6I5m6sMJiN5Uit++Q
lgAFjbBqN7qdPHY4z5cXazqDEcZdOGIxYJ/ZyA/XcKrXcO6/uO2uZH0QLoxK0yI4
uSyJfyHIEmmcYKbwXhruwkvToY7O1DMGO2RuBY/JiCEsseR5LNyZsgVYgOuVkQTX
0nfWkI7eQYRUzQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFLzCCAxegAwIBAgIIXrx+TJOdkuIwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UE
AwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgwODU4MjNaFw0zNTA4
MjUwODU4MjNaMCkxJzAlBgNVBAMMHmszcy1pbnRlcm1lZGlhdGUtY2FAMTc1MTk2
NTEwMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfxJHxlMq/Ul+7X
avcxrg6x8joXUn0T4TbaYiQJVRK0z8j42yDh1uJSQ82SkCB1ltkF2xHzQ65iqPx9
n6uluTP/fEoGOiGxfZfIqk+H+mPbumJPd7n3hmtqPwPmjhYCPZpLadT60rjNalkM
4hUX2O0PwXtvejODUaLgF9YLUJbIdoZvkzKNcv2bTg9gruW0AoAzEqAKLYRDh58N
XQMync3OQnnAMzUyPBBukhM7P2tysufV0HJg/ZcsgLek8hpuBQ2T1QVUrZFAgOXh
ZCcrK5OGKcjQh5bo1vcbIRr4DtfHT/Jl5RhA6q5IqTAiS/dQVAhNYs0lDHgF69kU
gI2iHqsv2awuW3k9Q+i5q9vMlo/h9wxpj87cbfxLpBkS2o/h+6zB1DdI6U1WRo/Q
pFp3vzsdtr/G8WEFxwL1OMDewjA+EsjhSjI0BBrm7CC2uJkNRM3v97r9RGNzBCYL
Qn3IxqqzVjOOEhJzQc3G8FKRJj1zPAkURvTus4s9c7vdMOp1sVd78b9ObXFa0TDF
DPe9ZQu5YGEvGGibKjp5cFwJ2M2pwjv53ZUDS4sxqqdXRBmVxcCkUtrwRL35PIpb
Tje1UZP8RJ66iXnXUPco2BKyd9NYyiaUAW4gZz5WROzfgPdnI/ArGc5RThk+O5sg
cb62eU/nADPGsG8t+VEUXfJjP19pAgMBAAGjYzBhMB0GA1UdDgQWBBSZVjjNDIyY
CtjsHgMrtXlZ/31IujAfBgNVHSMEGDAWgBSML4NHrHhdoo46ZRedOusGhJBsTDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwICpDANBgkqhkiG9w0BAQsFAAOC
AgEAxgdjETEkUB7G2g3cFz6Jb8TznrZXprVk9G1p1UNuMAAEe2NaiGI0BvivJNoQ
6DNpngB3x6l7u5hMOJY/72wzQRDXg05m5T8/vBfTcz/HcgoKU82hgYDxQiGA0I5e
5czfEhQu95uPT7T26m5pvWA38Tf6WbXCB7c0/FT8II8w1ptJlZrSKRW33+j1tb2r
t0/8RoMaAUS1MP6+12juG7qcuEx0rDVeKx33pa20NjsAtZeTAsXjugJkmUkkd/PC
cKbawQB9meqtWPfGzwmUu1qz6SQeWtOWFrOBSeTzx0HTeimSAiHVSaXGd7ms3orx
KsKUoPUbXi9rVIDVxCe5XwAKmcHMz8DGHfxJ6sodol25pYbHxKy/swgAzQdwtGF9
HWJAm6/3YSjtmD6+t89/yYzvxv+aMNDXVMLpDFb+7/ESsSl4757WjvvFoz0HxcwD
4qfmV2z+EaLM44P3QaJDD599/Qwt+TFHSQRfD/MqMH6A+9vZhZGWeGgFFmu82kzH
xKJas/jI+t+V+2TbfagUYlsinZ6UmLcju99myl6wq6nJu8X5b8Uhpv5/8kVniqXE
lWtFpMBmnE0oq0U+KR3OfnovSYdYTc7uWpaJlqMamsE5UVVBrlSyUe9J9EQzYYea
Ufoq67KnJInMobbQ4aonz7EQZW6WIZpqASuVGfT5heSKHDc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFMzCCAxugAwIBAgIUALEl344JEZxaOvwyrtO8QwLHAacwDQYJKoZIhvcNAQEL
BQAwITEfMB0GA1UEAwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgw
ODU4MjJaFw00NTA3MDMwODU4MjJaMCExHzAdBgNVBAMMFmszcy1yb290LWNhQDE3
NTE5NjUxMDAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDtESS+0V7T
0b3rN0ga9/zWThgaGIfOoKiCr2CSR4az0hjpmISAlS5pplhWrutGhydvaR/7vV7g
Grtn0ptmqidEc0XSeQTosqUv29SZ+hbCITZG05TFbMGGXmFo/1LHhJ8ZpgzUBqc7
inOXmEBbCyhOWX+fhddoJJiUIX7l2R3cbyNk7I7KFiZ1JDDnoyDWFMOJLvXwOqeT
CJQesS+2qpeXpdazgtkRQi7aOhZtXnCsJHnFbpL9VFTmWpq7vMIA9xkDva3/80S4
T2USiyN4/quUagjP8si5PIaGBVx9bJhnKHUdTrPPZWHFfxm74GUG7en4OtR9lOTM
TV49XuofNpJaJ2K5Dz+rk6gIYp2R9W+r8CN1HBXeLF5WJCvw54Lpcp0V2BA+MARq
Ij8UTUymu++rIo+WjKcHDT0qn39rhOhqJ3dXynW4UF/95KwB7e5UI+OxZ9sJ4oNP
FuP5PHrDINXsYG0DDM3KTDxA8memVSFGMdhm31DPD2GUvUPlupnd6uCepdcBc9ed
+9gTeSxF5cA6Q3gVOQa8ok9Ts0E5DwGaCIxjasyD+MIORf3Bkv0Z3lBNXicWDngP
FU5ya30GeTZQgzqhlGoXehjYfRxV28pgiR5ejl0/rmsYGfiWPdfa4Qy0LnxSKHj1
f2R1jEB55ORATo3f+k4Ez5bdjhk4KlA95QIDAQABo2MwYTAdBgNVHQ4EFgQUjC+D
R6x4XaKOOmUXnTrrBoSQbEwwHwYDVR0jBBgwFoAUjC+DR6x4XaKOOmUXnTrrBoSQ
bEwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQEL
BQADggIBACpzO1nV6/hS1xLIkkGf9RdypATYCH6RqeBJqMf/R5YEUQssLF/QBEvQ
NwockkxD1l8VwjH3Pp36QxkgthAl0D3ewK9LLkxEq1pp9VuVGxeD9siN/fxx6htG
KP1jT49pBDIdbzhJ7eR/O8xuI5dyZNLZLJkaumQkd7sEVHvDTFw55PhwUEJ3Wcxl
jAxXM1FFCKftXjWFmvVmzYZYkPj/AhB+PcVIIkFnNQYTXdUCUtsnSgj3pF1z/+g5
PttBGhsttrm93lJgddRFTEWV1lzfw1csrHkLYDYLDKDzsNQaVo71wKPmorK+xnbM
h1PQAVJeXypLTAfE636+n+Md/wSvnQuo0RzPBE24S9c9TWM2d96dvtU9kgJPbqoA
RX6jHw2ACnKp4RFJILqDCqFCOrytYPk3J/L8myW44dGpCCdSrFREqNCsyMrqu4v7
U+W9ENHT0qe7Nm0T4XNFlQstt6uGvk6ddEdbgcTfTvSv5jx2++Jfl2ynF+G67l0U
UASFHsrwThnulGQtpK2+heHkU8xQFjQOGZoQMlLiWzWg+bqo07aghAndKhKnW8s8
iRvMvdcsLjjDaPFCgeopGeQauiTd2od5aXGWCn+djzLq0fjIvezs4K70XOsStbGA
cJFFAnsnM40SbnrWyfe1EBlzuVJu0csuF77fpEU7CFz8uzd268Ho
-----END CERTIFICATE-----

View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIPcLNko4+/EQ5/23zlmItihyMP1E7TidAN0bIoPArlHToAoGCCqGSM49
AwEHoUQDQgAE90bIIKEOMnIQ926Jf5rC7/I1GYjOpbFZ+6jVCuBpG06RIhlrlGFx
/4Xmz5X+Wwm+JlZOwueW+Z5oNWTSN/pSvA==
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDZjCCAU6gAwIBAgIIXrx+TJOdkuMwDQYJKoZIhvcNAQELBQAwKTEnMCUGA1UE
AwweazNzLWludGVybWVkaWF0ZS1jYUAxNzUxOTY1MTAwMB4XDTI1MDcwODA4NTgy
M1oXDTM1MDgyNTA4NTgyM1owIzEhMB8GA1UEAwwYazNzLWNsaWVudC1jYUAxNzUx
OTY1MTAwMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE90bIIKEOMnIQ926Jf5rC
7/I1GYjOpbFZ+6jVCuBpG06RIhlrlGFx/4Xmz5X+Wwm+JlZOwueW+Z5oNWTSN/pS
vKNjMGEwHQYDVR0OBBYEFAYyQJEmofE3Socg5OBg/vBQwu44MB8GA1UdIwQYMBaA
FJlWOM0MjJgK2OweAyu1eVn/fUi6MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
BAQDAgKkMA0GCSqGSIb3DQEBCwUAA4ICAQAxi9riQZ2/3RCrbXtuvHCXKWEJXNID
z0Ubd1T61m6bXPrDUiRMwyB11pwVMQhSpOTuwVuP0tDcz95Gj4KOy4cWYBgN56hs
wAVPAKwsfbinxXBcZ16B6qnTNnPRhDbIqFHuezuzs40+RmR9wYAoyv34Cuw11oCe
h55w+0pnB9zGgpYGGm7uIwq5DVBOcMC36IGj/un5w+jniguGgxrgx2nxcZqab5aB
TVnrqA7vLpZPFrJ0m4QWDez+D9fYi53qI7JBZu7ixyN5Bo8mRxHjRvVMrZCotrzB
eBEbJNFEC5B49/R5GFLWvpyBpvAwE3ArxI/pvt2p1aoxwMl7hKcyDgWSRZQfpqZ/
Kk+9BUE2lka4xIx3WMXFsf8Ts/7h7bH91CAGmILHc2iDtF/whBNJuAT80MDQ2gfV
1482KHV6nRsX/l73bJRmqUvoM2DEZDWgdHvNNKi3+SLkMsuAIwdNE7RkuKYLxiC1
go39t5qLfwahGzOkkj7703MsbFObsB9zwY9bnYLjhei0uPk6I5m6sMJiN5Uit++Q
lgAFjbBqN7qdPHY4z5cXazqDEcZdOGIxYJ/ZyA/XcKrXcO6/uO2uZH0QLoxK0yI4
uSyJfyHIEmmcYKbwXhruwkvToY7O1DMGO2RuBY/JiCEsseR5LNyZsgVYgOuVkQTX
0nfWkI7eQYRUzQ==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,81 @@
-----BEGIN CERTIFICATE-----
MIIDaTCCAVGgAwIBAgIIXrx+TJOdkuYwDQYJKoZIhvcNAQELBQAwKTEnMCUGA1UE
AwweazNzLWludGVybWVkaWF0ZS1jYUAxNzUxOTY1MTAwMB4XDTI1MDcwODA4NTgy
NFoXDTM1MDgyNTA4NTgyNFowJjEkMCIGA1UEAwwbazNzLWV0Y2QtcGVlci1jYUAx
NzUxOTY1MTAwMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEH9/YWeczKMngMCXY
3woc+fdJ0Pgbgkwm+ad8wGb2DXA7puDbfiIiEz7z8qZDehxnckl5KdcWIK8hNcKB
CRGILaNjMGEwHQYDVR0OBBYEFI0GOYl4luW+/mBH7BCKsBZbnC0vMB8GA1UdIwQY
MBaAFJlWOM0MjJgK2OweAyu1eVn/fUi6MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
AQH/BAQDAgKkMA0GCSqGSIb3DQEBCwUAA4ICAQClsvi6TIEfYkRJ3923gMEmhAaF
WIXdLssY/FQSdhYeNBaJksTHPCmWDKpKJzL0x5MdePNy2oYPCtrAVzbyQe/oatp/
gg2krE1Wnq8YG95d/MrELZ5KGkQcwA8MGs2sMHYe/0XNDQ/DKOOJBhGvxs3OfySQ
BUks+UiY7UIpolTbxPIGI56IBfKk16fAPA57O9nQv1ReioEWnrOsJY7B/Dxly8tR
qlLwSJ5mJFs1ozFOrBG/CZ+zn/fRthXH7M2tYtmv8lEnOGE0R0A8iaW/vc9kWwq0
N6jSoC/w7njMl1rTMWrInsqa5ippK1EwV1kERF+qer08eJ/giZoA16C0zyG6ajPD
z/qSzn2TiknZR1DX7zZsvwfactpwUDK+taTL/3kbUzQYayjjG1PI/dNmELqWLXqZ
AoG5/s6+TKdSxjLGbchw56AC6E1+I0dNLMbxzjrNlIpa9V9BjI1ZbHIlEzjO7a63
1eZH9Ni5kYiaFUOtzqZQiM34W6q0LDAowyELik8FEkoe5fNsknWAhiSEDfbil8u+
NpNlQqpMxLydqZvepEyx34tsu4gvunPMFkxh+5kpSDmWm9e3oK7g1Mt7+qaxsy/N
jkoLbiP2ZVCp4LSwQombPNZFupo33kwIi1wN5F4RLlfesDHs007UrhV403xP7g3d
V9Q1NXFPCuFOCThm/w==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFLzCCAxegAwIBAgIIXrx+TJOdkuIwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UE
AwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgwODU4MjNaFw0zNTA4
MjUwODU4MjNaMCkxJzAlBgNVBAMMHmszcy1pbnRlcm1lZGlhdGUtY2FAMTc1MTk2
NTEwMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfxJHxlMq/Ul+7X
avcxrg6x8joXUn0T4TbaYiQJVRK0z8j42yDh1uJSQ82SkCB1ltkF2xHzQ65iqPx9
n6uluTP/fEoGOiGxfZfIqk+H+mPbumJPd7n3hmtqPwPmjhYCPZpLadT60rjNalkM
4hUX2O0PwXtvejODUaLgF9YLUJbIdoZvkzKNcv2bTg9gruW0AoAzEqAKLYRDh58N
XQMync3OQnnAMzUyPBBukhM7P2tysufV0HJg/ZcsgLek8hpuBQ2T1QVUrZFAgOXh
ZCcrK5OGKcjQh5bo1vcbIRr4DtfHT/Jl5RhA6q5IqTAiS/dQVAhNYs0lDHgF69kU
gI2iHqsv2awuW3k9Q+i5q9vMlo/h9wxpj87cbfxLpBkS2o/h+6zB1DdI6U1WRo/Q
pFp3vzsdtr/G8WEFxwL1OMDewjA+EsjhSjI0BBrm7CC2uJkNRM3v97r9RGNzBCYL
Qn3IxqqzVjOOEhJzQc3G8FKRJj1zPAkURvTus4s9c7vdMOp1sVd78b9ObXFa0TDF
DPe9ZQu5YGEvGGibKjp5cFwJ2M2pwjv53ZUDS4sxqqdXRBmVxcCkUtrwRL35PIpb
Tje1UZP8RJ66iXnXUPco2BKyd9NYyiaUAW4gZz5WROzfgPdnI/ArGc5RThk+O5sg
cb62eU/nADPGsG8t+VEUXfJjP19pAgMBAAGjYzBhMB0GA1UdDgQWBBSZVjjNDIyY
CtjsHgMrtXlZ/31IujAfBgNVHSMEGDAWgBSML4NHrHhdoo46ZRedOusGhJBsTDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwICpDANBgkqhkiG9w0BAQsFAAOC
AgEAxgdjETEkUB7G2g3cFz6Jb8TznrZXprVk9G1p1UNuMAAEe2NaiGI0BvivJNoQ
6DNpngB3x6l7u5hMOJY/72wzQRDXg05m5T8/vBfTcz/HcgoKU82hgYDxQiGA0I5e
5czfEhQu95uPT7T26m5pvWA38Tf6WbXCB7c0/FT8II8w1ptJlZrSKRW33+j1tb2r
t0/8RoMaAUS1MP6+12juG7qcuEx0rDVeKx33pa20NjsAtZeTAsXjugJkmUkkd/PC
cKbawQB9meqtWPfGzwmUu1qz6SQeWtOWFrOBSeTzx0HTeimSAiHVSaXGd7ms3orx
KsKUoPUbXi9rVIDVxCe5XwAKmcHMz8DGHfxJ6sodol25pYbHxKy/swgAzQdwtGF9
HWJAm6/3YSjtmD6+t89/yYzvxv+aMNDXVMLpDFb+7/ESsSl4757WjvvFoz0HxcwD
4qfmV2z+EaLM44P3QaJDD599/Qwt+TFHSQRfD/MqMH6A+9vZhZGWeGgFFmu82kzH
xKJas/jI+t+V+2TbfagUYlsinZ6UmLcju99myl6wq6nJu8X5b8Uhpv5/8kVniqXE
lWtFpMBmnE0oq0U+KR3OfnovSYdYTc7uWpaJlqMamsE5UVVBrlSyUe9J9EQzYYea
Ufoq67KnJInMobbQ4aonz7EQZW6WIZpqASuVGfT5heSKHDc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFMzCCAxugAwIBAgIUALEl344JEZxaOvwyrtO8QwLHAacwDQYJKoZIhvcNAQEL
BQAwITEfMB0GA1UEAwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgw
ODU4MjJaFw00NTA3MDMwODU4MjJaMCExHzAdBgNVBAMMFmszcy1yb290LWNhQDE3
NTE5NjUxMDAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDtESS+0V7T
0b3rN0ga9/zWThgaGIfOoKiCr2CSR4az0hjpmISAlS5pplhWrutGhydvaR/7vV7g
Grtn0ptmqidEc0XSeQTosqUv29SZ+hbCITZG05TFbMGGXmFo/1LHhJ8ZpgzUBqc7
inOXmEBbCyhOWX+fhddoJJiUIX7l2R3cbyNk7I7KFiZ1JDDnoyDWFMOJLvXwOqeT
CJQesS+2qpeXpdazgtkRQi7aOhZtXnCsJHnFbpL9VFTmWpq7vMIA9xkDva3/80S4
T2USiyN4/quUagjP8si5PIaGBVx9bJhnKHUdTrPPZWHFfxm74GUG7en4OtR9lOTM
TV49XuofNpJaJ2K5Dz+rk6gIYp2R9W+r8CN1HBXeLF5WJCvw54Lpcp0V2BA+MARq
Ij8UTUymu++rIo+WjKcHDT0qn39rhOhqJ3dXynW4UF/95KwB7e5UI+OxZ9sJ4oNP
FuP5PHrDINXsYG0DDM3KTDxA8memVSFGMdhm31DPD2GUvUPlupnd6uCepdcBc9ed
+9gTeSxF5cA6Q3gVOQa8ok9Ts0E5DwGaCIxjasyD+MIORf3Bkv0Z3lBNXicWDngP
FU5ya30GeTZQgzqhlGoXehjYfRxV28pgiR5ejl0/rmsYGfiWPdfa4Qy0LnxSKHj1
f2R1jEB55ORATo3f+k4Ez5bdjhk4KlA95QIDAQABo2MwYTAdBgNVHQ4EFgQUjC+D
R6x4XaKOOmUXnTrrBoSQbEwwHwYDVR0jBBgwFoAUjC+DR6x4XaKOOmUXnTrrBoSQ
bEwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQEL
BQADggIBACpzO1nV6/hS1xLIkkGf9RdypATYCH6RqeBJqMf/R5YEUQssLF/QBEvQ
NwockkxD1l8VwjH3Pp36QxkgthAl0D3ewK9LLkxEq1pp9VuVGxeD9siN/fxx6htG
KP1jT49pBDIdbzhJ7eR/O8xuI5dyZNLZLJkaumQkd7sEVHvDTFw55PhwUEJ3Wcxl
jAxXM1FFCKftXjWFmvVmzYZYkPj/AhB+PcVIIkFnNQYTXdUCUtsnSgj3pF1z/+g5
PttBGhsttrm93lJgddRFTEWV1lzfw1csrHkLYDYLDKDzsNQaVo71wKPmorK+xnbM
h1PQAVJeXypLTAfE636+n+Md/wSvnQuo0RzPBE24S9c9TWM2d96dvtU9kgJPbqoA
RX6jHw2ACnKp4RFJILqDCqFCOrytYPk3J/L8myW44dGpCCdSrFREqNCsyMrqu4v7
U+W9ENHT0qe7Nm0T4XNFlQstt6uGvk6ddEdbgcTfTvSv5jx2++Jfl2ynF+G67l0U
UASFHsrwThnulGQtpK2+heHkU8xQFjQOGZoQMlLiWzWg+bqo07aghAndKhKnW8s8
iRvMvdcsLjjDaPFCgeopGeQauiTd2od5aXGWCn+djzLq0fjIvezs4K70XOsStbGA
cJFFAnsnM40SbnrWyfe1EBlzuVJu0csuF77fpEU7CFz8uzd268Ho
-----END CERTIFICATE-----

View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOUlrNSewqNM4x31I4DeuP5GksD7NUfMZ3Lui+eFCD33oAoGCCqGSM49
AwEHoUQDQgAEH9/YWeczKMngMCXY3woc+fdJ0Pgbgkwm+ad8wGb2DXA7puDbfiIi
Ez7z8qZDehxnckl5KdcWIK8hNcKBCRGILQ==
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDaTCCAVGgAwIBAgIIXrx+TJOdkuYwDQYJKoZIhvcNAQELBQAwKTEnMCUGA1UE
AwweazNzLWludGVybWVkaWF0ZS1jYUAxNzUxOTY1MTAwMB4XDTI1MDcwODA4NTgy
NFoXDTM1MDgyNTA4NTgyNFowJjEkMCIGA1UEAwwbazNzLWV0Y2QtcGVlci1jYUAx
NzUxOTY1MTAwMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEH9/YWeczKMngMCXY
3woc+fdJ0Pgbgkwm+ad8wGb2DXA7puDbfiIiEz7z8qZDehxnckl5KdcWIK8hNcKB
CRGILaNjMGEwHQYDVR0OBBYEFI0GOYl4luW+/mBH7BCKsBZbnC0vMB8GA1UdIwQY
MBaAFJlWOM0MjJgK2OweAyu1eVn/fUi6MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
AQH/BAQDAgKkMA0GCSqGSIb3DQEBCwUAA4ICAQClsvi6TIEfYkRJ3923gMEmhAaF
WIXdLssY/FQSdhYeNBaJksTHPCmWDKpKJzL0x5MdePNy2oYPCtrAVzbyQe/oatp/
gg2krE1Wnq8YG95d/MrELZ5KGkQcwA8MGs2sMHYe/0XNDQ/DKOOJBhGvxs3OfySQ
BUks+UiY7UIpolTbxPIGI56IBfKk16fAPA57O9nQv1ReioEWnrOsJY7B/Dxly8tR
qlLwSJ5mJFs1ozFOrBG/CZ+zn/fRthXH7M2tYtmv8lEnOGE0R0A8iaW/vc9kWwq0
N6jSoC/w7njMl1rTMWrInsqa5ippK1EwV1kERF+qer08eJ/giZoA16C0zyG6ajPD
z/qSzn2TiknZR1DX7zZsvwfactpwUDK+taTL/3kbUzQYayjjG1PI/dNmELqWLXqZ
AoG5/s6+TKdSxjLGbchw56AC6E1+I0dNLMbxzjrNlIpa9V9BjI1ZbHIlEzjO7a63
1eZH9Ni5kYiaFUOtzqZQiM34W6q0LDAowyELik8FEkoe5fNsknWAhiSEDfbil8u+
NpNlQqpMxLydqZvepEyx34tsu4gvunPMFkxh+5kpSDmWm9e3oK7g1Mt7+qaxsy/N
jkoLbiP2ZVCp4LSwQombPNZFupo33kwIi1wN5F4RLlfesDHs007UrhV403xP7g3d
V9Q1NXFPCuFOCThm/w==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,81 @@
-----BEGIN CERTIFICATE-----
MIIDazCCAVOgAwIBAgIIXrx+TJOdkucwDQYJKoZIhvcNAQELBQAwKTEnMCUGA1UE
AwweazNzLWludGVybWVkaWF0ZS1jYUAxNzUxOTY1MTAwMB4XDTI1MDcwODA4NTgy
NFoXDTM1MDgyNTA4NTgyNFowKDEmMCQGA1UEAwwdazNzLWV0Y2Qtc2VydmVyLWNh
QDE3NTE5NjUxMDAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARmeiGLbDolASE6
7xA661ONzvJ4VwflDZ/b4bdS+5RlMjoVYPZXQN+Pr5GwDx+AkxoXJxm9O6Kgpp/d
txWrJl5mo2MwYTAdBgNVHQ4EFgQUlkh6vQIk77W9P5jJbv6u1XWh2gwwHwYDVR0j
BBgwFoAUmVY4zQyMmArY7B4DK7V5Wf99SLowDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQELBQADggIBAMjWYIUg4NNLFcCEQNYKLk92
e4t89kr9iVSz81Kr38xD1GAdR2rMitCe2MFgjtimOf01APOzJh/yCDHLIJNKprfu
NP0EaXM/0NkGnsx+8jWwc0GETPgEdkfg1ZBd9gJirQRs7yfReYI3AlXrvNW4+8CL
Cjji3BfJ+GHPs23HX8IKrNJeyULdPGSqwIvJpqjkvI5XkVgK0i64jf6wzZOgkX+a
gvwC4/xTu4jhCtSpoLE5M1Zf+sFufuVw1N/9y4FEr/aB5lfdFNYA14GyGrxrJ+56
DVfCoXBJfUCeognhXcolX6/QakBEdv2DQOBR8P/1AYBrwSCJDYJi70Z9RRH2sbM+
dmtB+dTcm6QF713tswT71+ZbZNkkaazpHfVkRlIkCTXzPFuNLAEoiorBjfQAZRNg
tMbXet6OECO/eS3vlTm4cj5D+aux3qjhnF5cn/cNyZ4lsZBm0lCQ72zF6ZL5RuIN
JWKh2++wUlAX7VZXc5ku0yIMNJVv7C8FUZK0YcDH9tRncYNkHAJpVQNE5Cr2VukG
InJCbl7cuXQK8cqa+36pgcV6/bqZas7/G6dVKPprSpF3G0vMRCx6QMcJIOrfjpB0
pXuXsotFKLN8p9TCkcAYYWu3pvhLDqn/l2ESQgXbiUAyYonrE1ndrLQWaMUq4glu
hatNYA2lxZ9c2Yb9bLoW
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFLzCCAxegAwIBAgIIXrx+TJOdkuIwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UE
AwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgwODU4MjNaFw0zNTA4
MjUwODU4MjNaMCkxJzAlBgNVBAMMHmszcy1pbnRlcm1lZGlhdGUtY2FAMTc1MTk2
NTEwMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfxJHxlMq/Ul+7X
avcxrg6x8joXUn0T4TbaYiQJVRK0z8j42yDh1uJSQ82SkCB1ltkF2xHzQ65iqPx9
n6uluTP/fEoGOiGxfZfIqk+H+mPbumJPd7n3hmtqPwPmjhYCPZpLadT60rjNalkM
4hUX2O0PwXtvejODUaLgF9YLUJbIdoZvkzKNcv2bTg9gruW0AoAzEqAKLYRDh58N
XQMync3OQnnAMzUyPBBukhM7P2tysufV0HJg/ZcsgLek8hpuBQ2T1QVUrZFAgOXh
ZCcrK5OGKcjQh5bo1vcbIRr4DtfHT/Jl5RhA6q5IqTAiS/dQVAhNYs0lDHgF69kU
gI2iHqsv2awuW3k9Q+i5q9vMlo/h9wxpj87cbfxLpBkS2o/h+6zB1DdI6U1WRo/Q
pFp3vzsdtr/G8WEFxwL1OMDewjA+EsjhSjI0BBrm7CC2uJkNRM3v97r9RGNzBCYL
Qn3IxqqzVjOOEhJzQc3G8FKRJj1zPAkURvTus4s9c7vdMOp1sVd78b9ObXFa0TDF
DPe9ZQu5YGEvGGibKjp5cFwJ2M2pwjv53ZUDS4sxqqdXRBmVxcCkUtrwRL35PIpb
Tje1UZP8RJ66iXnXUPco2BKyd9NYyiaUAW4gZz5WROzfgPdnI/ArGc5RThk+O5sg
cb62eU/nADPGsG8t+VEUXfJjP19pAgMBAAGjYzBhMB0GA1UdDgQWBBSZVjjNDIyY
CtjsHgMrtXlZ/31IujAfBgNVHSMEGDAWgBSML4NHrHhdoo46ZRedOusGhJBsTDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwICpDANBgkqhkiG9w0BAQsFAAOC
AgEAxgdjETEkUB7G2g3cFz6Jb8TznrZXprVk9G1p1UNuMAAEe2NaiGI0BvivJNoQ
6DNpngB3x6l7u5hMOJY/72wzQRDXg05m5T8/vBfTcz/HcgoKU82hgYDxQiGA0I5e
5czfEhQu95uPT7T26m5pvWA38Tf6WbXCB7c0/FT8II8w1ptJlZrSKRW33+j1tb2r
t0/8RoMaAUS1MP6+12juG7qcuEx0rDVeKx33pa20NjsAtZeTAsXjugJkmUkkd/PC
cKbawQB9meqtWPfGzwmUu1qz6SQeWtOWFrOBSeTzx0HTeimSAiHVSaXGd7ms3orx
KsKUoPUbXi9rVIDVxCe5XwAKmcHMz8DGHfxJ6sodol25pYbHxKy/swgAzQdwtGF9
HWJAm6/3YSjtmD6+t89/yYzvxv+aMNDXVMLpDFb+7/ESsSl4757WjvvFoz0HxcwD
4qfmV2z+EaLM44P3QaJDD599/Qwt+TFHSQRfD/MqMH6A+9vZhZGWeGgFFmu82kzH
xKJas/jI+t+V+2TbfagUYlsinZ6UmLcju99myl6wq6nJu8X5b8Uhpv5/8kVniqXE
lWtFpMBmnE0oq0U+KR3OfnovSYdYTc7uWpaJlqMamsE5UVVBrlSyUe9J9EQzYYea
Ufoq67KnJInMobbQ4aonz7EQZW6WIZpqASuVGfT5heSKHDc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFMzCCAxugAwIBAgIUALEl344JEZxaOvwyrtO8QwLHAacwDQYJKoZIhvcNAQEL
BQAwITEfMB0GA1UEAwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgw
ODU4MjJaFw00NTA3MDMwODU4MjJaMCExHzAdBgNVBAMMFmszcy1yb290LWNhQDE3
NTE5NjUxMDAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDtESS+0V7T
0b3rN0ga9/zWThgaGIfOoKiCr2CSR4az0hjpmISAlS5pplhWrutGhydvaR/7vV7g
Grtn0ptmqidEc0XSeQTosqUv29SZ+hbCITZG05TFbMGGXmFo/1LHhJ8ZpgzUBqc7
inOXmEBbCyhOWX+fhddoJJiUIX7l2R3cbyNk7I7KFiZ1JDDnoyDWFMOJLvXwOqeT
CJQesS+2qpeXpdazgtkRQi7aOhZtXnCsJHnFbpL9VFTmWpq7vMIA9xkDva3/80S4
T2USiyN4/quUagjP8si5PIaGBVx9bJhnKHUdTrPPZWHFfxm74GUG7en4OtR9lOTM
TV49XuofNpJaJ2K5Dz+rk6gIYp2R9W+r8CN1HBXeLF5WJCvw54Lpcp0V2BA+MARq
Ij8UTUymu++rIo+WjKcHDT0qn39rhOhqJ3dXynW4UF/95KwB7e5UI+OxZ9sJ4oNP
FuP5PHrDINXsYG0DDM3KTDxA8memVSFGMdhm31DPD2GUvUPlupnd6uCepdcBc9ed
+9gTeSxF5cA6Q3gVOQa8ok9Ts0E5DwGaCIxjasyD+MIORf3Bkv0Z3lBNXicWDngP
FU5ya30GeTZQgzqhlGoXehjYfRxV28pgiR5ejl0/rmsYGfiWPdfa4Qy0LnxSKHj1
f2R1jEB55ORATo3f+k4Ez5bdjhk4KlA95QIDAQABo2MwYTAdBgNVHQ4EFgQUjC+D
R6x4XaKOOmUXnTrrBoSQbEwwHwYDVR0jBBgwFoAUjC+DR6x4XaKOOmUXnTrrBoSQ
bEwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQEL
BQADggIBACpzO1nV6/hS1xLIkkGf9RdypATYCH6RqeBJqMf/R5YEUQssLF/QBEvQ
NwockkxD1l8VwjH3Pp36QxkgthAl0D3ewK9LLkxEq1pp9VuVGxeD9siN/fxx6htG
KP1jT49pBDIdbzhJ7eR/O8xuI5dyZNLZLJkaumQkd7sEVHvDTFw55PhwUEJ3Wcxl
jAxXM1FFCKftXjWFmvVmzYZYkPj/AhB+PcVIIkFnNQYTXdUCUtsnSgj3pF1z/+g5
PttBGhsttrm93lJgddRFTEWV1lzfw1csrHkLYDYLDKDzsNQaVo71wKPmorK+xnbM
h1PQAVJeXypLTAfE636+n+Md/wSvnQuo0RzPBE24S9c9TWM2d96dvtU9kgJPbqoA
RX6jHw2ACnKp4RFJILqDCqFCOrytYPk3J/L8myW44dGpCCdSrFREqNCsyMrqu4v7
U+W9ENHT0qe7Nm0T4XNFlQstt6uGvk6ddEdbgcTfTvSv5jx2++Jfl2ynF+G67l0U
UASFHsrwThnulGQtpK2+heHkU8xQFjQOGZoQMlLiWzWg+bqo07aghAndKhKnW8s8
iRvMvdcsLjjDaPFCgeopGeQauiTd2od5aXGWCn+djzLq0fjIvezs4K70XOsStbGA
cJFFAnsnM40SbnrWyfe1EBlzuVJu0csuF77fpEU7CFz8uzd268Ho
-----END CERTIFICATE-----

View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEICaMBfRVf3YbfM9fgseSQ9gdYGEMmumos1Ddy3Vtz6l3oAoGCCqGSM49
AwEHoUQDQgAEZnohi2w6JQEhOu8QOutTjc7yeFcH5Q2f2+G3UvuUZTI6FWD2V0Df
j6+RsA8fgJMaFycZvTuioKaf3bcVqyZeZg==
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDazCCAVOgAwIBAgIIXrx+TJOdkucwDQYJKoZIhvcNAQELBQAwKTEnMCUGA1UE
AwweazNzLWludGVybWVkaWF0ZS1jYUAxNzUxOTY1MTAwMB4XDTI1MDcwODA4NTgy
NFoXDTM1MDgyNTA4NTgyNFowKDEmMCQGA1UEAwwdazNzLWV0Y2Qtc2VydmVyLWNh
QDE3NTE5NjUxMDAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARmeiGLbDolASE6
7xA661ONzvJ4VwflDZ/b4bdS+5RlMjoVYPZXQN+Pr5GwDx+AkxoXJxm9O6Kgpp/d
txWrJl5mo2MwYTAdBgNVHQ4EFgQUlkh6vQIk77W9P5jJbv6u1XWh2gwwHwYDVR0j
BBgwFoAUmVY4zQyMmArY7B4DK7V5Wf99SLowDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQELBQADggIBAMjWYIUg4NNLFcCEQNYKLk92
e4t89kr9iVSz81Kr38xD1GAdR2rMitCe2MFgjtimOf01APOzJh/yCDHLIJNKprfu
NP0EaXM/0NkGnsx+8jWwc0GETPgEdkfg1ZBd9gJirQRs7yfReYI3AlXrvNW4+8CL
Cjji3BfJ+GHPs23HX8IKrNJeyULdPGSqwIvJpqjkvI5XkVgK0i64jf6wzZOgkX+a
gvwC4/xTu4jhCtSpoLE5M1Zf+sFufuVw1N/9y4FEr/aB5lfdFNYA14GyGrxrJ+56
DVfCoXBJfUCeognhXcolX6/QakBEdv2DQOBR8P/1AYBrwSCJDYJi70Z9RRH2sbM+
dmtB+dTcm6QF713tswT71+ZbZNkkaazpHfVkRlIkCTXzPFuNLAEoiorBjfQAZRNg
tMbXet6OECO/eS3vlTm4cj5D+aux3qjhnF5cn/cNyZ4lsZBm0lCQ72zF6ZL5RuIN
JWKh2++wUlAX7VZXc5ku0yIMNJVv7C8FUZK0YcDH9tRncYNkHAJpVQNE5Cr2VukG
InJCbl7cuXQK8cqa+36pgcV6/bqZas7/G6dVKPprSpF3G0vMRCx6QMcJIOrfjpB0
pXuXsotFKLN8p9TCkcAYYWu3pvhLDqn/l2ESQgXbiUAyYonrE1ndrLQWaMUq4glu
hatNYA2lxZ9c2Yb9bLoW
-----END CERTIFICATE-----

View File

@@ -0,0 +1,60 @@
-----BEGIN CERTIFICATE-----
MIIFLzCCAxegAwIBAgIIXrx+TJOdkuIwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UE
AwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgwODU4MjNaFw0zNTA4
MjUwODU4MjNaMCkxJzAlBgNVBAMMHmszcy1pbnRlcm1lZGlhdGUtY2FAMTc1MTk2
NTEwMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfxJHxlMq/Ul+7X
avcxrg6x8joXUn0T4TbaYiQJVRK0z8j42yDh1uJSQ82SkCB1ltkF2xHzQ65iqPx9
n6uluTP/fEoGOiGxfZfIqk+H+mPbumJPd7n3hmtqPwPmjhYCPZpLadT60rjNalkM
4hUX2O0PwXtvejODUaLgF9YLUJbIdoZvkzKNcv2bTg9gruW0AoAzEqAKLYRDh58N
XQMync3OQnnAMzUyPBBukhM7P2tysufV0HJg/ZcsgLek8hpuBQ2T1QVUrZFAgOXh
ZCcrK5OGKcjQh5bo1vcbIRr4DtfHT/Jl5RhA6q5IqTAiS/dQVAhNYs0lDHgF69kU
gI2iHqsv2awuW3k9Q+i5q9vMlo/h9wxpj87cbfxLpBkS2o/h+6zB1DdI6U1WRo/Q
pFp3vzsdtr/G8WEFxwL1OMDewjA+EsjhSjI0BBrm7CC2uJkNRM3v97r9RGNzBCYL
Qn3IxqqzVjOOEhJzQc3G8FKRJj1zPAkURvTus4s9c7vdMOp1sVd78b9ObXFa0TDF
DPe9ZQu5YGEvGGibKjp5cFwJ2M2pwjv53ZUDS4sxqqdXRBmVxcCkUtrwRL35PIpb
Tje1UZP8RJ66iXnXUPco2BKyd9NYyiaUAW4gZz5WROzfgPdnI/ArGc5RThk+O5sg
cb62eU/nADPGsG8t+VEUXfJjP19pAgMBAAGjYzBhMB0GA1UdDgQWBBSZVjjNDIyY
CtjsHgMrtXlZ/31IujAfBgNVHSMEGDAWgBSML4NHrHhdoo46ZRedOusGhJBsTDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwICpDANBgkqhkiG9w0BAQsFAAOC
AgEAxgdjETEkUB7G2g3cFz6Jb8TznrZXprVk9G1p1UNuMAAEe2NaiGI0BvivJNoQ
6DNpngB3x6l7u5hMOJY/72wzQRDXg05m5T8/vBfTcz/HcgoKU82hgYDxQiGA0I5e
5czfEhQu95uPT7T26m5pvWA38Tf6WbXCB7c0/FT8II8w1ptJlZrSKRW33+j1tb2r
t0/8RoMaAUS1MP6+12juG7qcuEx0rDVeKx33pa20NjsAtZeTAsXjugJkmUkkd/PC
cKbawQB9meqtWPfGzwmUu1qz6SQeWtOWFrOBSeTzx0HTeimSAiHVSaXGd7ms3orx
KsKUoPUbXi9rVIDVxCe5XwAKmcHMz8DGHfxJ6sodol25pYbHxKy/swgAzQdwtGF9
HWJAm6/3YSjtmD6+t89/yYzvxv+aMNDXVMLpDFb+7/ESsSl4757WjvvFoz0HxcwD
4qfmV2z+EaLM44P3QaJDD599/Qwt+TFHSQRfD/MqMH6A+9vZhZGWeGgFFmu82kzH
xKJas/jI+t+V+2TbfagUYlsinZ6UmLcju99myl6wq6nJu8X5b8Uhpv5/8kVniqXE
lWtFpMBmnE0oq0U+KR3OfnovSYdYTc7uWpaJlqMamsE5UVVBrlSyUe9J9EQzYYea
Ufoq67KnJInMobbQ4aonz7EQZW6WIZpqASuVGfT5heSKHDc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFMzCCAxugAwIBAgIUALEl344JEZxaOvwyrtO8QwLHAacwDQYJKoZIhvcNAQEL
BQAwITEfMB0GA1UEAwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgw
ODU4MjJaFw00NTA3MDMwODU4MjJaMCExHzAdBgNVBAMMFmszcy1yb290LWNhQDE3
NTE5NjUxMDAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDtESS+0V7T
0b3rN0ga9/zWThgaGIfOoKiCr2CSR4az0hjpmISAlS5pplhWrutGhydvaR/7vV7g
Grtn0ptmqidEc0XSeQTosqUv29SZ+hbCITZG05TFbMGGXmFo/1LHhJ8ZpgzUBqc7
inOXmEBbCyhOWX+fhddoJJiUIX7l2R3cbyNk7I7KFiZ1JDDnoyDWFMOJLvXwOqeT
CJQesS+2qpeXpdazgtkRQi7aOhZtXnCsJHnFbpL9VFTmWpq7vMIA9xkDva3/80S4
T2USiyN4/quUagjP8si5PIaGBVx9bJhnKHUdTrPPZWHFfxm74GUG7en4OtR9lOTM
TV49XuofNpJaJ2K5Dz+rk6gIYp2R9W+r8CN1HBXeLF5WJCvw54Lpcp0V2BA+MARq
Ij8UTUymu++rIo+WjKcHDT0qn39rhOhqJ3dXynW4UF/95KwB7e5UI+OxZ9sJ4oNP
FuP5PHrDINXsYG0DDM3KTDxA8memVSFGMdhm31DPD2GUvUPlupnd6uCepdcBc9ed
+9gTeSxF5cA6Q3gVOQa8ok9Ts0E5DwGaCIxjasyD+MIORf3Bkv0Z3lBNXicWDngP
FU5ya30GeTZQgzqhlGoXehjYfRxV28pgiR5ejl0/rmsYGfiWPdfa4Qy0LnxSKHj1
f2R1jEB55ORATo3f+k4Ez5bdjhk4KlA95QIDAQABo2MwYTAdBgNVHQ4EFgQUjC+D
R6x4XaKOOmUXnTrrBoSQbEwwHwYDVR0jBBgwFoAUjC+DR6x4XaKOOmUXnTrrBoSQ
bEwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQEL
BQADggIBACpzO1nV6/hS1xLIkkGf9RdypATYCH6RqeBJqMf/R5YEUQssLF/QBEvQ
NwockkxD1l8VwjH3Pp36QxkgthAl0D3ewK9LLkxEq1pp9VuVGxeD9siN/fxx6htG
KP1jT49pBDIdbzhJ7eR/O8xuI5dyZNLZLJkaumQkd7sEVHvDTFw55PhwUEJ3Wcxl
jAxXM1FFCKftXjWFmvVmzYZYkPj/AhB+PcVIIkFnNQYTXdUCUtsnSgj3pF1z/+g5
PttBGhsttrm93lJgddRFTEWV1lzfw1csrHkLYDYLDKDzsNQaVo71wKPmorK+xnbM
h1PQAVJeXypLTAfE636+n+Md/wSvnQuo0RzPBE24S9c9TWM2d96dvtU9kgJPbqoA
RX6jHw2ACnKp4RFJILqDCqFCOrytYPk3J/L8myW44dGpCCdSrFREqNCsyMrqu4v7
U+W9ENHT0qe7Nm0T4XNFlQstt6uGvk6ddEdbgcTfTvSv5jx2++Jfl2ynF+G67l0U
UASFHsrwThnulGQtpK2+heHkU8xQFjQOGZoQMlLiWzWg+bqo07aghAndKhKnW8s8
iRvMvdcsLjjDaPFCgeopGeQauiTd2od5aXGWCn+djzLq0fjIvezs4K70XOsStbGA
cJFFAnsnM40SbnrWyfe1EBlzuVJu0csuF77fpEU7CFz8uzd268Ho
-----END CERTIFICATE-----

View File

@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
MIIJJwIBAAKCAgEA1/EkfGUyr9SX7tdq9zGuDrHyOhdSfRPhNtpiJAlVErTPyPjb
IOHW4lJDzZKQIHWW2QXbEfNDrmKo/H2fq6W5M/98SgY6IbF9l8iqT4f6Y9u6Yk93
ufeGa2o/A+aOFgI9mktp1PrSuM1qWQziFRfY7Q/Be296M4NRouAX1gtQlsh2hm+T
Mo1y/ZtOD2Cu5bQCgDMSoAothEOHnw1dAzKdzc5CecAzNTI8EG6SEzs/a3Ky59XQ
cmD9lyyAt6TyGm4FDZPVBVStkUCA5eFkJysrk4YpyNCHlujW9xshGvgO18dP8mXl
GEDqrkipMCJL91BUCE1izSUMeAXr2RSAjaIeqy/ZrC5beT1D6Lmr28yWj+H3DGmP
ztxt/EukGRLaj+H7rMHUN0jpTVZGj9CkWne/Ox22v8bxYQXHAvU4wN7CMD4SyOFK
MjQEGubsILa4mQ1Eze/3uv1EY3MEJgtCfcjGqrNWM44SEnNBzcbwUpEmPXM8CRRG
9O6ziz1zu90w6nWxV3vxv05tcVrRMMUM971lC7lgYS8YaJsqOnlwXAnYzanCO/nd
lQNLizGqp1dEGZXFwKRS2vBEvfk8iltON7VRk/xEnrqJeddQ9yjYErJ301jKJpQB
biBnPlZE7N+A92cj8CsZzlFOGT47myBxvrZ5T+cAM8awby35URRd8mM/X2kCAwEA
AQKCAgAcJAAxt8xhro44IVl+qjo5DwZ2fIiS5S7Rw6bLdG3iOK7lTUzdHaEvsDHG
zeU7XaeRU5qHXdDBnnjQIpzWtQuME6zCRsp3jpZD2/IZ2CoQrlc9LYb4NKIPSHK6
0uZMRvF5NH+vshoY3CgSP8QMpKVvy0BXEiF2KhRO6e4hRisz4x7TCSJBEb7c/squ
5VYVeB5lT4KLWZgx5sz7NLYczxFSeyEdlab2tTuvloExwWRT38ghvzLhXPNfKn0B
sZydRh4hdVTq02ylA6dojbVMB2uv12mFkmtBBsnQvPfU+GOSyhYIjC/NN9R9btmh
fK6ypYS16kPIYR4dXAQur2XLT0e4oPyloIJCLsM5e1kOToQaHXRz5HzAhSdue7Cx
18jYe3IdZb1a7T+JoDbCp/9fqTSpuIecSwzfQK67/NSBr8oRZr/dUDzlmFA9zo7+
BYzY+7l+6hfpYlaEzCtF1wrZkgjk/aoRjjKTO1HdbKs1vd5bFcnlf82ZDP2eDZhL
QTURY8hc+DD8+92iqiLJfd+MlOznMt9xo2JmwEsb0q3aGoQpm5PZNx7VdnNl4C/B
+JcatbGQX19r1JiZ+BbxdvssLUbWq+qqnYqijyk7XFV4TFmq3lKd6CCoYE16KupW
n94LBWHkTMRjbSMDxL5hLTz2SbwAwZMuCmjd68vZ4TcNaxzM2wKCAQEA8x5oJMxG
uy9h2sbJ6M91Cr7Q2qfbGNSOg2G5H+x2J15rdtUNB+IaJGXwwuu62nhQQ7QZ8Oi/
GL4Gro7THs0+StKOyhj3YEU5bsCLTisBjW0FVlFadW/f2XdP573hxpGIRj08EA3e
1RA9qoFA+9uzjB1wbBEdXVzQJoPmKAGP9yzK4KKRZ41LNo2ElCc2tZQBHDWrjcaG
6xAPGsBF5/iWu738hxMJZXb17nz5klmoYBQ0j+yBEi4xoNPGNf7SsvCGBwTdkMZv
v97u0oZK1RJrJxJvR/Wj7xDs4ff1U/OLAaxRW2cVrF3QIdUovblEVwnklHEC5UsC
O0JwsE5SOcYzbwKCAQEA42IeAnVxdGJskMtU9M5igkEFFK3rtCI+rFUX1IPU7ZGN
+RFmVeBuauSYy84+3kSJXiEjM3H//DuT7oXiK7GWAgU/4z1YOePGsWIa/W1O0sD/
oZ0KY/QDd38jQShMbc2hcVZRkthSE1UTZlkGXsduIHY/wsAHx5K9NiFXvQ8F0d7E
Es4h5ryz7e+5a4rAdjbcuqw6+nLlEbgtn9U3f43euLzWys+QTI7Ojof5JTzVgvXf
cQsOfszWkoDKFUEm26az3Gt09fzjR8GR8xucvIed4SF5rS1zkRDxPQMMQGaI0JHn
Hu5SBlQenScRQ39nuPnu5QiCtYQMyLJM0qPkYThOpwKCAQA9PhKj+mVy78uprdvc
7q2gKFM6UYBqr9i6ldpphUp6Plm51I90xesp8hgFMhaexCIL/Alw22CQHgZW4Jmk
L7WaaZIYrNNcB/QgxxYQedrpQmZOyS2NWcI86MZTLUz7lVuLvg8sSCIy7+Vo1yiE
iWKgUCYqwuDvzNqOaTmIKGSYskrk7W7NdBVXR6z3GS257e+dqJNvomwIOMJlTbwO
ZFusLX64k/4Q9jebfRXtXPKCSXS4MK6O4t4TkmVi4q827koE6J/bwXETF1h35eZh
6ELf08/+g41pQo05mxnMrRP+NudDrCMUiYlNjIG30Ty65D4VeqZtFkkYnnL+pqwl
65y3AoIBAD6lYa87vC5cj5y06Isp8WoBj+zKng3bAXlpWE9sotVxLLRaXt96HfHF
WXONNzT1nQMaDiC2X9iWcYNdz5pKKxITcC6jUBNi9fMZHGaGHxlhowxbv+kZ6Xqa
xJPHDoeSB9C5/299ud8pqVahYGfseiLncVmunnYVr5uiRBIKeYgA3/RuZliz1L7R
NTyz1aK8KsQjf3xQ+1uOasOGcuvpolsza9okpZTyI2aRf8sKn6idJRp3+V5mARgL
86E3egU6QIOR939uVRAH/LYF/YDTvGOyXVuhEh39lPlCRbXYigksqYiUEHU959FU
WiVGjMUh1vezCJAJ+ZuxxAikrt86LDECggEANzLem5zdf3PIl3wKwcKau1IhRO11
c3hlpoTf0u/A1+tBXMXeSw7Shl1vGgVnV9IQ1eL4Lyxpj9c8724LVVNLcB7vU0DF
5WQw0bjV8PS0wg4YpJ8wSToE3FNSn1wAqn8zrmC5/y49vvOQsYjtyGMjr4Vn5P6h
ZKwSsKX1YMyaz/28kxxvOlwrWegaqXDWjwfOvYLIsLcJK33cXoKSYfe45HP55YK6
Rbc3ZdfZXLohCSxwcnAHefIjeTlcSVI3JZafF+Mn1U50f2CxK0Thr70waSSf/x4C
pP9KxgoP2URf7xLYK7tM40Lj+Mhwp+SAK2K00xLyxBySHD6FQE8ifFeZ4g==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFLzCCAxegAwIBAgIIXrx+TJOdkuIwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UE
AwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgwODU4MjNaFw0zNTA4
MjUwODU4MjNaMCkxJzAlBgNVBAMMHmszcy1pbnRlcm1lZGlhdGUtY2FAMTc1MTk2
NTEwMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfxJHxlMq/Ul+7X
avcxrg6x8joXUn0T4TbaYiQJVRK0z8j42yDh1uJSQ82SkCB1ltkF2xHzQ65iqPx9
n6uluTP/fEoGOiGxfZfIqk+H+mPbumJPd7n3hmtqPwPmjhYCPZpLadT60rjNalkM
4hUX2O0PwXtvejODUaLgF9YLUJbIdoZvkzKNcv2bTg9gruW0AoAzEqAKLYRDh58N
XQMync3OQnnAMzUyPBBukhM7P2tysufV0HJg/ZcsgLek8hpuBQ2T1QVUrZFAgOXh
ZCcrK5OGKcjQh5bo1vcbIRr4DtfHT/Jl5RhA6q5IqTAiS/dQVAhNYs0lDHgF69kU
gI2iHqsv2awuW3k9Q+i5q9vMlo/h9wxpj87cbfxLpBkS2o/h+6zB1DdI6U1WRo/Q
pFp3vzsdtr/G8WEFxwL1OMDewjA+EsjhSjI0BBrm7CC2uJkNRM3v97r9RGNzBCYL
Qn3IxqqzVjOOEhJzQc3G8FKRJj1zPAkURvTus4s9c7vdMOp1sVd78b9ObXFa0TDF
DPe9ZQu5YGEvGGibKjp5cFwJ2M2pwjv53ZUDS4sxqqdXRBmVxcCkUtrwRL35PIpb
Tje1UZP8RJ66iXnXUPco2BKyd9NYyiaUAW4gZz5WROzfgPdnI/ArGc5RThk+O5sg
cb62eU/nADPGsG8t+VEUXfJjP19pAgMBAAGjYzBhMB0GA1UdDgQWBBSZVjjNDIyY
CtjsHgMrtXlZ/31IujAfBgNVHSMEGDAWgBSML4NHrHhdoo46ZRedOusGhJBsTDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwICpDANBgkqhkiG9w0BAQsFAAOC
AgEAxgdjETEkUB7G2g3cFz6Jb8TznrZXprVk9G1p1UNuMAAEe2NaiGI0BvivJNoQ
6DNpngB3x6l7u5hMOJY/72wzQRDXg05m5T8/vBfTcz/HcgoKU82hgYDxQiGA0I5e
5czfEhQu95uPT7T26m5pvWA38Tf6WbXCB7c0/FT8II8w1ptJlZrSKRW33+j1tb2r
t0/8RoMaAUS1MP6+12juG7qcuEx0rDVeKx33pa20NjsAtZeTAsXjugJkmUkkd/PC
cKbawQB9meqtWPfGzwmUu1qz6SQeWtOWFrOBSeTzx0HTeimSAiHVSaXGd7ms3orx
KsKUoPUbXi9rVIDVxCe5XwAKmcHMz8DGHfxJ6sodol25pYbHxKy/swgAzQdwtGF9
HWJAm6/3YSjtmD6+t89/yYzvxv+aMNDXVMLpDFb+7/ESsSl4757WjvvFoz0HxcwD
4qfmV2z+EaLM44P3QaJDD599/Qwt+TFHSQRfD/MqMH6A+9vZhZGWeGgFFmu82kzH
xKJas/jI+t+V+2TbfagUYlsinZ6UmLcju99myl6wq6nJu8X5b8Uhpv5/8kVniqXE
lWtFpMBmnE0oq0U+KR3OfnovSYdYTc7uWpaJlqMamsE5UVVBrlSyUe9J9EQzYYea
Ufoq67KnJInMobbQ4aonz7EQZW6WIZpqASuVGfT5heSKHDc=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,81 @@
-----BEGIN CERTIFICATE-----
MIIDbjCCAVagAwIBAgIIXrx+TJOdkuUwDQYJKoZIhvcNAQELBQAwKTEnMCUGA1UE
AwweazNzLWludGVybWVkaWF0ZS1jYUAxNzUxOTY1MTAwMB4XDTI1MDcwODA4NTgy
NFoXDTM1MDgyNTA4NTgyNFowKzEpMCcGA1UEAwwgazNzLXJlcXVlc3QtaGVhZGVy
LWNhQDE3NTE5NjUxMDAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASJMULFots9
+kX+1xECtfDnn7ECAdfOXs+rWD6SwVII9iCYs2G3fH0I4XtBChJkgTLldvuEp9SW
l+AsAhag81oMo2MwYTAdBgNVHQ4EFgQUorDfU1fyEsXL5LLhvRnhb2ohF5QwHwYD
VR0jBBgwFoAUmVY4zQyMmArY7B4DK7V5Wf99SLowDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQELBQADggIBAEa3NyNf5roUG8MlpsMa
TcyIQJ2KyEvNhQxvyY9kBLHmWQpIcXdg1yGFS4t2fWs3tQItw97MTAptb1V/TqAW
h2UQeU6nsHyl2/iYXDknz1lBDYelQv9V+drvnW1ENFS6+M3973oeQ+G3APOsDUOq
xKIlRkwwLVJ/vJTRtQk3ZnhcqvcPAheALV3d7pLAOk3akoi7pA5IfWpe65Oee4dy
SM+qo0/wPytMfpn++mU3FxXXkS+Q9AUZJAzTB4rHI5yDXAP3x95FuuZCxD3Rd9j5
OEWGmVZHCRm0mq7QAmQNbWk0mYO5eANoQrBffooRPATIQyH6LxcaNfMfNhwmm1Px
SwlaQMzMfQ74geExXAhOsgt3S3pvuy4Fj6EMtcPJm69SuPBHIejWE7EE3H09sDlR
CKp+3OkWCslk5+wxhBOBgL4xMrMZSPbP5OYqfn4v1KbwO7rHu1ws/sPLJalz/bgT
dhRVkhBsLqfREI1dOthts4eE2NYjHXdNQ3cIV0rB+ZGHembivJmUROQANehOhUhF
/GIYn+MJXpbCFqeT4+/XB0EkiFnxjZtgTSk7rVQ9mVSEWhVKlCr+XB2J793nJ1/C
iosqQ9khSrqF8P01UoFLgZxIqaIjWxOgYvjVssPpr9X+I8p+dFqwNJ7ptJ+BfVMZ
OuWWE3YvsiKz1FsmYp8mQMs7
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFLzCCAxegAwIBAgIIXrx+TJOdkuIwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UE
AwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgwODU4MjNaFw0zNTA4
MjUwODU4MjNaMCkxJzAlBgNVBAMMHmszcy1pbnRlcm1lZGlhdGUtY2FAMTc1MTk2
NTEwMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfxJHxlMq/Ul+7X
avcxrg6x8joXUn0T4TbaYiQJVRK0z8j42yDh1uJSQ82SkCB1ltkF2xHzQ65iqPx9
n6uluTP/fEoGOiGxfZfIqk+H+mPbumJPd7n3hmtqPwPmjhYCPZpLadT60rjNalkM
4hUX2O0PwXtvejODUaLgF9YLUJbIdoZvkzKNcv2bTg9gruW0AoAzEqAKLYRDh58N
XQMync3OQnnAMzUyPBBukhM7P2tysufV0HJg/ZcsgLek8hpuBQ2T1QVUrZFAgOXh
ZCcrK5OGKcjQh5bo1vcbIRr4DtfHT/Jl5RhA6q5IqTAiS/dQVAhNYs0lDHgF69kU
gI2iHqsv2awuW3k9Q+i5q9vMlo/h9wxpj87cbfxLpBkS2o/h+6zB1DdI6U1WRo/Q
pFp3vzsdtr/G8WEFxwL1OMDewjA+EsjhSjI0BBrm7CC2uJkNRM3v97r9RGNzBCYL
Qn3IxqqzVjOOEhJzQc3G8FKRJj1zPAkURvTus4s9c7vdMOp1sVd78b9ObXFa0TDF
DPe9ZQu5YGEvGGibKjp5cFwJ2M2pwjv53ZUDS4sxqqdXRBmVxcCkUtrwRL35PIpb
Tje1UZP8RJ66iXnXUPco2BKyd9NYyiaUAW4gZz5WROzfgPdnI/ArGc5RThk+O5sg
cb62eU/nADPGsG8t+VEUXfJjP19pAgMBAAGjYzBhMB0GA1UdDgQWBBSZVjjNDIyY
CtjsHgMrtXlZ/31IujAfBgNVHSMEGDAWgBSML4NHrHhdoo46ZRedOusGhJBsTDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwICpDANBgkqhkiG9w0BAQsFAAOC
AgEAxgdjETEkUB7G2g3cFz6Jb8TznrZXprVk9G1p1UNuMAAEe2NaiGI0BvivJNoQ
6DNpngB3x6l7u5hMOJY/72wzQRDXg05m5T8/vBfTcz/HcgoKU82hgYDxQiGA0I5e
5czfEhQu95uPT7T26m5pvWA38Tf6WbXCB7c0/FT8II8w1ptJlZrSKRW33+j1tb2r
t0/8RoMaAUS1MP6+12juG7qcuEx0rDVeKx33pa20NjsAtZeTAsXjugJkmUkkd/PC
cKbawQB9meqtWPfGzwmUu1qz6SQeWtOWFrOBSeTzx0HTeimSAiHVSaXGd7ms3orx
KsKUoPUbXi9rVIDVxCe5XwAKmcHMz8DGHfxJ6sodol25pYbHxKy/swgAzQdwtGF9
HWJAm6/3YSjtmD6+t89/yYzvxv+aMNDXVMLpDFb+7/ESsSl4757WjvvFoz0HxcwD
4qfmV2z+EaLM44P3QaJDD599/Qwt+TFHSQRfD/MqMH6A+9vZhZGWeGgFFmu82kzH
xKJas/jI+t+V+2TbfagUYlsinZ6UmLcju99myl6wq6nJu8X5b8Uhpv5/8kVniqXE
lWtFpMBmnE0oq0U+KR3OfnovSYdYTc7uWpaJlqMamsE5UVVBrlSyUe9J9EQzYYea
Ufoq67KnJInMobbQ4aonz7EQZW6WIZpqASuVGfT5heSKHDc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFMzCCAxugAwIBAgIUALEl344JEZxaOvwyrtO8QwLHAacwDQYJKoZIhvcNAQEL
BQAwITEfMB0GA1UEAwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgw
ODU4MjJaFw00NTA3MDMwODU4MjJaMCExHzAdBgNVBAMMFmszcy1yb290LWNhQDE3
NTE5NjUxMDAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDtESS+0V7T
0b3rN0ga9/zWThgaGIfOoKiCr2CSR4az0hjpmISAlS5pplhWrutGhydvaR/7vV7g
Grtn0ptmqidEc0XSeQTosqUv29SZ+hbCITZG05TFbMGGXmFo/1LHhJ8ZpgzUBqc7
inOXmEBbCyhOWX+fhddoJJiUIX7l2R3cbyNk7I7KFiZ1JDDnoyDWFMOJLvXwOqeT
CJQesS+2qpeXpdazgtkRQi7aOhZtXnCsJHnFbpL9VFTmWpq7vMIA9xkDva3/80S4
T2USiyN4/quUagjP8si5PIaGBVx9bJhnKHUdTrPPZWHFfxm74GUG7en4OtR9lOTM
TV49XuofNpJaJ2K5Dz+rk6gIYp2R9W+r8CN1HBXeLF5WJCvw54Lpcp0V2BA+MARq
Ij8UTUymu++rIo+WjKcHDT0qn39rhOhqJ3dXynW4UF/95KwB7e5UI+OxZ9sJ4oNP
FuP5PHrDINXsYG0DDM3KTDxA8memVSFGMdhm31DPD2GUvUPlupnd6uCepdcBc9ed
+9gTeSxF5cA6Q3gVOQa8ok9Ts0E5DwGaCIxjasyD+MIORf3Bkv0Z3lBNXicWDngP
FU5ya30GeTZQgzqhlGoXehjYfRxV28pgiR5ejl0/rmsYGfiWPdfa4Qy0LnxSKHj1
f2R1jEB55ORATo3f+k4Ez5bdjhk4KlA95QIDAQABo2MwYTAdBgNVHQ4EFgQUjC+D
R6x4XaKOOmUXnTrrBoSQbEwwHwYDVR0jBBgwFoAUjC+DR6x4XaKOOmUXnTrrBoSQ
bEwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQEL
BQADggIBACpzO1nV6/hS1xLIkkGf9RdypATYCH6RqeBJqMf/R5YEUQssLF/QBEvQ
NwockkxD1l8VwjH3Pp36QxkgthAl0D3ewK9LLkxEq1pp9VuVGxeD9siN/fxx6htG
KP1jT49pBDIdbzhJ7eR/O8xuI5dyZNLZLJkaumQkd7sEVHvDTFw55PhwUEJ3Wcxl
jAxXM1FFCKftXjWFmvVmzYZYkPj/AhB+PcVIIkFnNQYTXdUCUtsnSgj3pF1z/+g5
PttBGhsttrm93lJgddRFTEWV1lzfw1csrHkLYDYLDKDzsNQaVo71wKPmorK+xnbM
h1PQAVJeXypLTAfE636+n+Md/wSvnQuo0RzPBE24S9c9TWM2d96dvtU9kgJPbqoA
RX6jHw2ACnKp4RFJILqDCqFCOrytYPk3J/L8myW44dGpCCdSrFREqNCsyMrqu4v7
U+W9ENHT0qe7Nm0T4XNFlQstt6uGvk6ddEdbgcTfTvSv5jx2++Jfl2ynF+G67l0U
UASFHsrwThnulGQtpK2+heHkU8xQFjQOGZoQMlLiWzWg+bqo07aghAndKhKnW8s8
iRvMvdcsLjjDaPFCgeopGeQauiTd2od5aXGWCn+djzLq0fjIvezs4K70XOsStbGA
cJFFAnsnM40SbnrWyfe1EBlzuVJu0csuF77fpEU7CFz8uzd268Ho
-----END CERTIFICATE-----

View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIC9U7kptnqrP7Yhr2npCmv3iR+5G2wysuzs2E1HMtiMQoAoGCCqGSM49
AwEHoUQDQgAEiTFCxaLbPfpF/tcRArXw55+xAgHXzl7Pq1g+ksFSCPYgmLNht3x9
COF7QQoSZIEy5Xb7hKfUlpfgLAIWoPNaDA==
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDbjCCAVagAwIBAgIIXrx+TJOdkuUwDQYJKoZIhvcNAQELBQAwKTEnMCUGA1UE
AwweazNzLWludGVybWVkaWF0ZS1jYUAxNzUxOTY1MTAwMB4XDTI1MDcwODA4NTgy
NFoXDTM1MDgyNTA4NTgyNFowKzEpMCcGA1UEAwwgazNzLXJlcXVlc3QtaGVhZGVy
LWNhQDE3NTE5NjUxMDAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASJMULFots9
+kX+1xECtfDnn7ECAdfOXs+rWD6SwVII9iCYs2G3fH0I4XtBChJkgTLldvuEp9SW
l+AsAhag81oMo2MwYTAdBgNVHQ4EFgQUorDfU1fyEsXL5LLhvRnhb2ohF5QwHwYD
VR0jBBgwFoAUmVY4zQyMmArY7B4DK7V5Wf99SLowDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQELBQADggIBAEa3NyNf5roUG8MlpsMa
TcyIQJ2KyEvNhQxvyY9kBLHmWQpIcXdg1yGFS4t2fWs3tQItw97MTAptb1V/TqAW
h2UQeU6nsHyl2/iYXDknz1lBDYelQv9V+drvnW1ENFS6+M3973oeQ+G3APOsDUOq
xKIlRkwwLVJ/vJTRtQk3ZnhcqvcPAheALV3d7pLAOk3akoi7pA5IfWpe65Oee4dy
SM+qo0/wPytMfpn++mU3FxXXkS+Q9AUZJAzTB4rHI5yDXAP3x95FuuZCxD3Rd9j5
OEWGmVZHCRm0mq7QAmQNbWk0mYO5eANoQrBffooRPATIQyH6LxcaNfMfNhwmm1Px
SwlaQMzMfQ74geExXAhOsgt3S3pvuy4Fj6EMtcPJm69SuPBHIejWE7EE3H09sDlR
CKp+3OkWCslk5+wxhBOBgL4xMrMZSPbP5OYqfn4v1KbwO7rHu1ws/sPLJalz/bgT
dhRVkhBsLqfREI1dOthts4eE2NYjHXdNQ3cIV0rB+ZGHembivJmUROQANehOhUhF
/GIYn+MJXpbCFqeT4+/XB0EkiFnxjZtgTSk7rVQ9mVSEWhVKlCr+XB2J793nJ1/C
iosqQ9khSrqF8P01UoFLgZxIqaIjWxOgYvjVssPpr9X+I8p+dFqwNJ7ptJ+BfVMZ
OuWWE3YvsiKz1FsmYp8mQMs7
-----END CERTIFICATE-----

30
tests/testdata/customcerts/root-ca.crt vendored Normal file
View File

@@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFMzCCAxugAwIBAgIUALEl344JEZxaOvwyrtO8QwLHAacwDQYJKoZIhvcNAQEL
BQAwITEfMB0GA1UEAwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgw
ODU4MjJaFw00NTA3MDMwODU4MjJaMCExHzAdBgNVBAMMFmszcy1yb290LWNhQDE3
NTE5NjUxMDAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDtESS+0V7T
0b3rN0ga9/zWThgaGIfOoKiCr2CSR4az0hjpmISAlS5pplhWrutGhydvaR/7vV7g
Grtn0ptmqidEc0XSeQTosqUv29SZ+hbCITZG05TFbMGGXmFo/1LHhJ8ZpgzUBqc7
inOXmEBbCyhOWX+fhddoJJiUIX7l2R3cbyNk7I7KFiZ1JDDnoyDWFMOJLvXwOqeT
CJQesS+2qpeXpdazgtkRQi7aOhZtXnCsJHnFbpL9VFTmWpq7vMIA9xkDva3/80S4
T2USiyN4/quUagjP8si5PIaGBVx9bJhnKHUdTrPPZWHFfxm74GUG7en4OtR9lOTM
TV49XuofNpJaJ2K5Dz+rk6gIYp2R9W+r8CN1HBXeLF5WJCvw54Lpcp0V2BA+MARq
Ij8UTUymu++rIo+WjKcHDT0qn39rhOhqJ3dXynW4UF/95KwB7e5UI+OxZ9sJ4oNP
FuP5PHrDINXsYG0DDM3KTDxA8memVSFGMdhm31DPD2GUvUPlupnd6uCepdcBc9ed
+9gTeSxF5cA6Q3gVOQa8ok9Ts0E5DwGaCIxjasyD+MIORf3Bkv0Z3lBNXicWDngP
FU5ya30GeTZQgzqhlGoXehjYfRxV28pgiR5ejl0/rmsYGfiWPdfa4Qy0LnxSKHj1
f2R1jEB55ORATo3f+k4Ez5bdjhk4KlA95QIDAQABo2MwYTAdBgNVHQ4EFgQUjC+D
R6x4XaKOOmUXnTrrBoSQbEwwHwYDVR0jBBgwFoAUjC+DR6x4XaKOOmUXnTrrBoSQ
bEwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQEL
BQADggIBACpzO1nV6/hS1xLIkkGf9RdypATYCH6RqeBJqMf/R5YEUQssLF/QBEvQ
NwockkxD1l8VwjH3Pp36QxkgthAl0D3ewK9LLkxEq1pp9VuVGxeD9siN/fxx6htG
KP1jT49pBDIdbzhJ7eR/O8xuI5dyZNLZLJkaumQkd7sEVHvDTFw55PhwUEJ3Wcxl
jAxXM1FFCKftXjWFmvVmzYZYkPj/AhB+PcVIIkFnNQYTXdUCUtsnSgj3pF1z/+g5
PttBGhsttrm93lJgddRFTEWV1lzfw1csrHkLYDYLDKDzsNQaVo71wKPmorK+xnbM
h1PQAVJeXypLTAfE636+n+Md/wSvnQuo0RzPBE24S9c9TWM2d96dvtU9kgJPbqoA
RX6jHw2ACnKp4RFJILqDCqFCOrytYPk3J/L8myW44dGpCCdSrFREqNCsyMrqu4v7
U+W9ENHT0qe7Nm0T4XNFlQstt6uGvk6ddEdbgcTfTvSv5jx2++Jfl2ynF+G67l0U
UASFHsrwThnulGQtpK2+heHkU8xQFjQOGZoQMlLiWzWg+bqo07aghAndKhKnW8s8
iRvMvdcsLjjDaPFCgeopGeQauiTd2od5aXGWCn+djzLq0fjIvezs4K70XOsStbGA
cJFFAnsnM40SbnrWyfe1EBlzuVJu0csuF77fpEU7CFz8uzd268Ho
-----END CERTIFICATE-----

51
tests/testdata/customcerts/root-ca.key vendored Normal file
View File

@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

30
tests/testdata/customcerts/root-ca.pem vendored Normal file
View File

@@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFMzCCAxugAwIBAgIUALEl344JEZxaOvwyrtO8QwLHAacwDQYJKoZIhvcNAQEL
BQAwITEfMB0GA1UEAwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgw
ODU4MjJaFw00NTA3MDMwODU4MjJaMCExHzAdBgNVBAMMFmszcy1yb290LWNhQDE3
NTE5NjUxMDAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDtESS+0V7T
0b3rN0ga9/zWThgaGIfOoKiCr2CSR4az0hjpmISAlS5pplhWrutGhydvaR/7vV7g
Grtn0ptmqidEc0XSeQTosqUv29SZ+hbCITZG05TFbMGGXmFo/1LHhJ8ZpgzUBqc7
inOXmEBbCyhOWX+fhddoJJiUIX7l2R3cbyNk7I7KFiZ1JDDnoyDWFMOJLvXwOqeT
CJQesS+2qpeXpdazgtkRQi7aOhZtXnCsJHnFbpL9VFTmWpq7vMIA9xkDva3/80S4
T2USiyN4/quUagjP8si5PIaGBVx9bJhnKHUdTrPPZWHFfxm74GUG7en4OtR9lOTM
TV49XuofNpJaJ2K5Dz+rk6gIYp2R9W+r8CN1HBXeLF5WJCvw54Lpcp0V2BA+MARq
Ij8UTUymu++rIo+WjKcHDT0qn39rhOhqJ3dXynW4UF/95KwB7e5UI+OxZ9sJ4oNP
FuP5PHrDINXsYG0DDM3KTDxA8memVSFGMdhm31DPD2GUvUPlupnd6uCepdcBc9ed
+9gTeSxF5cA6Q3gVOQa8ok9Ts0E5DwGaCIxjasyD+MIORf3Bkv0Z3lBNXicWDngP
FU5ya30GeTZQgzqhlGoXehjYfRxV28pgiR5ejl0/rmsYGfiWPdfa4Qy0LnxSKHj1
f2R1jEB55ORATo3f+k4Ez5bdjhk4KlA95QIDAQABo2MwYTAdBgNVHQ4EFgQUjC+D
R6x4XaKOOmUXnTrrBoSQbEwwHwYDVR0jBBgwFoAUjC+DR6x4XaKOOmUXnTrrBoSQ
bEwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQEL
BQADggIBACpzO1nV6/hS1xLIkkGf9RdypATYCH6RqeBJqMf/R5YEUQssLF/QBEvQ
NwockkxD1l8VwjH3Pp36QxkgthAl0D3ewK9LLkxEq1pp9VuVGxeD9siN/fxx6htG
KP1jT49pBDIdbzhJ7eR/O8xuI5dyZNLZLJkaumQkd7sEVHvDTFw55PhwUEJ3Wcxl
jAxXM1FFCKftXjWFmvVmzYZYkPj/AhB+PcVIIkFnNQYTXdUCUtsnSgj3pF1z/+g5
PttBGhsttrm93lJgddRFTEWV1lzfw1csrHkLYDYLDKDzsNQaVo71wKPmorK+xnbM
h1PQAVJeXypLTAfE636+n+Md/wSvnQuo0RzPBE24S9c9TWM2d96dvtU9kgJPbqoA
RX6jHw2ACnKp4RFJILqDCqFCOrytYPk3J/L8myW44dGpCCdSrFREqNCsyMrqu4v7
U+W9ENHT0qe7Nm0T4XNFlQstt6uGvk6ddEdbgcTfTvSv5jx2++Jfl2ynF+G67l0U
UASFHsrwThnulGQtpK2+heHkU8xQFjQOGZoQMlLiWzWg+bqo07aghAndKhKnW8s8
iRvMvdcsLjjDaPFCgeopGeQauiTd2od5aXGWCn+djzLq0fjIvezs4K70XOsStbGA
cJFFAnsnM40SbnrWyfe1EBlzuVJu0csuF77fpEU7CFz8uzd268Ho
-----END CERTIFICATE-----

View File

@@ -0,0 +1,81 @@
-----BEGIN CERTIFICATE-----
MIIDZjCCAU6gAwIBAgIIXrx+TJOdkuQwDQYJKoZIhvcNAQELBQAwKTEnMCUGA1UE
AwweazNzLWludGVybWVkaWF0ZS1jYUAxNzUxOTY1MTAwMB4XDTI1MDcwODA4NTgy
NFoXDTM1MDgyNTA4NTgyNFowIzEhMB8GA1UEAwwYazNzLXNlcnZlci1jYUAxNzUx
OTY1MTAwMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdG/lRafgvaXjr1L3zpvw
+EmcN23jypiMODfge9QVU9ST6wPOMcj2cyOluWAKSNw30lVhCSvi+nS2Hn/Za1U4
aKNjMGEwHQYDVR0OBBYEFGpvp9k1WNA5fse5+UFUg+F0idhlMB8GA1UdIwQYMBaA
FJlWOM0MjJgK2OweAyu1eVn/fUi6MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
BAQDAgKkMA0GCSqGSIb3DQEBCwUAA4ICAQCuUOrRoYovbN95EERDmEqgXfUpVSTm
GGhRXAPbN7O6aVRj226+sFPuPwLcpid7/G0N5+wS2+8+DT2uO8qGF5fUKwi8URit
TyCGnesp9mrUouFmqwZoufiPJhi6ZN4SF/pT3pAzFrjRbV7+/itgQMSoFXChmJ0F
+4IzXXABAhDb7b7SCxNfO8PZDdw1b+4xqby6K4y13VYj5fy4Z0Mv4gDE5PRMa4gL
4QhBUe0YYZV8CGd9rVB8X29faxma0gjkcMdYB4eb7YNFZhDXuf0RXcmBVZxCwZLw
10i6Yfx6WOLBMq8nOmvvo/PFw+gx4yOiHmlkb06K04GwhB84w9By4VUihNxDdCmq
XzahtO7UrvXT7AskySMr2/+PFOTIzl9w6fh/BRACkYGJakDURywCYsSu/XtFfG/1
pMV6PTH0ThvIVIh2K7WEOPCPi0c9CmXTb+VRoHl1sX5USmK04pep0/l4LjE455is
KlMdVPv1e1CgShIERNqBINcjWyyHY7PaeNGesXE1oB5+uNYcwX/Lpn/HV5L0sjhg
9a6UsrTw5wLMxO1+eUB43MFtHg6nXvJ2bQIjMUZEasErMw3NrBdmEWapSLEzYHli
v57H5KwV1kIdyz3KbI5kps98PZHEMg1LUNTkwUMeYduPJRftPHm8bEJRfVZxHkQl
vHba/vaD+ni4uw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFLzCCAxegAwIBAgIIXrx+TJOdkuIwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UE
AwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgwODU4MjNaFw0zNTA4
MjUwODU4MjNaMCkxJzAlBgNVBAMMHmszcy1pbnRlcm1lZGlhdGUtY2FAMTc1MTk2
NTEwMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfxJHxlMq/Ul+7X
avcxrg6x8joXUn0T4TbaYiQJVRK0z8j42yDh1uJSQ82SkCB1ltkF2xHzQ65iqPx9
n6uluTP/fEoGOiGxfZfIqk+H+mPbumJPd7n3hmtqPwPmjhYCPZpLadT60rjNalkM
4hUX2O0PwXtvejODUaLgF9YLUJbIdoZvkzKNcv2bTg9gruW0AoAzEqAKLYRDh58N
XQMync3OQnnAMzUyPBBukhM7P2tysufV0HJg/ZcsgLek8hpuBQ2T1QVUrZFAgOXh
ZCcrK5OGKcjQh5bo1vcbIRr4DtfHT/Jl5RhA6q5IqTAiS/dQVAhNYs0lDHgF69kU
gI2iHqsv2awuW3k9Q+i5q9vMlo/h9wxpj87cbfxLpBkS2o/h+6zB1DdI6U1WRo/Q
pFp3vzsdtr/G8WEFxwL1OMDewjA+EsjhSjI0BBrm7CC2uJkNRM3v97r9RGNzBCYL
Qn3IxqqzVjOOEhJzQc3G8FKRJj1zPAkURvTus4s9c7vdMOp1sVd78b9ObXFa0TDF
DPe9ZQu5YGEvGGibKjp5cFwJ2M2pwjv53ZUDS4sxqqdXRBmVxcCkUtrwRL35PIpb
Tje1UZP8RJ66iXnXUPco2BKyd9NYyiaUAW4gZz5WROzfgPdnI/ArGc5RThk+O5sg
cb62eU/nADPGsG8t+VEUXfJjP19pAgMBAAGjYzBhMB0GA1UdDgQWBBSZVjjNDIyY
CtjsHgMrtXlZ/31IujAfBgNVHSMEGDAWgBSML4NHrHhdoo46ZRedOusGhJBsTDAP
BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwICpDANBgkqhkiG9w0BAQsFAAOC
AgEAxgdjETEkUB7G2g3cFz6Jb8TznrZXprVk9G1p1UNuMAAEe2NaiGI0BvivJNoQ
6DNpngB3x6l7u5hMOJY/72wzQRDXg05m5T8/vBfTcz/HcgoKU82hgYDxQiGA0I5e
5czfEhQu95uPT7T26m5pvWA38Tf6WbXCB7c0/FT8II8w1ptJlZrSKRW33+j1tb2r
t0/8RoMaAUS1MP6+12juG7qcuEx0rDVeKx33pa20NjsAtZeTAsXjugJkmUkkd/PC
cKbawQB9meqtWPfGzwmUu1qz6SQeWtOWFrOBSeTzx0HTeimSAiHVSaXGd7ms3orx
KsKUoPUbXi9rVIDVxCe5XwAKmcHMz8DGHfxJ6sodol25pYbHxKy/swgAzQdwtGF9
HWJAm6/3YSjtmD6+t89/yYzvxv+aMNDXVMLpDFb+7/ESsSl4757WjvvFoz0HxcwD
4qfmV2z+EaLM44P3QaJDD599/Qwt+TFHSQRfD/MqMH6A+9vZhZGWeGgFFmu82kzH
xKJas/jI+t+V+2TbfagUYlsinZ6UmLcju99myl6wq6nJu8X5b8Uhpv5/8kVniqXE
lWtFpMBmnE0oq0U+KR3OfnovSYdYTc7uWpaJlqMamsE5UVVBrlSyUe9J9EQzYYea
Ufoq67KnJInMobbQ4aonz7EQZW6WIZpqASuVGfT5heSKHDc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFMzCCAxugAwIBAgIUALEl344JEZxaOvwyrtO8QwLHAacwDQYJKoZIhvcNAQEL
BQAwITEfMB0GA1UEAwwWazNzLXJvb3QtY2FAMTc1MTk2NTEwMDAeFw0yNTA3MDgw
ODU4MjJaFw00NTA3MDMwODU4MjJaMCExHzAdBgNVBAMMFmszcy1yb290LWNhQDE3
NTE5NjUxMDAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDtESS+0V7T
0b3rN0ga9/zWThgaGIfOoKiCr2CSR4az0hjpmISAlS5pplhWrutGhydvaR/7vV7g
Grtn0ptmqidEc0XSeQTosqUv29SZ+hbCITZG05TFbMGGXmFo/1LHhJ8ZpgzUBqc7
inOXmEBbCyhOWX+fhddoJJiUIX7l2R3cbyNk7I7KFiZ1JDDnoyDWFMOJLvXwOqeT
CJQesS+2qpeXpdazgtkRQi7aOhZtXnCsJHnFbpL9VFTmWpq7vMIA9xkDva3/80S4
T2USiyN4/quUagjP8si5PIaGBVx9bJhnKHUdTrPPZWHFfxm74GUG7en4OtR9lOTM
TV49XuofNpJaJ2K5Dz+rk6gIYp2R9W+r8CN1HBXeLF5WJCvw54Lpcp0V2BA+MARq
Ij8UTUymu++rIo+WjKcHDT0qn39rhOhqJ3dXynW4UF/95KwB7e5UI+OxZ9sJ4oNP
FuP5PHrDINXsYG0DDM3KTDxA8memVSFGMdhm31DPD2GUvUPlupnd6uCepdcBc9ed
+9gTeSxF5cA6Q3gVOQa8ok9Ts0E5DwGaCIxjasyD+MIORf3Bkv0Z3lBNXicWDngP
FU5ya30GeTZQgzqhlGoXehjYfRxV28pgiR5ejl0/rmsYGfiWPdfa4Qy0LnxSKHj1
f2R1jEB55ORATo3f+k4Ez5bdjhk4KlA95QIDAQABo2MwYTAdBgNVHQ4EFgQUjC+D
R6x4XaKOOmUXnTrrBoSQbEwwHwYDVR0jBBgwFoAUjC+DR6x4XaKOOmUXnTrrBoSQ
bEwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAqQwDQYJKoZIhvcNAQEL
BQADggIBACpzO1nV6/hS1xLIkkGf9RdypATYCH6RqeBJqMf/R5YEUQssLF/QBEvQ
NwockkxD1l8VwjH3Pp36QxkgthAl0D3ewK9LLkxEq1pp9VuVGxeD9siN/fxx6htG
KP1jT49pBDIdbzhJ7eR/O8xuI5dyZNLZLJkaumQkd7sEVHvDTFw55PhwUEJ3Wcxl
jAxXM1FFCKftXjWFmvVmzYZYkPj/AhB+PcVIIkFnNQYTXdUCUtsnSgj3pF1z/+g5
PttBGhsttrm93lJgddRFTEWV1lzfw1csrHkLYDYLDKDzsNQaVo71wKPmorK+xnbM
h1PQAVJeXypLTAfE636+n+Md/wSvnQuo0RzPBE24S9c9TWM2d96dvtU9kgJPbqoA
RX6jHw2ACnKp4RFJILqDCqFCOrytYPk3J/L8myW44dGpCCdSrFREqNCsyMrqu4v7
U+W9ENHT0qe7Nm0T4XNFlQstt6uGvk6ddEdbgcTfTvSv5jx2++Jfl2ynF+G67l0U
UASFHsrwThnulGQtpK2+heHkU8xQFjQOGZoQMlLiWzWg+bqo07aghAndKhKnW8s8
iRvMvdcsLjjDaPFCgeopGeQauiTd2od5aXGWCn+djzLq0fjIvezs4K70XOsStbGA
cJFFAnsnM40SbnrWyfe1EBlzuVJu0csuF77fpEU7CFz8uzd268Ho
-----END CERTIFICATE-----

View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIAQ2EsMn+Dy0Eh88MFflIeXd7Bde3z4Z1bm2KhiXu5p4oAoGCCqGSM49
AwEHoUQDQgAEdG/lRafgvaXjr1L3zpvw+EmcN23jypiMODfge9QVU9ST6wPOMcj2
cyOluWAKSNw30lVhCSvi+nS2Hn/Za1U4aA==
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDZjCCAU6gAwIBAgIIXrx+TJOdkuQwDQYJKoZIhvcNAQELBQAwKTEnMCUGA1UE
AwweazNzLWludGVybWVkaWF0ZS1jYUAxNzUxOTY1MTAwMB4XDTI1MDcwODA4NTgy
NFoXDTM1MDgyNTA4NTgyNFowIzEhMB8GA1UEAwwYazNzLXNlcnZlci1jYUAxNzUx
OTY1MTAwMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdG/lRafgvaXjr1L3zpvw
+EmcN23jypiMODfge9QVU9ST6wPOMcj2cyOluWAKSNw30lVhCSvi+nS2Hn/Za1U4
aKNjMGEwHQYDVR0OBBYEFGpvp9k1WNA5fse5+UFUg+F0idhlMB8GA1UdIwQYMBaA
FJlWOM0MjJgK2OweAyu1eVn/fUi6MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
BAQDAgKkMA0GCSqGSIb3DQEBCwUAA4ICAQCuUOrRoYovbN95EERDmEqgXfUpVSTm
GGhRXAPbN7O6aVRj226+sFPuPwLcpid7/G0N5+wS2+8+DT2uO8qGF5fUKwi8URit
TyCGnesp9mrUouFmqwZoufiPJhi6ZN4SF/pT3pAzFrjRbV7+/itgQMSoFXChmJ0F
+4IzXXABAhDb7b7SCxNfO8PZDdw1b+4xqby6K4y13VYj5fy4Z0Mv4gDE5PRMa4gL
4QhBUe0YYZV8CGd9rVB8X29faxma0gjkcMdYB4eb7YNFZhDXuf0RXcmBVZxCwZLw
10i6Yfx6WOLBMq8nOmvvo/PFw+gx4yOiHmlkb06K04GwhB84w9By4VUihNxDdCmq
XzahtO7UrvXT7AskySMr2/+PFOTIzl9w6fh/BRACkYGJakDURywCYsSu/XtFfG/1
pMV6PTH0ThvIVIh2K7WEOPCPi0c9CmXTb+VRoHl1sX5USmK04pep0/l4LjE455is
KlMdVPv1e1CgShIERNqBINcjWyyHY7PaeNGesXE1oB5+uNYcwX/Lpn/HV5L0sjhg
9a6UsrTw5wLMxO1+eUB43MFtHg6nXvJ2bQIjMUZEasErMw3NrBdmEWapSLEzYHli
v57H5KwV1kIdyz3KbI5kps98PZHEMg1LUNTkwUMeYduPJRftPHm8bEJRfVZxHkQl
vHba/vaD+ni4uw==
-----END CERTIFICATE-----

28
tests/testdata/customcerts/service.key vendored Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAneZv1/R43ZliQuH36SsvYsE8e1fIRhpov/wRji+QKJl3BWsL
OSZ+0dt+XxiJ+fVxYXKK2xAzx4gXLQqFVwd7kxB1TDueQk3JuAhJqACRaz4UNdvy
xh+h4yTRcDTdrXRP63IbaUEW7/i3Gnyq8KpZi45DmtYxop8m5XiQhped8TTF+0pt
rGYsvdpesYYfQVg0mnBpbsen2tDytHgwAxWVXBbvAPb24Q8ZyG3APTb4NvtgrIl5
OH00SbGtL/dXE/lafQcqf90TskO9bDe/IOdJxdzrzFUwZX5ycehGB83c08luCJdP
BCumdXspfEOHk3eNbf0CcmPJm9aVC27BCLcjpwIDAQABAoIBABUDoArrnFJRoYQp
MqczeiD4eqYnrp210g8K6wMzTUo58l8kOeAnQWWIgq8BQwujIK3JYrV42ItLj1oN
NmW4tzeBTzsQDCXi2F/HqpXTTYcqQeJRHWREvXTPZ5g5UO9OtXwuOXuuj/Dr9uJt
iQpygWxTSKgIrZ5o8/JCM2nWL8zz9XtG1ikFCF2r9gBdj+/1qXj9gdY/82odkKcl
WJPoUEh6eVA8juQVTWaoXMAWtQwyrKgpw7etH2kdVFYKR11HpLNo/qLU68r+SyJP
88luXIWoBxCbf39qCJ5VUeRo7WUYYeNpa9fnFDve6kaIyBBrBoNbSBJDJ8vltpO5
y94tPqECgYEA0mekJrVl6lXX+XDhE9vIX9TGOF5uFxzgFYt70Yd5oOCumNNT23aT
WL+jOKmVa0Z0sDRNydvJL/sl6cLjWFuoZarqiLyAHKbdROnrbrZ6m0BxKVQvYcpD
kcFj8pY4EsF0M/RpdwYe73pm/SfHAPIY3gct9h9TR5LYQCzlUF4b/D8CgYEAwB4P
T9VFXq4XEXmZPItgtcIdKjPt+Wfp2xWsP6+m3jXw00Bs81y9zx/AKB0gm3ibF7O+
pykFSZGA3GSbYS0poGBMHtzLToNiiLFnbn1DeWUtZZV7c0w7DYb1JROyQ/7KqTU/
pv72OlQJmjyQSnvx0vbAn8wwjr4anK2vjLoSHpkCgYEAub+Xkji4dY09ctAtVDvG
hJuyNtdet3bdeQe/0rWYMefJG9ANCwV+hW4BaaeE6sSzhU9XkSpATeSZjupnjHy2
iLLABODs9N53HzynhQEB8oeMn2Dbx6gpyMaDNwlZDW3N6YQPi21S6DYWL83rCLGy
NGkAMXVsLxa7ZMR92VqLuD8CgYEAjHBs+QsKnt/cdSXS4vNwSu4Pq94yRHO1/DWn
qRaagS4lUghynKRbDKJFMg243G4Z0gXPhRrzhogbDwFspGkDWP2MJ7N323kn+ozU
82wWexN/UBcqG2rKcGULp4Lyeco0E+WdFlKjZJgyPNGxGQHqETHYNfhqNq65fXdq
MRGEVWECgYANGkM0NzMQW6yLCzOoxcXOslIjDgdtUqHKqrpMXyDSPbZt34vXnth4
n+Oa8hvozl1C0/EAg486vsbVHZSUlKfoC9KFmDqH933bM7vO6F00mBzepn+LDTwr
rouXecdTdV5Bia55V/Iecpe3pg6xCKkgocep2iRIOLX/T3aL8Elcgg==
-----END RSA PRIVATE KEY-----

View File

@@ -1,6 +1,7 @@
package k3k_test
import (
"bytes"
"context"
"fmt"
"io"
@@ -21,9 +22,12 @@ import (
"helm.sh/helm/v3/pkg/chart/loader"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/remotecommand"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
)
@@ -36,6 +40,7 @@ func TestTests(t *testing.T) {
var (
k3sContainer *k3s.K3sContainer
hostIP string
restcfg *rest.Config
k8s *kubernetes.Clientset
k8sClient client.Client
)
@@ -59,7 +64,8 @@ var _ = BeforeSuite(func() {
})
func initKubernetesClient(kubeconfig []byte) {
restcfg, err := clientcmd.RESTConfigFromKubeConfig(kubeconfig)
var err error
restcfg, err = clientcmd.RESTConfigFromKubeConfig(kubeconfig)
Expect(err).To(Not(HaveOccurred()))
k8s, err = kubernetes.NewForConfig(restcfg)
@@ -189,3 +195,76 @@ func writeLogs(filename string, logs io.ReadCloser) {
fmt.Fprintln(GinkgoWriter, "logs written to: "+filename)
}
func readFileWithinPod(ctx context.Context, client *kubernetes.Clientset, config *rest.Config, name, namespace, path string) ([]byte, error) {
command := []string{"cat", path}
output := new(bytes.Buffer)
stderr, err := exec(ctx, client, config, namespace, name, command, nil, output)
if err != nil || len(stderr) > 0 {
return nil, fmt.Errorf("faile to read the following file %s: %v", path, err)
}
return output.Bytes(), nil
}
func exec(ctx context.Context, clientset *kubernetes.Clientset, config *rest.Config, namespace, name string, command []string, stdin io.Reader, stdout io.Writer) ([]byte, error) {
req := clientset.CoreV1().RESTClient().Post().
Resource("pods").
Name(name).
Namespace(namespace).
SubResource("exec")
scheme := runtime.NewScheme()
if err := v1.AddToScheme(scheme); err != nil {
return nil, fmt.Errorf("error adding to scheme: %v", err)
}
parameterCodec := runtime.NewParameterCodec(scheme)
req.VersionedParams(&v1.PodExecOptions{
Command: command,
Stdin: stdin != nil,
Stdout: stdout != nil,
Stderr: true,
TTY: false,
}, parameterCodec)
exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
if err != nil {
return nil, fmt.Errorf("error while creating Executor: %v", err)
}
var stderr bytes.Buffer
err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{
Stdin: stdin,
Stdout: stdout,
Stderr: &stderr,
Tty: false,
})
if err != nil {
return nil, fmt.Errorf("error in Stream: %v", err)
}
return stderr.Bytes(), nil
}
func caCertSecret(name, namespace string, crt, key []byte) *v1.Secret {
return &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
TypeMeta: metav1.TypeMeta{
Kind: "Secret",
APIVersion: "v1",
},
Data: map[string][]byte{
"tls.crt": crt,
"tls.key": key,
},
}
}