iaik.x509
Class X509Extensions

java.lang.Object
  |
  +--iaik.x509.X509Extensions
Direct Known Subclasses:
OCSPExtensions

public class X509Extensions
extends Object

This class is used to deal with X.509v3 certificate and X.509v2 CRL extensions.

The X.509v3 certificate format has been introduced by ISO/IEC and ANSI X9 to add the the Extensions field to the X.509v2 certificate format for including some additional information. Extension support for CRLs has been introduced by the X.509v2 CRL format (see RFC 2459). An extension may be a defined standard extension (e.g. certificatePolicies, keyUsage, ...), or it may be a private extension providing some community-specific information. If an extension is marked as critical, but the certificate handling software cannot parse this extension, the appertaining certifcate has to be rejected. Non-Critical extensions can be ignored, if they cannot be handled (i.e. of unknown state).

In ASN.1, the Extensions field is defined as a SEQUENCE of Extension:

 Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension

 Extension  ::=  SEQUENCE  {
   extnID      OBJECT IDENTIFIER,
   critical    BOOLEAN DEFAULT FALSE,
   extnValue   OCTET STRING  }
 

where critical specifies whether an extension has to be treated as being critical or not; the default value is FALSE. An extension can be identified by its object identifier, given in the extnID field. The value of the extension is represented as ASN.1 encoded OCTET STRING data structure in the extnValue field. Only one instance of a particular extension may be present in a particular certiifcate.

The X509v3 certificate profile presented in RFC 2459 prescribes that confirming CAs must support the AuthorityKeyIdentifier, SubjectKeyIdentifer, BasicConstraints, KeyUsage and CertificatePolicies extensions. The SubjectAltName extensions has to be supported if certificates with empty subject fields are issued.


This class consits of two parts:

Every class which implements a specific extension must first register itself, e.g.:

 MyPrivateExtension extens V3Extension {
   ...
   public static final ObjectID oid = ...;

 }

 X509Extensions.register(MyPrivateExtension.oid, MyPrivateExtension.class);
 

At this time, per default, implementations of the following extensions are registered:

The dynamic part of this class provides a variety of useful methods for managing extensions. Most of these methods are, for instance, internally called within the X509Certificate class for adding, accessing and removing extensions of a X509 certificate, or for querying for the properties of included extensions.

This class manages extensions by maintaining two separate hashtables for storing critical and noncritical extensions. When an extension has to be added to one of the two hashtables by calling the addExtension method, the DER encoded value of the extension is put into the corresponding hashtable using the OID of the extension as key. In the same way, when an already existing X509Extensions object is parsed for any included extensions, only their DER encoded values are put into the hashtables. For saving time, the extensions are not actually parsed for their internal structures at this time. Parsing some extension is induced when reading it back from one of the hashtables by calling getExtension(ObjectID). Only at this time actually the appropriate implementation class is instantiated and initialized through the DER encoded extension value derived from the corresponding hashtable. If the initialization process fails for some reason, a X509ExtensionInitException is thrown. If the extension just initialized is an unknown extension (i.e. an extension, for which there exists no registered implementation), an UnknownExtension object is created and returned by the getExtension method to be parsed for obtaining as much information as possible from the unknown extension. When using the listExtensions method for obtaining all the extensions included in the actual X509Extensions object, an enumeration is returned containing an UnknownExtension for any included unknown extension, and an ErrorExtension for any extension which cannot be initialized because it is burdened with some kind of error. Note the difference: Within the IAIK-JCE environment, an unknown extension denotes an extension, for which there exists no registered implementation; whereas an error extension represents an - registered or unknown - erroneous extension which cannot be parsed properly.

Version:
File Revision 48
See Also:
V3Extension, X509Certificate, RevokedCertificate, X509CRL

Field Summary
protected  Hashtable critical_extensions
          Repository for critical extensions.
protected  Hashtable noncritical_extensions
          Repository for noncritical extensions.
 
Constructor Summary
X509Extensions()
          Default Constructor.
X509Extensions(ASN1Object extensions)
          Creates a new X.509Extensions object from an ASN1Object.
 
Method Summary
 boolean addExtension(V3Extension e)
          Adds an extension to this X509Extensions object.
 int countExtensions()
          Returns the number of extensions included in this X509Extensions object.
