Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.security.jgss/share/classes/sun/security/krb5/internal/PAData.java
41161 views
1
/*
2
* Copyright (c) 2017, 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
*
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;
33
34
import java.io.IOException;
35
import java.util.Vector;
36
37
import static java.nio.charset.StandardCharsets.*;
38
39
import sun.security.krb5.Asn1Exception;
40
import sun.security.krb5.internal.util.KerberosString;
41
import sun.security.krb5.internal.crypto.EType;
42
import sun.security.util.*;
43
44
/**
45
* Implements the ASN.1 PA-DATA type.
46
*
47
* <pre>{@code
48
* PA-DATA ::= SEQUENCE {
49
* -- NOTE: first tag is [1], not [0]
50
* padata-type [1] Int32,
51
* padata-value [2] OCTET STRING -- might be encoded AP-REQ
52
* }
53
* }</pre>
54
*
55
* <p>
56
* This definition reflects the Network Working Group RFC 4120
57
* specification available at
58
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
59
* http://www.ietf.org/rfc/rfc4120.txt</a>.
60
*/
61
62
public class PAData {
63
private int pADataType;
64
private byte[] pADataValue = null;
65
private static final byte TAG_PATYPE = 1;
66
private static final byte TAG_PAVALUE = 2;
67
68
private PAData() {
69
}
70
71
public PAData(int new_pADataType, byte[] new_pADataValue) {
72
pADataType = new_pADataType;
73
if (new_pADataValue != null) {
74
pADataValue = new_pADataValue.clone();
75
}
76
}
77
78
public Object clone() {
79
PAData new_pAData = new PAData();
80
new_pAData.pADataType = pADataType;
81
if (pADataValue != null) {
82
new_pAData.pADataValue = new byte[pADataValue.length];
83
System.arraycopy(pADataValue, 0, new_pAData.pADataValue,
84
0, pADataValue.length);
85
}
86
return new_pAData;
87
}
88
89
/**
90
* Constructs a PAData object.
91
* @param encoding a Der-encoded data.
92
* @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
93
* @exception IOException if an I/O error occurs while reading encoded data.
94
*/
95
public PAData(DerValue encoding) throws Asn1Exception, IOException {
96
DerValue der = null;
97
if (encoding.getTag() != DerValue.tag_Sequence) {
98
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
99
}
100
der = encoding.getData().getDerValue();
101
if ((der.getTag() & 0x1F) == 0x01) {
102
this.pADataType = der.getData().getBigInteger().intValue();
103
}
104
else
105
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
106
der = encoding.getData().getDerValue();
107
if ((der.getTag() & 0x1F) == 0x02) {
108
this.pADataValue = der.getData().getOctetString();
109
}
110
if (encoding.getData().available() > 0)
111
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
112
}
113
114
/**
115
* Encodes this object to an OutputStream.
116
*
117
* @return byte array of the encoded data.
118
* @exception IOException if an I/O error occurs while reading encoded data.
119
* @exception Asn1Exception on encoding errors.
120
*/
121
public byte[] asn1Encode() throws Asn1Exception, IOException {
122
123
DerOutputStream bytes = new DerOutputStream();
124
DerOutputStream temp = new DerOutputStream();
125
126
temp.putInteger(pADataType);
127
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_PATYPE), temp);
128
temp = new DerOutputStream();
129
temp.putOctetString(pADataValue);
130
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_PAVALUE), temp);
131
132
temp = new DerOutputStream();
133
temp.write(DerValue.tag_Sequence, bytes);
134
return temp.toByteArray();
135
}
136
137
// accessor methods
138
public int getType() {
139
return pADataType;
140
}
141
142
public byte[] getValue() {
143
return ((pADataValue == null) ? null : pADataValue.clone());
144
}
145
146
/**
147
* Parse (unmarshal) a PAData from a DER input stream. This form
148
* parsing might be used when expanding a value which is part of
149
* a constructed sequence and uses explicitly tagged type.
150
*
151
* @exception Asn1Exception if an Asn1Exception occurs.
152
* @param data the Der input stream value, which contains one or more
153
* marshaled values.
154
* @param explicitTag tag number.
155
* @param optional indicates if this data field is optional.
156
* @return an array of PAData.
157
*/
158
public static PAData[] parseSequence(DerInputStream data,
159
byte explicitTag, boolean optional)
160
throws Asn1Exception, IOException {
161
if ((optional) &&
162
(((byte)data.peekByte() & (byte)0x1F) != explicitTag))
163
return null;
164
DerValue subDer = data.getDerValue();
165
DerValue subsubDer = subDer.getData().getDerValue();
166
if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
167
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
168
}
169
Vector<PAData> v = new Vector<>();
170
while (subsubDer.getData().available() > 0) {
171
v.addElement(new PAData(subsubDer.getData().getDerValue()));
172
}
173
if (v.size() > 0) {
174
PAData[] pas = new PAData[v.size()];
175
v.copyInto(pas);
176
return pas;
177
}
178
return null;
179
}
180
181
/**
182
* Gets the preferred etype from the PAData array.
183
* <ol>
184
* <li>ETYPE-INFO2-ENTRY with unknown s2kparams ignored</li>
185
* <li>ETYPE-INFO2 preferred to ETYPE-INFO</li>
186
* <li>Multiple entries for same etype in one PA-DATA, use the first one.</li>
187
* <li>Multiple PA-DATA with same type, choose the last one.</li>
188
* </ol>
189
* (This is useful when PA-DATAs from KRB-ERROR and AS-REP are combined).
190
*
191
* @return the etype, or defaultEType if not enough info
192
* @throws Asn1Exception|IOException if there is an encoding error
193
*/
194
public static int getPreferredEType(PAData[] pas, int defaultEType)
195
throws IOException, Asn1Exception {
196
197
if (pas == null) return defaultEType;
198
199
DerValue d = null, d2 = null;
200
for (PAData p: pas) {
201
if (p.getValue() == null) continue;
202
switch (p.getType()) {
203
case Krb5.PA_ETYPE_INFO:
204
d = new DerValue(p.getValue());
205
break;
206
case Krb5.PA_ETYPE_INFO2:
207
d2 = new DerValue(p.getValue());
208
break;
209
}
210
}
211
if (d2 != null) {
212
while (d2.data.available() > 0) {
213
DerValue value = d2.data.getDerValue();
214
ETypeInfo2 tmp = new ETypeInfo2(value);
215
if (EType.isNewer(tmp.getEType()) || tmp.getParams() == null) {
216
// we don't support non-null s2kparams for old etypes
217
return tmp.getEType();
218
}
219
}
220
}
221
if (d != null) {
222
while (d.data.available() > 0) {
223
DerValue value = d.data.getDerValue();
224
ETypeInfo tmp = new ETypeInfo(value);
225
return tmp.getEType();
226
}
227
}
228
return defaultEType;
229
}
230
231
/**
232
* A place to store a pair of salt and s2kparams.
233
* An empty salt is changed to null, to be interoperable
234
* with Windows 2000 server. This is in fact not correct.
235
*/
236
public static class SaltAndParams {
237
public final String salt;
238
public final byte[] params;
239
public SaltAndParams(String s, byte[] p) {
240
if (s != null && s.isEmpty()) s = null;
241
this.salt = s;
242
this.params = p;
243
}
244
}
245
246
/**
247
* Fetches salt and s2kparams value for eType in a series of PA-DATAs.
248
* 1. ETYPE-INFO2-ENTRY with unknown s2kparams ignored
249
* 2. PA-ETYPE-INFO2 preferred to PA-ETYPE-INFO preferred to PA-PW-SALT.
250
* 3. multiple entries for same etype in one PA-DATA, use the first one.
251
* 4. Multiple PA-DATA with same type, choose the last one
252
* (This is useful when PA-DATAs from KRB-ERROR and AS-REP are combined).
253
* @return salt and s2kparams. can be null if not found
254
*/
255
public static SaltAndParams getSaltAndParams(int eType, PAData[] pas)
256
throws Asn1Exception, IOException {
257
258
if (pas == null) return null;
259
260
DerValue d = null, d2 = null;
261
String paPwSalt = null;
262
263
for (PAData p: pas) {
264
if (p.getValue() == null) continue;
265
switch (p.getType()) {
266
case Krb5.PA_PW_SALT:
267
paPwSalt = new String(p.getValue(),
268
KerberosString.MSNAME ? UTF_8 : ISO_8859_1);
269
break;
270
case Krb5.PA_ETYPE_INFO:
271
d = new DerValue(p.getValue());
272
break;
273
case Krb5.PA_ETYPE_INFO2:
274
d2 = new DerValue(p.getValue());
275
break;
276
}
277
}
278
if (d2 != null) {
279
while (d2.data.available() > 0) {
280
DerValue value = d2.data.getDerValue();
281
ETypeInfo2 tmp = new ETypeInfo2(value);
282
if (tmp.getEType() == eType &&
283
(EType.isNewer(eType) || tmp.getParams() == null)) {
284
// we don't support non-null s2kparams for old etypes
285
return new SaltAndParams(tmp.getSalt(), tmp.getParams());
286
}
287
}
288
}
289
if (d != null) {
290
while (d.data.available() > 0) {
291
DerValue value = d.data.getDerValue();
292
ETypeInfo tmp = new ETypeInfo(value);
293
if (tmp.getEType() == eType) {
294
return new SaltAndParams(tmp.getSalt(), null);
295
}
296
}
297
}
298
if (paPwSalt != null) {
299
return new SaltAndParams(paPwSalt, null);
300
}
301
return null;
302
}
303
304
@Override
305
public String toString(){
306
StringBuilder sb = new StringBuilder();
307
sb.append(">>>Pre-Authentication Data:\n\t PA-DATA type = ")
308
.append(pADataType).append('\n');
309
310
switch(pADataType) {
311
case Krb5.PA_ENC_TIMESTAMP:
312
sb.append("\t PA-ENC-TIMESTAMP");
313
break;
314
case Krb5.PA_ETYPE_INFO:
315
if (pADataValue != null) {
316
try {
317
DerValue der = new DerValue(pADataValue);
318
while (der.data.available() > 0) {
319
DerValue value = der.data.getDerValue();
320
ETypeInfo info = new ETypeInfo(value);
321
sb.append("\t PA-ETYPE-INFO etype = ")
322
.append(info.getEType())
323
.append(", salt = ")
324
.append(info.getSalt())
325
.append('\n');
326
}
327
} catch (IOException|Asn1Exception e) {
328
sb.append("\t <Unparseable PA-ETYPE-INFO>\n");
329
}
330
}
331
break;
332
case Krb5.PA_ETYPE_INFO2:
333
if (pADataValue != null) {
334
try {
335
DerValue der = new DerValue(pADataValue);
336
while (der.data.available() > 0) {
337
DerValue value = der.data.getDerValue();
338
ETypeInfo2 info2 = new ETypeInfo2(value);
339
sb.append("\t PA-ETYPE-INFO2 etype = ")
340
.append(info2.getEType())
341
.append(", salt = ")
342
.append(info2.getSalt())
343
.append(", s2kparams = ");
344
byte[] s2kparams = info2.getParams();
345
if (s2kparams == null) {
346
sb.append("null\n");
347
} else if (s2kparams.length == 0) {
348
sb.append("empty\n");
349
} else {
350
sb.append(new sun.security.util.HexDumpEncoder()
351
.encodeBuffer(s2kparams));
352
}
353
}
354
} catch (IOException|Asn1Exception e) {
355
sb.append("\t <Unparseable PA-ETYPE-INFO>\n");
356
}
357
}
358
break;
359
case Krb5.PA_FOR_USER:
360
sb.append("\t PA-FOR-USER\n");
361
break;
362
default:
363
// Unknown Pre-auth type
364
break;
365
}
366
return sb.toString();
367
}
368
}
369
370