pgpainless/pgpainless-core/src/main/kotlin/org/pgpainless/signature/subpackets/SignatureSubpacketsHelper.kt

211 lines
11 KiB
Kotlin

// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
//
// 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.fromCode(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)
else -> 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()
}
}
}
}