Allows RSA signed trust anchors on linkerd cli (#7771) (#8868)

* Allows RSA signed trust anchors on linkerd cli (#7771)

Linkerd currently forces using an ECDSA P-256
issuer certificate along with a ECDSA trust
anchor. Still, it's still cryptographically valid
to have an ECDSA P-256 issuer certificate issued
by an RSA signed CA.

CheckCertAlgoRequirements checks if CA cert uses
ECDSA or RSA 2048/4096 signing algorithm.

Fixes #7771

Signed-off-by: Baeyens, Daniel <daniel.baeyens@gmail.com>
Co-authored-by: Alejandro Pedraza <alejandro@buoyant.io>
This commit is contained in:
Dani Baeyens 2022-08-08 15:04:24 +02:00 committed by GitHub
parent 7c74bc8322
commit 074f5e6cdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 274 additions and 17 deletions

View File

@ -250,6 +250,7 @@ jobs:
- cluster-domain
- default-policy-deny
- external
- rsa-ca
# Skipping Helm upgrade test given chart in 2.11 is backwards-incompatible
#- helm-upgrade
- multicluster

View File

@ -166,6 +166,7 @@ jobs:
- viz
- default-policy-deny
- external
- rsa-ca
# Skipping Helm upgrade test given chart in 2.11 is backwards-incompatible
#- helm-upgrade
- uninstall

View File

@ -6,7 +6,7 @@ set +e
##### Test setup helpers #####
export default_test_names=(deep viz external helm-upgrade uninstall upgrade-edge upgrade-stable default-policy-deny)
export default_test_names=(deep viz external helm-upgrade uninstall upgrade-edge upgrade-stable default-policy-deny rsa-ca)
export external_resource_test_names=(external-resources)
export all_test_names=(cluster-domain cni-calico-deep multicluster "${default_test_names[*]}" "${external_resource_test_names[*]}")
images_load_default=(proxy controller policy-controller web metrics-api tap)
@ -464,6 +464,10 @@ run_cni-calico-deep_test() {
run_test "$test_directory/deep/..." --cni
}
run_rsa-ca_test() {
run_test "$test_directory/rsa-ca/..."
}
run_external_test() {
run_test "$test_directory/external/..."
}

View File

@ -490,6 +490,7 @@ func TestValidate(t *testing.T) {
expectedError string
}{
{"valid", ""},
{"valid-with-rsa-anchor", ""},
{"expired", "failed to validate issuer credentials: not valid anymore. Expired on 1990-01-01T01:01:11Z"},
{"not-valid-yet", "failed to validate issuer credentials: not valid before: 2100-01-01T01:00:51Z"},
{"wrong-algo", "failed to validate issuer credentials: must use P-256 curve for public key, instead P-521 was used"},
@ -529,7 +530,7 @@ func TestValidate(t *testing.T) {
t.Fatalf("Expected error string\"%s\", got \"%s\"", tc.expectedError, err)
}
} else if err != nil {
t.Fatalf("Expected no error bu got \"%s\"", err)
t.Fatalf("Expected no error but got \"%s\"", err)
}
}
})

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDczCCAVugAwIBAgIQBnEaBGxW2/TyGJ0cE3hARDANBgkqhkiG9w0BAQsFADAl
MSMwIQYDVQQDExpyb290LmxpbmtlcmQuY2x1c3Rlci5sb2NhbDAeFw0yMjAyMDMw
NTQ2MzZaFw0zMjAyMDEwNTQ2MzZaMCkxJzAlBgNVBAMTHmlkZW50aXR5Lmxpbmtl
cmQuY2x1c3Rlci5sb2NhbDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAq1eW0j
d5hETb5jC5N2oZmJSNLLy1DQ0BbSmIEgoLhUmhRFjNvTm6PcqMnVykZZighF1Nhv
35JED57w7F7rTjijZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/
AgEAMB0GA1UdDgQWBBQc4E9DlG65aIumqcos/z03+C0KUDAfBgNVHSMEGDAWgBQF
L+ZbJA8ZzhZug1IYeyRqnuHhkTANBgkqhkiG9w0BAQsFAAOCAgEAyOrxL0aWmbUj
SjN7WUJOYDEy9aOYDzv3Itj7SIY9G8wg25RvmbMY5R9/LcmVDj9s2Y5ivwXnmfsE
VsYm7H4Q4H/MjkcFSI8J0iLbTtACkXgPvNx3rFaFXZ9Oe7tMXEfySE0NNXjGwa+a
kJtZ+ybpOqUIbNqjl+e3Srg1f9QznZik3hHbrBXaLEyAFOee5ijQyxFYFHS7VuhS
8b586FmGl/8a3/ES5VmGKJh3p4J3aD3MiuLvtL2phh+CdeFmGPYNz4jjb5y4QC1S
p1ZXoxYoeHJuvg6AVCqhwB+xOd8Hr03YUpZSw93tPn3WOtlYrHf8jpx/JV2CLyp3
pTviAv+tnbSVRD378dSs7ir4Q7/jI9KV5N8v1D6/q442nRMVko7zyFMJfryEY+RU
RfsCsmmgJRCCUEgGXLxQObWyX7+103BqZgFRUfbEaWuSmM8yQyOkFdg5AGMHTOOn
We4gG0hnL3hTFZJxofa7Ll1QUe3kwTWTgZdcs/Qn+ZvaZi1VQRVo0lCEOJ+k2NUo
nDHH9xik7lEv+6cRXPUuQnuO58cXn53tXOqNpA966AXyEGbglsJIzd+Qhgqgz0T5
9Ag+VdWoDqE5O3E3xhd2CVSHSRIEdlV6z38n/0I6xlFUh3VnPijfYuNv7KYAIQkN
wstaHKuqI8yy2STQKeVbw+8pCX6VhS0=
-----END CERTIFICATE-----

