Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/security/x509/AuthorityKeyIdentifierExtension.java
41159 views
1
/*
2
* Copyright (c) 1997, 2009, 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.x509;
27
28
import java.io.IOException;
29
import java.io.OutputStream;
30
import java.util.Enumeration;
31
32
import sun.security.util.*;
33
34
/**
35
* This class represents the Authority Key Identifier Extension.
36
*
37
* <p>The authority key identifier extension provides a means of
38
* identifying the particular public key used to sign a certificate.
39
* This extension would be used where an issuer has multiple signing
40
* keys (either due to multiple concurrent key pairs or due to
41
* changeover).
42
* <p>
43
* The ASN.1 syntax for this is:
44
* <pre>
45
* AuthorityKeyIdentifier ::= SEQUENCE {
46
* keyIdentifier [0] KeyIdentifier OPTIONAL,
47
* authorityCertIssuer [1] GeneralNames OPTIONAL,
48
* authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL
49
* }
50
* KeyIdentifier ::= OCTET STRING
51
* </pre>
52
* @author Amit Kapoor
53
* @author Hemma Prafullchandra
54
* @see Extension
55
* @see CertAttrSet
56
*/
57
public class AuthorityKeyIdentifierExtension extends Extension
58
implements CertAttrSet<String> {
59
/**
60
* Identifier for this attribute, to be used with the
61
* get, set, delete methods of Certificate, x509 type.
62
*/
63
public static final String IDENT =
64
"x509.info.extensions.AuthorityKeyIdentifier";
65
/**
66
* Attribute names.
67
*/
68
public static final String NAME = "AuthorityKeyIdentifier";
69
public static final String KEY_ID = "key_id";
70
public static final String AUTH_NAME = "auth_name";
71
public static final String SERIAL_NUMBER = "serial_number";
72
73
// Private data members
74
private static final byte TAG_ID = 0;
75
private static final byte TAG_NAMES = 1;
76
private static final byte TAG_SERIAL_NUM = 2;
77
78
private KeyIdentifier id = null;
79
private GeneralNames names = null;
80
private SerialNumber serialNum = null;
81
82
// Encode only the extension value
83
private void encodeThis() throws IOException {
84
if (id == null && names == null && serialNum == null) {
85
this.extensionValue = null;
86
return;
87
}
88
DerOutputStream seq = new DerOutputStream();
89
DerOutputStream tmp = new DerOutputStream();
90
if (id != null) {
91
DerOutputStream tmp1 = new DerOutputStream();
92
id.encode(tmp1);
93
tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
94
false, TAG_ID), tmp1);
95
}
96
try {
97
if (names != null) {
98
DerOutputStream tmp1 = new DerOutputStream();
99
names.encode(tmp1);
100
tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
101
true, TAG_NAMES), tmp1);
102
}
103
} catch (Exception e) {
104
throw new IOException(e.toString());
105
}
106
if (serialNum != null) {
107
DerOutputStream tmp1 = new DerOutputStream();
108
serialNum.encode(tmp1);
109
tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
110
false, TAG_SERIAL_NUM), tmp1);
111
}
112
seq.write(DerValue.tag_Sequence, tmp);
113
this.extensionValue = seq.toByteArray();
114
}
115
116
/**
117
* The default constructor for this extension. Null parameters make
118
* the element optional (not present).
119
*
120
* @param kid the KeyIdentifier associated with this extension.
121
* @param names the GeneralNames associated with this extension
122
* @param sn the CertificateSerialNumber associated with
123
* this extension.
124
* @exception IOException on error.
125
*/
126
public AuthorityKeyIdentifierExtension(KeyIdentifier kid, GeneralNames names,
127
SerialNumber sn)
128
throws IOException {
129
this.id = kid;
130
this.names = names;
131
this.serialNum = sn;
132
133
this.extensionId = PKIXExtensions.AuthorityKey_Id;
134
this.critical = false;
135
encodeThis();
136
}
137
138
/**
139
* Create the extension from the passed DER encoded value of the same.
140
*
141
* @param critical true if the extension is to be treated as critical.
142
* @param value an array of DER encoded bytes of the actual value.
143
* @exception ClassCastException if value is not an array of bytes
144
* @exception IOException on error.
145
*/
146
public AuthorityKeyIdentifierExtension(Boolean critical, Object value)
147
throws IOException {
148
this.extensionId = PKIXExtensions.AuthorityKey_Id;
149
this.critical = critical.booleanValue();
150
151
this.extensionValue = (byte[]) value;
152
DerValue val = new DerValue(this.extensionValue);
153
if (val.tag != DerValue.tag_Sequence) {
154
throw new IOException("Invalid encoding for " +
155
"AuthorityKeyIdentifierExtension.");
156
}
157
158
// Note that all the fields in AuthorityKeyIdentifier are defined as
159
// being OPTIONAL, i.e., there could be an empty SEQUENCE, resulting
160
// in val.data being null.
161
while ((val.data != null) && (val.data.available() != 0)) {
162
DerValue opt = val.data.getDerValue();
163
164
// NB. this is always encoded with the IMPLICIT tag
165
// The checks only make sense if we assume implicit tagging,
166
// with explicit tagging the form is always constructed.
167
if (opt.isContextSpecific(TAG_ID) && !opt.isConstructed()) {
168
if (id != null)
169
throw new IOException("Duplicate KeyIdentifier in " +
170
"AuthorityKeyIdentifier.");
171
opt.resetTag(DerValue.tag_OctetString);
172
id = new KeyIdentifier(opt);
173
174
} else if (opt.isContextSpecific(TAG_NAMES) &&
175
opt.isConstructed()) {
176
if (names != null)
177
throw new IOException("Duplicate GeneralNames in " +
178
"AuthorityKeyIdentifier.");
179
opt.resetTag(DerValue.tag_Sequence);
180
names = new GeneralNames(opt);
181
182
} else if (opt.isContextSpecific(TAG_SERIAL_NUM) &&
183
!opt.isConstructed()) {
184
if (serialNum != null)
185
throw new IOException("Duplicate SerialNumber in " +
186
"AuthorityKeyIdentifier.");
187
opt.resetTag(DerValue.tag_Integer);
188
serialNum = new SerialNumber(opt);
189
} else
190
throw new IOException("Invalid encoding of " +
191
"AuthorityKeyIdentifierExtension.");
192
}
193
}
194
195
/**
196
* Return the object as a string.
197
*/
198
public String toString() {
199
StringBuilder sb = new StringBuilder();
200
sb.append(super.toString())
201
.append("AuthorityKeyIdentifier [\n");
202
if (id != null) {
203
sb.append(id); // id already has a newline
204
}
205
if (names != null) {
206
sb.append(names).append('\n');
207
}
208
if (serialNum != null) {
209
sb.append(serialNum).append('\n');
210
}
211
sb.append("]\n");
212
return sb.toString();
213
}
214
215
/**
216
* Write the extension to the OutputStream.
217
*
218
* @param out the OutputStream to write the extension to.
219
* @exception IOException on error.
220
*/
221
public void encode(OutputStream out) throws IOException {
222
DerOutputStream tmp = new DerOutputStream();
223
if (this.extensionValue == null) {
224
extensionId = PKIXExtensions.AuthorityKey_Id;
225
critical = false;
226
encodeThis();
227
}
228
super.encode(tmp);
229
out.write(tmp.toByteArray());
230
}
231
232
/**
233
* Set the attribute value.
234
*/
235
public void set(String name, Object obj) throws IOException {
236
if (name.equalsIgnoreCase(KEY_ID)) {
237
if (!(obj instanceof KeyIdentifier)) {
238
throw new IOException("Attribute value should be of " +
239
"type KeyIdentifier.");
240
}
241
id = (KeyIdentifier)obj;
242
} else if (name.equalsIgnoreCase(AUTH_NAME)) {
243
if (!(obj instanceof GeneralNames)) {
244
throw new IOException("Attribute value should be of " +
245
"type GeneralNames.");
246
}
247
names = (GeneralNames)obj;
248
} else if (name.equalsIgnoreCase(SERIAL_NUMBER)) {
249
if (!(obj instanceof SerialNumber)) {
250
throw new IOException("Attribute value should be of " +
251
"type SerialNumber.");
252
}
253
serialNum = (SerialNumber)obj;
254
} else {
255
throw new IOException("Attribute name not recognized by " +
256
"CertAttrSet:AuthorityKeyIdentifier.");
257
}
258
encodeThis();
259
}
260
261
/**
262
* Get the attribute value.
263
*/
264
public Object get(String name) throws IOException {
265
if (name.equalsIgnoreCase(KEY_ID)) {
266
return (id);
267
} else if (name.equalsIgnoreCase(AUTH_NAME)) {
268
return (names);
269
} else if (name.equalsIgnoreCase(SERIAL_NUMBER)) {
270
return (serialNum);
271
} else {
272
throw new IOException("Attribute name not recognized by " +
273
"CertAttrSet:AuthorityKeyIdentifier.");
274
}
275
}
276
277
/**
278
* Delete the attribute value.
279
*/
280
public void delete(String name) throws IOException {
281
if (name.equalsIgnoreCase(KEY_ID)) {
282
id = null;
283
} else if (name.equalsIgnoreCase(AUTH_NAME)) {
284
names = null;
285
} else if (name.equalsIgnoreCase(SERIAL_NUMBER)) {
286
serialNum = null;
287
} else {
288
throw new IOException("Attribute name not recognized by " +
289
"CertAttrSet:AuthorityKeyIdentifier.");
290
}
291
encodeThis();
292
}
293
294
/**
295
* Return an enumeration of names of attributes existing within this
296
* attribute.
297
*/
298
public Enumeration<String> getElements() {
299
AttributeNameEnumeration elements = new AttributeNameEnumeration();
300
elements.addElement(KEY_ID);
301
elements.addElement(AUTH_NAME);
302
elements.addElement(SERIAL_NUMBER);
303
304
return (elements.elements());
305
}
306
307
/**
308
* Return the name of this attribute.
309
*/
310
public String getName() {
311
return (NAME);
312
}
313
314
/**
315
* Return the encoded key identifier, or null if not specified.
316
*/
317
public byte[] getEncodedKeyIdentifier() throws IOException {
318
if (id != null) {
319
DerOutputStream derOut = new DerOutputStream();
320
id.encode(derOut);
321
return derOut.toByteArray();
322
}
323
return null;
324
}
325
}
326
327