8303410: Remove ContentSigner APIs and jarsigner -altsigner and -altsignerpath options
Reviewed-by: weijun
This commit is contained in:
parent
0cc0f063e2
commit
31680b2bcf
src/jdk.jartool/share/classes
test/jdk
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015, 2020, 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. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.sun.jarsigner;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class defines a content signing service.
|
|
||||||
* Implementations must be instantiable using a zero-argument constructor.
|
|
||||||
*
|
|
||||||
* @since 1.5
|
|
||||||
* @author Vincent Ryan
|
|
||||||
* @deprecated This class has been deprecated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Deprecated(since="9", forRemoval=true)
|
|
||||||
public abstract class ContentSigner {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a PKCS #7 signed data message.
|
|
||||||
* This method is used when the signature has already been generated.
|
|
||||||
* The signature, the signer's details, and optionally a signature
|
|
||||||
* timestamp and the content that was signed, are all packaged into a
|
|
||||||
* signed data message.
|
|
||||||
*
|
|
||||||
* @param parameters The non-null input parameters.
|
|
||||||
* @param omitContent true if the content should be omitted from the
|
|
||||||
* signed data message. Otherwise the content is included.
|
|
||||||
* @param applyTimestamp true if the signature should be timestamped.
|
|
||||||
* Otherwise timestamping is not performed.
|
|
||||||
* @return A PKCS #7 signed data message.
|
|
||||||
* @throws NoSuchAlgorithmException The exception is thrown if the signature
|
|
||||||
* algorithm is unrecognised.
|
|
||||||
* @throws CertificateException The exception is thrown if an error occurs
|
|
||||||
* while processing the signer's certificate or the TSA's
|
|
||||||
* certificate.
|
|
||||||
* @throws IOException The exception is thrown if an error occurs while
|
|
||||||
* generating the signature timestamp or while generating the signed
|
|
||||||
* data message.
|
|
||||||
* @throws NullPointerException The exception is thrown if parameters is
|
|
||||||
* null.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
public abstract byte[] generateSignedData(
|
|
||||||
ContentSignerParameters parameters, boolean omitContent,
|
|
||||||
boolean applyTimestamp)
|
|
||||||
throws NoSuchAlgorithmException, CertificateException, IOException;
|
|
||||||
}
|
|
@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2003, 2020, 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. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.sun.jarsigner;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.zip.ZipFile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface encapsulates the parameters for a ContentSigner object.
|
|
||||||
*
|
|
||||||
* @since 1.5
|
|
||||||
* @author Vincent Ryan
|
|
||||||
* @deprecated This class has been deprecated.
|
|
||||||
*/
|
|
||||||
@Deprecated(since="9", forRemoval=true)
|
|
||||||
public interface ContentSignerParameters {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the command-line arguments passed to the jarsigner tool.
|
|
||||||
*
|
|
||||||
* @return The command-line arguments. May be null.
|
|
||||||
*/
|
|
||||||
public String[] getCommandLine();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the identifier for a Timestamping Authority (TSA).
|
|
||||||
*
|
|
||||||
* @return The TSA identifier. May be null.
|
|
||||||
*/
|
|
||||||
public URI getTimestampingAuthority();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the certificate for a Timestamping Authority (TSA).
|
|
||||||
*
|
|
||||||
* @return The TSA certificate. May be null.
|
|
||||||
*/
|
|
||||||
public X509Certificate getTimestampingAuthorityCertificate();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the TSAPolicyID for a Timestamping Authority (TSA).
|
|
||||||
*
|
|
||||||
* @return The TSAPolicyID. May be null.
|
|
||||||
*/
|
|
||||||
public default String getTSAPolicyID() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retreives the message digest algorithm that is used to generate
|
|
||||||
* the message imprint to be sent to the TSA server.
|
|
||||||
*
|
|
||||||
* @since 9
|
|
||||||
* @return The non-null string of the message digest algorithm name.
|
|
||||||
*/
|
|
||||||
public default String getTSADigestAlg() {
|
|
||||||
return "SHA-256";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the JAR file's signature.
|
|
||||||
*
|
|
||||||
* @return The non-null array of signature bytes.
|
|
||||||
*/
|
|
||||||
public byte[] getSignature();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the name of the signature algorithm.
|
|
||||||
*
|
|
||||||
* @return The non-null string name of the signature algorithm.
|
|
||||||
*/
|
|
||||||
public String getSignatureAlgorithm();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the signer's X.509 certificate chain.
|
|
||||||
*
|
|
||||||
* @return The non-null array of X.509 public-key certificates.
|
|
||||||
*/
|
|
||||||
public X509Certificate[] getSignerCertificateChain();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the content that was signed.
|
|
||||||
* The content is the JAR file's signature file.
|
|
||||||
*
|
|
||||||
* @return The content bytes. May be null.
|
|
||||||
*/
|
|
||||||
public byte[] getContent();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the original source ZIP file before it was signed.
|
|
||||||
*
|
|
||||||
* @return The original ZIP file. May be null.
|
|
||||||
*/
|
|
||||||
public ZipFile getSource();
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015, 2020, 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. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This package comprises the interfaces and classes used to define the
|
|
||||||
* signing mechanism used by the {@code jarsigner} tool.
|
|
||||||
* <p>
|
|
||||||
* Clients may override the default signing mechanism of the {@code jarsigner}
|
|
||||||
* tool by supplying an alternative implementation of
|
|
||||||
* {@link com.sun.jarsigner.ContentSigner}.
|
|
||||||
*
|
|
||||||
* The classes in this package have been deprecated and will be removed in
|
|
||||||
* a future release. New classes should not be added to this package.
|
|
||||||
* Use the {@link jdk.security.jarsigner.JarSigner} API to sign JAR files.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.sun.jarsigner;
|
|
@ -25,8 +25,6 @@
|
|||||||
|
|
||||||
package jdk.security.jarsigner;
|
package jdk.security.jarsigner;
|
||||||
|
|
||||||
import com.sun.jarsigner.ContentSigner;
|
|
||||||
import com.sun.jarsigner.ContentSignerParameters;
|
|
||||||
import jdk.internal.access.JavaUtilZipFileAccess;
|
import jdk.internal.access.JavaUtilZipFileAccess;
|
||||||
import jdk.internal.access.SharedSecrets;
|
import jdk.internal.access.SharedSecrets;
|
||||||
import sun.security.pkcs.PKCS7;
|
import sun.security.pkcs.PKCS7;
|
||||||
@ -123,8 +121,6 @@ public final class JarSigner {
|
|||||||
String tSADigestAlg;
|
String tSADigestAlg;
|
||||||
boolean sectionsonly = false;
|
boolean sectionsonly = false;
|
||||||
boolean internalsf = false;
|
boolean internalsf = false;
|
||||||
String altSignerPath;
|
|
||||||
String altSigner;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code JarSigner.Builder} object with
|
* Creates a {@code JarSigner.Builder} object with
|
||||||
@ -391,12 +387,6 @@ public final class JarSigner {
|
|||||||
case "sectionsonly":
|
case "sectionsonly":
|
||||||
this.sectionsonly = parseBoolean("sectionsonly", value);
|
this.sectionsonly = parseBoolean("sectionsonly", value);
|
||||||
break;
|
break;
|
||||||
case "altsignerpath":
|
|
||||||
altSignerPath = value;
|
|
||||||
break;
|
|
||||||
case "altsigner":
|
|
||||||
altSigner = value;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
"Unsupported key " + key);
|
"Unsupported key " + key);
|
||||||
@ -502,11 +492,6 @@ public final class JarSigner {
|
|||||||
private final String tSADigestAlg;
|
private final String tSADigestAlg;
|
||||||
private final boolean sectionsonly; // do not "sign" the whole manifest
|
private final boolean sectionsonly; // do not "sign" the whole manifest
|
||||||
private final boolean internalsf; // include the .SF inside the PKCS7 block
|
private final boolean internalsf; // include the .SF inside the PKCS7 block
|
||||||
|
|
||||||
@Deprecated(since="16", forRemoval=true)
|
|
||||||
private final String altSignerPath;
|
|
||||||
@Deprecated(since="16", forRemoval=true)
|
|
||||||
private final String altSigner;
|
|
||||||
private boolean extraAttrsDetected;
|
private boolean extraAttrsDetected;
|
||||||
|
|
||||||
private JarSigner(JarSigner.Builder builder) {
|
private JarSigner(JarSigner.Builder builder) {
|
||||||
@ -549,15 +534,6 @@ public final class JarSigner {
|
|||||||
this.tSAPolicyID = builder.tSAPolicyID;
|
this.tSAPolicyID = builder.tSAPolicyID;
|
||||||
this.sectionsonly = builder.sectionsonly;
|
this.sectionsonly = builder.sectionsonly;
|
||||||
this.internalsf = builder.internalsf;
|
this.internalsf = builder.internalsf;
|
||||||
this.altSigner = builder.altSigner;
|
|
||||||
this.altSignerPath = builder.altSignerPath;
|
|
||||||
|
|
||||||
// altSigner cannot support modern algorithms like RSASSA-PSS and EdDSA
|
|
||||||
if (altSigner != null
|
|
||||||
&& !sigalg.toUpperCase(Locale.ENGLISH).contains("WITH")) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Customized ContentSigner is not supported for " + sigalg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -658,10 +634,6 @@ public final class JarSigner {
|
|||||||
return Boolean.toString(internalsf);
|
return Boolean.toString(internalsf);
|
||||||
case "sectionsonly":
|
case "sectionsonly":
|
||||||
return Boolean.toString(sectionsonly);
|
return Boolean.toString(sectionsonly);
|
||||||
case "altsignerpath":
|
|
||||||
return altSignerPath;
|
|
||||||
case "altsigner":
|
|
||||||
return altSigner;
|
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
"Unsupported key " + key);
|
"Unsupported key " + key);
|
||||||
@ -854,46 +826,27 @@ public final class JarSigner {
|
|||||||
sf.write(baos);
|
sf.write(baos);
|
||||||
byte[] content = baos.toByteArray();
|
byte[] content = baos.toByteArray();
|
||||||
|
|
||||||
if (altSigner == null) {
|
Function<byte[], PKCS9Attributes> timestamper = null;
|
||||||
Function<byte[], PKCS9Attributes> timestamper = null;
|
if (tsaUrl != null) {
|
||||||
if (tsaUrl != null) {
|
timestamper = s -> {
|
||||||
timestamper = s -> {
|
try {
|
||||||
try {
|
// Timestamp the signature
|
||||||
// Timestamp the signature
|
HttpTimestamper tsa = new HttpTimestamper(tsaUrl);
|
||||||
HttpTimestamper tsa = new HttpTimestamper(tsaUrl);
|
byte[] tsToken = PKCS7.generateTimestampToken(
|
||||||
byte[] tsToken = PKCS7.generateTimestampToken(
|
tsa, tSAPolicyID, tSADigestAlg, s);
|
||||||
tsa, tSAPolicyID, tSADigestAlg, s);
|
|
||||||
|
|
||||||
return new PKCS9Attributes(new PKCS9Attribute[]{
|
return new PKCS9Attributes(new PKCS9Attribute[]{
|
||||||
new PKCS9Attribute(
|
new PKCS9Attribute(
|
||||||
PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID,
|
PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID,
|
||||||
tsToken)});
|
tsToken)});
|
||||||
} catch (IOException | CertificateException e) {
|
} catch (IOException | CertificateException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
// We now create authAttrs in block data, so "direct == false".
|
|
||||||
block = PKCS7.generateNewSignedData(sigalg, sigProvider, privateKey, certChain,
|
|
||||||
content, internalsf, false, timestamper);
|
|
||||||
} else {
|
|
||||||
Signature signer = SignatureUtil.fromKey(sigalg, privateKey, sigProvider);
|
|
||||||
signer.update(content);
|
|
||||||
byte[] signature = signer.sign();
|
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
ContentSignerParameters params =
|
|
||||||
new JarSignerParameters(null, tsaUrl, tSAPolicyID,
|
|
||||||
tSADigestAlg, signature,
|
|
||||||
signer.getAlgorithm(), certChain, content, zipFile);
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
ContentSigner signingMechanism = loadSigningMechanism(altSigner, altSignerPath);
|
|
||||||
block = signingMechanism.generateSignedData(
|
|
||||||
params,
|
|
||||||
!internalsf,
|
|
||||||
params.getTimestampingAuthority() != null
|
|
||||||
|| params.getTimestampingAuthorityCertificate() != null);
|
|
||||||
}
|
}
|
||||||
|
// We now create authAttrs in block data, so "direct == false".
|
||||||
|
block = PKCS7.generateNewSignedData(sigalg, sigProvider, privateKey, certChain,
|
||||||
|
content, internalsf, false, timestamper);
|
||||||
|
|
||||||
String sfFilename = sf.getMetaName();
|
String sfFilename = sf.getMetaName();
|
||||||
String bkFilename = sf.getBlockName(privateKey);
|
String bkFilename = sf.getBlockName(privateKey);
|
||||||
@ -1101,44 +1054,6 @@ public final class JarSigner {
|
|||||||
return base64Digests;
|
return base64Digests;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to load the specified signing mechanism.
|
|
||||||
* The URL class loader is used.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private ContentSigner loadSigningMechanism(String signerClassName,
|
|
||||||
String signerClassPath) {
|
|
||||||
|
|
||||||
// If there is no signerClassPath provided, search from here
|
|
||||||
if (signerClassPath == null) {
|
|
||||||
signerClassPath = ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
// construct class loader
|
|
||||||
String cpString; // make sure env.class.path defaults to dot
|
|
||||||
|
|
||||||
// do prepends to get correct ordering
|
|
||||||
cpString = PathList.appendPath(
|
|
||||||
System.getProperty("env.class.path"), null);
|
|
||||||
cpString = PathList.appendPath(
|
|
||||||
System.getProperty("java.class.path"), cpString);
|
|
||||||
cpString = PathList.appendPath(signerClassPath, cpString);
|
|
||||||
URL[] urls = PathList.pathToURLs(cpString);
|
|
||||||
ClassLoader appClassLoader = new URLClassLoader(urls);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// attempt to find signer
|
|
||||||
Class<?> signerClass = appClassLoader.loadClass(signerClassName);
|
|
||||||
Object signer = signerClass.getDeclaredConstructor().newInstance();
|
|
||||||
return (ContentSigner) signer;
|
|
||||||
} catch (ClassNotFoundException|InstantiationException|
|
|
||||||
IllegalAccessException|ClassCastException|
|
|
||||||
NoSuchMethodException| InvocationTargetException e) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Invalid altSigner or altSignerPath", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class SignatureFile {
|
static class SignatureFile {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1226,81 +1141,4 @@ public final class JarSigner {
|
|||||||
return getBaseSignatureFilesName(baseName) + type;
|
return getBaseSignatureFilesName(baseName) + type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
@Deprecated(since="16", forRemoval=true)
|
|
||||||
class JarSignerParameters implements ContentSignerParameters {
|
|
||||||
|
|
||||||
private String[] args;
|
|
||||||
private URI tsa;
|
|
||||||
private byte[] signature;
|
|
||||||
private String signatureAlgorithm;
|
|
||||||
private X509Certificate[] signerCertificateChain;
|
|
||||||
private byte[] content;
|
|
||||||
private ZipFile source;
|
|
||||||
private String tSAPolicyID;
|
|
||||||
private String tSADigestAlg;
|
|
||||||
|
|
||||||
JarSignerParameters(String[] args, URI tsa,
|
|
||||||
String tSAPolicyID, String tSADigestAlg,
|
|
||||||
byte[] signature, String signatureAlgorithm,
|
|
||||||
X509Certificate[] signerCertificateChain,
|
|
||||||
byte[] content, ZipFile source) {
|
|
||||||
|
|
||||||
Objects.requireNonNull(signature);
|
|
||||||
Objects.requireNonNull(signatureAlgorithm);
|
|
||||||
Objects.requireNonNull(signerCertificateChain);
|
|
||||||
|
|
||||||
this.args = args;
|
|
||||||
this.tsa = tsa;
|
|
||||||
this.tSAPolicyID = tSAPolicyID;
|
|
||||||
this.tSADigestAlg = tSADigestAlg;
|
|
||||||
this.signature = signature;
|
|
||||||
this.signatureAlgorithm = signatureAlgorithm;
|
|
||||||
this.signerCertificateChain = signerCertificateChain;
|
|
||||||
this.content = content;
|
|
||||||
this.source = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getCommandLine() {
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
public URI getTimestampingAuthority() {
|
|
||||||
return tsa;
|
|
||||||
}
|
|
||||||
|
|
||||||
public X509Certificate getTimestampingAuthorityCertificate() {
|
|
||||||
// We don't use this param. Always provide tsaURI.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTSAPolicyID() {
|
|
||||||
return tSAPolicyID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTSADigestAlg() {
|
|
||||||
return tSADigestAlg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getSignature() {
|
|
||||||
return signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSignatureAlgorithm() {
|
|
||||||
return signatureAlgorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public X509Certificate[] getSignerCertificateChain() {
|
|
||||||
return signerCertificateChain;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getContent() {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZipFile getSource() {
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. 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
|
||||||
@ -53,7 +53,6 @@ import jdk.internal.javac.ParticipatesInPreview;
|
|||||||
module jdk.jartool {
|
module jdk.jartool {
|
||||||
requires jdk.internal.opt;
|
requires jdk.internal.opt;
|
||||||
|
|
||||||
exports com.sun.jarsigner;
|
|
||||||
exports jdk.security.jarsigner;
|
exports jdk.security.jarsigner;
|
||||||
|
|
||||||
provides java.util.spi.ToolProvider with
|
provides java.util.spi.ToolProvider with
|
||||||
|
@ -179,8 +179,6 @@ public class Main {
|
|||||||
boolean revocationCheck = false; // Revocation check flag
|
boolean revocationCheck = false; // Revocation check flag
|
||||||
|
|
||||||
// read zip entry raw bytes
|
// read zip entry raw bytes
|
||||||
private String altSignerClass = null;
|
|
||||||
private String altSignerClasspath = null;
|
|
||||||
private ZipFile zipFile = null;
|
private ZipFile zipFile = null;
|
||||||
|
|
||||||
// Informational warnings
|
// Informational warnings
|
||||||
@ -483,18 +481,6 @@ public class Main {
|
|||||||
} else if (collator.compare(flags, "-tsacert") ==0) {
|
} else if (collator.compare(flags, "-tsacert") ==0) {
|
||||||
if (++n == args.length) usageNoArg();
|
if (++n == args.length) usageNoArg();
|
||||||
tsaAlias = args[n];
|
tsaAlias = args[n];
|
||||||
} else if (collator.compare(flags, "-altsigner") ==0) {
|
|
||||||
if (++n == args.length) usageNoArg();
|
|
||||||
altSignerClass = args[n];
|
|
||||||
System.err.println(
|
|
||||||
rb.getString("This.option.is.forremoval") +
|
|
||||||
"-altsigner");
|
|
||||||
} else if (collator.compare(flags, "-altsignerpath") ==0) {
|
|
||||||
if (++n == args.length) usageNoArg();
|
|
||||||
altSignerClasspath = args[n];
|
|
||||||
System.err.println(
|
|
||||||
rb.getString("This.option.is.forremoval") +
|
|
||||||
"-altsignerpath");
|
|
||||||
} else if (collator.compare(flags, "-sectionsonly") ==0) {
|
} else if (collator.compare(flags, "-sectionsonly") ==0) {
|
||||||
signManifest = false;
|
signManifest = false;
|
||||||
} else if (collator.compare(flags, "-internalsf") ==0) {
|
} else if (collator.compare(flags, "-internalsf") ==0) {
|
||||||
@ -698,12 +684,6 @@ public class Main {
|
|||||||
System.out.println(rb.getString
|
System.out.println(rb.getString
|
||||||
(".tsadigestalg.algorithm.of.digest.data.in.timestamping.request"));
|
(".tsadigestalg.algorithm.of.digest.data.in.timestamping.request"));
|
||||||
System.out.println();
|
System.out.println();
|
||||||
System.out.println(rb.getString
|
|
||||||
(".altsigner.class.class.name.of.an.alternative.signing.mechanism"));
|
|
||||||
System.out.println();
|
|
||||||
System.out.println(rb.getString
|
|
||||||
(".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism"));
|
|
||||||
System.out.println();
|
|
||||||
System.out.println(rb.getString
|
System.out.println(rb.getString
|
||||||
(".internalsf.include.the.SF.file.inside.the.signature.block"));
|
(".internalsf.include.the.SF.file.inside.the.signature.block"));
|
||||||
System.out.println();
|
System.out.println();
|
||||||
@ -1948,18 +1928,6 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (altSignerClass != null) {
|
|
||||||
builder.setProperty("altSigner", altSignerClass);
|
|
||||||
if (verbose != null) {
|
|
||||||
System.out.println(
|
|
||||||
rb.getString("using.an.alternative.signing.mechanism"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (altSignerClasspath != null) {
|
|
||||||
builder.setProperty("altSignerPath", altSignerClasspath);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.signerName(sigfile);
|
builder.signerName(sigfile);
|
||||||
|
|
||||||
builder.setProperty("sectionsOnly", Boolean.toString(!signManifest));
|
builder.setProperty("sectionsOnly", Boolean.toString(!signManifest));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. 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
|
||||||
@ -44,7 +44,6 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
{"provider.class.not.found", "Provider \"%s\" not found"},
|
{"provider.class.not.found", "Provider \"%s\" not found"},
|
||||||
{"jarsigner.error.", "jarsigner error: "},
|
{"jarsigner.error.", "jarsigner error: "},
|
||||||
{"Illegal.option.", "Illegal option: "},
|
{"Illegal.option.", "Illegal option: "},
|
||||||
{"This.option.is.forremoval", "This option is deprecated and will be removed in a future release: "},
|
|
||||||
{".keystore.must.be.NONE.if.storetype.is.{0}",
|
{".keystore.must.be.NONE.if.storetype.is.{0}",
|
||||||
"-keystore must be NONE if -storetype is {0}"},
|
"-keystore must be NONE if -storetype is {0}"},
|
||||||
{".keypass.can.not.be.specified.if.storetype.is.{0}",
|
{".keypass.can.not.be.specified.if.storetype.is.{0}",
|
||||||
@ -97,12 +96,6 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
"[-tsapolicyid <oid>] TSAPolicyID for Timestamping Authority"},
|
"[-tsapolicyid <oid>] TSAPolicyID for Timestamping Authority"},
|
||||||
{".tsadigestalg.algorithm.of.digest.data.in.timestamping.request",
|
{".tsadigestalg.algorithm.of.digest.data.in.timestamping.request",
|
||||||
"[-tsadigestalg <algorithm>] algorithm of digest data in timestamping request"},
|
"[-tsadigestalg <algorithm>] algorithm of digest data in timestamping request"},
|
||||||
{".altsigner.class.class.name.of.an.alternative.signing.mechanism",
|
|
||||||
"[-altsigner <class>] class name of an alternative signing mechanism\n" +
|
|
||||||
" (This option is deprecated and will be removed in a future release.)"},
|
|
||||||
{".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism",
|
|
||||||
"[-altsignerpath <pathlist>] location of an alternative signing mechanism\n" +
|
|
||||||
" (This option is deprecated and will be removed in a future release.)"},
|
|
||||||
{".internalsf.include.the.SF.file.inside.the.signature.block",
|
{".internalsf.include.the.SF.file.inside.the.signature.block",
|
||||||
"[-internalsf] include the .SF file inside the signature block"},
|
"[-internalsf] include the .SF file inside the signature block"},
|
||||||
{".sectionsonly.don.t.compute.hash.of.entire.manifest",
|
{".sectionsonly.don.t.compute.hash.of.entire.manifest",
|
||||||
@ -240,8 +233,6 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
{"or", "or"},
|
{"or", "or"},
|
||||||
{"Certificate.not.found.for.alias.alias.must.reference.a.valid.KeyStore.entry.containing.an.X.509.public.key.certificate.for.the",
|
{"Certificate.not.found.for.alias.alias.must.reference.a.valid.KeyStore.entry.containing.an.X.509.public.key.certificate.for.the",
|
||||||
"Certificate not found for: {0}. {1} must reference a valid KeyStore entry containing an X.509 public key certificate for the Timestamping Authority."},
|
"Certificate not found for: {0}. {1} must reference a valid KeyStore entry containing an X.509 public key certificate for the Timestamping Authority."},
|
||||||
{"using.an.alternative.signing.mechanism",
|
|
||||||
"using an alternative signing mechanism"},
|
|
||||||
{"entry.was.signed.on", "entry was signed on {0}"},
|
{"entry.was.signed.on", "entry was signed on {0}"},
|
||||||
{"Warning.", "Warning: "},
|
{"Warning.", "Warning: "},
|
||||||
{"Error.", "Error: "},
|
{"Error.", "Error: "},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. 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
|
||||||
@ -44,7 +44,6 @@ public class Resources_de extends java.util.ListResourceBundle {
|
|||||||
{"provider.class.not.found", "Provider \"%s\" nicht gefunden"},
|
{"provider.class.not.found", "Provider \"%s\" nicht gefunden"},
|
||||||
{"jarsigner.error.", "jarsigner-Fehler: "},
|
{"jarsigner.error.", "jarsigner-Fehler: "},
|
||||||
{"Illegal.option.", "Unzul\u00E4ssige Option: "},
|
{"Illegal.option.", "Unzul\u00E4ssige Option: "},
|
||||||
{"This.option.is.forremoval", "Diese Option ist veraltet und wird in einem zuk\u00FCnftigen Release entfernt: "},
|
|
||||||
{".keystore.must.be.NONE.if.storetype.is.{0}",
|
{".keystore.must.be.NONE.if.storetype.is.{0}",
|
||||||
"-keystore muss NONE sein, wenn -storetype {0} ist"},
|
"-keystore muss NONE sein, wenn -storetype {0} ist"},
|
||||||
{".keypass.can.not.be.specified.if.storetype.is.{0}",
|
{".keypass.can.not.be.specified.if.storetype.is.{0}",
|
||||||
@ -97,10 +96,6 @@ public class Resources_de extends java.util.ListResourceBundle {
|
|||||||
"[-tsapolicyid <OID>] TSAPolicyID f\u00FCr Zeitstempelautorit\u00E4t"},
|
"[-tsapolicyid <OID>] TSAPolicyID f\u00FCr Zeitstempelautorit\u00E4t"},
|
||||||
{".tsadigestalg.algorithm.of.digest.data.in.timestamping.request",
|
{".tsadigestalg.algorithm.of.digest.data.in.timestamping.request",
|
||||||
"[-tsadigestalg <Algorithmus>] Algorithmus der Digestdaten in Zeitstempelanforderung"},
|
"[-tsadigestalg <Algorithmus>] Algorithmus der Digestdaten in Zeitstempelanforderung"},
|
||||||
{".altsigner.class.class.name.of.an.alternative.signing.mechanism",
|
|
||||||
"[-altsigner <Klasse>] Klassenname eines alternativen Signiermechanismus\n (Diese Option ist veraltet und wird in einem zuk\u00FCnftigen Release entfernt.)"},
|
|
||||||
{".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism",
|
|
||||||
"[-altsignerpath <Pfadliste>] Speicherort eines alternativen Signiermechanismus\n (Diese Option ist veraltet und wird in einem zuk\u00FCnftigen Release entfernt.)"},
|
|
||||||
{".internalsf.include.the.SF.file.inside.the.signature.block",
|
{".internalsf.include.the.SF.file.inside.the.signature.block",
|
||||||
"[-internalsf] SF-Datei in Signaturblock aufnehmen"},
|
"[-internalsf] SF-Datei in Signaturblock aufnehmen"},
|
||||||
{".sectionsonly.don.t.compute.hash.of.entire.manifest",
|
{".sectionsonly.don.t.compute.hash.of.entire.manifest",
|
||||||
@ -236,8 +231,6 @@ public class Resources_de extends java.util.ListResourceBundle {
|
|||||||
{"or", "oder"},
|
{"or", "oder"},
|
||||||
{"Certificate.not.found.for.alias.alias.must.reference.a.valid.KeyStore.entry.containing.an.X.509.public.key.certificate.for.the",
|
{"Certificate.not.found.for.alias.alias.must.reference.a.valid.KeyStore.entry.containing.an.X.509.public.key.certificate.for.the",
|
||||||
"Zertifikat nicht gefunden f\u00FCr: {0}. {1} muss einen g\u00FCltigen Keystore-Eintrag referenzieren, der ein X.509-Public-Key-Zertifikat f\u00FCr die Zeitstempelautorit\u00E4t enth\u00E4lt."},
|
"Zertifikat nicht gefunden f\u00FCr: {0}. {1} muss einen g\u00FCltigen Keystore-Eintrag referenzieren, der ein X.509-Public-Key-Zertifikat f\u00FCr die Zeitstempelautorit\u00E4t enth\u00E4lt."},
|
||||||
{"using.an.alternative.signing.mechanism",
|
|
||||||
"Verwendung eines alternativen Signaturmechanismus"},
|
|
||||||
{"entry.was.signed.on", "Eintrag wurde signiert am {0}"},
|
{"entry.was.signed.on", "Eintrag wurde signiert am {0}"},
|
||||||
{"Warning.", "Warnung: "},
|
{"Warning.", "Warnung: "},
|
||||||
{"Error.", "Fehler: "},
|
{"Error.", "Fehler: "},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. 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
|
||||||
@ -44,7 +44,6 @@ public class Resources_ja extends java.util.ListResourceBundle {
|
|||||||
{"provider.class.not.found", "\u30D7\u30ED\u30D0\u30A4\u30C0\"%s\"\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093"},
|
{"provider.class.not.found", "\u30D7\u30ED\u30D0\u30A4\u30C0\"%s\"\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093"},
|
||||||
{"jarsigner.error.", "jarsigner\u30A8\u30E9\u30FC: "},
|
{"jarsigner.error.", "jarsigner\u30A8\u30E9\u30FC: "},
|
||||||
{"Illegal.option.", "\u4E0D\u6B63\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: "},
|
{"Illegal.option.", "\u4E0D\u6B63\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: "},
|
||||||
{"This.option.is.forremoval", "\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u975E\u63A8\u5968\u3067\u3042\u308A\u3001\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3059: "},
|
|
||||||
{".keystore.must.be.NONE.if.storetype.is.{0}",
|
{".keystore.must.be.NONE.if.storetype.is.{0}",
|
||||||
"-storetype\u304C{0}\u306E\u5834\u5408\u3001-keystore\u306FNONE\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059"},
|
"-storetype\u304C{0}\u306E\u5834\u5408\u3001-keystore\u306FNONE\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059"},
|
||||||
{".keypass.can.not.be.specified.if.storetype.is.{0}",
|
{".keypass.can.not.be.specified.if.storetype.is.{0}",
|
||||||
@ -97,10 +96,6 @@ public class Resources_ja extends java.util.ListResourceBundle {
|
|||||||
"[-tsapolicyid <oid>] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306ETSAPolicyID"},
|
"[-tsapolicyid <oid>] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306ETSAPolicyID"},
|
||||||
{".tsadigestalg.algorithm.of.digest.data.in.timestamping.request",
|
{".tsadigestalg.algorithm.of.digest.data.in.timestamping.request",
|
||||||
"[-tsadigestalg <algorithm>] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u30FB\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u30C0\u30A4\u30B8\u30A7\u30B9\u30C8\u30FB\u30C7\u30FC\u30BF\u306E\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0"},
|
"[-tsadigestalg <algorithm>] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u30FB\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u30C0\u30A4\u30B8\u30A7\u30B9\u30C8\u30FB\u30C7\u30FC\u30BF\u306E\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0"},
|
||||||
{".altsigner.class.class.name.of.an.alternative.signing.mechanism",
|
|
||||||
"[-altsigner <class>] \u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u30AF\u30E9\u30B9\u540D\n (\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u975E\u63A8\u5968\u3067\u3042\u308A\u3001\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3059\u3002)"},
|
|
||||||
{".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism",
|
|
||||||
"[-altsignerpath <pathlist>] \u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u5834\u6240\n (\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u975E\u63A8\u5968\u3067\u3042\u308A\u3001\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3059\u3002)"},
|
|
||||||
{".internalsf.include.the.SF.file.inside.the.signature.block",
|
{".internalsf.include.the.SF.file.inside.the.signature.block",
|
||||||
"[-internalsf] \u30B7\u30B0\u30CD\u30C1\u30E3\u30FB\u30D6\u30ED\u30C3\u30AF\u306B.SF\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u308B"},
|
"[-internalsf] \u30B7\u30B0\u30CD\u30C1\u30E3\u30FB\u30D6\u30ED\u30C3\u30AF\u306B.SF\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u308B"},
|
||||||
{".sectionsonly.don.t.compute.hash.of.entire.manifest",
|
{".sectionsonly.don.t.compute.hash.of.entire.manifest",
|
||||||
@ -236,8 +231,6 @@ public class Resources_ja extends java.util.ListResourceBundle {
|
|||||||
{"or", "\u307E\u305F\u306F"},
|
{"or", "\u307E\u305F\u306F"},
|
||||||
{"Certificate.not.found.for.alias.alias.must.reference.a.valid.KeyStore.entry.containing.an.X.509.public.key.certificate.for.the",
|
{"Certificate.not.found.for.alias.alias.must.reference.a.valid.KeyStore.entry.containing.an.X.509.public.key.certificate.for.the",
|
||||||
"\u8A3C\u660E\u66F8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F: {0}\u3002{1}\u306F\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306EX.509\u516C\u958B\u30AD\u30FC\u8A3C\u660E\u66F8\u304C\u542B\u307E\u308C\u3066\u3044\u308B\u6709\u52B9\u306AKeyStore\u30A8\u30F3\u30C8\u30EA\u3092\u53C2\u7167\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002"},
|
"\u8A3C\u660E\u66F8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F: {0}\u3002{1}\u306F\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306EX.509\u516C\u958B\u30AD\u30FC\u8A3C\u660E\u66F8\u304C\u542B\u307E\u308C\u3066\u3044\u308B\u6709\u52B9\u306AKeyStore\u30A8\u30F3\u30C8\u30EA\u3092\u53C2\u7167\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002"},
|
||||||
{"using.an.alternative.signing.mechanism",
|
|
||||||
"\u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u4F7F\u7528"},
|
|
||||||
{"entry.was.signed.on", "\u30A8\u30F3\u30C8\u30EA\u306F{0}\u306B\u7F72\u540D\u3055\u308C\u307E\u3057\u305F"},
|
{"entry.was.signed.on", "\u30A8\u30F3\u30C8\u30EA\u306F{0}\u306B\u7F72\u540D\u3055\u308C\u307E\u3057\u305F"},
|
||||||
{"Warning.", "\u8B66\u544A: "},
|
{"Warning.", "\u8B66\u544A: "},
|
||||||
{"Error.", "\u30A8\u30E9\u30FC: "},
|
{"Error.", "\u30A8\u30E9\u30FC: "},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. 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
|
||||||
@ -44,7 +44,6 @@ public class Resources_zh_CN extends java.util.ListResourceBundle {
|
|||||||
{"provider.class.not.found", "\u672A\u627E\u5230\u63D0\u4F9B\u65B9 \"%s\""},
|
{"provider.class.not.found", "\u672A\u627E\u5230\u63D0\u4F9B\u65B9 \"%s\""},
|
||||||
{"jarsigner.error.", "jarsigner \u9519\u8BEF: "},
|
{"jarsigner.error.", "jarsigner \u9519\u8BEF: "},
|
||||||
{"Illegal.option.", "\u975E\u6CD5\u9009\u9879: "},
|
{"Illegal.option.", "\u975E\u6CD5\u9009\u9879: "},
|
||||||
{"This.option.is.forremoval", "\u8BE5\u9009\u9879\u5DF2\u8FC7\u65F6\uFF0C\u5728\u5C06\u6765\u7684\u53D1\u884C\u7248\u4E2D\u5C06\u88AB\u5220\u9664\uFF1A"},
|
|
||||||
{".keystore.must.be.NONE.if.storetype.is.{0}",
|
{".keystore.must.be.NONE.if.storetype.is.{0}",
|
||||||
"\u5982\u679C -storetype \u4E3A {0}, \u5219 -keystore \u5FC5\u987B\u4E3A NONE"},
|
"\u5982\u679C -storetype \u4E3A {0}, \u5219 -keystore \u5FC5\u987B\u4E3A NONE"},
|
||||||
{".keypass.can.not.be.specified.if.storetype.is.{0}",
|
{".keypass.can.not.be.specified.if.storetype.is.{0}",
|
||||||
@ -97,10 +96,6 @@ public class Resources_zh_CN extends java.util.ListResourceBundle {
|
|||||||
"[-tsapolicyid <oid>] \u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684 TSAPolicyID"},
|
"[-tsapolicyid <oid>] \u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684 TSAPolicyID"},
|
||||||
{".tsadigestalg.algorithm.of.digest.data.in.timestamping.request",
|
{".tsadigestalg.algorithm.of.digest.data.in.timestamping.request",
|
||||||
"[-tsadigestalg <\u7B97\u6CD5>] \u65F6\u95F4\u6233\u8BF7\u6C42\u4E2D\u7684\u6458\u8981\u6570\u636E\u7684\u7B97\u6CD5"},
|
"[-tsadigestalg <\u7B97\u6CD5>] \u65F6\u95F4\u6233\u8BF7\u6C42\u4E2D\u7684\u6458\u8981\u6570\u636E\u7684\u7B97\u6CD5"},
|
||||||
{".altsigner.class.class.name.of.an.alternative.signing.mechanism",
|
|
||||||
"[-altsigner <class>] \u66FF\u4EE3\u7B7E\u540D\u673A\u5236\u7684\u7C7B\u540D\n \uFF08\u8BE5\u9009\u9879\u5DF2\u8FC7\u65F6\uFF0C\u5728\u5C06\u6765\u7684\u53D1\u884C\u7248\u4E2D\u5C06\u88AB\u5220\u9664\u3002\uFF09"},
|
|
||||||
{".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism",
|
|
||||||
"[-altsignerpath <pathlist>] \u66FF\u4EE3\u7B7E\u540D\u673A\u5236\u7684\u4F4D\u7F6E\n \uFF08\u8BE5\u9009\u9879\u5DF2\u8FC7\u65F6\uFF0C\u5728\u5C06\u6765\u7684\u53D1\u884C\u7248\u4E2D\u5C06\u88AB\u5220\u9664\u3002\uFF09"},
|
|
||||||
{".internalsf.include.the.SF.file.inside.the.signature.block",
|
{".internalsf.include.the.SF.file.inside.the.signature.block",
|
||||||
"[-internalsf] \u5728\u7B7E\u540D\u5757\u5185\u5305\u542B .SF \u6587\u4EF6"},
|
"[-internalsf] \u5728\u7B7E\u540D\u5757\u5185\u5305\u542B .SF \u6587\u4EF6"},
|
||||||
{".sectionsonly.don.t.compute.hash.of.entire.manifest",
|
{".sectionsonly.don.t.compute.hash.of.entire.manifest",
|
||||||
@ -236,8 +231,6 @@ public class Resources_zh_CN extends java.util.ListResourceBundle {
|
|||||||
{"or", "\u6216"},
|
{"or", "\u6216"},
|
||||||
{"Certificate.not.found.for.alias.alias.must.reference.a.valid.KeyStore.entry.containing.an.X.509.public.key.certificate.for.the",
|
{"Certificate.not.found.for.alias.alias.must.reference.a.valid.KeyStore.entry.containing.an.X.509.public.key.certificate.for.the",
|
||||||
"\u627E\u4E0D\u5230{0}\u7684\u8BC1\u4E66\u3002{1}\u5FC5\u987B\u5F15\u7528\u5305\u542B\u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684 X.509 \u516C\u5171\u5BC6\u94A5\u8BC1\u4E66\u7684\u6709\u6548\u5BC6\u94A5\u5E93\u6761\u76EE\u3002"},
|
"\u627E\u4E0D\u5230{0}\u7684\u8BC1\u4E66\u3002{1}\u5FC5\u987B\u5F15\u7528\u5305\u542B\u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684 X.509 \u516C\u5171\u5BC6\u94A5\u8BC1\u4E66\u7684\u6709\u6548\u5BC6\u94A5\u5E93\u6761\u76EE\u3002"},
|
||||||
{"using.an.alternative.signing.mechanism",
|
|
||||||
"\u6B63\u5728\u4F7F\u7528\u66FF\u4EE3\u7684\u7B7E\u540D\u673A\u5236"},
|
|
||||||
{"entry.was.signed.on", "\u6761\u76EE\u7684\u7B7E\u540D\u65E5\u671F\u4E3A {0}"},
|
{"entry.was.signed.on", "\u6761\u76EE\u7684\u7B7E\u540D\u65E5\u671F\u4E3A {0}"},
|
||||||
{"Warning.", "\u8B66\u544A: "},
|
{"Warning.", "\u8B66\u544A: "},
|
||||||
{"Error.", "\u9519\u8BEF: "},
|
{"Error.", "\u9519\u8BEF: "},
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2013, 2023, Oracle and/or its affiliates. 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
|
||||||
@ -217,7 +217,6 @@ jdk_security2 = \
|
|||||||
jdk_security3 = \
|
jdk_security3 = \
|
||||||
javax/security \
|
javax/security \
|
||||||
-javax/security/auth/kerberos \
|
-javax/security/auth/kerberos \
|
||||||
com/sun/jarsigner \
|
|
||||||
com/sun/security \
|
com/sun/security \
|
||||||
-com/sun/security/jgss \
|
-com/sun/security/jgss \
|
||||||
com/sun/org/apache/xml/internal/security \
|
com/sun/org/apache/xml/internal/security \
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014, 2016, 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 8039358
|
|
||||||
* @summary com.sun.jarsigner.ContentSignerParameters.getTSAPolicyID() should be default
|
|
||||||
* @modules jdk.jartool
|
|
||||||
* @compile DefaultMethod.java
|
|
||||||
*/
|
|
||||||
|
|
||||||
import com.sun.jarsigner.ContentSignerParameters;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.zip.ZipFile;
|
|
||||||
|
|
||||||
public class DefaultMethod implements ContentSignerParameters {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getCommandLine() {
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public URI getTimestampingAuthority() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public X509Certificate getTimestampingAuthorityCertificate() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getSignature() {
|
|
||||||
return new byte[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSignatureAlgorithm() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public X509Certificate[] getSignerCertificateChain() {
|
|
||||||
return new X509Certificate[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getContent() {
|
|
||||||
return new byte[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ZipFile getSource() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. 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
|
||||||
@ -34,8 +34,6 @@
|
|||||||
* @run main/othervm Spec
|
* @run main/othervm Spec
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.jarsigner.ContentSigner;
|
|
||||||
import com.sun.jarsigner.ContentSignerParameters;
|
|
||||||
import jdk.security.jarsigner.JarSigner;
|
import jdk.security.jarsigner.JarSigner;
|
||||||
import jdk.test.lib.util.JarUtils;
|
import jdk.test.lib.util.JarUtils;
|
||||||
import sun.security.provider.certpath.X509CertPath;
|
import sun.security.provider.certpath.X509CertPath;
|
||||||
@ -129,7 +127,6 @@ public class Spec {
|
|||||||
npe(()->b1.setProperty("sectionsonly", null));
|
npe(()->b1.setProperty("sectionsonly", null));
|
||||||
iae(()->b1.setProperty("sectionsonly", "OK"));
|
iae(()->b1.setProperty("sectionsonly", "OK"));
|
||||||
npe(()->b1.setProperty("sectionsonly", null));
|
npe(()->b1.setProperty("sectionsonly", null));
|
||||||
npe(()->b1.setProperty("altsigner", null));
|
|
||||||
npe(()->b1.eventHandler(null));
|
npe(()->b1.eventHandler(null));
|
||||||
|
|
||||||
// default values
|
// default values
|
||||||
@ -147,7 +144,6 @@ public class Spec {
|
|||||||
assertTrue(js2.getProperty("tsapolicyid") == null);
|
assertTrue(js2.getProperty("tsapolicyid") == null);
|
||||||
assertTrue(js2.getProperty("internalsf").equals("false"));
|
assertTrue(js2.getProperty("internalsf").equals("false"));
|
||||||
assertTrue(js2.getProperty("sectionsonly").equals("false"));
|
assertTrue(js2.getProperty("sectionsonly").equals("false"));
|
||||||
assertTrue(js2.getProperty("altsigner") == null);
|
|
||||||
uoe(()->js2.getProperty("invalid"));
|
uoe(()->js2.getProperty("invalid"));
|
||||||
|
|
||||||
// default values
|
// default values
|
||||||
@ -163,7 +159,6 @@ public class Spec {
|
|||||||
.setProperty("tsapolicyid", "1.2.3.4")
|
.setProperty("tsapolicyid", "1.2.3.4")
|
||||||
.setProperty("internalsf", "true")
|
.setProperty("internalsf", "true")
|
||||||
.setProperty("sectionsonly", "true")
|
.setProperty("sectionsonly", "true")
|
||||||
.setProperty("altsigner", "MyContentSigner")
|
|
||||||
.eventHandler(myeh);
|
.eventHandler(myeh);
|
||||||
JarSigner js3 = b3.build();
|
JarSigner js3 = b3.build();
|
||||||
|
|
||||||
@ -175,8 +170,6 @@ public class Spec {
|
|||||||
assertTrue(js3.getProperty("tsapolicyid").equals("1.2.3.4"));
|
assertTrue(js3.getProperty("tsapolicyid").equals("1.2.3.4"));
|
||||||
assertTrue(js3.getProperty("internalsf").equals("true"));
|
assertTrue(js3.getProperty("internalsf").equals("true"));
|
||||||
assertTrue(js3.getProperty("sectionsonly").equals("true"));
|
assertTrue(js3.getProperty("sectionsonly").equals("true"));
|
||||||
assertTrue(js3.getProperty("altsigner").equals("MyContentSigner"));
|
|
||||||
assertTrue(js3.getProperty("altsignerpath") == null);
|
|
||||||
|
|
||||||
assertTrue(JarSigner.Builder.getDefaultDigestAlgorithm()
|
assertTrue(JarSigner.Builder.getDefaultDigestAlgorithm()
|
||||||
.equals("SHA-384"));
|
.equals("SHA-384"));
|
||||||
@ -207,14 +200,6 @@ public class Spec {
|
|||||||
assertTrue(JarSigner.Builder
|
assertTrue(JarSigner.Builder
|
||||||
.getDefaultSignatureAlgorithm(kpg.generateKeyPair().getPrivate())
|
.getDefaultSignatureAlgorithm(kpg.generateKeyPair().getPrivate())
|
||||||
.equals("SHA512withECDSA"));
|
.equals("SHA512withECDSA"));
|
||||||
|
|
||||||
// altsigner does not support modern algorithms
|
|
||||||
JarSigner.Builder b4 = new JarSigner.Builder(
|
|
||||||
(PrivateKey)ks.getKey("e", pass),
|
|
||||||
CertificateFactory.getInstance("X.509")
|
|
||||||
.generateCertPath(Arrays.asList(ks.getCertificateChain("e"))));
|
|
||||||
b4.setProperty("altsigner", "MyContentSigner");
|
|
||||||
iae(() -> b4.build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RunnableWithException {
|
interface RunnableWithException {
|
||||||
@ -253,15 +238,4 @@ public class Spec {
|
|||||||
static void assertTrue(boolean x) throws Exception {
|
static void assertTrue(boolean x) throws Exception {
|
||||||
if (!x) throw new Exception("Not true");
|
if (!x) throw new Exception("Not true");
|
||||||
}
|
}
|
||||||
|
|
||||||
static class MyContentSigner extends ContentSigner {
|
|
||||||
@Override
|
|
||||||
public byte[] generateSignedData(
|
|
||||||
ContentSignerParameters parameters,
|
|
||||||
boolean omitContent,
|
|
||||||
boolean applyTimestamp) throws NoSuchAlgorithmException,
|
|
||||||
CertificateException, IOException {
|
|
||||||
return new byte[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. 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
|
||||||
@ -31,8 +31,6 @@
|
|||||||
* java.base/sun.security.x509
|
* java.base/sun.security.x509
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.sun.jarsigner.ContentSigner;
|
|
||||||
import com.sun.jarsigner.ContentSignerParameters;
|
|
||||||
import jdk.test.lib.Asserts;
|
import jdk.test.lib.Asserts;
|
||||||
import jdk.test.lib.SecurityTools;
|
import jdk.test.lib.SecurityTools;
|
||||||
import jdk.test.lib.util.JarUtils;
|
import jdk.test.lib.util.JarUtils;
|
||||||
@ -52,19 +50,6 @@ public class Options {
|
|||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
// Help
|
|
||||||
boolean lastLineHasAltSigner = false;
|
|
||||||
for (String line : SecurityTools.jarsigner("--help").asLines()) {
|
|
||||||
if (line.contains("-altsigner")) {
|
|
||||||
lastLineHasAltSigner = true;
|
|
||||||
} else {
|
|
||||||
if (lastLineHasAltSigner) {
|
|
||||||
Asserts.assertTrue(line.contains("deprecated and will be removed"));
|
|
||||||
}
|
|
||||||
lastLineHasAltSigner = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepares raw file
|
// Prepares raw file
|
||||||
Files.write(Path.of("a"), List.of("a"));
|
Files.write(Path.of("a"), List.of("a"));
|
||||||
|
|
||||||
@ -77,38 +62,6 @@ public class Options {
|
|||||||
" CN=A -alias a -genkeypair -keyalg rsa")
|
" CN=A -alias a -genkeypair -keyalg rsa")
|
||||||
.shouldHaveExitValue(0);
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
// -altsign
|
|
||||||
SecurityTools.jarsigner(
|
|
||||||
"-debug -signedjar altsign.jar -keystore jks -storepass changeit" +
|
|
||||||
" -altsigner Options$X" +
|
|
||||||
" -altsignerpath " + System.getProperty("test.classes") +
|
|
||||||
" a.jar a")
|
|
||||||
.shouldContain("removed in a future release: -altsigner")
|
|
||||||
.shouldContain("removed in a future release: -altsignerpath")
|
|
||||||
.shouldContain("PKCS7.parse"); // signature not parseable
|
|
||||||
// but signing succeeds
|
|
||||||
|
|
||||||
try (JarFile jf = new JarFile("altsign.jar")) {
|
|
||||||
JarEntry je = jf.getJarEntry("META-INF/A.RSA");
|
|
||||||
try (InputStream is = jf.getInputStream(je)) {
|
|
||||||
if (!Arrays.equals(is.readAllBytes(), "1234".getBytes())) {
|
|
||||||
throw new Exception("altsign go wrong");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -altsign with no -altsignerpath
|
|
||||||
Files.copy(Path.of(System.getProperty("test.classes"), "Options$X.class"),
|
|
||||||
Path.of("Options$X.class"));
|
|
||||||
SecurityTools.jarsigner(
|
|
||||||
"-debug -signedjar altsign.jar -keystore jks -storepass changeit" +
|
|
||||||
" -altsigner Options$X" +
|
|
||||||
" a.jar a")
|
|
||||||
.shouldContain("removed in a future release: -altsigner")
|
|
||||||
.shouldNotContain("removed in a future release: -altsignerpath")
|
|
||||||
.shouldContain("PKCS7.parse"); // signature not parseable
|
|
||||||
// but signing succeeds
|
|
||||||
|
|
||||||
// -sigfile, -digestalg, -sigalg, -internalsf, -sectionsonly
|
// -sigfile, -digestalg, -sigalg, -internalsf, -sectionsonly
|
||||||
SecurityTools.jarsigner(
|
SecurityTools.jarsigner(
|
||||||
"-debug -signedjar new.jar -keystore jks -storepass changeit" +
|
"-debug -signedjar new.jar -keystore jks -storepass changeit" +
|
||||||
@ -155,12 +108,4 @@ public class Options {
|
|||||||
|
|
||||||
// TSA-related ones are checked in ts.sh
|
// TSA-related ones are checked in ts.sh
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class X extends ContentSigner {
|
|
||||||
@Override
|
|
||||||
public byte[] generateSignedData(ContentSignerParameters parameters,
|
|
||||||
boolean omitContent, boolean applyTimestamp) {
|
|
||||||
return "1234".getBytes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user