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 0x00Of 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 0x00Of 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 0x00The 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
,
DerInputStream
protected 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 encodedASN1Object
public static ASN1Object decode(byte[] coding) throws CodingException
coding
- the array containing the DER encoded ASN.1 objectCodingException
- if there is an error while decodingASN1Object
public 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 decodingASN1Object
public 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
,
DerInputStream
public 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