Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I must be missing something really obvious here. I can decode this sample bit of data using online tools like http://asn1-playground.oss.com/ , but am having trouble with basic usage of Perl's Convert::ASN1. Any idea what I'm missing?

use strict;
use warnings;
use Convert::ASN1;
use feature 'say';
# example from:
# http://www.oss.com/asn1/resources/asn1-made-simple/introduction.html
my $hex_data = '3018800A4A6F686E20536D697468810A39383736353433323130';
my $bin_data = join '', pack 'H*', $hex_data;
Convert::ASN1::asn_dump($bin_data);
# prints:
#    0000   24: SEQUENCE {
#    0002   10:   [CONTEXT 0]
#    0004     :     4A 6F 68 6E 20 53 6D 69 74 68 __ __ __ __ __ __ John Smith
#    000E   10:   [CONTEXT 1]
#    0010     :     39 38 37 36 35 34 33 32 31 30 __ __ __ __ __ __ 9876543210
#    001A     : }    
my $asn = Convert::ASN1->new;
$asn->prepare(<<ASN1) or die $asn->error;    
    Contact ::= SEQUENCE {
        name VisibleString,
        phone NumericString
my $asn1_node = $asn->find('Contact') 
    or die $asn->error;
my $payload = $asn1_node->decode($bin_data) 
    or die "can't decode Contact: ".$asn1_node->error;
# prints:
#    can't decode Contact: decode error 80<=>1a 2 4 name

Supporting YaFred's answer below, this is where that 80 and 81 are in that encoded string:

SEQ length=24 ** l=10  J  o  h n   S m i t h  ** l=10  9 8 7 6 5 4 3 2 1 0
30  18        80 0A    4A 6F 686E20536D697468 81 0A    39383736353433323130

It's a bit long to explain if you start with ASN.1 ...

You are not giving the tagging context (the type Contact should be part of a module). So, the tools are making choices ...

The hexa you show is the result of encoding with AUTOMATIC TAGS

The tags of the 2 strings are '80' (Context tag 0 = 1000 0000) and '81' (Context tag 1 = 1000 0001)

@xxfelixxx gets something different because the encoding was performed as EXPLICIT TAGS

The tags of the 2 strings are '1a' (universal tag for VisibleString) and '12' (universal tag for NumericString)

That Perl module doesn't actually support those extra lines, but that's what was going on, yes. I'm going to update the question with some extra information showing where that 80 and 81 are in the string. – Kevin G. Mar 22, 2018 at 21:34 That's a pity. You can take your problem the other way around and surround your type with Module DEFINITIONS ::= BEGIN and END to make oss.com produce the encoding that your perl module should understand. – YaFred Mar 23, 2018 at 5:36

I'm not sure where you got your hex string from...but if you use the Convert::ASN1::encode method, you get a slightly different hex string which can get decoded correctly:

my $res = $asn->encode({ name => 'John Smith', phone => 9876543210 });
my $res_hex = unpack 'H*', $res;
print "res_hex after encode : $res_hex\n";
print "original hex_data    : " . lc($hex_data) . "\n";
print "\n";
my payload = $asn1_node->decode($res) or die $asn1_node->error;
use Data::Dumper;
print Dumper($payload);

output

res_hex after encode : 30181a0a4a6f686e20536d697468120a39383736353433323130
original hex_data    : 3018800a4a6f686e20536d697468810a39383736353433323130
$VAR1 = {
      'name' => 'John Smith',
      'phone' => '9876543210'
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.