mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-19 11:26:43 +00:00
8178728: Check the AlgorithmParameters in algorithm constraints
Reviewed-by: valeriep, ascarpino
This commit is contained in:
parent
ff3aa035f3
commit
dcb0a2763b
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2017, 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
|
||||
@ -27,6 +27,8 @@ package sun.security.util;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@ -134,6 +136,23 @@ public class AlgorithmDecomposer {
|
||||
return elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get aliases of the specified algorithm.
|
||||
*
|
||||
* May support more algorithms in the future.
|
||||
*/
|
||||
public static Collection<String> getAliases(String algorithm) {
|
||||
String[] aliases;
|
||||
if (algorithm.equalsIgnoreCase("DH") ||
|
||||
algorithm.equalsIgnoreCase("DiffieHellman")) {
|
||||
aliases = new String[] {"DH", "DiffieHellman"};
|
||||
} else {
|
||||
aliases = new String[] {algorithm};
|
||||
}
|
||||
|
||||
return Arrays.asList(aliases);
|
||||
}
|
||||
|
||||
private static void hasLoop(Set<String> elements, String find, String replace) {
|
||||
if (elements.contains(find)) {
|
||||
if (!elements.contains(replace)) {
|
||||
|
||||
@ -45,6 +45,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Collection;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Pattern;
|
||||
@ -106,7 +107,15 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
@Override
|
||||
public final boolean permits(Set<CryptoPrimitive> primitives,
|
||||
String algorithm, AlgorithmParameters parameters) {
|
||||
return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
|
||||
if (!checkAlgorithm(disabledAlgorithms, algorithm, decomposer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parameters != null) {
|
||||
return algorithmConstraints.permits(algorithm, parameters);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -242,7 +251,12 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
List<Constraint> constraintList =
|
||||
constraintsMap.getOrDefault(algorithm,
|
||||
new ArrayList<>(1));
|
||||
constraintsMap.putIfAbsent(algorithm, constraintList);
|
||||
|
||||
// Consider the impact of algorithm aliases.
|
||||
for (String alias : AlgorithmDecomposer.getAliases(algorithm)) {
|
||||
constraintsMap.putIfAbsent(alias, constraintList);
|
||||
}
|
||||
|
||||
if (space <= 0) {
|
||||
constraintList.add(new DisabledConstraint(algorithm));
|
||||
continue;
|
||||
@ -351,6 +365,27 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if constraints permit this AlgorithmParameters.
|
||||
public boolean permits(String algorithm, AlgorithmParameters aps) {
|
||||
List<Constraint> list = getConstraints(algorithm);
|
||||
if (list == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (Constraint constraint : list) {
|
||||
if (!constraint.permits(aps)) {
|
||||
if (debug != null) {
|
||||
debug.println("keySizeConstraint: failed algorithm " +
|
||||
"parameters constraint check " + aps);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if constraints permit this cert.
|
||||
public void permits(String algorithm, ConstraintsParameters cp)
|
||||
throws CertPathValidatorException {
|
||||
@ -444,6 +479,18 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the algorithm constraint permits a given cryptographic
|
||||
* parameters.
|
||||
*
|
||||
* @param parameters the cryptographic parameters
|
||||
* @return 'true' if the cryptographic parameters is allowed,
|
||||
* 'false' ortherwise.
|
||||
*/
|
||||
public boolean permits(AlgorithmParameters parameters) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an algorithm constraint is permitted with a given
|
||||
* ConstraintsParameters.
|
||||
@ -528,6 +575,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
* call next() for any following constraints. If it does not, exit
|
||||
* as this constraint(s) does not restrict the operation.
|
||||
*/
|
||||
@Override
|
||||
public void permits(ConstraintsParameters cp)
|
||||
throws CertPathValidatorException {
|
||||
if (debug != null) {
|
||||
@ -551,100 +599,101 @@ 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");
|
||||
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;
|
||||
DenyAfterConstraint(String algo, int year, int month, int day) {
|
||||
Calendar c;
|
||||
|
||||
algorithm = algo;
|
||||
algorithm = algo;
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("DenyAfterConstraint read in as: year " +
|
||||
year + ", month = " + month + ", day = " + day);
|
||||
}
|
||||
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();
|
||||
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);
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
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(ConstraintsParameters cp)
|
||||
throws CertPathValidatorException {
|
||||
Date currentDate;
|
||||
String errmsg;
|
||||
/*
|
||||
* 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(ConstraintsParameters cp)
|
||||
throws CertPathValidatorException {
|
||||
Date currentDate;
|
||||
String errmsg;
|
||||
|
||||
if (cp.getJARTimestamp() != null) {
|
||||
currentDate = cp.getJARTimestamp().getTimestamp();
|
||||
errmsg = "JAR Timestamp date: ";
|
||||
} else if (cp.getPKIXParamDate() != null) {
|
||||
currentDate = cp.getPKIXParamDate();
|
||||
errmsg = "PKIXParameter date: ";
|
||||
} else {
|
||||
currentDate = new Date();
|
||||
errmsg = "Current date: ";
|
||||
}
|
||||
if (cp.getJARTimestamp() != null) {
|
||||
currentDate = cp.getJARTimestamp().getTimestamp();
|
||||
errmsg = "JAR Timestamp date: ";
|
||||
} else if (cp.getPKIXParamDate() != null) {
|
||||
currentDate = cp.getPKIXParamDate();
|
||||
errmsg = "PKIXParameter date: ";
|
||||
} else {
|
||||
currentDate = new Date();
|
||||
errmsg = "Current date: ";
|
||||
}
|
||||
|
||||
if (!denyAfterDate.after(currentDate)) {
|
||||
if (next(cp)) {
|
||||
return;
|
||||
}
|
||||
throw new CertPathValidatorException(
|
||||
"denyAfter constraint check failed: " + algorithm +
|
||||
" used with Constraint date: " +
|
||||
dateFormat.format(denyAfterDate) + "; " + errmsg +
|
||||
dateFormat.format(currentDate) + extendedMsg(cp),
|
||||
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
|
||||
}
|
||||
}
|
||||
if (!denyAfterDate.after(currentDate)) {
|
||||
if (next(cp)) {
|
||||
return;
|
||||
}
|
||||
throw new CertPathValidatorException(
|
||||
"denyAfter constraint check failed: " + algorithm +
|
||||
" used with Constraint date: " +
|
||||
dateFormat.format(denyAfterDate) + "; " + errmsg +
|
||||
dateFormat.format(currentDate) + extendedMsg(cp),
|
||||
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 result if the constraint's date is beyond the current date
|
||||
* in UTC timezone.
|
||||
*/
|
||||
@Override
|
||||
public boolean permits(Key key) {
|
||||
if (next(key)) {
|
||||
return true;
|
||||
}
|
||||
if (debug != null) {
|
||||
debug.println("DenyAfterConstraints.permits(): " + algorithm);
|
||||
}
|
||||
|
||||
return denyAfterDate.after(new Date());
|
||||
}
|
||||
}
|
||||
return denyAfterDate.after(new Date());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The usage constraint is for the "usage" keyword. It checks against the
|
||||
@ -658,6 +707,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
this.usages = usages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void permits(ConstraintsParameters cp)
|
||||
throws CertPathValidatorException {
|
||||
for (String usage : usages) {
|
||||
@ -746,6 +796,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
* constraint Any permitted constraint will exit the linked list
|
||||
* to allow the operation.
|
||||
*/
|
||||
@Override
|
||||
public void permits(ConstraintsParameters cp)
|
||||
throws CertPathValidatorException {
|
||||
Key key = null;
|
||||
@ -769,6 +820,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
|
||||
// Check if key constraint disable the specified key
|
||||
// Uses old style permit()
|
||||
@Override
|
||||
public boolean permits(Key key) {
|
||||
// If we recursively find a constraint that permits us to use
|
||||
// this key, return true and skip any other constraint checks.
|
||||
@ -782,6 +834,30 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
return permitsImpl(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean permits(AlgorithmParameters parameters) {
|
||||
String paramAlg = parameters.getAlgorithm();
|
||||
if (!algorithm.equalsIgnoreCase(parameters.getAlgorithm())) {
|
||||
// Consider the impact of the algorithm aliases.
|
||||
Collection<String> aliases =
|
||||
AlgorithmDecomposer.getAliases(algorithm);
|
||||
if (!aliases.contains(paramAlg)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int keySize = KeyUtil.getKeySize(parameters);
|
||||
if (keySize == 0) {
|
||||
return false;
|
||||
} else if (keySize > 0) {
|
||||
return !((keySize < minSize) || (keySize > maxSize) ||
|
||||
(prohibitedSize == keySize));
|
||||
} // Otherwise, the key size is not accessible or determined.
|
||||
// Conservatively, please don't disable such keys.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean permitsImpl(Key key) {
|
||||
// Verify this constraint is for this public key algorithm
|
||||
if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) {
|
||||
@ -809,6 +885,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
algorithm = algo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void permits(ConstraintsParameters cp)
|
||||
throws CertPathValidatorException {
|
||||
throw new CertPathValidatorException(
|
||||
@ -817,6 +894,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean permits(Key key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
package sun.security.util;
|
||||
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.Key;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.AccessController;
|
||||
@ -35,6 +36,8 @@ import java.security.interfaces.DSAKey;
|
||||
import java.security.interfaces.DSAParams;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.interfaces.DHKey;
|
||||
import javax.crypto.interfaces.DHPublicKey;
|
||||
@ -99,6 +102,61 @@ public final class KeyUtil {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key size of the given cryptographic parameters in bits.
|
||||
*
|
||||
* @param parameters the cryptographic parameters, cannot be null
|
||||
* @return the key size of the given cryptographic parameters in bits,
|
||||
* or -1 if the key size is not accessible
|
||||
*/
|
||||
public static final int getKeySize(AlgorithmParameters parameters) {
|
||||
|
||||
String algorithm = parameters.getAlgorithm();
|
||||
switch (algorithm) {
|
||||
case "EC":
|
||||
try {
|
||||
ECKeySizeParameterSpec ps = parameters.getParameterSpec(
|
||||
ECKeySizeParameterSpec.class);
|
||||
if (ps != null) {
|
||||
return ps.getKeySize();
|
||||
}
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
try {
|
||||
ECParameterSpec ps = parameters.getParameterSpec(
|
||||
ECParameterSpec.class);
|
||||
if (ps != null) {
|
||||
return ps.getOrder().bitLength();
|
||||
}
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// Note: the ECGenParameterSpec case should be covered by the
|
||||
// ECParameterSpec case above.
|
||||
// See ECUtil.getECParameterSpec(Provider, String).
|
||||
|
||||
break;
|
||||
case "DiffieHellman":
|
||||
try {
|
||||
DHParameterSpec ps = parameters.getParameterSpec(
|
||||
DHParameterSpec.class);
|
||||
if (ps != null) {
|
||||
return ps.getP().bitLength();
|
||||
}
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
// ignore
|
||||
}
|
||||
break;
|
||||
|
||||
// May support more AlgorithmParameters algorithms in the future.
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the key is valid or not.
|
||||
* <P>
|
||||
|
||||
@ -38,6 +38,20 @@
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe4096 UseStrongDHSizes 2048
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe6144 UseStrongDHSizes 2048
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe8192 UseStrongDHSizes 2048
|
||||
* @run main/othervm UseStrongDHSizes 3072
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe3072 UseStrongDHSizes 3072
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe4096 UseStrongDHSizes 3072
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe6144 UseStrongDHSizes 3072
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe8192 UseStrongDHSizes 3072
|
||||
* @run main/othervm UseStrongDHSizes 4096
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe4096 UseStrongDHSizes 4096
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe6144 UseStrongDHSizes 4096
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe8192 UseStrongDHSizes 4096
|
||||
* @run main/othervm UseStrongDHSizes 6144
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe6144 UseStrongDHSizes 6144
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe8192 UseStrongDHSizes 6144
|
||||
* @run main/othervm UseStrongDHSizes 8192
|
||||
* @run main/othervm -Djdk.tls.namedGroups=ffdhe8192 UseStrongDHSizes 8192
|
||||
*/
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user