6480981: keytool should be able to import certificates from remote SSL servers
Reviewed-by: vinnie, wetmore
This commit is contained in:
parent
1f7f81d687
commit
9ac27197df
jdk
src/share/classes/sun/security
test/sun/security/tools/keytool
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,35 +26,23 @@
|
||||
package sun.security.tools;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Key;
|
||||
import java.security.PublicKey;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Security;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.security.UnrecoverableEntryException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.Principal;
|
||||
import java.security.Provider;
|
||||
import java.security.Identity;
|
||||
import java.security.Signer;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.interfaces.DSAParams;
|
||||
import java.security.interfaces.DSAPrivateKey;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.security.interfaces.RSAPrivateCrtKey;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.text.Collator;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
@ -62,7 +50,6 @@ import java.lang.reflect.Constructor;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import sun.misc.BASE64Decoder;
|
||||
import sun.misc.BASE64Encoder;
|
||||
import sun.security.util.ObjectIdentifier;
|
||||
import sun.security.pkcs.PKCS10;
|
||||
@ -72,11 +59,16 @@ import sun.security.provider.SystemIdentity;
|
||||
import sun.security.provider.X509Factory;
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.Password;
|
||||
import sun.security.util.Resources;
|
||||
import sun.security.util.PathList;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import sun.security.x509.*;
|
||||
|
||||
import static java.security.KeyStore.*;
|
||||
@ -132,6 +124,7 @@ public final class KeyTool {
|
||||
private String ksfname = null;
|
||||
private File ksfile = null;
|
||||
private InputStream ksStream = null; // keystore stream
|
||||
private String sslserver = null;
|
||||
private KeyStore keyStore = null;
|
||||
private boolean token = false;
|
||||
private boolean nullStream = false;
|
||||
@ -347,6 +340,9 @@ public final class KeyTool {
|
||||
} else if (collator.compare(flags, "-file") == 0) {
|
||||
if (++i == args.length) errorNeedArgument(flags);
|
||||
filename = args[i];
|
||||
} else if (collator.compare(flags, "-sslserver") == 0) {
|
||||
if (++i == args.length) errorNeedArgument(flags);
|
||||
sslserver = args[i];
|
||||
} else if (collator.compare(flags, "-srckeystore") == 0) {
|
||||
if (++i == args.length) errorNeedArgument(flags);
|
||||
srcksfname = args[i];
|
||||
@ -924,17 +920,7 @@ public final class KeyTool {
|
||||
doPrintEntries(out);
|
||||
}
|
||||
} else if (command == PRINTCERT) {
|
||||
InputStream inStream = System.in;
|
||||
if (filename != null) {
|
||||
inStream = new FileInputStream(filename);
|
||||
}
|
||||
try {
|
||||
doPrintCert(inStream, out);
|
||||
} finally {
|
||||
if (inStream != System.in) {
|
||||
inStream.close();
|
||||
}
|
||||
}
|
||||
doPrintCert(out);
|
||||
} else if (command == SELFCERT) {
|
||||
doSelfCert(alias, dname, sigAlgName);
|
||||
kssave = true;
|
||||
@ -1744,7 +1730,7 @@ public final class KeyTool {
|
||||
* Reads a certificate (or certificate chain) and prints its contents in
|
||||
* a human readbable format.
|
||||
*/
|
||||
private void doPrintCert(InputStream in, PrintStream out)
|
||||
private void printCertFromStream(InputStream in, PrintStream out)
|
||||
throws Exception
|
||||
{
|
||||
Collection<? extends Certificate> c = null;
|
||||
@ -1770,13 +1756,98 @@ public final class KeyTool {
|
||||
Object[] source = {new Integer(i + 1)};
|
||||
out.println(form.format(source));
|
||||
}
|
||||
printX509Cert(x509Cert, out);
|
||||
if (rfc) dumpCert(x509Cert, out);
|
||||
else printX509Cert(x509Cert, out);
|
||||
if (i < (certs.length-1)) {
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doPrintCert(final PrintStream out) throws Exception {
|
||||
if (sslserver != null) {
|
||||
SSLContext sc = SSLContext.getInstance("SSL");
|
||||
final boolean[] certPrinted = new boolean[1];
|
||||
sc.init(null, new TrustManager[] {
|
||||
new X509TrustManager() {
|
||||
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void checkClientTrusted(
|
||||
java.security.cert.X509Certificate[] certs, String authType) {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(
|
||||
java.security.cert.X509Certificate[] certs, String authType) {
|
||||
for (int i=0; i<certs.length; i++) {
|
||||
X509Certificate cert = certs[i];
|
||||
try {
|
||||
if (rfc) {
|
||||
dumpCert(cert, out);
|
||||
} else {
|
||||
out.println("Certificate #" + i);
|
||||
out.println("====================================");
|
||||
printX509Cert(cert, out);
|
||||
out.println();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (debug) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set to true where there's something to print
|
||||
if (certs.length > 0) {
|
||||
certPrinted[0] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(
|
||||
new HostnameVerifier() {
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
// HTTPS instead of raw SSL, so that -Dhttps.proxyHost and
|
||||
// -Dhttps.proxyPort can be used. Since we only go through
|
||||
// the handshake process, an HTTPS server is not needed.
|
||||
// This program should be able to deal with any SSL-based
|
||||
// network service.
|
||||
Exception ex = null;
|
||||
try {
|
||||
new URL("https://" + sslserver).openConnection().connect();
|
||||
} catch (Exception e) {
|
||||
ex = e;
|
||||
}
|
||||
// If the certs are not printed out, we consider it an error even
|
||||
// if the URL connection is successful.
|
||||
if (!certPrinted[0]) {
|
||||
Exception e = new Exception(
|
||||
rb.getString("No certificate from the SSL server"));
|
||||
if (ex != null) {
|
||||
e.initCause(ex);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
InputStream inStream = System.in;
|
||||
if (filename != null) {
|
||||
inStream = new FileInputStream(filename);
|
||||
}
|
||||
try {
|
||||
printCertFromStream(inStream, out);
|
||||
} finally {
|
||||
if (inStream != System.in) {
|
||||
inStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a self-signed certificate, and stores it as a single-element
|
||||
* certificate chain.
|
||||
@ -3127,7 +3198,7 @@ public final class KeyTool {
|
||||
System.err.println();
|
||||
|
||||
System.err.println(rb.getString
|
||||
("-printcert [-v] [-file <cert_file>]"));
|
||||
("-printcert [-v] [-rfc] [-file <cert_file> | -sslserver <host[:port]>]"));
|
||||
System.err.println();
|
||||
|
||||
System.err.println(rb.getString
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -386,8 +386,10 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
{"\t [-alias <alias>]", "\t [-alias <alias>]"},
|
||||
/** rest is same as -certreq starting from -keystore **/
|
||||
|
||||
{"-printcert [-v] [-file <cert_file>]",
|
||||
"-printcert [-v] [-file <cert_file>]"},
|
||||
{"-printcert [-v] [-rfc] [-file <cert_file> | -sslserver <host[:port]>]",
|
||||
"-printcert [-v] [-rfc] [-file <cert_file> | -sslserver <host[:port]>]"},
|
||||
{"No certificate from the SSL server",
|
||||
"No certificate from the SSL server"},
|
||||
|
||||
//{"-selfcert [-v] [-protected]",
|
||||
// "-selfcert [-v] [-protected]"},
|
||||
|
55
jdk/test/sun/security/tools/keytool/PrintSSL.java
Normal file
55
jdk/test/sun/security/tools/keytool/PrintSSL.java
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
// Read printssl.sh, this Java program starts an SSL server
|
||||
|
||||
import java.net.ServerSocket;
|
||||
import javax.net.ssl.SSLServerSocketFactory;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
public class PrintSSL {
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.setProperty("javax.net.ssl.keyStorePassword", "passphrase");
|
||||
System.setProperty("javax.net.ssl.keyStore",
|
||||
System.getProperty("test.src", "./") + "/../../ssl/etc/keystore");
|
||||
SSLServerSocketFactory sslssf =
|
||||
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
|
||||
final ServerSocket server = sslssf.createServerSocket(0);
|
||||
System.out.println(server.getLocalPort());
|
||||
System.out.flush();
|
||||
Thread t = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(30000);
|
||||
server.close();
|
||||
} catch (Exception e) {
|
||||
;
|
||||
}
|
||||
throw new RuntimeException("Timeout");
|
||||
}
|
||||
};
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
((SSLSocket)server.accept()).startHandshake();
|
||||
}
|
||||
}
|
58
jdk/test/sun/security/tools/keytool/printssl.sh
Normal file
58
jdk/test/sun/security/tools/keytool/printssl.sh
Normal file
@ -0,0 +1,58 @@
|
||||
#
|
||||
# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
# CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
# have any questions.
|
||||
#
|
||||
|
||||
# @test
|
||||
# @bug 6480981
|
||||
# @summary keytool should be able to import certificates from remote SSL servers
|
||||
|
||||
if [ "${TESTSRC}" = "" ] ; then
|
||||
TESTSRC="."
|
||||
fi
|
||||
if [ "${TESTJAVA}" = "" ] ; then
|
||||
echo "TESTJAVA not set. Test cannot execute."
|
||||
echo "FAILED!!!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux )
|
||||
FS="/"
|
||||
;;
|
||||
Windows_* )
|
||||
FS="\\"
|
||||
;;
|
||||
* )
|
||||
echo "Unrecognized operating system!"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}PrintSSL.java || exit 10
|
||||
${TESTJAVA}${FS}bin${FS}java -Dtest.src=$TESTSRC PrintSSL | ( read PORT; ${TESTJAVA}${FS}bin${FS}keytool -printcert -sslserver localhost:$PORT )
|
||||
status=$?
|
||||
|
||||
rm PrintSSL*.class
|
||||
|
||||
exit $status
|
Loading…
x
Reference in New Issue
Block a user