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 035 private static final long serialVersionUID = -5504819939017756749L; 036 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 private final String code; 168 private final String name; 169 170 /** 171 * Internal constructor. 172 * <p> 173 * The constructor is protected to guarantee only one instance of the key 174 * usage in the entire JVM. This makes it possible to use the operator 175 * {@code ==} or {@code !=} as it does for enums. 176 * 177 * @param code the key usage code 178 * @param name the usage name 179 */ 180 protected KeyUsage(String code, String name) { 181 Objects.requireNonNull(code, "The code of key usage is required"); 182 Objects.requireNonNull(name, "The name of key usage is required"); 183 if (code.length() != 2) //The length of the code must be 2 184 throw new IllegalArgumentException("The length of the key block Key Usage code must be 2"); 185 186 this.code = code; 187 this.name = name; 188 } 189 190 private static KeyUsage create(String code, String name) { 191 KeyUsage ku = new KeyUsage(code, name); 192 if (ISOUtil.isNumeric(code, 10)) 193 throw new IllegalArgumentException( 194 "The TR-31 Key Usage code can not consist of digits only" 195 ); 196 if (TR31MAP.containsKey(ku.getCode())) 197 throw new IllegalArgumentException( 198 "The TR-31 Key Usage code can by registered only once" 199 ); 200 TR31MAP.put(ku.getCode(), ku); 201 return ku; 202 } 203 204 /** 205 * Get key usage code. 206 * 207 * @return two characters which represents key usage code 208 */ 209 public String getCode() { 210 return code; 211 } 212 213 /** 214 * Get key usage name. 215 * 216 * @return the key usage name 217 */ 218 public String getName() { 219 return name; 220 } 221 222 @Override 223 public String toString() { 224 return String.format("KeyUsage[code: %s, name: %s]", code, name); 225 } 226 227 /** 228 * Returns the enum constant of this type with the specified {@code code}. 229 * 230 * @param code 231 * @return the enum constant with the specified processing code or 232 * {@code null} if unknown. 233 */ 234 public static KeyUsage valueOfByCode(String code) { 235 return TR31MAP.get(code); 236 } 237 238 public static Map<String, KeyUsage> entries() { 239 return Collections.unmodifiableMap(TR31MAP); 240 } 241 242}