Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*************************************************************************
* *
* CESeCore: CE Security Core *
* *
* This software is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or any later version. *
* *
* See terms of license at gnu.org. *
* *
*************************************************************************/
package org.cesecore.keys.validation;
import java.math.BigInteger;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.bouncycastle.math.Primes;
import org.cesecore.certificates.certificateprofile.CertificateProfile;
import org.cesecore.certificates.certificateprofile.CertificateProfileConstants;
import org.cesecore.certificates.util.AlgorithmConstants;
import org.cesecore.keys.util.KeyTools;
import org.cesecore.profiles.Profile;
import org.cesecore.util.ui.DynamicUiActionCallback;
import org.cesecore.util.ui.DynamicUiCallbackException;
import org.cesecore.util.ui.DynamicUiModel;
import org.cesecore.util.ui.DynamicUiProperty;
/**
* Default RSA key validator.
*
* The key validator is used to implement the CA/B-Forum requirements for RSA public
* key quality requirements, including FIPS 186-4 and NIST (SP 800-89 and NIST SP 56A: Revision 2)
* requirements. See: https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.4.2.pdf section 6.1.6
*
* @version $Id: RsaKeyValidator.java 29467 2018-07-05 16:23:04Z mikekushner $
*/
public class RsaKeyValidator extends KeyValidatorBase {
private static final long serialVersionUID = -335429118359811926L;
/** Class logger. */
private static final Logger log = Logger.getLogger(RsaKeyValidator.class);
/** MUST be at least 2048 bits key size. */
public static final int CAB_FORUM_BLR_142_KEY_SIZE_MIN = 2048;
/** SHOULD be odd exponent. */
public static final boolean CAB_FORUM_BLR_142_PUBLIC_EXPONENT_ONLY_ALLOW_ODD = true;
/** MUST be >= 3, SHOULD be > 2^16+1 = 65.536+1 */
public static final String CAB_FORUM_BLR_142_PUBLIC_EXPONENT_MIN = "65537";
/** SHOULD be <= 2^256-1 = 115792089237316195423570985008687907853269984665640564039457584007913129639936-1 = 2^64*2^4-1 */
public static final String CAB_FORUM_BLR_142_PUBLIC_EXPONENT_MAX = "115792089237316195423570985008687907853269984665640564039457584007913129639935";
/** SHOULD be odd modulus. */
public static final boolean CAB_FORUM_BLR_142_PUBLIC_MODULUS_ONLY_ALLOW_ODD = true;
/** SHOULD not be the power of a prime. */
public static final boolean CAB_FORUM_BLR_142_PUBLIC_MODULUS_DONT_ALLOW_POWER_OF_PRIME = true;
/** SHOULD be with smallest factor >= 752 */
public static final int CAB_FORUM_BLR_142_PUBLIC_MODULUS_SMALLEST_FACTOR = 752;
/** The key validator type. */
private static final String TYPE_IDENTIFIER = "RSA_KEY_VALIDATOR";
protected static final String BIT_LENGTHS = "bitLengths";
protected static final String PUBLIC_KEY_EXPONENT_ONLY_ALLOW_ODD = "publicKeyExponentOnlyAllowOdd";
protected static final String PUBLIC_KEY_EXPONENT_MIN = "publicKeyExponentMin";
protected static final String PUBLIC_KEY_EXPONENT_MAX = "publicKeyExponentMax";
protected static final String PUBLIC_KEY_MODULUS_ONLY_ALLOW_ODD = "publicKeyModulusOnlyAllowOdd";
protected static final String PUBLIC_KEY_MODULUS_DONT_ALLOW_POWER_OF_PRIME = "publicKeyModulusDontAllowPowerOfPrime";
protected static final String PUBLIC_KEY_MODULUS_DONT_ALLOW_ROCA_WEAK_KEYS = "publicKeyModulusDontAllowRocaWeakKeys";
protected static final String PUBLIC_KEY_MODULUS_MIN_FACTOR = "publicKeyModulusMinFactor";
protected static final String PUBLIC_KEY_MODULUS_MIN = "publicKeyModulusMin";
protected static final String PUBLIC_KEY_MODULUS_MAX = "publicKeyModulusMax";
/**
* Tests if the factors of the BigInteger modulus are prime.
* @param modulus the big integer modulus to test
* @return true if the modulus is power of a prime, false otherwise.
*/
protected static boolean isPowerOfPrime(BigInteger modulus) {
// The isPowerOfPrime test is copied from org.bouncycastle.crypto.asymmetric.KeyUtils in the BC-FIPS package.
// If we move to use the FIPS provider we can use the methods directly instead
// --- Begin BC code
// Use the same iterations as if we were testing a candidate p or q value with error probability 2^-100
int bits = modulus.bitLength();
int iterations = bits >= 1536 ? 3
: bits >= 1024 ? 4
: bits >= 512 ? 7
: 50;
// SP 800-89 requires use of an approved DRBG.
// SecureRandom testRandom = FipsDRBG.SHA256.fromEntropySource(new SecureRandom(), false)
// .build(Pack.longToBigEndian(System.currentTimeMillis()), false, Strings.toByteArray(Thread.currentThread().toString()));
SecureRandom testRandom = new SecureRandom(); // we cheat a little and use regular SecureRandom, which is good
Primes.MROutput mr = Primes.enhancedMRProbablePrimeTest(modulus, testRandom, iterations);
if (!mr.isProvablyComposite())
{
// FSM_TRANS:5.16, "FIPS 186-3/SP 800-89 ASSURANCES CHECK", "CONDITIONAL TEST", "FIPS 186-3/SP 800-89 Assurances test failed"
log.debug("RSA modulus is not composite");
return true;
}
if (!mr.isNotPrimePower())
{
// FSM_TRANS:5.16, "FIPS 186-3/SP 800-89 ASSURANCES CHECK", "CONDITIONAL TEST", "FIPS 186-3/SP 800-89 Assurances test failed"
log.debug("RSA modulus is a power of a prime");
return true;
}
// --- end BC code
return false;
}
// public static boolean isPowerOfPrime(BigInteger modulus) {
// BigInteger n = modulus;
// final Set result = new TreeSet();
// for (BigInteger i = BigInteger.valueOf(2); i.compareTo(n.divide(i).add(BigInteger.ONE)) == -1; i = i.add(BigInteger.ONE)) {
// while (n.mod(i).compareTo(BigInteger.ZERO) == 0) {
// if (result.contains(i)) { // is power of a prime.
// return true;
// }
// result.add(i);
// n = n.divide(i);
// }
// }
// if (n.compareTo(BigInteger.ONE) == 1) {
// if (result.contains(n)) { // is power of a prime.
// return true;
// }
// result.add(n);
// }
// return false;
// }
// /**
// * Checks if the given value is a prime.
// * @param value the positive integer value.
// * @return true if the value is a prime.
// */
// public static final boolean isPrime(BigInteger value) {
// if (!value.isProbablePrime(5)) {
// return false;
// }
// final BigInteger two = BigInteger.valueOf(2);
// if (!two.equals(value) && BigInteger.ZERO.equals(value.mod(two))) {
// return false;
// }
// for (BigInteger i = BigInteger.valueOf(3); i.multiply(i).compareTo(value) < 1; i = i.add(two)) {
// if (value.mod(i).equals(BigInteger.ZERO)) {
// return false;
// }
// }
// return true;
// }
/**
* Gets the smallest factor of the positive natural number greater than 2.
* @param n the number
* @return the smallest factor or 2 for n=0.
*/
protected static final boolean hasSmallerFactorThan(BigInteger n, int intFactor) {
// BigInteger factor = BigInteger.valueOf(intFactor);
final BigInteger two = new BigInteger("2");
if (intFactor < 3) {
return false;
}
if (n.mod(two).equals(BigInteger.ZERO) && intFactor > 2) {
return true;
}
for (int i = intFactor; i > 2; i = i - 2) {
if (n.mod(BigInteger.valueOf(i)).equals(BigInteger.ZERO)) {
return true;
}
}
return false;
}
/**
* Public constructor needed for deserialization.
*/
public RsaKeyValidator() {
super();
}
/**
* Creates a new instance.
*/
public RsaKeyValidator(final String name) {
super(name);
}
@Override
public void init() {
super.init();
if (null == data.get(BIT_LENGTHS)) {
setBitLengths(new ArrayList());
}
if (null == data.get(PUBLIC_KEY_EXPONENT_ONLY_ALLOW_ODD)) {
setPublicKeyExponentOnlyAllowOdd(false);
}
if (null == data.get(PUBLIC_KEY_MODULUS_ONLY_ALLOW_ODD)) {
setPublicKeyModulusOnlyAllowOdd(false);
}
if (null == data.get(PUBLIC_KEY_MODULUS_DONT_ALLOW_POWER_OF_PRIME)) {
setPublicKeyModulusDontAllowPowerOfPrime(false);
}
if (null == data.get(PUBLIC_KEY_MODULUS_DONT_ALLOW_ROCA_WEAK_KEYS)) {
setPublicKeyModulusDontAllowRocaWeakKeys(true);
}
}
@Override
@SuppressWarnings({ "serial", "unchecked" })
public void initDynamicUiModel() {
uiModel = new DynamicUiModel(data);
uiModel.add(new DynamicUiProperty("settings"));
final DynamicUiProperty settingsTemplate = new DynamicUiProperty(Integer.class, SETTINGS_TEMPLATE, getSettingsTemplate(), KeyValidatorSettingsTemplate.types());
settingsTemplate.setRenderingHint(DynamicUiProperty.RENDER_SELECT_ONE);
settingsTemplate.setLabels(KeyValidatorSettingsTemplate.map());
settingsTemplate.setRequired(true);
settingsTemplate.setActionCallback(new DynamicUiActionCallback() {
@Override
public void action(final Object parameter) throws DynamicUiCallbackException {
final Map