Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/security/pkcs10/PKCS10.java
41159 views
1
/*
2
* Copyright (c) 1996, 2020, 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
package sun.security.pkcs10;
28
29
import java.io.PrintStream;
30
import java.io.IOException;
31
import java.math.BigInteger;
32
33
import java.security.*;
34
35
import java.util.Base64;
36
37
import sun.security.util.*;
38
import sun.security.x509.AlgorithmId;
39
import sun.security.x509.X509Key;
40
import sun.security.x509.X500Name;
41
import sun.security.util.SignatureUtil;
42
43
44
/**
45
* A PKCS #10 certificate request is created and sent to a Certificate
46
* Authority, which then creates an X.509 certificate and returns it to
47
* the entity that requested it. A certificate request basically consists
48
* of the subject's X.500 name, public key, and optionally some attributes,
49
* signed using the corresponding private key.
50
*
51
* The ASN.1 syntax for a Certification Request is:
52
* <pre>
53
* CertificationRequest ::= SEQUENCE {
54
* certificationRequestInfo CertificationRequestInfo,
55
* signatureAlgorithm SignatureAlgorithmIdentifier,
56
* signature Signature
57
* }
58
*
59
* SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
60
* Signature ::= BIT STRING
61
*
62
* CertificationRequestInfo ::= SEQUENCE {
63
* version Version,
64
* subject Name,
65
* subjectPublicKeyInfo SubjectPublicKeyInfo,
66
* attributes [0] IMPLICIT Attributes
67
* }
68
* Attributes ::= SET OF Attribute
69
* </pre>
70
*
71
* @author David Brownell
72
* @author Amit Kapoor
73
* @author Hemma Prafullchandra
74
*/
75
public class PKCS10 {
76
/**
77
* Constructs an unsigned PKCS #10 certificate request. Before this
78
* request may be used, it must be encoded and signed. Then it
79
* must be retrieved in some conventional format (e.g. string).
80
*
81
* @param publicKey the public key that should be placed
82
* into the certificate generated by the CA.
83
*/
84
public PKCS10(PublicKey publicKey) {
85
subjectPublicKeyInfo = publicKey;
86
attributeSet = new PKCS10Attributes();
87
}
88
89
/**
90
* Constructs an unsigned PKCS #10 certificate request. Before this
91
* request may be used, it must be encoded and signed. Then it
92
* must be retrieved in some conventional format (e.g. string).
93
*
94
* @param publicKey the public key that should be placed
95
* into the certificate generated by the CA.
96
* @param attributes additonal set of PKCS10 attributes requested
97
* for in the certificate.
98
*/
99
public PKCS10(PublicKey publicKey, PKCS10Attributes attributes) {
100
subjectPublicKeyInfo = publicKey;
101
attributeSet = attributes;
102
}
103
104
/**
105
* Parses an encoded, signed PKCS #10 certificate request, verifying
106
* the request's signature as it does so. This constructor would
107
* typically be used by a Certificate Authority, from which a new
108
* certificate would then be constructed.
109
*
110
* @param data the DER-encoded PKCS #10 request.
111
* @exception IOException for low level errors reading the data
112
* @exception SignatureException when the signature is invalid
113
* @exception NoSuchAlgorithmException when the signature
114
* algorithm is not supported in this environment
115
*/
116
public PKCS10(byte[] data)
117
throws IOException, SignatureException, NoSuchAlgorithmException {
118
DerInputStream in;
119
DerValue[] seq;
120
AlgorithmId id;
121
byte[] sigData;
122
Signature sig;
123
124
encoded = data;
125
126
//
127
// Outer sequence: request, signature algorithm, signature.
128
// Parse, and prepare to verify later.
129
//
130
in = new DerInputStream(data);
131
seq = in.getSequence(3);
132
133
if (seq.length != 3)
134
throw new IllegalArgumentException("not a PKCS #10 request");
135
136
data = seq[0].toByteArray(); // reusing this variable
137
id = AlgorithmId.parse(seq[1]);
138
sigData = seq[2].getBitString();
139
140
//
141
// Inner sequence: version, name, key, attributes
142
//
143
BigInteger serial;
144
DerValue val;
145
146
serial = seq[0].data.getBigInteger();
147
if (!serial.equals(BigInteger.ZERO))
148
throw new IllegalArgumentException("not PKCS #10 v1");
149
150
subject = new X500Name(seq[0].data);
151
subjectPublicKeyInfo = X509Key.parse(seq[0].data.getDerValue());
152
153
// Cope with a somewhat common illegal PKCS #10 format
154
if (seq[0].data.available() != 0)
155
attributeSet = new PKCS10Attributes(seq[0].data);
156
else
157
attributeSet = new PKCS10Attributes();
158
159
if (seq[0].data.available() != 0)
160
throw new IllegalArgumentException("illegal PKCS #10 data");
161
162
//
163
// OK, we parsed it all ... validate the signature using the
164
// key and signature algorithm we found.
165
//
166
try {
167
sigAlg = id.getName();
168
sig = Signature.getInstance(sigAlg);
169
SignatureUtil.initVerifyWithParam(sig, subjectPublicKeyInfo,
170
SignatureUtil.getParamSpec(sigAlg, id.getParameters()));
171
172
sig.update(data);
173
if (!sig.verify(sigData)) {
174
throw new SignatureException("Invalid PKCS #10 signature");
175
}
176
} catch (InvalidKeyException e) {
177
throw new SignatureException("Invalid key");
178
} catch (InvalidAlgorithmParameterException e) {
179
throw new SignatureException("Invalid signature parameters", e);
180
} catch (ProviderException e) {
181
throw new SignatureException("Error parsing signature parameters",
182
e.getCause());
183
}
184
}
185
186
/**
187
* Create the signed certificate request. This will later be
188
* retrieved in either string or binary format.
189
*
190
* @param subject identifies the signer (by X.500 name).
191
* @param key private key to use.
192
* @param algorithm signing algorithm to use.
193
* @exception IOException on errors.
194
* @exception SignatureException on signature handling errors.
195
* @exception NoSuchAlgorithmException algorithm is not recognized
196
* @exception InvalidKeyException key has a problem
197
*/
198
public void encodeAndSign(X500Name subject, PrivateKey key, String algorithm)
199
throws IOException, SignatureException,
200
NoSuchAlgorithmException, InvalidKeyException {
201
202
DerOutputStream out, scratch;
203
byte[] certificateRequestInfo;
204
byte[] sig;
205
206
if (encoded != null) {
207
throw new SignatureException("request is already signed");
208
}
209
210
Signature signature = SignatureUtil.fromKey(
211
algorithm, key, (Provider)null);
212
213
this.subject = subject;
214
215
/*
216
* Encode cert request info, wrap in a sequence for signing
217
*/
218
scratch = new DerOutputStream();
219
scratch.putInteger(BigInteger.ZERO); // PKCS #10 v1.0
220
subject.encode(scratch); // X.500 name
221
scratch.write(subjectPublicKeyInfo.getEncoded()); // public key
222
attributeSet.encode(scratch);
223
224
out = new DerOutputStream();
225
out.write(DerValue.tag_Sequence, scratch); // wrap it!
226
certificateRequestInfo = out.toByteArray();
227
scratch = out;
228
229
/*
230
* Sign it ...
231
*/
232
signature.update(certificateRequestInfo, 0,
233
certificateRequestInfo.length);
234
sig = signature.sign();
235
sigAlg = signature.getAlgorithm();
236
237
/*
238
* Build guts of SIGNED macro
239
*/
240
AlgorithmId algId = SignatureUtil.fromSignature(signature, key);
241
242
algId.encode(scratch); // sig algorithm
243
scratch.putBitString(sig); // sig
244
245
/*
246
* Wrap those guts in a sequence
247
*/
248
out = new DerOutputStream();
249
out.write(DerValue.tag_Sequence, scratch);
250
encoded = out.toByteArray();
251
}
252
253
/**
254
* Returns the subject's name.
255
*/
256
public X500Name getSubjectName() { return subject; }
257
258
/**
259
* Returns the subject's public key.
260
*/
261
public PublicKey getSubjectPublicKeyInfo()
262
{ return subjectPublicKeyInfo; }
263
264
/**
265
* Returns the signature algorithm.
266
*/
267
public String getSigAlg() { return sigAlg; }
268
269
/**
270
* Returns the additional attributes requested.
271
*/
272
public PKCS10Attributes getAttributes()
273
{ return attributeSet; }
274
275
/**
276
* Returns the encoded and signed certificate request as a
277
* DER-encoded byte array.
278
*
279
* @return the certificate request, or null if encodeAndSign()
280
* has not yet been called.
281
*/
282
public byte[] getEncoded() {
283
if (encoded != null)
284
return encoded.clone();
285
else
286
return null;
287
}
288
289
/**
290
* Prints an E-Mailable version of the certificate request on the print
291
* stream passed. The format is a common base64 encoded one, supported
292
* by most Certificate Authorities because Netscape web servers have
293
* used this for some time. Some certificate authorities expect some
294
* more information, in particular contact information for the web
295
* server administrator.
296
*
297
* @param out the print stream where the certificate request
298
* will be printed.
299
* @exception IOException when an output operation failed
300
* @exception SignatureException when the certificate request was
301
* not yet signed.
302
*/
303
public void print(PrintStream out)
304
throws IOException, SignatureException {
305
if (encoded == null)
306
throw new SignatureException("Cert request was not signed");
307
308
309
byte[] CRLF = new byte[] {'\r', '\n'};
310
out.println("-----BEGIN NEW CERTIFICATE REQUEST-----");
311
out.println(Base64.getMimeEncoder(64, CRLF).encodeToString(encoded));
312
out.println("-----END NEW CERTIFICATE REQUEST-----");
313
}
314
315
/**
316
* Provides a short description of this request.
317
*/
318
public String toString() {
319
return "[PKCS #10 certificate request:\n"
320
+ subjectPublicKeyInfo.toString()
321
+ " subject: <" + subject + ">" + "\n"
322
+ " attributes: " + attributeSet.toString()
323
+ "\n]";
324
}
325
326
/**
327
* Compares this object for equality with the specified
328
* object. If the <code>other</code> object is an
329
* <code>instanceof</code> <code>PKCS10</code>, then
330
* its encoded form is retrieved and compared with the
331
* encoded form of this certificate request.
332
*
333
* @param other the object to test for equality with this object.
334
* @return true iff the encoded forms of the two certificate
335
* requests match, false otherwise.
336
*/
337
public boolean equals(Object other) {
338
if (this == other)
339
return true;
340
if (!(other instanceof PKCS10))
341
return false;
342
if (encoded == null) // not signed yet
343
return false;
344
byte[] otherEncoded = ((PKCS10)other).getEncoded();
345
if (otherEncoded == null)
346
return false;
347
348
return java.util.Arrays.equals(encoded, otherEncoded);
349
}
350
351
/**
352
* Returns a hashcode value for this certificate request from its
353
* encoded form.
354
*
355
* @return the hashcode value.
356
*/
357
public int hashCode() {
358
int retval = 0;
359
if (encoded != null)
360
for (int i = 1; i < encoded.length; i++)
361
retval += encoded[i] * i;
362
return(retval);
363
}
364
365
private X500Name subject;
366
private PublicKey subjectPublicKeyInfo;
367
private String sigAlg;
368
private PKCS10Attributes attributeSet;
369
private byte[] encoded; // signed
370
}
371
372