6937978: let keytool -gencert generate the chain
Reviewed-by: mullan
This commit is contained in:
parent
d0a7eafe8d
commit
7afbc895a8
@ -1211,6 +1211,14 @@ public final class KeyTool {
|
|||||||
X509CertImpl cert = new X509CertImpl(info);
|
X509CertImpl cert = new X509CertImpl(info);
|
||||||
cert.sign(privateKey, sigAlgName);
|
cert.sign(privateKey, sigAlgName);
|
||||||
dumpCert(cert, out);
|
dumpCert(cert, out);
|
||||||
|
for (Certificate ca: keyStore.getCertificateChain(alias)) {
|
||||||
|
if (ca instanceof X509Certificate) {
|
||||||
|
X509Certificate xca = (X509Certificate)ca;
|
||||||
|
if (!isSelfSigned(xca)) {
|
||||||
|
dumpCert(xca, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2640,19 +2648,33 @@ public final class KeyTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given certificate is trusted, false otherwise.
|
* Locates a signer for a given certificate from a given keystore and
|
||||||
|
* returns the signer's certificate.
|
||||||
|
* @param cert the certificate whose signer is searched, not null
|
||||||
|
* @param ks the keystore to search with, not null
|
||||||
|
* @return <code>cert</code> itself if it's already inside <code>ks</code>,
|
||||||
|
* or a certificate inside <code>ks</code> who signs <code>cert</code>,
|
||||||
|
* or null otherwise.
|
||||||
*/
|
*/
|
||||||
private boolean isTrusted(Certificate cert)
|
private static Certificate getTrustedSigner(Certificate cert, KeyStore ks)
|
||||||
throws Exception
|
throws Exception {
|
||||||
{
|
if (ks.getCertificateAlias(cert) != null) {
|
||||||
if (keyStore.getCertificateAlias(cert) != null) {
|
return cert;
|
||||||
return true; // found in own keystore
|
|
||||||
}
|
}
|
||||||
if (trustcacerts && (caks != null) &&
|
for (Enumeration<String> aliases = ks.aliases();
|
||||||
(caks.getCertificateAlias(cert) != null)) {
|
aliases.hasMoreElements(); ) {
|
||||||
return true; // found in CA keystore
|
String name = aliases.nextElement();
|
||||||
|
Certificate trustedCert = ks.getCertificate(name);
|
||||||
|
if (trustedCert != null) {
|
||||||
|
try {
|
||||||
|
cert.verify(trustedCert.getPublicKey());
|
||||||
|
return trustedCert;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Not verified, skip to the next one
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2985,27 +3007,13 @@ public final class KeyTool {
|
|||||||
return replyCerts;
|
return replyCerts;
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we trust the (root) cert at the top?
|
// do we trust the cert at the top?
|
||||||
Certificate topCert = replyCerts[replyCerts.length-1];
|
Certificate topCert = replyCerts[replyCerts.length-1];
|
||||||
if (!isTrusted(topCert)) {
|
Certificate root = getTrustedSigner(topCert, keyStore);
|
||||||
boolean verified = false;
|
if (root == null && trustcacerts && caks != null) {
|
||||||
Certificate rootCert = null;
|
root = getTrustedSigner(topCert, caks);
|
||||||
if (trustcacerts && (caks!= null)) {
|
|
||||||
for (Enumeration<String> aliases = caks.aliases();
|
|
||||||
aliases.hasMoreElements(); ) {
|
|
||||||
String name = aliases.nextElement();
|
|
||||||
rootCert = caks.getCertificate(name);
|
|
||||||
if (rootCert != null) {
|
|
||||||
try {
|
|
||||||
topCert.verify(rootCert.getPublicKey());
|
|
||||||
verified = true;
|
|
||||||
break;
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
}
|
||||||
}
|
if (root == null) {
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!verified) {
|
|
||||||
System.err.println();
|
System.err.println();
|
||||||
System.err.println
|
System.err.println
|
||||||
(rb.getString("Top-level certificate in reply:\n"));
|
(rb.getString("Top-level certificate in reply:\n"));
|
||||||
@ -3018,17 +3026,16 @@ public final class KeyTool {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!isSelfSigned((X509Certificate)topCert)) {
|
if (root != topCert) {
|
||||||
// append the (self-signed) root CA cert to the chain
|
// append the root CA cert to the chain
|
||||||
Certificate[] tmpCerts =
|
Certificate[] tmpCerts =
|
||||||
new Certificate[replyCerts.length+1];
|
new Certificate[replyCerts.length+1];
|
||||||
System.arraycopy(replyCerts, 0, tmpCerts, 0,
|
System.arraycopy(replyCerts, 0, tmpCerts, 0,
|
||||||
replyCerts.length);
|
replyCerts.length);
|
||||||
tmpCerts[tmpCerts.length-1] = rootCert;
|
tmpCerts[tmpCerts.length-1] = root;
|
||||||
replyCerts = tmpCerts;
|
replyCerts = tmpCerts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return replyCerts;
|
return replyCerts;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
# Copyright 2009-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,8 +22,8 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# @test
|
# @test
|
||||||
# @bug 6825352
|
# @bug 6825352 6937978
|
||||||
# @summary support self-issued certificate in keytool
|
# @summary support self-issued certificate in keytool and let -gencert generate the chain
|
||||||
#
|
#
|
||||||
# @run shell selfissued.sh
|
# @run shell selfissued.sh
|
||||||
#
|
#
|
||||||
@ -50,20 +50,22 @@ KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystor
|
|||||||
rm $KS
|
rm $KS
|
||||||
|
|
||||||
$KT -alias ca -dname CN=CA -genkeypair
|
$KT -alias ca -dname CN=CA -genkeypair
|
||||||
$KT -alias me -dname CN=CA -genkeypair
|
$KT -alias ca1 -dname CN=CA -genkeypair
|
||||||
|
$KT -alias ca2 -dname CN=CA -genkeypair
|
||||||
$KT -alias e1 -dname CN=E1 -genkeypair
|
$KT -alias e1 -dname CN=E1 -genkeypair
|
||||||
$KT -alias e2 -dname CN=E2 -genkeypair
|
|
||||||
|
|
||||||
# me signed by ca, self-issued
|
# ca signs ca1, ca1 signs ca2, all self-issued
|
||||||
$KT -alias me -certreq | $KT -alias ca -gencert | $KT -alias me -importcert
|
$KT -alias ca1 -certreq | $KT -alias ca -gencert -ext san=dns:ca1 \
|
||||||
|
| $KT -alias ca1 -importcert
|
||||||
|
$KT -alias ca2 -certreq | $KT -alias ca1 -gencert -ext san=dns:ca2 \
|
||||||
|
| $KT -alias ca2 -importcert
|
||||||
|
|
||||||
# Import e1 signed by me, should add me and ca
|
# Import e1 signed by ca2, should add ca2 and ca1, at least 3 certs in the chain
|
||||||
$KT -alias e1 -certreq | $KT -alias me -gencert | $KT -alias e1 -importcert
|
$KT -alias e1 -certreq | $KT -alias ca2 -gencert > e1.cert
|
||||||
|
$KT -alias ca1 -delete
|
||||||
|
$KT -alias ca2 -delete
|
||||||
|
cat e1.cert | $KT -alias e1 -importcert
|
||||||
$KT -alias e1 -list -v | grep '\[3\]' || { echo Bad E1; exit 1; }
|
$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
|
echo Good
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user