001// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
002//
003// SPDX-License-Identifier: Apache-2.0
004
005package org.pgpainless.algorithm;
006
007import static org.bouncycastle.bcpg.SignatureSubpacketTags.ATTESTED_CERTIFICATIONS;
008import static org.bouncycastle.bcpg.SignatureSubpacketTags.CREATION_TIME;
009import static org.bouncycastle.bcpg.SignatureSubpacketTags.EMBEDDED_SIGNATURE;
010import static org.bouncycastle.bcpg.SignatureSubpacketTags.EXPIRE_TIME;
011import static org.bouncycastle.bcpg.SignatureSubpacketTags.EXPORTABLE;
012import static org.bouncycastle.bcpg.SignatureSubpacketTags.FEATURES;
013import static org.bouncycastle.bcpg.SignatureSubpacketTags.INTENDED_RECIPIENT_FINGERPRINT;
014import static org.bouncycastle.bcpg.SignatureSubpacketTags.ISSUER_FINGERPRINT;
015import static org.bouncycastle.bcpg.SignatureSubpacketTags.ISSUER_KEY_ID;
016import static org.bouncycastle.bcpg.SignatureSubpacketTags.KEY_EXPIRE_TIME;
017import static org.bouncycastle.bcpg.SignatureSubpacketTags.KEY_FLAGS;
018import static org.bouncycastle.bcpg.SignatureSubpacketTags.KEY_SERVER_PREFS;
019import static org.bouncycastle.bcpg.SignatureSubpacketTags.NOTATION_DATA;
020import static org.bouncycastle.bcpg.SignatureSubpacketTags.PLACEHOLDER;
021import static org.bouncycastle.bcpg.SignatureSubpacketTags.POLICY_URL;
022import static org.bouncycastle.bcpg.SignatureSubpacketTags.PREFERRED_AEAD_ALGORITHMS;
023import static org.bouncycastle.bcpg.SignatureSubpacketTags.PREFERRED_COMP_ALGS;
024import static org.bouncycastle.bcpg.SignatureSubpacketTags.PREFERRED_HASH_ALGS;
025import static org.bouncycastle.bcpg.SignatureSubpacketTags.PREFERRED_KEY_SERV;
026import static org.bouncycastle.bcpg.SignatureSubpacketTags.PREFERRED_SYM_ALGS;
027import static org.bouncycastle.bcpg.SignatureSubpacketTags.PRIMARY_USER_ID;
028import static org.bouncycastle.bcpg.SignatureSubpacketTags.REG_EXP;
029import static org.bouncycastle.bcpg.SignatureSubpacketTags.REVOCABLE;
030import static org.bouncycastle.bcpg.SignatureSubpacketTags.REVOCATION_KEY;
031import static org.bouncycastle.bcpg.SignatureSubpacketTags.REVOCATION_REASON;
032import static org.bouncycastle.bcpg.SignatureSubpacketTags.SIGNATURE_TARGET;
033import static org.bouncycastle.bcpg.SignatureSubpacketTags.SIGNER_USER_ID;
034import static org.bouncycastle.bcpg.SignatureSubpacketTags.TRUST_SIG;
035
036import java.util.ArrayList;
037import java.util.List;
038import java.util.Map;
039import java.util.concurrent.ConcurrentHashMap;
040
041/**
042 * Enumeration of possible subpackets that might be found in the hashed and unhashed area of an OpenPGP signature.
043 *
044 * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.1">RFC4880: Signature Subpacket Specification</a>
045 */
046public enum SignatureSubpacket {
047
048    /**
049     * The time the signature was made.
050     * MUST be present in the hashed area of the signature.
051     *
052     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.4">Signature Creation Time</a>
053     */
054    signatureCreationTime(CREATION_TIME),
055
056    /**
057     * The validity period of the signature.  This is the number of seconds
058     * after the signature creation time that the signature expires.  If
059     * this is not present or has a value of zero, it never expires.
060     *
061     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.10">Signature Expiration Time</a>
062     */
063    signatureExpirationTime(EXPIRE_TIME),
064
065    /**
066     * Denotes whether the signature is exportable for other users.
067     *
068     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.11">Exportable Certification</a>
069     */
070    exportableCertification(EXPORTABLE),
071
072    /**
073     * Signer asserts that the key is not only valid but also trustworthy at
074     * the specified level.  Level 0 has the same meaning as an ordinary
075     * validity signature.  Level 1 means that the signed key is asserted to
076     * be a valid, trusted introducer, with the 2nd octet of the body
077     * specifying the degree of trust.  Level 2 means that the signed key is
078     * asserted to be trusted to issue level 1 trust signatures, i.e., that
079     * it is a "meta introducer".  Generally, a level n trust signature
080     * asserts that a key is trusted to issue level n-1 trust signatures.
081     * The trust amount is in a range from 0-255, interpreted such that
082     * values less than 120 indicate partial trust and values of 120 or
083     * greater indicate complete trust.  Implementations SHOULD emit values
084     * of 60 for partial trust and 120 for complete trust.
085     *
086     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.13">Trust Signature</a>
087     */
088    trustSignature(TRUST_SIG),
089
090    /**
091     * Used in conjunction with trust Signature packets (of level greater 0) to
092     * limit the scope of trust that is extended.  Only signatures by the
093     * target key on User IDs that match the regular expression in the body
094     * of this packet have trust extended by the trust Signature subpacket.
095     * The regular expression uses the same syntax as the Henry Spencer's
096     * "almost public domain" regular expression [REGEX] package.  A
097     * description of the syntax is found in Section 8 below.
098     *
099     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.14">Regular Expression</a>
100     */
101    regularExpression(REG_EXP),
102
103    /**
104     * Signature's revocability status.  The packet body contains a Boolean
105     * flag indicating whether the signature is revocable.  Signatures that
106     * are not revocable have any later revocation signatures ignored.  They
107     * represent a commitment by the signer that he cannot revoke his
108     * signature for the life of his key.  If this packet is not present,
109     * the signature is revocable.
110     *
111     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.12">Revocable</a>
112     */
113    revocable(REVOCABLE),
114
115    /**
116     * The validity period of the key.  This is the number of seconds after
117     * the key creation time that the key expires.  If this is not present
118     * or has a value of zero, the key never expires.  This is found only on
119     * a self-signature.
120     *
121     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.6">Key Expiration Time</a>
122     */
123    keyExpirationTime(KEY_EXPIRE_TIME),
124
125    /**
126     * Placeholder for backwards compatibility.
127     */
128    placeholder(PLACEHOLDER),
129
130    /**
131     *  Symmetric algorithm numbers that indicate which algorithms the keyholder
132     *  prefers to use.  The subpackets body is an ordered list of
133     *  octets with the most preferred listed first.  It is assumed that only
134     *  algorithms listed are supported by the recipient's software.
135     *  This is only found on a self-signature.
136     *
137     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.7">Preferred Symmetric Algorithms</a>
138     */
139    preferredSymmetricAlgorithms(PREFERRED_SYM_ALGS),
140
141    /**
142     * Authorizes the specified key to issue revocation signatures for this
143     * key.  Class octet must have bit 0x80 set.  If the bit 0x40 is set,
144     * then this means that the revocation information is sensitive.  Other
145     * bits are for future expansion to other kinds of authorizations.  This
146     * is found on a self-signature.
147     *
148     * If the "sensitive" flag is set, the keyholder feels this subpacket
149     * contains private trust information that describes a real-world
150     * sensitive relationship.  If this flag is set, implementations SHOULD
151     * NOT export this signature to other users except in cases where the
152     * data needs to be available: when the signature is being sent to the
153     * designated revoker, or when it is accompanied by a revocation
154     * signature from that revoker.  Note that it may be appropriate to
155     * isolate this subpacket within a separate signature so that it is not
156     * combined with other subpackets that need to be exported.
157     *
158     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.15">Revocation Key</a>
159     */
160    revocationKey(REVOCATION_KEY),
161
162    /**
163     * The OpenPGP Key ID of the key issuing the signature.
164     *
165     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.5">Issuer Key ID</a>
166     */
167    issuerKeyId(ISSUER_KEY_ID),
168
169    /**
170     * This subpacket describes a "notation" on the signature that the
171     * issuer wishes to make.  The notation has a name and a value, each of
172     * which are strings of octets.  There may be more than one notation in
173     * a signature.  Notations can be used for any extension the issuer of
174     * the signature cares to make.  The "flags" field holds four octets of
175     * flags.
176     *
177     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.16">Notation Data</a>
178     */
179    notationData(NOTATION_DATA),
180
181    /**
182     * Message digest algorithm numbers that indicate which algorithms the
183     * keyholder prefers to receive.  Like the preferred symmetric
184     * algorithms, the list is ordered.
185     * This is only found on a self-signature.
186     *
187     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.8">Preferred Hash Algorithms</a>
188     */
189    preferredHashAlgorithms(PREFERRED_HASH_ALGS),
190
191    /**
192     * Compression algorithm numbers that indicate which algorithms the
193     * keyholder prefers to use.  Like the preferred symmetric algorithms, the
194     * list is ordered. If this subpacket is not included, ZIP is preferred.
195     * A zero denotes that uncompressed data is preferred; the keyholder's
196     * software might have no compression software in that implementation.
197     * This is only found on a self-signature.
198     *
199     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.9">Preferred Compressio Algorithms</a>
200     */
201    preferredCompressionAlgorithms(PREFERRED_COMP_ALGS),
202
203    /**
204     * This is a list of one-bit flags that indicate preferences that the
205     * keyholder has about how the key is handled on a key server.  All
206     * undefined flags MUST be zero.
207     * This is found only on a self-signature.
208     *
209     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.17">Key Server Preferences</a>
210     */
211    keyServerPreferences(KEY_SERVER_PREFS),
212
213    /**
214     * This is a URI of a key server that the keyholder prefers be used for
215     * updates.  Note that keys with multiple User IDs can have a preferred
216     * key server for each User ID.  Note also that since this is a URI, the
217     * key server can actually be a copy of the key retrieved by ftp, http,
218     * finger, etc.
219     *
220     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.18">Preferred Key Server</a>
221     */
222    preferredKeyServers(PREFERRED_KEY_SERV),
223
224    /**
225     * This is a flag in a User ID's self-signature that states whether this
226     * User ID is the main User ID for this key.  It is reasonable for an
227     * implementation to resolve ambiguities in preferences, etc. by
228     * referring to the primary User ID.  If this flag is absent, its value
229     * is zero.  If more than one User ID in a key is marked as primary, the
230     * implementation may resolve the ambiguity in any way it sees fit, but
231     * it is RECOMMENDED that priority be given to the User ID with the most
232     * recent self-signature.
233     *
234     * When appearing on a self-signature on a User ID packet, this
235     * subpacket applies only to User ID packets.  When appearing on a
236     * self-signature on a User Attribute packet, this subpacket applies
237     * only to User Attribute packets.  That is to say, there are two
238     * different and independent "primaries" -- one for User IDs, and one
239     * for User Attributes.
240     *
241     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.19">Primary User-ID</a>
242     */
243    primaryUserId(PRIMARY_USER_ID),
244
245    /**
246     * This subpacket contains a URI of a document that describes the policy
247     * under which the signature was issued.
248     *
249     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.20">Policy URL</a>
250     */
251    policyUrl(POLICY_URL),
252
253    /**
254     * This subpacket contains a list of binary flags that hold information
255     * about a key.  It is a string of octets, and an implementation MUST
256     * NOT assume a fixed size.  This is so it can grow over time.  If a
257     * list is shorter than an implementation expects, the unstated flags
258     * are considered to be zero.
259     *
260     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.21">Key Flags</a>
261     */
262    keyFlags(KEY_FLAGS),
263
264    /**
265     * This subpacket allows a keyholder to state which User ID is
266     * responsible for the signing.  Many keyholders use a single key for
267     * different purposes, such as business communications as well as
268     * personal communications.  This subpacket allows such a keyholder to
269     * state which of their roles is making a signature.
270     *
271     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.22">Signer's User ID</a>
272     */
273    signerUserId(SIGNER_USER_ID),
274
275    /**
276     * This subpacket is used only in key revocation and certification
277     * revocation signatures.  It describes the reason why the key or
278     * certificate was revoked.
279     *
280     * The first octet contains a machine-readable code that denotes the
281     * reason for the revocation:
282     *
283     *         0  - No reason specified (key revocations or cert revocations)
284     *         1  - Key is superseded (key revocations)
285     *         2  - Key material has been compromised (key revocations)
286     *         3  - Key is retired and no longer used (key revocations)
287     *         32 - User ID information is no longer valid (cert revocations)
288     *    100-110 - Private Use
289     *
290     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.23">Reason for Revocation</a>
291     */
292    revocationReason(REVOCATION_REASON),
293
294    /**
295     * The Features subpacket denotes which advanced OpenPGP features a
296     * user's implementation supports.  This is so that as features are
297     * added to OpenPGP that cannot be backwards-compatible, a user can
298     * state that they can use that feature.  The flags are single bits that
299     * indicate that a given feature is supported.
300     *
301     * This subpacket is similar to a preferences subpacket, and only
302     * appears in a self-signature.
303     *
304     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.24">Features</a>
305     */
306    features(FEATURES),
307
308    /**
309     * This subpacket identifies a specific target signature to which a
310     * signature refers.  For revocation signatures, this subpacket
311     * provides explicit designation of which signature is being revoked.
312     * For a third-party or timestamp signature, this designates what
313     * signature is signed.  All arguments are an identifier of that target
314     * signature.
315     *
316     * The N octets of hash data MUST be the size of the hash of the
317     * signature.  For example, a target signature with a SHA-1 hash MUST
318     * have 20 octets of hash data.
319     *
320     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.25">Signature Target</a>
321     */
322    signatureTarget(SIGNATURE_TARGET),
323
324    /**
325     * This subpacket contains a complete Signature packet body as
326     * specified in Section 5.2 above.  It is useful when one signature
327     * needs to refer to, or be incorporated in, another signature.
328     *
329     * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.26">Embedded Signature</a>
330     */
331    embeddedSignature(EMBEDDED_SIGNATURE),
332
333    /**
334     * The OpenPGP Key fingerprint of the key issuing the signature.  This
335     * subpacket SHOULD be included in all signatures.  If the version of
336     * the issuing key is 4 and an Issuer subpacket is also included in the
337     * signature, the key ID of the Issuer subpacket MUST match the low 64
338     * bits of the fingerprint.
339     *
340     * Note that the length N of the fingerprint for a version 4 key is 20
341     * octets; for a version 5 key N is 32.
342     *
343     * @see <a href="https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10#section-5.2.3.28">Issuer Fingerprint</a>
344     */
345    issuerFingerprint(ISSUER_FINGERPRINT),
346
347    /**
348     * AEAD algorithm numbers that indicate which AEAD algorithms the
349     * keyholder prefers to use.  The subpackets body is an ordered list of
350     * octets with the most preferred listed first.  It is assumed that only
351     * algorithms listed are supported by the recipient's software.
352     * This is only found on a self-signature.
353     * Note that support for the AEAD Encrypted Data packet in the general
354     * is indicated by a Feature Flag.
355     *
356     * @see <a href="https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10#section-5.2.3.8">Preferred AEAD Algorithms</a>
357     */
358    preferredAEADAlgorithms(PREFERRED_AEAD_ALGORITHMS),
359
360    /**
361     * The OpenPGP Key fingerprint of the intended recipient primary key.
362     * If one or more subpackets of this type are included in a signature,
363     * it SHOULD be considered valid only in an encrypted context, where the
364     * key it was encrypted to is one of the indicated primary keys, or one
365     * of their subkeys.  This can be used to prevent forwarding a signature
366     * outside its intended, encrypted context.
367     *
368     * Note that the length N of the fingerprint for a version 4 key is 20
369     * octets; for a version 5 key N is 32.
370     *
371     * @see <a href="https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10#section-5.2.3.29">Intended Recipient Fingerprint</a>
372     */
373    intendedRecipientFingerprint(INTENDED_RECIPIENT_FINGERPRINT),
374
375    /**
376     * This subpacket MUST only appear as a hashed subpacket of an
377     * Attestation Key Signature.  It has no meaning in any other signature
378     * type.  It is used by the primary key to attest to a set of third-
379     * party certifications over the associated User ID or User Attribute.
380     * This enables the holder of an OpenPGP primary key to mark specific
381     * third-party certifications as re-distributable with the rest of the
382     * Transferable Public Key (see the "No-modify" flag in "Key Server
383     * Preferences", above).  Implementations MUST include exactly one
384     * Attested Certification subpacket in any generated Attestation Key
385     * Signature.
386     *
387     * @see <a href="https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-10#section-5.2.3.30">Attested Certification</a>
388     */
389    attestedCertification(ATTESTED_CERTIFICATIONS)
390    ;
391
392    private static final Map<Integer, SignatureSubpacket> MAP = new ConcurrentHashMap<>();
393    static {
394        for (SignatureSubpacket p : values()) {
395            MAP.put(p.code, p);
396        }
397    }
398
399    private final int code;
400
401    SignatureSubpacket(int code) {
402        this.code = code;
403    }
404
405    /**
406     * Return the numerical identifier of the {@link SignatureSubpacket}.
407     * @return id
408     */
409    public int getCode() {
410        return code;
411    }
412
413    /**
414     * Return the {@link SignatureSubpacket} that corresponds to the provided id.
415     *
416     * @param code id
417     * @return signature subpacket
418     */
419    public static SignatureSubpacket fromCode(int code) {
420        SignatureSubpacket tag = MAP.get(code);
421        if (tag == null) {
422            throw new IllegalArgumentException("No SignatureSubpacket tag found with code " + code);
423        }
424        return tag;
425    }
426
427    /**
428     * Convert an array of signature subpacket tags into a list of {@link SignatureSubpacket SignatureSubpackets}.
429     *
430     * @param codes array of codes
431     * @return list of subpackets
432     */
433    public static List<SignatureSubpacket> fromCodes(int[] codes) {
434        List<SignatureSubpacket> tags = new ArrayList<>();
435        for (int code : codes) {
436            tags.add(fromCode(code));
437        }
438        return tags;
439    }
440}