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