try {
SSLContext sc = SSLContext.getInstance("SSL");
- sc.init(null, TesterSupport.TRUST_ALL_CERTS,
+ sc.init(null, TesterSupport.getTrustManagers(),
new java.security.SecureRandom());
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
sc.getSocketFactory());
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.catalina.Context;
+import org.apache.catalina.authenticator.SSLAuthenticator;
+import org.apache.catalina.deploy.LoginConfig;
+import org.apache.catalina.deploy.SecurityCollection;
+import org.apache.catalina.deploy.SecurityConstraint;
+import org.apache.catalina.startup.TestTomcat.MapRealm;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.tomcat.util.buf.ByteChunk;
public class TestSsl extends TomcatBaseTest {
public void testSimpleSsl() throws Exception {
- // Install the all-trusting trust manager so https:// works
- // with unsigned certs.
-
- try {
- SSLContext sc = SSLContext.getInstance("SSL");
- sc.init(null, TesterSupport.TRUST_ALL_CERTS,
- new java.security.SecureRandom());
- javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
- sc.getSocketFactory());
- } catch (Exception e) {
- e.printStackTrace();
- }
+ configureClientSsl();
Tomcat tomcat = getTomcatInstance();
tomcat.start();
SSLContext sslCtx = SSLContext.getInstance("TLS");
- sslCtx.init(null, TesterSupport.TRUST_ALL_CERTS,
+ sslCtx.init(null, TesterSupport.getTrustManagers(),
new java.security.SecureRandom());
SSLSocketFactory socketFactory = sslCtx.getSocketFactory();
SSLSocket socket = (SSLSocket) socketFactory.createSocket("localhost", getPort());
}
SSLContext sslCtx = SSLContext.getInstance("TLS");
- sslCtx.init(null, TesterSupport.TRUST_ALL_CERTS, new java.security.SecureRandom());
+ sslCtx.init(null, TesterSupport.getTrustManagers(),
+ new java.security.SecureRandom());
SSLSocketFactory socketFactory = sslCtx.getSocketFactory();
SSLSocket socket = (SSLSocket) socketFactory.createSocket("localhost", getPort());
}
+ public void testClientCert() throws Exception {
+
+ Tomcat tomcat = getTomcatInstance();
+
+ String protocol = tomcat.getConnector().getProtocolHandlerClassName();
+ if (protocol.indexOf("Nio") != -1) {
+ return; // Not supported yet (2011-03-01)
+ }
+ if (protocol.indexOf("Apr") != -1) {
+ return; // Disabled by default in 1.1.20 windows binary (2010-07-27)
+ }
+
+ TesterSupport.initSsl(tomcat);
+
+ // Need a web application with a protected and unprotected URL
+ // Must have a real docBase - just use temp
+ Context ctx =
+ tomcat.addContext("", System.getProperty("java.io.tmpdir"));
+
+ Tomcat.addServlet(ctx, "simple", new SimpleServlet());
+ ctx.addServletMapping("/unprotected", "simple");
+ ctx.addServletMapping("/protected", "simple");
+
+ // Security constraints
+ SecurityCollection collection = new SecurityCollection();
+ collection.addPattern("/protected");
+ SecurityConstraint sc = new SecurityConstraint();
+ sc.addAuthRole("testrole");
+ sc.addCollection(collection);
+ ctx.addConstraint(sc);
+
+ // Configure the Realm
+ MapRealm realm = new MapRealm();
+ realm.addUser("CN=user1, C=US", "not used");
+ realm.addUserRole("CN=user1, C=US", "testrole");
+ ctx.setRealm(realm);
+
+ // Configure the authenticator
+ LoginConfig lc = new LoginConfig();
+ lc.setAuthMethod("CLIENT-CERT");
+ ctx.setLoginConfig(lc);
+ ctx.getPipeline().addValve(new SSLAuthenticator());
+
+ // Start Tomcat
+ tomcat.start();
+
+ configureClientSsl();
+
+ // Get the unprotected resource
+ ByteChunk res =
+ getUrl("https://localhost:" + getPort() + "/unprotected");
+ assertEquals("OK", res.toString());
+
+ // Get the protected resource
+ res = getUrl("https://localhost:" + getPort() + "/protected");
+ assertEquals("OK", res.toString());
+ }
+
@Override
public void setUp() throws Exception {
if (!TesterSupport.RFC_5746_SUPPORTED) {
}
super.setUp();
}
+
+ private void configureClientSsl() {
+ try {
+ SSLContext sc = SSLContext.getInstance("SSL");
+ sc.init(TesterSupport.getUser1KeyManagers(),
+ TesterSupport.getTrustManagers(),
+ new java.security.SecureRandom());
+ javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(
+ sc.getSocketFactory());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static class SimpleServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ resp.setContentType("text/plain");
+ resp.getWriter().print("OK");
+ }
+ }
}
package org.apache.tomcat.util.net;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
import java.security.KeyManagementException;
+import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
-import java.security.cert.X509Certificate;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
+import javax.net.ssl.TrustManagerFactory;
import org.apache.catalina.startup.Tomcat;
RFC_5746_SUPPORTED = result;
}
- protected static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[] {
- new X509TrustManager() {
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
- @Override
- public void checkClientTrusted(X509Certificate[] certs,
- String authType) {
- // NOOP - Trust everything
- }
- @Override
- public void checkServerTrusted(X509Certificate[] certs,
- String authType) {
- // NOOP - Trust everything
- }
- }
- };
-
protected static void initSsl(Tomcat tomcat) {
String protocol = tomcat.getConnector().getProtocolHandlerClassName();
if (protocol.indexOf("Apr") == -1) {
tomcat.getConnector().setProperty("sslProtocol", "tls");
File keystoreFile = new File(
- "test/org/apache/tomcat/util/net/test.keystore");
+ "test/org/apache/tomcat/util/net/localhost.jks");
tomcat.getConnector().setAttribute("keystoreFile",
keystoreFile.getAbsolutePath());
+ File truststoreFile = new File(
+ "test/org/apache/tomcat/util/net/ca.jks");
+ tomcat.getConnector().setAttribute("truststoreFile",
+ truststoreFile.getAbsolutePath());
} else {
File keystoreFile = new File(
- "test/org/apache/tomcat/util/net/test-cert.pem");
+ "test/org/apache/tomcat/util/net/localhost-cert.pem");
tomcat.getConnector().setAttribute("SSLCertificateFile",
keystoreFile.getAbsolutePath());
keystoreFile = new File(
- "test/org/apache/tomcat/util/net/test-key.pem");
+ "test/org/apache/tomcat/util/net/localhost-key.pem");
tomcat.getConnector().setAttribute("SSLCertificateKeyFile",
keystoreFile.getAbsolutePath());
}
tomcat.getConnector().setProperty("SSLEnabled", "true");
}
+ protected static KeyManager[] getUser1KeyManagers() throws Exception {
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+ KeyManagerFactory.getDefaultAlgorithm());
+ kmf.init(getKeyStore("test/org/apache/tomcat/util/net/user1.jks"),
+ "changeit".toCharArray());
+ return kmf.getKeyManagers();
+ }
+
+ protected static TrustManager[] getTrustManagers() throws Exception {
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(getKeyStore("test/org/apache/tomcat/util/net/ca.jks"));
+ return tmf.getTrustManagers();
+ }
+
+ private static KeyStore getKeyStore(String keystore) throws Exception {
+ File keystoreFile = new File(keystore);
+ InputStream is = new FileInputStream(keystoreFile);
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(is, "changeit".toCharArray());
+ return ks;
+ }
}
--- /dev/null
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 4096 (0x1000)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=US, CN=ca-test.tomcat.apache.org
+ Validity
+ Not Before: Feb 28 23:10:55 2011 GMT
+ Not After : Feb 27 23:10:55 2013 GMT
+ Subject: C=US, CN=localhost
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (2048 bit)
+ Modulus (2048 bit):
+ 00:b0:e3:8b:82:f8:b1:82:d9:b1:e8:e8:08:fd:3c:
+ 8a:14:d1:cd:a1:b7:d8:f8:58:93:46:54:c2:6b:b3:
+ 52:fe:ae:7f:a5:70:9e:6c:cf:1f:c7:fb:d7:c2:c2:
+ 5d:0f:18:c9:66:2a:c4:8a:57:ca:0e:4d:b0:0b:af:
+ 1b:26:e9:ad:dd:95:86:69:e4:ac:60:9d:b9:ae:65:
+ aa:d4:9d:3b:02:19:31:60:df:c3:3e:a5:85:cd:49:
+ 01:12:84:36:4c:02:f5:9c:38:b2:20:bf:43:1d:5f:
+ 0c:ae:86:5a:67:24:65:74:77:fa:f4:cd:04:9f:8c:
+ c0:f2:5e:4f:bf:db:da:ce:d2:db:a6:51:82:40:ce:
+ 62:0c:9b:5e:d3:10:7b:49:d5:7a:c9:8e:bf:4b:b8:
+ e3:ac:30:ed:d8:b7:25:1c:c5:5c:0e:1e:57:7c:ad:
+ 60:44:ba:65:6d:45:26:e4:08:a2:1f:c9:3a:cf:7d:
+ bc:e5:61:23:ea:3e:19:46:f0:16:f8:26:e5:32:c6:
+ 69:e5:ea:18:62:2e:05:65:93:49:23:45:11:c3:da:
+ 4c:3b:b4:c6:4a:72:ea:0b:e9:26:06:2c:69:4d:e7:
+ b2:a5:3d:54:ae:7f:17:d3:63:8f:d8:36:5b:46:43:
+ af:bc:c1:09:fc:98:e1:4f:be:74:68:a2:3e:d5:21:
+ 31:d3
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 36:5C:54:F4:2E:91:6D:E7:BC:DD:94:C7:F8:D7:55:01:4A:F7:7D:CD
+ X509v3 Authority Key Identifier:
+ keyid:B0:3B:BC:C9:FA:28:5F:3E:04:1F:9B:6C:C7:8B:68:D8:01:B0:F8:3D
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 30:d5:b3:07:2d:04:25:9b:f1:20:bb:91:49:dc:3d:bf:7e:1c:
+ 2d:09:01:87:a0:30:2b:50:fe:3b:17:34:c6:1d:fa:51:c0:b3:
+ af:f5:62:a6:de:3a:bf:6c:f7:07:e6:80:26:08:d1:84:5b:a3:
+ 5a:0c:6a:07:de:d6:26:1d:c1:89:ed:8a:15:1d:1a:36:0c:13:
+ db:ab:7c:43:35:0b:c2:c6:63:a6:43:81:ce:e5:52:28:cd:ee:
+ c7:0d:3c:8e:a1:07:3b:7c:48:ff:fe:b9:1d:04:51:18:27:d1:
+ fb:b4:1e:bf:36:f1:ef:a9:87:89:3b:b1:49:a9:70:62:5b:f0:
+ 49:e7:27:3a:cc:91:6f:08:43:a4:de:28:f2:1c:69:90:09:5d:
+ bd:78:9f:25:ec:b6:4c:7a:ce:d4:3c:a1:d3:5c:3c:78:04:91:
+ b3:35:56:81:64:4c:61:7b:80:ae:42:34:e1:9a:a1:33:0e:23:
+ dc:76:bf:29:ca:6e:c1:ce:1a:f0:1b:a6:b5:ab:dc:be:19:e9:
+ 9a:e3:6f:7d:ed:a1:e7:bf:f5:23:ad:60:ce:2b:79:49:4e:73:
+ 7f:00:da:a6:95:af:f1:ae:e7:51:de:7f:35:70:60:5d:fb:61:
+ 54:34:a9:22:7a:7e:76:49:70:9f:e7:ab:f1:38:a7:a1:53:87:
+ fb:61:b8:3f
+-----BEGIN CERTIFICATE-----
+MIIDSTCCAjGgAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwMTELMAkGA1UEBhMCVVMx
+IjAgBgNVBAMTGWNhLXRlc3QudG9tY2F0LmFwYWNoZS5vcmcwHhcNMTEwMjI4MjMx
+MDU1WhcNMTMwMjI3MjMxMDU1WjAhMQswCQYDVQQGEwJVUzESMBAGA1UEAxMJbG9j
+YWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsOOLgvixgtmx
+6OgI/TyKFNHNobfY+FiTRlTCa7NS/q5/pXCebM8fx/vXwsJdDxjJZirEilfKDk2w
+C68bJumt3ZWGaeSsYJ25rmWq1J07AhkxYN/DPqWFzUkBEoQ2TAL1nDiyIL9DHV8M
+roZaZyRldHf69M0En4zA8l5Pv9vaztLbplGCQM5iDJte0xB7SdV6yY6/S7jjrDDt
+2LclHMVcDh5XfK1gRLplbUUm5AiiH8k6z3285WEj6j4ZRvAW+CblMsZp5eoYYi4F
+ZZNJI0URw9pMO7TGSnLqC+kmBixpTeeypT1Urn8X02OP2DZbRkOvvMEJ/JjhT750
+aKI+1SEx0wIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVu
+U1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUNlxU9C6Rbee83ZTH
++NdVAUr3fc0wHwYDVR0jBBgwFoAUsDu8yfooXz4EH5tsx4to2AGw+D0wDQYJKoZI
+hvcNAQEFBQADggEBADDVswctBCWb8SC7kUncPb9+HC0JAYegMCtQ/jsXNMYd+lHA
+s6/1YqbeOr9s9wfmgCYI0YRbo1oMagfe1iYdwYntihUdGjYME9urfEM1C8LGY6ZD
+gc7lUijN7scNPI6hBzt8SP/+uR0EURgn0fu0Hr828e+ph4k7sUmpcGJb8EnnJzrM
+kW8IQ6TeKPIcaZAJXb14nyXstkx6ztQ8odNcPHgEkbM1VoFkTGF7gK5CNOGaoTMO
+I9x2vynKbsHOGvAbprWr3L4Z6Zrjb33toee/9SOtYM4reUlOc38A2qaVr/Gu51He
+fzVwYF37YVQ0qSJ6fnZJcJ/nq/E4p6FTh/thuD8=
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAsOOLgvixgtmx6OgI/TyKFNHNobfY+FiTRlTCa7NS/q5/pXCe
+bM8fx/vXwsJdDxjJZirEilfKDk2wC68bJumt3ZWGaeSsYJ25rmWq1J07AhkxYN/D
+PqWFzUkBEoQ2TAL1nDiyIL9DHV8MroZaZyRldHf69M0En4zA8l5Pv9vaztLbplGC
+QM5iDJte0xB7SdV6yY6/S7jjrDDt2LclHMVcDh5XfK1gRLplbUUm5AiiH8k6z328
+5WEj6j4ZRvAW+CblMsZp5eoYYi4FZZNJI0URw9pMO7TGSnLqC+kmBixpTeeypT1U
+rn8X02OP2DZbRkOvvMEJ/JjhT750aKI+1SEx0wIDAQABAoIBACTERx1D//GIujgE
+8slgKftF2I4CnrCQCJyXxYmJTnjtYE7M58EKFDsHF8O9joYyyrnXrd5rfO4YK71h
++izOaXsjNzsPctzqK8waCbYDsF4xSlguanC9CuCuifCFVpvaCZ8dEblIx/R06zfj
+aSsDH6tjvN/hNVLMeNZnz/+6/PH7/SP+HbDWGEi15yx1CSuqD3Dj/wIY7uhvlv/J
+DGDeYhjcSupjofBkk2guwHzV6qL7fLWyn7MPVS3iRHeX8yWxAWabiW7WVqpClAKE
+OTfP9h13yutQx10dhMzIYdxcXeyyfOVfI+mwyi8AN9FAwP11dN7w/0xqTMNErCox
+qW1C1YECgYEA6QKjfMGkmtpWsDKpu0I4wgnPh0VtuhQGaLy/f0IFn05BOZVD0LiF
+0jqyj1HtNkBSeX0Cz5GCG7DihX4seMjiYbHrOLTRrqIGxMLGJdMNUkmZZHCX7ZhT
+SXFTgbqF3gCSPL5avta2eyPKjrCJYDYwqpbvd2lc7YKPOfHyOgqyDnMCgYEAwldk
+xZUK3HR94/4GWS46TNIsv0IYLTbrzJKNFnbn0t1JVPR7aHUeI8cSrGa5mCHzn1wK
+JFwe7JzlgyLZvgblqbxgDw5x8/GrLNhR3ClxtROusAg7zgX2Pxl0Gk1pr8dBgoiU
+m3cZPKgvhagPQ6NKkP+ryzqJxXc8Pm51neZbFyECgYEA0Z91ExRmkIVivasmdXfS
+9gW7dNeqKmA/j9RWdxcfVb0iArrdQpXulj4GS9eJj2f4iqFDeRdPtLfCYhQr0BHx
+T7Cvi9loVjIf4r3TY03myyO5YtnEZJTIQOc6GBiEvD9JUGpz2wHxMwD1Br+dJzg5
+Og8FqijY2De/wIKAx2S94S8CgYEAlZ4gx/ipxvWsYhWUn532ZmQ87PYelNi+it2c
+31mlunKA3XXneJEKJjNCDhZ79kLVQ6/hYwLFEBbun5n6FtFKiPWs4oqVcmBxD3Ju
++1ew4d6IU5/TIxb18LhQ6VsF7b0ykyNBfbsgY9F73KN5NPKHGsCrayfjH3JfoBT8
+WhcZs+ECgYBu7Y+hbGzMpHiuzyV/Niii5Iec2X+5H5rnM6S5h9I37aVnOp2Kl8bo
+Eg5krCCeR6/F+I8Qj3KSgu3af1pTliO4m7Dt0sm3SEJeGrb7xQF2m0mf4VJ7Bf/w
+H/H3Cuk63tsLedxWD0AYdlNbT7cA47bl15G8J+5qRQXZyuxUP1mZ9Q==
+-----END RSA PRIVATE KEY-----
+++ /dev/null
------BEGIN CERTIFICATE-----
-MIICUzCCAbygAwIBAgIESviASzANBgkqhkiG9w0BAQUFADBuMRAwDgYDVQQGEwdV
-bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD
-VQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRIwEAYDVQQDEwlsb2NhbGhv
-c3QwHhcNMDkxMTA5MjA0OTE1WhcNMTAwMjA3MjA0OTE1WjBuMRAwDgYDVQQGEwdV
-bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD
-VQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRIwEAYDVQQDEwlsb2NhbGhv
-c3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALGOFqjC4Fefz0oOcfJeS8eL
-V8jYzA3sHUnTKmASfgfhG8prWUgSEq7O/849MrBysiKpIvTN8R+ykV4QCAxauGUR
-DsNI2ZtAv23YX2MbcfYfYqD0tgHEn355HKey0ICgmRuq3norlUWAH3hRv5qiQMc0
-UIhNrmdTs0jyvQ8E8AlZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAPHUr1BDENlV2
-8yIQvJOWKYbcNWLd6Cp8xCltSI897xhPpKQ5tDvs+l0gVfdBv5+jou0F5gbCkqgc
-lBuUnUUWsU7r4HYBLVB8FiGSy9v5yuFJWyMMLJkWAfBgzxV1nHsCPhOnrspSB+i6
-bwag0i3ENXstD/Fg1lN/7l9dRpurneI=
------END CERTIFICATE-----
+++ /dev/null
------BEGIN PRIVATE KEY-----
-MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALGOFqjC4Fefz0oO
-cfJeS8eLV8jYzA3sHUnTKmASfgfhG8prWUgSEq7O/849MrBysiKpIvTN8R+ykV4Q
-CAxauGURDsNI2ZtAv23YX2MbcfYfYqD0tgHEn355HKey0ICgmRuq3norlUWAH3hR
-v5qiQMc0UIhNrmdTs0jyvQ8E8AlZAgMBAAECgYBybr8P2Tk5gBfbBOBPcpKocpgL
-LB6nQmvF7sC61nA/p8d/eBw8pNlBrMuVIkAPFHzWdee/mxMyeKXT18U4ISgBdIKL
-F9LwILhIgR8CwElLucmF2OdXqFe7baBIFI6OaqLvDgOwdHSIS6uZhAWOWIAZ38Dh
-JbHMzPpfeBv1bAIhAQJBAPwhjzWqSWZjAfcED4htKa/ZSbdqMa1iYtveoHdXIcLu
-j4Ck1DKQEFpzLnUe2gwul/TDcoW3ZVp85jn7jwnrNDECQQC0R5LgkGdGNMBih4kP
-U87tHFHUnggSMyIOBnCEXuQEN6i68VOwbdm2F7Rg1XGHD8IIJmVeiTSgLtS/mJRh
-t6WpAkEAqs9VhQbTaTDkEOPIXiWOW1q6rS6dbxg7XzdowNDfx3706zM/qu2clpp3
-u9Ll5+DdA24xtNM1L+Nz2Y5KLm8Q0QJAQqpxEx/zQNADEKyEL6nTTHV7gT+LRoeo
-IT2aYCji8vhOKgtR4l1M8/xiFKj5mXNnUjI4rDPaxR1sSQm4XUZXOQJBAJaCD0Ah
-acU+KaOtk65tBJ7N2dKTbc5gs/CAz1uGgJtoD/jPjELMQwrxdp6AZP6+L6osqy6z
-DI3WzNHXS+wWAd0=
------END PRIVATE KEY-----