From 0150925a30e5773ac9c865e8fc337c6d6efd002c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Luk=C5=A1a?= Date: Wed, 17 Nov 2021 19:17:33 +0100 Subject: [PATCH] MAISTRA-2687 Fix spiffe certificate verification (#116) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * MAISTRA-2687 Fix spiffe certificate verification Previously, when copying the X509 store context, the code erroneously copied the output certificate chain instead of the input (untrusted) chain to the new context. As the output certificate chain is set only after you run X509_verify_cert(), this chain was always empty. Thus, the code only worked properly when the leaf certificate was signed by one of the certificates in the trust bundle (e.g. when the leaf certificate was signed directly by the root certificate). In cases involving intermediate certificates, the leaf certificate was only trusted if all the intermediate certificates were in the trust bundle. Intermediate certificates sent by the client were ignored. When copying the X509 store context, the input intermediate certificates should be retrieved by calling X509_STORE_CTX_get0_untrusted(), not X509_STORE_CTX_get0_chain(). * Add test * Fix test * Release references to certs Signed-off-by: Marko Lukša --- .../cert_validator/spiffe/spiffe_validator.cc | 5 +- .../spiffe/spiffe_validator_test.cc | 33 +++++++++ .../transport_sockets/tls/test_data/certs.sh | 6 ++ ...spiffe_san_signed_by_intermediate_cert.pem | 26 +++++++ ..._san_signed_by_intermediate_cert_chain.pem | 72 +++++++++++++++++++ ...ffe_san_signed_by_intermediate_cert_info.h | 8 +++ .../spiffe_san_signed_by_intermediate_key.pem | 27 +++++++ 7 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert.pem create mode 100644 test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert_chain.pem create mode 100644 test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert_info.h create mode 100644 test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_key.pem diff --git a/source/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator.cc b/source/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator.cc index d2a6e0ddd01e..7ac0b323f9d7 100644 --- a/source/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator.cc +++ b/source/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator.cc @@ -160,8 +160,7 @@ int SPIFFEValidator::doVerifyCertChain(X509_STORE_CTX* store_ctx, // Note that there's no api to copy crls from one store_ctx to another; the assumption is that // neither X509_V_FLAG_CRL_CHECK nor X509_V_FLAG_CRL_CHECK_ALL verify_params are not used. // Should this change, consider opening up X509_STORE_CTX struct, which is internal atm. - X509_STORE_CTX_init(verify_ctx.get(), trust_bundle, &leaf_cert, - X509_STORE_CTX_get0_chain(store_ctx)); + X509_STORE_CTX_init(verify_ctx.get(), trust_bundle, &leaf_cert, X509_STORE_CTX_get0_untrusted(store_ctx)); X509_VERIFY_PARAM* verify_params = X509_VERIFY_PARAM_new(); X509_VERIFY_PARAM_inherit(verify_params, X509_STORE_CTX_get0_param(store_ctx)); X509_STORE_CTX_set0_param(verify_ctx.get(), verify_params); @@ -298,7 +297,7 @@ class SPIFFEValidatorFactory : public CertValidatorFactory { return std::make_unique(config, stats, time_source); } - absl::string_view name() override { return "envoy.tls.cert_validator.spiffe"; } + absl::string_view name() override { return CertValidatorNames::get().SPIFFE; } }; REGISTER_FACTORY(SPIFFEValidatorFactory, CertValidatorFactory); diff --git a/test/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator_test.cc b/test/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator_test.cc index cf77bdf3737a..c11b5f552b3b 100644 --- a/test/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator_test.cc +++ b/test/extensions/transport_sockets/tls/cert_validator/spiffe/spiffe_validator_test.cc @@ -260,6 +260,39 @@ name: envoy.tls.cert_validator.spiffe EXPECT_EQ(2, stats().fail_verify_error_.value()); } +TEST_F(TestSPIFFEValidator, TestDoVerifyCertChainIntermediateCerts) { + initialize(TestEnvironment::substitute(R"EOF( +name: envoy.tls.cert_validator.spiffe +typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig + trust_domains: + - name: example.com + trust_bundle: + filename: "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/ca_cert.pem" + )EOF")); + + X509StorePtr ssl_ctx = X509_STORE_new(); + + // Chain contains workload, intermediate, and ca cert, so it should be accepted. + auto cert = readCertFromFile(TestEnvironment::substitute( + "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert.pem")); + auto intermediate_ca_cert = readCertFromFile(TestEnvironment::substitute( + "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/intermediate_ca_cert.pem")); + auto ca_cert = readCertFromFile(TestEnvironment::substitute( + "{{ test_rundir }}/test/extensions/transport_sockets/tls/test_data/ca_cert.pem")); + + STACK_OF(X509) *intermediates = sk_X509_new_null(); + sk_X509_push(intermediates, ca_cert.release()); + sk_X509_push(intermediates, intermediate_ca_cert.release()); + sk_X509_push(intermediates, cert.get()); // not necessary, but reflects real-world use-case + + X509StoreContextPtr store_ctx = X509_STORE_CTX_new(); + EXPECT_TRUE(X509_STORE_CTX_init(store_ctx.get(), ssl_ctx.get(), cert.get(), intermediates)); + EXPECT_TRUE(validator().doVerifyCertChain(store_ctx.get(), nullptr, *cert, nullptr)); + + sk_X509_pop_free(intermediates, X509_free); +} + TEST_F(TestSPIFFEValidator, TestDoVerifyCertChainMultipleTrustDomain) { initialize(TestEnvironment::substitute(R"EOF( name: envoy.tls.cert_validator.spiffe diff --git a/test/extensions/transport_sockets/tls/test_data/certs.sh b/test/extensions/transport_sockets/tls/test_data/certs.sh index 4afb702255f7..b78c35c0e452 100755 --- a/test/extensions/transport_sockets/tls/test_data/certs.sh +++ b/test/extensions/transport_sockets/tls/test_data/certs.sh @@ -273,6 +273,12 @@ generate_x509_cert spiffe_san ca generate_rsa_key non_spiffe_san generate_x509_cert non_spiffe_san ca +cp -f spiffe_san_cert.cfg spiffe_san_signed_by_intermediate_cert.cfg +generate_rsa_key spiffe_san_signed_by_intermediate +generate_x509_cert spiffe_san_signed_by_intermediate intermediate_ca +rm -f spiffe_san_signed_by_intermediate_cert.cfg +cat spiffe_san_signed_by_intermediate_cert.pem intermediate_ca_cert.pem ca_cert.pem > spiffe_san_signed_by_intermediate_cert_chain.pem + cp -f spiffe_san_cert.cfg expired_spiffe_san_cert.cfg generate_rsa_key expired_spiffe_san generate_x509_cert expired_spiffe_san ca -365 diff --git a/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert.pem b/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert.pem new file mode 100644 index 000000000000..fd91218a23c0 --- /dev/null +++ b/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEUjCCAzqgAwIBAgIUYXWgru9mpTn6Ag1U4rb+6yHMfaUwDQYJKoZIhvcNAQEL +BQAwgYMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH +DA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVu +Z2luZWVyaW5nMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTAeFw0yMTEw +MjkxMjEzNTdaFw0yMzEwMjkxMjEzNTdaMHoxCzAJBgNVBAYTAlVTMRMwEQYDVQQI +DApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARM +eWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2luZWVyaW5nMRQwEgYDVQQDDAtUZXN0IFNl +cnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANb5x7HerRCkhw7+ +UOgDaldCI/G9DMqEedvTTiSqxoOfKKKrzVop4dzrJbxfDM2Up5VADLz/1Zcc718R +S4F2dVGozU0RnUZGl+hwM97FgE+Hd+aoT6jJRIYKw6niHq2bqxppWyavfu3D0Zt6 +J3Qab+6twlDhPVZrCHmpWHchC9emJeOhiK3kyj0i95krQ7YWg9Z4vMpN1RAwLxv6 +Mkcmo1eoi45hNI+//I1ooF9k6MrSP/1i8kPmjRbxbgko+CM0qOfPpKhC8lXrO5db +1EEtguLBehmOBnnJUzWyIT8qrbiE5GL41+82NIm1Xhom9tZB+uWaZu2trjCnlY7W +jm49LUcCAwEAAaOBxTCBwjAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIF4DAdBgNV +HSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwRgYDVR0RBD8wPYIJZW52b3kuY29t +hh1zcGlmZmU6Ly9leGFtcGxlLmNvbS93b3JrbG9hZIERZW52b3lAZXhhbXBsZS5j +b20wHQYDVR0OBBYEFN5CxzxsYI1NAdO4UIurG6O1Q9XaMB8GA1UdIwQYMBaAFKbQ +dxTWui6GjBedEeOPwmCUdTCwMA0GCSqGSIb3DQEBCwUAA4IBAQCPEaiqpS6i6st8 +3a6TTjDwDomNrqY4uqot6itqTMUrQCG2p4ew9uff8aIwGut/Utrh5TxVdGmfRU/T +KE4U+5z9mq5RfCZkSQGI+i2rnKdAFEjtHoN9KmnArLgO2t6xG4pkfc+RlER8nmTP +HPt6pFKSup6DpwicV5ThQgKxii+EmS3QbfMGHV1JtlPFtEXwUS7eF+eFhdoRMmWh +fRkmdkKv3ZVGGWScGtupx2nbCtbcVZ0ThOeuvDlsnqvVQvdYS651GqakMwJvFxQ2 +dAdUKV8PNHt1C6G/EzM3sOIWp6K3kJ2J+aulkW58s00pZ53zUmCbKpZyvHs4DevU +G375NUqI +-----END CERTIFICATE----- diff --git a/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert_chain.pem b/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert_chain.pem new file mode 100644 index 000000000000..2dc51720e265 --- /dev/null +++ b/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert_chain.pem @@ -0,0 +1,72 @@ +-----BEGIN CERTIFICATE----- +MIIEUjCCAzqgAwIBAgIUYXWgru9mpTn6Ag1U4rb+6yHMfaUwDQYJKoZIhvcNAQEL +BQAwgYMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH +DA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVu +Z2luZWVyaW5nMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTAeFw0yMTEw +MjkxMjEzNTdaFw0yMzEwMjkxMjEzNTdaMHoxCzAJBgNVBAYTAlVTMRMwEQYDVQQI +DApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARM +eWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2luZWVyaW5nMRQwEgYDVQQDDAtUZXN0IFNl +cnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANb5x7HerRCkhw7+ +UOgDaldCI/G9DMqEedvTTiSqxoOfKKKrzVop4dzrJbxfDM2Up5VADLz/1Zcc718R +S4F2dVGozU0RnUZGl+hwM97FgE+Hd+aoT6jJRIYKw6niHq2bqxppWyavfu3D0Zt6 +J3Qab+6twlDhPVZrCHmpWHchC9emJeOhiK3kyj0i95krQ7YWg9Z4vMpN1RAwLxv6 +Mkcmo1eoi45hNI+//I1ooF9k6MrSP/1i8kPmjRbxbgko+CM0qOfPpKhC8lXrO5db +1EEtguLBehmOBnnJUzWyIT8qrbiE5GL41+82NIm1Xhom9tZB+uWaZu2trjCnlY7W +jm49LUcCAwEAAaOBxTCBwjAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIF4DAdBgNV +HSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwRgYDVR0RBD8wPYIJZW52b3kuY29t +hh1zcGlmZmU6Ly9leGFtcGxlLmNvbS93b3JrbG9hZIERZW52b3lAZXhhbXBsZS5j +b20wHQYDVR0OBBYEFN5CxzxsYI1NAdO4UIurG6O1Q9XaMB8GA1UdIwQYMBaAFKbQ +dxTWui6GjBedEeOPwmCUdTCwMA0GCSqGSIb3DQEBCwUAA4IBAQCPEaiqpS6i6st8 +3a6TTjDwDomNrqY4uqot6itqTMUrQCG2p4ew9uff8aIwGut/Utrh5TxVdGmfRU/T +KE4U+5z9mq5RfCZkSQGI+i2rnKdAFEjtHoN9KmnArLgO2t6xG4pkfc+RlER8nmTP +HPt6pFKSup6DpwicV5ThQgKxii+EmS3QbfMGHV1JtlPFtEXwUS7eF+eFhdoRMmWh +fRkmdkKv3ZVGGWScGtupx2nbCtbcVZ0ThOeuvDlsnqvVQvdYS651GqakMwJvFxQ2 +dAdUKV8PNHt1C6G/EzM3sOIWp6K3kJ2J+aulkW58s00pZ53zUmCbKpZyvHs4DevU +G375NUqI +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID4zCCAsugAwIBAgIJAPDlREG4TLxSMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNV +BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp +c2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2luZWVyaW5nMRAw +DgYDVQQDDAdUZXN0IENBMB4XDTIwMDgyNzE1MTA1MVoXDTIyMDgyNzE1MTA1MVow +gYMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1T +YW4gRnJhbmNpc2NvMQ0wCwYDVQQKDARMeWZ0MRkwFwYDVQQLDBBMeWZ0IEVuZ2lu +ZWVyaW5nMR0wGwYDVQQDDBRUZXN0IEludGVybWVkaWF0ZSBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKGa0pSi8MI88LdnHT8oZJVDpZ6qa9ooYP6m +3S+xIxRBOVOGEs0a1dxko5iAfWgJJRF8igT1bRQAlNsnK/lZpGOOo8txjWsTQPFD +FLUSVVn78lnXvyYlIhAMqmhIAmSK+qo02TcsncBNa/iCT9aH9SEf0a7xjiAcyfm6 +3XHScpPC0o47tICqKnkMCJvOxi4yKM0SWIxNpnoXq/ixxcipsA8QFQ4GU2r9LBSB +8+7+couSKdPDR0AvDA/t47P8pNxQHCCzvspEtX5wGMEOVVhAsh1GgwMNyYh9IbUO +TkHqR45D2ky+x6emPDPdAgqzh4xDpMR4V+hsPQ/GWdXpKLfKjdECAwEAAaNmMGQw +EgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFKbQ +dxTWui6GjBedEeOPwmCUdTCwMB8GA1UdIwQYMBaAFNPBCyPjw6jyMr5fVME/eDgT +VQPZMA0GCSqGSIb3DQEBCwUAA4IBAQBFEUnhtsWzHM/xoy/vlntkdau/TYrpLQkE +KXIeDbjtjLnMBKXu5z3epKWrSV12kEQWrkARNTuhW4+5XkZUA9gb2MPMXh2yse4u +Oy3rRhhzbXMas45IFbXqnI+xuS/99vJQrhjXGB49dbUV9P9dJ4hj2Uc27UmAx/zB +6MHKDXhpRw/R6MXPtpQpZjDTEA4QU2yuwHWOZ56QHJ/aj0QZJvSbdK6DDY7VSKEC +2yCX1d+S0lF5Hcgrhhi4Me2sKA7JQwKLDDlXMOKpcI0vMZAoKXPbA+tVBQUZICZU +/t9YW49y8KWCjXK113JDIxQOtTCV8SaLnV9+qL+3ckbih6gz76Vw +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIUb7lp5EdaTy6KCfKjvbTXaDHYMtgwDQYJKoZIhvcNAQEL +BQAwdjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsMEEx5ZnQgRW5n +aW5lZXJpbmcxEDAOBgNVBAMMB1Rlc3QgQ0EwHhcNMjAwODIwMTY1NzQ2WhcNMjIw +ODIwMTY1NzQ2WjB2MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW +MBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwETHlmdDEZMBcGA1UECwwQ +THlmdCBFbmdpbmVlcmluZzEQMA4GA1UEAwwHVGVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKmqkuzB22hUhvai26KtFtia0yfQgyBYtWx8MCxw +1XI+CeOC1JsYbEozm2ze+ytxlS+1Yr8U2Sb7D43AuVd27HeQllMT7DP5JV6mQkQG +4ms1yTz8oN4H1V6au3Gy6K8BZOf7rY+1yiJMzG2yqC3ipShD8up/RXmXQWInSv9G +U6lU7ZK+bK6IezsPEUPiFVzfxspQDMCSLSLi3jZmD4S0Uld4d6pFG21pWBSSRxI8 +d8xJkqqOAMc400V65rnaHm96uwvcjeWZGiI50HwhfTVjiztzcCblN1qt/Es7yhBs +eQFr+2b8N04zCMDLlL7grn9imW/XLiVSRvVrkXDyqIUmwRECAwEAAaNjMGEwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNPBCyPjw6jy +Mr5fVME/eDgTVQPZMB8GA1UdIwQYMBaAFNPBCyPjw6jyMr5fVME/eDgTVQPZMA0G +CSqGSIb3DQEBCwUAA4IBAQAVnbqXnnVFGz83S2tkry/Xq0wviklVWOsIn+emjV13 +h4SC4WgQWHViIwVz1XjUvpguIgMg+R1uE9cPrs0G2Pi6JkrzJB3Btre6QeRvMGhN +T4HsEdyfg2KvcNj0VhkHAFD53R0g9UZywxyVcTFwjFDE4ELUSRGcYsF3lH0AU/cP +hMLm0TBsUaPDxHUSpKqn63oAjKh2BN9r8Ecg9ii7I0nYakWtjz9W8e9CPTrVHxrl +V6/lXdvkXEEtblCnNonawqYSbd4Rqs7duk2jgVX9zjguA57/0wmxeb+dDUYvVFMp +xFQdzaxezPS7myjbpTP+TUyWhbTZDJLKxhMf9LAOV3A1 +-----END CERTIFICATE----- diff --git a/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert_info.h b/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert_info.h new file mode 100644 index 000000000000..31bf78429dda --- /dev/null +++ b/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_cert_info.h @@ -0,0 +1,8 @@ +// NOLINT(namespace-envoy) +constexpr char TEST_SPIFFE_SAN_SIGNED_BY_INTERMEDIATE_CERT_256_HASH[] = + "ebdaf34636d5c934f87218b41e892a28cb755f31c76e9908a7a774d12af81b6c"; +constexpr char TEST_SPIFFE_SAN_SIGNED_BY_INTERMEDIATE_CERT_1_HASH[] = "ed905c1fff40bb9d50a614d1fe6232ae77ca720f"; +constexpr char TEST_SPIFFE_SAN_SIGNED_BY_INTERMEDIATE_CERT_SPKI[] = "Pg5Hx7VWs6yWnvEsJo+RVag88rHkEfaNDtyWjmLxZOQ="; +constexpr char TEST_SPIFFE_SAN_SIGNED_BY_INTERMEDIATE_CERT_SERIAL[] = "6175a0aeef66a539fa020d54e2b6feeb21cc7da5"; +constexpr char TEST_SPIFFE_SAN_SIGNED_BY_INTERMEDIATE_CERT_NOT_BEFORE[] = "Oct 29 12:13:57 2021 GMT"; +constexpr char TEST_SPIFFE_SAN_SIGNED_BY_INTERMEDIATE_CERT_NOT_AFTER[] = "Oct 29 12:13:57 2023 GMT"; diff --git a/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_key.pem b/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_key.pem new file mode 100644 index 000000000000..5a20110c75c5 --- /dev/null +++ b/test/extensions/transport_sockets/tls/test_data/spiffe_san_signed_by_intermediate_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA1vnHsd6tEKSHDv5Q6ANqV0Ij8b0MyoR529NOJKrGg58ooqvN +Winh3OslvF8MzZSnlUAMvP/VlxzvXxFLgXZ1UajNTRGdRkaX6HAz3sWAT4d35qhP +qMlEhgrDqeIerZurGmlbJq9+7cPRm3ondBpv7q3CUOE9VmsIealYdyEL16Yl46GI +reTKPSL3mStDthaD1ni8yk3VEDAvG/oyRyajV6iLjmE0j7/8jWigX2ToytI//WLy +Q+aNFvFuCSj4IzSo58+kqELyVes7l1vUQS2C4sF6GY4GeclTNbIhPyqtuITkYvjX +7zY0ibVeGib21kH65Zpm7a2uMKeVjtaObj0tRwIDAQABAoIBAQCx0hcO2ESLmaxm +CJNf90NFPl6BHYGxGve5kAX5apGeWk7AkB/izvYXSSMDuBPdEXO1jy96PpyszLBs +EOBGDHhqvZhkgYd4k/gfuoANa40BO+tADkUmNqXJwqmqonIB5NwZksBlNZFmly2Q +z/BGp3+jDHPJdybHju2JxTx5/gnPrAlcxn7FGzXWOH7iVJJpVamPiHVaOFt9mZHY +6ITgLCsjMyjdNhuE20yJyUl7TCwbdP8m5W2j1prVaFe/tc2py5xUOPYFwYvjpH7K +w7kLm9C74iBoQhziI99G1ryQW0pY5var/RKEAjpPjGulGo6fFNUQjGvofPM/lZtK +PtvPClixAoGBAOuJ1yZ30bL3ysRvlfczDJULpzj8tBejJsCvxK69RWGzoKh/Kptx +ik2uI9vTo36+nSBzcXSWHlGrx5za2shjE/ivVV5uNLYCZpHOZ2vm5EtWMCBOPmZ+ +wydcOnfHUAC2uVsDx/JgNvO4uozqurP+chrS3WcTZZFRxzQWFQWkHmbDAoGBAOmm +pKdsm9FwZs5ANLkIUqJefxiEWTIk9XyT/4AUG73Xm3EnamPCkqaQqSjT2VTHpJGC +WNU3XNn+9W5ZyooBpjyPm9vUCRIwBeTKMvE11asUJw7i03V1h0Y8GVI4ytL+LlSq +ZpjhiACS/YqAwpjNKTGQwKlty5NVZ3IuH3Pjhp8tAoGBALmAywkJ7wbTr0d8VpDl +DLDKB76TD8daAGhbRj0U5fLnxM1Psh/QkUtSrf0wtqBYwWlQYneez2wlLUX0+8A8 +f/spI8QGac87HssQ01Ug+IX48FhRJ0YT6eEy+v1g5Tparqrm1G+opT7YK1xWdgrS +h81ma2cF2MVVsdzs00upESR/AoGAIhVE/4dAU5Tp6jxDdJpaM4VFVPY5bK8ngDy2 +kKBeS5sf+ameQ18mtVV015fPpCZbQz6YZsHksYgXlTlT6j3DWiI4wiB0EksfEPjN +5ZHM0V/nMqyz2/aA/SXXK79NFuotJ/yTasm7ZRoMEiAmQtPqpmhPMmfpwlw68tT3 +kZgnEyECgYEAu1E2pv47b63MA7EotEwQr5FpkOa4tc1p77/Es7/9tsoxlNKJHu5I +csezg38mrb86NFREoC/29W0Pn57dM9201Rd7LukADx4eKMROXP5n/oe4o9T19GDZ +w4BPPQ0g7IdmIoLY5v8sI0yaKT7BeOv3mJYGwEh+3FSVg6XrktxXRpE= +-----END RSA PRIVATE KEY-----