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.Nonnull;
008import javax.annotation.Nullable;
009
010import org.bouncycastle.openpgp.PGPException;
011import org.bouncycastle.openpgp.PGPPublicKeyRing;
012import org.bouncycastle.openpgp.PGPSecretKey;
013import org.bouncycastle.openpgp.PGPSignature;
014import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector;
015import org.pgpainless.algorithm.SignatureType;
016import org.pgpainless.exception.WrongPassphraseException;
017import org.pgpainless.key.protection.SecretKeyRingProtector;
018import org.pgpainless.signature.subpackets.CertificationSubpackets;
019
020/**
021 * Certification signature builder used to certify other users keys.
022 */
023public class ThirdPartyCertificationSignatureBuilder extends AbstractSignatureBuilder<ThirdPartyCertificationSignatureBuilder> {
024
025    /**
026     * Create a new certification signature builder.
027     * This constructor uses {@link SignatureType#GENERIC_CERTIFICATION} as signature type.
028     *
029     * @param signingKey our own certification key
030     * @param protector protector to unlock the certification key
031     * @throws WrongPassphraseException in case of a wrong passphrase
032     */
033    public ThirdPartyCertificationSignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector)
034            throws PGPException {
035        this(SignatureType.GENERIC_CERTIFICATION, signingKey, protector);
036    }
037
038    /**
039     * Create a new certification signature builder.
040     *
041     * @param signatureType type of certification
042     * @param signingKey our own certification key
043     * @param protector protector to unlock the certification key
044     * @throws WrongPassphraseException in case of a wrong passphrase
045     */
046    public ThirdPartyCertificationSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector)
047            throws PGPException {
048        super(signatureType, signingKey, protector);
049    }
050
051    /**
052     * Create a new certification signature builder.
053     *
054     * @param signingKey our own certification key
055     * @param protector protector to unlock the certification key
056     * @param archetypeSignature signature to use as a template for the new signature
057     * @throws WrongPassphraseException in case of a wrong passphrase
058     */
059    public ThirdPartyCertificationSignatureBuilder(
060            PGPSecretKey signingKey,
061            SecretKeyRingProtector protector,
062            PGPSignature archetypeSignature)
063            throws PGPException {
064        super(signingKey, protector, archetypeSignature);
065    }
066
067    public CertificationSubpackets getHashedSubpackets() {
068        return hashedSubpackets;
069    }
070
071    public CertificationSubpackets getUnhashedSubpackets() {
072        return unhashedSubpackets;
073    }
074
075    public void applyCallback(@Nullable CertificationSubpackets.Callback callback) {
076        if (callback != null) {
077            callback.modifyHashedSubpackets(getHashedSubpackets());
078            callback.modifyUnhashedSubpackets(getUnhashedSubpackets());
079        }
080    }
081
082    /**
083     * Create a certification signature for the given user-id and the primary key of the given key ring.
084     * @param certifiedKey key ring
085     * @param userId user-id to certify
086     * @return signature
087     */
088    public PGPSignature build(PGPPublicKeyRing certifiedKey, String userId) throws PGPException {
089        return buildAndInitSignatureGenerator().generateCertification(userId, certifiedKey.getPublicKey());
090    }
091
092    /**
093     * Create a certification signature for the given user attribute and the primary key of the given key ring.
094     * @param certifiedKey key ring
095     * @param userAttribute user-attributes to certify
096     * @return signature
097     */
098    public PGPSignature build(PGPPublicKeyRing certifiedKey, PGPUserAttributeSubpacketVector userAttribute)
099            throws PGPException {
100        return buildAndInitSignatureGenerator().generateCertification(userAttribute, certifiedKey.getPublicKey());
101    }
102
103    @Override
104    protected boolean isValidSignatureType(@Nonnull SignatureType type) {
105        switch (type) {
106            case GENERIC_CERTIFICATION:
107            case NO_CERTIFICATION:
108            case CASUAL_CERTIFICATION:
109            case POSITIVE_CERTIFICATION:
110                return true;
111            default:
112                return false;
113        }
114    }
115}