All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator Maven / Gradle / Ivy

Go to download

The Bouncy Castle Java API for handling the OpenPGP protocol. This jar contains the OpenPGP API for JDK 1.8 and up. The APIs can be used in conjunction with a JCE/JCA provider such as the one provided with the Bouncy Castle Cryptography APIs.

The newest version!
package org.bouncycastle.openpgp;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.bouncycastle.bcpg.SignatureSubpacket;
import org.bouncycastle.bcpg.SignatureSubpacketTags;
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.IssuerFingerprint;
import org.bouncycastle.bcpg.sig.IssuerKeyID;
import org.bouncycastle.bcpg.sig.KeyExpirationTime;
import org.bouncycastle.bcpg.sig.KeyFlags;
import org.bouncycastle.bcpg.sig.LibrePGPPreferredEncryptionModes;
import org.bouncycastle.bcpg.sig.NotationData;
import org.bouncycastle.bcpg.sig.PolicyURI;
import org.bouncycastle.bcpg.sig.PreferredAEADCiphersuites;
import org.bouncycastle.bcpg.sig.PreferredAlgorithms;
import org.bouncycastle.bcpg.sig.PreferredKeyServer;
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.RevocationKeyTags;
import org.bouncycastle.bcpg.sig.RevocationReason;
import org.bouncycastle.bcpg.sig.SignatureCreationTime;
import org.bouncycastle.bcpg.sig.SignatureExpirationTime;
import org.bouncycastle.bcpg.sig.SignatureTarget;
import org.bouncycastle.bcpg.sig.SignerUserID;
import org.bouncycastle.bcpg.sig.TrustSignature;

/**
 * Generator for signature subpackets.
 */
public class PGPSignatureSubpacketGenerator
{
    List packets = new ArrayList();

    /**
     * Base constructor, creates an empty generator.
     */
    public PGPSignatureSubpacketGenerator()
    {
    }

    /**
     * Constructor for pre-initialising the generator from an existing one.
     *
     * @param sigSubV an initial set of subpackets.
     */
    public PGPSignatureSubpacketGenerator(PGPSignatureSubpacketVector sigSubV)
    {
        if (sigSubV != null)
        {
            for (int i = 0; i != sigSubV.packets.length; i++)
            {
                packets.add(sigSubV.packets[i]);
            }
        }
    }

    /**
     * Specify, whether or not the signature is revocable.
     *
     * @param isCritical  true if should be treated as critical, false otherwise.
     * @param isRevocable true if the signature should be revocable, false otherwise.
     */
    public void setRevocable(boolean isCritical, boolean isRevocable)
    {
        if (contains(SignatureSubpacketTags.REVOCABLE))
        {
            throw new IllegalStateException("Revocable exists in the Signature Subpacket Generator");
        }
        packets.add(new Revocable(isCritical, isRevocable));
    }

    /**
     * Specify, whether or not the signature should be marked as exportable.
     * If this subpacket is missing, the signature is treated as being exportable.
     *
     * @param isCritical   true if should be treated as critical, false otherwise.
     * @param isExportable true if the signature should be exportable, false otherwise.
     */
    public void setExportable(boolean isCritical, boolean isExportable)
    {
        if (contains(SignatureSubpacketTags.EXPORTABLE))
        {
            throw new IllegalStateException("Exportable Certification exists in the Signature Subpacket Generator");
        }
        packets.add(new Exportable(isCritical, isExportable));
    }

    /**
     * Specify the set of features of the key.
     *
     * @param isCritical true if should be treated as critical, false otherwise.
     * @param feature    features
     */
    public void setFeature(boolean isCritical, byte feature)
    {
        packets.add(new Features(isCritical, feature));
    }

    /**
     * Add a TrustSignature packet to the signature. The values for depth and trust are
     * largely installation dependent but there are some guidelines in RFC 4880 -
     * 5.2.3.13.
     *
     * @param isCritical  true if the packet is critical.
     * @param depth       depth level.
     * @param trustAmount trust amount.
     */
    public void setTrust(boolean isCritical, int depth, int trustAmount)
    {
        packets.add(new TrustSignature(isCritical, depth, trustAmount));
    }

    /**
     * Set the number of seconds a key is valid for after the time of its creation. A
     * value of zero means the key never expires.
     *
     * @param isCritical true if should be treated as critical, false otherwise.
     * @param seconds
     */
    public void setKeyExpirationTime(boolean isCritical, long seconds)
    {
        packets.add(new KeyExpirationTime(isCritical, seconds));
    }