static V3Extension create(ObjectID oid)
          Returns the implementation of the specified extension defined through an ASN.1 ObjectID.
 Set getCriticalExtensionOIDs()
          Gets a Set of the OID strings for the extension(s) marked CRITICAL in this X509Extensions object.
 V3Extension getExtension(ObjectID oid)
          Returns a particular extension, specified by its object ID.
 byte[] getExtensionValue(String oid)
          Returns a byte array representing the DER encoding of the extension value identified by the passed-in OID string.
 Set getNonCriticalExtensionOIDs()
          Gets a Set of the OID strings for the extension(s) marked NON-CRITICAL in this X509Extensions object.
 boolean hasExtensions()
          Checks, if there are any extensions currently maintained by this X509Extensions object.
 boolean hasUnsupportedCriticalExtension()
          Returns true if there are unsupported critical extensions.
 Enumeration listExtensions()
          Returns an enumeration of all extensions currently maintained by this X509Extensions object.
protected  void parseExtensions(ASN1Object extObj)
          Initializes the extensions from an ASN1Object.
static void register(ObjectID oid, Class cl)
          Registers a new implementation for a X.509 certificate or CRL extension.
 void removeAllExtensions()
          Removes all extensions currently maintained by this X509Extensions object.
 boolean removeExtension(ObjectID oid)
          Removes an extension, identified by its object ID.
 ASN1Object toASN1Object()
          Returns this X509Extensions object as (SEQUENCE) ASN1Object.
 String toString()
          Returns a string that represents the contents of the extensions.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

critical_extensions

protected Hashtable critical_extensions
Repository for critical extensions.

noncritical_extensions

protected Hashtable noncritical_extensions
Repository for noncritical extensions.
Constructor Detail

X509Extensions

public X509Extensions()
Default Constructor. Creates a new X509Extensions object to be supplied with V3Extensions. Two hashtables - one for critical and the other for non critical extensions - are created.

X509Extensions

public X509Extensions(ASN1Object extensions)
               throws X509ExtensionException
Creates a new X.509Extensions object from an ASN1Object.

The given ASN1Object has the ASN.1 type "SEQUENCE of Extensions", and may have been created by calling the toASN1Objetct method.

Parameters:
extensions - the extensions as ASN1Object
Throws:
X509ExtensionException - if the extensions cannot be parsed
Method Detail

create

public static V3Extension create(ObjectID oid)
                          throws InstantiationException
Returns the implementation of the specified extension defined through an ASN.1 ObjectID.

This method belongs to the static part of this class.

Parameters:
oid - the ObjectID of the extension.
Returns:
the implementation of the extension with this oid
Throws:
InstantiationException - if the internal factory couldn't create an instance of requested type

register

public static void register(ObjectID oid,
                            Class cl)
Registers a new implementation for a X.509 certificate or CRL extension. This method belongs to the static part of this class.
Parameters:
oid - the object id of the extension to be registered
class - the class which implements this extension

addExtension

public boolean addExtension(V3Extension e)
                     throws X509ExtensionException
Adds an extension to this X509Extensions object.

The extension to be added shall be an implemented V3Extension. This class manages extensions by maintaining two separate hashtables for storing critical and noncritical extensions. Only the DER encoded value of the given extension is put into the corresponding hashtable using the OID of the extension as key. If an extension with the same object ID already exists, it is replaced. In this case this method returns true, otherwise - if there exists no extension with the same object ID - this method returns false. For reading back some extension from one of the hashtables, use the getExtension(ObjectID) method. Only at this time actually the appropriate implementation class is created and initialized through the DER encoded extension value derived from the corresponding hashtable.

Parameters:
e - the X509v3 extension to add to the list of extensions
Returns:
true, if an extension with the same object id has been replaced, or false if there has yet not been included any extension with the same ObjectID
Throws:
X509ExtensionException - if an error occurs while DER encoding the extension

removeExtension

public boolean removeExtension(ObjectID oid)
Removes an extension, identified by its object ID.
Parameters:
objectID - the object ID of the extension to remove
Returns:
true if the extension successfully has been removed, false otherwise

removeAllExtensions

public void removeAllExtensions()
Removes all extensions currently maintained by this X509Extensions object.

listExtensions

public Enumeration listExtensions()
Returns an enumeration of all extensions currently maintained by this X509Extensions object.

The enumeration returned by this method will contain an UnknownExtension for any included unknown extension, and an ErrorExtension for any extension which cannot be initialized because it is burdened with some kind of error.

Returns:
an enumeration of the extensions

hasExtensions

public boolean hasExtensions()
Checks, if there are any extensions currently maintained by this X509Extensions object.
Returns:
true if there are extensions, false if not

countExtensions

public int countExtensions()
Returns the number of extensions included in this X509Extensions object.
Returns:
the number of extensions

getExtension

public V3Extension getExtension(ObjectID oid)
                         throws X509ExtensionInitException
Returns a particular extension, specified by its object ID.

