2016-05-05 36 views
4

Ich bin neu in der Arbeit mit ASN.1 kodierten Streams und es fällt mir schwer einen freien Klassencompiler und -decoder zu finden, vorzugsweise für Java.Opensource Java ASN.1 Decoder, der mit automatischen Tags arbeitet

Ich habe einen codierten Hex-String:

String test("30820274800200a2810105820410300c3d830401bb0afc84... 

Hier ist ein Beispiel für die Notation:

SEMI DEFINITIONS AUTOMATIC TAGS ::= BEGIN 

IntersectionSituationData ::= SEQUENCE { 
    dialogID  SemiDialogID,     -- 0xA2  
    seqID   SemiSequenceID,     -- 0x05 Data 
    groupID   GroupID,       
    -- Some more members 
} 

SemiDialogID ::= ENUMERATED { 
    intersectionSitDataDep  (162), -- 0xA2 
    -- additional DialogIDs 
} 
SemiSequenceID ::= ENUMERATED { 
    data    (5), -- Data 
    -- additional SeqIDs 
} 

Ich begann JAC mit: https://sourceforge.net/projects/jac-asn1/ Aber es spielt keine automatische Tags unterstützen.

Ich versuchte als nächstes jASN1: https://www.openmuc.org/asn1/ Es sagt nicht, ob es automatische Tags unterstützt oder nicht. Es scheint, die Notation ohne Beschwerde zu kompilieren, aber ich kann es nicht richtig dekodieren und es sieht aus wie die Markierung, wenn falsch.

Wenn wir den Beginn des kodierten String nehmen: 82 02 74 30 80 02 00 a2 ... Das ist mein Verständnis:

30 = Sequence 
82 = Length encoded in 2 octets 
02 74 = Length = 2x256 + 7x16 +4 == 638 bytes, correct 
80 ?? is this a result of automatic encoding? x80= 128= 8th bit set = context-specific class, number 0? 
02 = length of value is 2 octets 
00 a2 is value == xA2 as expected from SemiDialogID 

Aber wenn ich einen Test von "IntersectionSituationData" kodieren ich das Folgende: 30 81 8a 0a 02 00 a2 dh der Typ ist 'x0a' == 10 das ist ASN.1 Universal ENUMERATED. Das macht Sinn, wenn man auf die Benachrichtigung schaut, aber ich vermute, dass automatische Tags von jASN1 ignoriert werden. Wenn ich die generierten Java-Klassen betrachten, sehen wir SemiDialogID BerEnum erstreckt, die Universal-cla Kennung verwendet:

// SemiDialogID.java 
public class SemiDialogID extends BerEnum { 
    ... 
} 

//BerEnum.java 
public class BerEnum extends BerInteger { 

    public final static BerIdentifier identifier = new BerIdentifier(BerIdentifier.UNIVERSAL_CLASS, 
     BerIdentifier.PRIMITIVE, BerIdentifier.ENUMERATED_TAG); 

Gibt es etwas, was ich tun müssen, um bekommen jASN1 mit automatischer Tags zu arbeiten oder muss ich eine andere Bibliothek? Wenn Letzteres, was empfehlen die Leute? Idealerweise suche ich nach einer Open-Source-Java-Lösung, die einfach zu bedienen ist. Ich denke, ich könnte mit einer C-Lösung auskommen und JNI verwenden, um es zum Laufen zu bringen.

Antwort

1

Hier ist ein sehr schmutziger Hack, um jASN1 mit automatischen Tags zu arbeiten. Dies ist keine allgemeine Lösung und benötigt viel Zeit, um alle generierten Klassen manuell zu bearbeiten. Daher suche ich immer noch nach einer vollständigen Lösung.

Innerhalb der generierten Klassen für die verschiedenen Sequenzen in dem Verfahren:

public int decode(InputStream is, boolean explicit) throws IOException { 

Sie werden einige Code wie folgt sehen, die den Tag/Kennung überprüft:

if (berIdentifier.equals(MsgCount.identifier)) { 
     msgCnt = new MsgCount(); 
     subCodeLength += msgCnt.decode(is, false); 
     subCodeLength += berIdentifier.decode(is); 
    } 
    else { 
     throw new IOException("Identifier does not match the mandatory sequence element identifer."); 
    } 

Die Ausnahme ausgelöst wird weil die Bezeichner nicht übereinstimmen. Die generierte Klasse erwartet normalerweise eine universelle ASN-Klasse, wobei die Tag-Nummer einer der universellen Typen oder etwas wie eine konstruierte Sequenz ist. Sie können schnell die Unterschiede sehen durch den entschlüsselten Kennung Ausdrucken und die erwartete Kennung:

System.out.println("Decoded: " + berIdentifier + ", expected: " + MsgCount.identifier); 

Sie können also dann die erwartete Kennung erzwingen korrekt für die automatischen Tags zu sein, die Klasse Einstellung CONTEXT_CLASS und die letzte zu sein integer, kann die Tag-Nummer, t der Index des Feldes in der Reihenfolge:

BerIdentifier identifier2 = new BerIdentifier(BerIdentifier.CONTEXT_CLASS, BerIdentifier.PRIMITIVE, 2); // Hardcode the true idenifier 
if (berIdentifier.equals(identifier2)) { // Check the decoded identifier matches our hard-coded value, instead of the generated 
     msgCnt = new MsgCount(); 
     ... // Carry on as before 

Einige Einschränkungen: in einem großen Protokoll es viel Zeit in Anspruch nehmen, durch alle relevanten dekodieren Schritte zu gehen. Dies ist fehleranfällig.Eine Änderung des Protokolls erfordert das erneute Generieren der Klassen und das Zusammenführen von Änderungen, was schmerzhaft sein wird. Keines der obigen befasst sich mit der Codierung. Ich habe noch nicht alles vollständig getestet, aber ich glaube, dass dies die einzigen Änderungen sind, die erforderlich sind.

Also ja, bitte posten Sie keine Vorschläge, aber ich hoffe, das obige ist nützlich für jeden, der wirklich feststeckt und einen schnellen Hack braucht.

1

Seit Version 1.6.0 unterstützt jASN1 automatisches Tagging.