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 org.jpos.iso.ISOUtil; 022 023import java.io.PrintStream; 024import java.util.regex.Matcher; 025import java.util.regex.Pattern; 026 027/** 028 * The SecureDESKey class represents: <br> 029 * Single, double or triple length DES keys that are secured by a security module. 030 * This is typically the DES key encrypted under one of the Local Master Keys of the 031 * security module. 032 * <p> 033 * SecureDESKey has an extra property "Key Check Value". It allows assuring that 034 * two SecureDESKeys owned by two different parties map 035 * to the same clear key. This can be a useful manual check for successful key 036 * exchange. 037 * <p> 038 * NOTE: The security of SecureDESKey is totally dependent on the security of 039 * the used security module. 040 * 041 * @author Hani S. Kirollos 042 * @author Robert Demski 043 * @see SMAdapter 044 */ 045public class SecureDESKey extends SecureVariantKey { 046 047 private static final long serialVersionUID = -9145281998779008306L; 048 049 /** 050 * Regular expression pattern representing key type string value. 051 */ 052 protected static final Pattern KEY_TYPE_PATTERN = Pattern.compile("([^:;]*)([:;])?([^:;])?([^:;])?"); 053 054 public SecureDESKey() { 055 super(); 056 } 057 058 /** 059 * Constructs an SecureDESKey 060 * @param keyLength e.g. LENGTH_DES, LENGTH_DES3_2KEY, LENGTH_DES3_3KEY 061 * @param keyType 062 * @param variant 063 * @param scheme 064 * @param keyBytes DES Key in the secure proprietary format of your security module 065 * @param keyCheckValue 066 * @see SMAdapter 067 */ 068 public SecureDESKey (short keyLength, String keyType, byte variant, KeyScheme scheme, byte[] keyBytes, 069 byte[] keyCheckValue) { 070 setKeyLength(keyLength); 071 setKeyType(keyType); 072 setVariant(variant); 073 setScheme(scheme); 074 setKeyBytes(keyBytes); 075 setKeyCheckValue(keyCheckValue); 076 } 077 078 /** 079 * Constructs an SecureDESKey 080 * @param keyLength e.g. LENGTH_DES, LENGTH_DES3_2KEY, LENGTH_DES3_3KEY 081 * @param keyType 082 * @param keyBytes DES Key in the secure proprietary format of your security module 083 * @param keyCheckValue 084 * @see SMAdapter 085 */ 086 public SecureDESKey (short keyLength, String keyType, byte[] keyBytes, 087 byte[] keyCheckValue) { 088 setKeyLength(keyLength); 089 setKeyType(keyType); 090 setKeyBytes(keyBytes); 091 setKeyCheckValue(keyCheckValue); 092 getVariant(); //only for set variant with defaults 093 getScheme(); //only set scheme with defaults 094 } 095 096 /** 097 * Constructs an SecureDESKey 098 * @param keyLength 099 * @param keyType 100 * @param keyHexString secure key represented as HexString instead of byte[] 101 * @param keyCheckValueHexString key check value represented as HexString instead of byte[] 102 */ 103 public SecureDESKey (short keyLength, String keyType, String keyHexString, 104 String keyCheckValueHexString) { 105 this(keyLength, keyType, ISOUtil.hex2byte(keyHexString), ISOUtil.hex2byte(keyCheckValueHexString)); 106 } 107 108 /** 109 * Constructs an SecureDESKey 110 * @param keyLength 111 * @param keyType 112 * @param variant 113 * @param scheme 114 * @param keyHexString secure key represented as HexString instead of byte[] 115 * @param keyCheckValueHexString key check value represented as HexString instead of byte[] 116 */ 117 public SecureDESKey (short keyLength, String keyType, byte variant, KeyScheme scheme, String keyHexString, 118 String keyCheckValueHexString) { 119 this(keyLength, keyType, variant, scheme, ISOUtil.hex2byte(keyHexString), ISOUtil.hex2byte(keyCheckValueHexString)); 120 } 121 122 @Override 123 public byte getVariant () { 124 if (variant!=null) 125 return variant; 126 /** 127 * Some variant derivation if it hasn't been explicity stated 128 */ 129 variant = 0; 130 Matcher m = KEY_TYPE_PATTERN.matcher(keyType); 131 m.find(); 132 if (m.group(3) != null) 133 try { 134 variant = Byte.valueOf(m.group(3)); 135 } catch (NumberFormatException ex){ 136 throw new NumberFormatException("Value "+m.group(4)+" is not valid key variant"); 137 } 138 return variant; 139 } 140 141 @Override 142 public KeyScheme getScheme () { 143 if (scheme!=null) 144 return scheme; 145 /** 146 * Some scheme derivation if it hasn't been explicity stated 147 */ 148 switch (keyLength){ 149 case SMAdapter.LENGTH_DES: 150 scheme = KeyScheme.Z; break; 151 case SMAdapter.LENGTH_DES3_2KEY: 152 scheme = KeyScheme.X; break; 153 case SMAdapter.LENGTH_DES3_3KEY: 154 scheme = KeyScheme.Y; break; 155 } 156 Matcher m = KEY_TYPE_PATTERN.matcher(keyType); 157 m.find(); 158 if (m.group(4) != null) 159 try { 160 scheme = KeyScheme.valueOf(m.group(4)); 161 } catch (IllegalArgumentException ex){ 162 throw new IllegalArgumentException("Value "+m.group(4)+" is not valid key scheme"); 163 } 164 return scheme; 165 } 166 167 /** 168 * dumps SecureDESKey basic information 169 * @param p a PrintStream usually supplied by Logger 170 * @param indent indention string, usually suppiled by Logger 171 * @see org.jpos.util.Loggeable 172 */ 173 @Override 174 public void dump (PrintStream p, String indent) { 175 String inner = indent + " "; 176 p.print(indent + "<secure-des-key"); 177 p.print(" length=\"" + getKeyLength() + "\""); 178 p.print(" type=\"" + keyType + "\""); 179 p.print(" variant=\"" + getVariant() + "\""); 180 p.print(" scheme=\"" + this.getScheme() + "\""); 181 if (keyName != null) 182 p.print(" name=\"" + keyName + "\""); 183 184 p.println(">"); 185 p.println(inner + "<data>" + ISOUtil.hexString(getKeyBytes()) + "</data>"); 186 p.println(inner + "<check-value>" + ISOUtil.hexString(getKeyCheckValue()) + "</check-value>"); 187 p.println(indent + "</secure-des-key>"); 188 } 189} 190 191 192