mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-30 08:12:06 +01:00
Incorporate feedback
This commit is contained in:
parent
5364e21b5e
commit
aef9ebfd7b
1 changed files with 43 additions and 11 deletions
|
@ -42,16 +42,6 @@ public class PublicKeyParameterValidationUtil {
|
||||||
throws KeyIntegrityException, PGPException {
|
throws KeyIntegrityException, PGPException {
|
||||||
PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.fromId(publicKey.getAlgorithm());
|
PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.fromId(publicKey.getAlgorithm());
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
// Additional to the algorithm-specific tests further below, we also perform
|
|
||||||
// generic functionality tests with the key, such as whether it is able to decrypt encrypted data
|
|
||||||
// or verify signatures.
|
|
||||||
// These tests should be more or less constant time.
|
|
||||||
if (publicKeyAlgorithm.isSigningCapable()) {
|
|
||||||
valid = verifyCanSign(privateKey, publicKey) && valid;
|
|
||||||
}
|
|
||||||
if (publicKeyAlgorithm.isEncryptionCapable()) {
|
|
||||||
valid = verifyCanDecrypt(privateKey, publicKey) && valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Algorithm specific validations
|
// Algorithm specific validations
|
||||||
BCPGKey key = privateKey.getPrivateKeyDataPacket();
|
BCPGKey key = privateKey.getPrivateKeyDataPacket();
|
||||||
|
@ -77,6 +67,21 @@ public class PublicKeyParameterValidationUtil {
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
throw new KeyIntegrityException();
|
throw new KeyIntegrityException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Additional to the algorithm-specific tests further above, we also perform
|
||||||
|
// generic functionality tests with the key, such as whether it is able to decrypt encrypted data
|
||||||
|
// or verify signatures.
|
||||||
|
// These tests should be more or less constant time.
|
||||||
|
if (publicKeyAlgorithm.isSigningCapable()) {
|
||||||
|
valid = verifyCanSign(privateKey, publicKey);
|
||||||
|
}
|
||||||
|
if (publicKeyAlgorithm.isEncryptionCapable()) {
|
||||||
|
valid = verifyCanDecrypt(privateKey, publicKey) && valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
throw new KeyIntegrityException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean verifyCanSign(PGPPrivateKey privateKey, PGPPublicKey publicKey) throws PGPException {
|
private static boolean verifyCanSign(PGPPrivateKey privateKey, PGPPublicKey publicKey) throws PGPException {
|
||||||
|
@ -149,19 +154,46 @@ public class PublicKeyParameterValidationUtil {
|
||||||
BigInteger sX = privateKey.getX();
|
BigInteger sX = privateKey.getX();
|
||||||
|
|
||||||
boolean pPrime = pP.isProbablePrime(certainty);
|
boolean pPrime = pP.isProbablePrime(certainty);
|
||||||
|
if (!pPrime) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
boolean qPrime = pQ.isProbablePrime(certainty);
|
boolean qPrime = pQ.isProbablePrime(certainty);
|
||||||
|
if (!qPrime) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// q > 160 bits
|
// q > 160 bits
|
||||||
boolean qLarge = pQ.getLowestSetBit() > 160;
|
boolean qLarge = pQ.getLowestSetBit() > 160;
|
||||||
|
if (!qLarge) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// q divides p - 1
|
// q divides p - 1
|
||||||
boolean qDividesPminus1 = pP.subtract(BigInteger.ONE).mod(pQ).equals(BigInteger.ZERO);
|
boolean qDividesPminus1 = pP.subtract(BigInteger.ONE).mod(pQ).equals(BigInteger.ZERO);
|
||||||
|
if (!qDividesPminus1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// 1 < g < p
|
// 1 < g < p
|
||||||
boolean gInBounds = BigInteger.ONE.max(pG).equals(pG) && pG.max(pP).equals(pP);
|
boolean gInBounds = BigInteger.ONE.max(pG).equals(pG) && pG.max(pP).equals(pP);
|
||||||
|
if (!gInBounds) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// g^q = 1 mod p
|
// g^q = 1 mod p
|
||||||
boolean gPowXModPEquals1 = pG.modPow(pQ, pP).equals(BigInteger.ONE);
|
boolean gPowXModPEquals1 = pG.modPow(pQ, pP).equals(BigInteger.ONE);
|
||||||
|
if (!gPowXModPEquals1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// y = g^x mod p
|
// y = g^x mod p
|
||||||
boolean yEqualsGPowXModP = pY.equals(pG.modPow(sX, pP));
|
boolean yEqualsGPowXModP = pY.equals(pG.modPow(sX, pP));
|
||||||
|
if (!yEqualsGPowXModP) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return pPrime && qPrime && qLarge && qDividesPminus1 && gInBounds && gPowXModPEquals1 && yEqualsGPowXModP;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean verifyRSAKeyIntegrity(RSASecretBCPGKey secretKey, RSAPublicBCPGKey publicKey)
|
private static boolean verifyRSAKeyIntegrity(RSASecretBCPGKey secretKey, RSAPublicBCPGKey publicKey)
|
||||||
|
|
Loading…
Reference in a new issue