2016-05-05 10 views
4

Я новичок в работе с закодированными потоками ASN.1, и мне трудно найти бесплатный компилятор и декодер класса, желательно для Java.Opensource Java ASN.1 декодер, который работает с автоматическими тегами

У меня есть кодированная шестнадцатеричная строка:

String test("30820274800200a2810105820410300c3d830401bb0afc84... 

Вот пример обозначения:

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 
} 

Я начал использовать JAC: https://sourceforge.net/projects/jac-asn1/ Но он не поддерживает автоматические метки.

Я следующий пробовал jASN1: https://www.openmuc.org/asn1/ Он не говорит, поддерживает ли он автоматические метки или нет. Кажется, что компиляция Обозначения без жалобы, но я не могу заставить ее правильно декодировать, и похоже, что пометка неверна.

Если мы возьмем начало закодированной строки: 82 02 30 74 80 02 00 a2 ... Это мое понимание:

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 

Но если закодировать тест "IntersectionSituationData" Я получаю следующее: 30 81 8a 0a 02 00 a2 т. е. тип «x0a» == 10, который является ASN.1 Universal ENUMERATED. Это имеет смысл, глядя на его уведомление, но я предполагаю, что автоматические теги игнорируются jASN1. Когда я смотрю на сгенерированные классы Java мы видим SemiDialogID расширяет BerEnum, который использует универсальный CLAs идентификатор:

// 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); 

Есть ли что-то мне нужно сделать, чтобы получить jASN1 работать с автоматическими тегами или мне нужно сделать другую библиотеку? ЕСЛИ последнее, что люди рекомендуют? В идеале я ищу Java-решение с открытым исходным кодом, которое прост в использовании. Думаю, я мог бы решить проблему с решением C и использовать JNI, чтобы заставить его работать.

ответ

1

Вот очень грязный хак, чтобы заставить JASN1 работать с автоматическими тегами. Это не общее решение и занимает много времени, чтобы вручную редактировать все сгенерированные классы, поэтому я все еще ищу полное решение.

Внутри сгенерированных классов для различных последовательностей в методе:

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

Вы увидите код, как это, который является проверка тегов/идентификатор:

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."); 
    } 

Исключение брошено потому что идентификаторы не совпадают. Сгенерированный класс обычно ожидает класс ASN Universal, причем номер тега является одним из универсальных типов или что-то вроде построенной последовательности. Вы можете быстро увидеть различие распечатав декодированного идентификатора и ожидаемый идентификатора:

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

Поэтому вы можете затем заставить ожидаемый идентификатор, чтобы быть правильными для автоматических тегов, установка класса быть CONTEXT_CLASS, и окончательным целое число, число тегов, т быть индексом поля в следующей последовательности:

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 

некоторых предостережения: в большом протоколе это займет много времени, чтобы пройти через все соответствующие шаги декодирования. Это подвержено ошибкам.Изменение протокола требует восстановления классов и слияния изменений, которые будут болезненными. Ни одно из вышеперечисленных вопросов не связано с кодированием. Я не полностью тестировал все, но я верю, что это единственные изменения.

Да, пожалуйста, продолжайте размещать какие-либо предложения, но я надеюсь, что вышеуказанное полезно для тех, кто действительно застрял и нуждается в быстром взломе.

1

С версии 1.6.0 jASN1 поддерживает автоматическую маркировку.