mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-22 19:08:00 +01:00
Introduce AEADAlgorithmCombination class
This commit is contained in:
parent
8f8b8f534b
commit
678f296b5c
4 changed files with 120 additions and 13 deletions
|
@ -0,0 +1,73 @@
|
|||
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.algorithm;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.bouncycastle.bcpg.sig.PreferredAEADCiphersuites;
|
||||
|
||||
public final class AEADAlgorithmCombination {
|
||||
|
||||
private final AEADAlgorithm aeadAlgorithm;
|
||||
private final SymmetricKeyAlgorithm symmetricKeyAlgorithm;
|
||||
|
||||
/**
|
||||
* AES-128 + OCB is a MUST implement and is therefore implicitly supported.
|
||||
*
|
||||
* @see <a href="https://openpgp-wg.gitlab.io/rfc4880bis/#name-preferred-aead-ciphersuites">
|
||||
* Crypto-Refresh § 5.2.3.15. Preferred AEAD Ciphersuites</a>
|
||||
*/
|
||||
public static AEADAlgorithmCombination AES_128_OCB = AEADAlgorithmCombination.from(
|
||||
SymmetricKeyAlgorithm.AES_128, AEADAlgorithm.OCB);
|
||||
|
||||
private AEADAlgorithmCombination(@Nonnull SymmetricKeyAlgorithm symmetricKeyAlgorithm,
|
||||
@Nonnull AEADAlgorithm aeadAlgorithm) {
|
||||
this.aeadAlgorithm = aeadAlgorithm;
|
||||
this.symmetricKeyAlgorithm = symmetricKeyAlgorithm;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public AEADAlgorithm getAeadAlgorithm() {
|
||||
return aeadAlgorithm;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public SymmetricKeyAlgorithm getSymmetricKeyAlgorithm() {
|
||||
return symmetricKeyAlgorithm;
|
||||
}
|
||||
|
||||
public static AEADAlgorithmCombination from(@Nonnull SymmetricKeyAlgorithm symmetricKeyAlgorithm,
|
||||
@Nonnull AEADAlgorithm aeadAlgorithm) {
|
||||
return new AEADAlgorithmCombination(symmetricKeyAlgorithm, aeadAlgorithm);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static AEADAlgorithmCombination from(PreferredAEADCiphersuites.Combination combination) {
|
||||
return fromIds(combination.getSymmetricAlgorithm(), combination.getAeadAlgorithm());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static AEADAlgorithmCombination requireFrom(PreferredAEADCiphersuites.Combination combination) {
|
||||
return requireFromIds(combination.getSymmetricAlgorithm(), combination.getAeadAlgorithm());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static AEADAlgorithmCombination fromIds(int symmetricAlgorithmId, int aeadAlgorithmId) {
|
||||
SymmetricKeyAlgorithm symmetric = SymmetricKeyAlgorithm.fromId(symmetricAlgorithmId);
|
||||
AEADAlgorithm aead = AEADAlgorithm.fromId(aeadAlgorithmId);
|
||||
|
||||
if (symmetric == null || aead == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AEADAlgorithmCombination(symmetric, aead);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static AEADAlgorithmCombination requireFromIds(int symmetricAlgorithmId, int aeadAlgorithmId) {
|
||||
return from(SymmetricKeyAlgorithm.requireFromId(symmetricAlgorithmId), AEADAlgorithm.requireFromId(aeadAlgorithmId));
|
||||
}
|
||||
}
|
|
@ -18,13 +18,12 @@ import org.bouncycastle.bcpg.sig.PreferredAlgorithms;
|
|||
import org.bouncycastle.bcpg.sig.PrimaryUserID;
|
||||
import org.bouncycastle.bcpg.sig.RevocationKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.pgpainless.algorithm.AEADAlgorithm;
|
||||
import org.pgpainless.algorithm.AEADAlgorithmCombination;
|
||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||
import org.pgpainless.algorithm.Feature;
|
||||
import org.pgpainless.algorithm.HashAlgorithm;
|
||||
import org.pgpainless.algorithm.KeyFlag;
|
||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||
import org.pgpainless.util.Tuple;
|
||||
|
||||
public interface SelfSignatureSubpackets extends BaseSignatureSubpackets {
|
||||
|
||||
|
@ -59,11 +58,11 @@ public interface SelfSignatureSubpackets extends BaseSignatureSubpackets {
|
|||
|
||||
SelfSignatureSubpackets setKeyExpirationTime(@Nullable KeyExpirationTime keyExpirationTime);
|
||||
|
||||
SelfSignatureSubpackets setPreferredAEADCiphersuites(Tuple<SymmetricKeyAlgorithm, AEADAlgorithm>... algorithms);
|
||||
SelfSignatureSubpackets setPreferredAEADCiphersuites(AEADAlgorithmCombination... algorithms);
|
||||
|
||||
SelfSignatureSubpackets setPreferredAEADCiphersuites(Set<Tuple<SymmetricKeyAlgorithm, AEADAlgorithm>> algorithms);
|
||||
SelfSignatureSubpackets setPreferredAEADCiphersuites(Set<AEADAlgorithmCombination> algorithms);
|
||||
|
||||
SelfSignatureSubpackets setPreferredAEADCiphersuites(boolean isCritical, Set<Tuple<SymmetricKeyAlgorithm, AEADAlgorithm>> algorithms);
|
||||
SelfSignatureSubpackets setPreferredAEADCiphersuites(boolean isCritical, Set<AEADAlgorithmCombination> algorithms);
|
||||
|
||||
SelfSignatureSubpackets setPreferredAEADCiphersuites(@Nullable PreferredAEADCiphersuites algorithms);
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ import org.bouncycastle.bcpg.sig.TrustSignature;
|
|||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPSignature;
|
||||
import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
|
||||
import org.pgpainless.algorithm.AEADAlgorithm;
|
||||
import org.pgpainless.algorithm.AEADAlgorithmCombination;
|
||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||
import org.pgpainless.algorithm.Feature;
|
||||
import org.pgpainless.algorithm.HashAlgorithm;
|
||||
|
@ -51,7 +51,6 @@ import org.pgpainless.algorithm.KeyFlag;
|
|||
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||
import org.pgpainless.key.util.RevocationAttributes;
|
||||
import org.pgpainless.util.Tuple;
|
||||
|
||||
public class SignatureSubpackets
|
||||
implements BaseSignatureSubpackets, SelfSignatureSubpackets, CertificationSubpackets, RevocationSignatureSubpackets {
|
||||
|
@ -318,23 +317,24 @@ public class SignatureSubpackets
|
|||
}
|
||||
|
||||
@Override
|
||||
public SelfSignatureSubpackets setPreferredAEADCiphersuites(Tuple<SymmetricKeyAlgorithm, AEADAlgorithm>... algorithms) {
|
||||
public SelfSignatureSubpackets setPreferredAEADCiphersuites(AEADAlgorithmCombination... algorithms) {
|
||||
return setPreferredAEADCiphersuites(new LinkedHashSet<>(Arrays.asList(algorithms)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelfSignatureSubpackets setPreferredAEADCiphersuites(Set<Tuple<SymmetricKeyAlgorithm, AEADAlgorithm>> algorithms) {
|
||||
public SelfSignatureSubpackets setPreferredAEADCiphersuites(Set<AEADAlgorithmCombination> algorithms) {
|
||||
return setPreferredAEADCiphersuites(false, algorithms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelfSignatureSubpackets setPreferredAEADCiphersuites(boolean isCritical, Set<Tuple<SymmetricKeyAlgorithm, AEADAlgorithm>> algorithms) {
|
||||
public SelfSignatureSubpackets setPreferredAEADCiphersuites(boolean isCritical, Set<AEADAlgorithmCombination> algorithms) {
|
||||
List<PreferredAEADCiphersuites.Combination> combinations = new ArrayList<>();
|
||||
Iterator<Tuple<SymmetricKeyAlgorithm, AEADAlgorithm>> iterator = algorithms.iterator();
|
||||
Iterator<AEADAlgorithmCombination> iterator = algorithms.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Tuple<SymmetricKeyAlgorithm, AEADAlgorithm> tuple = iterator.next();
|
||||
AEADAlgorithmCombination combination = iterator.next();
|
||||
combinations.add(new PreferredAEADCiphersuites.Combination(
|
||||
tuple.getA().getAlgorithmId(), tuple.getB().getAlgorithmId()));
|
||||
combination.getSymmetricKeyAlgorithm().getAlgorithmId(),
|
||||
combination.getAeadAlgorithm().getAlgorithmId()));
|
||||
}
|
||||
PreferredAEADCiphersuites subpacket = new PreferredAEADCiphersuites(
|
||||
isCritical, combinations.toArray(new PreferredAEADCiphersuites.Combination[0]));
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.bouncycastle.bcpg.sig.IssuerKeyID;
|
|||
import org.bouncycastle.bcpg.sig.KeyExpirationTime;
|
||||
import org.bouncycastle.bcpg.sig.KeyFlags;
|
||||
import org.bouncycastle.bcpg.sig.NotationData;
|
||||
import org.bouncycastle.bcpg.sig.PreferredAEADCiphersuites;
|
||||
import org.bouncycastle.bcpg.sig.PreferredAlgorithms;
|
||||
import org.bouncycastle.bcpg.sig.PrimaryUserID;
|
||||
import org.bouncycastle.bcpg.sig.RegularExpression;
|
||||
|
@ -37,6 +38,7 @@ import org.bouncycastle.openpgp.PGPPublicKey;
|
|||
import org.bouncycastle.openpgp.PGPSignature;
|
||||
import org.bouncycastle.openpgp.PGPSignatureList;
|
||||
import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
|
||||
import org.pgpainless.algorithm.AEADAlgorithmCombination;
|
||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||
import org.pgpainless.algorithm.Feature;
|
||||
import org.pgpainless.algorithm.HashAlgorithm;
|
||||
|
@ -334,6 +336,39 @@ public final class SignatureSubpacketsUtil {
|
|||
return algorithms;
|
||||
}
|
||||
|
||||
public static @Nullable PreferredAEADCiphersuites getPreferredAEADAlgorithms(PGPSignature signature) {
|
||||
org.bouncycastle.bcpg.SignatureSubpacket subpacket = hashed(signature, SignatureSubpacket.preferredAEADAlgorithms);
|
||||
if (subpacket == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Workaround for https://github.com/pgpainless/pgpainless/pull/399
|
||||
// TODO: Remove when BC 1.77 is released
|
||||
if (subpacket instanceof PreferredAlgorithms) {
|
||||
List<PreferredAEADCiphersuites.Combination> combinationList = new ArrayList<>();
|
||||
int[] algorithms = ((PreferredAlgorithms) subpacket).getPreferences();
|
||||
for (int i = 0; i < algorithms.length; i += 2) {
|
||||
combinationList.add(new PreferredAEADCiphersuites.Combination(algorithms[i], algorithms[i + 1]));
|
||||
}
|
||||
PreferredAEADCiphersuites aead = new PreferredAEADCiphersuites(
|
||||
subpacket.isCritical(), combinationList.toArray(new PreferredAEADCiphersuites.Combination[0]));
|
||||
return aead;
|
||||
}
|
||||
|
||||
return (PreferredAEADCiphersuites) subpacket;
|
||||
}
|
||||
|
||||
public static @Nonnull Set<AEADAlgorithmCombination> parsePreferredAEADAlgorithms(PGPSignature signature) {
|
||||
Set<AEADAlgorithmCombination> algorithms = new LinkedHashSet<>();
|
||||
PreferredAEADCiphersuites preferences = getPreferredAEADAlgorithms(signature);
|
||||
if (preferences != null) {
|
||||
for (PreferredAEADCiphersuites.Combination combination : preferences.getAlgorithms()) {
|
||||
algorithms.add(AEADAlgorithmCombination.from(combination));
|
||||
}
|
||||
}
|
||||
return algorithms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the primary user-id subpacket from the signatures hashed area.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue