public final class DerCoder
extends java.lang.Object
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 application has to
decide whether to write/read the encoding to/from a byte array or to/from a
stream.
public static byte[] encode(ASN1Object
object)
Since this method performs whole the DER encoding within the memory, it shall not be used for the encoding of very large ASN.1 structures.
The second encoding method performs the encoding in the right order and writes the encoding immediately to an output stream:
public static void
encodeTo(ASN1Object object, OutputStream os)
This method shall be used for encoding large ASN.1 structures. Since this method writes the encoded data to the stream immediately as it is encoded, the length of the encoding result is not known in advance, and therefore the indefinite length encoding method has to be used:
0x04 <length> <data>Consider, for example the five data bytes
0x01 0xAB 0x23 0x7F 0xCA and their primitive definite encoding
to:
0x04 0x05 0x01 0xAB 0x23 0x7F 0xCA
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!
0x24 0x80
0x04 0x02 0x01 0xAB
0x04 0x02 0x23 0x7F
0x04 0x01 0xCA
0x00 0x00
encode or the encodeTo method
may be used, depending on whether the encoding shall be written to byte array
or to an output stream. The second (indefinite primitive) octet string
encoding method only can be realized when using the encodeTo
method. 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 indefinite 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");
Note that, of course, also the encode method may be used for
encoding structured ASN.1 objects like sequences or sets with the indefinite
length encoding variant. However, for indefinite constructed encoding an octet
string, the encodeTo method has to be used.
DerInputStream decoding utility.ASN1Object,
DerInputStream| Modifier and Type | Method and Description |
|---|---|
static ASN1Object |
decode(byte[] coding)
Creates an ASN.1 object from the DER encoded version.
|
static ASN1Object |
decode(byte[] coding,
boolean ensureDER)
Creates an ASN.1 object from the DER encoded version.
|
static ASN1Object |
decode(java.io.InputStream is)
Creates an ASN.1 object from the DER encoded version.
|
static ASN1Object |
decode(java.io.InputStream is,
boolean ensureDER)
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,
java.io.OutputStream os)
Encodes the given ASN1Object and writes the coding directly to the
specified OutputStream.
|
protected static void |
encodeTo(ASN1Object object,
java.io.OutputStream os,
boolean implicitlyTagged)
The internal method additionally allows to specify whether the supplied
ASN1Object has to be implicitly tagged.
|
public static void encodeTo(ASN1Object object, java.io.OutputStream os) throws java.io.IOException
Indefinite length encoding works this way:
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!
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 indefinite 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.
object - the ASN1Object to be DER encodedos - the OutputStream where the encoding shall be written tojava.io.IOException - if an I/O or encoding error occursOCTET_STRING,
SEQUENCE,
SET,
CON_SPEC,
DerInputStreamprotected static void encodeTo(ASN1Object object, java.io.OutputStream os, boolean implicitlyTagged) throws java.io.IOException
object - the ASN1Object to be DER encodedos - the OutputStream where the encoding shall be written toimplicitlyTagged - whether to enforce implicit tagging or not; only can be true if
the supplied ASN1Object belongs to a CON_SPECjava.io.IOException - if an I/O or encoding error occurspublic static byte[] encode(ASN1Object object)
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.
object - the ASN1Object to be DER encodedASN1Objectpublic static ASN1Object decode(byte[] coding) throws CodingException
coding - the array containing the DER encoded ASN.1 objectCodingException - if there is an error while decodingASN1Objectpublic static ASN1Object decode(byte[] coding, boolean ensureDER) throws CodingException
If ensureDER is set to true the encoding is
checked for compliance with the Distinguished Encoding Rules (DER)
according to ITU-T Rec. X.690 (07/2002), sections 10 and 11.
Setting ensureDER to true may be done only if absolutely
required since checking for DER compliance will cost both, performance
and memory.
coding - the array containing the DER encoded ASN.1 objectensureDER - whether to check the encoding against
the Distinguished Encoding Rules (DER) or
to accept BER encoding, tooCodingException - if there is an error while decodingASN1Objectpublic static ASN1Object decode(java.io.InputStream is) throws CodingException, java.io.IOException
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.is - the InputStream with the DER encoded ASN.1 objectCodingException - if there occurs an error while decodingjava.io.IOException - if there is an error with the InputStreamASN1Object,
DerInputStreampublic static ASN1Object decode(java.io.InputStream is, boolean ensureDER) throws CodingException, java.io.IOException
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.
If ensureDER is set to true the encoding is
checked for compliance with the Distinguished Encoding Rules (DER)
according to ITU-T Rec. X.690 (07/2002), sections 10 and 11.
Setting ensureDER to true may be done only if absolutely
required since checking for DER compliance will cost both, performance
and memory.
is - the InputStream with the DER encoded ASN.1 objectensureDER - whether to check the encoding against
the Distinguished Encoding Rules (DER) or
to accept BER encoding, tooCodingException - if there occurs an error while decodingjava.io.IOException - if there is an error with the InputStreamASN1Object,
DerInputStream