1 /* 2 * Copyright (c) 2000, 2010, 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 final boolean ALLOW_WEAK_CRYPTO; 52 53 static { 54 boolean allowed = true; 55 try { 56 Config cfg = Config.getInstance(); 57 String temp = cfg.getDefault("allow_weak_crypto", "libdefaults"); 58 if (temp != null && temp.equals("false")) allowed = false; 59 } catch (Exception exc) { 60 if (DEBUG) { 61 System.out.println ("Exception in getting allow_weak_crypto, " + 62 "using default value " + 63 exc.getMessage()); 64 } 65 } 66 ALLOW_WEAK_CRYPTO = allowed; 67 } 68 69 public static EType getInstance (int eTypeConst) 70 throws KdcErrException { 71 EType eType = null; 72 String eTypeName = null; 73 switch (eTypeConst) { 74 case EncryptedData.ETYPE_NULL: 75 eType = new NullEType(); 76 eTypeName = "sun.security.krb5.internal.crypto.NullEType"; 77 break; 78 case EncryptedData.ETYPE_DES_CBC_CRC: 79 eType = new DesCbcCrcEType(); 80 eTypeName = "sun.security.krb5.internal.crypto.DesCbcCrcEType"; 81 break; 82 case EncryptedData.ETYPE_DES_CBC_MD5: 83 eType = new DesCbcMd5EType(); 84 eTypeName = "sun.security.krb5.internal.crypto.DesCbcMd5EType"; 85 break; 86 87 case EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD: 88 eType = new Des3CbcHmacSha1KdEType(); 89 eTypeName = 90 "sun.security.krb5.internal.crypto.Des3CbcHmacSha1KdEType"; 91 break; 92 93 case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96: 94 eType = new Aes128CtsHmacSha1EType(); 95 eTypeName = 96 "sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType"; 97 break; 98 99 case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96: 100 eType = new Aes256CtsHmacSha1EType(); 101 eTypeName = 102 "sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType"; 103 break; 104 105 case EncryptedData.ETYPE_ARCFOUR_HMAC: 106 eType = new ArcFourHmacEType(); 107 eTypeName = "sun.security.krb5.internal.crypto.ArcFourHmacEType"; 108 break; 109 110 default: 111 String msg = "encryption type = " + toString(eTypeConst) 112 + " (" + eTypeConst + ")"; 113 throw new KdcErrException(Krb5.KDC_ERR_ETYPE_NOSUPP, msg); 114 } 115 if (DEBUG) { 116 System.out.println(">>> EType: " + eTypeName); 117 } 118 return eType; 119 } 120 121 public abstract int eType(); 122 123 public abstract int minimumPadSize(); 124 125 public abstract int confounderSize(); 126 127 public abstract int checksumType(); 128 129 public abstract int checksumSize(); 130 131 public abstract int blockSize(); 132 133 public abstract int keyType(); 134 135 public abstract int keySize(); 136 137 public abstract byte[] encrypt(byte[] data, byte[] key, int usage) 138 throws KrbCryptoException; 139 140 public abstract byte[] encrypt(byte[] data, byte[] key, byte[] ivec, 141 int usage) throws KrbCryptoException; 142 143 public abstract byte[] decrypt(byte[] cipher, byte[] key, int usage) 144 throws KrbApErrException, KrbCryptoException; 145 146 public abstract byte[] decrypt(byte[] cipher, byte[] key, byte[] ivec, 147 int usage) throws KrbApErrException, KrbCryptoException; 148 149 public int dataSize(byte[] data) 150 // throws Asn1Exception 151 { 152 // EncodeRef ref = new EncodeRef(data, startOfData()); 153 // return ref.end - startOfData(); 154 // should be the above according to spec, but in fact 155 // implementations include the pad bytes in the data size 156 return data.length - startOfData(); 157 } 158 159 public int padSize(byte[] data) { 160 return data.length - confounderSize() - checksumSize() - 161 dataSize(data); 162 } 163 164 public int startOfChecksum() { 165 return confounderSize(); 166 } 167 168 public int startOfData() { 169 return confounderSize() + checksumSize(); 170 } 171 172 public int startOfPad(byte[] data) { 173 return confounderSize() + checksumSize() + dataSize(data); 174 } 175 176 public byte[] decryptedData(byte[] data) { 177 int tempSize = dataSize(data); 178 byte[] result = new byte[tempSize]; 179 System.arraycopy(data, startOfData(), result, 0, tempSize); 180 return result; 181 } 182 183 // Note: the first 2 entries of BUILTIN_ETYPES and BUILTIN_ETYPES_NOAES256 184 // should be kept DES-related. They will be removed when allow_weak_crypto 185 // is set to false. 186 187 private static final int[] BUILTIN_ETYPES = new int[] { 188 EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96, 189 EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96, 190 EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD, 191 EncryptedData.ETYPE_ARCFOUR_HMAC, 192 EncryptedData.ETYPE_DES_CBC_CRC, 193 EncryptedData.ETYPE_DES_CBC_MD5, 194 }; 195 196 private static final int[] BUILTIN_ETYPES_NOAES256 = new int[] { 197 EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96, 198 EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD, 199 EncryptedData.ETYPE_ARCFOUR_HMAC, 200 EncryptedData.ETYPE_DES_CBC_CRC, 201 EncryptedData.ETYPE_DES_CBC_MD5, 202 }; 203 204 205 // used in Config 206 public static int[] getBuiltInDefaults() { 207 int allowed = 0; 208 try { 209 allowed = Cipher.getMaxAllowedKeyLength("AES"); 210 } catch (Exception e) { 211 // should not happen 212 } 213 int[] result; 214 if (allowed < 256) { 215 result = BUILTIN_ETYPES_NOAES256; 216 } else { 217 result = BUILTIN_ETYPES; 218 } 219 if (!ALLOW_WEAK_CRYPTO) { 220 // The last 2 etypes are now weak ones 221 return Arrays.copyOfRange(result, 0, result.length - 2); 222 } 223 return result; 224 } 225 226 /** 227 * Retrieves the default etypes from the configuration file, or 228 * if that's not available, return the built-in list of default etypes. 229 */ 230 // used in KrbAsReq, KeyTab 231 public static int[] getDefaults(String configName) { 232 try { 233 return Config.getInstance().defaultEtype(configName); 234 } catch (KrbException exc) { 235 if (DEBUG) { 236 System.out.println("Exception while getting " + 237 configName + exc.getMessage()); 238 System.out.println("Using default builtin etypes"); 239 } 240 return getBuiltInDefaults(); 241 } 242 } 243 244 /** 245 * Retrieve the default etypes from the configuration file for 246 * those etypes for which there are corresponding keys. 247 * Used in scenario we have some keys from a keytab with etypes 248 * different from those named in configName. Then, in order 249 * to decrypt an AS-REP, we should only ask for etypes for which 250 * we have keys. 251 */ 252 public static int[] getDefaults(String configName, EncryptionKey[] keys) 253 throws KrbException { 254 int[] answer = getDefaults(configName); 255 if (answer == null) { 256 throw new KrbException("No supported encryption types listed in " 257 + configName); 258 } 259 260 List<Integer> list = new ArrayList<>(answer.length); 261 for (int i = 0; i < answer.length; i++) { 262 if (EncryptionKey.findKey(answer[i], keys) != null) { 263 list.add(answer[i]); 264 } 265 } 266 int len = list.size(); 267 if (len <= 0) { 268 StringBuffer keystr = new StringBuffer(); 269 for (int i = 0; i < keys.length; i++) { 270 keystr.append(toString(keys[i].getEType())); 271 keystr.append(" "); 272 } 273 throw new KrbException( 274 "Do not have keys of types listed in " + configName + 275 " available; only have keys of following type: " + 276 keystr.toString()); 277 } else { 278 answer = new int[len]; 279 for (int i = 0; i < len; i++) { 280 answer[i] = list.get(i); 281 } 282 return answer; 283 } 284 } 285 286 public static boolean isSupported(int eTypeConst, int[] config) { 287 for (int i = 0; i < config.length; i++) { 288 if (eTypeConst == config[i]) { 289 return true; 290 } 291 } 292 return false; 293 } 294 295 public static boolean isSupported(int eTypeConst) { 296 int[] enabledETypes = getBuiltInDefaults(); 297 return isSupported(eTypeConst, enabledETypes); 298 } 299 300 public static String toString(int type) { 301 switch (type) { 302 case 0: 303 return "NULL"; 304 case 1: 305 return "DES CBC mode with CRC-32"; 306 case 2: 307 return "DES CBC mode with MD4"; 308 case 3: 309 return "DES CBC mode with MD5"; 310 case 4: 311 return "reserved"; 312 case 5: 313 return "DES3 CBC mode with MD5"; 314 case 6: 315 return "reserved"; 316 case 7: 317 return "DES3 CBC mode with SHA1"; 318 case 9: 319 return "DSA with SHA1- Cms0ID"; 320 case 10: 321 return "MD5 with RSA encryption - Cms0ID"; 322 case 11: 323 return "SHA1 with RSA encryption - Cms0ID"; 324 case 12: 325 return "RC2 CBC mode with Env0ID"; 326 case 13: 327 return "RSA encryption with Env0ID"; 328 case 14: 329 return "RSAES-0AEP-ENV-0ID"; 330 case 15: 331 return "DES-EDE3-CBC-ENV-0ID"; 332 case 16: 333 return "DES3 CBC mode with SHA1-KD"; 334 case 17: 335 return "AES128 CTS mode with HMAC SHA1-96"; 336 case 18: 337 return "AES256 CTS mode with HMAC SHA1-96"; 338 case 23: 339 return "RC4 with HMAC"; 340 case 24: 341 return "RC4 with HMAC EXP"; 342 343 } 344 return "Unknown (" + type + ")"; 345 } 346 }