1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-12-10 22:31:09 +01:00

Change SymmetricEncryptionAlgorithmNegotiator to return the 'best' avail. alg

This commit is contained in:
Paul Schaub 2021-07-01 21:33:38 +02:00
parent 30740aba4f
commit 9b046a0cf1
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
4 changed files with 124 additions and 22 deletions

View file

@ -17,7 +17,7 @@ package org.pgpainless.algorithm.negotiation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -53,8 +53,8 @@ public interface SymmetricKeyAlgorithmNegotiator {
return override;
}
// Count score (occurrences) of each algorithm
Map<SymmetricKeyAlgorithm, Integer> supportWeight = new LinkedHashMap<>();
for (Set<SymmetricKeyAlgorithm> keyPreferences : preferences) {
for (SymmetricKeyAlgorithm preferred : keyPreferences) {
if (supportWeight.containsKey(preferred)) {
@ -65,21 +65,33 @@ public interface SymmetricKeyAlgorithmNegotiator {
}
}
List<SymmetricKeyAlgorithm> scoreboard = new ArrayList<>(supportWeight.keySet());
// Sort scoreboard by descending popularity
Collections.sort(scoreboard, new Comparator<SymmetricKeyAlgorithm>() {
@Override
public int compare(SymmetricKeyAlgorithm t0, SymmetricKeyAlgorithm t1) {
return -supportWeight.get(t0).compareTo(supportWeight.get(t1));
// Pivot the score map
Map<Integer, List<SymmetricKeyAlgorithm>> byScore = new HashMap<>();
for (SymmetricKeyAlgorithm algorithm : supportWeight.keySet()) {
int score = supportWeight.get(algorithm);
List<SymmetricKeyAlgorithm> withSameScore = byScore.get(score);
if (withSameScore == null) {
withSameScore = new ArrayList<>();
byScore.put(score, withSameScore);
}
});
withSameScore.add(algorithm);
}
for (SymmetricKeyAlgorithm mostWanted : scoreboard) {
if (policy.isAcceptable(mostWanted)) {
return mostWanted;
List<Integer> scores = new ArrayList<>(byScore.keySet());
// Sort map and iterate from highest to lowest score
Collections.sort(scores);
for (int i = scores.size() - 1; i >= 0; i--) {
int score = scores.get(i);
List<SymmetricKeyAlgorithm> withSameScore = byScore.get(score);
// Select best algorithm
SymmetricKeyAlgorithm best = policy.selectBest(withSameScore);
if (best != null) {
return best;
}
}
// If no algorithm is acceptable, choose fallback
return policy.getDefaultSymmetricKeyAlgorithm();
}
};

View file

@ -231,14 +231,14 @@ public final class Policy {
public static SymmetricKeyAlgorithmPolicy defaultSymmetricKeyEncryptionAlgorithmPolicy() {
return new SymmetricKeyAlgorithmPolicy(SymmetricKeyAlgorithm.AES_256, Arrays.asList(
// Reject: Unencrypted, IDEA, TripleDES, CAST5
SymmetricKeyAlgorithm.BLOWFISH,
SymmetricKeyAlgorithm.AES_128,
SymmetricKeyAlgorithm.AES_192,
SymmetricKeyAlgorithm.AES_256,
SymmetricKeyAlgorithm.AES_192,
SymmetricKeyAlgorithm.AES_128,
SymmetricKeyAlgorithm.BLOWFISH,
SymmetricKeyAlgorithm.TWOFISH,
SymmetricKeyAlgorithm.CAMELLIA_128,
SymmetricKeyAlgorithm.CAMELLIA_256,
SymmetricKeyAlgorithm.CAMELLIA_192,
SymmetricKeyAlgorithm.CAMELLIA_256
SymmetricKeyAlgorithm.CAMELLIA_128
));
}
@ -251,16 +251,34 @@ public final class Policy {
return new SymmetricKeyAlgorithmPolicy(SymmetricKeyAlgorithm.AES_256, Arrays.asList(
// Reject: Unencrypted, IDEA, TripleDES
SymmetricKeyAlgorithm.CAST5,
SymmetricKeyAlgorithm.BLOWFISH,
SymmetricKeyAlgorithm.AES_128,
SymmetricKeyAlgorithm.AES_192,
SymmetricKeyAlgorithm.AES_256,
SymmetricKeyAlgorithm.AES_192,
SymmetricKeyAlgorithm.AES_128,
SymmetricKeyAlgorithm.BLOWFISH,
SymmetricKeyAlgorithm.TWOFISH,
SymmetricKeyAlgorithm.CAMELLIA_128,
SymmetricKeyAlgorithm.CAMELLIA_256,
SymmetricKeyAlgorithm.CAMELLIA_192,
SymmetricKeyAlgorithm.CAMELLIA_256
SymmetricKeyAlgorithm.CAMELLIA_128
));
}
/**
* Select the best acceptable algorithm from the options list.
* The best algorithm is the first algorithm we encounter in our list of acceptable algorithms that
* is also contained in the list of options.
*
*
* @param options list of algorithm options
* @return best
*/
public SymmetricKeyAlgorithm selectBest(List<SymmetricKeyAlgorithm> options) {
for (SymmetricKeyAlgorithm acceptable : acceptableSymmetricKeyAlgorithms) {
if (options.contains(acceptable)) {
return acceptable;
}
}
return null;
}
}
public static final class HashAlgorithmPolicy {