    /**
     * Set the number of seconds a signature is valid for after the time of its creation.
     * A value of zero means the signature never expires.
     *
     * @param isCritical true if should be treated as critical, false otherwise.
     * @param seconds
     */
    public void setSignatureExpirationTime(boolean isCritical, long seconds)
    {
        packets.add(new SignatureExpirationTime(isCritical, seconds));
    }

    /**
     * Set the creation time for the signature.
     * 

* Note: this overrides the generation of a creation time when the signature is * generated. */ public void setSignatureCreationTime(boolean isCritical, Date date) { packets.add(new SignatureCreationTime(isCritical, date)); } /** * Specify the preferred hash algorithms of the key. * See {@link org.bouncycastle.bcpg.HashAlgorithmTags}. * * @param isCritical true if should be treated as critical, false otherwise. * @param algorithms array of algorithms in descending preference */ public void setPreferredHashAlgorithms(boolean isCritical, int[] algorithms) { packets.add(new PreferredAlgorithms(SignatureSubpacketTags.PREFERRED_HASH_ALGS, isCritical, algorithms)); } /** * Specify the preferred symmetric encryption algorithms of the key. * See {@link org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags}. * * @param isCritical true if should be treated as critical, false otherwise. * @param algorithms array of algorithms in descending preference */ public void setPreferredSymmetricAlgorithms(boolean isCritical, int[] algorithms) { packets.add(new PreferredAlgorithms(SignatureSubpacketTags.PREFERRED_SYM_ALGS, isCritical, algorithms)); } /** * Specify the preferred compression algorithms of this key. * See {@link org.bouncycastle.bcpg.CompressionAlgorithmTags}. * * @param isCritical true if should be treated as critical, false otherwise. * @param algorithms array of algorithms in descending preference */ public void setPreferredCompressionAlgorithms(boolean isCritical, int[] algorithms) { packets.add(new PreferredAlgorithms(SignatureSubpacketTags.PREFERRED_COMP_ALGS, isCritical, algorithms)); } /** * This method is BROKEN! * Specify the preferred AEAD algorithms of this key. * * @param isCritical true if should be treated as critical, false otherwise. * @param algorithms array of algorithms in descending preference * @deprecated use {@link #setPreferredAEADCiphersuites(boolean, PreferredAEADCiphersuites.Combination[])} * or {@link #setPreferredLibrePgpEncryptionModes(boolean, int[])} instead. */ @Deprecated public void setPreferredAEADAlgorithms(boolean isCritical, int[] algorithms) { packets.add(new PreferredAlgorithms(SignatureSubpacketTags.PREFERRED_AEAD_ALGORITHMS, isCritical, algorithms)); } /** * Specify the preferred OpenPGP AEAD ciphersuites of this key. * * @see * RFC9580: Preferred AEAD Ciphersuites * * @param isCritical true, if this packet should be treated as critical, false otherwise. * @param algorithms array of algorithms in descending preference */ public void setPreferredAEADCiphersuites(boolean isCritical, PreferredAEADCiphersuites.Combination[] algorithms) { packets.add(new PreferredAEADCiphersuites(isCritical, algorithms)); } /** * Specify the preferred OpenPGP AEAD ciphersuites of this key. * * @see * RFC9580: Preferred AEAD Ciphersuites * * @param builder builder to build the ciphersuites packet from */ public void setPreferredAEADCiphersuites(PreferredAEADCiphersuites.Builder builder) { packets.add(builder.build()); } /** * Set the preferred encryption modes for LibrePGP keys. * Note: LibrePGP is not OpenPGP. An application strictly compliant to only the OpenPGP standard will not * know how to handle LibrePGP encryption modes. * The LibrePGP spec states that this subpacket shall be ignored and the application shall instead assume * {@link org.bouncycastle.bcpg.AEADAlgorithmTags#OCB}. * * @see * LibrePGP: Preferred Encryption Modes * @see org.bouncycastle.bcpg.AEADAlgorithmTags for possible algorithms * * @param isCritical whether the packet is critical * @param algorithms list of algorithms * @deprecated the use of this subpacket is deprecated in LibrePGP */ @Deprecated public void setPreferredLibrePgpEncryptionModes(boolean isCritical, int[] algorithms) { packets.add(new LibrePGPPreferredEncryptionModes(isCritical, algorithms)); } /** * Specify the preferred key server for the signed user-id / key. * Note, that the key server might also be a http/ftp etc. URI pointing to the key itself. * * @param isCritical true if the subpacket should be treated as critical * @param uri key server URI */ public void setPreferredKeyServer(boolean isCritical, String uri) { packets.add(new PreferredKeyServer(isCritical, uri)); } public void addPolicyURI(boolean isCritical, String policyUri) { packets.add(new PolicyURI(isCritical, policyUri)); } /** * Set this keys key flags. * See {@link PGPKeyFlags}. * * @param isCritical true if should be treated as critical, false otherwise. * @param flags flags */ public void setKeyFlags(boolean isCritical, int flags) { packets.add(new KeyFlags(isCritical, flags)); } /** * Add a signer user-id to the signature. * * @param isCritical true if should be treated as critical, false otherwise. * @param userID signer user-id * @deprecated use {@link #addSignerUserID(boolean, String)} instead. */ public void setSignerUserID(boolean isCritical, String userID) { addSignerUserID(isCritical, userID); } /** * Add a signer user-id to the signature. * * @param isCritical true if should be treated as critical, false otherwise. * @param userID signer user-id */ public void addSignerUserID(boolean isCritical, String userID) { if (userID == null) { throw new IllegalArgumentException("attempt to set null SignerUserID"); } packets.add(new SignerUserID(isCritical, userID)); } /** * Add a signer user-id to the signature. * * @param isCritical true if should be treated as critical, false otherwise. * @param rawUserID signer user-id * @deprecated use {@link #addSignerUserID(boolean, byte[])} instead. */ public void setSignerUserID(boolean isCritical, byte[] rawUserID) { addSignerUserID(isCritical, rawUserID); } /** * Add a signer user-id to the signature. * * @param isCritical true if should be treated as critical, false otherwise. * @param rawUserID signer user-id */ public void addSignerUserID(boolean isCritical, byte[] rawUserID) { if (rawUserID == null) { throw new IllegalArgumentException("attempt to set null SignerUserID"); } packets.add(new SignerUserID(isCritical, false, rawUserID)); } /** * Add an embedded signature packet. * * @param isCritical true if should be treated as critical, false otherwise. * @param pgpSignature embedded signature * @throws IOException in case of an error * @deprecated use {@link #addEmbeddedSignature(boolean, PGPSignature)} instead. */ public void setEmbeddedSignature(boolean isCritical, PGPSignature pgpSignature) throws IOException { addEmbeddedSignature(isCritical, pgpSignature); } /** * Add an embedded signature packet. * * @param isCritical true if should be treated as critical, false otherwise. * @param pgpSignature embedded signature * @throws IOException in case of an error */ public void addEmbeddedSignature(boolean isCritical, PGPSignature pgpSignature) throws IOException { byte[] sig = pgpSignature.getEncoded(); byte[] data; if (sig.length - 1 > 256) { data = new byte[sig.length - 3]; } else { data = new byte[sig.length - 2]; } System.arraycopy(sig, sig.length - data.length, data, 0, data.length); packets.add(new EmbeddedSignature(isCritical, false, data)); } public void setPrimaryUserID(boolean isCritical, boolean isPrimaryUserID) { packets.add(new PrimaryUserID(isCritical, isPrimaryUserID)); } /** * Add a notation data packet to the signature. * * @param isCritical true if should be treated as critical, false otherwise. * @param isHumanReadable true if the notation is human-readable. * @param notationName name of the notation key * @param notationValue value of the notation * @deprecated use {@link #addNotationData(boolean, boolean, String, String)} instead. */ public void setNotationData(boolean isCritical, boolean isHumanReadable, String notationName, String notationValue) { addNotationData(isCritical, isHumanReadable, notationName, notationValue); } /** * Add a notation data packet to the signature. * * @param isCritical true if should be treated as critical, false otherwise. * @param isHumanReadable true if the notation is human-readable. * @param notationName name of the notation key. * @param notationValue value of the notation. */ public void addNotationData(boolean isCritical, boolean isHumanReadable, String notationName, String notationValue) { packets.add(new NotationData(isCritical, isHumanReadable, notationName, notationValue)); } /** * Sets revocation reason sub packet. * See {@link org.bouncycastle.bcpg.sig.RevocationReasonTags}. * * @param isCritical true if should be treated as critical, false otherwise. * @param reason reason code for the revocation * @param description human readable description of the revocation reason */ public void setRevocationReason(boolean isCritical, byte reason, String description) { packets.add(new RevocationReason(isCritical, reason, description)); } /** * Adds a revocation key sub packet. * * @param isCritical true if should be treated as critical, false otherwise. * @param keyAlgorithm algorithm of the revocation key * @param fingerprint fingerprint of the revocation key (v4 only) * @deprecated the revocation key mechanism is deprecated. Applications MUST NOT generate such a packet. */ public void setRevocationKey(boolean isCritical, int keyAlgorithm, byte[] fingerprint) { addRevocationKey(isCritical, keyAlgorithm, fingerprint); } /** * Adds a revocation key sub packet. * * @param isCritical true if should be treated as critical, false otherwise. * @param keyAlgorithm algorithm of the revocation key * @param fingerprint fingerprint of the revocation key (v4 only) * @deprecated the revocation key mechanism is deprecated. Applications MUST NOT generate such a packet. */ public void addRevocationKey(boolean isCritical, int keyAlgorithm, byte[] fingerprint) { packets.add(new RevocationKey(isCritical, RevocationKeyTags.CLASS_DEFAULT, keyAlgorithm, fingerprint)); } /** * Sets issuer key-id subpacket. * * @param isCritical true if should be treated as critical, false otherwise. * @param keyID id of the key that issued the signature */ public void setIssuerKeyID(boolean isCritical, long keyID) { packets.add(new IssuerKeyID(isCritical, keyID)); } /** * Sets the signature target sub packet. * * @param isCritical true if should be treated as critical, false otherwise. * @param publicKeyAlgorithm algorithm of the key that issued the signature that is being referred to. * @param hashAlgorithm hash algorithm that was used to calculate the hash data. * @param hashData hash of the signature that is being referred to. */ public void setSignatureTarget(boolean isCritical, int publicKeyAlgorithm, int hashAlgorithm, byte[] hashData) { packets.add(new SignatureTarget(isCritical, publicKeyAlgorithm, hashAlgorithm, hashData)); } /** * Sets the signature issuer fingerprint for the signing key. * * @param isCritical true if critical, false otherwise. * @param secretKey the secret key used to generate the associated signature. */ public void setIssuerFingerprint(boolean isCritical, PGPSecretKey secretKey) { this.setIssuerFingerprint(isCritical, secretKey.getPublicKey()); } /** * Sets the signature issuer fingerprint for the signing key. * * @param isCritical true if critical, false otherwise. * @param publicKey the public key needed to verify the associated signature. */ public void setIssuerFingerprint(boolean isCritical, PGPPublicKey publicKey) { packets.add(new IssuerFingerprint(isCritical, publicKey.getVersion(), publicKey.getFingerprint())); } /** * Adds a intended recipient fingerprint for an encrypted payload the signature is associated with. * * @param isCritical true if critical, false otherwise. * @param publicKey the public key the encrypted payload was encrypted against. * @deprecated use {@link #addIntendedRecipientFingerprint(boolean, PGPPublicKey)} instead. */ public void setIntendedRecipientFingerprint(boolean isCritical, PGPPublicKey publicKey) { addIntendedRecipientFingerprint(isCritical, publicKey); } /** * Adds a intended recipient fingerprint for an encrypted payload the signature is associated with. * * @param isCritical true if critical, false otherwise. * @param publicKey the public key the encrypted payload was encrypted against. */ public void addIntendedRecipientFingerprint(boolean isCritical, PGPPublicKey publicKey) { packets.add(new IntendedRecipientFingerprint(isCritical, publicKey.getVersion(), publicKey.getFingerprint())); } /** * Add a custom subpacket. * Miscellaneous subpackets are subpackets that Bouncycastle does not recognize or * doesn't have first class support for. * * @param subpacket subpacket */ public void addCustomSubpacket(SignatureSubpacket subpacket) { packets.add(subpacket); } /** * Remove a previously set packet from the generator. * * @param packet the signature subpacket to remove. */ public boolean removePacket(SignatureSubpacket packet) { return packets.remove(packet); } /** * Return true if a particular subpacket type exists. * * @param type type to look for. * @return true if present, false otherwise. */ public boolean hasSubpacket( int type) { for (int i = 0; i != packets.size(); i++) { if (((SignatureSubpacket)packets.get(i)).getType() == type) { return true; } } return false; } /** * Return all signature subpackets of the passed in type currently in * the generator. * * @param type subpacket type code * @return an array of zero or more matching subpackets. */ public SignatureSubpacket[] getSubpackets( int type) { List list = new ArrayList(); for (int i = 0; i != packets.size(); i++) { if (((SignatureSubpacket)packets.get(i)).getType() == type) { list.add(packets.get(i)); } } return (SignatureSubpacket[])list.toArray(new SignatureSubpacket[]{}); } public PGPSignatureSubpacketVector generate() { return new PGPSignatureSubpacketVector( (SignatureSubpacket[])packets.toArray(new SignatureSubpacket[packets.size()])); } private boolean contains(int type) { for (int i = 0; i < packets.size(); ++i) { if (((SignatureSubpacket)packets.get(i)).getType() == type) { return true; } } return false; } /** * Adds a regular expression. * * @param isCritical true if should be treated as critical, false otherwise. * @param regularExpression the regular expression */ public void addRegularExpression(boolean isCritical, String regularExpression) { if (regularExpression == null) { throw new IllegalArgumentException("attempt to set null regular expression"); } packets.add(new RegularExpression(isCritical, regularExpression)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy