blob: b7da802af13ca828079cb471eb04dc8f15fe618f [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Portions Copyright 2000-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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
32package sun.security.krb5.internal.crypto;
33
34import sun.security.krb5.internal.*;
35import sun.security.krb5.Config;
36import sun.security.krb5.EncryptedData;
37import sun.security.krb5.EncryptionKey;
38import sun.security.krb5.KrbException;
39import sun.security.krb5.Asn1Exception;
40import sun.security.krb5.KrbCryptoException;
41import javax.crypto.*;
42import java.util.List;
43import java.util.ArrayList;
44
45//only needed if dataSize() implementation changes back to spec;
46//see dataSize() below
47
48public abstract class EType {
49
50 private static final boolean DEBUG = Krb5.DEBUG;
51
52 public static EType getInstance (int eTypeConst)
53 throws KdcErrException {
54 EType eType = null;
55 String eTypeName = null;
56 switch (eTypeConst) {
57 case EncryptedData.ETYPE_NULL:
58 eType = new NullEType();
59 eTypeName = "sun.security.krb5.internal.crypto.NullEType";
60 break;
61 case EncryptedData.ETYPE_DES_CBC_CRC:
62 eType = new DesCbcCrcEType();
63 eTypeName = "sun.security.krb5.internal.crypto.DesCbcCrcEType";
64 break;
65 case EncryptedData.ETYPE_DES_CBC_MD5:
66 eType = new DesCbcMd5EType();
67 eTypeName = "sun.security.krb5.internal.crypto.DesCbcMd5EType";
68 break;
69
70 case EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD:
71 eType = new Des3CbcHmacSha1KdEType();
72 eTypeName =
73 "sun.security.krb5.internal.crypto.Des3CbcHmacSha1KdEType";
74 break;
75
76 case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96:
77 eType = new Aes128CtsHmacSha1EType();
78 eTypeName =
79 "sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType";
80 break;
81
82 case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
83 eType = new Aes256CtsHmacSha1EType();
84 eTypeName =
85 "sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType";
86 break;
87
88 case EncryptedData.ETYPE_ARCFOUR_HMAC:
89 eType = new ArcFourHmacEType();
90 eTypeName = "sun.security.krb5.internal.crypto.ArcFourHmacEType";
91 break;
92
93 default:
94 String msg = "encryption type = " + toString(eTypeConst)
95 + " (" + eTypeConst + ")";
96 throw new KdcErrException(Krb5.KDC_ERR_ETYPE_NOSUPP, msg);
97 }
98 if (DEBUG) {
99 System.out.println(">>> EType: " + eTypeName);
100 }
101 return eType;
102 }
103
104 public abstract int eType();
105
106 public abstract int minimumPadSize();
107
108 public abstract int confounderSize();
109
110 public abstract int checksumType();
111
112 public abstract int checksumSize();
113
114 public abstract int blockSize();
115
116 public abstract int keyType();
117
118 public abstract int keySize();
119
120 public abstract byte[] encrypt(byte[] data, byte[] key, int usage)
121 throws KrbCryptoException;
122
123 public abstract byte[] encrypt(byte[] data, byte[] key, byte[] ivec,
124 int usage) throws KrbCryptoException;
125
126 public abstract byte[] decrypt(byte[] cipher, byte[] key, int usage)
127 throws KrbApErrException, KrbCryptoException;
128
129 public abstract byte[] decrypt(byte[] cipher, byte[] key, byte[] ivec,
130 int usage) throws KrbApErrException, KrbCryptoException;
131
132 public int dataSize(byte[] data)
133 // throws Asn1Exception
134 {
135 // EncodeRef ref = new EncodeRef(data, startOfData());
136 // return ref.end - startOfData();
137 // should be the above according to spec, but in fact
138 // implementations include the pad bytes in the data size
139 return data.length - startOfData();
140 }
141
142 public int padSize(byte[] data) {
143 return data.length - confounderSize() - checksumSize() -
144 dataSize(data);
145 }
146
147 public int startOfChecksum() {
148 return confounderSize();
149 }
150
151 public int startOfData() {
152 return confounderSize() + checksumSize();
153 }
154
155 public int startOfPad(byte[] data) {
156 return confounderSize() + checksumSize() + dataSize(data);
157 }
158
159 public byte[] decryptedData(byte[] data) {
160 int tempSize = dataSize(data);
161 byte[] result = new byte[tempSize];
162 System.arraycopy(data, startOfData(), result, 0, tempSize);
163 return result;
164 }
165
166 private static final int[] BUILTIN_ETYPES = new int[] {
167 EncryptedData.ETYPE_DES_CBC_MD5,
168 EncryptedData.ETYPE_DES_CBC_CRC,
169 EncryptedData.ETYPE_ARCFOUR_HMAC,
170 EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD,
171 EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96,
172 EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96,
173 };
174
175 private static final int[] BUILTIN_ETYPES_NOAES256 = new int[] {
176 EncryptedData.ETYPE_DES_CBC_MD5,
177 EncryptedData.ETYPE_DES_CBC_CRC,
178 EncryptedData.ETYPE_ARCFOUR_HMAC,
179 EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD,
180 EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96,
181 };
182
183
184 // used in Config
185 public static int[] getBuiltInDefaults() {
186 int allowed = 0;
187 try {
188 allowed = Cipher.getMaxAllowedKeyLength("AES");
189 } catch (Exception e) {
190 // should not happen
191 }
192 if (allowed < 256) {
193 return BUILTIN_ETYPES_NOAES256;
194 }
195 return BUILTIN_ETYPES;
196 }
197
198 /**
199 * Retrieves the default etypes from the configuration file, or
200 * if that's not available, return the built-in list of default etypes.
201 */
202 // used in KrbAsReq, KeyTab
203 public static int[] getDefaults(String configName) {
204 try {
205 return Config.getInstance().defaultEtype(configName);
206 } catch (KrbException exc) {
207 if (DEBUG) {
208 System.out.println("Exception while getting " +
209 configName + exc.getMessage());
210 System.out.println("Using defaults " +
211 "des-cbc-md5, des-cbc-crc, des3-cbc-sha1," +
212 " aes128cts, aes256cts, rc4-hmac");
213 }
214 return getBuiltInDefaults();
215 }
216 }
217
218 /**
219 * Retrieve the default etypes from the configuration file for
220 * those etypes for which there are corresponding keys.
221 * Used in scenario we have some keys from a keytab with etypes
222 * different from those named in configName. Then, in order
223 * to decrypt an AS-REP, we should only ask for etypes for which
224 * we have keys.
225 */
226 public static int[] getDefaults(String configName, EncryptionKey[] keys)
227 throws KrbException {
228 int[] answer = getDefaults(configName);
229 if (answer == null) {
230 throw new KrbException("No supported encryption types listed in "
231 + configName);
232 }
233
234 List<Integer> list = new ArrayList<Integer> (answer.length);
235 for (int i = 0; i < answer.length; i++) {
236 if (EncryptionKey.findKey(answer[i], keys) != null) {
237 list.add(answer[i]);
238 }
239 }
240 int len = list.size();
241 if (len <= 0) {
242 StringBuffer keystr = new StringBuffer();
243 for (int i = 0; i < keys.length; i++) {
244 keystr.append(toString(keys[i].getEType()));
245 keystr.append(" ");
246 }
247 throw new KrbException(
248 "Do not have keys of types listed in " + configName +
249 " available; only have keys of following type: " +
250 keystr.toString());
251 } else {
252 answer = new int[len];
253 for (int i = 0; i < len; i++) {
254 answer[i] = list.get(i);
255 }
256 return answer;
257 }
258 }
259
260 public static boolean isSupported(int eTypeConst, int[] config) {
261 for (int i = 0; i < config.length; i++) {
262 if (eTypeConst == config[i]) {
263 return true;
264 }
265 }
266 return false;
267 }
268
269 public static boolean isSupported(int eTypeConst) {
270 int[] enabledETypes = getBuiltInDefaults();
271 return isSupported(eTypeConst, enabledETypes);
272 }
273
274 public static String toString(int type) {
275 switch (type) {
276 case 0:
277 return "NULL";
278 case 1:
279 return "DES CBC mode with CRC-32";
280 case 2:
281 return "DES CBC mode with MD4";
282 case 3:
283 return "DES CBC mode with MD5";
284 case 4:
285 return "reserved";
286 case 5:
287 return "DES3 CBC mode with MD5";
288 case 6:
289 return "reserved";
290 case 7:
291 return "DES3 CBC mode with SHA1";
292 case 9:
293 return "DSA with SHA1- Cms0ID";
294 case 10:
295 return "MD5 with RSA encryption - Cms0ID";
296 case 11:
297 return "SHA1 with RSA encryption - Cms0ID";
298 case 12:
299 return "RC2 CBC mode with Env0ID";
300 case 13:
301 return "RSA encryption with Env0ID";
302 case 14:
303 return "RSAES-0AEP-ENV-0ID";
304 case 15:
305 return "DES-EDE3-CBC-ENV-0ID";
306 case 16:
307 return "DES3 CBC mode with SHA1-KD";
308 case 17:
309 return "AES128 CTS mode with HMAC SHA1-96";
310 case 18:
311 return "AES256 CTS mode with HMAC SHA1-96";
312 case 23:
313 return "RC4 with HMAC";
314 case 24:
315 return "RC4 with HMAC EXP";
316
317 }
318 return "Unknown (" + type + ")";
319 }
320}