提交 258cf254 编写于 作者: M mullan

8168963: Backout JDK-8154005

Reviewed-by: igerasim
上级 e4118ea4
...@@ -29,7 +29,6 @@ import java.security.AlgorithmConstraints; ...@@ -29,7 +29,6 @@ import java.security.AlgorithmConstraints;
import java.security.CryptoPrimitive; import java.security.CryptoPrimitive;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.Set; import java.util.Set;
import java.util.EnumSet; import java.util.EnumSet;
import java.math.BigInteger; import java.math.BigInteger;
...@@ -60,7 +59,7 @@ import sun.security.x509.X509CRLImpl; ...@@ -60,7 +59,7 @@ import sun.security.x509.X509CRLImpl;
import sun.security.x509.AlgorithmId; import sun.security.x509.AlgorithmId;
/** /**
* A {@code PKIXCertPathChecker} implementation to check whether a * A <code>PKIXCertPathChecker</code> implementation to check whether a
* specified certificate contains the required algorithm constraints. * specified certificate contains the required algorithm constraints.
* <p> * <p>
* Certificate fields such as the subject public key, the signature * Certificate fields such as the subject public key, the signature
...@@ -75,7 +74,6 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -75,7 +74,6 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
private final AlgorithmConstraints constraints; private final AlgorithmConstraints constraints;
private final PublicKey trustedPubKey; private final PublicKey trustedPubKey;
private final Date pkixdate;
private PublicKey prevPubKey; private PublicKey prevPubKey;
private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET = private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
...@@ -101,7 +99,7 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -101,7 +99,7 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
private boolean trustedMatch = false; private boolean trustedMatch = false;
/** /**
* Create a new {@code AlgorithmChecker} with the algorithm * Create a new <code>AlgorithmChecker</code> with the algorithm
* constraints specified in security property * constraints specified in security property
* "jdk.certpath.disabledAlgorithms". * "jdk.certpath.disabledAlgorithms".
* *
...@@ -109,26 +107,11 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -109,26 +107,11 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
* certificate * certificate
*/ */
public AlgorithmChecker(TrustAnchor anchor) { public AlgorithmChecker(TrustAnchor anchor) {
this(anchor, certPathDefaultConstraints, null); this(anchor, certPathDefaultConstraints);
} }
/** /**
* Create a new {@code AlgorithmChecker} with the * Create a new <code>AlgorithmChecker</code> with the
* given {@code TrustAnchor} and {@code AlgorithmConstraints}.
*
* @param anchor the trust anchor selected to validate the target
* certificate
* @param constraints the algorithm constraints (or null)
*
* @throws IllegalArgumentException if the {@code anchor} is null
*/
public AlgorithmChecker(TrustAnchor anchor,
AlgorithmConstraints constraints) {
this(anchor, constraints, null);
}
/**
* Create a new {@code AlgorithmChecker} with the
* given {@code AlgorithmConstraints}. * given {@code AlgorithmConstraints}.
* <p> * <p>
* Note that this constructor will be used to check a certification * Note that this constructor will be used to check a certification
...@@ -141,24 +124,20 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -141,24 +124,20 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
this.prevPubKey = null; this.prevPubKey = null;
this.trustedPubKey = null; this.trustedPubKey = null;
this.constraints = constraints; this.constraints = constraints;
this.pkixdate = null;
} }
/** /**
* Create a new {@code AlgorithmChecker} with the * Create a new <code>AlgorithmChecker</code> with the
* given {@code TrustAnchor} and {@code AlgorithmConstraints}. * given <code>TrustAnchor</code> and <code>AlgorithmConstraints</code>.
* *
* @param anchor the trust anchor selected to validate the target * @param anchor the trust anchor selected to validate the target
* certificate * certificate
* @param constraints the algorithm constraints (or null) * @param constraints the algorithm constraints (or null)
* @param pkixdate Date the constraints are checked against. The value is
* either the PKIXParameter date or null for the current date.
* *
* @throws IllegalArgumentException if the {@code anchor} is null * @throws IllegalArgumentException if the <code>anchor</code> is null
*/ */
public AlgorithmChecker(TrustAnchor anchor, public AlgorithmChecker(TrustAnchor anchor,
AlgorithmConstraints constraints, AlgorithmConstraints constraints) {
Date pkixdate) {
if (anchor == null) { if (anchor == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
...@@ -178,22 +157,6 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -178,22 +157,6 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
this.prevPubKey = trustedPubKey; this.prevPubKey = trustedPubKey;
this.constraints = constraints; this.constraints = constraints;
this.pkixdate = pkixdate;
}
/**
* Create a new {@code AlgorithmChecker} with the
* given {@code TrustAnchor} and {@code PKIXParameter} date.
*
* @param anchor the trust anchor selected to validate the target
* certificate
* @param pkixdate Date the constraints are checked against. The value is
* either the PKIXParameter date or null for the current date.
*
* @throws IllegalArgumentException if the {@code anchor} is null
*/
public AlgorithmChecker(TrustAnchor anchor, Date pkixdate) {
this(anchor, certPathDefaultConstraints, pkixdate);
} }
// Check this 'cert' for restrictions in the AnchorCertificates // Check this 'cert' for restrictions in the AnchorCertificates
...@@ -296,7 +259,7 @@ final public class AlgorithmChecker extends PKIXCertPathChecker { ...@@ -296,7 +259,7 @@ final public class AlgorithmChecker extends PKIXCertPathChecker {
// permits() will throw exception on failure. // permits() will throw exception on failure.
certPathDefaultConstraints.permits(primitives, certPathDefaultConstraints.permits(primitives,
new CertConstraintParameters((X509Certificate)cert, new CertConstraintParameters((X509Certificate)cert,
trustedMatch, pkixdate)); trustedMatch));
// new CertConstraintParameters(x509Cert, trustedMatch)); // new CertConstraintParameters(x509Cert, trustedMatch));
// If there is no previous key, set one and exit // If there is no previous key, set one and exit
if (prevPubKey == null) { if (prevPubKey == null) {
......
...@@ -172,7 +172,7 @@ public final class PKIXCertPathValidator extends CertPathValidatorSpi { ...@@ -172,7 +172,7 @@ public final class PKIXCertPathValidator extends CertPathValidatorSpi {
List<PKIXCertPathChecker> certPathCheckers = new ArrayList<>(); List<PKIXCertPathChecker> certPathCheckers = new ArrayList<>();
// add standard checkers that we will be using // add standard checkers that we will be using
certPathCheckers.add(untrustedChecker); certPathCheckers.add(untrustedChecker);
certPathCheckers.add(new AlgorithmChecker(anchor, params.date())); certPathCheckers.add(new AlgorithmChecker(anchor));
certPathCheckers.add(new KeyChecker(certPathLen, certPathCheckers.add(new KeyChecker(certPathLen,
params.targetCertConstraints())); params.targetCertConstraints()));
certPathCheckers.add(new ConstraintsChecker(certPathLen)); certPathCheckers.add(new ConstraintsChecker(certPathLen));
......
...@@ -343,8 +343,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { ...@@ -343,8 +343,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
checkers.add(policyChecker); checkers.add(policyChecker);
// add the algorithm checker // add the algorithm checker
checkers.add(new AlgorithmChecker(builder.trustAnchor, checkers.add(new AlgorithmChecker(builder.trustAnchor));
buildParams.date()));
BasicChecker basicChecker = null; BasicChecker basicChecker = null;
if (nextState.keyParamsNeeded()) { if (nextState.keyParamsNeeded()) {
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
package sun.security.util; package sun.security.util;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Date;
/** /**
* This class is a wrapper for keeping state and passing objects between PKIX, * This class is a wrapper for keeping state and passing objects between PKIX,
...@@ -35,21 +34,18 @@ import java.util.Date; ...@@ -35,21 +34,18 @@ import java.util.Date;
public class CertConstraintParameters { public class CertConstraintParameters {
// A certificate being passed to check against constraints. // A certificate being passed to check against constraints.
private final X509Certificate cert; private final X509Certificate cert;
// This is true if the trust anchor in the certificate chain matches a cert // This is true if the trust anchor in the certificate chain matches a cert
// in AnchorCertificates // in AnchorCertificates
private final boolean trustedMatch; private final boolean trustedMatch;
// PKIXParameter date
private final Date pkixDate;
public CertConstraintParameters(X509Certificate c, boolean match, public CertConstraintParameters(X509Certificate c, boolean match) {
Date pkixdate) {
cert = c; cert = c;
trustedMatch = match; trustedMatch = match;
pkixDate = pkixdate;
} }
public CertConstraintParameters(X509Certificate c) { public CertConstraintParameters(X509Certificate c) {
this(c, false, null); this(c, false);
} }
// Returns if the trust anchor has a match if anchor checking is enabled. // Returns if the trust anchor has a match if anchor checking is enabled.
...@@ -60,9 +56,4 @@ public class CertConstraintParameters { ...@@ -60,9 +56,4 @@ public class CertConstraintParameters {
public X509Certificate getCertificate() { public X509Certificate getCertificate() {
return cert; return cert;
} }
public Date getPKIXParamDate() {
return pkixDate;
}
} }
...@@ -31,15 +31,11 @@ import java.security.Key; ...@@ -31,15 +31,11 @@ import java.security.Key;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.Matcher; import java.util.regex.Matcher;
...@@ -242,8 +238,6 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -242,8 +238,6 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
private Map<String, Set<Constraint>> constraintsMap = new HashMap<>(); private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
private static final Pattern keySizePattern = Pattern.compile( private static final Pattern keySizePattern = Pattern.compile(
"keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)"); "keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
private static final Pattern denyAfterPattern = Pattern.compile(
"denyAfter\\s+(\\d{4})-(\\d{2})-(\\d{2})");
public Constraints(String[] constraintArray) { public Constraints(String[] constraintArray) {
for (String constraintEntry : constraintArray) { for (String constraintEntry : constraintArray) {
...@@ -277,8 +271,6 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -277,8 +271,6 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
Constraint c, lastConstraint = null; Constraint c, lastConstraint = null;
// Allow only one jdkCA entry per constraint entry // Allow only one jdkCA entry per constraint entry
boolean jdkCALimit = false; boolean jdkCALimit = false;
// Allow only one denyAfter entry per constraint entry
boolean denyAfterLimit = false;
for (String entry : policy.split("&")) { for (String entry : policy.split("&")) {
entry = entry.trim(); entry = entry.trim();
...@@ -304,22 +296,6 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -304,22 +296,6 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
} }
c = new jdkCAConstraint(algorithm); c = new jdkCAConstraint(algorithm);
jdkCALimit = true; jdkCALimit = true;
} else if(matcher.usePattern(denyAfterPattern).matches()) {
if (debug != null) {
debug.println("Constraints set to denyAfter");
}
if (denyAfterLimit) {
throw new IllegalArgumentException("Only one " +
"denyAfter entry allowed in property. " +
"Constraint: " + constraintEntry);
}
int year = Integer.parseInt(matcher.group(1));
int month = Integer.parseInt(matcher.group(2));
int day = Integer.parseInt(matcher.group(3));
c = new DenyAfterConstraint(algorithm, year, month,
day);
denyAfterLimit = true;
} else { } else {
throw new IllegalArgumentException("Error in security" + throw new IllegalArgumentException("Error in security" +
" property. Constraint unknown: " + entry); " property. Constraint unknown: " + entry);
...@@ -396,15 +372,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -396,15 +372,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
} }
} }
/** // Abstract class for algorithm constraint checking
* This abstract Constraint class for algorithm-based checking
* may contain one or more constraints. If the '&' on the {@Security}
* property is used, multiple constraints have been grouped together
* requiring all the constraints to fail for the check to be disallowed.
*
* If the class contains multiple constraints, the next constraint
* is stored in {@code nextConstraint} in linked-list fashion.
*/
private abstract static class Constraint { private abstract static class Constraint {
String algorithm; String algorithm;
Constraint nextConstraint = null; Constraint nextConstraint = null;
...@@ -440,79 +408,22 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -440,79 +408,22 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
} }
/** /**
* Check if an algorithm constraint is permitted with a given key. * Check if an algorithm constraint permit this key to be used.
*
* If the check inside of {@code permit()} fails, it must call
* {@code next()} with the same {@code Key} parameter passed if
* multiple constraints need to be checked.
*
* @param key Public key * @param key Public key
* @return 'true' if constraint is allowed, 'false' if disallowed. * @return true if constraints do not match
*/ */
public boolean permits(Key key) { public boolean permits(Key key) {
return true; return true;
} }
/** /**
* Check if an algorithm constraint is permitted with a given * Check if an algorithm constraint is permit this certificate to
* CertConstraintParameters. * be used.
* * @param cp CertificateParameter containing certificate and state info
* If the check inside of {@code permits()} fails, it must call * @return true if constraints do not match
* {@code next()} with the same {@code CertConstraintParameters}
* parameter passed if multiple constraints need to be checked.
*
* @param cp CertConstraintParameter containing certificate info
* @throws CertPathValidatorException if constraint disallows.
*
*/ */
public abstract void permits(CertConstraintParameters cp) public abstract void permits(CertConstraintParameters cp)
throws CertPathValidatorException; throws CertPathValidatorException;
/**
* Recursively check if the constraints are allowed.
*
* If {@code nextConstraint} is non-null, this method will
* call {@code nextConstraint}'s {@code permits()} to check if the
* constraint is allowed or denied. If the constraint's
* {@code permits()} is allowed, this method will exit this and any
* recursive next() calls, returning 'true'. If the constraints called
* were disallowed, the last constraint will throw
* {@code CertPathValidatorException}.
*
* @param cp CertConstraintParameters
* @return 'true' if constraint allows the operation, 'false' if
* we are at the end of the constraint list or,
* {@code nextConstraint} is null.
*/
boolean next(CertConstraintParameters cp)
throws CertPathValidatorException {
if (nextConstraint != null) {
nextConstraint.permits(cp);
return true;
}
return false;
}
/**
* Recursively check if this constraint is allowed,
*
* If {@code nextConstraint} is non-null, this method will
* call {@code nextConstraint}'s {@code permit()} to check if the
* constraint is allowed or denied. If the constraint's
* {@code permit()} is allowed, this method will exit this and any
* recursive next() calls, returning 'true'. If the constraints
* called were disallowed the check will exit with 'false'.
*
* @param key Public key
* @return 'true' if constraint allows the operation, 'false' if
* the constraint denies the operation.
*/
boolean next(Key key) {
if (nextConstraint != null && nextConstraint.permits(key)) {
return true;
}
return false;
}
} }
/* /*
...@@ -525,9 +436,9 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -525,9 +436,9 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
} }
/* /*
* Check if CertConstraintParameters has a trusted match, if it does * Check if each constraint fails and check if there is a linked
* call next() for any following constraints. If it does not, exit * constraint Any permitted constraint will exit the linked list
* as this constraint(s) does not restrict the operation. * to allow the operation.
*/ */
public void permits(CertConstraintParameters cp) public void permits(CertConstraintParameters cp)
throws CertPathValidatorException { throws CertPathValidatorException {
...@@ -535,9 +446,10 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -535,9 +446,10 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
debug.println("jdkCAConstraints.permits(): " + algorithm); debug.println("jdkCAConstraints.permits(): " + algorithm);
} }
// Check chain has a trust anchor in cacerts // Return false if the chain has a trust anchor in cacerts
if (cp.isTrustedMatch()) { if (cp.isTrustedMatch()) {
if (next(cp)) { if (nextConstraint != null) {
nextConstraint.permits(cp);
return; return;
} }
throw new CertPathValidatorException( throw new CertPathValidatorException(
...@@ -548,99 +460,6 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { ...@@ -548,99 +460,6 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
} }
} }
/*
* This class handles the denyAfter constraint. The date is in the UTC/GMT
* timezone.
*/
private static class DenyAfterConstraint extends Constraint {
private Date denyAfterDate;
private static final SimpleDateFormat dateFormat =
new SimpleDateFormat("EEE, MMM d HH:mm:ss z YYYY");
DenyAfterConstraint(String algo, int year, int month, int day) {
Calendar c;
algorithm = algo;
if (debug != null) {
debug.println("DenyAfterConstraint read in as: year " +
year + ", month = " + month + ", day = " + day);
}
c = new Calendar.Builder().setTimeZone(TimeZone.getTimeZone("GMT"))
.setDate(year, month - 1, day).build();
if (year > c.getActualMaximum(Calendar.YEAR) ||
year < c.getActualMinimum(Calendar.YEAR)) {
throw new IllegalArgumentException(
"Invalid year given in constraint: " + year);
}
if ((month - 1) > c.getActualMaximum(Calendar.MONTH) ||
(month - 1) < c.getActualMinimum(Calendar.MONTH)) {
throw new IllegalArgumentException(
"Invalid month given in constraint: " + month);
}
if (day > c.getActualMaximum(Calendar.DAY_OF_MONTH) ||
day < c.getActualMinimum(Calendar.DAY_OF_MONTH)) {
throw new IllegalArgumentException(
"Invalid Day of Month given in constraint: " + day);
}
denyAfterDate = c.getTime();
if (debug != null) {
debug.println("DenyAfterConstraint date set to: " +
dateFormat.format(denyAfterDate));
}
}
/*
* Checking that the provided date is not beyond the constraint date.
* The provided date can be the PKIXParameter date if given,
* otherwise it is the current date.
*
* If the constraint disallows, call next() for any following
* constraints. Throw an exception if this is the last constraint.
*/
@Override
public void permits(CertConstraintParameters cp)
throws CertPathValidatorException {
Date currentDate;
if (cp.getPKIXParamDate() != null) {
currentDate = cp.getPKIXParamDate();
} else {
currentDate = new Date();
}
if (!denyAfterDate.after(currentDate)) {
if (next(cp)) {
return;
}
throw new CertPathValidatorException(
"denyAfter constraint check failed. " +
"Constraint date: " +
dateFormat.format(denyAfterDate) +
"; Cert date: " +
dateFormat.format(currentDate),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
/*
* Return result if the constraint's date is beyond the current date
* in UTC timezone.
*/
public boolean permits(Key key) {
if (next(key)) {
return true;
}
if (debug != null) {
debug.println("DenyAfterConstraints.permits(): " + algorithm);
}
return denyAfterDate.after(new Date());
}
}
/* /*
* This class contains constraints dealing with the key size * This class contains constraints dealing with the key size
......
...@@ -422,7 +422,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -422,7 +422,9 @@ krb5.kdc.bad.policy = tryLast
# describes the mechanism for disabling algorithms based on algorithm name # describes the mechanism for disabling algorithms based on algorithm name
# and/or key length. This includes algorithms used in certificates, as well # and/or key length. This includes algorithms used in certificates, as well
# as revocation information such as CRLs and signed OCSP Responses. # as revocation information such as CRLs and signed OCSP Responses.
# The syntax of the disabled algorithm string is described as follows: #
# The syntax of the disabled algorithm string is described as this Java
# BNF-style:
# DisabledAlgorithms: # DisabledAlgorithms:
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
...@@ -433,22 +435,25 @@ krb5.kdc.bad.policy = tryLast ...@@ -433,22 +435,25 @@ krb5.kdc.bad.policy = tryLast
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint | CAConstraint | DenyAfterConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator KeyLength # keySize Operator DecimalInteger
# #
# Operator: # Operator:
# <= | < | == | != | >= | > # <= | < | == | != | >= | >
# #
# KeyLength: # DecimalInteger:
# Integer value of the algorithm's key length in bits # DecimalDigits
# #
# CAConstraint: # DecimalDigits:
# jdkCA # DecimalDigit {DecimalDigit}
#
# DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0
# #
# DenyAfterConstraint: # CertConstraint
# denyAfter YYYY-MM-DD # jdkCA
# #
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
...@@ -462,42 +467,27 @@ krb5.kdc.bad.policy = tryLast ...@@ -462,42 +467,27 @@ krb5.kdc.bad.policy = tryLast
# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
# will not disable algorithms related to "ECDSA". # will not disable algorithms related to "ECDSA".
# #
# A "Constraint" defines restrictions on the keys and/or certificates for # A "Constraint" provides further guidance for the algorithm being specified.
# a specified AlgorithmName: # The "KeySizeConstraint" requires a key of a valid size range if the
# # "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
# KeySizeConstraint: # key size specified in number of bits. For example, "RSA keySize <= 1024"
# keySize Operator KeyLength # indicates that any RSA key with key size less than or equal to 1024 bits
# The constraint requires a key of a valid size range if the # should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates # that any RSA key with key size less than 1024 or greater than 2048 should
# the key size specified in number of bits. For example, # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# "RSA keySize <= 1024" indicates that any RSA key with key size less # algorithms.
# than or equal to 1024 bits should be disabled, and #
# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key # "CertConstraint" specifies additional constraints for
# with key size less than 1024 or greater than 2048 should be disabled. # certificates that contain algorithms that are restricted:
# This constraint is only used on algorithms that have a key size. #
# # "jdkCA" prohibits the specified algorithm only if the algorithm is used
# CAConstraint: # in a certificate chain that terminates at a marked trust anchor in the
# jdkCA # lib/security/cacerts keystore. All other chains are not affected.
# This constraint prohibits the specified algorithm only if the # If the jdkCA constraint is not set, then all chains using the
# algorithm is used in a certificate chain that terminates at a marked # specified algorithm are restricted. jdkCA may only be used once in
# trust anchor in the lib/security/cacerts keystore. If the jdkCA # a DisabledAlgorithm expression.
# constraint is not set, then all chains using the specified algorithm # Example: To apply this constraint to SHA-1 certificates, include
# are restricted. jdkCA may only be used once in a DisabledAlgorithm # the following "SHA1 jdkCA"
# expression.
# Example:  To apply this constraint to SHA-1 certificates, include
# the following:  "SHA1 jdkCA"
#
# DenyAfterConstraint:
# denyAfter YYYY-MM-DD
# This constraint prohibits a certificate with the specified algorithm
# from being used after the date regardless of the certificate's
# validity.  JAR files that are signed and timestamped before the
# constraint date with certificates containing the disabled algorithm
# will not be restricted.  The date is processed in the UTC timezone.
# This constraint can only be used once in a DisabledAlgorithm
# expression.
# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020,
# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03"
# #
# When an algorithm must satisfy more than one constraint, it must be # When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a # delimited by an ampersand '&'. For example, to restrict certificates in a
......
...@@ -422,7 +422,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -422,7 +422,9 @@ krb5.kdc.bad.policy = tryLast
# describes the mechanism for disabling algorithms based on algorithm name # describes the mechanism for disabling algorithms based on algorithm name
# and/or key length. This includes algorithms used in certificates, as well # and/or key length. This includes algorithms used in certificates, as well
# as revocation information such as CRLs and signed OCSP Responses. # as revocation information such as CRLs and signed OCSP Responses.
# The syntax of the disabled algorithm string is described as follows: #
# The syntax of the disabled algorithm string is described as this Java
# BNF-style:
# DisabledAlgorithms: # DisabledAlgorithms:
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
...@@ -433,22 +435,25 @@ krb5.kdc.bad.policy = tryLast ...@@ -433,22 +435,25 @@ krb5.kdc.bad.policy = tryLast
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint | CAConstraint | DenyAfterConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator KeyLength # keySize Operator DecimalInteger
# #
# Operator: # Operator:
# <= | < | == | != | >= | > # <= | < | == | != | >= | >
# #
# KeyLength: # DecimalInteger:
# Integer value of the algorithm's key length in bits # DecimalDigits
# #
# CAConstraint: # DecimalDigits:
# jdkCA # DecimalDigit {DecimalDigit}
#
# DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0
# #
# DenyAfterConstraint: # CertConstraint
# denyAfter YYYY-MM-DD # jdkCA
# #
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
...@@ -462,42 +467,27 @@ krb5.kdc.bad.policy = tryLast ...@@ -462,42 +467,27 @@ krb5.kdc.bad.policy = tryLast
# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
# will not disable algorithms related to "ECDSA". # will not disable algorithms related to "ECDSA".
# #
# A "Constraint" defines restrictions on the keys and/or certificates for # A "Constraint" provides further guidance for the algorithm being specified.
# a specified AlgorithmName: # The "KeySizeConstraint" requires a key of a valid size range if the
# # "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
# KeySizeConstraint: # key size specified in number of bits. For example, "RSA keySize <= 1024"
# keySize Operator KeyLength # indicates that any RSA key with key size less than or equal to 1024 bits
# The constraint requires a key of a valid size range if the # should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates # that any RSA key with key size less than 1024 or greater than 2048 should
# the key size specified in number of bits. For example, # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# "RSA keySize <= 1024" indicates that any RSA key with key size less # algorithms.
# than or equal to 1024 bits should be disabled, and #
# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key # "CertConstraint" specifies additional constraints for
# with key size less than 1024 or greater than 2048 should be disabled. # certificates that contain algorithms that are restricted:
# This constraint is only used on algorithms that have a key size. #
# # "jdkCA" prohibits the specified algorithm only if the algorithm is used
# CAConstraint: # in a certificate chain that terminates at a marked trust anchor in the
# jdkCA # lib/security/cacerts keystore. All other chains are not affected.
# This constraint prohibits the specified algorithm only if the # If the jdkCA constraint is not set, then all chains using the
# algorithm is used in a certificate chain that terminates at a marked # specified algorithm are restricted. jdkCA may only be used once in
# trust anchor in the lib/security/cacerts keystore. If the jdkCA # a DisabledAlgorithm expression.
# constraint is not set, then all chains using the specified algorithm # Example: To apply this constraint to SHA-1 certificates, include
# are restricted. jdkCA may only be used once in a DisabledAlgorithm # the following: "SHA1 jdkCA"
# expression.
# Example:  To apply this constraint to SHA-1 certificates, include
# the following:  "SHA1 jdkCA"
#
# DenyAfterConstraint:
# denyAfter YYYY-MM-DD
# This constraint prohibits a certificate with the specified algorithm
# from being used after the date regardless of the certificate's
# validity.  JAR files that are signed and timestamped before the
# constraint date with certificates containing the disabled algorithm
# will not be restricted.  The date is processed in the UTC timezone.
# This constraint can only be used once in a DisabledAlgorithm
# expression.
# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020,
# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03"
# #
# When an algorithm must satisfy more than one constraint, it must be # When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a # delimited by an ampersand '&'. For example, to restrict certificates in a
......
...@@ -425,7 +425,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -425,7 +425,9 @@ krb5.kdc.bad.policy = tryLast
# describes the mechanism for disabling algorithms based on algorithm name # describes the mechanism for disabling algorithms based on algorithm name
# and/or key length. This includes algorithms used in certificates, as well # and/or key length. This includes algorithms used in certificates, as well
# as revocation information such as CRLs and signed OCSP Responses. # as revocation information such as CRLs and signed OCSP Responses.
# The syntax of the disabled algorithm string is described as follows: #
# The syntax of the disabled algorithm string is described as this Java
# BNF-style:
# DisabledAlgorithms: # DisabledAlgorithms:
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
...@@ -436,22 +438,25 @@ krb5.kdc.bad.policy = tryLast ...@@ -436,22 +438,25 @@ krb5.kdc.bad.policy = tryLast
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint | CAConstraint | DenyAfterConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator KeyLength # keySize Operator DecimalInteger
# #
# Operator: # Operator:
# <= | < | == | != | >= | > # <= | < | == | != | >= | >
# #
# KeyLength: # DecimalInteger:
# Integer value of the algorithm's key length in bits # DecimalDigits
# #
# CAConstraint: # DecimalDigits:
# jdkCA # DecimalDigit {DecimalDigit}
#
# DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0
# #
# DenyAfterConstraint: # CertConstraint
# denyAfter YYYY-MM-DD # jdkCA
# #
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
...@@ -465,42 +470,27 @@ krb5.kdc.bad.policy = tryLast ...@@ -465,42 +470,27 @@ krb5.kdc.bad.policy = tryLast
# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
# will not disable algorithms related to "ECDSA". # will not disable algorithms related to "ECDSA".
# #
# A "Constraint" defines restrictions on the keys and/or certificates for # A "Constraint" provides further guidance for the algorithm being specified.
# a specified AlgorithmName: # The "KeySizeConstraint" requires a key of a valid size range if the
# # "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
# KeySizeConstraint: # key size specified in number of bits. For example, "RSA keySize <= 1024"
# keySize Operator KeyLength # indicates that any RSA key with key size less than or equal to 1024 bits
# The constraint requires a key of a valid size range if the # should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates # that any RSA key with key size less than 1024 or greater than 2048 should
# the key size specified in number of bits. For example, # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# "RSA keySize <= 1024" indicates that any RSA key with key size less # algorithms.
# than or equal to 1024 bits should be disabled, and #
# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key # "CertConstraint" specifies additional constraints for
# with key size less than 1024 or greater than 2048 should be disabled. # certificates that contain algorithms that are restricted:
# This constraint is only used on algorithms that have a key size. #
# # "jdkCA" prohibits the specified algorithm only if the algorithm is used
# CAConstraint: # in a certificate chain that terminates at a marked trust anchor in the
# jdkCA # lib/security/cacerts keystore. All other chains are not affected.
# This constraint prohibits the specified algorithm only if the # If the jdkCA constraint is not set, then all chains using the
# algorithm is used in a certificate chain that terminates at a marked # specified algorithm are restricted. jdkCA may only be used once in
# trust anchor in the lib/security/cacerts keystore. If the jdkCA # a DisabledAlgorithm expression.
# constraint is not set, then all chains using the specified algorithm # Example: To apply this constraint to SHA-1 certificates, include
# are restricted. jdkCA may only be used once in a DisabledAlgorithm # the following: "SHA1 jdkCA"
# expression.
# Example:  To apply this constraint to SHA-1 certificates, include
# the following:  "SHA1 jdkCA"
#
# DenyAfterConstraint:
# denyAfter YYYY-MM-DD
# This constraint prohibits a certificate with the specified algorithm
# from being used after the date regardless of the certificate's
# validity.  JAR files that are signed and timestamped before the
# constraint date with certificates containing the disabled algorithm
# will not be restricted.  The date is processed in the UTC timezone.
# This constraint can only be used once in a DisabledAlgorithm
# expression.
# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020,
# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03"
# #
# When an algorithm must satisfy more than one constraint, it must be # When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a # delimited by an ampersand '&'. For example, to restrict certificates in a
......
...@@ -424,7 +424,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -424,7 +424,9 @@ krb5.kdc.bad.policy = tryLast
# describes the mechanism for disabling algorithms based on algorithm name # describes the mechanism for disabling algorithms based on algorithm name
# and/or key length. This includes algorithms used in certificates, as well # and/or key length. This includes algorithms used in certificates, as well
# as revocation information such as CRLs and signed OCSP Responses. # as revocation information such as CRLs and signed OCSP Responses.
# The syntax of the disabled algorithm string is described as follows: #
# The syntax of the disabled algorithm string is described as this Java
# BNF-style:
# DisabledAlgorithms: # DisabledAlgorithms:
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
...@@ -435,22 +437,25 @@ krb5.kdc.bad.policy = tryLast ...@@ -435,22 +437,25 @@ krb5.kdc.bad.policy = tryLast
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint | CAConstraint | DenyAfterConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator KeyLength # keySize Operator DecimalInteger
# #
# Operator: # Operator:
# <= | < | == | != | >= | > # <= | < | == | != | >= | >
# #
# KeyLength: # DecimalInteger:
# Integer value of the algorithm's key length in bits # DecimalDigits
# #
# CAConstraint: # DecimalDigits:
# jdkCA # DecimalDigit {DecimalDigit}
#
# DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0
# #
# DenyAfterConstraint: # CertConstraint
# denyAfter YYYY-MM-DD # jdkCA
# #
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
...@@ -464,42 +469,27 @@ krb5.kdc.bad.policy = tryLast ...@@ -464,42 +469,27 @@ krb5.kdc.bad.policy = tryLast
# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
# will not disable algorithms related to "ECDSA". # will not disable algorithms related to "ECDSA".
# #
# A "Constraint" defines restrictions on the keys and/or certificates for # A "Constraint" provides further guidance for the algorithm being specified.
# a specified AlgorithmName: # The "KeySizeConstraint" requires a key of a valid size range if the
# # "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
# KeySizeConstraint: # key size specified in number of bits. For example, "RSA keySize <= 1024"
# keySize Operator KeyLength # indicates that any RSA key with key size less than or equal to 1024 bits
# The constraint requires a key of a valid size range if the # should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates # that any RSA key with key size less than 1024 or greater than 2048 should
# the key size specified in number of bits. For example, # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# "RSA keySize <= 1024" indicates that any RSA key with key size less # algorithms.
# than or equal to 1024 bits should be disabled, and #
# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key # "CertConstraint" specifies additional constraints for
# with key size less than 1024 or greater than 2048 should be disabled. # certificates that contain algorithms that are restricted:
# This constraint is only used on algorithms that have a key size. #
# # "jdkCA" prohibits the specified algorithm only if the algorithm is used
# CAConstraint: # in a certificate chain that terminates at a marked trust anchor in the
# jdkCA # lib/security/cacerts keystore. All other chains are not affected.
# This constraint prohibits the specified algorithm only if the # If the jdkCA constraint is not set, then all chains using the
# algorithm is used in a certificate chain that terminates at a marked # specified algorithm are restricted. jdkCA may only be used once in
# trust anchor in the lib/security/cacerts keystore. If the jdkCA # a DisabledAlgorithm expression.
# constraint is not set, then all chains using the specified algorithm # Example: To apply this constraint to SHA-1 certificates, include
# are restricted. jdkCA may only be used once in a DisabledAlgorithm # the following: "SHA1 jdkCA"
# expression.
# Example:  To apply this constraint to SHA-1 certificates, include
# the following:  "SHA1 jdkCA"
#
# DenyAfterConstraint:
# denyAfter YYYY-MM-DD
# This constraint prohibits a certificate with the specified algorithm
# from being used after the date regardless of the certificate's
# validity.  JAR files that are signed and timestamped before the
# constraint date with certificates containing the disabled algorithm
# will not be restricted.  The date is processed in the UTC timezone.
# This constraint can only be used once in a DisabledAlgorithm
# expression.
# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020,
# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03"
# #
# When an algorithm must satisfy more than one constraint, it must be # When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a # delimited by an ampersand '&'. For example, to restrict certificates in a
......
...@@ -425,7 +425,9 @@ krb5.kdc.bad.policy = tryLast ...@@ -425,7 +425,9 @@ krb5.kdc.bad.policy = tryLast
# describes the mechanism for disabling algorithms based on algorithm name # describes the mechanism for disabling algorithms based on algorithm name
# and/or key length. This includes algorithms used in certificates, as well # and/or key length. This includes algorithms used in certificates, as well
# as revocation information such as CRLs and signed OCSP Responses. # as revocation information such as CRLs and signed OCSP Responses.
# The syntax of the disabled algorithm string is described as follows: #
# The syntax of the disabled algorithm string is described as this Java
# BNF-style:
# DisabledAlgorithms: # DisabledAlgorithms:
# " DisabledAlgorithm { , DisabledAlgorithm } " # " DisabledAlgorithm { , DisabledAlgorithm } "
# #
...@@ -436,22 +438,25 @@ krb5.kdc.bad.policy = tryLast ...@@ -436,22 +438,25 @@ krb5.kdc.bad.policy = tryLast
# (see below) # (see below)
# #
# Constraint: # Constraint:
# KeySizeConstraint | CAConstraint | DenyAfterConstraint # KeySizeConstraint, CertConstraint
# #
# KeySizeConstraint: # KeySizeConstraint:
# keySize Operator KeyLength # keySize Operator DecimalInteger
# #
# Operator: # Operator:
# <= | < | == | != | >= | > # <= | < | == | != | >= | >
# #
# KeyLength: # DecimalInteger:
# Integer value of the algorithm's key length in bits # DecimalDigits
# #
# CAConstraint: # DecimalDigits:
# jdkCA # DecimalDigit {DecimalDigit}
#
# DecimalDigit: one of
# 1 2 3 4 5 6 7 8 9 0
# #
# DenyAfterConstraint: # CertConstraint
# denyAfter YYYY-MM-DD # jdkCA
# #
# The "AlgorithmName" is the standard algorithm name of the disabled # The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
...@@ -465,42 +470,27 @@ krb5.kdc.bad.policy = tryLast ...@@ -465,42 +470,27 @@ krb5.kdc.bad.policy = tryLast
# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion # that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
# will not disable algorithms related to "ECDSA". # will not disable algorithms related to "ECDSA".
# #
# A "Constraint" defines restrictions on the keys and/or certificates for # A "Constraint" provides further guidance for the algorithm being specified.
# a specified AlgorithmName: # The "KeySizeConstraint" requires a key of a valid size range if the
# # "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
# KeySizeConstraint: # key size specified in number of bits. For example, "RSA keySize <= 1024"
# keySize Operator KeyLength # indicates that any RSA key with key size less than or equal to 1024 bits
# The constraint requires a key of a valid size range if the # should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
# "AlgorithmName" is of a key algorithm. The "KeyLength" indicates # that any RSA key with key size less than 1024 or greater than 2048 should
# the key size specified in number of bits. For example, # be disabled. Note that the "KeySizeConstraint" only makes sense to key
# "RSA keySize <= 1024" indicates that any RSA key with key size less # algorithms.
# than or equal to 1024 bits should be disabled, and #
# "RSA keySize < 1024, RSA keySize > 2048" indicates that any RSA key # "CertConstraint" specifies additional constraints for
# with key size less than 1024 or greater than 2048 should be disabled. # certificates that contain algorithms that are restricted:
# This constraint is only used on algorithms that have a key size. #
# # "jdkCA" prohibits the specified algorithm only if the algorithm is used
# CAConstraint: # in a certificate chain that terminates at a marked trust anchor in the
# jdkCA # lib/security/cacerts keystore. All other chains are not affected.
# This constraint prohibits the specified algorithm only if the # If the jdkCA constraint is not set, then all chains using the
# algorithm is used in a certificate chain that terminates at a marked # specified algorithm are restricted. jdkCA may only be used once in
# trust anchor in the lib/security/cacerts keystore. If the jdkCA # a DisabledAlgorithm expression.
# constraint is not set, then all chains using the specified algorithm # Example: To apply this constraint to SHA-1 certificates, include
# are restricted. jdkCA may only be used once in a DisabledAlgorithm # the following: "SHA1 jdkCA"
# expression.
# Example:  To apply this constraint to SHA-1 certificates, include
# the following:  "SHA1 jdkCA"
#
# DenyAfterConstraint:
# denyAfter YYYY-MM-DD
# This constraint prohibits a certificate with the specified algorithm
# from being used after the date regardless of the certificate's
# validity.  JAR files that are signed and timestamped before the
# constraint date with certificates containing the disabled algorithm
# will not be restricted.  The date is processed in the UTC timezone.
# This constraint can only be used once in a DisabledAlgorithm
# expression.
# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020,
# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03"
# #
# When an algorithm must satisfy more than one constraint, it must be # When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a # delimited by an ampersand '&'. For example, to restrict certificates in a
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册