View File

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIBEi2tPdN7b8F4lLkq4X6f0EWm2NuJoOKMM0vHJD792NoAoGCCqGSM49
AwEHoUQDQgAECrV5bSN3mERNvmMLk3ahmYlI0svLUNDQFtKYgSCguFSaFEWM29Ob
o9yoydXKRlmKCEXU2G/fkkQPnvDsXutOOA==
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFGTCCAwGgAwIBAgIQYvKHmkN454rA18Vg9l8TrDANBgkqhkiG9w0BAQsFADAl
MSMwIQYDVQQDExpyb290LmxpbmtlcmQuY2x1c3Rlci5sb2NhbDAeFw0yMjAyMDMw
NTQ1NTVaFw0zMjAyMDEwNTQ1NTNaMCUxIzAhBgNVBAMTGnJvb3QubGlua2VyZC5j
bHVzdGVyLmxvY2FsMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzbli
L5U1YpclMWjzK1wPQHK8E5RJT0x7yn09e8o/GaG+xo+PQBNe8f26DQQi75N6wpZD
oyDcnfOjPE4ptnB8DU9desDL+KJb1KhUoafqtnc7iXp0fqUIfe/CyLZ7Ve/5yM9C
RIFPNkLMV4WSXFbHr2xWFPtl78qovei2Ja4AJMkhFEemAxZspBPR2LL274zXBpsP
sYJl/ZA61RK5WvFF83cMPeM6fc1SzQIYPw3ptRf+eprsZRiX/51/QdGfkxBa7iJB
E5nCUYsCLhADlSdfljUqD6Jj5luUeYXJJ+UL92NBp/whA1rKXbhQQDs2yXZQyRat
dVNoSCUCGtsQn4f8mgRIPD3wGIB8hJtYBfigfvOit6KkquDKT3SUSA7HDgfJ14dA
L9ID5o1Jvdd6zhmzKTa5Uz9PgeDDk6+P0Ac2xssoVKJ5lSDbcEzn6u5RbQSUOuVX
ULYoYXO5i4FM3C1sO9PqYCpMR1YZTFL8qWk5Be5BNH3XwAg84rKmjzgxGWNjk1c/
k5MYy2AZmNQsQS0Zcxcy2O4BovZlc6eJ1rIdk7norWh5Q6DhABzJswdRiK/E+5UQ
5WuwAUFI0D8+/34lHecB+TLPoSID8Zy5FdBFL3qJz6JNPsID3PyJyyrjqcNcemUE
LyOX0RzcUCYlifeqHigd7frOLS98rybv4u9VpjECAwEAAaNFMEMwDgYDVR0PAQH/
BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFAUv5lskDxnOFm6D
Uhh7JGqe4eGRMA0GCSqGSIb3DQEBCwUAA4ICAQDJW/5E4euxYMOvt4KDwVCLlLt7
2Wt3u7Kq1rp0qssT47vdU9FtuYXWLI19smGI4KTg4D8r8gMLg6mbi1otZkyrSNLf
wIja9Aag1KCqk1OfgHLcdyfXLEADWvv3AuoFuBh/RgiciLII6ieOxG/g8j80EC7I
2PsxDaAKxrLOg5ZFZf8TSnXyZnENn++tAhb5tm0LqTnRKD0og2nZ7z7IeuYaJGJC
9q0+LZW5C5PhFsmBKKp4xQ96OsjPLQnyoEKMehpvwv3t/WFh5f5XSVNI3gcLoyNj
ZctHl6SUFJGY1L0uJDeWNrPaGyCpaClLVNeyZanjqV9A/jNC2cdtd02VGFZBLlr6
7j7Aeioe26fJT0Tr6Ynu/eikuL1TEmgUwcHKwkIyUXV1qPTN4JDNnupmMAu9T7Z0
21YpgYu64TysVRKrY7Zu4D4rDzol3Y46yvhFZGY+7KEBL+0TPq2ll9QRBPp/Rbzc
tcN9RSep/KJZlW0d7jgrPhg/pvAHuvq/FZlhMiPqQD5BGSyxbiTcyXtI7j5kDgvU
2WJfkgRRr9RfbpSlX7o1U4Y2UKxLXwmFnXkPAV8n+HLk7/bcdUVXaXgVsP6RVXgw
++9zFJi9fJj3ZnKQH/U6MIba6cn3oBMXQOTQs0BdN/JTh7Bt+knwqcdOvKT4wBbw
mcB/6uAtyaBhb8h/xg==
-----END CERTIFICATE-----

