001// SPDX-FileCopyrightText: 2018 Paul Schaub <vanitasvitae@fsfe.org>
002//
003// SPDX-License-Identifier: Apache-2.0
004
005package org.pgpainless.algorithm;
006
007import java.util.Map;
008import java.util.concurrent.ConcurrentHashMap;
009
010import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
011
012/**
013 * Enumeration of public key algorithms as defined in RFC4880.
014 *
015 * @see <a href="https://tools.ietf.org/html/rfc4880#section-9.1">RFC4880: Public-Key Algorithms</a>
016 */
017public enum PublicKeyAlgorithm {
018
019    /**
020     * RSA capable of encryption and signatures.
021     */
022    RSA_GENERAL     (PublicKeyAlgorithmTags.RSA_GENERAL, true, true),
023
024    /**
025     * RSA with usage encryption.
026     *
027     * @deprecated see https://tools.ietf.org/html/rfc4880#section-13.5
028     */
029    @Deprecated
030    RSA_ENCRYPT     (PublicKeyAlgorithmTags.RSA_ENCRYPT, false, true),
031
032    /**
033     * RSA with usage of creating signatures.
034     *
035     * @deprecated see https://tools.ietf.org/html/rfc4880#section-13.5
036     */
037    @Deprecated
038    RSA_SIGN        (PublicKeyAlgorithmTags.RSA_SIGN, true, false),
039
040    /**
041     * ElGamal with usage encryption.
042     */
043    ELGAMAL_ENCRYPT (PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, false, true),
044
045    /**
046     * Digital Signature Algorithm.
047     */
048    DSA             (PublicKeyAlgorithmTags.DSA, true, false),
049
050    /**
051     * EC is deprecated.
052     * @deprecated use {@link #ECDH} instead.
053     */
054    @Deprecated
055    EC              (PublicKeyAlgorithmTags.EC, false, true),
056
057    /**
058     * Elliptic Curve Diffie-Hellman.
059     */
060    ECDH            (PublicKeyAlgorithmTags.ECDH, false, true),
061
062    /**
063     * Elliptic Curve Digital Signature Algorithm.
064     */
065    ECDSA           (PublicKeyAlgorithmTags.ECDSA, true, false),
066
067    /**
068     * ElGamal General.
069     *
070     * @deprecated see https://tools.ietf.org/html/rfc4880#section-13.8
071     */
072    @Deprecated
073    ELGAMAL_GENERAL (PublicKeyAlgorithmTags.ELGAMAL_GENERAL, true, true),
074
075    /**
076     * Diffie-Hellman key exchange algorithm.
077     */
078    DIFFIE_HELLMAN  (PublicKeyAlgorithmTags.DIFFIE_HELLMAN, false, true),
079
080    /**
081     * Digital Signature Algorithm based on twisted Edwards Curves.
082     */
083    EDDSA           (PublicKeyAlgorithmTags.EDDSA, true, false),
084    ;
085
086    private static final Map<Integer, PublicKeyAlgorithm> MAP = new ConcurrentHashMap<>();
087
088    static {
089        for (PublicKeyAlgorithm p : PublicKeyAlgorithm.values()) {
090            MAP.put(p.algorithmId, p);
091        }
092    }
093
094    /**
095     * Return the {@link PublicKeyAlgorithm} that corresponds to the provided algorithm id.
096     * If an invalid id is provided, null is returned.
097     *
098     * @param id numeric algorithm id
099     * @return algorithm
100     */
101    public static PublicKeyAlgorithm fromId(int id) {
102        return MAP.get(id);
103    }
104
105    private final int algorithmId;
106    private final boolean signingCapable;
107    private final boolean encryptionCapable;
108
109    PublicKeyAlgorithm(int algorithmId, boolean signingCapable, boolean encryptionCapable) {
110        this.algorithmId = algorithmId;
111        this.signingCapable = signingCapable;
112        this.encryptionCapable = encryptionCapable;
113    }
114
115    /**
116     * Return the numeric identifier of the public key algorithm.
117     *
118     * @return id
119     */
120    public int getAlgorithmId() {
121        return algorithmId;
122    }
123
124    /**
125     * Return true if this public key algorithm is able to create signatures.
126     *
127     * @return true if the algorithm can sign
128     */
129    public boolean isSigningCapable() {
130        return signingCapable;
131    }
132
133    /**
134     * Return true if this public key algorithm can be used as an encryption algorithm.
135     *
136     * @return true if the algorithm can encrypt
137     */
138    public boolean isEncryptionCapable() {
139        return encryptionCapable;
140    }
141}