From b72f95b46cc00caff7eb93505a0045f76a4ee884 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Fri, 20 Oct 2023 14:55:51 +0200 Subject: [PATCH] Kotlin conversion: SignatureSubpacketsHelper --- .../subpackets/SignatureSubpacketsHelper.java | 196 ------------------ .../signature/subpackets/package-info.java | 8 - .../subpackets/SignatureSubpackets.kt | 8 +- .../subpackets/SignatureSubpacketsHelper.kt | 159 ++++++++++++++ 4 files changed, 161 insertions(+), 210 deletions(-) delete mode 100644 pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SignatureSubpacketsHelper.java delete mode 100644 pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/package-info.java create mode 100644 pgpainless-core/src/main/kotlin/org/pgpainless/signature/subpackets/SignatureSubpacketsHelper.kt diff --git a/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SignatureSubpacketsHelper.java b/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SignatureSubpacketsHelper.java deleted file mode 100644 index 2a7d4f83..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/SignatureSubpacketsHelper.java +++ /dev/null @@ -1,196 +0,0 @@ -// SPDX-FileCopyrightText: 2021 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.signature.subpackets; - -import org.bouncycastle.bcpg.SignatureSubpacket; -import org.bouncycastle.bcpg.sig.EmbeddedSignature; -import org.bouncycastle.bcpg.sig.Exportable; -import org.bouncycastle.bcpg.sig.Features; -import org.bouncycastle.bcpg.sig.IntendedRecipientFingerprint; -import org.bouncycastle.bcpg.sig.KeyExpirationTime; -import org.bouncycastle.bcpg.sig.KeyFlags; -import org.bouncycastle.bcpg.sig.NotationData; -import org.bouncycastle.bcpg.sig.PolicyURI; -import org.bouncycastle.bcpg.sig.PreferredAlgorithms; -import org.bouncycastle.bcpg.sig.PrimaryUserID; -import org.bouncycastle.bcpg.sig.RegularExpression; -import org.bouncycastle.bcpg.sig.Revocable; -import org.bouncycastle.bcpg.sig.RevocationKey; -import org.bouncycastle.bcpg.sig.RevocationReason; -import org.bouncycastle.bcpg.sig.SignatureExpirationTime; -import org.bouncycastle.bcpg.sig.SignatureTarget; -import org.bouncycastle.bcpg.sig.SignerUserID; -import org.bouncycastle.bcpg.sig.TrustSignature; -import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; -import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; -import org.pgpainless.algorithm.Feature; -import org.pgpainless.algorithm.HashAlgorithm; -import org.pgpainless.algorithm.KeyFlag; -import org.pgpainless.algorithm.PublicKeyAlgorithm; -import org.pgpainless.key.util.RevocationAttributes; - -public class SignatureSubpacketsHelper { - - public static SignatureSubpackets applyFrom(PGPSignatureSubpacketVector vector, SignatureSubpackets subpackets) { - for (SignatureSubpacket subpacket : vector.toArray()) { - org.pgpainless.algorithm.SignatureSubpacket type = org.pgpainless.algorithm.SignatureSubpacket.requireFromCode(subpacket.getType()); - switch (type) { - case signatureCreationTime: - case issuerKeyId: - case issuerFingerprint: - // ignore, we override this anyways - break; - case signatureExpirationTime: - SignatureExpirationTime sigExpTime = (SignatureExpirationTime) subpacket; - subpackets.setSignatureExpirationTime(sigExpTime.isCritical(), sigExpTime.getTime()); - break; - case exportableCertification: - Exportable exp = (Exportable) subpacket; - subpackets.setExportable(exp.isCritical(), exp.isExportable()); - break; - case trustSignature: - TrustSignature trustSignature = (TrustSignature) subpacket; - subpackets.setTrust(trustSignature.isCritical(), trustSignature.getDepth(), trustSignature.getTrustAmount()); - break; - case revocable: - Revocable rev = (Revocable) subpacket; - subpackets.setRevocable(rev.isCritical(), rev.isRevocable()); - break; - case keyExpirationTime: - KeyExpirationTime keyExpTime = (KeyExpirationTime) subpacket; - subpackets.setKeyExpirationTime(keyExpTime.isCritical(), keyExpTime.getTime()); - break; - case preferredSymmetricAlgorithms: - subpackets.setPreferredSymmetricKeyAlgorithms((PreferredAlgorithms) subpacket); - break; - case revocationKey: - RevocationKey revocationKey = (RevocationKey) subpacket; - subpackets.addRevocationKey(revocationKey); - break; - case notationData: - NotationData notationData = (NotationData) subpacket; - subpackets.addNotationData(notationData.isCritical(), notationData.getNotationName(), notationData.getNotationValue()); - break; - case preferredHashAlgorithms: - subpackets.setPreferredHashAlgorithms((PreferredAlgorithms) subpacket); - break; - case preferredCompressionAlgorithms: - subpackets.setPreferredCompressionAlgorithms((PreferredAlgorithms) subpacket); - break; - case primaryUserId: - PrimaryUserID primaryUserID = (PrimaryUserID) subpacket; - subpackets.setPrimaryUserId(primaryUserID); - break; - case keyFlags: - KeyFlags flags = (KeyFlags) subpacket; - subpackets.setKeyFlags(flags.isCritical(), KeyFlag.fromBitmask(flags.getFlags()).toArray(new KeyFlag[0])); - break; - case signerUserId: - SignerUserID signerUserID = (SignerUserID) subpacket; - subpackets.setSignerUserId(signerUserID.isCritical(), signerUserID.getID()); - break; - case revocationReason: - RevocationReason reason = (RevocationReason) subpacket; - subpackets.setRevocationReason(reason.isCritical(), - RevocationAttributes.Reason.fromCode(reason.getRevocationReason()), - reason.getRevocationDescription()); - break; - case features: - Features f = (Features) subpacket; - subpackets.setFeatures(f.isCritical(), Feature.fromBitmask(f.getData()[0]).toArray(new Feature[0])); - break; - case signatureTarget: - SignatureTarget target = (SignatureTarget) subpacket; - subpackets.setSignatureTarget(target.isCritical(), - PublicKeyAlgorithm.requireFromId(target.getPublicKeyAlgorithm()), - HashAlgorithm.requireFromId(target.getHashAlgorithm()), - target.getHashData()); - break; - case embeddedSignature: - EmbeddedSignature embeddedSignature = (EmbeddedSignature) subpacket; - subpackets.addEmbeddedSignature(embeddedSignature); - break; - case intendedRecipientFingerprint: - IntendedRecipientFingerprint intendedRecipientFingerprint = (IntendedRecipientFingerprint) subpacket; - subpackets.addIntendedRecipientFingerprint(intendedRecipientFingerprint); - break; - case policyUrl: - PolicyURI policyURI = (PolicyURI) subpacket; - subpackets.setPolicyUrl(policyURI); - break; - case regularExpression: - RegularExpression regex = (RegularExpression) subpacket; - subpackets.setRegularExpression(regex); - break; - - case keyServerPreferences: - case preferredKeyServers: - case placeholder: - case preferredAEADAlgorithms: - case attestedCertification: - subpackets.addResidualSubpacket(subpacket); - break; - } - } - return subpackets; - } - - public static PGPSignatureSubpacketGenerator applyTo(SignatureSubpackets subpackets, PGPSignatureSubpacketGenerator generator) { - addSubpacket(generator, subpackets.getIssuerKeyIdSubpacket()); - addSubpacket(generator, subpackets.getIssuerFingerprintSubpacket()); - addSubpacket(generator, subpackets.getSignatureCreationTimeSubpacket()); - addSubpacket(generator, subpackets.getSignatureExpirationTimeSubpacket()); - addSubpacket(generator, subpackets.getExportableSubpacket()); - addSubpacket(generator, subpackets.getPolicyURISubpacket()); - addSubpacket(generator, subpackets.getRegularExpressionSubpacket()); - for (NotationData notationData : subpackets.getNotationDataSubpackets()) { - addSubpacket(generator, notationData); - } - for (IntendedRecipientFingerprint intendedRecipientFingerprint : subpackets.getIntendedRecipientFingerprintSubpackets()) { - addSubpacket(generator, intendedRecipientFingerprint); - } - for (RevocationKey revocationKey : subpackets.getRevocationKeySubpackets()) { - addSubpacket(generator, revocationKey); - } - addSubpacket(generator, subpackets.getSignatureTargetSubpacket()); - addSubpacket(generator, subpackets.getFeaturesSubpacket()); - addSubpacket(generator, subpackets.getKeyFlagsSubpacket()); - addSubpacket(generator, subpackets.getTrustSubpacket()); - addSubpacket(generator, subpackets.getPreferredCompressionAlgorithmsSubpacket()); - addSubpacket(generator, subpackets.getPreferredSymmetricKeyAlgorithmsSubpacket()); - addSubpacket(generator, subpackets.getPreferredHashAlgorithmsSubpacket()); - for (EmbeddedSignature embeddedSignature : subpackets.getEmbeddedSignatureSubpackets()) { - addSubpacket(generator, embeddedSignature); - } - addSubpacket(generator, subpackets.getSignerUserIdSubpacket()); - addSubpacket(generator, subpackets.getKeyExpirationTimeSubpacket()); - addSubpacket(generator, subpackets.getPrimaryUserIdSubpacket()); - addSubpacket(generator, subpackets.getRevocableSubpacket()); - addSubpacket(generator, subpackets.getRevocationReasonSubpacket()); - for (SignatureSubpacket subpacket : subpackets.getResidualSubpackets()) { - addSubpacket(generator, subpacket); - } - - return generator; - } - - private static void addSubpacket(PGPSignatureSubpacketGenerator generator, SignatureSubpacket subpacket) { - if (subpacket != null) { - generator.addCustomSubpacket(subpacket); - } - } - - public static PGPSignatureSubpacketVector toVector(SignatureSubpackets subpackets) { - PGPSignatureSubpacketGenerator generator = new PGPSignatureSubpacketGenerator(); - applyTo(subpackets, generator); - return generator.generate(); - } - - public static PGPSignatureSubpacketVector toVector(RevocationSignatureSubpackets subpackets) { - PGPSignatureSubpacketGenerator generator = new PGPSignatureSubpacketGenerator(); - applyTo((SignatureSubpackets) subpackets, generator); - return generator.generate(); - } -} diff --git a/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/package-info.java b/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/package-info.java deleted file mode 100644 index 09dfd6a2..00000000 --- a/pgpainless-core/src/main/java/org/pgpainless/signature/subpackets/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-FileCopyrightText: 2018 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -/** - * Classes related to OpenPGP signatures. - */ -package org.pgpainless.signature.subpackets; diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/signature/subpackets/SignatureSubpackets.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/signature/subpackets/SignatureSubpackets.kt index d7d907f0..a88e4e8a 100644 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/signature/subpackets/SignatureSubpackets.kt +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/signature/subpackets/SignatureSubpackets.kt @@ -70,16 +70,12 @@ class SignatureSubpackets @JvmStatic fun createSubpacketsFrom(base: PGPSignatureSubpacketVector): SignatureSubpackets { - return SignatureSubpackets().apply { - SignatureSubpacketsHelper.applyFrom(base, this) - } + return SignatureSubpacketsHelper.applyFrom(base, SignatureSubpackets()) } @JvmStatic fun createHashedSubpackets(issuer: PGPPublicKey): SignatureSubpackets { - return SignatureSubpackets().apply { - setIssuerFingerprintAndKeyId(issuer) - } + return createEmptySubpackets().setIssuerFingerprintAndKeyId(issuer) } @JvmStatic diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/signature/subpackets/SignatureSubpacketsHelper.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/signature/subpackets/SignatureSubpacketsHelper.kt new file mode 100644 index 00000000..6767b0af --- /dev/null +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/signature/subpackets/SignatureSubpacketsHelper.kt @@ -0,0 +1,159 @@ +// SPDX-FileCopyrightText: 2023 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.signature.subpackets + +import org.bouncycastle.bcpg.sig.* +import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator +import org.bouncycastle.openpgp.PGPSignatureSubpacketVector +import org.pgpainless.algorithm.* +import org.pgpainless.key.util.RevocationAttributes + +class SignatureSubpacketsHelper { + + companion object { + @JvmStatic + fun applyFrom(vector: PGPSignatureSubpacketVector, subpackets: SignatureSubpackets) = subpackets.apply { + for (subpacket in vector.toArray()) { + val type = SignatureSubpacket.requireFromCode(subpacket.type) + when (type) { + SignatureSubpacket.signatureCreationTime, + SignatureSubpacket.issuerKeyId, + SignatureSubpacket.issuerFingerprint -> { /* ignore, we override this anyway */ } + SignatureSubpacket.signatureExpirationTime -> (subpacket as SignatureExpirationTime).let { + subpackets.setSignatureExpirationTime(it.isCritical, it.time) + } + SignatureSubpacket.exportableCertification -> (subpacket as Exportable).let { + subpackets.setExportable(it.isCritical, it.isExportable) + } + SignatureSubpacket.trustSignature -> (subpacket as TrustSignature).let { + subpackets.setTrust(it.isCritical, it.depth, it.trustAmount) + } + SignatureSubpacket.revocable -> (subpacket as Revocable).let { + subpackets.setRevocable(it.isCritical, it.isRevocable) + } + SignatureSubpacket.keyExpirationTime -> (subpacket as KeyExpirationTime).let { + subpackets.setKeyExpirationTime(it.isCritical, it.time) + } + SignatureSubpacket.preferredSymmetricAlgorithms -> (subpacket as PreferredAlgorithms).let { + subpackets.setPreferredSymmetricKeyAlgorithms(PreferredAlgorithms(it.type, it.isCritical, it.isLongLength, it.data)) + } + SignatureSubpacket.preferredHashAlgorithms -> (subpacket as PreferredAlgorithms).let { + subpackets.setPreferredHashAlgorithms(PreferredAlgorithms(it.type, it.isCritical, it.isLongLength, it.data)) + } + SignatureSubpacket.preferredCompressionAlgorithms -> (subpacket as PreferredAlgorithms).let { + subpackets.setPreferredCompressionAlgorithms(PreferredAlgorithms(it.type, it.isCritical, it.isLongLength, it.data)) + } + SignatureSubpacket.revocationKey -> (subpacket as RevocationKey).let { + subpackets.addRevocationKey(RevocationKey(it.isCritical, it.signatureClass, it.algorithm, it.fingerprint)) + } + SignatureSubpacket.notationData -> (subpacket as NotationData).let { + subpackets.addNotationData(it.isCritical, it.isHumanReadable, it.notationName, it.notationValue) + } + SignatureSubpacket.primaryUserId -> (subpacket as PrimaryUserID).let { + subpackets.setPrimaryUserId(PrimaryUserID(it.isCritical, it.isPrimaryUserID)) + } + SignatureSubpacket.keyFlags -> (subpacket as KeyFlags).let { + subpackets.setKeyFlags(it.isCritical, *(KeyFlag.fromBitmask(it.flags).toTypedArray())) + } + SignatureSubpacket.signerUserId -> (subpacket as SignerUserID).let { + subpackets.setSignerUserId(it.isCritical, it.id) + } + SignatureSubpacket.revocationReason -> (subpacket as RevocationReason).let { + subpackets.setRevocationReason(it.isCritical, RevocationAttributes.Reason.fromCode(it.revocationReason), it.revocationDescription) + } + SignatureSubpacket.features -> (subpacket as Features).let { + subpackets.setFeatures(it.isCritical, *(Feature.fromBitmask(it.features.toInt()).toTypedArray())) + } + SignatureSubpacket.signatureTarget -> (subpacket as SignatureTarget).let { + subpackets.setSignatureTarget(it.isCritical, + PublicKeyAlgorithm.requireFromId(it.publicKeyAlgorithm), + HashAlgorithm.requireFromId(it.hashAlgorithm), + it.hashData) + } + SignatureSubpacket.embeddedSignature -> (subpacket as EmbeddedSignature).let { + subpackets.addEmbeddedSignature(it) + } + SignatureSubpacket.intendedRecipientFingerprint -> (subpacket as IntendedRecipientFingerprint).let { + subpackets.addIntendedRecipientFingerprint(it) + } + SignatureSubpacket.policyUrl -> (subpacket as PolicyURI).let { + subpackets.setPolicyUrl(it) + } + SignatureSubpacket.regularExpression -> (subpacket as RegularExpression).let { + subpackets.setRegularExpression(it) + } + SignatureSubpacket.keyServerPreferences, + SignatureSubpacket.preferredKeyServers, + SignatureSubpacket.placeholder, + SignatureSubpacket.preferredAEADAlgorithms, + SignatureSubpacket.attestedCertification -> subpackets.addResidualSubpacket(subpacket) + } + } + } + + @JvmStatic + fun applyTo(subpackets: SignatureSubpackets, generator: PGPSignatureSubpacketGenerator): PGPSignatureSubpacketGenerator { + return generator.apply { + addSubpacket(subpackets.issuerKeyIdSubpacket) + addSubpacket(subpackets.issuerFingerprintSubpacket) + addSubpacket(subpackets.signatureCreationTimeSubpacket) + addSubpacket(subpackets.signatureExpirationTimeSubpacket) + addSubpacket(subpackets.exportableSubpacket) + addSubpacket(subpackets.policyURISubpacket) + addSubpacket(subpackets.regularExpressionSubpacket) + for (notation in subpackets.notationDataSubpackets) { + addSubpacket(notation) + } + for (recipient in subpackets.intendedRecipientFingerprintSubpackets) { + addSubpacket(recipient) + } + for (revocationKey in subpackets.revocationKeySubpackets) { + addSubpacket(revocationKey) + } + addSubpacket(subpackets.signatureTargetSubpacket) + addSubpacket(subpackets.featuresSubpacket) + addSubpacket(subpackets.keyFlagsSubpacket) + addSubpacket(subpackets.trustSubpacket) + addSubpacket(subpackets.preferredCompressionAlgorithmsSubpacket) + addSubpacket(subpackets.preferredSymmetricKeyAlgorithmsSubpacket) + addSubpacket(subpackets.preferredHashAlgorithmsSubpacket) + for (embedded in subpackets.embeddedSignatureSubpackets) { + addSubpacket(embedded) + } + addSubpacket(subpackets.signerUserIdSubpacket) + addSubpacket(subpackets.keyExpirationTimeSubpacket) + addSubpacket(subpackets.primaryUserIdSubpacket) + addSubpacket(subpackets.revocableSubpacket) + addSubpacket(subpackets.revocationReasonSubpacket) + for (residual in subpackets.residualSubpackets) { + addSubpacket(residual) + } + } + } + + @JvmStatic + private fun PGPSignatureSubpacketGenerator.addSubpacket(subpacket: org.bouncycastle.bcpg.SignatureSubpacket?) { + if (subpacket != null) { + this.addCustomSubpacket(subpacket) + } + } + + @JvmStatic + fun toVector(subpackets: SignatureSubpackets): PGPSignatureSubpacketVector { + return PGPSignatureSubpacketGenerator().let { + applyTo(subpackets, it) + it.generate() + } + } + + @JvmStatic + fun toVector(subpackets: RevocationSignatureSubpackets): PGPSignatureSubpacketVector { + return PGPSignatureSubpacketGenerator().let { + applyTo(subpackets as SignatureSubpackets, it) + it.generate() + } + } + } +} \ No newline at end of file