001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2026 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jpos.security;
020
021import java.io.Serializable;
022import java.util.Collections;
023import java.util.LinkedHashMap;
024import java.util.Map;
025import java.util.Objects;
026import org.jpos.iso.ISOUtil;
027
028/**
029 * Defines the primary usage of the key contained in the key block.
030 * <p>
031 * Each value repesents bytes 5-6 of the keyblock header.
032 */
033public class KeyUsage implements Serializable {
034    private static final long serialVersionUID = -5504819939017756749L;
035
036    /** TR-31 key usage code registry mapping code strings to KeyUsage enum constants. */
037    protected static final Map<String, KeyUsage> TR31MAP =  new LinkedHashMap<>();
038
039    /**
040     * TR-31 BDK Base Derivation Key.
041     */
042    public final static KeyUsage BDK       = create("B0", "BDK - Base Derivation Key");
043
044    /**
045     * TR-31 DUKPT Initial Key (IKEY aka IPEK).
046     */
047    public final static KeyUsage IKEY      = create("B1", "IKEY - DUKPT Initial Key");
048
049    /**
050     * TR-31 CVK Card Verification Key.
051     */
052    public final static KeyUsage CVK       = create("C0", "CVK - Card Verification Key");
053
054    /**
055     * TR-31 Data Encryption Key.
056     */
057    public final static KeyUsage ENC       = create("D0", "Data Encryption Key");
058
059    /**
060     * TR-31 Initialization Value.
061     * <p>
062     * Used for protect eg. Initalization Vector or Decimalization Table.
063     */
064    public final static KeyUsage INIT      = create("I0", "Initialization Value");
065
066    /**
067     * TR-31 Generic Key Encryption / Wrapping Key.
068     */
069    public final static KeyUsage KEK       = create("K0", "Key Encryption / Wrapping Key");
070
071    /**
072     * TR-31 Key Block Protection Key.
073     */
074    public final static KeyUsage KEKWRAP   = create("K1", "Key Block Protection Key");
075
076    /**
077     * TR-31 ISO 16609 MAC algorithm 1 Key <i>(using 3-DES)</i>.
078     */
079    public final static KeyUsage ISOMAC0   = create("M0", "ISO 16609 MAC algorithm 1 Key");
080
081    /**
082     * TR-31 ISO 9797-1 MAC algorithm 1 Key.
083     */
084    public final static KeyUsage ISOMAC1   = create("M1", "ISO 9797-1 MAC algorithm 1 Key");
085
086    /**
087     * TR-31 ISO 9797-1 MAC algorithm 2 Key.
088     */
089    public final static KeyUsage ISOMAC2   = create("M2", "ISO 9797-1 MAC algorithm 2 Key");
090
091    /**
092     * TR-31 ISO 9797-1 MAC algorithm 3 Key.
093     */
094    public final static KeyUsage ISOMAC3   = create("M3", "ISO 9797-1 MAC algorithm 3 Key");
095
096    /**
097     * TR-31 ISO 9797-1 MAC algorithm 4 Key.
098     */
099    public final static KeyUsage ISOMAC4   = create("M4", "ISO 9797-1 MAC algorithm 4 Key");
100
101    /**
102     * TR-31 ISO 9797-1 MAC algorithm 5 Key.
103     */
104    public final static KeyUsage ISOMAC5   = create("M5", "ISO 9797-1 MAC algorithm 5 Key");
105
106    /**
107     * TR-31 Generic PIN Encription Key.
108     */
109    public final static KeyUsage PINENC    = create("P0", "PIN encryption key");
110
111    /**
112     * TR-31 Generic PIN Verification Key.
113     */
114    public final static KeyUsage PINVER    = create("V0", "PIN verification key or other algorithm");
115
116    /**
117     * TR-31 PIN Verification Key (IBM 3624 algorithm).
118     */
119    public final static KeyUsage PINV3624  = create("V1", "PIN verification key, IBM 3624 algorithm");
120
121    /**
122     * TR-31 PIN Verification Key (Visa PVV algorithm).
123     */
124    public final static KeyUsage VISAPVV   = create("V2", "PIN verification key, VISA PVV algorithm");
125
126    /**
127     * TR-31 Application Cryptograms Key.
128     */
129    public final static KeyUsage EMVACMK   = create("E0", "EMV/Chip card Master Key, MKAC - Application Cryptogram");
130
131    /**
132     * TR-31 Secure Messaging for Confidentiality Key.
133     */
134    public final static KeyUsage EMVSCMK   = create("E1", "EMV/Chip card Master Key, MKSMC - Secure Messaging for Confidentiality");
135
136    /**
137     * TR-31 Secure Messaging for Integrity.
138     */
139    public final static KeyUsage EMVSIMK   = create("E2", "EMV/Chip card Master Key, MKSMI - Secure Messaging for Integrity");
140
141    /**
142     * TR-31 Data Authentication Code Key.
143     */
144    public final static KeyUsage EMVDAMK   = create("E3", "EMV/Chip card Master Key, MKDAC - Data Authentication Code");
145
146    /**
147     * TR-31 Dynamic Numbers Key.
148     */
149    public final static KeyUsage EMVDNMK   = create("E4", "EMV/Chip card Master Key, MKDN - Dynamic Numbers");
150
151    /**
152     * TR-31 Card Personalization Key.
153     */
154    public final static KeyUsage EMVCPMK   = create("E5", "EMV/Chip card Master Key, Card Personalization");
155
156    /**
157     * TR-31 Chip card Master Key.
158     */
159    public final static KeyUsage EMVOTMK   = create("E6", "EMV/Chip card Master Key, Other");
160
161    /**
162     * TR-31 Master Personalization Key.
163     */
164    public final static KeyUsage EMVMPMK   = create("E7", "EMV/Master Personalization Key");
165
166
167    /** Two-character TR-31 key-usage code. */
168    private final String code;
169    /** Human-readable description of the key usage. */
170    private final String name;
171
172    /**
173     * Internal constructor.
174     * <p>
175     * The constructor is protected to guarantee only one instance of the key
176     * usage in the entire JVM. This makes it possible to use the operator
177     * {@code ==} or {@code !=} as it does for enums.
178     *
179     * @param code the key usage code
180     * @param name the usage name
181     */
182    protected KeyUsage(String code, String name) {
183        Objects.requireNonNull(code, "The code of key usage is required");
184        Objects.requireNonNull(name, "The name of key usage is required");
185        if (code.length() != 2)  //The length of the code must be 2
186            throw new IllegalArgumentException("The length of the key block Key Usage code must be 2");
187
188        this.code = code;
189        this.name = name;
190    }
191
192    private static KeyUsage create(String code, String name) {
193        KeyUsage ku = new KeyUsage(code, name);
194        if (ISOUtil.isNumeric(code, 10))
195            throw new IllegalArgumentException(
196                "The TR-31 Key Usage code can not consist of digits only"
197            );
198        if (TR31MAP.containsKey(ku.getCode()))
199            throw new IllegalArgumentException(
200                "The TR-31 Key Usage code can by registered only once"
201            );
202        TR31MAP.put(ku.getCode(), ku);
203        return ku;
204    }
205
206    /**
207     * Get key usage code.
208     *
209     * @return two characters which represents key usage code
210     */
211    public String getCode() {
212        return code;
213    }
214
215    /**
216     * Get key usage name.
217     *
218     * @return the key usage name
219     */
220    public String getName() {
221        return name;
222    }
223
224    @Override
225    public String toString() {
226        return String.format("KeyUsage[code: %s, name: %s]", code, name);
227    }
228
229    /**
230     * Returns the enum constant of this type with the specified {@code code}.
231     *
232     * @param code the TR-31 key usage code to look up
233     * @return the enum constant with the specified processing code or
234     *         {@code null} if unknown.
235     */
236    public static KeyUsage valueOfByCode(String code) {
237        return TR31MAP.get(code);
238    }
239
240    /**
241     * Returns an unmodifiable view of the TR-31 code → {@link KeyUsage} map.
242     *
243     * @return read-only mapping of TR-31 codes to enum constants
244     */
245    public static Map<String, KeyUsage> entries() {
246        return Collections.unmodifiableMap(TR31MAP);
247    }
248
249}