Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/krb5/Checksum.java
38830 views
1
/*
2
* Copyright (c) 2000, 2019, 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
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
28
* Copyright 1997 The Open Group Research Institute. All rights reserved.
29
*/
30
31
package sun.security.krb5;
32
33
import java.util.Arrays;
34
import sun.security.util.*;
35
import sun.security.krb5.internal.*;
36
import sun.security.krb5.internal.crypto.*;
37
import java.io.IOException;
38
import java.math.BigInteger;
39
40
/**
41
* This class encapsulates the concept of a Kerberos checksum.
42
*/
43
public class Checksum {
44
45
private int cksumType;
46
private byte[] checksum;
47
48
// ----------------------------------------------+-------------+-----------
49
// Checksum type |sumtype |checksum
50
// |value | size
51
// ----------------------------------------------+-------------+-----------
52
public static final int CKSUMTYPE_NULL = 0; // 0
53
public static final int CKSUMTYPE_CRC32 = 1; // 4
54
public static final int CKSUMTYPE_RSA_MD4 = 2; // 16
55
public static final int CKSUMTYPE_RSA_MD4_DES = 3; // 24
56
public static final int CKSUMTYPE_DES_MAC = 4; // 16
57
public static final int CKSUMTYPE_DES_MAC_K = 5; // 8
58
public static final int CKSUMTYPE_RSA_MD4_DES_K = 6; // 16
59
public static final int CKSUMTYPE_RSA_MD5 = 7; // 16
60
public static final int CKSUMTYPE_RSA_MD5_DES = 8; // 24
61
62
// draft-ietf-krb-wg-crypto-07.txt
63
public static final int CKSUMTYPE_HMAC_SHA1_DES3_KD = 12; // 20
64
65
// draft-raeburn-krb-rijndael-krb-07.txt
66
public static final int CKSUMTYPE_HMAC_SHA1_96_AES128 = 15; // 96
67
public static final int CKSUMTYPE_HMAC_SHA1_96_AES256 = 16; // 96
68
69
// draft-brezak-win2k-krb-rc4-hmac-04.txt
70
public static final int CKSUMTYPE_HMAC_MD5_ARCFOUR = -138;
71
72
// default checksum type, -1 if not set
73
static int CKSUMTYPE_DEFAULT;
74
static int SAFECKSUMTYPE_DEFAULT;
75
76
private static boolean DEBUG = Krb5.DEBUG;
77
static {
78
initStatic();
79
}
80
81
public static void initStatic() {
82
String temp = null;
83
Config cfg = null;
84
try {
85
cfg = Config.getInstance();
86
temp = cfg.get("libdefaults", "default_checksum");
87
if (temp != null) {
88
CKSUMTYPE_DEFAULT = Config.getType(temp);
89
} else {
90
CKSUMTYPE_DEFAULT = -1;
91
}
92
} catch (Exception exc) {
93
if (DEBUG) {
94
System.out.println("Exception in getting default checksum "+
95
"value from the configuration. " +
96
"No default checksum set.");
97
exc.printStackTrace();
98
}
99
CKSUMTYPE_DEFAULT = -1;
100
}
101
102
103
try {
104
temp = cfg.get("libdefaults", "safe_checksum_type");
105
if (temp != null)
106
{
107
SAFECKSUMTYPE_DEFAULT = Config.getType(temp);
108
} else {
109
SAFECKSUMTYPE_DEFAULT = -1;
110
}
111
} catch (Exception exc) {
112
if (DEBUG) {
113
System.out.println("Exception in getting safe default " +
114
"checksum value " +
115
"from the configuration Setting. " +
116
"No safe default checksum set.");
117
exc.printStackTrace();
118
}
119
SAFECKSUMTYPE_DEFAULT = -1;
120
}
121
}
122
123
/**
124
* Constructs a new Checksum using the raw data and type.
125
*
126
* This constructor is only used by Authenticator Checksum
127
* {@link sun.security.jgss.krb5.InitialToken.OverloadedChecksum}
128
* where the checksum type must be 0x8003
129
* (see https://tools.ietf.org/html/rfc4121#section-4.1.1)
130
* and checksum field/value is used to convey service flags,
131
* channel bindings, and optional delegation information.
132
* This special type does NOT have a {@link CksumType} and has its
133
* own calculating and verification rules. It does has the same
134
* ASN.1 encoding though.
135
*
136
* @param data the byte array of checksum.
137
* @param new_cksumType the type of checksum.
138
*/
139
public Checksum(byte[] data, int new_cksumType) {
140
cksumType = new_cksumType;
141
checksum = data;
142
}
143
144
/**
145
* Constructs a new Checksum by calculating over the data using
146
* the specified checksum type. If the checksum is unkeyed, key
147
* and usage are ignored.
148
*
149
* @param new_cksumType the type of checksum. If set to -1, the
150
* {@linkplain EType#checksumType() mandatory checksum type}
151
* for the encryption type of {@code key} will be used
152
* @param data the data that needs to be performed a checksum calculation on
153
* @param key the key used by a keyed checksum
154
* @param usage the usage used by a keyed checksum
155
*/
156
public Checksum(int new_cksumType, byte[] data,
157
EncryptionKey key, int usage)
158
throws KdcErrException, KrbApErrException, KrbCryptoException {
159
if (new_cksumType == -1) {
160
cksumType = EType.getInstance(key.getEType()).checksumType();
161
} else {
162
cksumType = new_cksumType;
163
}
164
checksum = CksumType.getInstance(cksumType).calculateChecksum(
165
data, data.length, key.getBytes(), usage);
166
}
167
168
/**
169
* Verifies the keyed checksum over the data passed in.
170
*/
171
public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key, int usage)
172
throws KdcErrException, KrbApErrException, KrbCryptoException {
173
CksumType cksumEngine = CksumType.getInstance(cksumType);
174
if (!cksumEngine.isKeyed()) {
175
throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
176
} else {
177
return cksumEngine.verifyChecksum(
178
data, data.length, key.getBytes(), checksum, usage);
179
}
180
}
181
182
183
/**
184
* Verifies the checksum over the data passed in. The checksum might
185
* be a keyed or not.
186
*
187
* =============== ATTENTION! Use with care ==================
188
* According to https://tools.ietf.org/html/rfc3961#section-6.1,
189
* An unkeyed checksum should only be used "in limited circumstances
190
* where the lack of a key does not provide a window for an attack,
191
* preferably as part of an encrypted message".
192
*/
193
public boolean verifyAnyChecksum(byte[] data, EncryptionKey key, int usage)
194
throws KdcErrException, KrbCryptoException {
195
return CksumType.getInstance(cksumType).verifyChecksum(
196
data, data.length, key.getBytes(), checksum, usage);
197
}
198
199
boolean isEqual(Checksum cksum) throws KdcErrException {
200
if (cksumType != cksum.cksumType) {
201
return false;
202
}
203
return CksumType.isChecksumEqual(checksum, cksum.checksum);
204
}
205
206
/**
207
* Constructs an instance of Checksum from an ASN.1 encoded representation.
208
* @param encoding a single DER-encoded value.
209
* @exception Asn1Exception if an error occurs while decoding an ASN1
210
* encoded data.
211
* @exception IOException if an I/O error occurs while reading encoded data.
212
*
213
*/
214
public Checksum(DerValue encoding) throws Asn1Exception, IOException {
215
DerValue der;
216
if (encoding.getTag() != DerValue.tag_Sequence) {
217
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
218
}
219
der = encoding.getData().getDerValue();
220
if ((der.getTag() & (byte)0x1F) == (byte)0x00) {
221
cksumType = der.getData().getBigInteger().intValue();
222
}
223
else
224
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
225
der = encoding.getData().getDerValue();
226
if ((der.getTag() & (byte)0x1F) == (byte)0x01) {
227
checksum = der.getData().getOctetString();
228
}
229
else
230
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
231
if (encoding.getData().available() > 0) {
232
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
233
}
234
}
235
236
/**
237
* Encodes a Checksum object.
238
* <pre>{@code
239
* Checksum ::= SEQUENCE {
240
* cksumtype [0] Int32,
241
* checksum [1] OCTET STRING
242
* }
243
* }</pre>
244
*
245
* <p>
246
* This definition reflects the Network Working Group RFC 4120
247
* specification available at
248
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
249
* http://www.ietf.org/rfc/rfc4120.txt</a>.
250
* @return byte array of enocded Checksum.
251
* @exception Asn1Exception if an error occurs while decoding an
252
* ASN1 encoded data.
253
* @exception IOException if an I/O error occurs while reading
254
* encoded data.
255
*
256
*/
257
public byte[] asn1Encode() throws Asn1Exception, IOException {
258
DerOutputStream bytes = new DerOutputStream();
259
DerOutputStream temp = new DerOutputStream();
260
temp.putInteger(BigInteger.valueOf(cksumType));
261
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
262
true, (byte)0x00), temp);
263
temp = new DerOutputStream();
264
temp.putOctetString(checksum);
265
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
266
true, (byte)0x01), temp);
267
temp = new DerOutputStream();
268
temp.write(DerValue.tag_Sequence, bytes);
269
return temp.toByteArray();
270
}
271
272
273
/**
274
* Parse (unmarshal) a checksum object from a DER input stream. This form
275
* parsing might be used when expanding a value which is part of
276
* a constructed sequence and uses explicitly tagged type.
277
*
278
* @exception Asn1Exception if an error occurs while decoding an
279
* ASN1 encoded data.
280
* @exception IOException if an I/O error occurs while reading
281
* encoded data.
282
* @param data the Der input stream value, which contains one or more
283
* marshaled value.
284
* @param explicitTag tag number.
285
* @param optional indicates if this data field is optional
286
* @return an instance of Checksum.
287
*
288
*/
289
public static Checksum parse(DerInputStream data,
290
byte explicitTag, boolean optional)
291
throws Asn1Exception, IOException {
292
293
if ((optional) &&
294
(((byte)data.peekByte() & (byte)0x1F) != explicitTag)) {
295
return null;
296
}
297
DerValue der = data.getDerValue();
298
if (explicitTag != (der.getTag() & (byte)0x1F)) {
299
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
300
} else {
301
DerValue subDer = der.getData().getDerValue();
302
return new Checksum(subDer);
303
}
304
}
305
306
/**
307
* Returns the raw bytes of the checksum, not in ASN.1 encoded form.
308
*/
309
public final byte[] getBytes() {
310
return checksum;
311
}
312
313
public final int getType() {
314
return cksumType;
315
}
316
317
@Override public boolean equals(Object obj) {
318
if (this == obj) {
319
return true;
320
}
321
if (!(obj instanceof Checksum)) {
322
return false;
323
}
324
325
try {
326
return isEqual((Checksum)obj);
327
} catch (KdcErrException kee) {
328
return false;
329
}
330
}
331
332
@Override public int hashCode() {
333
int result = 17;
334
result = 37 * result + cksumType;
335
if (checksum != null) {
336
result = 37 * result + Arrays.hashCode(checksum);
337
}
338
return result;
339
}
340
}
341
342