This method creates a new implementation of the class registered for this ObjectID and initializes it with the extension value derived from the corresponding hashtable. If the extension is an unknown extension, an UnknownExtension is returned. If the extension cannot be initialized properly because of some error, an X509ExtensionInitException is thrown.

Parameters:
objectID - the object ID of the extension
Returns:
the desired extension if it is available, or null if not
Throws:
X509ExtensionInitException - if the extension can not be initialized

getCriticalExtensionOIDs

public Set getCriticalExtensionOIDs()
Gets a Set of the OID strings for the extension(s) marked CRITICAL in this X509Extensions object. Note that when using JDK 1.1 a IAIK implementation of the JDK 1.2 Set class is used that provides only limited functionality.
Returns:
a Set (or an empty Set if none are marked critical) of the extension OID strings for extensions that are marked critical. If there are no extensions present at all, then this method returns null

getNonCriticalExtensionOIDs

public Set getNonCriticalExtensionOIDs()
Gets a Set of the OID strings for the extension(s) marked NON-CRITICAL in this X509Extensions object. Note that when using JDK 1.1 a IAIK implementation of the JDK 1.2 Set class is used that provides only limited functionality.
Returns:
a Set (or an empty Set if none are marked non-critical) of the extension OID strings for extensions that are marked non-critical. If there are no extensions present at all, then this method returns null.

hasUnsupportedCriticalExtension

public boolean hasUnsupportedCriticalExtension()
Returns true if there are unsupported critical extensions.
Returns:
true, if there are unsupported critical extensions

getExtensionValue

public byte[] getExtensionValue(String oid)
Returns a byte array representing the DER encoding of the extension value identified by the passed-in OID string.

The OID string is represented by a set of positive whole numbers separated by periods, e.g. "2.5.29.15" for the KeyUsage extension.

In ASN.1, the Extensions field is defined as a SEQUENCE of Extension:

 Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension

 Extension  ::=  SEQUENCE  {
   extnID      OBJECT IDENTIFIER,
   critical    BOOLEAN DEFAULT FALSE,
   extnValue   OCTET STRING  }
 

where critical specifies whether an extension has to be treated as being critical or not; the default value is FALSE. An extension can be identified by its object identifier, given in the extnID field. The value of the extension is represented as ASN.1 OCTET STRING data structure in the extnValue field. Only one instance of a particular extension may be present in a particular certificate.

The byte value returned by this method represents the DER encoding of the extnValue (OCTET_STRING) from above, and the value of this OCTET STRING represents the DER encoding of the specific extension´s ASN.1 representation itsself.

Attention: For compatibility reasons to the standard JCA certificate API this method has been changed to return the OCTET STRING value as described above. Prior versions of this class have returned the DER encoding of the specific extension´s ASN.1 representation itsself.

Parameters:
oid - the Object Identifier value for the extension
Returns:
the DER encodeded ASN.1 representation of the extension value or null if it is not present

parseExtensions

protected void parseExtensions(ASN1Object extObj)
                        throws X509ExtensionException
Initializes the extensions from an ASN1Object.

The ASN1Object must be an ASN.1 datastructure "SEQUENCE of Extensions", as can be found in X509v3 certificates or X509v2 CRLs.

The given ASN1Object is parsed for any included extension. For each included extension, the DER encoded extension value is computed and put into one of two hashtables for critical respectively non-critical extensions. For actually getting an implematation of some included extension call the getExtension method. For getting an enumeration of all included extensions, use the listExtensions() method.

Parameters:
extObj - the ASN.1 datastructure "SEQUENCE of Extensions"
Throws:
X509ExtensionException - if there is an error while parsing the extensions
See Also:
UnknownExtension

toASN1Object

public ASN1Object toASN1Object()
                        throws X509ExtensionException
Returns this X509Extensions object as (SEQUENCE) ASN1Object. The ASN1Object has the ASN.1 type "SEQUENCE of Extensions".
Returns:
the extensions as ASN1Object.
Throws:
X509ExtensionException - if the extensions could not be created

toString

public String toString()
Returns a string that represents the contents of the extensions.
Overrides:
toString in class Object
Returns:
the string representation

This Javadoc may contain text parts from Internet Standard specifications (RFC 2459, 3280, 3039, 2560, 1521, 821, 822, 2253, 1319, 1321, ,2630, 2631, 2268, 3058, 2984, 2104, 2144, 2040, 2311, 2279, see copyright note) and RSA Data Security Public-Key Cryptography Standards (PKCS#1,3,5,7,8,9,10,12, see copyright note).

IAIK-JCE 3.1 with IAIK-JCE CC Core 3.1, (c) 1997-2004 IAIK