From a0ac0f231e49526ab81ffdb90aaac4bb90bd1dbf Mon Sep 17 00:00:00 2001 From: John Jiang Date: Wed, 15 Jan 2025 15:57:15 +0800 Subject: [PATCH] TKSS-1061: Backport JDK-8342062: Reformat keytool and jarsigner output for keys with a named parameter set --- .../kona/sun/security/tools/keytool/Main.java | 90 ++++++++++--------- .../sun/security/tools/keytool/Resources.java | 21 ++--- .../kona/sun/security/util/KeyUtil.java | 22 +---- 3 files changed, 62 insertions(+), 71 deletions(-) diff --git a/kona-pkix/src/main/java/com/tencent/kona/sun/security/tools/keytool/Main.java b/kona-pkix/src/main/java/com/tencent/kona/sun/security/tools/keytool/Main.java index 72972f29..b1d15804 100644 --- a/kona-pkix/src/main/java/com/tencent/kona/sun/security/tools/keytool/Main.java +++ b/kona-pkix/src/main/java/com/tencent/kona/sun/security/tools/keytool/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. 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 @@ -38,7 +38,8 @@ import java.security.cert.X509Certificate; import java.security.cert.CertificateException; import java.security.cert.TrustAnchor; - +import java.security.spec.ECParameterSpec; +//import java.security.spec.NamedParameterSpec; import java.text.Collator; import java.text.MessageFormat; import java.util.*; @@ -62,21 +63,12 @@ import com.tencent.kona.pkix.PKIXInsts; import com.tencent.kona.sun.security.pkcs12.PKCS12KeyStore; import com.tencent.kona.sun.security.provider.certpath.CertPathConstraintsParameters; -import com.tencent.kona.sun.security.util.ConstraintsParameters; -import com.tencent.kona.sun.security.util.ECKeySizeParameterSpec; -import com.tencent.kona.sun.security.util.HexDumpEncoder; -import com.tencent.kona.sun.security.util.IOUtils; -import com.tencent.kona.sun.security.util.KeyUtil; -import com.tencent.kona.sun.security.util.ObjectIdentifier; +import com.tencent.kona.sun.security.util.*; import com.tencent.kona.sun.security.pkcs10.PKCS10; import com.tencent.kona.sun.security.pkcs10.PKCS10Attribute; import com.tencent.kona.sun.security.provider.X509Factory; import com.tencent.kona.sun.security.provider.certpath.ssl.SSLServerCertStore; -import com.tencent.kona.sun.security.util.KnownOIDs; -import com.tencent.kona.sun.security.util.Password; -import com.tencent.kona.sun.security.util.SecurityProperties; -import com.tencent.kona.sun.security.util.SecurityProviderConstants; -import com.tencent.kona.sun.security.util.SignatureUtil; + import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; @@ -84,15 +76,12 @@ import com.tencent.kona.sun.security.pkcs.PKCS9Attribute; import com.tencent.kona.sun.security.tools.KeyStoreUtil; -import com.tencent.kona.sun.security.util.DerValue; -import com.tencent.kona.sun.security.util.Pem; import com.tencent.kona.sun.security.validator.Validator; import com.tencent.kona.sun.security.x509.*; import static java.security.KeyStore.*; import static com.tencent.kona.sun.security.tools.keytool.Main.Command.*; import static com.tencent.kona.sun.security.tools.keytool.Main.Option.*; -import com.tencent.kona.sun.security.util.DisabledAlgorithmConstraints; /** * This tool manages keystores. @@ -2062,20 +2051,18 @@ private void doGenKeyPair(String alias, String dname, String keyAlgName, Object[] source; if (signerAlias != null) { form = new MessageFormat(rb.getString - ("Generating.keysize.bit.keyAlgName.key.pair.and.a.certificate.sigAlgName.issued.by.signerAlias.with.a.validity.of.validality.days.for")); + ("Generating.full.keyAlgName.key.pair.and.a.certificate.sigAlgName.issued.by.signerAlias.with.a.validity.of.days.for")); source = new Object[]{ - groupName == null ? keysize : KeyUtil.getKeySize(privKey), - KeyUtil.fullDisplayAlgName(privKey), + fullDisplayKeyName(privKey), newCert.getSigAlgName(), signerAlias, validity, x500Name}; } else { form = new MessageFormat(rb.getString - ("Generating.keysize.bit.keyAlgName.key.pair.and.self.signed.certificate.sigAlgName.with.a.validity.of.validality.days.for")); + ("Generating.full.keyAlgName.key.pair.and.self.signed.certificate.sigAlgName.with.a.validity.of.days.for")); source = new Object[]{ - groupName == null ? keysize : KeyUtil.getKeySize(privKey), - KeyUtil.fullDisplayAlgName(privKey), + fullDisplayKeyName(privKey), newCert.getSigAlgName(), validity, x500Name}; @@ -2100,6 +2087,38 @@ private void doGenKeyPair(String alias, String dname, String keyAlgName, keyStore.setKeyEntry(alias, privKey, keyPass, finalChain); } + /** + * Returns the full display name of the given key object. Could be + * - "X25519", if its getParams() is NamedParameterSpec + * - "EC (secp256r1)", if it's an EC key + * - "1024-bit RSA", other known keys + * - plain algorithm name, otherwise + * + * Note: the same method appears in keytool and jarsigner which uses + * same resource string defined in their own Resources.java. + * + * @param key the key object, cannot be null + * @return the full name + */ + private static String fullDisplayKeyName(Key key) { + String alg = key.getAlgorithm(); +// if (key instanceof AsymmetricKey ak) { +// var params = ak.getParams(); +// if (params instanceof NamedParameterSpec nps) { +// return nps.getName(); // directly return +// } else if (params instanceof ECParameterSpec eps) { +// var nc = CurveDB.lookup(eps); +// if (nc != null) { +// alg += " (" + nc.getNameAndAliases()[0] + ")"; // append name +// } +// } +// } + int size = KeyUtil.getKeySize(key); + return size >= 0 + ? String.format(rb.getString("size.bit.alg"), size, alg) + : alg; + } + private String ecGroupNameForSize(int size) throws Exception { AlgorithmParameters ap = CryptoInsts.getAlgorithmParameters("EC"); ap.init(new ECKeySizeParameterSpec(size)); @@ -3629,22 +3648,17 @@ private String withWeak(String alg) { private String withWeakConstraint(Key key, CertPathConstraintsParameters cpcp) { - int kLen = KeyUtil.getKeySize(key); - String displayAlg = KeyUtil.fullDisplayAlgName(key); + String displayAlg = fullDisplayKeyName(key); try { DISABLED_CHECK.permits(key.getAlgorithm(), cpcp, true); } catch (CertPathValidatorException e) { - return String.format(rb.getString("key.bit.disabled"), kLen, displayAlg); + return String.format(rb.getString("key.bit.disabled"), displayAlg); } try { LEGACY_CHECK.permits(key.getAlgorithm(), cpcp, true); - if (kLen >= 0) { - return String.format(rb.getString("key.bit"), kLen, displayAlg); - } else { - return String.format(rb.getString("unknown.size.1"), displayAlg); - } + return String.format(rb.getString("key.bit"), displayAlg); } catch (CertPathValidatorException e) { - return String.format(rb.getString("key.bit.weak"), kLen, displayAlg); + return String.format(rb.getString("key.bit.weak"), displayAlg); } } @@ -5009,14 +5023,12 @@ private void checkWeakConstraint(String label, String sigAlg, Key key, } catch (CertPathValidatorException e) { weakWarnings.add(String.format( rb.getString("whose.key.weak"), label, - String.format(rb.getString("key.bit"), - KeyUtil.getKeySize(key), KeyUtil.fullDisplayAlgName(key)))); + String.format(rb.getString("key.bit"), fullDisplayKeyName(key)))); } } catch (CertPathValidatorException e) { weakWarnings.add(String.format( rb.getString("whose.key.disabled"), label, - String.format(rb.getString("key.bit"), - KeyUtil.getKeySize(key), KeyUtil.fullDisplayAlgName(key)))); + String.format(rb.getString("key.bit"), fullDisplayKeyName(key)))); } } } @@ -5036,13 +5048,11 @@ private void checkWeak(String label, String sigAlg, Key key) { if (!DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { weakWarnings.add(String.format( rb.getString("whose.key.disabled"), label, - String.format(rb.getString("key.bit"), - KeyUtil.getKeySize(key), KeyUtil.fullDisplayAlgName(key)))); + String.format(rb.getString("key.bit"), fullDisplayKeyName(key)))); } else if (!LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) { weakWarnings.add(String.format( rb.getString("whose.key.weak"), label, - String.format(rb.getString("key.bit"), - KeyUtil.getKeySize(key), KeyUtil.fullDisplayAlgName(key)))); + String.format(rb.getString("key.bit"), fullDisplayKeyName(key)))); } } } @@ -5109,7 +5119,7 @@ private void checkWeakConstraint(String label, SecretKey secKey, weakWarnings.add(String.format( rb.getString("key.size.weak"), label, String.format(rb.getString("key.bit"), - KeyUtil.getKeySize(secKey), secKeyAlg))); + fullDisplayKeyName(secKey)))); } else { weakWarnings.add(String.format( rb.getString("key.algorithm.weak"), label, secKeyAlg)); diff --git a/kona-pkix/src/main/java/com/tencent/kona/sun/security/tools/keytool/Resources.java b/kona-pkix/src/main/java/com/tencent/kona/sun/security/tools/keytool/Resources.java index 34550c4a..864b2365 100644 --- a/kona-pkix/src/main/java/com/tencent/kona/sun/security/tools/keytool/Resources.java +++ b/kona-pkix/src/main/java/com/tencent/kona/sun/security/tools/keytool/Resources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. 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 @@ -307,10 +307,12 @@ public class Resources extends java.util.ListResourceBundle { "Specifying -keysize for generating EC keys is deprecated, please use \"-groupname %s\" instead."}, {"Key.pair.not.generated.alias.alias.already.exists", "Key pair not generated, alias <{0}> already exists"}, - {"Generating.keysize.bit.keyAlgName.key.pair.and.self.signed.certificate.sigAlgName.with.a.validity.of.validality.days.for", - "Generating {0} bit {1} key pair and self-signed certificate ({2}) with a validity of {3} days\n\tfor: {4}"}, - {"Generating.keysize.bit.keyAlgName.key.pair.and.a.certificate.sigAlgName.issued.by.signerAlias.with.a.validity.of.validality.days.for", - "Generating {0} bit {1} key pair and a certificate ({2}) issued by <{3}> with a validity of {4} days\n\tfor: {5}"}, + {"size.bit.alg", + "%1$d-bit %2$s"}, + {"Generating.full.keyAlgName.key.pair.and.self.signed.certificate.sigAlgName.with.a.validity.of.days.for", + "Generating {0} key pair and self-signed certificate ({1}) with a validity of {2} days\n\tfor: {3}"}, + {"Generating.full.keyAlgName.key.pair.and.a.certificate.sigAlgName.issued.by.signerAlias.with.a.validity.of.days.for", + "Generating {0} key pair and a certificate ({1}) issued by <{2}> with a validity of {3} days\n\tfor: {4}"}, {"Enter.key.password.for.alias.", "Enter key password for <{0}>"}, {".RETURN.if.same.as.keystore.password.", "\t(RETURN if same as keystore password): "}, @@ -479,10 +481,9 @@ public class Resources extends java.util.ListResourceBundle { {"alias.in.keystore", "Issuer <%s>"}, {"with.weak", "%s (weak)"}, {"with.disabled", "%s (disabled)"}, - {"key.bit", "%1$d-bit %2$s key"}, - {"key.bit.weak", "%1$d-bit %2$s key (weak)"}, - {"key.bit.disabled", "%1$d-bit %2$s key (disabled)"}, - {"unknown.size.1", "%s key of unknown size"}, + {"key.bit", "%s key"}, + {"key.bit.weak", "%s key (weak)"}, + {"key.bit.disabled", "%s key (disabled)"}, {".PATTERN.printX509Cert.with.weak", "Owner: {0}\nIssuer: {1}\nSerial number: {2}\nValid from: {3} until: {4}\nCertificate fingerprints:\n\t SHA1: {5}\n\t SHA256: {6}\nSignature algorithm name: {7}\nSubject Public Key Algorithm: {8}\nVersion: {9}"}, {"PKCS.10.with.weak", @@ -493,7 +494,7 @@ public class Resources extends java.util.ListResourceBundle { {"whose.sigalg.usagesignedjar", "%1$s uses the %2$s signature algorithm which is considered a security risk and cannot be used to sign JARs after %3$s."}, {"Unable.to.parse.denyAfter.string.in.exception.message", "Unable to parse denyAfter date string in exception message"}, {"whose.sigalg.weak", "%1$s uses the %2$s signature algorithm which is considered a security risk."}, - {"whose.key.disabled", "%1$s uses a %2$s which is considered a security risk and is disabled."}, + {"whose.key.weak", "%1$s uses a %2$s which is considered a security risk. It will be disabled in a future update."}, {"whose.key.weak", "%1$s uses a %2$s which is considered a security risk. This key size will be disabled in a future update."}, {"jks.storetype.warning", "The %1$s keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using \"keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12\"."}, {"migrate.keystore.warning", "Migrated \"%1$s\" to %4$s. The %2$s keystore is backed up as \"%3$s\"."}, diff --git a/kona-pkix/src/main/java/com/tencent/kona/sun/security/util/KeyUtil.java b/kona-pkix/src/main/java/com/tencent/kona/sun/security/util/KeyUtil.java index c9729279..4fc7ce16 100644 --- a/kona-pkix/src/main/java/com/tencent/kona/sun/security/util/KeyUtil.java +++ b/kona-pkix/src/main/java/com/tencent/kona/sun/security/util/KeyUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. 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 @@ -167,26 +167,6 @@ public static final int getKeySize(AlgorithmParameters parameters) { return -1; } - /** - * Returns the algorithm name of the given key object. If an EC key is - * specified, returns the algorithm name and its named curve. - * - * @param key the key object, cannot be null - * @return the algorithm name of the given key object, or return in the - * form of "EC (named curve)" if the given key object is an EC key - */ - public static final String fullDisplayAlgName(Key key) { - String result = key.getAlgorithm(); - if (key instanceof ECKey) { - ECParameterSpec paramSpec = ((ECKey) key).getParams(); - if (paramSpec instanceof NamedCurve) { - NamedCurve nc = (NamedCurve)paramSpec; - result += " (" + nc.getNameAndAliases()[0] + ")"; - } - } - return result; - } - /** * Returns whether the key is valid or not. *