added tests
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/67f70260 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/67f70260 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/67f70260 Branch: refs/heads/master Commit: 67f70260f7062672b49f9b9b8f5d6b82915988ec Parents: c05e072 Author: Robert Dale <robd...@gmail.com> Authored: Mon Jan 23 14:27:37 2017 -0500 Committer: Robert Dale <robd...@gmail.com> Committed: Fri Jan 27 16:26:33 2017 -0500 ---------------------------------------------------------------------- .../server/GremlinServerIntegrateTest.java | 87 +++++++++++++++++++- gremlin-server/src/test/resources/client.crt | 40 +++++++++ .../src/test/resources/client.key.pk8 | 47 +++++++++++ gremlin-server/src/test/resources/server.crt | 41 +++++++++ .../src/test/resources/server.key.pk8 | 47 +++++++++++ 5 files changed, 261 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67f70260/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java index 1743e89..6e6d1ff 100644 --- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java +++ b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerIntegrateTest.java @@ -18,6 +18,7 @@ */ package org.apache.tinkerpop.gremlin.server; +import io.netty.handler.ssl.ClientAuth; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslProvider; @@ -105,7 +106,13 @@ import static org.junit.Assert.assertEquals; */ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegrationTest { - private Log4jRecordingAppender recordingAppender = null; + private static final String SERVER_KEY = "src/test/resources/server.key.pk8"; + private static final String SERVER_CRT = "src/test/resources/server.crt"; + private static final String KEY_PASS = "changeit"; + private static final String CLIENT_KEY = "src/test/resources/client.key.pk8"; + private static final String CLIENT_CRT = "src/test/resources/client.crt"; + + private Log4jRecordingAppender recordingAppender = null; private final Supplier<Graph> graphGetter = () -> server.getServerGremlinExecutor().getGraphManager().getGraphs().get("graph"); private final Configuration conf = new BaseConfiguration() {{ setProperty(Graph.GRAPH, RemoteGraph.class.getName()); @@ -165,6 +172,36 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration settings.ssl.enabled = true; settings.ssl.overrideSslContext(createServerSslContext()); break; + case "shouldEnableSslAndClientCertificateAuth": + settings.ssl = new Settings.SslSettings(); + settings.ssl.enabled = true; + settings.ssl.needClientAuth = ClientAuth.REQUIRE; + settings.ssl.keyCertChainFile = SERVER_CRT; + settings.ssl.keyFile = SERVER_KEY; + settings.ssl.keyPassword =KEY_PASS; + // Trust the client + settings.ssl.trustCertChainFile = CLIENT_CRT; + break; + case "shouldEnableSslAndClientCertificateAuthAndFailWithoutCert": + settings.ssl = new Settings.SslSettings(); + settings.ssl.enabled = true; + settings.ssl.needClientAuth = ClientAuth.REQUIRE; + settings.ssl.keyCertChainFile = SERVER_CRT; + settings.ssl.keyFile = SERVER_KEY; + settings.ssl.keyPassword =KEY_PASS; + // Trust the client + settings.ssl.trustCertChainFile = CLIENT_CRT; + break; + case "shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCert": + settings.ssl = new Settings.SslSettings(); + settings.ssl.enabled = true; + settings.ssl.needClientAuth = ClientAuth.REQUIRE; + settings.ssl.keyCertChainFile = SERVER_CRT; + settings.ssl.keyFile = SERVER_KEY; + settings.ssl.keyPassword =KEY_PASS; + // Trust ONLY the server cert + settings.ssl.trustCertChainFile = SERVER_CRT; + break; case "shouldStartWithDefaultSettings": // test with defaults exception for port because we want to keep testing off of 8182 final Settings defaultSettings = new Settings(); @@ -373,7 +410,55 @@ public class GremlinServerIntegrateTest extends AbstractGremlinServerIntegration cluster.close(); } } + + @Test + public void shouldEnableSslAndClientCertificateAuth() { + final Cluster cluster = TestClientFactory.build().enableSsl(true) + .keyCertChainFile(CLIENT_CRT).keyFile(CLIENT_KEY) + .keyPassword(KEY_PASS).trustCertificateChainFile(SERVER_CRT).create(); + final Client client = cluster.connect(); + + try { + assertEquals("test", client.submit("'test'").one().getString()); + } finally { + cluster.close(); + } + } + + @Test + public void shouldEnableSslAndClientCertificateAuthAndFailWithoutCert() { + final Cluster cluster = TestClientFactory.build().enableSsl(true).create(); + final Client client = cluster.connect(); + + try { + client.submit("'test'").one(); + fail("Should throw exception because ssl client auth is enabled on the server but client does not have a cert"); + } catch(Exception x) { + final Throwable root = ExceptionUtils.getRootCause(x); + assertThat(root, instanceOf(TimeoutException.class)); + } finally { + cluster.close(); + } + } + + @Test + public void shouldEnableSslAndClientCertificateAuthAndFailWithoutTrustedClientCert() { + final Cluster cluster = TestClientFactory.build().enableSsl(true) + .keyCertChainFile(CLIENT_CRT).keyFile(CLIENT_KEY) + .keyPassword(KEY_PASS).trustCertificateChainFile(SERVER_CRT).create(); + final Client client = cluster.connect(); + try { + client.submit("'test'").one(); + fail("Should throw exception because ssl client auth is enabled on the server but does not trust client's cert"); + } catch(Exception x) { + final Throwable root = ExceptionUtils.getRootCause(x); + assertThat(root, instanceOf(TimeoutException.class)); + } finally { + cluster.close(); + } + } + @Test public void shouldRespectHighWaterMarkSettingAndSucceed() throws Exception { // the highwatermark should get exceeded on the server and thus pause the writes, but have no problem catching http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67f70260/gremlin-server/src/test/resources/client.crt ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/resources/client.crt b/gremlin-server/src/test/resources/client.crt new file mode 100644 index 0000000..297335b --- /dev/null +++ b/gremlin-server/src/test/resources/client.crt @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +-----BEGIN CERTIFICATE----- +MIIDajCCAlICCQCG0QGj7JgLvTANBgkqhkiG9w0BAQsFADB2MQswCQYDVQQGEwJV +UzELMAkGA1UECAwCTkMxEDAOBgNVBAcMB1JhbGVpZ2gxEzARBgNVBAoMCkNsaWVu +dCBBcHAxDzANBgNVBAMMBmNsaWVudDEiMCAGCSqGSIb3DQEJARYTZ3JlbWxpbi11 +c2VyQGNsaWVudDAgFw0xNzAxMjMxODQzMjNaGA8yMTE2MTIzMDE4NDMyM1owdjEL +MAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5DMRAwDgYDVQQHDAdSYWxlaWdoMRMwEQYD +VQQKDApDbGllbnQgQXBwMQ8wDQYDVQQDDAZjbGllbnQxIjAgBgkqhkiG9w0BCQEW +E2dyZW1saW4tdXNlckBjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDU7U5tNN+0HCKZX31ZKMZwAUI7qGCpYXd05z5SKRWesNsrEeCLnu1DgYhL +j+hSi2LI+RwTF45DH8zEPIzQ6HEMzuCd2uy7bdDrXv6H/tFUx9Iw0ea5oXGX1qNa +tzjPTSmw22VXbSo+B5EG0coC5oDy9SpYb2HxeDmegI2OZL6ROFPKbCUTzyJfqTpy +1mdgnnKTVuQdtWvj/sXDAZzRqtFHwBkHezKCOC4yLNi5+pI01+0V7FbtyCqH7iPS +VS9VKsLuhPkzAkRh/x9CxaSrwicyzyB3Kyfg7kjmtdrUOrfgxdw+MMPog3JrGoLr +tfvc9LUh0ImpLPngyWhwc5iNGwmLAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAEi0 +IVUIbDuirNivJXXXT5eFUgfAx5iPjbR1XBjCuHO061d0B8itU7cidKs0y5mDoauy +vuywNBih6FAsHoYLrqI1gt65fybGxq3wlhnqdLH7GDeHw65e2PB2x+M4NtQlkPTq +dUgUtQzAo8Hc4DNR5BrvCtLjqT7Knq8QHtGLys8eoDur09894+6WeUjrgUTp88Jl +uqrZqRHvdMW7sge73cpU1dsDJW0rJqCLZ+qA2V+ZRRCQY1oHuHeK6Dkokabaq3rr +WrpxfppIPCusJx4nnIwu4d0gZwAKwabOS8lJPjV0frRkA0BuAEpMIbOwZ10Tw7ZM +2HzamAOiiks4NFDSs94= +-----END CERTIFICATE----- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67f70260/gremlin-server/src/test/resources/client.key.pk8 ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/resources/client.key.pk8 b/gremlin-server/src/test/resources/client.key.pk8 new file mode 100644 index 0000000..213cce3 --- /dev/null +++ b/gremlin-server/src/test/resources/client.key.pk8 @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIE6TAbBgkqhkiG9w0BBQMwDgQIuH3rVXHniaECAggABIIEyDzHWny/fttnN6ze +Q/iNE1z72HBg2anTK3gHdu8W3F9W6BSLhuKaUumxcxX6IfkZmxinqwUxSNrRBswr +s71EZ7QmX2eaeiWxlo6zP0I898fzqvSBWk6NhntV1SVG++/CMeIMZARs85OxcNGN +fKEXtBUf5jlo+hy9bVgQRO2M1vHzek/deOHyj1eXwEi2Oxcw1ly3o9lRayIFJFou +0olp58h8pD5qOsSfIrNG6bHBg00eP1ILE1FUPCdOfDrQEjiKKVqllCXdsUz/KjBY +0iGYMw3aT2LELnibTy0alFswGaDBRqlzGSIGrejdGTOBj7NmeiW2yOY+aUjCkdXw +ll862oItlJZO/B16EGgI+czdXZgcL5YRGVOu6loOlGxU60Y681Acjn9wdlxxOqXa +te7khLGX6qm3ceMJ2DQbMO8JS6UBsGjZqq/ictwfGxNDiTeiWmoyrQvO3qkaqsEt +iLBJdSsogzxx+hfj+xiBRorf9Gvkk6hDnzeuZl9Voak5qY7RrcmxD8ecdh3g2faO +VFtxTAxmHJakgGF7fZ7jQoxZJzzRn+rjIhATaEH1/MMME77Z+8rkE74oxFOrizDU +Eb4AMUV/xgrAtQLGpIFALL7oPk2r1exFgywL40q5/BcXCx65eliXtyoBIc5X+t90 +fTB8lA3K5mT2MXzwMyMPv2n8d8Ta2OjisRHjSue6AqNqifBuniVfSpHP9OUlsKaL +u3eN8mSuPDhlo7RGG8+B7mSqGDjORR/+BJvwgFreIyurOL22g887uPwjzPXs6lll +3VFclsrfEqNMP6kBsXlHNAxjT10WoWrF+ONPEyg9PrzTGryTRqW+ptzBqtiQrVag +/KMee3sdg6i9GN+EGc43DNJzxxlFXvT9kBvOk66tOPEE5963k3ZikjuAX7xBVOvM +AlqzHHW727fHXqYp0yabWTpr72RuUGQOqPZiMsWd6x65HL2I0WHP9PXTf1vMmnj3 +NgiN1paATl5L8S9Jt8WL8iLskVt2f+CAKJuQfamY5Fg54m/cJzNHV8nAMTTl+0EN +9vUhvn672wZd9JfB4PMtrIhYFNJElJmmdAwjFrop6goXA/UGgf3M4QNiQetFGxWP +aJ0tMSdA/ax9nGA5LU6iCwPe51ExrQJAVFw+oE3I8+J1oz1fQOl8zIgyOFwG+bJx +/Y/JyraEssZ5RLtaGgcm9vZm8Wo8a5TQCbqhoY8x7MwyF7/VpbRZ3bGEUFnWd/yF +1tCPeZ+q5HN79P3qfZzAcFAU3z3HawXDwQ3XO3Plix04Vjr+QFENeJxhL+3FXtLx +4nF+Y9Fq6I5x8YQLrPYkIyRz8xWxVBQFZTeNhWx5nYWNcDXgz/S8v3ipY+EPEj9Q +uOQWNdSJ9XOR+Ju/KSP0151guLkUwpHBCi/CFY4TgD6iFglTyLuZpW2bbim1mmDI +LSDHwrERQWNmcNznK4PIw227w6EZqUEI0jjkANhXQG6dz1VkaTIZAoEVWHhFNi8S +gSPkhsWN822QzxZQb+74JoUFBTifP50giaCd6p2HKw8U20FAPyseVIY3IsYatuLU +8VhfeBQ1GLOOy8/5mRyjL+Gjn/OfNPwps9uuOogx/jGf0JhtjAEY2WNoEEB9DkUv +AijT0ck1+DM3by4MlA== +-----END ENCRYPTED PRIVATE KEY----- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67f70260/gremlin-server/src/test/resources/server.crt ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/resources/server.crt b/gremlin-server/src/test/resources/server.crt new file mode 100644 index 0000000..b777e34 --- /dev/null +++ b/gremlin-server/src/test/resources/server.crt @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +-----BEGIN CERTIFICATE----- +MIIDrjCCApYCCQCg8hxjInTcQzANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMC +VVMxCzAJBgNVBAgMAkNBMRQwEgYDVQQHDAtTYW50YSBDbGFyYTEZMBcGA1UECgwQ +QXBhY2hlIFRpbmtlclBvcDEQMA4GA1UECwwHR3JlbWxpbjESMBAGA1UEAwwJbG9j +YWxob3N0MSQwIgYJKoZIhvcNAQkBFhVzcG1hbGxldHRlQGFwYWNoZS5vcmcwIBcN +MTcwMTIzMTg0MTEwWhgPMjExNjEyMzAxODQxMTBaMIGXMQswCQYDVQQGEwJVUzEL +MAkGA1UECAwCQ0ExFDASBgNVBAcMC1NhbnRhIENsYXJhMRkwFwYDVQQKDBBBcGFj +aGUgVGlua2VyUG9wMRAwDgYDVQQLDAdHcmVtbGluMRIwEAYDVQQDDAlsb2NhbGhv +c3QxJDAiBgkqhkiG9w0BCQEWFXNwbWFsbGV0dGVAYXBhY2hlLm9yZzCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5l+5DDrSGq1n1vYIMbb95buWlo4u5s +V8wHNmeFCuqNvGfxermHS88SSy6qvdSXISfe+kj9Jkfn1Pjx4czwcnF/q4Au3Gc6 +T9MiAKJUfb4+MwPKERacFobk6LTreKpzvXymAhhM1ktvvA7/opZ+nENDEoIJK/KS +CY9vRWeHqI1Q+Rf5Nrqw8eySq/ZhPDlppsu5sQr1ghSsuzXhpYNhq8VBMsysL2Zi +VF5DFMqg9yhBkxrqo70W/pjo4kQJ/iF/4d/3HHicSCVq3/NCkWMVg0HeOZ1eVaZ/ +D6EXv8cYwyaRmf7SldE7RtdbAU0M+Y0Lmuoi2evls0Oiqf8uxEDXeLUCAwEAATAN +BgkqhkiG9w0BAQsFAAOCAQEAJFAAUxYeUbf6tAGEKCXISted10TybPW/qCxOXEPN +TTO+xvnzksbcbzOc2X0N+yYIKtkfiuWgD9UJ4QnLSeEKmouMbkTk0ToYJj7SrviI +f+9R1IiZMiwz+n0igETkEGOK0Ql26Z4g3kc1IueSD07QOLASTvVLtEyoya7LD4S6 +jk1LnbpbHVmgHY4kmtsg6lVQ1zkqrsDQg9goh8dI5AlNCudpd8zLxzsPbm+Q2+DC +Wd4A2lKdh3rbY2LYpbVhBj9c6E0laaqgyGC7s37XfmyBp4wYlX/30p6RpCR2rcRW +SKh5NXN52Xx3WuiP42wm9ZC/de8gaODrW8n44xlEaMPJ3A== +-----END CERTIFICATE----- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/67f70260/gremlin-server/src/test/resources/server.key.pk8 ---------------------------------------------------------------------- diff --git a/gremlin-server/src/test/resources/server.key.pk8 b/gremlin-server/src/test/resources/server.key.pk8 new file mode 100644 index 0000000..9dc6720 --- /dev/null +++ b/gremlin-server/src/test/resources/server.key.pk8 @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIE6TAbBgkqhkiG9w0BBQMwDgQIJi2M3dPcx+cCAggABIIEyG/0PwTaqm3ekGkn +8daHjfcqxCpvwOku0pCCgV7AMsrsj4TvMOHOkId+xKVs4AlXV2grPfTQoMrIFFp0 +26hzpZOHEjAe9XbtzVWgphwLVeWOr5ugovyXPxdCqMBrn251y9Yg6csh5pPrsHEp +RLTZPQPvEVIhA0tRkPPag5BSlj//nH7PnXYRm4VSRg7WQS15ieHsC1xDM9zYni/b +ffU++twOGvCdvtGd/lqjJj3dPomKynb6Y4cEc73vQ6cQjeXN1W1Nil4QsDZ53H3U +KvoWuEVYDf1WDFySgHMFgePHXMMWA8ZkgS6rOrV1TDnoZIhG5BSe7aJNJQdVVMub +NAxZB4C1unIICuAtsP9IEAhevbfNGySi0jbrnun0pTD22Q95HZVycl1YWamrr1Hl +17TmHQT7zh4GLlXVI3L/FevoswbuR7misyqE3ketNpxdLcHKs82MVLCwbLzuqm60 +tpSm/jrexhNErKU28kdPzWCwruEHdrlOuMSS8N2YgSZxHIjEId8pZED8dsnPvqhe +CAEa3F68Js9sngeMvThYirpr0wOsSGmGCDrXTmQvTw+q8C+DJLWpjfpKZA4g624f +E3CUojwOaPrmaEa25eYm0oYDstY8QncG7nBAuljeXWBYfxARYcLI/bLC/M/q+UeS +gzjQgoacH4r2Y7rwEA0aeYC+9TWn5rPHPWegdc01A2e7OlYKrlu9C1aKZr//GyBM +lEVRc0u8RL+RVhmp7ftRyATDG9kJR+zDT26hewaEa5atnPKLjf+37hu7a/6GI+2X +dpWTzmvWal4eEkFuBg2ekl1lCsuuCUBDWyYrlhsWPYTOSKJ/PTuLq7HVqdGB9kEw +SavnXV5LPOaY4nAzJTdRk9DHdxSwSrjZ5rvMMD1CAbob/GA9t8aYaGcAWtTwMFs4 +sps40mmab3X0LLvTblHtmRCHWswcACbH2DC6H+0awsaZNI80GxSSutKN+2vH3N0C +6fLwP1VaYm0qPA3pI1vp9Xu5I//6Hzt3aT/R+6KhS+CH3qbJiHNzg1ywdNqgD3Pp +bJNEiDKWdLd65bvclVVyWHovWIvvEly1TWUsp4YbdrT5asL/VV82fvo4wCttOq96 +msk9OL5vQADJ32D7vnnYadiT2tpJMjNSug7JKHutJ/cJmm8qkqNwFm/BH+w2t7kh +elbG0f2P7FpPXVMCJPHhmI/+OBECqBHAAWgRRn91GqeGgY+Xy05orL2R/qeNdBbT +qmrxqm7LesPgo0IqU82quTkiBERaXMu8qUYaYPGVJIskQuWqd/aArhaFmqZhK3bz +lepJMDAaeaBT/3ULICHdhsSVAhl6iwid40ow8x1cRFoPEljZ9t6fERN1h2ptNyZT +LRJ4DUXy4RWTHl3+AVyzwcgMpxkxRTzdjguzAjceOHEMm7UNCvSVhFHVBkG6kXXw +940iYvhkRnn6HRcPbP5xeJp6GX8RoAl42giRO6OGnkhkepOuAcFKJCC2N5OgdKmq +mlVGEKndriwyzyiPN8noEJksenL1iMSA7HSnM34uCJoEetTBRuv8+721bTdz8dy0 +s/GghsYztugLjho4yivn2fcxw4gMFiSiliyrfbocJnHAubDMZwEu0fpfY+0fBi9+ +e/Odgw8aTlMUKSo+UA== +-----END ENCRYPTED PRIVATE KEY-----