blob: 7ac6e854b8674f6621402b113cee2ba7a3cd191e [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25/*
26 * $Id: KeyInfoFactory.java,v 1.12 2005/05/10 16:35:35 mullan Exp $
27 */
28package javax.xml.crypto.dsig.keyinfo;
29
30import java.math.BigInteger;
31import java.security.KeyException;
32import java.security.NoSuchAlgorithmException;
33import java.security.NoSuchProviderException;
34import java.security.Provider;
35import java.security.PublicKey;
36import java.security.Security;
37import java.security.cert.X509CRL;
38import java.util.List;
39import javax.xml.crypto.MarshalException;
40import javax.xml.crypto.NoSuchMechanismException;
41import javax.xml.crypto.URIDereferencer;
42import javax.xml.crypto.XMLStructure;
43import javax.xml.crypto.dom.DOMStructure;
44import javax.xml.crypto.dsig.*;
45
46import sun.security.jca.*;
47import sun.security.jca.GetInstance.Instance;
48
49/**
50 * A factory for creating {@link KeyInfo} objects from scratch or for
51 * unmarshalling a <code>KeyInfo</code> object from a corresponding XML
52 * representation.
53 *
54 * <p>Each instance of <code>KeyInfoFactory</code> supports a specific
55 * XML mechanism type. To create a <code>KeyInfoFactory</code>, call one of the
56 * static {@link #getInstance getInstance} methods, passing in the XML
57 * mechanism type desired, for example:
58 *
59 * <blockquote><code>
60 * KeyInfoFactory factory = KeyInfoFactory.getInstance("DOM");
61 * </code></blockquote>
62 *
63 * <p>The objects that this factory produces will be based
64 * on DOM and abide by the DOM interoperability requirements as defined in the
65 * <a href="../../../../../../technotes/guides/security/xmldsig/overview.html#DOM Mechanism Requirements">
66 * DOM Mechanism Requirements</a> section of the API overview. See the
67 * <a href="../../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">
68 * Service Providers</a> section of the API overview for a list of standard
69 * mechanism types.
70 *
71 * <p><code>KeyInfoFactory</code> implementations are registered and loaded
72 * using the {@link java.security.Provider} mechanism.
73 * For example, a service provider that supports the
74 * DOM mechanism would be specified in the <code>Provider</code> subclass as:
75 * <pre>
76 * put("KeyInfoFactory.DOM", "org.example.DOMKeyInfoFactory");
77 * </pre>
78 *
79 * <p>Also, the <code>XMLStructure</code>s that are created by this factory
80 * may contain state specific to the <code>KeyInfo</code> and are not
81 * intended to be reusable.
82 *
83 * <p>An implementation MUST minimally support the default mechanism type: DOM.
84 *
85 * <p>Note that a caller must use the same <code>KeyInfoFactory</code>
86 * instance to create the <code>XMLStructure</code>s of a particular
87 * <code>KeyInfo</code> object. The behavior is undefined if
88 * <code>XMLStructure</code>s from different providers or different mechanism
89 * types are used together.
90 *
91 * <p><b>Concurrent Access</b>
92 * <p>The static methods of this class are guaranteed to be thread-safe.
93 * Multiple threads may concurrently invoke the static methods defined in this
94 * class with no ill effects.
95 *
96 * <p>However, this is not true for the non-static methods defined by this
97 * class. Unless otherwise documented by a specific provider, threads that
98 * need to access a single <code>KeyInfoFactory</code> instance concurrently
99 * should synchronize amongst themselves and provide the necessary locking.
100 * Multiple threads each manipulating a different <code>KeyInfoFactory</code>
101 * instance need not synchronize.
102 *
103 * @author Sean Mullan
104 * @author JSR 105 Expert Group
105 * @since 1.6
106 */
107public abstract class KeyInfoFactory {
108
109 private String mechanismType;
110 private Provider provider;
111
112 /**
113 * Default constructor, for invocation by subclasses.
114 */
115 protected KeyInfoFactory() {}
116
117 /**
118 * Returns a <code>KeyInfoFactory</code> that supports the
119 * specified XML processing mechanism and representation type (ex: "DOM").
120 *
121 * <p>This method uses the standard JCA provider lookup mechanism to
122 * locate and instantiate a <code>KeyInfoFactory</code> implementation of
123 * the desired mechanism type. It traverses the list of registered security
124 * <code>Provider</code>s, starting with the most preferred
125 * <code>Provider</code>. A new <code>KeyInfoFactory</code> object
126 * from the first <code>Provider</code> that supports the specified
127 * mechanism is returned.
128 *
129 * <p> Note that the list of registered providers may be retrieved via
130 * the {@link Security#getProviders() Security.getProviders()} method.
131 *
132 * @param mechanismType the type of the XML processing mechanism and
133 * representation. See the <a
134 * href="../../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">
135 * Service Providers</a> section of the API overview for a list of
136 * standard mechanism types.
137 * @return a new <code>KeyInfoFactory</code>
138 * @throws NullPointerException if <code>mechanismType</code> is
139 * <code>null</code>
140 * @throws NoSuchMechanismException if no <code>Provider</code> supports a
141 * <code>KeyInfoFactory</code> implementation for the specified mechanism
142 * @see Provider
143 */
144 public static KeyInfoFactory getInstance(String mechanismType) {
145 if (mechanismType == null) {
146 throw new NullPointerException("mechanismType cannot be null");
147 }
148 Instance instance;
149 try {
150 instance = GetInstance.getInstance
151 ("KeyInfoFactory", null, mechanismType);
152 } catch (NoSuchAlgorithmException nsae) {
153 throw new NoSuchMechanismException(nsae);
154 }
155 KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
156 factory.mechanismType = mechanismType;
157 factory.provider = instance.provider;
158 return factory;
159 }
160
161 /**
162 * Returns a <code>KeyInfoFactory</code> that supports the
163 * requested XML processing mechanism and representation type (ex: "DOM"),
164 * as supplied by the specified provider. Note that the specified
165 * <code>Provider</code> object does not have to be registered in the
166 * provider list.
167 *
168 * @param mechanismType the type of the XML processing mechanism and
169 * representation. See the <a
170 * href="../../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">
171 * Service Providers</a> section of the API overview for a list of
172 * standard mechanism types.
173 * @param provider the <code>Provider</code> object
174 * @return a new <code>KeyInfoFactory</code>
175 * @throws NullPointerException if <code>mechanismType</code> or
176 * <code>provider</code> are <code>null</code>
177 * @throws NoSuchMechanismException if a <code>KeyInfoFactory</code>
178 * implementation for the specified mechanism is not available from the
179 * specified <code>Provider</code> object
180 * @see Provider
181 */
182 public static KeyInfoFactory getInstance(String mechanismType,
183 Provider provider) {
184 if (mechanismType == null) {
185 throw new NullPointerException("mechanismType cannot be null");
186 } else if (provider == null) {
187 throw new NullPointerException("provider cannot be null");
188 }
189
190 Instance instance;
191 try {
192 instance = GetInstance.getInstance
193 ("KeyInfoFactory", null, mechanismType, provider);
194 } catch (NoSuchAlgorithmException nsae) {
195 throw new NoSuchMechanismException(nsae);
196 }
197 KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
198 factory.mechanismType = mechanismType;
199 factory.provider = instance.provider;
200 return factory;
201 }
202
203 /**
204 * Returns a <code>KeyInfoFactory</code> that supports the
205 * requested XML processing mechanism and representation type (ex: "DOM"),
206 * as supplied by the specified provider. The specified provider must be
207 * registered in the security provider list.
208 *
209 * <p>Note that the list of registered providers may be retrieved via
210 * the {@link Security#getProviders() Security.getProviders()} method.
211 *
212 * @param mechanismType the type of the XML processing mechanism and
213 * representation. See the <a
214 * href="../../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">
215 * Service Providers</a> section of the API overview for a list of
216 * standard mechanism types.
217 * @param provider the string name of the provider
218 * @return a new <code>KeyInfoFactory</code>
219 * @throws NoSuchProviderException if the specified provider is not
220 * registered in the security provider list
221 * @throws NullPointerException if <code>mechanismType</code> or
222 * <code>provider</code> are <code>null</code>
223 * @throws NoSuchMechanismException if a <code>KeyInfoFactory</code>
224 * implementation for the specified mechanism is not available from the
225 * specified provider
226 * @see Provider
227 */
228 public static KeyInfoFactory getInstance(String mechanismType,
229 String provider) throws NoSuchProviderException {
230 if (mechanismType == null) {
231 throw new NullPointerException("mechanismType cannot be null");
232 } else if (provider == null) {
233 throw new NullPointerException("provider cannot be null");
234 } else if (provider.length() == 0) {
235 throw new NoSuchProviderException();
236 }
237
238 Instance instance;
239 try {
240 instance = GetInstance.getInstance
241 ("KeyInfoFactory", null, mechanismType, provider);
242 } catch (NoSuchAlgorithmException nsae) {
243 throw new NoSuchMechanismException(nsae);
244 }
245 KeyInfoFactory factory = (KeyInfoFactory) instance.impl;
246 factory.mechanismType = mechanismType;
247 factory.provider = instance.provider;
248 return factory;
249 }
250
251 /**
252 * Returns a <code>KeyInfoFactory</code> that supports the
253 * default XML processing mechanism and representation type ("DOM").
254 *
255 * <p>This method uses the standard JCA provider lookup mechanism to
256 * locate and instantiate a <code>KeyInfoFactory</code> implementation of
257 * the default mechanism type. It traverses the list of registered security
258 * <code>Provider</code>s, starting with the most preferred
259 * <code>Provider</code>. A new <code>KeyInfoFactory</code> object
260 * from the first <code>Provider</code> that supports the DOM mechanism is
261 * returned.
262 *
263 * <p> Note that the list of registered providers may be retrieved via
264 * the {@link Security#getProviders() Security.getProviders()} method.
265 *
266 * @return a new <code>KeyInfoFactory</code>
267 * @throws NoSuchMechanismException if no <code>Provider</code> supports a
268 * <code>KeyInfoFactory</code> implementation for the DOM mechanism
269 * @see Provider
270 */
271 public static KeyInfoFactory getInstance() {
272 return getInstance("DOM");
273 }
274
275 /**
276 * Returns the type of the XML processing mechanism and representation
277 * supported by this <code>KeyInfoFactory</code> (ex: "DOM")
278 *
279 * @return the XML processing mechanism type supported by this
280 * <code>KeyInfoFactory</code>
281 */
282 public final String getMechanismType() {
283 return mechanismType;
284 }
285
286 /**
287 * Returns the provider of this <code>KeyInfoFactory</code>.
288 *
289 * @return the provider of this <code>KeyInfoFactory</code>
290 */
291 public final Provider getProvider() {
292 return provider;
293 }
294
295 /**
296 * Creates a <code>KeyInfo</code> containing the specified list of
297 * key information types.
298 *
299 * @param content a list of one or more {@link XMLStructure}s representing
300 * key information types. The list is defensively copied to protect
301 * against subsequent modification.
302 * @return a <code>KeyInfo</code>
303 * @throws NullPointerException if <code>content</code> is <code>null</code>
304 * @throws IllegalArgumentException if <code>content</code> is empty
305 * @throws ClassCastException if <code>content</code> contains any entries
306 * that are not of type {@link XMLStructure}
307 */
308 public abstract KeyInfo newKeyInfo(List content);
309
310 /**
311 * Creates a <code>KeyInfo</code> containing the specified list of key
312 * information types and optional id. The
313 * <code>id</code> parameter represents the value of an XML
314 * <code>ID</code> attribute and is useful for referencing
315 * the <code>KeyInfo</code> from other XML structures.
316 *
317 * @param content a list of one or more {@link XMLStructure}s representing
318 * key information types. The list is defensively copied to protect
319 * against subsequent modification.
320 * @param id the value of an XML <code>ID</code> (may be <code>null</code>)
321 * @return a <code>KeyInfo</code>
322 * @throws NullPointerException if <code>content</code> is <code>null</code>
323 * @throws IllegalArgumentException if <code>content</code> is empty
324 * @throws ClassCastException if <code>content</code> contains any entries
325 * that are not of type {@link XMLStructure}
326 */
327 public abstract KeyInfo newKeyInfo(List content, String id);
328
329 /**
330 * Creates a <code>KeyName</code> from the specified name.
331 *
332 * @param name the name that identifies the key
333 * @return a <code>KeyName</code>
334 * @throws NullPointerException if <code>name</code> is <code>null</code>
335 */
336 public abstract KeyName newKeyName(String name);
337
338 /**
339 * Creates a <code>KeyValue</code> from the specified public key.
340 *
341 * @param key the public key
342 * @return a <code>KeyValue</code>
343 * @throws KeyException if the <code>key</code>'s algorithm is not
344 * recognized or supported by this <code>KeyInfoFactory</code>
345 * @throws NullPointerException if <code>key</code> is <code>null</code>
346 */
347 public abstract KeyValue newKeyValue(PublicKey key) throws KeyException;
348
349 /**
350 * Creates a <code>PGPData</code> from the specified PGP public key
351 * identifier.
352 *
353 * @param keyId a PGP public key identifier as defined in <a href=
354 * "http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>, section 11.2.
355 * The array is cloned to protect against subsequent modification.
356 * @return a <code>PGPData</code>
357 * @throws NullPointerException if <code>keyId</code> is <code>null</code>
358 * @throws IllegalArgumentException if the key id is not in the correct
359 * format
360 */
361 public abstract PGPData newPGPData(byte[] keyId);
362
363 /**
364 * Creates a <code>PGPData</code> from the specified PGP public key
365 * identifier, and optional key material packet and list of external
366 * elements.
367 *
368 * @param keyId a PGP public key identifier as defined in <a href=
369 * "http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>, section 11.2.
370 * The array is cloned to protect against subsequent modification.
371 * @param keyPacket a PGP key material packet as defined in <a href=
372 * "http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>, section 5.5.
373 * The array is cloned to protect against subsequent modification. May
374 * be <code>null</code>.
375 * @param other a list of {@link XMLStructure}s representing elements from
376 * an external namespace. The list is defensively copied to protect
377 * against subsequent modification. May be <code>null</code> or empty.
378 * @return a <code>PGPData</code>
379 * @throws NullPointerException if <code>keyId</code> is <code>null</code>
380 * @throws IllegalArgumentException if the <code>keyId</code> or
381 * <code>keyPacket</code> is not in the correct format. For
382 * <code>keyPacket</code>, the format of the packet header is
383 * checked and the tag is verified that it is of type key material. The
384 * contents and format of the packet body are not checked.
385 * @throws ClassCastException if <code>other</code> contains any
386 * entries that are not of type {@link XMLStructure}
387 */
388 public abstract PGPData newPGPData(byte[] keyId, byte[] keyPacket,
389 List other);
390
391 /**
392 * Creates a <code>PGPData</code> from the specified PGP key material
393 * packet and optional list of external elements.
394 *
395 * @param keyPacket a PGP key material packet as defined in <a href=
396 * "http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>, section 5.5.
397 * The array is cloned to protect against subsequent modification.
398 * @param other a list of {@link XMLStructure}s representing elements from
399 * an external namespace. The list is defensively copied to protect
400 * against subsequent modification. May be <code>null</code> or empty.
401 * @return a <code>PGPData</code>
402 * @throws NullPointerException if <code>keyPacket</code> is
403 * <code>null</code>
404 * @throws IllegalArgumentException if <code>keyPacket</code> is not in the
405 * correct format. For <code>keyPacket</code>, the format of the packet
406 * header is checked and the tag is verified that it is of type key
407 * material. The contents and format of the packet body are not checked.
408 * @throws ClassCastException if <code>other</code> contains any
409 * entries that are not of type {@link XMLStructure}
410 */
411 public abstract PGPData newPGPData(byte[] keyPacket, List other);
412
413 /**
414 * Creates a <code>RetrievalMethod</code> from the specified URI.
415 *
416 * @param uri the URI that identifies the <code>KeyInfo</code> information
417 * to be retrieved
418 * @return a <code>RetrievalMethod</code>
419 * @throws NullPointerException if <code>uri</code> is <code>null</code>
420 * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396
421 * compliant
422 */
423 public abstract RetrievalMethod newRetrievalMethod(String uri);
424
425 /**
426 * Creates a <code>RetrievalMethod</code> from the specified parameters.
427 *
428 * @param uri the URI that identifies the <code>KeyInfo</code> information
429 * to be retrieved
430 * @param type a URI that identifies the type of <code>KeyInfo</code>
431 * information to be retrieved (may be <code>null</code>)
432 * @param transforms a list of {@link Transform}s. The list is defensively
433 * copied to protect against subsequent modification. May be
434 * <code>null</code> or empty.
435 * @return a <code>RetrievalMethod</code>
436 * @throws NullPointerException if <code>uri</code> is <code>null</code>
437 * @throws IllegalArgumentException if <code>uri</code> is not RFC 2396
438 * compliant
439 * @throws ClassCastException if <code>transforms</code> contains any
440 * entries that are not of type {@link Transform}
441 */
442 public abstract RetrievalMethod newRetrievalMethod(String uri, String type,
443 List transforms);
444
445 /**
446 * Creates a <code>X509Data</code> containing the specified list of
447 * X.509 content.
448 *
449 * @param content a list of one or more X.509 content types. Valid types are
450 * {@link String} (subject names), <code>byte[]</code> (subject key ids),
451 * {@link java.security.cert.X509Certificate}, {@link X509CRL},
452 * or {@link XMLStructure} ({@link X509IssuerSerial}
453 * objects or elements from an external namespace). Subject names are
454 * distinguished names in RFC 2253 String format. Implementations MUST
455 * support the attribute type keywords defined in RFC 2253 (CN, L, ST,
456 * O, OU, C, STREET, DC and UID). Implementations MAY support additional
457 * keywords. The list is defensively copied to protect against
458 * subsequent modification.
459 * @return a <code>X509Data</code>
460 * @throws NullPointerException if <code>content</code> is <code>null</code>
461 * @throws IllegalArgumentException if <code>content</code> is empty, or
462 * if a subject name is not RFC 2253 compliant or one of the attribute
463 * type keywords is not recognized.
464 * @throws ClassCastException if <code>content</code> contains any entries
465 * that are not of one of the valid types mentioned above
466 */
467 public abstract X509Data newX509Data(List content);
468
469 /**
470 * Creates an <code>X509IssuerSerial</code> from the specified X.500 issuer
471 * distinguished name and serial number.
472 *
473 * @param issuerName the issuer's distinguished name in RFC 2253 String
474 * format. Implementations MUST support the attribute type keywords
475 * defined in RFC 2253 (CN, L, ST, O, OU, C, STREET, DC and UID).
476 * Implementations MAY support additional keywords.
477 * @param serialNumber the serial number
478 * @return an <code>X509IssuerSerial</code>
479 * @throws NullPointerException if <code>issuerName</code> or
480 * <code>serialNumber</code> are <code>null</code>
481 * @throws IllegalArgumentException if the issuer name is not RFC 2253
482 * compliant or one of the attribute type keywords is not recognized.
483 */
484 public abstract X509IssuerSerial newX509IssuerSerial
485 (String issuerName, BigInteger serialNumber);
486
487 /**
488 * Indicates whether a specified feature is supported.
489 *
490 * @param feature the feature name (as an absolute URI)
491 * @return <code>true</code> if the specified feature is supported,
492 * <code>false</code> otherwise
493 * @throws NullPointerException if <code>feature</code> is <code>null</code>
494 */
495 public abstract boolean isFeatureSupported(String feature);
496
497 /**
498 * Returns a reference to the <code>URIDereferencer</code> that is used by
499 * default to dereference URIs in {@link RetrievalMethod} objects.
500 *
501 * @return a reference to the default <code>URIDereferencer</code>
502 */
503 public abstract URIDereferencer getURIDereferencer();
504
505 /**
506 * Unmarshals a new <code>KeyInfo</code> instance from a
507 * mechanism-specific <code>XMLStructure</code> (ex: {@link DOMStructure})
508 * instance.
509 *
510 * @param xmlStructure a mechanism-specific XML structure from which to
511 * unmarshal the keyinfo from
512 * @return the <code>KeyInfo</code>
513 * @throws NullPointerException if <code>xmlStructure</code> is
514 * <code>null</code>
515 * @throws ClassCastException if the type of <code>xmlStructure</code> is
516 * inappropriate for this factory
517 * @throws MarshalException if an unrecoverable exception occurs during
518 * unmarshalling
519 */
520 public abstract KeyInfo unmarshalKeyInfo(XMLStructure xmlStructure)
521 throws MarshalException;
522}