1 /* 2 * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * 28 * (C) Copyright IBM Corp. 1999 All Rights Reserved. 29 * Copyright 1997 The Open Group Research Institute. All rights reserved. 30 */ 31 32 package sun.security.krb5.internal.crypto; 33 34 import sun.security.krb5.internal.*; 35 import sun.security.krb5.Config; 36 import sun.security.krb5.EncryptedData; 37 import sun.security.krb5.EncryptionKey; 38 import sun.security.krb5.KrbException; 39 import sun.security.krb5.KrbCryptoException; 40 import javax.crypto.*; 41 import java.util.Arrays; 42 import java.util.List; 43 import java.util.ArrayList; 44 45 //only needed if dataSize() implementation changes back to spec; 46 //see dataSize() below 47 48 public abstract class EType { 49 50 private static final boolean DEBUG = Krb5.DEBUG; 51 private static boolean allowWeakCrypto; 52 53 static { 54 initStatic(); 55 } 56 57 public static void initStatic() { 58 boolean allowed = false; 59 try { 60 Config cfg = Config.getInstance(); 61 String temp = cfg.get("libdefaults", "allow_weak_crypto"); 62 if (temp != null && temp.equals("true")) allowed = true; 63 } catch (Exception exc) { 64 if (DEBUG) { 65 System.out.println ("Exception in getting allow_weak_crypto, " + 66 "using default value " + 67 exc.getMessage()); 68 } 69 } 70 allowWeakCrypto = allowed; 71 } 72 73 public static EType getInstance (int eTypeConst) 74 throws KdcErrException { 75 EType eType = null; 76 String eTypeName = null; 77 switch (eTypeConst) { 78 case EncryptedData.ETYPE_NULL: 79 eType = new NullEType(); 80 eTypeName = "sun.security.krb5.internal.crypto.NullEType"; 81 break; 82 case EncryptedData.ETYPE_DES_CBC_CRC: 83 eType = new DesCbcCrcEType(); 84 eTypeName = "sun.security.krb5.internal.crypto.DesCbcCrcEType"; 85 break; 86 case EncryptedData.ETYPE_DES_CBC_MD5: 87 eType = new DesCbcMd5EType(); 88 eTypeName = "sun.security.krb5.internal.crypto.DesCbcMd5EType"; 89 break; 90 91 case EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD: 92 eType = new Des3CbcHmacSha1KdEType(); 93 eTypeName = 94 "sun.security.krb5.internal.crypto.Des3CbcHmacSha1KdEType"; 95 break; 96 97 case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96: 98 eType = new Aes128CtsHmacSha1EType(); 99 eTypeName = 100 "sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType"; 101 break; 102 103 case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96: 104 eType = new Aes256CtsHmacSha1EType(); 105 eTypeName = 106 "sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType"; 107 break; 108 109 case EncryptedData.ETYPE_ARCFOUR_HMAC: 110 eType = new ArcFourHmacEType(); 111 eTypeName = "sun.security.krb5.internal.crypto.ArcFourHmacEType"; 112 break; 113 114 default: 115 String msg = "encryption type = " + toString(eTypeConst) 116 + " (" + eTypeConst + ")"; 117 throw new KdcErrException(Krb5.KDC_ERR_ETYPE_NOSUPP, msg); 118 } 119 if (DEBUG) { 120 System.out.println(">>> EType: " + eTypeName); 121 } 122 return eType; 123 } 124 125 public abstract int eType(); 126 127 public abstract int minimumPadSize(); 128 129 public abstract int confounderSize(); 130 131 public abstract int checksumType(); 132 133 public abstract int checksumSize(); 134 135 public abstract int blockSize(); 136 137 public abstract int keyType(); 138 139 public abstract int keySize(); 140 141 public abstract byte[] encrypt(byte[] data, byte[] key, int usage) 142 throws KrbCryptoException; 143 144 public abstract byte[] encrypt(byte[] data, byte[] key, byte[] ivec, 145 int usage) throws KrbCryptoException; 146 147 public abstract byte[] decrypt(byte[] cipher, byte[] key, int usage) 148 throws KrbApErrException, KrbCryptoException; 149 150 public abstract byte[] decrypt(byte[] cipher, byte[] key, byte[] ivec, 151 int usage) throws KrbApErrException, KrbCryptoException; 152 153 public int dataSize(byte[] data) 154 // throws Asn1Exception 155 { 156 // EncodeRef ref = new EncodeRef(data, startOfData()); 157 // return ref.end - startOfData(); 158 // should be the above according to spec, but in fact 159 // implementations include the pad bytes in the data size 160 return data.length - startOfData(); 161 } 162 163 public int padSize(byte[] data) { 164 return data.length - confounderSize() - checksumSize() - 165 dataSize(data); 166 } 167 168 public int startOfChecksum() { 169 return confounderSize(); 170 } 171 172 public int startOfData() { 173 return confounderSize() + checksumSize(); 174 } 175 176 public int startOfPad(byte[] data) { 177 return confounderSize() + checksumSize() + dataSize(data); 178 } 179 180 public byte[] decryptedData(byte[] data) { 181 int tempSize = dataSize(data); 182 byte[] result = new byte[tempSize]; 183 System.arraycopy(data, startOfData(), result, 0, tempSize); 184 return result; 185 } 186 187 // Note: the first 2 entries of BUILTIN_ETYPES and BUILTIN_ETYPES_NOAES256 188 // should be kept DES-related. They will be removed when allow_weak_crypto 189 // is set to false. 190 191 private static final int[] BUILTIN_ETYPES = new int[] { 192 EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96, 193 EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96, 194 EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD, 195 EncryptedData.ETYPE_ARCFOUR_HMAC, 196 EncryptedData.ETYPE_DES_CBC_CRC, 197 EncryptedData.ETYPE_DES_CBC_MD5, 198 }; 199 200 private static final int[] BUILTIN_ETYPES_NOAES256 = new int[] { 201 EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96, 202 EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD, 203 EncryptedData.ETYPE_ARCFOUR_HMAC, 204 EncryptedData.ETYPE_DES_CBC_CRC, 205 EncryptedData.ETYPE_DES_CBC_MD5, 206 }; 207 208 209 // used in Config 210 public static int[] getBuiltInDefaults() { 211 int allowed = 0; 212 try { 213 allowed = Cipher.getMaxAllowedKeyLength("AES"); 214 } catch (Exception e) { 215 // should not happen 216 } 217 int[] result; 218 if (allowed < 256) { 219 result = BUILTIN_ETYPES_NOAES256; 220 } else { 221 result = BUILTIN_ETYPES; 222 } 223 if (!allowWeakCrypto) { 224 // The last 2 etypes are now weak ones 225 return Arrays.copyOfRange(result, 0, result.length - 2); 226 } 227 return result; 228 } 229 230 /** 231 * Retrieves the default etypes from the configuration file, or 232 * if that's not available, return the built-in list of default etypes. 233 */ 234 // used in KrbAsReq, KeyTab 235 public static int[] getDefaults(String configName) { 236 try { 237 return Config.getInstance().defaultEtype(configName); 238 } catch (KrbException exc) { 239 if (DEBUG) { 240 System.out.println("Exception while getting " + 241 configName + exc.getMessage()); 242 System.out.println("Using default builtin etypes"); 243 } 244 return getBuiltInDefaults(); 245 } 246 } 247 248 /** 249 * Retrieve the default etypes from the configuration file for 250 * those etypes for which there are corresponding keys. 251 * Used in scenario we have some keys from a keytab with etypes 252 * different from those named in configName. Then, in order 253 * to decrypt an AS-REP, we should only ask for etypes for which 254 * we have keys. 255 */ 256 public static int[] getDefaults(String configName, EncryptionKey[] keys) 257 throws KrbException { 258 int[] answer = getDefaults(configName); 259 if (answer == null) { 260 throw new KrbException("No supported encryption types listed in " 261 + configName); 262 } 263 264 List<Integer> list = new ArrayList<>(answer.length); 265 for (int i = 0; i < answer.length; i++) { 266 if (EncryptionKey.findKey(answer[i], keys) != null) { 267 list.add(answer[i]); 268 } 269 } 270 int len = list.size(); 271 if (len <= 0) { 272 StringBuffer keystr = new StringBuffer(); 273 for (int i = 0; i < keys.length; i++) { 274 keystr.append(toString(keys[i].getEType())); 275 keystr.append(" "); 276 } 277 throw new KrbException( 278 "Do not have keys of types listed in " + configName + 279 " available; only have keys of following type: " + 280 keystr.toString()); 281 } else { 282 answer = new int[len]; 283 for (int i = 0; i < len; i++) { 284 answer[i] = list.get(i); 285 } 286 return answer; 287 } 288 } 289 290 public static boolean isSupported(int eTypeConst, int[] config) { 291 for (int i = 0; i < config.length; i++) { 292 if (eTypeConst == config[i]) { 293 return true; 294 } 295 } 296 return false; 297 } 298 299 public static boolean isSupported(int eTypeConst) { 300 int[] enabledETypes = getBuiltInDefaults(); 301 return isSupported(eTypeConst, enabledETypes); 302 } 303 304 public static String toString(int type) { 305 switch (type) { 306 case 0: 307 return "NULL"; 308 case 1: 309 return "DES CBC mode with CRC-32"; 310 case 2: 311 return "DES CBC mode with MD4"; 312 case 3: 313 return "DES CBC mode with MD5"; 314 case 4: 315 return "reserved"; 316 case 5: 317 return "DES3 CBC mode with MD5"; 318 case 6: 319 return "reserved"; 320 case 7: 321 return "DES3 CBC mode with SHA1"; 322 case 9: 323 return "DSA with SHA1- Cms0ID"; 324 case 10: 325 return "MD5 with RSA encryption - Cms0ID"; 326 case 11: 327 return "SHA1 with RSA encryption - Cms0ID"; 328 case 12: 329 return "RC2 CBC mode with Env0ID"; 330 case 13: 331 return "RSA encryption with Env0ID"; 332 case 14: 333 return "RSAES-0AEP-ENV-0ID"; 334 case 15: 335 return "DES-EDE3-CBC-ENV-0ID"; 336 case 16: 337 return "DES3 CBC mode with SHA1-KD"; 338 case 17: 339 return "AES128 CTS mode with HMAC SHA1-96"; 340 case 18: 341 return "AES256 CTS mode with HMAC SHA1-96"; 342 case 23: 343 return "RC4 with HMAC"; 344 case 24: 345 return "RC4 with HMAC EXP"; 346 347 } 348 return "Unknown (" + type + ")"; 349 } 350 }