Mudanças entre as edições de "Compilador ASN1"
Linha 47: | Linha 47: | ||
A nova API foi denominada ASN1++, e pode ser obtida em: | A nova API foi denominada ASN1++, e pode ser obtida em: | ||
* [http://tele.sj.ifsc.edu.br/~msobral/ptc/asn1++.tgz API ASN1++] | * [http://tele.sj.ifsc.edu.br/~msobral/ptc/asn1++.tgz API ASN1++] | ||
+ | |||
A API é composta destes arquivos: | A API é composta destes arquivos: | ||
Linha 55: | Linha 56: | ||
− | Para utilizá-la basta copiar todos os arquivos nela contidos para o mesmo diretório onde está sua especificação ASN1. Caso deseje usar os scripts de compilação, | + | Para utilizá-la basta copiar todos os arquivos nela contidos para o mesmo diretório onde está sua especificação ASN1. Caso deseje usar os scripts de compilação, edite ''Makefile.build'' e modifique-o conforme ali indicado. |
+ | |||
+ | |||
+ | A API ASN1++ contém as seguintes classes e classes template: | ||
+ | * '''ASN1DataType<T>''': classe para auxiliar o uso do tipo de dados ASN1 definido pelo usuário. Definida como template para suportar qualquer tipo de dados | ||
+ | * '''ASN1String''': classe para auxiliar o acesso, conversão e modificação de strings ASN1 | ||
+ | * '''ASN1BitString''': classe para auxiliar o uso de BIT STRING | ||
+ | * '''ASN1Oid''': classe para auxiliar o acesso e modificação de OBJECT IDENTIFIER | ||
+ | * '''ASN1RelativeOid''': classe para auxiliar o acesso e modificação de RELATIVE OID (um caso especial de OID). Tem mesmas operações que ASN1Oid. | ||
+ | * '''ASN1Sequence<T>''': classe para facilitar o uso de sequências ASN1 (SEQUENCE OF e SET OF). Definida como template pois o tipo do dado contido em sequências é genérico | ||
+ | * '''ASN1DERSerializer<T>''': codificador DER. Codifica estruturas de dados e grava o resultado em um stream (ex: ofstream ou ostringstream) | ||
+ | * '''ASN1XERSerializer<T>''': codificador XER. Codifica estruturas de dados e grava o resultado em um stream (ex: ofstream ou ostringstream) | ||
+ | * '''ASN1DERDeserializer<T>''': decodificador DER. Decodifica octetos lidos de um stream (ex: ifstream ou istringstream) e gera uma estrutura de dados. | ||
+ | * '''ASN1XERDeserializer<T>''': decodificador XER. Decodifica octetos lidos de um stream (ex: ifstream ou istringstream) e gera uma estrutura de dados. | ||
+ | |||
=== Guia rápido para a biblioteca de codificação === | === Guia rápido para a biblioteca de codificação === |
Edição das 15h46min de 29 de setembro de 2015
O compilador ASN1 desenvolvido por Lev Walkin traduz as especificações ASN1 para linguagem C, além de prover uma biblioteca para codificação e decodificação. Ele é compatível com ASN.1 rev. 2002. Há duas formas de utilizá-lo:
- Obtendo seu código-fonte, e realizando sua compilação e instalação
- Acessando sua versão online
O resultado da compilação ASN1 é um conjunto de arquivos em código-fonte C, contendo a definição dos tipos de dados criados com ASN1 e as funções auxiliares para usar esses tipos de dados e realizar codificação e decodificação. Por exemplo, ao compilar esta especificação ASN1:
Exemplo DEFINITIONS ::=
BEGIN
Mensagem ::= SEQUENCE {
id VisibleString,
cod INTEGER,
oid OBJECT IDENTIFIER
}
END
... são gerados estes arquivos:
asn_application.h +Compiler.Log Mensagem.h per_opentype.c
asn_codecs.h constraints.c module.asn1 per_opentype.h
asn_codecs_prim.c constraints.h NativeEnumerated.c per_support.c
asn_codecs_prim.h constr_SEQUENCE.c NativeEnumerated.h per_support.h
asn_internal.h constr_SEQUENCE.h NativeInteger.c VisibleString.c
asn_system.h constr_TYPE.c NativeInteger.h VisibleString.h
ber_decoder.c constr_TYPE.h OBJECT_IDENTIFIER.c xer_decoder.c
ber_decoder.h converter-sample.c OBJECT_IDENTIFIER.h xer_decoder.h
ber_tlv_length.c der_encoder.c OCTET_STRING.c xer_encoder.c
ber_tlv_length.h der_encoder.h OCTET_STRING.h xer_encoder.h
ber_tlv_tag.c INTEGER.c per_decoder.c xer_support.c
ber_tlv_tag.h INTEGER.h per_decoder.h xer_support.h
BIT_STRING.c Makefile.am.sample per_encoder.c
BIT_STRING.h Mensagem.c per_encoder.h
Dentre eles, os arquivos Mensagem.c e Mensagem.h contêm as declarações correspondentes à estrutura de dados Mensagem. Os demais arquivos incluem funções e declarações para o uso, codificação e decodificação de estruturas de dados especificadas via ASN1. Portanto, além de compilar uma especificação, é gerada uma API para usar as estruturas de dados criadas.
A API nativa gerada pelo compilador pode ser usada diretamente, porém ela apresenta limitações quanto ao uso dos tipos de dados básicos ASN1. Alguns tipos de dados, tais como OCTET STRING e suas variações, OBJECT IDENTIFIER e RELATIVE-OID, não estão acompanhados de funções na API para manipulá-los de forma prática. Em alguns casos é necessário criar algoritmos para acessar a estrutura interna desses tipos de dados, o que se torna repetitivo ao usá-los em programas e sujeito a erros. Além disso, as operações de codificação e decodificação também demandam uma quantidade razoável de código-fonte extra a ser escrito para poderem ser usadas. Por isso essa API gerada pelo compilador foi encapsulada em uma outra API C++, que oferece um conjunto de classes para sanar essas limitações.
API ASN1++
A nova API foi denominada ASN1++, e pode ser obtida em:
A API é composta destes arquivos:
- asn1++.h: declarações das classes que compõem a API.
- asn1++-impl.h: implementação dos métodos das classes
- Makefile: script de compilação para ajudar a compilação de um projeto ASN1. Possibilita compilar a especificação ASN1 e também o projeto
- Makefile.build: script de compilação auxiliar
Para utilizá-la basta copiar todos os arquivos nela contidos para o mesmo diretório onde está sua especificação ASN1. Caso deseje usar os scripts de compilação, edite Makefile.build e modifique-o conforme ali indicado.
A API ASN1++ contém as seguintes classes e classes template:
- ASN1DataType<T>: classe para auxiliar o uso do tipo de dados ASN1 definido pelo usuário. Definida como template para suportar qualquer tipo de dados
- ASN1String: classe para auxiliar o acesso, conversão e modificação de strings ASN1
- ASN1BitString: classe para auxiliar o uso de BIT STRING
- ASN1Oid: classe para auxiliar o acesso e modificação de OBJECT IDENTIFIER
- ASN1RelativeOid: classe para auxiliar o acesso e modificação de RELATIVE OID (um caso especial de OID). Tem mesmas operações que ASN1Oid.
- ASN1Sequence<T>: classe para facilitar o uso de sequências ASN1 (SEQUENCE OF e SET OF). Definida como template pois o tipo do dado contido em sequências é genérico
- ASN1DERSerializer<T>: codificador DER. Codifica estruturas de dados e grava o resultado em um stream (ex: ofstream ou ostringstream)
- ASN1XERSerializer<T>: codificador XER. Codifica estruturas de dados e grava o resultado em um stream (ex: ofstream ou ostringstream)
- ASN1DERDeserializer<T>: decodificador DER. Decodifica octetos lidos de um stream (ex: ifstream ou istringstream) e gera uma estrutura de dados.
- ASN1XERDeserializer<T>: decodificador XER. Decodifica octetos lidos de um stream (ex: ifstream ou istringstream) e gera uma estrutura de dados.
Guia rápido para a biblioteca de codificação
- Acesso a membros do tipo INTEGER e BOOLEAN: basta referenciá-los diretamente, como neste exemplo aplicado à estrutura de dados Ativo:
Ativo_t * pkt = (Ativo_t*)malloc(sizeof(Ativo_t)); pkt->codigo = 555;
- Conversão de string C para OCTET STRING:
int OCTET_STRING_fromString(OCTET_STRING_t *s, const char *str);
- Conversão de OCTET STRING para string C:
// "ptr" é do tipo OCTET_STRING_t * // "data" é do tipo char*, e deve ter capacidade >= ptr->size+1 memcpy(data, ptr->buf, ptr->size); data[ptr->size] = 0;
Para membros da estrutura de dados que forem SET OF ou SEQUENCE OF (i.e. listas de valores), usa-se esta definição de estrutura de dados como exemplo:
ASN.1 | Linguagem C |
---|---|
Ativo ::= SEQUENCE {
nome PrintableString (SIZE(1..16)),
codigo INTEGER,
valor SET OF INTEGER
}
|
/* Ativo */
typedef struct Ativo {
PrintableString_t nome;
long codigo;
struct valor {
A_SET_OF(long) list;
/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
} valor;
/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
} Ativo_t;
|
- Anexar um valor a uma SEQUENCE OF ou SET OF:
// "pkt" é do tipo Ativo_t* int * p; p = (int*)malloc(sizeof(int)); asn_set_add(&pkt->valor, p);
- Remover um valor de uma SEQUENCE OF ou SET OF:
// remove o valor na posição "0" da sequência // "valor" da estrutura de dados Ativo_t apontada por "pkt" // o último parâmetro informa se memória do dado removido deve ser liberada (0=não, 1=sim) asn_set_del(&pkt->valor, 0, 0);
- Esvazia uma SEQUENCE OF ou SET OF:
// remove todos os dados da sequência "valor" // liberando suas áreas de memória asn_set_empty(&pkt->valor);
- Acesso a um dado de uma SEQUENCE OF ou SET OF:
// n: posição acessada no vetor interno de dados da sequência // k: posição lógica do dado acessado (equivalente à usada em asn_set_del) int n, k; for (n=0, k=0; (k < pkt->valor.list.count) && (n < pkt->valor.list.size);) { if (pkt->valor.list.array[n] != NULL) { long * number = pkt->valor.list.array[n]; printf("valor[%d]=%d\n", k, *number); k++; } }
- Codificar com BER
- Codificar com DER
- Codificar com PER
- Codificar com XER