001// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
002//
003// SPDX-License-Identifier: Apache-2.0
004
005package org.pgpainless.signature.builder;
006
007import javax.annotation.Nullable;
008
009import org.bouncycastle.openpgp.PGPException;
010import org.bouncycastle.openpgp.PGPPublicKey;
011import org.bouncycastle.openpgp.PGPSecretKey;
012import org.bouncycastle.openpgp.PGPSignature;
013import org.bouncycastle.openpgp.PGPSignatureGenerator;
014import org.pgpainless.algorithm.SignatureType;
015import org.pgpainless.key.protection.SecretKeyRingProtector;
016import org.pgpainless.signature.subpackets.RevocationSignatureSubpackets;
017
018public class RevocationSignatureBuilder extends AbstractSignatureBuilder<RevocationSignatureBuilder> {
019
020    public RevocationSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector) throws PGPException {
021        super(signatureType, signingKey, protector);
022        getHashedSubpackets().setRevocable(true, false);
023    }
024
025    @Override
026    protected boolean isValidSignatureType(SignatureType type) {
027        switch (type) {
028            case KEY_REVOCATION:
029            case SUBKEY_REVOCATION:
030            case CERTIFICATION_REVOCATION:
031                return true;
032            default:
033                return false;
034        }
035    }
036
037    public RevocationSignatureSubpackets getHashedSubpackets() {
038        return hashedSubpackets;
039    }
040
041    public RevocationSignatureSubpackets getUnhashedSubpackets() {
042        return unhashedSubpackets;
043    }
044
045    public void applyCallback(@Nullable RevocationSignatureSubpackets.Callback callback) {
046        if (callback != null) {
047            callback.modifyHashedSubpackets(getHashedSubpackets());
048            callback.modifyUnhashedSubpackets(getUnhashedSubpackets());
049        }
050    }
051
052    public PGPSignature build(PGPPublicKey revokeeSubkey) throws PGPException {
053        PGPSignatureGenerator signatureGenerator = buildAndInitSignatureGenerator();
054        if (signatureType == SignatureType.KEY_REVOCATION) {
055            if (revokeeSubkey.getKeyID() != publicSigningKey.getKeyID()) {
056                throw new IllegalArgumentException("Signature type is KEY_REVOCATION, but provided revokeeSubkey is != signingPublicKey.");
057            }
058            return signatureGenerator.generateCertification(publicSigningKey);
059        } else {
060            return signatureGenerator.generateCertification(publicSigningKey, revokeeSubkey);
061        }
062    }
063
064    public PGPSignature build(String revokeeUserId) throws PGPException {
065        PGPSignatureGenerator signatureGenerator = buildAndInitSignatureGenerator();
066        if (signatureType != SignatureType.CERTIFICATION_REVOCATION) {
067            throw new IllegalArgumentException("Signature type is != CERTIFICATION_REVOCATION.");
068        }
069        return signatureGenerator.generateCertification(revokeeUserId, publicSigningKey);
070    }
071}