From f4dc00d4bcef235886ec2f462ebf1b0d8c80f8c1 Mon Sep 17 00:00:00 2001 From: Francisco Ferrari Bihurriet Date: Thu, 18 Sep 2025 16:49:44 +0200 Subject: [PATCH 1/3] Backport bbd5b174c50346152a624317b6bd76ec48f7e551 --- src/bsd/doc/man/jarsigner.1 | 5 + .../sun/security/tools/jarsigner/Main.java | 148 ++++++++++++++++++ .../security/tools/jarsigner/Resources.java | 28 ++++ .../tools/jarsigner/Resources_ja.java | 28 ++++ .../tools/jarsigner/Resources_zh_CN.java | 28 ++++ src/linux/doc/man/ja/jarsigner.1 | 5 + src/linux/doc/man/jarsigner.1 | 5 + src/solaris/doc/sun/man/man1/ja/jarsigner.1 | 5 + src/solaris/doc/sun/man/man1/jarsigner.1 | 5 + .../tools/jarsigner/VerifyJarEntryName.java | 136 ++++++++++++++++ 10 files changed, 393 insertions(+) create mode 100644 test/jdk/sun/security/tools/jarsigner/VerifyJarEntryName.java diff --git a/src/bsd/doc/man/jarsigner.1 b/src/bsd/doc/man/jarsigner.1 index ee57c504487..0a64318c40a 100644 --- a/src/bsd/doc/man/jarsigner.1 +++ b/src/bsd/doc/man/jarsigner.1 @@ -624,6 +624,11 @@ Informational warnings include those that are not errors but regarded as bad pra hasExpiringCert This jar contains entries whose signer certificate will expire within six months\&. .TP +internalInconsistenciesDetected +This jar contains internal inconsistencies detected during verification +that may result in different contents when reading via JarFile +and JarInputStream\&. +.TP noTimestamp This jar contains signatures that does not include a timestamp\&. Without a timestamp, users may not be able to validate this JAR file after the signer certificate\&'s expiration date (\f3YYYY-MM-DD\fR) or after any future revocation date\&. .SH EXAMPLES diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java index f32e299c206..a820937cb9c 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java @@ -27,6 +27,8 @@ import java.io.*; import java.net.UnknownHostException; +import java.nio.file.Files; +import java.nio.file.Path; import java.security.cert.CertPathValidatorException; import java.security.cert.PKIXBuilderParameters; import java.util.*; @@ -217,6 +219,8 @@ public static void main(String args[]) throws Exception { private Throwable chainNotValidatedReason = null; private Throwable tsaChainNotValidatedReason = null; + private List crossChkWarnings = new ArrayList<>(); + PKIXBuilderParameters pkixParameters; Set trustedCerts = new HashSet<>(); @@ -1045,6 +1049,7 @@ void verifyJar(String jarName) } } System.out.println(); + crossCheckEntries(jarName); if (!anySigned) { if (disabledAlgFound) { @@ -1079,6 +1084,143 @@ void verifyJar(String jarName) System.exit(1); } + private void crossCheckEntries(String jarName) throws Exception { + Set locEntries = new HashSet<>(); + + try (JarFile jarFile = new JarFile(jarName); + JarInputStream jis = new JarInputStream( + Files.newInputStream(Path.of(jarName)))) { + + Manifest cenManifest = jarFile.getManifest(); + Manifest locManifest = jis.getManifest(); + compareManifest(cenManifest, locManifest); + + JarEntry locEntry; + while ((locEntry = jis.getNextJarEntry()) != null) { + String entryName = locEntry.getName(); + locEntries.add(entryName); + + JarEntry cenEntry = jarFile.getJarEntry(entryName); + if (cenEntry == null) { + crossChkWarnings.add(String.format(rb.getString( + "entry.1.present.when.reading.jarinputstream.but.missing.via.jarfile"), + entryName)); + continue; + } + + try { + readEntry(jis); + } catch (SecurityException e) { + crossChkWarnings.add(String.format(rb.getString( + "signature.verification.failed.on.entry.1.when.reading.via.jarinputstream"), + entryName)); + continue; + } + + try (InputStream cenInputStream = jarFile.getInputStream(cenEntry)) { + if (cenInputStream == null) { + crossChkWarnings.add(String.format(rb.getString( + "entry.1.present.in.jarfile.but.unreadable"), + entryName)); + continue; + } else { + try { + readEntry(cenInputStream); + } catch (SecurityException e) { + crossChkWarnings.add(String.format(rb.getString( + "signature.verification.failed.on.entry.1.when.reading.via.jarfile"), + entryName)); + continue; + } + } + } + + compareSigners(cenEntry, locEntry); + } + + jarFile.stream() + .map(JarEntry::getName) + .filter(n -> !locEntries.contains(n) && !n.equals(JarFile.MANIFEST_NAME)) + .forEach(n -> crossChkWarnings.add(String.format(rb.getString( + "entry.1.present.when.reading.jarfile.but.missing.via.jarinputstream"), n))); + } + } + + private void readEntry(InputStream is) throws IOException { + is.transferTo(OutputStream.nullOutputStream()); + } + + private void compareManifest(Manifest cenManifest, Manifest locManifest) { + if (cenManifest == null) { + crossChkWarnings.add(rb.getString( + "manifest.missing.when.reading.jarfile")); + return; + } + if (locManifest == null) { + crossChkWarnings.add(rb.getString( + "manifest.missing.when.reading.jarinputstream")); + return; + } + + Attributes cenMainAttrs = cenManifest.getMainAttributes(); + Attributes locMainAttrs = locManifest.getMainAttributes(); + + for (Object key : cenMainAttrs.keySet()) { + Object cenValue = cenMainAttrs.get(key); + Object locValue = locMainAttrs.get(key); + + if (locValue == null) { + crossChkWarnings.add(String.format(rb.getString( + "manifest.attribute.1.present.when.reading.jarfile.but.missing.via.jarinputstream"), + key)); + } else if (!cenValue.equals(locValue)) { + crossChkWarnings.add(String.format(rb.getString( + "manifest.attribute.1.differs.jarfile.value.2.jarinputstream.value.3"), + key, cenValue, locValue)); + } + } + + for (Object key : locMainAttrs.keySet()) { + if (!cenMainAttrs.containsKey(key)) { + crossChkWarnings.add(String.format(rb.getString( + "manifest.attribute.1.present.when.reading.jarinputstream.but.missing.via.jarfile"), + key)); + } + } + } + + private void compareSigners(JarEntry cenEntry, JarEntry locEntry) { + CodeSigner[] cenSigners = cenEntry.getCodeSigners(); + CodeSigner[] locSigners = locEntry.getCodeSigners(); + + boolean cenHasSigners = cenSigners != null; + boolean locHasSigners = locSigners != null; + + if (cenHasSigners && locHasSigners) { + if (!Arrays.equals(cenSigners, locSigners)) { + crossChkWarnings.add(String.format(rb.getString( + "codesigners.different.for.entry.1.when.reading.jarfile.and.jarinputstream"), + cenEntry.getName())); + } + } else if (cenHasSigners) { + crossChkWarnings.add(String.format(rb.getString( + "entry.1.is.signed.in.jarfile.but.is.not.signed.in.jarinputstream"), + cenEntry.getName())); + } else if (locHasSigners) { + crossChkWarnings.add(String.format(rb.getString( + "entry.1.is.signed.in.jarinputstream.but.is.not.signed.in.jarfile"), + locEntry.getName())); + } + } + + private void displayCrossChkWarnings() { + System.out.println(); + // First is a summary warning + System.out.println(rb.getString("jar.contains.internal.inconsistencies.result.in.different.contents.via.jarfile.and.jarinputstream")); + // each warning message with prefix "- " + crossChkWarnings.forEach(warning -> System.out.println("- " + warning)); + } + private void displayMessagesAndResult(boolean isSigning) { String result; List errors = new ArrayList<>(); @@ -1314,6 +1456,9 @@ private void displayMessagesAndResult(boolean isSigning) { System.out.println(rb.getString("Warning.")); warnings.forEach(System.out::println); } + if (!crossChkWarnings.isEmpty()) { + displayCrossChkWarnings(); + } } else { if (!errors.isEmpty() || !warnings.isEmpty()) { System.out.println(); @@ -1321,6 +1466,9 @@ private void displayMessagesAndResult(boolean isSigning) { errors.forEach(System.out::println); warnings.forEach(System.out::println); } + if (!crossChkWarnings.isEmpty()) { + displayCrossChkWarnings(); + } } if (!isSigning && (!errors.isEmpty() || !warnings.isEmpty())) { if (! (verbose != null && showcerts)) { diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java index 6c3d5260bc2..80e81c562a1 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java @@ -324,6 +324,34 @@ public class Resources extends java.util.ListResourceBundle { {"Cannot.find.environment.variable.", "Cannot find environment variable: "}, {"Cannot.find.file.", "Cannot find file: "}, + {"manifest.missing.when.reading.jarfile", + "Manifest is missing when reading via JarFile"}, + {"manifest.missing.when.reading.jarinputstream", + "Manifest is missing when reading via JarInputStream"}, + {"manifest.attribute.1.present.when.reading.jarfile.but.missing.via.jarinputstream", + "Manifest main attribute %s is present when reading via JarFile but missing when reading via JarInputStream"}, + {"manifest.attribute.1.present.when.reading.jarinputstream.but.missing.via.jarfile", + "Manifest main attribute %s is present when reading via JarInputStream but missing when reading via JarFile"}, + {"manifest.attribute.1.differs.jarfile.value.2.jarinputstream.value.3", + "Manifest main attribute %1$s differs: JarFile value = %2$s, JarInputStream value = %3$s"}, + {"entry.1.present.when.reading.jarinputstream.but.missing.via.jarfile", + "Entry %s is present when reading via JarInputStream but missing when reading via JarFile"}, + {"entry.1.present.when.reading.jarfile.but.missing.via.jarinputstream", + "Entry %s is present when reading via JarFile but missing when reading via JarInputStream"}, + {"entry.1.present.in.jarfile.but.unreadable", + "Entry %s is present in JarFile but unreadable"}, + {"codesigners.different.for.entry.1.when.reading.jarfile.and.jarinputstream", + "Code signers are different for entry %s when reading from JarFile and JarInputStream"}, + {"entry.1.is.signed.in.jarfile.but.is.not.signed.in.jarinputstream", + "Entry %s is signed in JarFile but is not signed in JarInputStream"}, + {"entry.1.is.signed.in.jarinputstream.but.is.not.signed.in.jarfile", + "Entry %s is signed in JarInputStream but is not signed in JarFile"}, + {"jar.contains.internal.inconsistencies.result.in.different.contents.via.jarfile.and.jarinputstream", + "This JAR file contains internal inconsistencies that may result in different contents when reading via JarFile and JarInputStream:"}, + {"signature.verification.failed.on.entry.1.when.reading.via.jarinputstream", + "Signature verification failed on entry %s when reading via JarInputStream"}, + {"signature.verification.failed.on.entry.1.when.reading.via.jarfile", + "Signature verification failed on entry %s when reading via JarFile"}, }; /** diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_ja.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_ja.java index f77eae65a48..d24c6de29b2 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_ja.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_ja.java @@ -300,6 +300,34 @@ public class Resources_ja extends java.util.ListResourceBundle { {"Cannot.find.environment.variable.", "\u74B0\u5883\u5909\u6570\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: "}, {"Cannot.find.file.", "\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: "}, + {"manifest.missing.when.reading.jarfile", + "JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304C\u3042\u308A\u307E\u305B\u3093"}, + {"manifest.missing.when.reading.jarinputstream", + "JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304C\u3042\u308A\u307E\u305B\u3093"}, + {"manifest.attribute.1.present.when.reading.jarfile.but.missing.via.jarinputstream", + "\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u306E\u30E1\u30A4\u30F3\u5C5E\u6027%s\u306F\u3001JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306F\u5B58\u5728\u3057\u307E\u3059\u304C\u3001JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u306F\u3042\u308A\u307E\u305B\u3093"}, + {"manifest.attribute.1.present.when.reading.jarinputstream.but.missing.via.jarfile", + "\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u306E\u30E1\u30A4\u30F3\u5C5E\u6027%s\u306F\u3001JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306F\u5B58\u5728\u3057\u307E\u3059\u304C\u3001JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u306F\u3042\u308A\u307E\u305B\u3093"}, + {"manifest.attribute.1.differs.jarfile.value.2.jarinputstream.value.3", + "\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u306E\u30E1\u30A4\u30F3\u5C5E\u6027%1$s\u304C\u7570\u306A\u308A\u307E\u3059: JarFile\u306E\u5024 = %2$s\u3001JarInputStream\u306E\u5024 = %3$s"}, + {"entry.1.present.when.reading.jarinputstream.but.missing.via.jarfile", + "\u30A8\u30F3\u30C8\u30EA%s\u306F\u3001JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306F\u5B58\u5728\u3057\u307E\u3059\u304C\u3001JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u306F\u3042\u308A\u307E\u305B\u3093"}, + {"entry.1.present.when.reading.jarfile.but.missing.via.jarinputstream", + "\u30A8\u30F3\u30C8\u30EA%s\u306F\u3001JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306F\u5B58\u5728\u3057\u307E\u3059\u304C\u3001JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u306F\u3042\u308A\u307E\u305B\u3093"}, + {"entry.1.present.in.jarfile.but.unreadable", + "\u30A8\u30F3\u30C8\u30EA%s\u306FJarFile\u306B\u5B58\u5728\u3057\u307E\u3059\u304C\u8AAD\u307F\u53D6\u308C\u307E\u305B\u3093"}, + {"codesigners.different.for.entry.1.when.reading.jarfile.and.jarinputstream", + "JarFile\u3068JarInputStream\u304B\u3089\u8AAD\u307F\u53D6\u308B\u5834\u5408\u306E\u30A8\u30F3\u30C8\u30EA%s\u306E\u30B3\u30FC\u30C9\u7F72\u540D\u8005\u304C\u7570\u306A\u308A\u307E\u3059"}, + {"entry.1.is.signed.in.jarfile.but.is.not.signed.in.jarinputstream", + "\u30A8\u30F3\u30C8\u30EA%s\u306F\u3001JarFile\u3067\u306F\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001JarInputStream\u3067\u306F\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u305B\u3093"}, + {"entry.1.is.signed.in.jarinputstream.but.is.not.signed.in.jarfile", + "\u30A8\u30F3\u30C8\u30EA%s\u306F\u3001JarInputStream\u3067\u306F\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001JarFile\u3067\u306F\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u305B\u3093"}, + {"jar.contains.internal.inconsistencies.result.in.different.contents.via.jarfile.and.jarinputstream", + "\u3053\u306EJAR\u30D5\u30A1\u30A4\u30EB\u306B\u306F\u5185\u90E8\u7684\u306A\u4E0D\u6574\u5408\u304C\u3042\u308B\u305F\u3081\u3001JarFile\u3068JarInputStream\u304B\u3089\u8AAD\u307F\u53D6\u308B\u5834\u5408\u306B\u30B3\u30F3\u30C6\u30F3\u30C4\u304C\u7570\u306A\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059:"}, + {"signature.verification.failed.on.entry.1.when.reading.via.jarinputstream", + "JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u7F72\u540D\u691C\u8A3C\u304C\u30A8\u30F3\u30C8\u30EA%s\u3067\u5931\u6557\u3057\u307E\u3057\u305F"}, + {"signature.verification.failed.on.entry.1.when.reading.via.jarfile", + "JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u7F72\u540D\u691C\u8A3C\u304C\u30A8\u30F3\u30C8\u30EA%s\u3067\u5931\u6557\u3057\u307E\u3057\u305F"}, }; /** diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java index 91d80b17e1f..66de6e62d68 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java @@ -300,6 +300,34 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Cannot.find.environment.variable.", "\u627E\u4E0D\u5230\u73AF\u5883\u53D8\u91CF: "}, {"Cannot.find.file.", "\u627E\u4E0D\u5230\u6587\u4EF6: "}, + {"manifest.missing.when.reading.jarfile", + "\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\u7F3A\u5C11\u6E05\u5355"}, + {"manifest.missing.when.reading.jarinputstream", + "\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\u7F3A\u5C11\u6E05\u5355"}, + {"manifest.attribute.1.present.when.reading.jarfile.but.missing.via.jarinputstream", + "\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\uFF0C\u6E05\u5355\u4E3B\u5C5E\u6027 %s \u5B58\u5728\uFF0C\u4F46\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\u7F3A\u5931"}, + {"manifest.attribute.1.present.when.reading.jarinputstream.but.missing.via.jarfile", + "\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\uFF0C\u6E05\u5355\u4E3B\u5C5E\u6027 %s \u5B58\u5728\uFF0C\u4F46\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\u7F3A\u5931"}, + {"manifest.attribute.1.differs.jarfile.value.2.jarinputstream.value.3", + "\u6E05\u5355\u4E3B\u5C5E\u6027 %1$s \u4E0D\u540C\uFF1AJarFile \u503C = %2$s\uFF0CJarInputStream \u503C = %3$s"}, + {"entry.1.present.when.reading.jarinputstream.but.missing.via.jarfile", + "\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\uFF0C\u6761\u76EE %s \u5B58\u5728\uFF0C\u4F46\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\u7F3A\u5931"}, + {"entry.1.present.when.reading.jarfile.but.missing.via.jarinputstream", + "\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\uFF0C\u6761\u76EE %s \u5B58\u5728\uFF0C\u4F46\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\u7F3A\u5931"}, + {"entry.1.present.in.jarfile.but.unreadable", + "\u6761\u76EE %s \u5B58\u5728\u4E8E JarFile \u4E2D\uFF0C\u4F46\u65E0\u6CD5\u8BFB\u53D6"}, + {"codesigners.different.for.entry.1.when.reading.jarfile.and.jarinputstream", + "\u4ECE JarFile \u548C JarInputStream \u8BFB\u53D6\u65F6\uFF0C\u6761\u76EE %s \u7684\u4EE3\u7801\u7B7E\u540D\u8005\u4E0D\u540C"}, + {"entry.1.is.signed.in.jarfile.but.is.not.signed.in.jarinputstream", + "\u6761\u76EE %s \u5DF2\u5728 JarFile \u4E2D\u7B7E\u540D\uFF0C\u4F46\u672A\u5728 JarInputStream \u4E2D\u7B7E\u540D"}, + {"entry.1.is.signed.in.jarinputstream.but.is.not.signed.in.jarfile", + "\u6761\u76EE %s \u5DF2\u5728 JarInputStream \u4E2D\u7B7E\u540D\uFF0C\u4F46\u672A\u5728 JarFile \u4E2D\u7B7E\u540D"}, + {"jar.contains.internal.inconsistencies.result.in.different.contents.via.jarfile.and.jarinputstream", + "\u6B64 JAR \u6587\u4EF6\u5305\u542B\u5185\u90E8\u4E0D\u4E00\u81F4\uFF0C\u901A\u8FC7 JarFile \u548C JarInputStream \u8BFB\u53D6\u65F6\u53EF\u80FD\u4F1A\u5BFC\u81F4\u5185\u5BB9\u4E0D\u540C\uFF1A"}, + {"signature.verification.failed.on.entry.1.when.reading.via.jarinputstream", + "\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\uFF0C\u6761\u76EE %s \u7684\u7B7E\u540D\u9A8C\u8BC1\u5931\u8D25"}, + {"signature.verification.failed.on.entry.1.when.reading.via.jarfile", + "\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\uFF0C\u6761\u76EE %s \u7684\u7B7E\u540D\u9A8C\u8BC1\u5931\u8D25"}, }; /** diff --git a/src/linux/doc/man/ja/jarsigner.1 b/src/linux/doc/man/ja/jarsigner.1 index b23fb5b8bad..5cc11dc23df 100644 --- a/src/linux/doc/man/ja/jarsigner.1 +++ b/src/linux/doc/man/ja/jarsigner.1 @@ -922,6 +922,11 @@ hasExpiringCert このjarには、署名者証明書が6か月以内に期限切れとなるエントリが含まれています。 .RE .PP +internalInconsistenciesDetected +.RS 4 +このjarには検証中に検出された内部的な不整合があるため、JarFileとJarInputStreamから読み取る場合にコンテンツが異なる可能性があります。 +.RE +.PP noTimestamp .RS 4 このjarには、タイムスタンプを含まない署名が含まれています。タイムスタンプなしでは、署名者証明書の有効期限(\fBYYYY\-MM\-DD\fR)後または将来の取消日後、ユーザーはこのJARファイルを検証できない場合があります。 diff --git a/src/linux/doc/man/jarsigner.1 b/src/linux/doc/man/jarsigner.1 index ee57c504487..0a64318c40a 100644 --- a/src/linux/doc/man/jarsigner.1 +++ b/src/linux/doc/man/jarsigner.1 @@ -624,6 +624,11 @@ Informational warnings include those that are not errors but regarded as bad pra hasExpiringCert This jar contains entries whose signer certificate will expire within six months\&. .TP +internalInconsistenciesDetected +This jar contains internal inconsistencies detected during verification +that may result in different contents when reading via JarFile +and JarInputStream\&. +.TP noTimestamp This jar contains signatures that does not include a timestamp\&. Without a timestamp, users may not be able to validate this JAR file after the signer certificate\&'s expiration date (\f3YYYY-MM-DD\fR) or after any future revocation date\&. .SH EXAMPLES diff --git a/src/solaris/doc/sun/man/man1/ja/jarsigner.1 b/src/solaris/doc/sun/man/man1/ja/jarsigner.1 index b23fb5b8bad..5cc11dc23df 100644 --- a/src/solaris/doc/sun/man/man1/ja/jarsigner.1 +++ b/src/solaris/doc/sun/man/man1/ja/jarsigner.1 @@ -922,6 +922,11 @@ hasExpiringCert このjarには、署名者証明書が6か月以内に期限切れとなるエントリが含まれています。 .RE .PP +internalInconsistenciesDetected +.RS 4 +このjarには検証中に検出された内部的な不整合があるため、JarFileとJarInputStreamから読み取る場合にコンテンツが異なる可能性があります。 +.RE +.PP noTimestamp .RS 4 このjarには、タイムスタンプを含まない署名が含まれています。タイムスタンプなしでは、署名者証明書の有効期限(\fBYYYY\-MM\-DD\fR)後または将来の取消日後、ユーザーはこのJARファイルを検証できない場合があります。 diff --git a/src/solaris/doc/sun/man/man1/jarsigner.1 b/src/solaris/doc/sun/man/man1/jarsigner.1 index ee57c504487..0a64318c40a 100644 --- a/src/solaris/doc/sun/man/man1/jarsigner.1 +++ b/src/solaris/doc/sun/man/man1/jarsigner.1 @@ -624,6 +624,11 @@ Informational warnings include those that are not errors but regarded as bad pra hasExpiringCert This jar contains entries whose signer certificate will expire within six months\&. .TP +internalInconsistenciesDetected +This jar contains internal inconsistencies detected during verification +that may result in different contents when reading via JarFile +and JarInputStream\&. +.TP noTimestamp This jar contains signatures that does not include a timestamp\&. Without a timestamp, users may not be able to validate this JAR file after the signer certificate\&'s expiration date (\f3YYYY-MM-DD\fR) or after any future revocation date\&. .SH EXAMPLES diff --git a/test/jdk/sun/security/tools/jarsigner/VerifyJarEntryName.java b/test/jdk/sun/security/tools/jarsigner/VerifyJarEntryName.java new file mode 100644 index 00000000000..faa3ab7b897 --- /dev/null +++ b/test/jdk/sun/security/tools/jarsigner/VerifyJarEntryName.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 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 + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8339280 + * @summary Test that jarsigner -verify emits a warning when the filename of + * an entry in the LOC is changed + * @library /test/lib + * @run junit VerifyJarEntryName + */ + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.FileOutputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import jdk.test.lib.SecurityTools; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class VerifyJarEntryName { + + private static final Path ORIGINAL_JAR = Path.of("test.jar"); + private static final Path MODIFIED_JAR = Path.of("modified_test.jar"); + + @BeforeAll + static void setup() throws Exception { + try (FileOutputStream fos = new FileOutputStream(ORIGINAL_JAR.toFile()); + ZipOutputStream zos = new ZipOutputStream(fos)) { + zos.putNextEntry(new ZipEntry(JarFile.MANIFEST_NAME)); + zos.write("Manifest-Version: 1.0\nCreated-By: Test\n". + getBytes(StandardCharsets.UTF_8)); + zos.closeEntry(); + + // Add hello.txt file + ZipEntry textEntry = new ZipEntry("hello.txt"); + zos.putNextEntry(textEntry); + zos.write("hello".getBytes(StandardCharsets.UTF_8)); + zos.closeEntry(); + } + + SecurityTools.keytool("-genkeypair -keystore ks -storepass changeit " + + "-alias mykey -keyalg rsa -dname CN=me "); + + SecurityTools.jarsigner("-keystore ks -storepass changeit " + + ORIGINAL_JAR + " mykey") + .shouldHaveExitValue(0); + } + + @BeforeEach + void cleanup() throws Exception { + Files.deleteIfExists(MODIFIED_JAR); + } + + /* + * Modify a single byte in "MANIFEST.MF" filename in LOC, and + * validate that jarsigner -verify emits a warning message. + */ + @Test + void verifyManifestEntryName() throws Exception { + modifyJarEntryName(ORIGINAL_JAR, MODIFIED_JAR, "MANIFEST.MF"); + SecurityTools.jarsigner("-verify -verbose " + MODIFIED_JAR) + .shouldContain("This JAR file contains internal " + + "inconsistencies that may result in different " + + "contents when reading via JarFile and JarInputStream:") + .shouldContain("- Manifest is missing when " + + "reading via JarInputStream") + .shouldHaveExitValue(0); + } + + /* + * Modify a single byte in signature filename in LOC, and + * validate that jarsigner -verify emits a warning message. + */ + @Test + void verifySignatureEntryName() throws Exception { + modifyJarEntryName(ORIGINAL_JAR, MODIFIED_JAR, "MYKEY.SF"); + SecurityTools.jarsigner("-verify -verbose " + MODIFIED_JAR) + .shouldContain("This JAR file contains internal " + + "inconsistencies that may result in different " + + "contents when reading via JarFile and JarInputStream:") + .shouldContain("- Entry XETA-INF/MYKEY.SF is present when reading " + + "via JarInputStream but missing when reading via JarFile") + .shouldHaveExitValue(0); + } + + /* + * Validate that jarsigner -verify on a valid JAR works without + * emitting warnings about internal inconsistencies. + */ + @Test + void verifyOriginalJar() throws Exception { + SecurityTools.jarsigner("-verify -verbose " + ORIGINAL_JAR) + .shouldNotContain("This JAR file contains internal " + + "inconsistencies that may result in different contents when " + + "reading via JarFile and JarInputStream:") + .shouldHaveExitValue(0); + } + + private void modifyJarEntryName(Path origJar, Path modifiedJar, + String entryName) throws Exception { + byte[] jarBytes = Files.readAllBytes(origJar); + var jarString = new String(jarBytes, StandardCharsets.UTF_8); + var pos = jarString.indexOf(entryName); + assertTrue(pos != -1, entryName + " is not present in the JAR"); + jarBytes[pos] = 'X'; + Files.write(modifiedJar, jarBytes); + } +} From 4d0f781bf41a3c10dd9966193e4b1c832a055ad3 Mon Sep 17 00:00:00 2001 From: Francisco Ferrari Bihurriet Date: Thu, 18 Sep 2025 16:50:43 +0200 Subject: [PATCH 2/3] Backport 8353299 & 8367782 --- .../tools/jarsigner/VerifyJarEntryName.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/test/jdk/sun/security/tools/jarsigner/VerifyJarEntryName.java b/test/jdk/sun/security/tools/jarsigner/VerifyJarEntryName.java index faa3ab7b897..e2554ee0f91 100644 --- a/test/jdk/sun/security/tools/jarsigner/VerifyJarEntryName.java +++ b/test/jdk/sun/security/tools/jarsigner/VerifyJarEntryName.java @@ -38,12 +38,13 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import java.util.jar.JarFile; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import jdk.test.lib.SecurityTools; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; public class VerifyJarEntryName { @@ -85,7 +86,7 @@ void cleanup() throws Exception { */ @Test void verifyManifestEntryName() throws Exception { - modifyJarEntryName(ORIGINAL_JAR, MODIFIED_JAR, "MANIFEST.MF"); + modifyJarEntryName(ORIGINAL_JAR, MODIFIED_JAR, "META-INF/MANIFEST.MF"); SecurityTools.jarsigner("-verify -verbose " + MODIFIED_JAR) .shouldContain("This JAR file contains internal " + "inconsistencies that may result in different " + @@ -101,7 +102,7 @@ void verifyManifestEntryName() throws Exception { */ @Test void verifySignatureEntryName() throws Exception { - modifyJarEntryName(ORIGINAL_JAR, MODIFIED_JAR, "MYKEY.SF"); + modifyJarEntryName(ORIGINAL_JAR, MODIFIED_JAR, "META-INF/MYKEY.SF"); SecurityTools.jarsigner("-verify -verbose " + MODIFIED_JAR) .shouldContain("This JAR file contains internal " + "inconsistencies that may result in different " + @@ -127,9 +128,14 @@ void verifyOriginalJar() throws Exception { private void modifyJarEntryName(Path origJar, Path modifiedJar, String entryName) throws Exception { byte[] jarBytes = Files.readAllBytes(origJar); - var jarString = new String(jarBytes, StandardCharsets.UTF_8); - var pos = jarString.indexOf(entryName); - assertTrue(pos != -1, entryName + " is not present in the JAR"); + byte[] entryNameBytes = entryName.getBytes(StandardCharsets.UTF_8); + int pos = 0; + try { + while (!Arrays.equals(jarBytes, pos, pos + entryNameBytes.length, + entryNameBytes, 0, entryNameBytes.length)) pos++; + } catch (ArrayIndexOutOfBoundsException ignore) { + fail(entryName + " is not present in the JAR"); + } jarBytes[pos] = 'X'; Files.write(modifiedJar, jarBytes); } From 191d5cad9c8c0d452c0571c669e06b375b9f578a Mon Sep 17 00:00:00 2001 From: Francisco Ferrari Bihurriet Date: Fri, 19 Sep 2025 20:40:08 +0200 Subject: [PATCH 3/3] Remove internationalized messages --- .../tools/jarsigner/Resources_ja.java | 28 ------------------- .../tools/jarsigner/Resources_zh_CN.java | 28 ------------------- src/linux/doc/man/ja/jarsigner.1 | 5 ---- src/solaris/doc/sun/man/man1/ja/jarsigner.1 | 5 ---- 4 files changed, 66 deletions(-) diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_ja.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_ja.java index d24c6de29b2..f77eae65a48 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_ja.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_ja.java @@ -300,34 +300,6 @@ public class Resources_ja extends java.util.ListResourceBundle { {"Cannot.find.environment.variable.", "\u74B0\u5883\u5909\u6570\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: "}, {"Cannot.find.file.", "\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: "}, - {"manifest.missing.when.reading.jarfile", - "JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304C\u3042\u308A\u307E\u305B\u3093"}, - {"manifest.missing.when.reading.jarinputstream", - "JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304C\u3042\u308A\u307E\u305B\u3093"}, - {"manifest.attribute.1.present.when.reading.jarfile.but.missing.via.jarinputstream", - "\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u306E\u30E1\u30A4\u30F3\u5C5E\u6027%s\u306F\u3001JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306F\u5B58\u5728\u3057\u307E\u3059\u304C\u3001JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u306F\u3042\u308A\u307E\u305B\u3093"}, - {"manifest.attribute.1.present.when.reading.jarinputstream.but.missing.via.jarfile", - "\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u306E\u30E1\u30A4\u30F3\u5C5E\u6027%s\u306F\u3001JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306F\u5B58\u5728\u3057\u307E\u3059\u304C\u3001JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u306F\u3042\u308A\u307E\u305B\u3093"}, - {"manifest.attribute.1.differs.jarfile.value.2.jarinputstream.value.3", - "\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u306E\u30E1\u30A4\u30F3\u5C5E\u6027%1$s\u304C\u7570\u306A\u308A\u307E\u3059: JarFile\u306E\u5024 = %2$s\u3001JarInputStream\u306E\u5024 = %3$s"}, - {"entry.1.present.when.reading.jarinputstream.but.missing.via.jarfile", - "\u30A8\u30F3\u30C8\u30EA%s\u306F\u3001JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306F\u5B58\u5728\u3057\u307E\u3059\u304C\u3001JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u306F\u3042\u308A\u307E\u305B\u3093"}, - {"entry.1.present.when.reading.jarfile.but.missing.via.jarinputstream", - "\u30A8\u30F3\u30C8\u30EA%s\u306F\u3001JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306F\u5B58\u5728\u3057\u307E\u3059\u304C\u3001JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u306F\u3042\u308A\u307E\u305B\u3093"}, - {"entry.1.present.in.jarfile.but.unreadable", - "\u30A8\u30F3\u30C8\u30EA%s\u306FJarFile\u306B\u5B58\u5728\u3057\u307E\u3059\u304C\u8AAD\u307F\u53D6\u308C\u307E\u305B\u3093"}, - {"codesigners.different.for.entry.1.when.reading.jarfile.and.jarinputstream", - "JarFile\u3068JarInputStream\u304B\u3089\u8AAD\u307F\u53D6\u308B\u5834\u5408\u306E\u30A8\u30F3\u30C8\u30EA%s\u306E\u30B3\u30FC\u30C9\u7F72\u540D\u8005\u304C\u7570\u306A\u308A\u307E\u3059"}, - {"entry.1.is.signed.in.jarfile.but.is.not.signed.in.jarinputstream", - "\u30A8\u30F3\u30C8\u30EA%s\u306F\u3001JarFile\u3067\u306F\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001JarInputStream\u3067\u306F\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u305B\u3093"}, - {"entry.1.is.signed.in.jarinputstream.but.is.not.signed.in.jarfile", - "\u30A8\u30F3\u30C8\u30EA%s\u306F\u3001JarInputStream\u3067\u306F\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001JarFile\u3067\u306F\u7F72\u540D\u3055\u308C\u3066\u3044\u307E\u305B\u3093"}, - {"jar.contains.internal.inconsistencies.result.in.different.contents.via.jarfile.and.jarinputstream", - "\u3053\u306EJAR\u30D5\u30A1\u30A4\u30EB\u306B\u306F\u5185\u90E8\u7684\u306A\u4E0D\u6574\u5408\u304C\u3042\u308B\u305F\u3081\u3001JarFile\u3068JarInputStream\u304B\u3089\u8AAD\u307F\u53D6\u308B\u5834\u5408\u306B\u30B3\u30F3\u30C6\u30F3\u30C4\u304C\u7570\u306A\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059:"}, - {"signature.verification.failed.on.entry.1.when.reading.via.jarinputstream", - "JarInputStream\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u7F72\u540D\u691C\u8A3C\u304C\u30A8\u30F3\u30C8\u30EA%s\u3067\u5931\u6557\u3057\u307E\u3057\u305F"}, - {"signature.verification.failed.on.entry.1.when.reading.via.jarfile", - "JarFile\u3092\u4ECB\u3057\u3066\u8AAD\u307F\u53D6\u308B\u3068\u304D\u306B\u7F72\u540D\u691C\u8A3C\u304C\u30A8\u30F3\u30C8\u30EA%s\u3067\u5931\u6557\u3057\u307E\u3057\u305F"}, }; /** diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java index 66de6e62d68..91d80b17e1f 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java @@ -300,34 +300,6 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Cannot.find.environment.variable.", "\u627E\u4E0D\u5230\u73AF\u5883\u53D8\u91CF: "}, {"Cannot.find.file.", "\u627E\u4E0D\u5230\u6587\u4EF6: "}, - {"manifest.missing.when.reading.jarfile", - "\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\u7F3A\u5C11\u6E05\u5355"}, - {"manifest.missing.when.reading.jarinputstream", - "\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\u7F3A\u5C11\u6E05\u5355"}, - {"manifest.attribute.1.present.when.reading.jarfile.but.missing.via.jarinputstream", - "\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\uFF0C\u6E05\u5355\u4E3B\u5C5E\u6027 %s \u5B58\u5728\uFF0C\u4F46\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\u7F3A\u5931"}, - {"manifest.attribute.1.present.when.reading.jarinputstream.but.missing.via.jarfile", - "\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\uFF0C\u6E05\u5355\u4E3B\u5C5E\u6027 %s \u5B58\u5728\uFF0C\u4F46\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\u7F3A\u5931"}, - {"manifest.attribute.1.differs.jarfile.value.2.jarinputstream.value.3", - "\u6E05\u5355\u4E3B\u5C5E\u6027 %1$s \u4E0D\u540C\uFF1AJarFile \u503C = %2$s\uFF0CJarInputStream \u503C = %3$s"}, - {"entry.1.present.when.reading.jarinputstream.but.missing.via.jarfile", - "\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\uFF0C\u6761\u76EE %s \u5B58\u5728\uFF0C\u4F46\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\u7F3A\u5931"}, - {"entry.1.present.when.reading.jarfile.but.missing.via.jarinputstream", - "\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\uFF0C\u6761\u76EE %s \u5B58\u5728\uFF0C\u4F46\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\u7F3A\u5931"}, - {"entry.1.present.in.jarfile.but.unreadable", - "\u6761\u76EE %s \u5B58\u5728\u4E8E JarFile \u4E2D\uFF0C\u4F46\u65E0\u6CD5\u8BFB\u53D6"}, - {"codesigners.different.for.entry.1.when.reading.jarfile.and.jarinputstream", - "\u4ECE JarFile \u548C JarInputStream \u8BFB\u53D6\u65F6\uFF0C\u6761\u76EE %s \u7684\u4EE3\u7801\u7B7E\u540D\u8005\u4E0D\u540C"}, - {"entry.1.is.signed.in.jarfile.but.is.not.signed.in.jarinputstream", - "\u6761\u76EE %s \u5DF2\u5728 JarFile \u4E2D\u7B7E\u540D\uFF0C\u4F46\u672A\u5728 JarInputStream \u4E2D\u7B7E\u540D"}, - {"entry.1.is.signed.in.jarinputstream.but.is.not.signed.in.jarfile", - "\u6761\u76EE %s \u5DF2\u5728 JarInputStream \u4E2D\u7B7E\u540D\uFF0C\u4F46\u672A\u5728 JarFile \u4E2D\u7B7E\u540D"}, - {"jar.contains.internal.inconsistencies.result.in.different.contents.via.jarfile.and.jarinputstream", - "\u6B64 JAR \u6587\u4EF6\u5305\u542B\u5185\u90E8\u4E0D\u4E00\u81F4\uFF0C\u901A\u8FC7 JarFile \u548C JarInputStream \u8BFB\u53D6\u65F6\u53EF\u80FD\u4F1A\u5BFC\u81F4\u5185\u5BB9\u4E0D\u540C\uFF1A"}, - {"signature.verification.failed.on.entry.1.when.reading.via.jarinputstream", - "\u901A\u8FC7 JarInputStream \u8BFB\u53D6\u65F6\uFF0C\u6761\u76EE %s \u7684\u7B7E\u540D\u9A8C\u8BC1\u5931\u8D25"}, - {"signature.verification.failed.on.entry.1.when.reading.via.jarfile", - "\u901A\u8FC7 JarFile \u8BFB\u53D6\u65F6\uFF0C\u6761\u76EE %s \u7684\u7B7E\u540D\u9A8C\u8BC1\u5931\u8D25"}, }; /** diff --git a/src/linux/doc/man/ja/jarsigner.1 b/src/linux/doc/man/ja/jarsigner.1 index 5cc11dc23df..b23fb5b8bad 100644 --- a/src/linux/doc/man/ja/jarsigner.1 +++ b/src/linux/doc/man/ja/jarsigner.1 @@ -922,11 +922,6 @@ hasExpiringCert このjarには、署名者証明書が6か月以内に期限切れとなるエントリが含まれています。 .RE .PP -internalInconsistenciesDetected -.RS 4 -このjarには検証中に検出された内部的な不整合があるため、JarFileとJarInputStreamから読み取る場合にコンテンツが異なる可能性があります。 -.RE -.PP noTimestamp .RS 4 このjarには、タイムスタンプを含まない署名が含まれています。タイムスタンプなしでは、署名者証明書の有効期限(\fBYYYY\-MM\-DD\fR)後または将来の取消日後、ユーザーはこのJARファイルを検証できない場合があります。 diff --git a/src/solaris/doc/sun/man/man1/ja/jarsigner.1 b/src/solaris/doc/sun/man/man1/ja/jarsigner.1 index 5cc11dc23df..b23fb5b8bad 100644 --- a/src/solaris/doc/sun/man/man1/ja/jarsigner.1 +++ b/src/solaris/doc/sun/man/man1/ja/jarsigner.1 @@ -922,11 +922,6 @@ hasExpiringCert このjarには、署名者証明書が6か月以内に期限切れとなるエントリが含まれています。 .RE .PP -internalInconsistenciesDetected -.RS 4 -このjarには検証中に検出された内部的な不整合があるため、JarFileとJarInputStreamから読み取る場合にコンテンツが異なる可能性があります。 -.RE -.PP noTimestamp .RS 4 このjarには、タイムスタンプを含まない署名が含まれています。タイムスタンプなしでは、署名者証明書の有効期限(\fBYYYY\-MM\-DD\fR)後または将来の取消日後、ユーザーはこのJARファイルを検証できない場合があります。