Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert BER result to JSON #42

Closed
ashkank83 opened this issue Jul 22, 2020 · 6 comments
Closed

Convert BER result to JSON #42

ashkank83 opened this issue Jul 22, 2020 · 6 comments
Labels
feedback needed More feedback is needed in order to solve.

Comments

@ashkank83
Copy link

Hi,
I'm trying to use your library for converting TAP files and have the result as JSON.using the example below I can convert the file however I can't find anyway to convert the whole object into JSON. Is there anyway to convert the result to JSON?
Below is my sample code (nodeJS):

"use strict";
var fs = require("fs");

var ASN1 = require("@lapo/asn1js");

var data = fs.readFileSync("/sampleTAP");
//console.log(data);

var obj = ASN1.decode(data, 0);
console.log(obj);
//console.log(obj.sub[0].sub[0]);

and below is what I see in the logs:

ASN1 {
  stream: Stream {
    enc: <Buffer 61 83 01 31 e4 64 81 8b 5f 81 44 05 44 4e 4b 54 44 5f 81 36 05 32 53 50 35 30 5f 6d 05 32 38 39 33 30 7f 6c 19 50 0e 32 30 32 30 30 35 31 35 32 33 35 ... 78263 more bytes>,
    pos: 8
  },
  header: 4,
  length: 5,
  tag: ASN1Tag { tagClass: 1, tagConstructed: false, tagNumber: 196 },
  tagLen: 3,
  sub: null
}
@lapo-luchini lapo-luchini added the feedback needed More feedback is needed in order to solve. label Jul 22, 2020
@lapo-luchini
Copy link
Owner

Hi, it all depends on what type of JSON you expect to produce, there isn't a standard way to represent ASN.1 data as JSON.
(okay well there is/will be JER, but I don't think we're talking about that?)

Example given:

const ASN1 = require('./asn1');
const ber = Buffer.from('23800303000A3B230A0302005F030404291CD00000', 'hex');
console.log(ASN1.decode(ber).toPrettyString());

produces this output:

BIT_STRING @0-19 (constructed): (44 bit)|00001010001110110101111100101001000111001101
  BIT_STRING @2+3: (16 bit)|0000101000111011
  BIT_STRING @7+10 (constructed): (28 bit)|0101111100101001000111001101
    BIT_STRING @9+2: (8 bit)|01011111
    BIT_STRING @13+4: (20 bit)|00101001000111001101

and you could imagine producing a JSON like this:

{
  "type": "BIT_STRING",
  "length": 19,
  "constructed": true,
  "content": "00001010001110110101111100101001000111001101",
  "parts": [
    {
      "type": "BIT_STRING",
      "length": 5,
      "content": "0000101000111011",
    },
    {
      "type": "BIT_STRING",
      "length": 17,
      "constructed": true,
      "content": "0101111100101001000111001101",
      "parts": [
        {
          "type": "BIT_STRING",
          "length": 11,
          "content": "01011111"
        },
        {
          "type": "BIT_STRING",
          "length": 21,
          "content": "00101001000111001101"
        }
      ]
    }
  ]
}

But you could desire many other possible formats.

Consider that ASN.1 value by them selves have no "meaning", only structure, and the meaning (i.e. names associated to values) are defined by ASN.1 specifications such as the one you're linking (and you could try to get some JSON with proper names such as {"batchControlInfo": {"sender":…,"recipient":…}}) then unfortunately you need a validating parser for that, and (right now) this isn't (see #13 regarding that).

@ashkank83
Copy link
Author

Hi,
Thanks for your answer and sorry for my late reply. I understand a parser is not available however what I'm thinking is much simpler and looks like you already have something similar available. See below a copy & paste from your website where I decoded a sample file:

ASN.1 JavaScript decoder
Application 1 (5 elem)
  Application 4 (9 elem)
    Application 196 (5 byte) BBKTD
    Application 182 (5 byte) 2SP50
    Application 109 (5 byte) 33353
    Application 108 (2 elem)
      Application 16 (14 byte) 20201105005515
      Application 231 (5 byte) +0100

Is there a way to have this same result in json where it looks like:

{
          "1": {
              "4" : {
                  "196" : "BBKTD",
                  "182" : "2SP50",
                  "109" : 33353,
                  "108" : {
                      "16" : 20201105005515,
                      "231" : "+0100"
                  }
              }
          }
      }
}

@lapo-luchini
Copy link
Owner

In your example all the elements use a different custom application number but there could be in principle be more elements with the same application number and in that case the format you propose wouldn't be able to represent it.

All in all, it seems a very custom format that you can derive yourself from the current library's output, perhaps something like this? (I added an array to allow having multiple tags with the same number, but of course the order of element appearance is still lost)

const ASN1 = require('@lapo/asn1js');
const ber = Buffer.from('3082017F30820131A00302010202147C8E6449D70ED92D3E2E4A5D2F76F6554246D746300506032B65703035310B3009060355040613024954310F300D06035504070C064D696C616E6F3115301306035504030C0C546573742065643235353139301E170D3230303930323133323532365A170D3330303930323133323532365A3035310B3009060355040613024954310F300D06035504070C064D696C616E6F3115301306035504030C0C546573742065643235353139302A300506032B65700321003BA92FFDCB1766DE40A292F793DE30F80A23A831215DD007D863242EFF682185A3533051301D0603551D0E041604146BA5BDCF9DFA235978126417AE1E72D89A804AE8301F0603551D230418301680146BA5BDCF9DFA235978126417AE1E72D89A804AE8300F0603551D130101FF040530030101FF300506032B65700341006F7377BE28965A3336D7E534FD90F3FD407F1F02F90057F2160F166B04BF6584B698D2D0D2BF4CD66F0EB6E2E89D04A3E09950F9C26DDE73AD1D355785658606', 'hex');
function customJSON(asn1) {
    if (asn1.sub == null)
        return asn1.content();
    const x = {};
    for (const el of asn1.sub) {
        const key = el.tag.tagNumber;
        (x[key] = x[key] || []).push(customJSON(el));
    }
    return x;
}
console.log('Custom JSON:', JSON.stringify(customJSON(ASN1.decode(ber)), null, 2));

@ashkank83
Copy link
Author

Thank you very much, this is working like a charm :-) I just had to modify Stream.prototype.parseOctetString so it won't return the byte length (len byte).

@lapo-luchini
Copy link
Owner

BTW: I plan to add a new method similar to content() but more machine-oriented.
(e.g. maybe a short object description of content, instead of a human-oriented string)

@ashkank83
Copy link
Author

I think that'll be perfect. for example I'm storing the decoded data in MongoDB and I believe something like what you mentioned would help a lot. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feedback needed More feedback is needed in order to solve.
Projects
None yet
Development

No branches or pull requests

2 participants