How can you construct an implicitly tagged DERSet using BC?

View: New views
6 Messages — Rating Filter:   Alert me  

How can you construct an implicitly tagged DERSet using BC?

by Lothar Kimmeringer-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

public class DERSetTest {

    public final static void main(String[] args) throws Exception{
        ASN1EncodableVector vec = new ASN1EncodableVector();
        vec.add(new DERInteger(1));
        vec.add(new DERInteger(2));
        vec.add(new DERInteger(3));
        DERSet set = new DERSet(vec);
        DERTaggedObject tag = new DERTaggedObject(false, 1, set);

        byte[] encoded = tag.getDEREncoded();

        System.out.println(ASN1Dump.dumpAsString(new ASN1InputStream(encoded).readObject()));
    }
}

When executing I get

Tagged [1] IMPLICIT
    DER Sequence
        Integer(1)
        Integer(2)
        Integer(3)

Is it impossible to do this (then why is it used e.g. in X.228)
or is there something wrong with the encoding of such a structure?


Regards, Lothar


Re: How can you construct an implicitly tagged DERSet using BC?

by David Hook-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


The code is correct - it's more an issue of the way the dump class
works. Unfortunately (or fortunately depending on which side of the line
you're on) an implicitly tagged object doesn't represent a specific type
clearly as if it's a sequence or a set the object is tagged as
constructed, which is also used as the flag to indicate in BER/DER that
an object is explicitly tagged.

The BC dump command is able to guess that the object is implicit because
it is tagged as constructed and there is more than one element in it
(try an implicit set with a single object and you'll see what I mean).
It shows the type as sequence as a sequence is used as the carrying type
(the reasons for this date back quite a few years...) to hold the
elements until the real type can be resolved.

So the answer is that the dump command has to guess when it sees a
tagged object, so it guess's a sequence. I'll probably change this as it
can obviously be confusing if you're not familiar with what's going on,
but there will still be issues with constructed primitives with only one
member element - they'll almost never be distinguished properly
(explicitly tagged sets and sequences excepted), it's not possible to do
so unless you really know the context.

Or put another way, seeing a tag on an object in a BER/DER stream is
like seeing an indicator light flashing on a car - it means the globe is
working. Whether the driver turns or not is still for later discovery.
In the same way, without explicit knowledge of the ASN.1 structure being
parsed, a tagged object is just that...

Regards,

David

On Wed, 2009-10-21 at 17:06 +0200, Lothar Kimmeringer wrote:

> public class DERSetTest {
>
>     public final static void main(String[] args) throws Exception{
>         ASN1EncodableVector vec = new ASN1EncodableVector();
>         vec.add(new DERInteger(1));
>         vec.add(new DERInteger(2));
>         vec.add(new DERInteger(3));
>         DERSet set = new DERSet(vec);
>         DERTaggedObject tag = new DERTaggedObject(false, 1, set);
>
>         byte[] encoded = tag.getDEREncoded();
>
>         System.out.println(ASN1Dump.dumpAsString(new ASN1InputStream(encoded).readObject()));
>     }
> }
>
> When executing I get
>
> Tagged [1] IMPLICIT
>     DER Sequence
>         Integer(1)
>         Integer(2)
>         Integer(3)
>
> Is it impossible to do this (then why is it used e.g. in X.228)
> or is there something wrong with the encoding of such a structure?
>
>
> Regards, Lothar
>



Re: How can you construct an implicitly tagged DERSet using BC?

by Lothar Kimmeringer-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

David Hook schrieb:
> The code is correct - it's more an issue of the way the dump class
> works.

The problem isn't the Dump-class, my example with X.228 is not
coming by coincidence:

 PPDUDataElement te = new PPDUDataElement();

 te.setModeSelector(PPDUDataElement.MODE_SELECTOR_X410_1984);
 te.setProtocolVersion(1);
 ASN1EncodableVector vec = new ASN1EncodableVector();
 vec.add(new DERInteger(1));
 vec.add(new DERInteger(2));
 vec.add(new DERInteger(3));
 te.setReliableTransferElements(new DERSet(vec));
 DERTaggedObject tag;
 DEROctetString val = new DEROctetString("val1".getBytes("8859_1"));
 tag = new DERTaggedObject(false, 1, val);
 te.getElementParamters().add(tag);
 val = new DEROctetString("val2".getBytes("8859_1"));
 tag = new DERTaggedObject(false, 2, val);
 te.getElementParamters().add(tag);
 DERApplicationSpecific app = new DERApplicationSpecific(1, new DEROctetString("userdata".getBytes("8859_1")));
 te.setUserData(app);

 byte[] bytes = te.getBytes();
 assertNotNull("check existance of returned data", bytes);
 PPDUDataElementtest = new PPDUDataElement(te.getPpduType(), bytes);

getBytes() is defined more or less the way I was giving in my example,
the constructor is using ASN1InputStream (as used in my example) to
read DER-objects from that array.

ASN1Dump was just used by me after I got a ClassCastException in
that TestCase:

java.lang.ClassCastException: org.bouncycastle.asn1.DERSequence
        at mypkg.osi6presentation.command.PPDUDataElement.initValues(PPDUDataElement.java:254)
        at mypkg.osi6presentation.command.PPDUDataElement.<init>(PPDUDataElement.java:146)
        at mypkg.osi6presentation.command.__Test_PPDUDataElement$TestElement.<init>(__Test_PPDUDataElement.java:392)
        at mypkg.osi6presentation.command.__Test_PPDUDataElement.testGetBytes(__Test_PPDUDataElement.java:340)

> Unfortunately (or fortunately depending on which side of the line
> you're on) an implicitly tagged object doesn't represent a specific type
> clearly as if it's a sequence or a set the object is tagged as
> constructed, which is also used as the flag to indicate in BER/DER that
> an object is explicitly tagged.

So can I be sure that a DERSequence is returned? From a pragmatic
point of view I don't care very much what is returned as long as
I don't need to start instanceof-check cascades.


Regards, Lothar


Re: How can you construct an implicitly tagged DERSet using BC?

by David Hook-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


My guess is you're calling taggedObject.getObject().

You need to use ASN1Set.getInstance(taggedObject, explicit) with (in
this case) false - as I said, if an object is implicitly tagged it's
original type is lost, so the BC library assumes a sequence in the event
there are multiple objects until told otherwise. The getInstance methods
are provided to allow the original type to be restored.

Regards,

David

On Thu, 2009-10-22 at 14:31 +0200, Lothar Kimmeringer wrote:

> David Hook schrieb:
> > The code is correct - it's more an issue of the way the dump class
> > works.
>
> The problem isn't the Dump-class, my example with X.228 is not
> coming by coincidence:
>
>  PPDUDataElement te = new PPDUDataElement();
>
>  te.setModeSelector(PPDUDataElement.MODE_SELECTOR_X410_1984);
>  te.setProtocolVersion(1);
>  ASN1EncodableVector vec = new ASN1EncodableVector();
>  vec.add(new DERInteger(1));
>  vec.add(new DERInteger(2));
>  vec.add(new DERInteger(3));
>  te.setReliableTransferElements(new DERSet(vec));
>  DERTaggedObject tag;
>  DEROctetString val = new DEROctetString("val1".getBytes("8859_1"));
>  tag = new DERTaggedObject(false, 1, val);
>  te.getElementParamters().add(tag);
>  val = new DEROctetString("val2".getBytes("8859_1"));
>  tag = new DERTaggedObject(false, 2, val);
>  te.getElementParamters().add(tag);
>  DERApplicationSpecific app = new DERApplicationSpecific(1, new DEROctetString("userdata".getBytes("8859_1")));
>  te.setUserData(app);
>
>  byte[] bytes = te.getBytes();
>  assertNotNull("check existance of returned data", bytes);
>  PPDUDataElementtest = new PPDUDataElement(te.getPpduType(), bytes);
>
> getBytes() is defined more or less the way I was giving in my example,
> the constructor is using ASN1InputStream (as used in my example) to
> read DER-objects from that array.
>
> ASN1Dump was just used by me after I got a ClassCastException in
> that TestCase:
>
> java.lang.ClassCastException: org.bouncycastle.asn1.DERSequence
> at mypkg.osi6presentation.command.PPDUDataElement.initValues(PPDUDataElement.java:254)
> at mypkg.osi6presentation.command.PPDUDataElement.<init>(PPDUDataElement.java:146)
> at mypkg.osi6presentation.command.__Test_PPDUDataElement$TestElement.<init>(__Test_PPDUDataElement.java:392)
> at mypkg.osi6presentation.command.__Test_PPDUDataElement.testGetBytes(__Test_PPDUDataElement.java:340)
>
> > Unfortunately (or fortunately depending on which side of the line
> > you're on) an implicitly tagged object doesn't represent a specific type
> > clearly as if it's a sequence or a set the object is tagged as
> > constructed, which is also used as the flag to indicate in BER/DER that
> > an object is explicitly tagged.
>
> So can I be sure that a DERSequence is returned? From a pragmatic
> point of view I don't care very much what is returned as long as
> I don't need to start instanceof-check cascades.
>
>
> Regards, Lothar
>



Re: How can you construct an implicitly tagged DERSet using BC?

by Lothar Kimmeringer-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

David Hook schrieb:
> My guess is you're calling taggedObject.getObject().

That was the case.

> You need to use ASN1Set.getInstance(taggedObject, explicit) with (in
> this case) false

After writing the mail to the list I was going into the source
of that class and found that method already. This now works,
thank you for the confirmation, that I am rigth this time ;-)

I sent you an email with a patch containing classes for the ASN.1-
type External. Have you had the time to have a look into that? I'm
currently working no reading in data that contains this time and
with the current version of BC I get IOExceptions when trying to
read that in.


Best regards, Lothar


Re: How can you construct an implicitly tagged DERSet using BC?

by David Hook-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Yes, I've put a beta up with it in it. I emailed you on the 15th of
October. It's in the betas area.

I've resent the emails.

Regards,

David

On Mon, 2009-10-26 at 02:15 +0100, Lothar Kimmeringer wrote:

> David Hook schrieb:
> > My guess is you're calling taggedObject.getObject().
>
> That was the case.
>
> > You need to use ASN1Set.getInstance(taggedObject, explicit) with (in
> > this case) false
>
> After writing the mail to the list I was going into the source
> of that class and found that method already. This now works,
> thank you for the confirmation, that I am rigth this time ;-)
>
> I sent you an email with a patch containing classes for the ASN.1-
> type External. Have you had the time to have a look into that? I'm
> currently working no reading in data that contains this time and
> with the current version of BC I get IOExceptions when trying to
> read that in.
>
>
> Best regards, Lothar
>