mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-12-10 06:11:08 +01:00
Do some first prototype algorithm negotiation
This commit is contained in:
parent
909f0e7be3
commit
4e63313c91
4 changed files with 239 additions and 2 deletions
|
|
@ -17,6 +17,12 @@ package org.pgpainless.encryption_signing;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
|
|
@ -31,6 +37,8 @@ import org.pgpainless.algorithm.HashAlgorithm;
|
|||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||
import org.pgpainless.decryption_verification.OpenPgpMetadata;
|
||||
import org.pgpainless.exception.KeyValidationException;
|
||||
import org.pgpainless.key.SubkeyIdentifier;
|
||||
import org.pgpainless.key.info.KeyView;
|
||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||
import org.pgpainless.policy.Policy;
|
||||
import org.pgpainless.util.Passphrase;
|
||||
|
|
@ -267,7 +275,33 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
|||
return encryptionAlgorithmOverride;
|
||||
}
|
||||
|
||||
// TODO: Negotiation
|
||||
Map<SymmetricKeyAlgorithm, Integer> supportWeight = new LinkedHashMap<>();
|
||||
|
||||
for (SubkeyIdentifier key : encryptionOptions.getKeyViews().keySet()) {
|
||||
KeyView keyView = encryptionOptions.getKeyViews().get(key);
|
||||
for (SymmetricKeyAlgorithm preferred : keyView.getPreferredSymmetricKeyAlgorithms()) {
|
||||
if (supportWeight.containsKey(preferred)) {
|
||||
supportWeight.put(preferred, supportWeight.get(preferred) + 1);
|
||||
} else {
|
||||
supportWeight.put(preferred, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
});
|
||||
|
||||
for (SymmetricKeyAlgorithm mostWanted : scoreboard) {
|
||||
if (PGPainless.getPolicy().getSymmetricKeyEncryptionAlgorithmPolicy().isAcceptable(mostWanted)) {
|
||||
return mostWanted;
|
||||
}
|
||||
}
|
||||
|
||||
return PGPainless.getPolicy().getSymmetricKeyEncryptionAlgorithmPolicy().getDefaultSymmetricKeyAlgorithm();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
|||
import org.pgpainless.implementation.ImplementationFactory;
|
||||
import org.pgpainless.key.SubkeyIdentifier;
|
||||
import org.pgpainless.key.info.KeyRingInfo;
|
||||
import org.pgpainless.key.info.KeyView;
|
||||
import org.pgpainless.util.Passphrase;
|
||||
|
||||
/**
|
||||
|
|
@ -66,6 +67,7 @@ public class EncryptionOptions {
|
|||
private final Set<PGPKeyEncryptionMethodGenerator> encryptionMethods = new LinkedHashSet<>();
|
||||
private final Set<SubkeyIdentifier> encryptionKeys = new LinkedHashSet<>();
|
||||
private final Map<SubkeyIdentifier, KeyRingInfo> keyRingInfo = new HashMap<>();
|
||||
private final Map<SubkeyIdentifier, KeyView> keyViews = new HashMap<>();
|
||||
private final EncryptionKeySelector encryptionKeySelector = encryptToFirstSubkey();
|
||||
|
||||
private SymmetricKeyAlgorithm encryptionAlgorithmOverride = null;
|
||||
|
|
@ -131,6 +133,9 @@ public class EncryptionOptions {
|
|||
}
|
||||
|
||||
for (PGPPublicKey encryptionSubkey : encryptionSubkeys) {
|
||||
SubkeyIdentifier keyId = new SubkeyIdentifier(key, encryptionSubkey.getKeyID());
|
||||
keyRingInfo.put(keyId, info);
|
||||
keyViews.put(keyId, new KeyView.ViaUserId(info, keyId, userId));
|
||||
addRecipientKey(key, encryptionSubkey);
|
||||
}
|
||||
|
||||
|
|
@ -162,6 +167,9 @@ public class EncryptionOptions {
|
|||
}
|
||||
|
||||
for (PGPPublicKey encryptionSubkey : encryptionSubkeys) {
|
||||
SubkeyIdentifier keyId = new SubkeyIdentifier(key, encryptionSubkey.getKeyID());
|
||||
keyRingInfo.put(keyId, info);
|
||||
keyViews.put(keyId, new KeyView.ViaKeyId(info, keyId));
|
||||
addRecipientKey(key, encryptionSubkey);
|
||||
}
|
||||
|
||||
|
|
@ -204,14 +212,22 @@ public class EncryptionOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Set<PGPKeyEncryptionMethodGenerator> getEncryptionMethods() {
|
||||
Set<PGPKeyEncryptionMethodGenerator> getEncryptionMethods() {
|
||||
return new HashSet<>(encryptionMethods);
|
||||
}
|
||||
|
||||
Map<SubkeyIdentifier, KeyRingInfo> getKeyRingInfo() {
|
||||
return new HashMap<>(keyRingInfo);
|
||||
}
|
||||
|
||||
public Set<SubkeyIdentifier> getEncryptionKeyIdentifiers() {
|
||||
return new HashSet<>(encryptionKeys);
|
||||
}
|
||||
|
||||
public Map<SubkeyIdentifier, KeyView> getKeyViews() {
|
||||
return new HashMap<>(keyViews);
|
||||
}
|
||||
|
||||
public SymmetricKeyAlgorithm getEncryptionAlgorithmOverride() {
|
||||
return encryptionAlgorithmOverride;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright 2021 Paul Schaub.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pgpainless.key.info;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPSignature;
|
||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||
import org.pgpainless.algorithm.HashAlgorithm;
|
||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||
import org.pgpainless.key.SubkeyIdentifier;
|
||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil;
|
||||
|
||||
public abstract class KeyView {
|
||||
|
||||
protected final KeyRingInfo info;
|
||||
protected final SubkeyIdentifier key;
|
||||
|
||||
public KeyView(KeyRingInfo info, SubkeyIdentifier key) {
|
||||
this.info = info;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public abstract PGPSignature getSignatureWithPreferences();
|
||||
|
||||
public List<SymmetricKeyAlgorithm> getPreferredSymmetricKeyAlgorithms() {
|
||||
List<SymmetricKeyAlgorithm> algos = SignatureSubpacketsUtil.parsePreferredSymmetricKeyAlgorithms(getSignatureWithPreferences());
|
||||
return new ArrayList<>(new LinkedHashSet<>(algos)); // remove duplicates
|
||||
}
|
||||
|
||||
public List<HashAlgorithm> getPreferredHashAlgorithms() {
|
||||
List<HashAlgorithm> algos = SignatureSubpacketsUtil.parsePreferredHashAlgorithms(getSignatureWithPreferences());
|
||||
return new ArrayList<>(new LinkedHashSet<>(algos)); // remove duplicates
|
||||
}
|
||||
|
||||
public List<CompressionAlgorithm> getPreferredCompressionAlgorithms() {
|
||||
List<CompressionAlgorithm> algos = SignatureSubpacketsUtil.parsePreferredCompressionAlgorithms(getSignatureWithPreferences());
|
||||
return new ArrayList<>(new LinkedHashSet<>(algos)); // remove duplicates
|
||||
}
|
||||
|
||||
public static class ViaUserId extends KeyView {
|
||||
|
||||
private final String userId;
|
||||
|
||||
public ViaUserId(KeyRingInfo info, SubkeyIdentifier key, String userId) {
|
||||
super(info, key);
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PGPSignature getSignatureWithPreferences() {
|
||||
return info.getLatestUserIdCertification(userId);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ViaKeyId extends KeyView {
|
||||
|
||||
public ViaKeyId(KeyRingInfo info, SubkeyIdentifier key) {
|
||||
super(info, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PGPSignature getSignatureWithPreferences() {
|
||||
PGPSignature signature = info.getLatestDirectKeySelfSignature();
|
||||
if (signature != null) {
|
||||
return signature;
|
||||
}
|
||||
|
||||
return info.getLatestUserIdCertification(info.getPrimaryUserId());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue