Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/security/pkcs/PKCS9Attributes.java
41159 views
1
/*
2
* Copyright (c) 1997, 2006, 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
package sun.security.pkcs;
27
28
import java.io.IOException;
29
import java.io.OutputStream;
30
import java.util.Hashtable;
31
import sun.security.util.DerEncoder;
32
import sun.security.util.DerValue;
33
import sun.security.util.DerInputStream;
34
import sun.security.util.DerOutputStream;
35
import sun.security.util.ObjectIdentifier;
36
37
/**
38
* A set of attributes of class PKCS9Attribute.
39
*
40
* @author Douglas Hoover
41
*/
42
public class PKCS9Attributes {
43
/**
44
* Attributes in this set indexed by OID.
45
*/
46
private final Hashtable<ObjectIdentifier, PKCS9Attribute> attributes =
47
new Hashtable<ObjectIdentifier, PKCS9Attribute>(3);
48
49
/**
50
* The keys of this hashtable are the OIDs of permitted attributes.
51
*/
52
private final Hashtable<ObjectIdentifier, ObjectIdentifier> permittedAttributes;
53
54
/**
55
* The DER encoding of this attribute set. The tag byte must be
56
* DerValue.tag_SetOf.
57
*/
58
private final byte[] derEncoding;
59
60
/*
61
* Contols how attributes, which are not recognized by the PKCS9Attribute
62
* class, are handled during parsing.
63
*/
64
private boolean ignoreUnsupportedAttributes = false;
65
66
/**
67
* Construct a set of PKCS9 Attributes from its
68
* DER encoding on a DerInputStream, accepting only attributes
69
* with OIDs on the given
70
* list. If the array is null, accept all attributes supported by
71
* class PKCS9Attribute.
72
*
73
* @param permittedAttributes
74
* Array of attribute OIDs that will be accepted.
75
* @param in
76
* the contents of the DER encoding of the attribute set.
77
*
78
* @exception IOException
79
* on i/o error, encoding syntax error, unacceptable or
80
* unsupported attribute, or duplicate attribute.
81
*
82
* @see PKCS9Attribute
83
*/
84
public PKCS9Attributes(ObjectIdentifier[] permittedAttributes,
85
DerInputStream in) throws IOException {
86
if (permittedAttributes != null) {
87
this.permittedAttributes =
88
new Hashtable<>(permittedAttributes.length);
89
90
for (int i = 0; i < permittedAttributes.length; i++)
91
this.permittedAttributes.put(permittedAttributes[i],
92
permittedAttributes[i]);
93
} else {
94
this.permittedAttributes = null;
95
}
96
97
// derEncoding initialized in <code>decode()</code>
98
derEncoding = decode(in);
99
}
100
101
/**
102
* Construct a set of PKCS9 Attributes from the contents of its
103
* DER encoding on a DerInputStream. Accept all attributes
104
* supported by class PKCS9Attribute and reject any unsupported
105
* attributes.
106
*
107
* @param in the contents of the DER encoding of the attribute set.
108
* @exception IOException
109
* on i/o error, encoding syntax error, or unsupported or
110
* duplicate attribute.
111
*
112
* @see PKCS9Attribute
113
*/
114
public PKCS9Attributes(DerInputStream in) throws IOException {
115
this(in, false);
116
}
117
118
/**
119
* Construct a set of PKCS9 Attributes from the contents of its
120
* DER encoding on a DerInputStream. Accept all attributes
121
* supported by class PKCS9Attribute and ignore any unsupported
122
* attributes, if directed.
123
*
124
* @param in the contents of the DER encoding of the attribute set.
125
* @param ignoreUnsupportedAttributes If true then any attributes
126
* not supported by the PKCS9Attribute class are ignored. Otherwise
127
* unsupported attributes cause an exception to be thrown.
128
* @exception IOException
129
* on i/o error, encoding syntax error, or unsupported or
130
* duplicate attribute.
131
*
132
* @see PKCS9Attribute
133
*/
134
public PKCS9Attributes(DerInputStream in,
135
boolean ignoreUnsupportedAttributes) throws IOException {
136
137
this.ignoreUnsupportedAttributes = ignoreUnsupportedAttributes;
138
// derEncoding initialized in <code>decode()</code>
139
derEncoding = decode(in);
140
permittedAttributes = null;
141
}
142
143
/**
144
* Construct a set of PKCS9 Attributes from the given array of
145
* PKCS9 attributes.
146
* DER encoding on a DerInputStream. All attributes in
147
* <code>attribs</code> must be
148
* supported by class PKCS9Attribute.
149
*
150
* @exception IOException
151
* on i/o error, encoding syntax error, or unsupported or
152
* duplicate attribute.
153
*
154
* @see PKCS9Attribute
155
*/
156
public PKCS9Attributes(PKCS9Attribute[] attribs)
157
throws IllegalArgumentException, IOException {
158
ObjectIdentifier oid;
159
for (int i=0; i < attribs.length; i++) {
160
oid = attribs[i].getOID();
161
if (attributes.containsKey(oid))
162
throw new IllegalArgumentException(
163
"PKCSAttribute " + attribs[i].getOID() +
164
" duplicated while constructing " +
165
"PKCS9Attributes.");
166
167
attributes.put(oid, attribs[i]);
168
}
169
derEncoding = generateDerEncoding();
170
permittedAttributes = null;
171
}
172
173
174
/**
175
* Decode this set of PKCS9 attributes from the contents of its
176
* DER encoding. Ignores unsupported attributes when directed.
177
*
178
* @param in
179
* the contents of the DER encoding of the attribute set.
180
*
181
* @exception IOException
182
* on i/o error, encoding syntax error, unacceptable or
183
* unsupported attribute, or duplicate attribute.
184
*/
185
private byte[] decode(DerInputStream in) throws IOException {
186
187
DerValue val = in.getDerValue();
188
189
// save the DER encoding with its proper tag byte.
190
byte[] derEncoding = val.toByteArray();
191
derEncoding[0] = DerValue.tag_SetOf;
192
193
DerInputStream derIn = new DerInputStream(derEncoding);
194
DerValue[] derVals = derIn.getSet(3,true);
195
196
PKCS9Attribute attrib;
197
ObjectIdentifier oid;
198
boolean reuseEncoding = true;
199
200
for (int i=0; i < derVals.length; i++) {
201
202
try {
203
attrib = new PKCS9Attribute(derVals[i]);
204
205
} catch (ParsingException e) {
206
if (ignoreUnsupportedAttributes) {
207
reuseEncoding = false; // cannot reuse supplied DER encoding
208
continue; // skip
209
} else {
210
throw e;
211
}
212
}
213
oid = attrib.getOID();
214
215
if (attributes.get(oid) != null)
216
throw new IOException("Duplicate PKCS9 attribute: " + oid);
217
218
if (permittedAttributes != null &&
219
!permittedAttributes.containsKey(oid))
220
throw new IOException("Attribute " + oid +
221
" not permitted in this attribute set");
222
223
attributes.put(oid, attrib);
224
}
225
return reuseEncoding ? derEncoding : generateDerEncoding();
226
}
227
228
/**
229
* Put the DER encoding of this PKCS9 attribute set on an
230
* DerOutputStream, tagged with the given implicit tag.
231
*
232
* @param tag the implicit tag to use in the DER encoding.
233
* @param out the output stream on which to put the DER encoding.
234
*
235
* @exception IOException on output error.
236
*/
237
public void encode(byte tag, OutputStream out) throws IOException {
238
out.write(tag);
239
out.write(derEncoding, 1, derEncoding.length -1);
240
}
241
242
private byte[] generateDerEncoding() throws IOException {
243
DerOutputStream out = new DerOutputStream();
244
Object[] attribVals = attributes.values().toArray();
245
246
out.putOrderedSetOf(DerValue.tag_SetOf,
247
castToDerEncoder(attribVals));
248
return out.toByteArray();
249
}
250
251
/**
252
* Return the DER encoding of this attribute set, tagged with
253
* DerValue.tag_SetOf.
254
*/
255
public byte[] getDerEncoding() throws IOException {
256
return derEncoding.clone();
257
258
}
259
260
/**
261
* Get an attribute from this set.
262
*/
263
public PKCS9Attribute getAttribute(ObjectIdentifier oid) {
264
return attributes.get(oid);
265
}
266
267
/**
268
* Get an attribute from this set.
269
*/
270
public PKCS9Attribute getAttribute(String name) {
271
return attributes.get(PKCS9Attribute.getOID(name));
272
}
273
274
275
/**
276
* Get an array of all attributes in this set, in order of OID.
277
*/
278
public PKCS9Attribute[] getAttributes() {
279
PKCS9Attribute[] attribs = new PKCS9Attribute[attributes.size()];
280
ObjectIdentifier oid;
281
282
int j = 0;
283
for (int i=1; i < PKCS9Attribute.PKCS9_OIDS.length &&
284
j < attribs.length; i++) {
285
attribs[j] = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]);
286
287
if (attribs[j] != null)
288
j++;
289
}
290
return attribs;
291
}
292
293
/**
294
* Get an attribute value by OID.
295
*/
296
public Object getAttributeValue(ObjectIdentifier oid)
297
throws IOException {
298
try {
299
Object value = getAttribute(oid).getValue();
300
return value;
301
} catch (NullPointerException ex) {
302
throw new IOException("No value found for attribute " + oid);
303
}
304
305
}
306
307
/**
308
* Get an attribute value by type name.
309
*/
310
public Object getAttributeValue(String name) throws IOException {
311
ObjectIdentifier oid = PKCS9Attribute.getOID(name);
312
313
if (oid == null)
314
throw new IOException("Attribute name " + name +
315
" not recognized or not supported.");
316
317
return getAttributeValue(oid);
318
}
319
320
321
/**
322
* Returns the PKCS9 block in a printable string form.
323
*/
324
public String toString() {
325
StringBuilder sb = new StringBuilder(200);
326
sb.append("PKCS9 Attributes: [\n\t");
327
328
ObjectIdentifier oid;
329
PKCS9Attribute value;
330
331
boolean first = true;
332
for (int i = 1; i < PKCS9Attribute.PKCS9_OIDS.length; i++) {
333
value = getAttribute(PKCS9Attribute.PKCS9_OIDS[i]);
334
335
if (value == null) continue;
336
337
// we have a value; print it
338
if (first)
339
first = false;
340
else
341
sb.append(";\n\t");
342
343
sb.append(value.toString());
344
}
345
346
sb.append("\n\t] (end PKCS9 Attributes)");
347
348
return sb.toString();
349
}
350
351
/**
352
* Cast an object array whose components are
353
* <code>DerEncoder</code>s to <code>DerEncoder[]</code>.
354
*/
355
static DerEncoder[] castToDerEncoder(Object[] objs) {
356
357
DerEncoder[] encoders = new DerEncoder[objs.length];
358
359
for (int i=0; i < encoders.length; i++)
360
encoders[i] = (DerEncoder) objs[i];
361
362
return encoders;
363
}
364
}
365
366