iaik.asn1
Class DerCoder

java.lang.Object
  |
  +--iaik.asn1.DerCoder

public final class DerCoder
extends Object

This class provides DER en/decoding utility for arbitrary ASN.1 structures. Since this class only contains static methods it never will be directly instantiated.
This class provides two methods to be used for DER encoding ASN.1 objects (encode respectively encodeTo(ASN1Object, OutputStream)) and two methods for performing the reverse procedure of decoding DER encoded ASN.1 objects (decode(byte[]) respectively decode(InputStream)). Regardless of having to encode an ASN.1 object or decoding a given encoding, an appplication has to decide whether to write/read the encoding to/from a byte array or to/from a stream.

Both methods are able to decode aribitrary DER encoded data as long as the appertaining ASN.1 structure can be parsed within the memory. For decoding pre-known strutures of any length, use the DerInputStream decoding utility.

Version:
File Revision 30
See Also:
ASN1Object, DerInputStream

Method Summary
static ASN1Object decode(byte[] coding)
          Creates an ASN.1 object from the DER encoded version.
static ASN1Object decode(InputStream is)
          Creates an ASN.1 object from the DER encoded version.
static byte[] encode(ASN1Object object)
          DER encodes the given ASN.1 object and returns the coding as a byte array.
static void encodeTo(ASN1Object object, OutputStream os)
          Encodes the given ASN1Object and writes the coding directly to the specified OutputStream.
protected static void encodeTo(ASN1Object object, OutputStream os, boolean implicitlyTagged)
          The internal method additionally allows to specifiy whether the supplied ASN1Object has to be implicitly tagged.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

encodeTo

public static void encodeTo(ASN1Object object,
                            OutputStream os)
                     throws IOException
Encodes the given ASN1Object and writes the coding directly to the specified OutputStream. This method avoids building up the coding in the memory because large OCTET STRINGs often cause problems. For that reason, the indefinite constrcuted encoding method shall be used for BER - not DER - encoding octet strings that carry large amounts of data.

Indefinite length encoding works this way:

Since an octet string is not allowed to be indefinite primitive encoded (how to distinguish EOC octets from two adjacent 0x00 0x00 data bytes?), a BER encoding variant has to be used where whole the octet string is encoded as indefinite constructed octet string, being composed of a certain number of rather small primitive definite encoded octet string components. The length of each primitive component shall be set to a predefined blocksize. Following this, the data bytes are read block by block according to the specified block size. When actually reading some block it immediately is encoded and written to the given output stream. In this way, the number of bytes actually handled within the memory can be kept within reasonable bounds. The whole encoding would be indefinite and constructed giving an octet string that consists of a certain number of definite primitive encoded octet strings:
 0x24 0x80
           0x04 <blocksize> <data>
           0x04 <blocksize> <data>
           0x04 <blocksize> <data>
                ...
 0x00 0x00
 
Of course, the last block may be shorter than the defined blocksize!
For example, the five data bytes 0x01 0xAB 0x23 0x7F 0xCA may be encoded as:
 0x24 0x80
           0x04 0x02 0x01 0xAB
           0x04 0x02 0x23 0x7F
           0x04 0x01 0xCA
 0x00 0x00
 