View File

@ -944,7 +944,7 @@ func (hc *HealthChecker) allCategories() []*Category {
check: func(context.Context) error {
var invalidAnchors []string
for _, anchor := range hc.trustAnchors {
if err := issuercerts.CheckCertAlgoRequirements(anchor); err != nil {
if err := issuercerts.CheckTrustAnchorAlgoRequirements(anchor); err != nil {
invalidAnchors = append(invalidAnchors, fmt.Sprintf("* %v %s %s", anchor.SerialNumber, anchor.Subject.CommonName, err))
}
}
@ -994,7 +994,7 @@ func (hc *HealthChecker) allCategories() []*Category {
hintAnchor: "l5d-identity-issuer-cert-uses-supported-crypto",
fatal: true,
check: func(context.Context) error {
if err := issuercerts.CheckCertAlgoRequirements(hc.issuerCert.Certificate); err != nil {
if err := issuercerts.CheckIssuerCertAlgoRequirements(hc.issuerCert.Certificate); err != nil {
return fmt.Errorf("issuer certificate %w", err)
}
return nil

View File

@ -3,6 +3,7 @@ package issuercerts
import (
"context"
"crypto/ecdsa"
"crypto/rsa"
"crypto/x509"
"fmt"
"io/ioutil"
@ -133,25 +134,71 @@ func CheckExpiringSoon(cert *x509.Certificate) error {
return nil
}
// CheckCertAlgoRequirements ensures the certificate respects with the constraints
// we have posed on the public key and signature algorithms
func CheckCertAlgoRequirements(cert *x509.Certificate) error {
// CheckIssuerCertAlgoRequirements ensures the certificate respects with the constraints
// we have posed on the public key and signature algorithms. Issuer certificates can only
// be signed by an ECDSA certificate.
func CheckIssuerCertAlgoRequirements(cert *x509.Certificate) error {
if cert.PublicKeyAlgorithm == x509.ECDSA {
// this is a safe cast here as we know we are using ECDSA
k, ok := cert.PublicKey.(*ecdsa.PublicKey)
if !ok {
return fmt.Errorf("expected ecdsa.PublicKey but got something %v", cert.PublicKey)
}
if k.Params().BitSize != 256 {
return fmt.Errorf("must use P-256 curve for public key, instead P-%d was used", k.Params().BitSize)
err := checkECDSACertRequirements(cert)
if err != nil {
return err
}
} else {
return fmt.Errorf("must use ECDSA for public key algorithm, instead %s was used", cert.PublicKeyAlgorithm)
return fmt.Errorf("issuer certificate must use ECDSA for public key algorithm, instead %s was used", cert.PublicKeyAlgorithm)
}
if cert.SignatureAlgorithm != x509.ECDSAWithSHA256 {
return nil
}
// CheckTrustAnchorAlgoRequirements ensures the certificate respects with the constraints
// we have posed on the public key and signature algorithms. Trust anchors can be signed by
// an ECDSA or RSA certificate.
func CheckTrustAnchorAlgoRequirements(cert *x509.Certificate) error {
if cert.PublicKeyAlgorithm == x509.ECDSA {
err := checkECDSACertRequirements(cert)
if err != nil {
return err
}
} else if cert.PublicKeyAlgorithm == x509.RSA {
err := checkRSACertRequirements(cert)
if err != nil {
return err
}
} else {
return fmt.Errorf("trust anchor must use ECDSA or RSA for public key algorithm, instead %s was used", cert.PublicKeyAlgorithm)
}
return nil
}
func checkECDSACertRequirements(cert *x509.Certificate) error {
k, ok := cert.PublicKey.(*ecdsa.PublicKey)
if !ok {
return fmt.Errorf("expected ecdsa.PublicKey but got something %v", cert.PublicKey)
}
if k.Params().BitSize != 256 {
return fmt.Errorf("must use P-256 curve for public key, instead P-%d was used", k.Params().BitSize)
}
if cert.SignatureAlgorithm != x509.ECDSAWithSHA256 &&
cert.SignatureAlgorithm != x509.SHA256WithRSA {
return fmt.Errorf("must be signed by an ECDSA P-256 key, instead %s was used", cert.SignatureAlgorithm)
}
return nil
}
func checkRSACertRequirements(cert *x509.Certificate) error {
k, ok := cert.PublicKey.(*rsa.PublicKey)
if !ok {
return fmt.Errorf("expected rsa.PublicKey but got something %v", cert.PublicKey)
}
if k.N.BitLen() != 2048 && k.N.BitLen() != 4096 {
return fmt.Errorf("RSA must use at least 2084 bit public key, instead %d bit public key was used", k.N.BitLen())
}
if cert.SignatureAlgorithm != x509.SHA256WithRSA {
return fmt.Errorf("must be signed by an RSA 2048/4096 bit key, instead %s was used", cert.SignatureAlgorithm)
}
return nil
}
@ -168,7 +215,7 @@ func (ic *IssuerCertData) VerifyAndBuildCreds() (*tls.Cred, error) {
}
// we check the algo requirements of the issuer cert
if err := CheckCertAlgoRequirements(creds.Certificate); err != nil {
if err := CheckIssuerCertAlgoRequirements(creds.Certificate); err != nil {
return nil, err
}

View File

@ -0,0 +1,80 @@
package rsaca
import (
"context"
"fmt"
"os"
"testing"
"github.com/linkerd/linkerd2/testutil"
)
//////////////////////
/// TEST SETUP ///
//////////////////////
var (
TestHelper *testutil.TestHelper
)
func TestMain(m *testing.M) {
TestHelper = testutil.NewTestHelper()
os.Exit(m.Run())
}
//////////////////////
/// TEST EXECUTION ///
//////////////////////
func TestRsaCa(t *testing.T) {
err := TestHelper.CreateControlPlaneNamespaceIfNotExists(context.Background(), TestHelper.GetLinkerdNamespace())
if err != nil {
testutil.AnnotatedFatalf(t, fmt.Sprintf("failed to create %s namespace", TestHelper.GetLinkerdNamespace()),
"failed to create %s namespace: %s", TestHelper.GetLinkerdNamespace(), err)
}
// Install CRDs
cmd := []string{
"install",
"--crds",
"--controller-log-level", "debug",
"--set", fmt.Sprintf("proxy.image.version=%s", TestHelper.GetVersion()),
"--set", "heartbeatSchedule=1 2 3 4 5",
}
// Pipe cmd & args to `linkerd`
out, err := TestHelper.LinkerdRun(cmd...)
if err != nil {
testutil.AnnotatedFatal(t, "'linkerd install --crds' command failed", err)
}
out, err = TestHelper.KubectlApplyWithArgs(out)
if err != nil {
testutil.AnnotatedFatalf(t, "'kubectl apply' command failed",
"'kubectl apply' command failed\n%s", out)
}
// Install control-plane with a RSA CA which has issued an ECDSA issuer certificate
cmd = []string{
"install",
"--controller-log-level", "debug",
"--set", fmt.Sprintf("proxy.image.version=%s", TestHelper.GetVersion()),
"--identity-trust-anchors-file", "testdata/ca.crt",
"--identity-issuer-certificate-file", "testdata/issuer.crt",
"--identity-issuer-key-file", "testdata/issuer.key",
}
// Pipe cmd & args to `linkerd`
out, err = TestHelper.LinkerdRun(cmd...)
if err != nil {
testutil.AnnotatedFatal(t, "'linkerd install' command failed", err)
}
out, err = TestHelper.KubectlApplyWithArgs(out)
if err != nil {
testutil.AnnotatedFatalf(t, "'kubectl apply' command failed",
"'kubectl apply' command failed\n%s", out)
}
TestHelper.WaitRollout(t, testutil.LinkerdDeployReplicasEdge)
}

19
test/integration/rsa-ca/testdata/ca.crt vendored Normal file
View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDGTCCAgGgAwIBAgIQWo14Dx0kQlRe11eECx1kLDANBgkqhkiG9w0BAQsFADAl
MSMwIQYDVQQDExpyb290LmxpbmtlcmQuY2x1c3Rlci5sb2NhbDAeFw0yMjA3MTIy
MjM4NDhaFw0zMjA3MDkyMjM4NDhaMCUxIzAhBgNVBAMTGnJvb3QubGlua2VyZC5j
bHVzdGVyLmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1cNW
64sk7nRqF5IZOv/FTzl1PE+4v09pbcIN/21NbEcd3aBPwlbMJHuUgAuxvw5Kq/g2
iIIJTb9X1ohy19eiO32ZfinRKJYIL3vf79zKepANvvlWxR+u/H77KajVPj3mpql2
BVzMWlmThIJBzc7Huch/hjhP+/hQ/7mE1G+dnxwGlMhsb4EvxRZzJnIXP0u0/Lpz
cK0dQ6iKX/l46s5Y0IJibiZ8GboZTrq9TOp+cN3jFrPO29F4tnjqF9cBgG1lO4b9
/oCVPaJpIlrmqmqVKzS2S62lYxV9KvxPrUMWNW/xoej035hH74+dSJHZhn5HybxG
TsZ0ZV5w2vpWse9sNwIDAQABo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/
BAgwBgEB/wIBATAdBgNVHQ4EFgQU1YCd8Jwk+twWuamPccLOjX8zwZEwDQYJKoZI
hvcNAQELBQADggEBAAFJ1u8RPyaCDzIHZm7p9p2uGzw+yvVF6JkW+4ZXzSCennlm
YaT78pj9P2ZpE1s0i8UL8Qss/FKdaknFxkeMBWJKS21OdsQVJVy0zGBhbRwYWHWq
CsxBw/THB8EHYh92tpwb5SYTFBKEsFCnxDgql5JMdFLsuWSIKl9WXFluxUJPlJB/
1NBheB1BPyHYQIPF6jl+d5DJx7WyS7Pa/rYTzdKsERM+cbtiZYWl3h84FGboXR1C
7pfsBxJGrO7+3IRFkUxKtZtkKY2ibJ0oJVgPRop610IAuwH/WdathNwQhuzdkMjB
0DHSkgBoskZlzniPcNl/wOBB+yvC9nlWRSXf2bQ=
-----END CERTIFICATE-----

27
test/integration/rsa-ca/testdata/ca.key vendored Normal file
View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA1cNW64sk7nRqF5IZOv/FTzl1PE+4v09pbcIN/21NbEcd3aBP
wlbMJHuUgAuxvw5Kq/g2iIIJTb9X1ohy19eiO32ZfinRKJYIL3vf79zKepANvvlW
xR+u/H77KajVPj3mpql2BVzMWlmThIJBzc7Huch/hjhP+/hQ/7mE1G+dnxwGlMhs
b4EvxRZzJnIXP0u0/LpzcK0dQ6iKX/l46s5Y0IJibiZ8GboZTrq9TOp+cN3jFrPO
29F4tnjqF9cBgG1lO4b9/oCVPaJpIlrmqmqVKzS2S62lYxV9KvxPrUMWNW/xoej0
35hH74+dSJHZhn5HybxGTsZ0ZV5w2vpWse9sNwIDAQABAoIBADkvNIV2h76yrd74
Wn+KBMKY4F/uA8JKAC44h34ZQ2j/7WFojW2zwpDP7n4Cot41eIxgrlX+U3bVBS6C
+hX7vY6knvc9QJLW8AGj5dhI/HGlL8gy859wRmONpKsUW1d3P8i99LCijphs9iWw
ouHnu05b8KF7VwpU93YxrvMVmNkDLRy7l5AIfDNlJuhLBqabbxWtMAmIOJE+c4B4
JnCZmzRrjRluN++O4VAJwMY138kYGGpzhD6oPWA/1q0IJDfNMS1Wl3eKkhXdORV4
93VxbCUp6j4sKj+rX/S3CtQ56gzCgxyBCINrc8ZaXdklcGkuMJOYoQ4TdgGMIaOp
WKSJXsECgYEA5ECpMiH6jjMD9uKXnFxf7AfrjUoiAQ4Zp3HPx9m2mzTuxmuALllY
uq5zZpG0aMkOgh1m5Io5ysvfnuHI6OktG6by/5dJYVGywdwQVT8qpswxn/kEV5Fe
G2E293SWd465QFKu/6D0N71/qTGzfuHpqjleSKTwuIRNQ1674tysGpkCgYEA77/B
toqAq49dn0nXV2jCsydxifGfWNCWAFM2f7OU6SZt6hY54SViWY94kH8wKAKxoJnO
Ibc25c4i+dY5xEBR+HlOIGxxS2UkSz5RY1vROcu8mRiRs4JRHa8I7cFWQp7SB3mR
2K1D4L4Ipkw0e3zxOV54NNGpSNwwJUC91bJOT08CgYEA0rhbO1whKxwv4cHpA8JI
D+hz7tlssRqqVmp8z1zP91OTyHzANonnn1ikUyHasw5CpZ6tOfneRrmWteBuEZAL
Q8cJ+Spa5Ux+Qfh+36RUJO7INY64EnuyrIZAL41jx/ZsUdTDmF2oeLkqXTH0KwQ3
Kx6RS3FyhnYlujeAL31YKakCgYBjvdIYYDyxox5fA3hcPBAsOm+o5OXXLEgLcJMO
w6Zi7QLzTTXdLhFhkyekbdWZ/6zoVLSGIFPtfTnd2LsFo4C2r7jKEnN722MjDpUL
kgpUUidvReJv3PpkMAq15yY85xgX1gLQMx03Jbgxfyiia1Nr+5pk1wjnb/tztCCG
A/1CTwKBgEXtlnAUDL23HlnBs7TzqkGuk03M+hubm83m4ZEFnnCMChWS+xl0bZ6O
lHMV/4tcMTNC/hA0agdyDWKkESTm1ve0zd7RSFOABsRtDhIWr3R7HARzf8t+VKPL
sg5lQZ+41hr4f3rg48fZz4xw66AbIfQktP4AnUH+V5zshzxqJlnn
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE-----
MIICczCCAVugAwIBAgIQHI4iWZqqY9YGKn6LnMIMqzANBgkqhkiG9w0BAQsFADAl
MSMwIQYDVQQDExpyb290LmxpbmtlcmQuY2x1c3Rlci5sb2NhbDAeFw0yMjA4MDEx
ODE5MzVaFw0zMjA3MjkxODE5MzVaMCkxJzAlBgNVBAMTHmlkZW50aXR5Lmxpbmtl
cmQuY2x1c3Rlci5sb2NhbDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABI8FK0Bc
b40+TKUIjLpr/k/AmBlp367W8xsW1TZ60TEO0OXBpGYLdNvuOh5vIOTG/Xn9OSmZ
iHXHZ7ikpeJzVNqjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/
AgEAMB0GA1UdDgQWBBSMHJIetxtiZ/yBCF9pDUOhZ+GbUjAfBgNVHSMEGDAWgBTV
gJ3wnCT63Ba5qY9xws6NfzPBkTANBgkqhkiG9w0BAQsFAAOCAQEAehCuAwQoZYek
bTvlJJICoWG99bg/bouZYpNHo3bSoLw4EmM0hTGPSIiajLv2kwnRQOWnQ/SgUvQM
w+EGFWtI7x8uRdYkX7go2hrt28Pr/aTYcKhnBoDl/4mo0341SFSG7FwpvoEqWulD
Z354tptDShoHXZAQciZDDr2cBtabszNn3aUXWuMsPXi/cSMgwErD3yalidAHVGMM
rq60AUhVgGgBED/yzbNzgaHqGbsLEDYgmn7SEWla5dalm/b+3UInm3VLucU0bAS0
LE2O6P+vqMJZTwH0d7rfQYd5FpFlLR4UrsdjKTzVPV+rP1S0reEKctM+4exqM+Yr
omqyVHdmJA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIGbPfosDdsWQD5U/2SiIP46WEc1Z8YiW0gVIpf7fKvHJoAoGCCqGSM49
AwEHoUQDQgAEjwUrQFxvjT5MpQiMumv+T8CYGWnfrtbzGxbVNnrRMQ7Q5cGkZgt0
2+46Hm8g5Mb9ef05KZmIdcdnuKSl4nNU2g==
-----END EC PRIVATE KEY-----