History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/pkcs/PKCS10.java (1 of 18352 files). Show all

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t