Skip to content

Commit

Permalink
feat: Allow configuration of Connaisseur's TLS certificate
Browse files Browse the repository at this point in the history
This commit allows for configuration of the TLS paramters used by Connaisseur when being called on one of its endpoints. This allows configuring both publicly trusted or self-signed certificates.

Fix #225
  • Loading branch information
Starkteetje committed Dec 23, 2022
1 parent 420fb36 commit 7ef4625
Show file tree
Hide file tree
Showing 12 changed files with 247 additions and 12 deletions.
1 change: 1 addition & 0 deletions .github/workflows/cicd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ jobs:
"deployment",
"pre-config",
"other-ns",
"configured-cert",
]
services:
alerting-endpoint:
Expand Down
20 changes: 20 additions & 0 deletions connaisseur/res/config_schema.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
{
"type": "object",
"properties": {
"deployment": {
"type": "object",
"properties": {
"tls": {
"type": "object",
"properties": {
"cert": {
"type": "string"
},
"key": {
"type": "string"
}
},
"dependentRequired": {
"cert": ["key"],
"key": ["cert"]
}
}
}
},
"validators": {
"type": "array",
"items": {
Expand Down
4 changes: 2 additions & 2 deletions helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: connaisseur
description: Helm chart for Connaisseur - a Kubernetes admission controller to integrate container image signature verification and trust pinning into a cluster.
type: application
version: 1.4.4
appVersion: 2.6.5
version: 1.5.0
appVersion: 2.7.0
keywords:
- container image
- signature
Expand Down
25 changes: 23 additions & 2 deletions helm/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,27 @@ Extract Kubernetes Minor Version.
{{- end -}}


{{- define "getInstalledTLSCert" -}}
{{- define "validateTLSConfig" -}}
{{- if hasKey .Values.deployment "tls" -}}
{{- if and (not (hasKey .Values.deployment.tls "cert")) (hasKey .Values.deployment.tls "key")}}
{{ fail "Helm configuration has a 'deployment.tls' section with a 'key' attribute, but is missing the 'cert' attribute." -}}
{{- end -}}
{{- if and (not (hasKey .Values.deployment.tls "key")) (hasKey .Values.deployment.tls "cert")}}
{{ fail "Helm configuration has a 'deployment.tls' section with a 'cert' attribute, but is missing the 'key' attribute." -}}
{{- end -}}
{{- end -}}
{{- end -}}


{{- define "getInstalledEncodedTLSCert" -}}
{{- $data := (lookup "v1" "Secret" .Release.Namespace (printf "%s-tls" .Chart.Name)).data -}}
{{- if $data -}}
{{ get $data "tls.crt" }}
{{- end -}}
{{- end -}}


{{- define "getInstalledTLSKey" -}}
{{- define "getInstalledEncodedTLSKey" -}}
{{- $data := (lookup "v1" "Secret" .Release.Namespace (printf "%s-tls" .Chart.Name)).data -}}
{{- if $data -}}
{{ get $data "tls.key" }}
Expand All @@ -150,6 +162,15 @@ Extract Kubernetes Minor Version.
{{- end -}}


{{- define "getConfigChecksum" -}}
{{- if hasKey .Values.deployment "tls" -}}
{{- printf "%s\n%s" .Values.deployment.tls (include "getConfigFiles" .) | sha256sum }}
{{- else -}}
{{ include "getConfigFiles" . | sha256sum }}
{{- end -}}
{{- end -}}


{{- define "hasCosignCerts" -}}
{{- range .Values.validators -}}
{{- if and (eq .type "cosign") (hasKey . "cert") -}}
Expand Down
36 changes: 31 additions & 5 deletions helm/templates/certificate_webhook-conf.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
{{- $k8sMinor := (include "k8s-version-minor" .) -}}

# Validate that if 'tls' key is set, either both or none of 'cert' and 'key' are set
{{- include "validateTLSConfig" . -}}

# Set up certificate and private key to use for TLS communication:
# If there's a configured one in the values.yaml, use that to allow rotation
# Otherwise, if there's an existing installation re-use the previous certificate
# Otherwise, generate a new self-signed certificate
{{- $altNames := list -}}
{{- $altNames = append $altNames (printf "%s-svc" .Chart.Name) -}}
{{- $altNames = append $altNames (printf "%s-svc.%s" .Chart.Name .Release.Namespace) -}}
{{- $altNames = append $altNames (printf "%s-svc.%s.svc" .Chart.Name .Release.Namespace) -}}
{{- $altNames = append $altNames (printf "%s-svc.%s.svc.cluster.local" .Chart.Name .Release.Namespace) -}}
{{- $certs := genSelfSignedCert (printf "%s-svc.%s.svc" .Chart.Name .Release.Namespace) nil $altNames 36500 -}}
{{- $newCertificate := genSelfSignedCert (printf "%s-svc.%s.svc" .Chart.Name .Release.Namespace) nil $altNames 36500 -}}

# Default to certificate of existing installation over new self-signed certificate
{{ $encodedTLSCert := default ($newCertificate.Cert | b64enc) (include "getInstalledEncodedTLSCert" .) }}
{{ $encodedTLSKey := default ($newCertificate.Key | b64enc) (include "getInstalledEncodedTLSKey" .) }}

# If present, use the configured certificate
{{- if hasKey .Values.deployment "tls" -}}
{{- if hasKey .Values.deployment.tls "key" -}}
{{- $certByHelmConfig := buildCustomCert (.Values.deployment.tls.cert | b64enc) (.Values.deployment.tls.key | b64enc) -}}
{{- $encodedTLSCert = $certByHelmConfig.Cert | b64enc -}}
{{- $encodedTLSKey = $certByHelmConfig.Key | b64enc -}}
{{- end -}}
{{- end -}}

# For whatever reason Helm concatenates the comments with the apiVersion field below
# unless there's a comment below the Helm commands or there's no comments at all.
# As I wanted to have comments, here's this comment commenting why this comment is here.

apiVersion: v1
kind: Secret
metadata:
Expand All @@ -14,8 +40,8 @@ metadata:
{{- include "helm.labels" . | nindent 4 }}
type: Opaque
data:
tls.crt: {{ default ($certs.Cert | b64enc) (include "getInstalledTLSCert" .) }}
tls.key: {{ default ($certs.Key | b64enc) (include "getInstalledTLSKey" .) }}
tls.crt: {{ $encodedTLSCert }}
tls.key: {{ $encodedTLSKey }}
---
{{ if lt ($k8sMinor | int) 17 }}
apiVersion: admissionregistration.k8s.io/v1beta1
Expand All @@ -39,7 +65,7 @@ webhooks:
name: {{ .Chart.Name }}-svc
namespace: {{ .Release.Namespace }}
path: /mutate
caBundle: {{ default ($certs.Cert | b64enc) (include "getInstalledTLSCert" .) }}
caBundle: {{ $encodedTLSCert }}
rules: []
sideEffects: None
{{- if lt ($k8sMinor | int) 17 }}
Expand Down Expand Up @@ -69,7 +95,7 @@ webhooks:
name: {{ .Chart.Name }}-svc
namespace: {{ .Release.Namespace }}
path: /mutate
caBundle: {{ default ($certs.Cert | b64enc) (include "getInstalledTLSCert" .) }}
caBundle: {{ $encodedTLSCert }}
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["*"]
Expand Down
4 changes: 2 additions & 2 deletions helm/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
labels:
{{- include "helm.labels" . | nindent 4 }}
annotations:
checksum/config: {{ include "getConfigFiles" . | sha256sum }}
checksum/config: {{ include "getConfigChecksum" . }}
spec:
replicas: {{ .Values.deployment.replicasCount }}
selector:
Expand All @@ -19,7 +19,7 @@ spec:
app.kubernetes.io/name: {{ include "helm.name" . }}
app.kubernetes.io/instance: {{ .Chart.Name }}
annotations:
checksum/config: {{ include "getConfigFiles" . | sha256sum }}
checksum/config: {{ include "getConfigChecksum" . }}
{{- if .Values.deployment.annotations }}
{{- toYaml .Values.deployment.annotations | nindent 8 }}
{{- end }}
Expand Down
17 changes: 16 additions & 1 deletion helm/values.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# configure Connaisseur deployment
deployment:
replicasCount: 3
image: securesystemsengineering/connaisseur:v2.6.5
image: securesystemsengineering/connaisseur:v2.7.0
imagePullPolicy: IfNotPresent
# imagePullSecrets contains an optional list of Kubernetes Secrets, in Connaisseur namespace,
# that are needed to access the registry containing Connaisseur image.
Expand Down Expand Up @@ -58,6 +58,21 @@ deployment:
extraContainers: []
extraVolumes: []
extraVolumeMounts: []
# tls:
# # Public TLS certificate to be used by Connaisseur for its endpoints
# # Will override certificate of prior installation
# # Has to be used in conjunction with a private TLS key
# cert: |
# -----BEGIN CERTIFICATE-----
# ...
# -----END CERTIFICATE-----
# # Private TLS key to be used by Connaisseur for its endpoints
# # Will override key of prior installation
# # Has to be used in conjunction with a public certificate
# key: |
# -----BEGIN PRIVATE KEY-----
# ...
# -----END PRIVATE KEY-----

# configure Connaisseur service
service:
Expand Down
15 changes: 15 additions & 0 deletions tests/integration/cases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,18 @@ test_cases:
namespace: default
expected_msg: pod/pod-poff created
expected_result: null
certificate:
- id: x509u
txt: Testing unsigned image...
type: deploy
ref: securesystemsengineering/testimage:unsigned
namespace: default
expected_msg: Unable to find signed digest for image docker.io/securesystemsengineering/testimage:unsigned.
expected_result: INVALID
- id: x509s
txt: Testing signed image...
type: deploy
ref: securesystemsengineering/testimage:signed
namespace: default
expected_msg: pod/pod-x509s created
expected_result: VALID
35 changes: 35 additions & 0 deletions tests/integration/integration-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,29 @@ pre_config_int_test() {
multi_test "pre-config"
}

### CERTIFICATE INT TEST ####################################
certificate_int_test() {
multi_test "certificate"
}

### CERTIFICATE TEST ####################################
certificate_check() {
DIFF=$(diff tests/integration/tls.key <(kubectl get secrets -n connaisseur connaisseur-tls -o json | jq -r '.data."tls.key"' | base64 -d) || true)
if [[ ${DIFF} != "" ]]; then
echo "Unexpected TLS key. Should be pre-configured one."
EXIT=1
else
echo "Found expected TLS key."
fi
DIFF=$(diff tests/integration/tls.cert <(kubectl get secrets -n connaisseur connaisseur-tls -o json | jq -r '.data."tls.crt"' | base64 -d) || true)
if [[ ${DIFF} != "" ]]; then
echo "Unexpected TLS certificate. Should be pre-configured one."
EXIT=1
else
echo "Found expected TLS certificate."
fi
}

case $1 in
"regular")
update_via_env_vars
Expand Down Expand Up @@ -404,6 +427,18 @@ case $1 in
make_install
load_test
;;
"configured-cert")
echo "Testing deployment of Connaisseur using a pre-configured TLS certificate. See issue https://github.com/sse-secure-systems/connaisseur/issues/225"
update_via_env_vars
make install
certificate_int_test
# Clean up such that next test doesn't run into existing test pods
kubectl delete pods -luse="connaisseur-integration-test" -A >/dev/null
yq eval-all --inplace 'select(fileIndex == 0) * select(fileIndex == 1)' helm/values.yaml tests/integration/update_cert.yaml
make_upgrade
certificate_check
certificate_int_test
;;
*)
echo "Invalid test case. Exiting..."
exit 1
Expand Down
22 changes: 22 additions & 0 deletions tests/integration/tls.cert
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDrDCCApSgAwIBAgIQIzbIGJeH6q01hcLkeJnmajANBgkqhkiG9w0BAQsFADAq
MSgwJgYDVQQDEx9jb25uYWlzc2V1ci1zdmMuY29ubmFpc3NldXIuc3ZjMCAXDTIy
MTIxNjEzMTU0MloYDzIxMjIxMTIyMTMxNTQyWjAqMSgwJgYDVQQDEx9jb25uYWlz
c2V1ci1zdmMuY29ubmFpc3NldXIuc3ZjMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAuJO5jZXK9Pbz4fvrmulgAPJUWZkjavOvucLCE/xMmOUCha22wGMe
y2KPuGSBJNfRgzb8BBnKn+Zjjh1BKnCQ/cCZtVMbw2kVjIN/HZ6bSstBNBb8GQd4
junzBu1DBO0d/LlVUuB5348iir0qLVEkoz2W0ySkhPO4LK/ZvPQIVT3mtTUwZb9z
3ey1l3jp5dZFHkzEa+3XzJK08tanPeADoc/Vot1NOxuwIukbi6fISPzCMYsCuuVp
9Qa73iBqs/QGY2/hLQHsaxoh9BAIzi3paTOdwNH0CJEKaEL9kQhIK7voeNRzLX9K
VEcCPZ9zkMrPZVZQHLO4FXjrkYAXme6hnQIDAQABo4HLMIHIMA4GA1UdDwEB/wQE
AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIw
ADCBiAYDVR0RBIGAMH6CD2Nvbm5haXNzZXVyLXN2Y4IbY29ubmFpc3NldXItc3Zj
LmNvbm5haXNzZXVygh9jb25uYWlzc2V1ci1zdmMuY29ubmFpc3NldXIuc3Zjgi1j
b25uYWlzc2V1ci1zdmMuY29ubmFpc3NldXIuc3ZjLmNsdXN0ZXIubG9jYWwwDQYJ
KoZIhvcNAQELBQADggEBAAfxrjqiYMM88hLRDZXuUxUfxwxikgCxuL7EH77rSh9I
8hE8DzRUE0WHWzj9qPo3oI+eZHVr/EcljgrQE+waecQD41qMEf6ovBerTb6MiNRh
IUgsoNDv9Ptk1mTy+Z7/xIZvnHUOikpwFmPiS+rapB/1/Zlq8KE1eZFQj+lA7PhF
cUgY3SfkABAJGU0S7YDx6I5yX2msF7YpsgPCANk8/cWPJxVnE0b8aG1+bMLilplh
QUnXk0HU8gRMwwwnUNN/uEJYSgvnKmSeVQvSXSnZeThRqkTB2MlLY59gWwWI83Fy
TG8KSTj5wOFtVUc3DUzkEmtcB1VJ7HZGrekdw21Wl04=
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions tests/integration/tls.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAuJO5jZXK9Pbz4fvrmulgAPJUWZkjavOvucLCE/xMmOUCha22
wGMey2KPuGSBJNfRgzb8BBnKn+Zjjh1BKnCQ/cCZtVMbw2kVjIN/HZ6bSstBNBb8
GQd4junzBu1DBO0d/LlVUuB5348iir0qLVEkoz2W0ySkhPO4LK/ZvPQIVT3mtTUw
Zb9z3ey1l3jp5dZFHkzEa+3XzJK08tanPeADoc/Vot1NOxuwIukbi6fISPzCMYsC
uuVp9Qa73iBqs/QGY2/hLQHsaxoh9BAIzi3paTOdwNH0CJEKaEL9kQhIK7voeNRz
LX9KVEcCPZ9zkMrPZVZQHLO4FXjrkYAXme6hnQIDAQABAoIBAQCRND3EIbRRtDk2
bb3y12ecNweemPeg+uYiSBHwMQp9OaQbUAa2IQQn0njoAcELH/GFvWrTOwsJcfCd
62vJnFakGbGSUThFKVU3fncw8QaP94hrFy3p7tOr8mYq69pOdM+jcpWqJkgaVHtD
E/+rOOuOtDQEFQ6MPUOFfC3aFUy86SYQAbRiRFxIoznShRG/zQVOBhN/gwg2/7Jq
J5axuMdQKxc6nKgqvaz5swf1R//4PoslDuoyLQQ8JnpBANT+AUwcD0dqfGnBHmAx
COmQUJaTFZMEjfI8N5lN/qeI9RlBQ+MtjsFnL+/QEI99NK/rcJRI0ru35x7z+jab
DfYS8SIBAoGBAPW7PVW3L9v6O2yUpZAsQK733320xy2AlCvr/XllSVssfqXNjb8v
yS/OgwjuwE5BFvkl1iSLDpIjuBADDZM2aUnfB18Aqz/U18aH2/CGSZ7609I0wOAb
NicHv2TaokxxJl3Tu2aFh6vzZXw17/ngfIqgISBsYWnxJ+aGJIFy1BodAoGBAMBK
Rj7krgnM2CMSZICGaYsIS4itdLt1APdbslxKaFNvtY9b0YZUvbrjtZ1jgnW0bVLF
u+6w+5Hk8mH+TXK5TH/xW0xYPkh1HBUbHQcW7Wrr1rDJvy9V0ovW44zB/o2t6rDO
fVSVuk0cLt8YXP/yaYy/GGTy/1WhENlm/vd5gg2BAoGBAMQTof9xasj2xNABVJLU
HNEAjN67j2spfBIH/nwNbBlKScx3VrHFqZ1yBXDtQZmvqmsn29XQ99F4mvh71ysu
cZk2U6Vk3UDTz1FlOwSTws8OilLjMTwhunYuYnRRWMvyRZD80D4gMn/seYBBcblL
fVUILSa4FIr6mMIDK8H3JHOpAoGAOY4BuJF6BjTp/JVkv5N7w8GX2jEQ34sF3wPz
PuyGjXLCRUaWUD7NC0Nc+N7wDYsTrdLBjZArvF9qrSoQxGXyH9l+GjvPaKCk5yxW
Y+jY50fv2rqIHwLxIioPsfHe30lPFdy4ZrjqKmplHSGNtI46SYZpJs4U3ux2vpu1
dR1JcAECgYA1lGxwcFhmGc/IM2aQ15G0hifchlnn7WUzgxxiGOnkwGtDwSYX4hH1
IsD3/0zmXxXGNz2IcKwoeCrCuKmfiuZx/mKVuPivBJQ/s4t1SBnq/psfoigKXqlu
kOFwQLtwILzLFp/k+fpE5L1b2hOKQZfogjk38OD4PPnqOZdmkjg4wA==
-----END RSA PRIVATE KEY-----
53 changes: 53 additions & 0 deletions tests/integration/update_cert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
deployment:
tls:
cert: |
-----BEGIN CERTIFICATE-----
MIIDrDCCApSgAwIBAgIQIzbIGJeH6q01hcLkeJnmajANBgkqhkiG9w0BAQsFADAq
MSgwJgYDVQQDEx9jb25uYWlzc2V1ci1zdmMuY29ubmFpc3NldXIuc3ZjMCAXDTIy
MTIxNjEzMTU0MloYDzIxMjIxMTIyMTMxNTQyWjAqMSgwJgYDVQQDEx9jb25uYWlz
c2V1ci1zdmMuY29ubmFpc3NldXIuc3ZjMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAuJO5jZXK9Pbz4fvrmulgAPJUWZkjavOvucLCE/xMmOUCha22wGMe
y2KPuGSBJNfRgzb8BBnKn+Zjjh1BKnCQ/cCZtVMbw2kVjIN/HZ6bSstBNBb8GQd4
junzBu1DBO0d/LlVUuB5348iir0qLVEkoz2W0ySkhPO4LK/ZvPQIVT3mtTUwZb9z
3ey1l3jp5dZFHkzEa+3XzJK08tanPeADoc/Vot1NOxuwIukbi6fISPzCMYsCuuVp
9Qa73iBqs/QGY2/hLQHsaxoh9BAIzi3paTOdwNH0CJEKaEL9kQhIK7voeNRzLX9K
VEcCPZ9zkMrPZVZQHLO4FXjrkYAXme6hnQIDAQABo4HLMIHIMA4GA1UdDwEB/wQE
AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIw
ADCBiAYDVR0RBIGAMH6CD2Nvbm5haXNzZXVyLXN2Y4IbY29ubmFpc3NldXItc3Zj
LmNvbm5haXNzZXVygh9jb25uYWlzc2V1ci1zdmMuY29ubmFpc3NldXIuc3Zjgi1j
b25uYWlzc2V1ci1zdmMuY29ubmFpc3NldXIuc3ZjLmNsdXN0ZXIubG9jYWwwDQYJ
KoZIhvcNAQELBQADggEBAAfxrjqiYMM88hLRDZXuUxUfxwxikgCxuL7EH77rSh9I
8hE8DzRUE0WHWzj9qPo3oI+eZHVr/EcljgrQE+waecQD41qMEf6ovBerTb6MiNRh
IUgsoNDv9Ptk1mTy+Z7/xIZvnHUOikpwFmPiS+rapB/1/Zlq8KE1eZFQj+lA7PhF
cUgY3SfkABAJGU0S7YDx6I5yX2msF7YpsgPCANk8/cWPJxVnE0b8aG1+bMLilplh
QUnXk0HU8gRMwwwnUNN/uEJYSgvnKmSeVQvSXSnZeThRqkTB2MlLY59gWwWI83Fy
TG8KSTj5wOFtVUc3DUzkEmtcB1VJ7HZGrekdw21Wl04=
-----END CERTIFICATE-----
key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAuJO5jZXK9Pbz4fvrmulgAPJUWZkjavOvucLCE/xMmOUCha22
wGMey2KPuGSBJNfRgzb8BBnKn+Zjjh1BKnCQ/cCZtVMbw2kVjIN/HZ6bSstBNBb8
GQd4junzBu1DBO0d/LlVUuB5348iir0qLVEkoz2W0ySkhPO4LK/ZvPQIVT3mtTUw
Zb9z3ey1l3jp5dZFHkzEa+3XzJK08tanPeADoc/Vot1NOxuwIukbi6fISPzCMYsC
uuVp9Qa73iBqs/QGY2/hLQHsaxoh9BAIzi3paTOdwNH0CJEKaEL9kQhIK7voeNRz
LX9KVEcCPZ9zkMrPZVZQHLO4FXjrkYAXme6hnQIDAQABAoIBAQCRND3EIbRRtDk2
bb3y12ecNweemPeg+uYiSBHwMQp9OaQbUAa2IQQn0njoAcELH/GFvWrTOwsJcfCd
62vJnFakGbGSUThFKVU3fncw8QaP94hrFy3p7tOr8mYq69pOdM+jcpWqJkgaVHtD
E/+rOOuOtDQEFQ6MPUOFfC3aFUy86SYQAbRiRFxIoznShRG/zQVOBhN/gwg2/7Jq
J5axuMdQKxc6nKgqvaz5swf1R//4PoslDuoyLQQ8JnpBANT+AUwcD0dqfGnBHmAx
COmQUJaTFZMEjfI8N5lN/qeI9RlBQ+MtjsFnL+/QEI99NK/rcJRI0ru35x7z+jab
DfYS8SIBAoGBAPW7PVW3L9v6O2yUpZAsQK733320xy2AlCvr/XllSVssfqXNjb8v
yS/OgwjuwE5BFvkl1iSLDpIjuBADDZM2aUnfB18Aqz/U18aH2/CGSZ7609I0wOAb
NicHv2TaokxxJl3Tu2aFh6vzZXw17/ngfIqgISBsYWnxJ+aGJIFy1BodAoGBAMBK
Rj7krgnM2CMSZICGaYsIS4itdLt1APdbslxKaFNvtY9b0YZUvbrjtZ1jgnW0bVLF
u+6w+5Hk8mH+TXK5TH/xW0xYPkh1HBUbHQcW7Wrr1rDJvy9V0ovW44zB/o2t6rDO
fVSVuk0cLt8YXP/yaYy/GGTy/1WhENlm/vd5gg2BAoGBAMQTof9xasj2xNABVJLU
HNEAjN67j2spfBIH/nwNbBlKScx3VrHFqZ1yBXDtQZmvqmsn29XQ99F4mvh71ysu
cZk2U6Vk3UDTz1FlOwSTws8OilLjMTwhunYuYnRRWMvyRZD80D4gMn/seYBBcblL
fVUILSa4FIr6mMIDK8H3JHOpAoGAOY4BuJF6BjTp/JVkv5N7w8GX2jEQ34sF3wPz
PuyGjXLCRUaWUD7NC0Nc+N7wDYsTrdLBjZArvF9qrSoQxGXyH9l+GjvPaKCk5yxW
Y+jY50fv2rqIHwLxIioPsfHe30lPFdy4ZrjqKmplHSGNtI46SYZpJs4U3ux2vpu1
dR1JcAECgYA1lGxwcFhmGc/IM2aQ15G0hifchlnn7WUzgxxiGOnkwGtDwSYX4hH1
IsD3/0zmXxXGNz2IcKwoeCrCuKmfiuZx/mKVuPivBJQ/s4t1SBnq/psfoigKXqlu
kOFwQLtwILzLFp/k+fpE5L1b2hOKQZfogjk38OD4PPnqOZdmkjg4wA==
-----END RSA PRIVATE KEY-----

0 comments on commit 7ef4625

Please sign in to comment.