History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/krb5/EncryptedData.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/krb5/EncryptedData.java+380−0
@@ -0,0 +1,380 @@
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;
33+
34+import sun.security.util.*;
35+import sun.security.krb5.internal.crypto.*;
36+import sun.security.krb5.internal.*;
37+import java.io.IOException;
38+import java.math.BigInteger;
39+
40+/**
41+ * This class encapsulates Kerberos encrypted data. It allows
42+ * callers access to both the ASN.1 encoded form of the EncryptedData
43+ * type as well as the raw cipher text.
44+ */
45+
46+public class EncryptedData implements Cloneable {
47+ int eType;
48+ Integer kvno; // optional
49+ byte[] cipher;
50+ byte[] plain; // not part of ASN.1 encoding
51+
52+ // ----------------+-----------+----------+----------------+---------------
53+ // Encryption type |etype value|block size|minimum pad size|confounder size
54+ // ----------------+-----------+----------+----------------+---------------
55+ public static final int
56+ ETYPE_NULL = 0; // 1 0 0
57+ public static final int
58+ ETYPE_DES_CBC_CRC = 1; // 8 4 8
59+ public static final int
60+ ETYPE_DES_CBC_MD4 = 2; // 8 0 8
61+ public static final int
62+ ETYPE_DES_CBC_MD5 = 3; // 8 0 8
63+
64+ // draft-brezak-win2k-krb-rc4-hmac-04.txt
65+ public static final int
66+ ETYPE_ARCFOUR_HMAC = 23; // 1
67+ // NOTE: the exportable RC4-HMAC is not supported;
68+ // it is no longer a usable encryption type
69+ public static final int
70+ ETYPE_ARCFOUR_HMAC_EXP = 24; // 1
71+
72+ // draft-ietf-krb-wg-crypto-07.txt
73+ public static final int
74+ ETYPE_DES3_CBC_HMAC_SHA1_KD = 16; // 8 0 8
75+
76+ // draft-raeburn-krb-rijndael-krb-07.txt
77+ public static final int
78+ ETYPE_AES128_CTS_HMAC_SHA1_96 = 17; // 16 0 16
79+ public static final int
80+ ETYPE_AES256_CTS_HMAC_SHA1_96 = 18; // 16 0 16
81+
82+ /* used by self */
83+ private EncryptedData() {
84+ }
85+
86+ public Object clone() {
87+ EncryptedData new_encryptedData = new EncryptedData();
88+ new_encryptedData.eType = eType;
89+ if (kvno != null) {
90+ new_encryptedData.kvno = new Integer(kvno.intValue());
91+ }
92+ if (cipher != null) {
93+ new_encryptedData.cipher = new byte[cipher.length];
94+ System.arraycopy(cipher, 0, new_encryptedData.cipher,
95+ 0, cipher.length);
96+ }
97+ return new_encryptedData;
98+ }
99+
100+ // Used in JSSE (com.sun.net.ssl.internal.KerberosPreMasterSecret)
101+ public EncryptedData(
102+ int new_eType,
103+ Integer new_kvno,
104+ byte[] new_cipher) {
105+ eType = new_eType;
106+ kvno = new_kvno;
107+ cipher = new_cipher;
108+ }
109+
110+ /*
111+ // Not used.
112+ public EncryptedData(
113+ EncryptionKey key,
114+ byte[] plaintext)
115+ throws KdcErrException, KrbCryptoException {
116+ EType etypeEngine = EType.getInstance(key.getEType());
117+ cipher = etypeEngine.encrypt(plaintext, key.getBytes());
118+ eType = key.getEType();
119+ kvno = key.getKeyVersionNumber();
120+ }
121+ */
122+
123+ // used in KrbApRep, KrbApReq, KrbAsReq, KrbCred, KrbPriv
124+ // Used in JSSE (com.sun.net.ssl.internal.KerberosPreMasterSecret)
125+ public EncryptedData(
126+ EncryptionKey key,
127+ byte[] plaintext,
128+ int usage)
129+ throws KdcErrException, KrbCryptoException {
130+ EType etypeEngine = EType.getInstance(key.getEType());
131+ cipher = etypeEngine.encrypt(plaintext, key.getBytes(), usage);
132+ eType = key.getEType();
133+ kvno = key.getKeyVersionNumber();
134+ }
135+
136+ /*
137+ // Not used.
138+ public EncryptedData(
139+ EncryptionKey key,
140+ byte[] ivec,
141+ byte[] plaintext)
142+ throws KdcErrException, KrbCryptoException {
143+ EType etypeEngine = EType.getInstance(key.getEType());
144+ cipher = etypeEngine.encrypt(plaintext, key.getBytes(), ivec);
145+ eType = key.getEType();
146+ kvno = key.getKeyVersionNumber();
147+ }
148+ */
149+
150+ /*
151+ // Not used.
152+ EncryptedData(
153+ StringBuffer password,
154+ byte[] plaintext)
155+ throws KdcErrException, KrbCryptoException {
156+ EncryptionKey key = new EncryptionKey(password);
157+ EType etypeEngine = EType.getInstance(key.getEType());
158+ cipher = etypeEngine.encrypt(plaintext, key.getBytes());
159+ eType = key.getEType();
160+ kvno = key.getKeyVersionNumber();
161+ }
162+ */
163+
164+ // currently destructive on cipher
165+ public byte[] decrypt(
166+ EncryptionKey key, int usage)
167+ throws KdcErrException, KrbApErrException, KrbCryptoException {
168+ if (eType != key.getEType()) {
169+ throw new KrbCryptoException(
170+ "EncryptedData is encrypted using keytype " +
171+ EType.toString(eType) +
172+ " but decryption key is of type " +
173+ EType.toString(key.getEType()));
174+ }
175+
176+ EType etypeEngine = EType.getInstance(eType);
177+ plain = etypeEngine.decrypt(cipher, key.getBytes(), usage);
178+ cipher = null;
179+ return etypeEngine.decryptedData(plain);
180+ }
181+
182+ /*
183+ // currently destructive on cipher
184+ // Not used.
185+ public byte[] decrypt(
186+ EncryptionKey key,
187+ byte[] ivec, int usage)
188+ throws KdcErrException, KrbApErrException, KrbCryptoException {
189+ // XXX check for matching eType and kvno here
190+ EType etypeEngine = EType.getInstance(eType);
191+ plain = etypeEngine.decrypt(cipher, key.getBytes(), ivec, usage);
192+ cipher = null;
193+ return etypeEngine.decryptedData(plain);
194+ }
195+
196+ // currently destructive on cipher
197+ // Not used.
198+ byte[] decrypt(StringBuffer password)
199+ throws KdcErrException, KrbApErrException, KrbCryptoException {
200+ EncryptionKey key = new EncryptionKey(password);
201+ // XXX check for matching eType here
202+ EType etypeEngine = EType.getInstance(eType);
203+ plain = etypeEngine.decrypt(cipher, key.getBytes());
204+ cipher = null;
205+ return etypeEngine.decryptedData(plain);
206+ }
207+ */
208+
209+ private byte[] decryptedData() throws KdcErrException {
210+ if (plain != null) {
211+ EType etypeEngine = EType.getInstance(eType);
212+ return etypeEngine.decryptedData(plain);
213+ }
214+ return null;
215+ }
216+
217+ /**
218+ * Constructs an instance of EncryptedData type.
219+ * @param encoding a single DER-encoded value.
220+ * @exception Asn1Exception if an error occurs while decoding an
221+ * ASN1 encoded data.
222+ * @exception IOException if an I/O error occurs while reading encoded
223+ * data.
224+ *
225+ */
226+ /* Used by self */
227+ private EncryptedData(DerValue encoding)
228+ throws Asn1Exception, IOException {
229+
230+ DerValue der = null;
231+ if (encoding.getTag() != DerValue.tag_Sequence) {
232+ throw new Asn1Exception(Krb5.ASN1_BAD_ID);
233+ }
234+ der = encoding.getData().getDerValue();
235+ if ((der.getTag() & (byte)0x1F) == (byte)0x00) {
236+ eType = (der.getData().getBigInteger()).intValue();
237+ } else {
238+ throw new Asn1Exception(Krb5.ASN1_BAD_ID);
239+ }
240+
241+ if ((encoding.getData().peekByte() & 0x1F) == 1) {
242+ der = encoding.getData().getDerValue();
243+ int i = (der.getData().getBigInteger()).intValue();
244+ kvno = new Integer(i);
245+ } else {
246+ kvno = null;
247+ }
248+ der = encoding.getData().getDerValue();
249+ if ((der.getTag() & (byte)0x1F) == (byte)0x02) {
250+ cipher = der.getData().getOctetString();
251+ } else {
252+ throw new Asn1Exception(Krb5.ASN1_BAD_ID);
253+ }
254+ if (encoding.getData().available() > 0) {
255+ throw new Asn1Exception(Krb5.ASN1_BAD_ID);
256+ }
257+ }
258+
259+ /**
260+ * Returns an ASN.1 encoded EncryptedData type.
261+ *
262+ * <xmp>
263+ * EncryptedData ::= SEQUENCE {
264+ * etype [0] Int32 -- EncryptionType --,
265+ * kvno [1] UInt32 OPTIONAL,
266+ * cipher [2] OCTET STRING -- ciphertext
267+ * }
268+ * </xmp>
269+ *
270+ * <p>
271+ * This definition reflects the Network Working Group RFC 4120
272+ * specification available at
273+ * <a href="http://www.ietf.org/rfc/rfc4120.txt">
274+ * http://www.ietf.org/rfc/rfc4120.txt</a>.
275+ * <p>
276+ * @return byte array of encoded EncryptedData object.
277+ * @exception Asn1Exception if an error occurs while decoding an
278+ * ASN1 encoded data.
279+ * @exception IOException if an I/O error occurs while reading
280+ * encoded data.
281+ *
282+ */
283+ public byte[] asn1Encode() throws Asn1Exception, IOException {
284+ DerOutputStream bytes = new DerOutputStream();
285+ DerOutputStream temp = new DerOutputStream();
286+ temp.putInteger(BigInteger.valueOf(this.eType));
287+ bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
288+ true, (byte)0x00), temp);
289+ temp = new DerOutputStream();
290+ if (kvno != null) {
291+ // encode as an unsigned integer (UInt32)
292+ temp.putInteger(BigInteger.valueOf(this.kvno.longValue()));
293+ bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
294+ true, (byte)0x01), temp);
295+ temp = new DerOutputStream();
296+ }
297+ temp.putOctetString(this.cipher);
298+ bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
299+ (byte)0x02), temp);
300+ temp = new DerOutputStream();
301+ temp.write(DerValue.tag_Sequence, bytes);
302+ return temp.toByteArray();
303+ }
304+
305+
306+ /**
307+ * Parse (unmarshal) an EncryptedData from a DER input stream. This form
308+ * parsing might be used when expanding a value which is part of
309+ * a constructed sequence and uses explicitly tagged type.
310+ *
311+ * @param data the Der input stream value, which contains one or more
312+ * marshaled value.
313+ * @param explicitTag tag number.
314+ * @param optional indicate if this data field is optional
315+ * @exception Asn1Exception if an error occurs while decoding an
316+ * ASN1 encoded data.
317+ * @exception IOException if an I/O error occurs while reading
318+ * encoded data.
319+ * @return an instance of EncryptedData.
320+ *
321+ */
322+ public static EncryptedData parse(DerInputStream data,
323+ byte explicitTag,
324+ boolean optional)
325+ throws Asn1Exception, IOException {
326+ if ((optional) &&
327+ (((byte)data.peekByte() & (byte)0x1F) != explicitTag))
328+ return null;
329+ DerValue der = data.getDerValue();
330+ if (explicitTag != (der.getTag() & (byte)0x1F)) {
331+ throw new Asn1Exception(Krb5.ASN1_BAD_ID);
332+ } else {
333+ DerValue subDer = der.getData().getDerValue();
334+ return new EncryptedData(subDer);
335+ }
336+ }
337+
338+ /**
339+ * Reset asn.1 data stream after decryption, remove redundant bytes.
340+ * @param data the decrypted data from decrypt().
341+ * @return the reset byte array which holds exactly one asn1 datum
342+ * including its tag and length.
343+ *
344+ */
345+ public byte[] reset(byte[] data) {
346+ byte[] bytes = null;
347+ // for asn.1 encoded data, we use length field to
348+ // determine the data length and remove redundant paddings.
349+ if ((data[1] & 0xFF) < 128) {
350+ bytes = new byte[data[1] + 2];
351+ System.arraycopy(data, 0, bytes, 0, data[1] + 2);
352+ } else {
353+ if ((data[1] & 0xFF) > 128) {
354+ int len = data[1] & (byte)0x7F;
355+ int result = 0;
356+ for (int i = 0; i < len; i++) {
357+ result |= (data[i + 2] & 0xFF) << (8 * (len - i - 1));
358+ }
359+ bytes = new byte[result + len + 2];
360+ System.arraycopy(data, 0, bytes, 0, result + len + 2);
361+ }
362+ }
363+ return bytes;
364+ }
365+
366+ public int getEType() {
367+ return eType;
368+ }
369+
370+ public Integer getKeyVersionNumber() {
371+ return kvno;
372+ }
373+
374+ /**
375+ * Returns the raw cipher text bytes, not in ASN.1 encoding.
376+ */
377+ public byte[] getBytes() {
378+ return cipher;
379+ }
380+}