--- a/jdk/src/share/classes/sun/security/tools/KeyTool.java Tue Mar 31 23:52:04 2009 -0700
+++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java Fri Apr 03 11:36:19 2009 +0800
@@ -2545,7 +2545,19 @@
* Returns true if the certificate is self-signed, false otherwise.
*/
private boolean isSelfSigned(X509Certificate cert) {
- return cert.getSubjectDN().equals(cert.getIssuerDN());
+ return signedBy(cert, cert);
+ }
+
+ private boolean signedBy(X509Certificate end, X509Certificate ca) {
+ if (!ca.getSubjectDN().equals(end.getIssuerDN())) {
+ return false;
+ }
+ try {
+ end.verify(ca.getPublicKey());
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
}
/**
@@ -2869,20 +2881,18 @@
Certificate tmpCert = replyCerts[0];
replyCerts[0] = replyCerts[i];
replyCerts[i] = tmpCert;
- Principal issuer = ((X509Certificate)replyCerts[0]).getIssuerDN();
+
+ X509Certificate thisCert = (X509Certificate)replyCerts[0];
for (i=1; i < replyCerts.length-1; i++) {
- // find a cert in the reply whose "subject" is the same as the
- // given "issuer"
+ // find a cert in the reply who signs thisCert
int j;
for (j=i; j<replyCerts.length; j++) {
- Principal subject;
- subject = ((X509Certificate)replyCerts[j]).getSubjectDN();
- if (subject.equals(issuer)) {
+ if (signedBy(thisCert, (X509Certificate)replyCerts[j])) {
tmpCert = replyCerts[i];
replyCerts[i] = replyCerts[j];
replyCerts[j] = tmpCert;
- issuer = ((X509Certificate)replyCerts[i]).getIssuerDN();
+ thisCert = (X509Certificate)replyCerts[i];
break;
}
}
@@ -2892,18 +2902,6 @@
}
}
- // now verify each cert in the ordered chain
- for (i=0; i<replyCerts.length-1; i++) {
- PublicKey pubKey = replyCerts[i+1].getPublicKey();
- try {
- replyCerts[i].verify(pubKey);
- } catch (Exception e) {
- throw new Exception(rb.getString
- ("Certificate chain in reply does not verify: ") +
- e.getMessage());
- }
- }
-
if (noprompt) {
return replyCerts;
}
@@ -3035,9 +3033,8 @@
private boolean buildChain(X509Certificate certToVerify,
Vector<Certificate> chain,
Hashtable<Principal, Vector<Certificate>> certs) {
- Principal subject = certToVerify.getSubjectDN();
Principal issuer = certToVerify.getIssuerDN();
- if (subject.equals(issuer)) {
+ if (isSelfSigned(certToVerify)) {
// reached self-signed root cert;
// no verification needed because it's trusted.
chain.addElement(certToVerify);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/keytool/selfissued.sh Fri Apr 03 11:36:19 2009 +0800
@@ -0,0 +1,69 @@
+#
+# Copyright 2009 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 6825352
+# @summary support self-issued certificate in keytool
+#
+# @run shell selfissued.sh
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ Windows_* )
+ FS="\\"
+ ;;
+ * )
+ FS="/"
+ ;;
+esac
+
+KS=selfsigned.jks
+KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS"
+
+rm $KS
+
+$KT -alias ca -dname CN=CA -genkeypair
+$KT -alias me -dname CN=CA -genkeypair
+$KT -alias e1 -dname CN=E1 -genkeypair
+$KT -alias e2 -dname CN=E2 -genkeypair
+
+# me signed by ca, self-issued
+$KT -alias me -certreq | $KT -alias ca -gencert | $KT -alias me -importcert
+
+# Import e1 signed by me, should add me and ca
+$KT -alias e1 -certreq | $KT -alias me -gencert | $KT -alias e1 -importcert
+$KT -alias e1 -list -v | grep '\[3\]' || { echo Bad E1; exit 1; }
+
+# Import (e2 signed by me,ca,me), should reorder to (e2,me,ca)
+( $KT -alias e2 -certreq | $KT -alias me -gencert; $KT -exportcert -alias ca; $KT -exportcert -alias me ) | $KT -alias e2 -importcert
+$KT -alias e2 -list -v | grep '\[3\]' || { echo Bad E2; exit 1; }
+
+echo Good
+