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