The blockSize already has to be specified when creating the OCTET_STRING, e.g. for blocksize 1000:
 OCTET_STRING os = new OCTET_STRING(new FileInputStream("large.object", 1000);
 DerCoder.encodeTo(seq, new FileOutputStream("large.der");
 
When using an OCTET_STRING to be indefinite constructed encoded as component of another structured ASN.1 object (e.g. SEQUENCE, SET), this wrapping object also has to be enforced to be indfinite encode by setting the indefiniteLength qualifier to true:
 SEQUENCE seq = new SEQUENCE();
 OCTET_STRING os = new OCTET_STRING(new FileInputStream("large.object", 1000);
 seq.addComponent(os);
 seq.setIndefiniteLength(true);
 DerCoder.encodeTo(seq, new FileOutputStream("large.der");
 
In the same way, when context specific tagging an OCTET_STRING to be indefinite constructed encoded, the superior CON_SPEC has to be forced to be indefinite encoded, too, e.g.:
 SEQUENCE seq = new SEQUENCE();
 OCTET_STRING os = new OCTET_STRING(new FileInputStream("large.object", 1000);
 CON_SPEC con_spec = new CON_SPEC(0, os, implicitlyTagged);
 seq.addComponent(con_spec);
 con_spec.setIndefiniteLength(true);
 seq.setIndefiniteLength(true);
 ...
 DerCoder.encodeTo(seq, new FileOutputStream("large.der");
 
For decoding pre-known large ASN.1 objects you may use the DerInputStream utility.

Of course, this encodeTo method also can be used for encoding ASN.1 objects according to the definite primitive encoding practice. Indefinite encoding only will be enforced if the indefiniteLength qualifier of the ASN.1 object to be encoded, is set to true, which may be done by means of the setIndefiniteLength method of the ASN1Object class.

Parameters:
object - the ASN1Object to be DER encoded
os - the OutputStream where the encoding shall be written to
Throws:
IOException - if an I/O or encoding error occurs
See Also:
OCTET_STRING, SEQUENCE, SET, CON_SPEC, DerInputStream

encodeTo

protected static void encodeTo(ASN1Object object,
                               OutputStream os,
                               boolean implicitlyTagged)
                        throws IOException
The internal method additionally allows to specifiy whether the supplied ASN1Object has to be implicitly tagged. If implicit tagging shall be used, the tag and length of the underlying ASN.1 object are not encoded.
Parameters:
object - the ASN1Object to be DER encoded
os - the OutputStream where the encoding shall be written to
implicitlyTagged - whether to enforce implicit tagging or not
Throws:
IOException - if an I/O or encoding error occurs

encode

public static byte[] encode(ASN1Object object)
DER encodes the given ASN.1 object and returns the coding as a byte array. To facilitate length determination, the encoding algorithm encodes the values in tail recursive order, starting from the last lower level object. For each object - when encoding a structured type, any number of objects may be included - first the inherent value is written to a temporary stream in reverse order. The number of bytes actually written gives the length octet(s) which is(are) written to the temporary stream just behind the content bytes. Finally the identifier octet is written and the stream data is "turned around" to give the right order before returning it as a byte array. Because whole the encoding is done in memory a lot of memory will be needed for encoding large objects. For that reason, the encodeTo method shall be used for encoding large ASN.1 objects.

For enforcing indefinite length encoding, enable the indefiniteLength parameter by means of the setIndefiniteLength method of the ASN1Object class.

Parameters:
object - the ASN1Object to be DER encoded
Returns:
the DER encoded version of the ASN.1 object as byte array
See Also:
ASN1Object

decode

public static ASN1Object decode(byte[] coding)
                         throws CodingException
Creates an ASN.1 object from the DER encoded version. The DER encoded ASN.1 object has to be supplied as a byte array. This method decodes the given encoding and returns the recovered ASN.1 object.
Parameters:
coding - the array containing the DER encoded ASN.1 object
Returns:
the ASN1Object created from the DER encoded ASN.1 object, derived from the given byte array
Throws:
CodingException - if there is an error while decoding
See Also:
ASN1Object

decode

public static ASN1Object decode(InputStream is)
                         throws CodingException,
                                IOException
Creates an ASN.1 object from the DER encoded version. The DER encoded ASN.1 object has to be supplied from an InputStream. This method decodes the given encoding and returns the recovered ASN.1 object. This method is able to decode any arbitrary ASN.1 structure, given in its DER encoded format. However, since whole the decoding is performed within the memory, this method may not be suitable for decoding very large ASN.1 object. An application may use the DerInputStream utility for decoding large ASN.1 objects. However, when using the DerInputStream class, the structure of the DER encoded ASN.1 object to be encoded has to be known in advance.
Parameters:
is - the InputStream with the DER encoded ASN.1 object
Returns:
the ASN1Object created from the DER encoded ASN.1 object, derived from the given input stream
Throws:
CodingException - if there occurs an error while decoding
IOException - if there is an error with the InputStream
See Also:
ASN1Object, DerInputStream

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