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/tools/keytool/CertAndKeyGen.java
38923 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
package sun.security.tools.keytool;
27
28
import java.io.IOException;
29
import java.security.cert.X509Certificate;
30
import java.security.cert.CertificateException;
31
import java.security.cert.CertificateEncodingException;
32
import java.security.*;
33
import java.security.spec.AlgorithmParameterSpec;
34
import java.util.Date;
35
36
import sun.security.pkcs10.PKCS10;
37
import sun.security.x509.*;
38
39
/**
40
* Generate a pair of keys, and provide access to them. This class is
41
* provided primarily for ease of use.
42
*
43
* <P>This provides some simple certificate management functionality.
44
* Specifically, it allows you to create self-signed X.509 certificates
45
* as well as PKCS 10 based certificate signing requests.
46
*
47
* <P>Keys for some public key signature algorithms have algorithm
48
* parameters, such as DSS/DSA. Some sites' Certificate Authorities
49
* adopt fixed algorithm parameters, which speeds up some operations
50
* including key generation and signing. <em>At this time, this interface
51
* does not provide a way to provide such algorithm parameters, e.g.
52
* by providing the CA certificate which includes those parameters.</em>
53
*
54
* <P>Also, note that at this time only signature-capable keys may be
55
* acquired through this interface. Diffie-Hellman keys, used for secure
56
* key exchange, may be supported later.
57
*
58
* @author David Brownell
59
* @author Hemma Prafullchandra
60
* @see PKCS10
61
* @see X509CertImpl
62
*/
63
public final class CertAndKeyGen {
64
/**
65
* Creates a CertAndKeyGen object for a particular key type
66
* and signature algorithm.
67
*
68
* @param keyType type of key, e.g. "RSA", "DSA"
69
* @param sigAlg name of the signature algorithm, e.g. "MD5WithRSA",
70
* "MD2WithRSA", "SHAwithDSA".
71
* @exception NoSuchAlgorithmException on unrecognized algorithms.
72
*/
73
public CertAndKeyGen (String keyType, String sigAlg)
74
throws NoSuchAlgorithmException
75
{
76
keyGen = KeyPairGenerator.getInstance(keyType);
77
this.sigAlg = sigAlg;
78
}
79
80
/**
81
* Creates a CertAndKeyGen object for a particular key type,
82
* signature algorithm, and provider.
83
*
84
* @param keyType type of key, e.g. "RSA", "DSA"
85
* @param sigAlg name of the signature algorithm, e.g. "MD5WithRSA",
86
* "MD2WithRSA", "SHAwithDSA".
87
* @param providerName name of the provider
88
* @exception NoSuchAlgorithmException on unrecognized algorithms.
89
* @exception NoSuchProviderException on unrecognized providers.
90
*/
91
public CertAndKeyGen (String keyType, String sigAlg, String providerName)
92
throws NoSuchAlgorithmException, NoSuchProviderException
93
{
94
if (providerName == null) {
95
keyGen = KeyPairGenerator.getInstance(keyType);
96
} else {
97
try {
98
keyGen = KeyPairGenerator.getInstance(keyType, providerName);
99
} catch (Exception e) {
100
// try first available provider instead
101
keyGen = KeyPairGenerator.getInstance(keyType);
102
}
103
}
104
this.sigAlg = sigAlg;
105
}
106
107
/**
108
* Sets the source of random numbers used when generating keys.
109
* If you do not provide one, a system default facility is used.
110
* You may wish to provide your own source of random numbers
111
* to get a reproducible sequence of keys and signatures, or
112
* because you may be able to take advantage of strong sources
113
* of randomness/entropy in your environment.
114
*/
115
public void setRandom (SecureRandom generator)
116
{
117
prng = generator;
118
}
119
120
// want "public void generate (X509Certificate)" ... inherit DSA/D-H param
121
122
/**
123
* Generates a random public/private key pair, with a given key
124
* size. Different algorithms provide different degrees of security
125
* for the same key size, because of the "work factor" involved in
126
* brute force attacks. As computers become faster, it becomes
127
* easier to perform such attacks. Small keys are to be avoided.
128
*
129
* <P>Note that not all values of "keyBits" are valid for all
130
* algorithms, and not all public key algorithms are currently
131
* supported for use in X.509 certificates. If the algorithm
132
* you specified does not produce X.509 compatible keys, an
133
* invalid key exception is thrown.
134
*
135
* @param keyBits the number of bits in the keys.
136
* @exception InvalidKeyException if the environment does not
137
* provide X.509 public keys for this signature algorithm.
138
*/
139
public void generate (int keyBits)
140
throws InvalidKeyException
141
{
142
KeyPair pair;
143
144
try {
145
if (prng == null) {
146
prng = new SecureRandom();
147
}
148
keyGen.initialize(keyBits, prng);
149
pair = keyGen.generateKeyPair();
150
151
} catch (Exception e) {
152
throw new IllegalArgumentException(e.getMessage());
153
}
154
155
publicKey = pair.getPublic();
156
privateKey = pair.getPrivate();
157
158
// publicKey's format must be X.509 otherwise
159
// the whole CertGen part of this class is broken.
160
if (!"X.509".equalsIgnoreCase(publicKey.getFormat())) {
161
throw new IllegalArgumentException("publicKey's is not X.509, but "
162
+ publicKey.getFormat());
163
}
164
}
165
166
167
/**
168
* Returns the public key of the generated key pair if it is of type
169
* <code>X509Key</code>, or null if the public key is of a different type.
170
*
171
* XXX Note: This behaviour is needed for backwards compatibility.
172
* What this method really should return is the public key of the
173
* generated key pair, regardless of whether or not it is an instance of
174
* <code>X509Key</code>. Accordingly, the return type of this method
175
* should be <code>PublicKey</code>.
176
*/
177
public X509Key getPublicKey()
178
{
179
if (!(publicKey instanceof X509Key)) {
180
return null;
181
}
182
return (X509Key)publicKey;
183
}
184
185
/**
186
* Always returns the public key of the generated key pair. Used
187
* by KeyTool only.
188
*
189
* The publicKey is not necessarily to be an instance of
190
* X509Key in some JCA/JCE providers, for example SunPKCS11.
191
*/
192
public PublicKey getPublicKeyAnyway() {
193
return publicKey;
194
}
195
196
/**
197
* Returns the private key of the generated key pair.
198
*
199
* <P><STRONG><em>Be extremely careful when handling private keys.
200
* When private keys are not kept secret, they lose their ability
201
* to securely authenticate specific entities ... that is a huge
202
* security risk!</em></STRONG>
203
*/
204
public PrivateKey getPrivateKey ()
205
{
206
return privateKey;
207
}
208
209
/**
210
* Returns a self-signed X.509v3 certificate for the public key.
211
* The certificate is immediately valid. No extensions.
212
*
213
* <P>Such certificates normally are used to identify a "Certificate
214
* Authority" (CA). Accordingly, they will not always be accepted by
215
* other parties. However, such certificates are also useful when
216
* you are bootstrapping your security infrastructure, or deploying
217
* system prototypes.
218
*
219
* @param myname X.500 name of the subject (who is also the issuer)
220
* @param firstDate the issue time of the certificate
221
* @param validity how long the certificate should be valid, in seconds
222
* @exception CertificateException on certificate handling errors.
223
* @exception InvalidKeyException on key handling errors.
224
* @exception SignatureException on signature handling errors.
225
* @exception NoSuchAlgorithmException on unrecognized algorithms.
226
* @exception NoSuchProviderException on unrecognized providers.
227
*/
228
public X509Certificate getSelfCertificate (
229
X500Name myname, Date firstDate, long validity)
230
throws CertificateException, InvalidKeyException, SignatureException,
231
NoSuchAlgorithmException, NoSuchProviderException
232
{
233
return getSelfCertificate(myname, firstDate, validity, null);
234
}
235
236
// Like above, plus a CertificateExtensions argument, which can be null.
237
public X509Certificate getSelfCertificate (X500Name myname, Date firstDate,
238
long validity, CertificateExtensions ext)
239
throws CertificateException, InvalidKeyException, SignatureException,
240
NoSuchAlgorithmException, NoSuchProviderException
241
{
242
X509CertImpl cert;
243
Date lastDate;
244
245
try {
246
lastDate = new Date ();
247
lastDate.setTime (firstDate.getTime () + validity * 1000);
248
249
CertificateValidity interval =
250
new CertificateValidity(firstDate,lastDate);
251
252
X509CertInfo info = new X509CertInfo();
253
AlgorithmParameterSpec params = AlgorithmId
254
.getDefaultAlgorithmParameterSpec(sigAlg, privateKey);
255
// Add all mandatory attributes
256
info.set(X509CertInfo.VERSION,
257
new CertificateVersion(CertificateVersion.V3));
258
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(
259
new java.util.Random().nextInt() & 0x7fffffff));
260
AlgorithmId algID = AlgorithmId.getWithParameterSpec(sigAlg, params);
261
info.set(X509CertInfo.ALGORITHM_ID,
262
new CertificateAlgorithmId(algID));
263
info.set(X509CertInfo.SUBJECT, myname);
264
info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey));
265
info.set(X509CertInfo.VALIDITY, interval);
266
info.set(X509CertInfo.ISSUER, myname);
267
if (ext != null) info.set(X509CertInfo.EXTENSIONS, ext);
268
269
cert = new X509CertImpl(info);
270
cert.sign(privateKey,
271
params,
272
sigAlg,
273
null);
274
275
return (X509Certificate)cert;
276
277
} catch (IOException e) {
278
throw new CertificateEncodingException("getSelfCert: " +
279
e.getMessage());
280
} catch (InvalidAlgorithmParameterException e2) {
281
throw new SignatureException(
282
"Unsupported PSSParameterSpec: " + e2.getMessage());
283
}
284
}
285
286
// Keep the old method
287
public X509Certificate getSelfCertificate (X500Name myname, long validity)
288
throws CertificateException, InvalidKeyException, SignatureException,
289
NoSuchAlgorithmException, NoSuchProviderException
290
{
291
return getSelfCertificate(myname, new Date(), validity);
292
}
293
294
/**
295
* Returns a PKCS #10 certificate request. The caller uses either
296
* <code>PKCS10.print</code> or <code>PKCS10.toByteArray</code>
297
* operations on the result, to get the request in an appropriate
298
* transmission format.
299
*
300
* <P>PKCS #10 certificate requests are sent, along with some proof
301
* of identity, to Certificate Authorities (CAs) which then issue
302
* X.509 public key certificates.
303
*
304
* @param myname X.500 name of the subject
305
* @exception InvalidKeyException on key handling errors.
306
* @exception SignatureException on signature handling errors.
307
*/
308
// This method is not used inside JDK. Will not update it.
309
public PKCS10 getCertRequest (X500Name myname)
310
throws InvalidKeyException, SignatureException
311
{
312
PKCS10 req = new PKCS10 (publicKey);
313
314
try {
315
Signature signature = Signature.getInstance(sigAlg);
316
signature.initSign (privateKey);
317
req.encodeAndSign(myname, signature);
318
319
} catch (CertificateException e) {
320
throw new SignatureException (sigAlg + " CertificateException");
321
322
} catch (IOException e) {
323
throw new SignatureException (sigAlg + " IOException");
324
325
} catch (NoSuchAlgorithmException e) {
326
// "can't happen"
327
throw new SignatureException (sigAlg + " unavailable?");
328
}
329
return req;
330
}
331
332
private SecureRandom prng;
333
private String sigAlg;
334
private KeyPairGenerator keyGen;
335
private PublicKey publicKey;
336
private PrivateKey privateKey;
337
}
338
339