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/internal/PAData.java
38923 views
1
/*
2
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation. Oracle designates this
9
* particular file as subject to the "Classpath" exception as provided
10
* by Oracle in the LICENSE file that accompanied this code.
11
*
12
* This code is distributed in the hope that it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15
* version 2 for more details (a copy is included in the LICENSE file that
16
* accompanied this code).
17
*
18
* You should have received a copy of the GNU General Public License version
19
* 2 along with this work; if not, write to the Free Software Foundation,
20
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21
*
22
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23
* or visit www.oracle.com if you need additional information or have any
24
* questions.
25
*/
26
27
/*
28
*
29
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
30
* Copyright 1997 The Open Group Research Institute. All rights reserved.
31
*/
32
33
package sun.security.krb5.internal;
34
35
import sun.security.krb5.internal.crypto.EType;
36
import sun.security.util.*;
37
import sun.security.krb5.Asn1Exception;
38
import java.io.IOException;
39
import java.util.Vector;
40
41
import sun.security.krb5.internal.util.KerberosString;
42
43
/**
44
* Implements the ASN.1 PA-DATA type.
45
*
46
* <pre>{@code
47
* PA-DATA ::= SEQUENCE {
48
* -- NOTE: first tag is [1], not [0]
49
* padata-type [1] Int32,
50
* padata-value [2] OCTET STRING -- might be encoded AP-REQ
51
* }
52
* }</pre>
53
*
54
* <p>
55
* This definition reflects the Network Working Group RFC 4120
56
* specification available at
57
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
58
* http://www.ietf.org/rfc/rfc4120.txt</a>.
59
*/
60
61
public class PAData {
62
private int pADataType;
63
private byte[] pADataValue = null;
64
private static final byte TAG_PATYPE = 1;
65
private static final byte TAG_PAVALUE = 2;
66
67
private PAData() {
68
}
69
70
public PAData(int new_pADataType, byte[] new_pADataValue) {
71
pADataType = new_pADataType;
72
if (new_pADataValue != null) {
73
pADataValue = new_pADataValue.clone();
74
}
75
}
76
77
public Object clone() {
78
PAData new_pAData = new PAData();
79
new_pAData.pADataType = pADataType;
80
if (pADataValue != null) {
81
new_pAData.pADataValue = new byte[pADataValue.length];
82
System.arraycopy(pADataValue, 0, new_pAData.pADataValue,
83
0, pADataValue.length);
84
}
85
return new_pAData;
86
}
87
88
/**
89
* Constructs a PAData object.
90
* @param encoding a Der-encoded data.
91
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
92
* @exception IOException if an I/O error occurs while reading encoded data.
93
*/
94
public PAData(DerValue encoding) throws Asn1Exception, IOException {
95
DerValue der = null;
96
if (encoding.getTag() != DerValue.tag_Sequence) {
97
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
98
}
99
der = encoding.getData().getDerValue();
100
if ((der.getTag() & 0x1F) == 0x01) {
101
this.pADataType = der.getData().getBigInteger().intValue();
102
}
103
else
104
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
105
der = encoding.getData().getDerValue();
106
if ((der.getTag() & 0x1F) == 0x02) {
107
this.pADataValue = der.getData().getOctetString();
108
}
109
if (encoding.getData().available() > 0)
110
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
111
}
112
113
/**
114
* Encodes this object to an OutputStream.
115
*
116
* @return byte array of the encoded data.
117
* @exception IOException if an I/O error occurs while reading encoded data.
118
* @exception Asn1Exception on encoding errors.
119
*/
120
public byte[] asn1Encode() throws Asn1Exception, IOException {
121
122
DerOutputStream bytes = new DerOutputStream();
123
DerOutputStream temp = new DerOutputStream();
124
125
temp.putInteger(pADataType);
126
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_PATYPE), temp);
127
temp = new DerOutputStream();
128
temp.putOctetString(pADataValue);
129
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_PAVALUE), temp);
130
131
temp = new DerOutputStream();
132
temp.write(DerValue.tag_Sequence, bytes);
133
return temp.toByteArray();
134
}
135
136
// accessor methods
137
public int getType() {
138
return pADataType;
139
}
140
141
public byte[] getValue() {
142
return ((pADataValue == null) ? null : pADataValue.clone());
143
}
144
145
/**
146
* Parse (unmarshal) a PAData from a DER input stream. This form
147
* parsing might be used when expanding a value which is part of
148
* a constructed sequence and uses explicitly tagged type.
149
*
150
* @exception Asn1Exception if an Asn1Exception occurs.
151
* @param data the Der input stream value, which contains one or more
152
* marshaled values.
153
* @param explicitTag tag number.
154
* @param optional indicates if this data field is optional.
155
* @return an array of PAData.
156
*/
157
public static PAData[] parseSequence(DerInputStream data,
158
byte explicitTag, boolean optional)
159
throws Asn1Exception, IOException {
160
if ((optional) &&
161
(((byte)data.peekByte() & (byte)0x1F) != explicitTag))
162
return null;
163
DerValue subDer = data.getDerValue();
164
DerValue subsubDer = subDer.getData().getDerValue();
165
if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
166
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
167
}
168
Vector<PAData> v = new Vector<>();
169
while (subsubDer.getData().available() > 0) {
170
v.addElement(new PAData(subsubDer.getData().getDerValue()));
171
}
172
if (v.size() > 0) {
173
PAData[] pas = new PAData[v.size()];
174
v.copyInto(pas);
175
return pas;
176
}
177
return null;
178
}
179
180
/**
181
* Gets the preferred etype from the PAData array.
182
* <ol>
183
* <li>ETYPE-INFO2-ENTRY with unknown s2kparams ignored</li>
184
* <li>ETYPE-INFO2 preferred to ETYPE-INFO</li>
185
* <li>Multiple entries for same etype in one PA-DATA, use the first one.</li>
186
* <li>Multiple PA-DATA with same type, choose the last one.</li>
187
* </ol>
188
* (This is useful when PA-DATAs from KRB-ERROR and AS-REP are combined).
189
*
190
* @return the etype, or defaultEType if not enough info
191
* @throws Asn1Exception|IOException if there is an encoding error
192
*/
193
public static int getPreferredEType(PAData[] pas, int defaultEType)
194
throws IOException, Asn1Exception {
195
196
if (pas == null) return defaultEType;
197
198
DerValue d = null, d2 = null;
199
for (PAData p: pas) {
200
if (p.getValue() == null) continue;
201
switch (p.getType()) {
202
case Krb5.PA_ETYPE_INFO:
203
d = new DerValue(p.getValue());
204
break;
205
case Krb5.PA_ETYPE_INFO2:
206
d2 = new DerValue(p.getValue());
207
break;
208
}
209
}
210
if (d2 != null) {
211
while (d2.data.available() > 0) {
212
DerValue value = d2.data.getDerValue();
213
ETypeInfo2 tmp = new ETypeInfo2(value);
214
if (EType.isNewer(tmp.getEType()) || tmp.getParams() == null) {
215
// we don't support non-null s2kparams for old etypes
216
return tmp.getEType();
217
}
218
}
219
}
220
if (d != null) {
221
while (d.data.available() > 0) {
222
DerValue value = d.data.getDerValue();
223
ETypeInfo tmp = new ETypeInfo(value);
224
return tmp.getEType();
225
}
226
}
227
return defaultEType;
228
}
229
230
/**
231
* A place to store a pair of salt and s2kparams.
232
* An empty salt is changed to null, to be interoperable
233
* with Windows 2000 server. This is in fact not correct.
234
*/
235
public static class SaltAndParams {
236
public final String salt;
237
public final byte[] params;
238
public SaltAndParams(String s, byte[] p) {
239
if (s != null && s.isEmpty()) s = null;
240
this.salt = s;
241
this.params = p;
242
}
243
}
244
245
/**
246
* Fetches salt and s2kparams value for eType in a series of PA-DATAs.
247
* 1. ETYPE-INFO2-ENTRY with unknown s2kparams ignored
248
* 2. PA-ETYPE-INFO2 preferred to PA-ETYPE-INFO preferred to PA-PW-SALT.
249
* 3. multiple entries for same etype in one PA-DATA, use the first one.
250
* 4. Multiple PA-DATA with same type, choose the last one
251
* (This is useful when PA-DATAs from KRB-ERROR and AS-REP are combined).
252
* @return salt and s2kparams. can be null if not found
253
*/
254
public static SaltAndParams getSaltAndParams(int eType, PAData[] pas)
255
throws Asn1Exception, IOException {
256
257
if (pas == null) return null;
258
259
DerValue d = null, d2 = null;
260
String paPwSalt = null;
261
262
for (PAData p: pas) {
263
if (p.getValue() == null) continue;
264
switch (p.getType()) {
265
case Krb5.PA_PW_SALT:
266
paPwSalt = new String(p.getValue(),
267
KerberosString.MSNAME?"UTF8":"8859_1");
268
break;
269
case Krb5.PA_ETYPE_INFO:
270
d = new DerValue(p.getValue());
271
break;
272
case Krb5.PA_ETYPE_INFO2:
273
d2 = new DerValue(p.getValue());
274
break;
275
}
276
}
277
if (d2 != null) {
278
while (d2.data.available() > 0) {
279
DerValue value = d2.data.getDerValue();
280
ETypeInfo2 tmp = new ETypeInfo2(value);
281
if (tmp.getEType() == eType &&
282
(EType.isNewer(eType) || tmp.getParams() == null)) {
283
// we don't support non-null s2kparams for old etypes
284
return new SaltAndParams(tmp.getSalt(), tmp.getParams());
285
}
286
}
287
}
288
if (d != null) {
289
while (d.data.available() > 0) {
290
DerValue value = d.data.getDerValue();
291
ETypeInfo tmp = new ETypeInfo(value);
292
if (tmp.getEType() == eType) {
293
return new SaltAndParams(tmp.getSalt(), null);
294
}
295
}
296
}
297
if (paPwSalt != null) {
298
return new SaltAndParams(paPwSalt, null);
299
}
300
return null;
301
}
302
303
@Override
304
public String toString(){
305
StringBuilder sb = new StringBuilder();
306
sb.append(">>>Pre-Authentication Data:\n\t PA-DATA type = ")
307
.append(pADataType).append('\n');
308
309
switch(pADataType) {
310
case Krb5.PA_ENC_TIMESTAMP:
311
sb.append("\t PA-ENC-TIMESTAMP");
312
break;
313
case Krb5.PA_ETYPE_INFO:
314
if (pADataValue != null) {
315
try {
316
DerValue der = new DerValue(pADataValue);
317
while (der.data.available() > 0) {
318
DerValue value = der.data.getDerValue();
319
ETypeInfo info = new ETypeInfo(value);
320
sb.append("\t PA-ETYPE-INFO etype = ")
321
.append(info.getEType())
322
.append(", salt = ")
323
.append(info.getSalt())
324
.append('\n');
325
}
326
} catch (IOException|Asn1Exception e) {
327
sb.append("\t <Unparseable PA-ETYPE-INFO>\n");
328
}
329
}
330
break;
331
case Krb5.PA_ETYPE_INFO2:
332
if (pADataValue != null) {
333
try {
334
DerValue der = new DerValue(pADataValue);
335
while (der.data.available() > 0) {
336
DerValue value = der.data.getDerValue();
337
ETypeInfo2 info2 = new ETypeInfo2(value);
338
sb.append("\t PA-ETYPE-INFO2 etype = ")
339
.append(info2.getEType())
340
.append(", salt = ")
341
.append(info2.getSalt())
342
.append(", s2kparams = ");
343
byte[] s2kparams = info2.getParams();
344
if (s2kparams == null) {
345
sb.append("null\n");
346
} else if (s2kparams.length == 0) {
347
sb.append("empty\n");
348
} else {
349
sb.append(new sun.misc.HexDumpEncoder()
350
.encodeBuffer(s2kparams));
351
}
352
}
353
} catch (IOException|Asn1Exception e) {
354
sb.append("\t <Unparseable PA-ETYPE-INFO>\n");
355
}
356
}
357
break;
358
case Krb5.PA_FOR_USER:
359
sb.append("\t PA-FOR-USER\n");
360
break;
361
default:
362
// Unknown Pre-auth type
363
break;
364
}
365
return sb.toString();
366
}
367
}
368
369