From 3b6c8cb7f558e9480ccd88fa98a88287bf6e3495 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Fri, 4 Aug 2023 17:03:43 +0200 Subject: [PATCH] Kotlin conversion: Feature --- .../org/pgpainless/algorithm/Feature.java | 152 ------------------ .../java/org/pgpainless/algorithm/Feature.kt | 83 ++++++++++ 2 files changed, 83 insertions(+), 152 deletions(-) delete mode 100644 pgpainless-core/src/main/java/org/pgpainless/algorithm/Feature.java create mode 100644 pgpainless-core/src/main/java/org/pgpainless/algorithm/Feature.kt diff --git a/pgpainless-core/src/main/java/org/pgpainless/algorithm/Feature.java b/pgpainless-core/src/main/java/org/pgpainless/algorithm/Feature.java deleted file mode 100644 index d9aa9b90..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/algorithm/Feature.java +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-FileCopyrightText: 2018 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.algorithm; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.concurrent.ConcurrentHashMap; - -import org.bouncycastle.bcpg.sig.Features; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** - * An enumeration of features that may be set in the {@link Features} subpacket. - * - * @see RFC4880: Features - */ -public enum Feature { - - /** - * Support for Symmetrically Encrypted Integrity Protected Data Packets (version 1) using Modification - * Detection Code Packets. - * - * @see - * RFC-4880 §5.14: Modification Detection Code Packet - */ - MODIFICATION_DETECTION(Features.FEATURE_MODIFICATION_DETECTION), - - /** - * Support for Authenticated Encryption with Additional Data (AEAD). - * If a key announces this feature, it signals support for consuming AEAD Encrypted Data Packets. - * - * NOTE: PGPAINLESS DOES NOT YET SUPPORT THIS FEATURE!!! - * NOTE: This value is currently RESERVED. - * - * @see - * AEAD Encrypted Data Packet - */ - GNUPG_AEAD_ENCRYPTED_DATA(Features.FEATURE_AEAD_ENCRYPTED_DATA), - - /** - * If a key announces this feature, it is a version 5 public key. - * The version 5 format is similar to the version 4 format except for the addition of a count for the key material. - * This count helps to parse secret key packets (which are an extension of the public key packet format) in the case - * of an unknown algorithm. - * In addition, fingerprints of version 5 keys are calculated differently from version 4 keys. - * - * NOTE: PGPAINLESS DOES NOT YET SUPPORT THIS FEATURE!!! - * NOTE: This value is currently RESERVED. - * - * @see - * Public-Key Packet Formats - */ - GNUPG_VERSION_5_PUBLIC_KEY(Features.FEATURE_VERSION_5_PUBLIC_KEY), - - /** - * Support for Symmetrically Encrypted Integrity Protected Data packet version 2. - * - * @see - * crypto-refresh-06 §5.13.2. Version 2 Sym. Encrypted Integrity Protected Data Packet Format - */ - MODIFICATION_DETECTION_2((byte) 0x08), - ; - - private static final Map MAP = new ConcurrentHashMap<>(); - - static { - for (Feature f : Feature.values()) { - MAP.put(f.featureId, f); - } - } - - /** - * Return the {@link Feature} encoded by the given id. - * If the id does not match any known features, return null. - * - * @param id feature id - * @return feature - */ - @Nullable - public static Feature fromId(byte id) { - return MAP.get(id); - } - - /** - * Return the {@link Feature} encoded by the given id. - * If the id does not match any known features, throw an {@link NoSuchElementException}. - * - * @param id feature id - * @return feature - * @throws NoSuchElementException if an unmatched feature id is encountered - */ - @Nonnull - public static Feature requireFromId(byte id) { - Feature feature = fromId(id); - if (feature == null) { - throw new NoSuchElementException("Unknown feature id encountered: " + id); - } - return feature; - } - - private final byte featureId; - - Feature(byte featureId) { - this.featureId = featureId; - } - - /** - * Return the id of the feature. - * - * @return feature id - */ - public byte getFeatureId() { - return featureId; - } - - /** - * Convert a bitmask into a list of {@link KeyFlag KeyFlags}. - * - * @param bitmask bitmask - * @return list of key flags encoded by the bitmask - */ - @Nonnull - public static List fromBitmask(int bitmask) { - List features = new ArrayList<>(); - for (Feature f : Feature.values()) { - if ((bitmask & f.featureId) != 0) { - features.add(f); - } - } - return features; - } - - /** - * Encode a list of {@link KeyFlag KeyFlags} into a bitmask. - * - * @param features list of flags - * @return bitmask - */ - public static byte toBitmask(Feature... features) { - byte mask = 0; - for (Feature f : features) { - mask |= f.featureId; - } - return mask; - } -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/algorithm/Feature.kt b/pgpainless-core/src/main/java/org/pgpainless/algorithm/Feature.kt new file mode 100644 index 00000000..2e0058b5 --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/algorithm/Feature.kt @@ -0,0 +1,83 @@ +// SPDX-FileCopyrightText: 2023 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.algorithm + +/** + * An enumeration of features that may be set in the feature subpacket. + * + * See [RFC4880: Features](https://tools.ietf.org/html/rfc4880#section-5.2.3.24) + */ +enum class Feature(val featureId: Byte) { + + /** + * Support for Symmetrically Encrypted Integrity Protected Data Packets (version 1) using Modification + * Detection Code Packets. + * + * See [RFC-4880 §5.14: Modification Detection Code Packet](https://tools.ietf.org/html/rfc4880#section-5.14) + */ + MODIFICATION_DETECTION(0x01), + + /** + * Support for Authenticated Encryption with Additional Data (AEAD). + * If a key announces this feature, it signals support for consuming AEAD Encrypted Data Packets. + * + * NOTE: PGPAINLESS DOES NOT YET SUPPORT THIS FEATURE!!! + * NOTE: This value is currently RESERVED. + * + * See [AEAD Encrypted Data Packet](https://openpgp-wg.gitlab.io/rfc4880bis/#name-aead-encrypted-data-packet-) + */ + GNUPG_AEAD_ENCRYPTED_DATA(0x02), + + /** + * If a key announces this feature, it is a version 5 public key. + * The version 5 format is similar to the version 4 format except for the addition of a count for the key material. + * This count helps to parse secret key packets (which are an extension of the public key packet format) in the case + * of an unknown algorithm. + * In addition, fingerprints of version 5 keys are calculated differently from version 4 keys. + * + * NOTE: PGPAINLESS DOES NOT YET SUPPORT THIS FEATURE!!! + * NOTE: This value is currently RESERVED. + * + * See [Public-Key Packet Formats](https://openpgp-wg.gitlab.io/rfc4880bis/#name-public-key-packet-formats) + */ + GNUPG_VERSION_5_PUBLIC_KEY(0x04), + + /** + * Support for Symmetrically Encrypted Integrity Protected Data packet version 2. + * + * See [crypto-refresh-06 §5.13.2. Version 2 Sym. Encrypted Integrity Protected Data Packet Format](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-06.html#version-two-seipd) + */ + MODIFICATION_DETECTION_2(0x08), + ; + + companion object { + @JvmStatic + fun fromId(id: Byte): Feature? { + return values().firstOrNull { + f -> f.featureId == id + } + } + + @JvmStatic + fun requireFromId(id: Byte): Feature { + return fromId(id) ?: + throw NoSuchElementException("Unknown feature id encountered: $id") + } + + @JvmStatic + fun fromBitmask(bitmask: Int): List { + return values().filter { + it.featureId.toInt() and bitmask != 0 + } + } + + @JvmStatic + fun toBitmask(vararg features: Feature): Byte { + return features.map { it.featureId.toInt() } + .reduceOrNull { mask, f -> mask or f }?.toByte() + ?: 0 + } + } +} \ No newline at end of file