ASN.1

por David Esmerodes Fraguas, Eva Marcos Doldán, Oscar Pérez Piñeiro, Diana María Piñeiro Iglesias e Marina Rodríguez Iglesias / Junio'98


  1. INTRODUCCIÓN

 

1.1) PRESENTACIÓN.

 

Uno de los problemas fundamentales que aparecen en la comunicación entre usuarios es el traslado eficaz de los datos, es decir, que los datos que se reciban son los que se han enviado (Integridad). El problema de cómo comunicar dos sistemas diferentes es similar al problema que se presenta entre dos personas a la hora de comunicarse, siendo por ejemplo una inglesa y la otra de nacionalidad alemana (inglés vs alemán). Ilustremos este comentario con un ejemplo :

 

FIGURA 1

 

Supongamos dos máquinas que usan diferentes sistemas e incluso lenguajes de programación diferentes. La máquina A usa el lenguaje de programación Pascal y la máquina B utiliza C. Si queremos trasladar información desde la máquina A a la B, necesitamos: o bien, que la máquina B entienda código en Pascal o bien que la máquina A genere una traducción de su código en Pascal a código C. Imaginemos ahora que en lugar de 2 máquinas, tenemos 20 con diferentes sistemas y diferentes lenguajes de programación; desde luego, la comunicación entre las máquinas se presenta complicada ya a primera vista y, cualquiera de las dos soluciones aportadas antes no parece arreglarnos demasiado la papeleta. La solución consiste en la utilización de una vía de comunicación, de una sintaxis abstracta que sea independiente de la máquina donde estemos trabajando. Esta sintaxis abstracta y un conjunto de reglas para su realización, va a ser común y va utilizarse para la representación de datos y estructuras de datos.

En el ejemplo de los dos ciudadanos de distinta nacionalidad, sería como si introdujésemos una lengua común, un esperanto, que hiciese posible la comunicación entre ambos. Pero así como el ciudadano inglés y el alemán han de saber esperanto, cada máquina ha de conocer esa sintaxis abstracta y sus reglas para que sea posible llevar a cabo esta opción.

De esta forma, la máquina A debe traducir sus rutinas en Pascal a la representación abstracta apoyándose en las reglas de sintaxis; y, la máquina B debe trasladar esta información codificada en la sintaxis común a su propio lenguaje, el C.

El lenguaje del que hablamos se llama ASN.1 (Abstract Syntax Notation One) y las reglas básicas de codificación se llaman BER(Basic Encoding Rules).

Los primeros protocolos de transmisión usaban sólo técnicas de codificación simple. Las capas de control de transmisión, tales como HDLC o IP usaban sólo unos pocos bytes para cabeceras (headers), y eran localizados con precisión en campos de bits. Pero con el desarrollo de las aplicaciones mediante lenguajes de alto nivel surgió la necesidad de una estructuración de la información.

ASN.1 es un lenguaje formal desarrollado y eestándarizado por CCIT(X:208) e ISO(8824). ASN.1 es importante porque :

  • Es usado para la definición de sintaxis abstractas de aplicaciones de datos.
  • Es usado para definir la estructura de la aplicación y presentación de las unidades de protocolos de datos(PDUs).
  • Es usado para definir la gestión de la información base por los dos sistemas de gestión más importantes: SNMP y OSI.

 

El aprendizaje de ASN.1 es similar al de cualquier lenguaje de programación de alto nivel. ASN.1 nos proporciona una herramienta fundamental para el uso de aplicaciones, para la descripción de la información de una forma común e independiente de cualquier implementación particular.

 

Los estándares relevantes de ISO son:

  • 8824 Specification of Abstract Syntax Notation One
  • 8825 Specification of Basic Encoding Rules for ASN.1

 

Los estándares relevantes de CCITT son:

  • X.208 Specification of Abstract Syntax Notation One
  • X.209 Specification of Basic Encoding Rules for ASN.1

 

    1. ASN.1 Y OSI.
    2.  

      OSI (Open Systems Interconnection), es una arquitectura internacionalmente eestándarizada que rige las interconexiones entre computadoras desde la capa física a la capa de aplicaciones de usuario. Los objetos en las capas altas reciben un tratamiento abstracto y son implementados en las capas más bajas. Por ejemplo, una capa puede requerir la transferencia de ciertos objetos abstractos entre computadoras; una capa baja puede proporcionar transferencia de servicios por medio de strings de unos y ceros, usando reglas de codificación para transformar los objetos abstractos en tales strings.

      El método de OSI para la especificación de objetos abstractos es llamado ASN.1, y el conjunto de reglas para representar tales objetos como strings de unos y ceros es llamado BER. ASN.1 es una notación flexible que permite definir varios tipos de datos, desde tipos simples como enteros hasta tipos estructurados como conjuntos y secuencias, además de tipos complejos definidos en función de otros. BER describe como representar o codificar los valores de los tipos de ASN.1 como un string de grupos de ocho bits (eight-bit octects).

      La conversión entre el formato del mensaje de la representación local usada por una computadora y el formato binario en el cual se transportan los datos por las líneas de comunicación es llevada a cabo en OSI en la capa de Presentación ( Presentation Layer).

      Una sintaxis abstracta es una descripción de un mensaje desde el punto de vista lógico. En el modelo OSI, la representación de los tipos de datos y estructuras para facilitar la transferencia entre sistemas es una función de la Capa de Aplicación (Application Layer); la codificación de los datos en la citada secuencia de bits se atribuye a la Capa de Presentación (Presentation Layer). Esta separación de funciones de OSI, permite a la Capa de Aplicación tratar sólo con el contenido y estructura de los datos, dejando la elección de la forma de representación para la Capa de Presentación. Debido a esta separación aparece la notación abstracta vía ASN.1 y BER.

       

    3. CONCEPTOS PREVIOS.

 

La Tabla 1 define algunos de los términos clave para llevar a cabo la discusión sobre ASN.1 y la figura 2 ilustra los conceptos fundamentales. Un sistema con una arquitectura de comunicaciones puede dividirse mayoritariamente en dos componentes:

· La de transferencia de datos (data transfer component), que son los mecanismos para la transferencia de datos entre sistemas. En el caso de la suite de protocolos TCP/IP, esta componente consistiría en TCP o UDP. En el caso de la arquitectura OSI, esta componente consistiría en la capa de sesión (Session layer).

· La de aplicación (application component) es la usuaria de la "componente de transferencia de datos" y consiste en las aplicaciones de usuario. En el caso de TCP/IP, esta componente consistiría en una aplicación como SNMP, FTP, SNTP o TELNET. En el caso de OSI, esta componente actualmente consta de la capa de aplicación (Application layer), la cual está compuesta por un número de aplicaciones de elementos de servicio, y de la capa de presentación ( Presentation layer).

 

Cuando nosotros cruzamos el límite de la componente de aplicación a la componente de transferencia de datos, hay un cambio significativo en la forma en que se ven los datos. Para la componente de transferencia de datos, los datos recibidos de una aplicación son especificados como valores binarios de una secuencia de octetos. Este valor binario puede ser directamente ensamblado en unidades de servicio de datos (SDUs) para pasar entre entidades de protocolos en una capa. La componente de aplicación, sin embargo, se preocupa de la visión del usuario de los datos. En general, este punto de vista es un conjunto estructurado de información, tal como un documento de texto, un6 6fichero personal... . El usuario está inicialmente interesado en la semántica de los datos. La componente de aplicación debe proporcionar una representación de estos datos que pueda ser convertida a valores binarios; esto es, debe preocuparse de la sintaxis de los datos.

 

 

 

 

 

TABLA 1 TÉRMINOS RELEVANTES PARA ASN.1

 

Sintaxis abstracta. Describe la estructura genérica de los datos independiente-

2 mente de cualquier codificación técnica para la representa-

ción de los datos. La sintaxis permite definir tipos de datos

y especificar valores para estos datos.

 

Tipos de datos Un conjunto de valores con nombre. Un tipo puede ser simple,

definido por la especificación de un conjunto de los valores

que puede tomar; o estructurado, en función de otros tipos.

 

Codificación La secuencia completa de octetos usados para representar

el valor de los datos.

Reglas de Codificación Una especificación de un mapeo de una sintaxis a otra. Espe-

cíficamente, para algún conjunto de valores definidos en una

sintaxis abstracta, reglas de codificación determinan

algorítmicamente la representación de esos valores en una

sintaxis de transferencia.

 

Sintaxis de Transferencia La forma en la cual los datos son actualmente representados

en términos de patrones de bits mientras están en tránsito

entre entidades.

 

 

Describamos pues el contenido de la figura 2:

Para la componente de aplicación, la información es representada en una sintaxis abstracta que trata con tipos de datos y valores de datos. La sintaxis abstracta especifica formalmente los datos independientemente de cualquier representación particular. De este modo, una sintaxis abstracta tiene muchas similitudes con cualquier definición de datos y de tipos de un lenguaje de programación convencional como Pascal, C... . Los protocolos de Aplicación describen sus PDUs en términos de una sintaxis abstracta.

Esta sintaxis abstracta es usada para intercambiar información entre componentes de aplicación de diferentes sistemas. El intercambio consiste en PDUs del nivel de aplicación, los cuales contienen información de protocolos de control y datos de usuario. En un sistema, la información representada usando una sintaxis abstracta debe ser mapeada ("traducida"), de alguna forma para su presentación al usuario humano. Similarmente, esta sintaxis abstracta debe ser mapeada en algún formato local al sistema para su almacenamiento. Es importante destacar que tal "traducción" es usada en el caso de la información base de gestión: la MIB. Sin embargo, los elementos en la MIB son definidos usando la sintaxis abstracta. De este modo, la notación de la sintaxis abstracta es empleada por un usuario para definir la MIB; la aplicación debe entonces convertir esta definición de forma conveniente para su almacenamiento local.

 

 

 

La componente debe también traducir la información de la sintaxis abstracta de la aplicación a la sintaxis de transferencia que describe los valores de los datos en formato binario, conveniente para la iteración con la componente de transferencia de datos. Por ejemplo, una sintaxis abstracta puede incluir un tipo de dato carácter; la sintaxis de transferencia podría especificar código ASCII o EBCDIC.

La sintaxis de transferencia de este modo define la representación de los datos para ser intercambiados entre las componentes de transferencia de datos. La traducción de sintaxis abstracta a sintaxis de transferencia es llevada a cabo mediante reglas de codificación significativa que especifica la representación de cada tipo y valor de datos.

Este enfoque para el intercambio de datos de aplicación soluciona los dos problemas que se presentan en un entorno distribuido heterogéneo en la representación de los datos

  • Hay una representación común para el intercambio de datos entre diferentes sistemas.
  • Internamente a un sistema, una aplicación usa alguna representación particular. El esquema sintaxis abstracta/transferencia soluciona automáticamente dife-rencias en la representación entre entidades cooperantes en una aplicación.

 

La característica fundamental de una sintaxis de transferencia es que debe apoyar la correspondiente sintaxis abstracta. La elección de qué sintaxis de transferencia utilizar dependerá dos consideraciones fundamentalmente: coste y seguridad.

 

  1. ABSTRACT SYNTAX NOTATION ONE. ASN.1

 

La unidad fundamental de ASN.1 es el módulo. El único propósito de un módulo es nombrar una colección de definiciones de tipos y/o definiciones de valores, que constituyen una especificación de datos. Una definición de tipos es usada para definir y nombrar un nuevo tipo por medio de una asignación de tipos y una definición de valor es usada para definir y nombrar un valor específico, cuando sea necesario por medio de una asignación de valor. Cada asignación de valor o de tipo debe hacerse en una línea diferente. Los módulos tienen como forma básica:

 

<modulereference> DEFINITIONS ::=

BEGIN

EXPORTS

IMPORTS

AssignmentList

End

 

Modulereference en un nombre de módulo seguido opcionalmente por un identificador de objeto para identificar el módulo. El constructor EXPORTS indica que definiciones de tipos y valores en este módulo puede ser importados por otros módulos. IMPORTS indica que definiciones de tipos y valores de otros módulos son importados por este módulo. EXPORTS e IMPORTS no pueden ser incluidos sino aparece el identificador de objeto. Finalmente, la lista de asignación consiste en asignaciones de tipos, asignaciones de valores, y macro definiciones.

En ASN.1, un tipo es un conjunto de valores, posiblemente infinito en tamaño; un valor de un tipo dado en ASN.1, es un elemento del conjunto de valores de ese tipo.

La asignación de tipos en ASN.1 consiste en una referencia de tipo, el nombre del tipo, el carácter "::=" (carácter de asignación) y el tipo apropiado. Entre cada una de estas partes ha de haber como mínimo un espacio. La definición de tipos sigue pues el esquema:

<nuevoTipo> "::=" <especificación de tipo>

 

 

La asignación de valores consiste en una referencia al valor (el nombre), el tipo de valor, el operador "::=" y un valor válido. La definición de valores sigue pues el esquema:

<nuevoValor> <tipo> "::=" <especificación del valor>

 

El lenguaje ASN.1 tiene las siguientes propiedades:

  • La disposición no es significativa; espacios múltiples y líneas en blanco pueden ser consideradas como espacios simples.
  • Los comentarios empiezan por 2 guiones "—" y terminan del mismo modo o por final de línea.
  • Los identificadores del lenguaje empiezan con una letra, pueden contener letras, dígitos y guiones, pero no pueden terminar con un guión o contener dos consecutivos.
  • El identificador para un tipo debe empezar con una letra mayúscula.
  • El identificador para un valor debe empezar con una letra minúscula
  • Las palabras reservadas están todas en letras mayúsculas.
  • Una referencia de tipo o el nombre de un módulo empiezan por mayúsculas.

 

El conjunto de caracteres usado por ASN.1 está limitado a:

 

A-Z, a-z, 0-9, ":", ";", ",", {, }, <, ".", ( , ) , [, ], "-" , " ' "e "

 

Los caracteres que no están en este conjunto pueden ser usados como valores de strings y como comentarios, pero todas las palabras clave, identificadores y puntuaciones deben usar ese conjunto

TABLA

Podemos clasificar los tipos de ASN.1 en cuatros categorías:

  • simple: son tipos "atómicos" y no tienen componentes.
  • estructurados: tienen componentes.
  • tagged (etiquetados): Se trata de tipos derivados de otros tipos.
  • other (otros): Esta categoría incluye los tipos CHOICE y ANY.

Cada tipo ASN.1 a excepción de CHOICE y ANY, tiene una etiqueta (tag), que consiste en un nombre de clase y una etiqueta numérica no negativa. Los tipos en ASN.1 son abstractamente los mismos sí y sólo si sus etiquetas numéricas son las mismas. En otras palabras, el nombre un tipo no afecta a su significado abstracto, sólo lo hace su "tag" .

Hay cuatro clases de tag:

  • Universal: para tipos que significan lo mismo en todas las aplicaciones; estos tipos son sólo definidos en X.208 (tabla 3)
  • Application: para tipos que tienen un significado específico para una aplicación, tal como el directorio de servicio X.500; tipos en dos aplicaciones diferentes pueden tener la misma etiqueta específica de aplicación y diferentes significados.
  • Private: para tipos cuyo significado es específico de una empresa. Son tipos definidos por usuarios y no están en ningún estándar.
  • Context-specific: relevantes para una aplicación particular, pero sólo aplicables en un contexto determinado. Para tipos cuyo significado es específico para un tipo estructurado dado; estas tags son usadas para distinguir entre componentes de tipo con la misma tag subyacente dentro del contexto de un tipo estructurado dado, y tipos de componente en dos tipos estructurados diferentes pueden tener el mismo tag y significados diferentes.

TABLA 3

Tag

Nombre del tipo

Conjunto de valores

Tipos Básicos

UNIVERSAL 1

BOOLEAN

TRUE o FALSE

UNIVERSAL 2

INTEGER

Números enteros positivos y negativos incluyendo el cero.

UNIVERSAL 3

BIT STRING

Una secuencia de cero o más bits

UNIVERSAL 4

OCTET STRING

Una secuencia de cero o más octetos

UNIVERSAL 9

REAL

Números reales

UNIVERSAL 10

ENUMERATED

Una lista explícita de valores enteros que puede tomar una instancia de un tipo de datos.

 

Tag

Nombre del tipo

Conjunto de valores

Tipos Objeto

UNIVERSAL 6

OBJECT IDENTIFIER

Conjunto de valores asociados con información de objetos contenidos por este estándar.

UNIVERSAL 7

Object descriptor

Descripción breve del objeto.

 

Tag

Nombre del tipo

Conjunto de valores

Tipos Character string

UNIVERSAL 18

NumericString

Dígitos de cero a nueve y ' '

UNIVERSAL 19

PrintableString

Caracteres imprimibles

UNIVERSAL 20

TeletexString

Caracteres definidos por CCITT Recommendation T.61

UNIVERSAL 21

VideotexString

Conjunto de caracteres alfabeticos y gráficos definidos por CCITT Recommendation T.100 y T.101

UNIVERSAL 22

IA5String

Alfabeto Internacional 5 (equivalente al ASCII)

UNIVERSAL 25

GraphicString

Conjunto de caracteres definidos por ISO 8824

UNIVERSAL 26

VisibleString

Conjunto de caracteres definidos por ISO 646 (equivalente al ASCII)

UNIVERSAL 27

GeneralString

General Character String

 

Tag

Nombre del tipo

Conjunto de valores

Tipos miscelanous

UNIVERSAL 5

NULL

El valor simple null, es usado donde es posible varias alternativas pero ninguna de ellas es aplicada.

UNIVERSAL 8

EXTERNAL

Tipo definido en algunos documentos (No es necesario que sea uno de los tipos validos en ASN.1

UNIVERSAL 23

UTCTime

Consiste en una fecha seguida de una hora. En formato: AAMMDDhhmmss

UNIVERSAL 24

GeneralizedTime

Consiste en una fecha seguida de una hora. En formato: AAAAMMDDhhmmss

UNIVERSAL 9-15

Reserved

Reserved for addenda to the ASN.1 Estándard

8UNIVERSAL 28-

Reserved

Reserved for addenda to the ASN.1 Estándard

 

Tag

Nombre del tipo

Conjunto de valores

Tipos Estructurados

UNIVERSAL 16

SEQUENCE

SEQUENCE OF

Sequence à Definido por una referencia fija, una lista ordenada de tipos, que tienen un valor asignado.

Sequence à Definido por una referencia a un tipo simple existente, cada valor es una lista ordenada de cero o más valores del tipo existente

UNIVERSAL 17

SET

SET OF

Set à Definido por una referencia fija, una lista desordenada de tipos, que tienen un valor asignado.

Set of à Definido por una referencia a un tipo simple existente, cada valor es una lista desordenada de cero o más valores del tipo existente

 

Los tipos con tags universal son definidos en X.208. La tabla 4 lista algunos tipos ASN.1 y sus tags de clase universal.

TABLA 4.

 

 

2.1 TIPOS SIMPLES.

 

Los tipos simples no tienen componentes; son "atómicos". Son definidos directamente por el conjunto de los valores que pueden tomar. Todos los demás tipos están construidos a partir de los tipos simples.

En la tabla 3 vemos todos los tipos que se presentan dentro de la clase universal, agrupados por conveniencia, en categorías. Entre ellos se encuentran los tipos simples repartidos por las diferentes categorías (BOOLEAN, INTEGER, ENUMERATED, REAL, OBJECT IDENTIFIER, NULL...), pero en este trabajo vamos a resaltar los siguientes por ser relevantes para los PKCS estándar: (esta última afirmación según guía Layman):

  • BIT STRING—un string arbitrario de bits.
  • IA5String—un string arbitrario de caracteres IA5 (ASCII).
  • INTEGER—un integer cualquiera.
  • OBJECT IDENTIFIER—es el único identificador para un objeto en particular. Su valor consiste en una secuencia de enteros. En SNMP, la longitud de la secuencia es limitada a un máximo de 128 elementos, y el valor máximo de cualquier elemento es (232)-1 (42949667295).
  • OCTECT STRING—una secuencia de bytes(8 bits), octetos de información binaria.
  • PrintableString—un string de caracteres imprimibles cualquiera.
  • UTCTime—un "tiempo universal coordinado" o valor Greenwich Mean Time (GMT). Se trata de una forma de expresar el tiempo. Ver en tabla 3.

 

Los tipos simples se clasifican en 2 categorías. Tipos string y tipos no string. BIT STRING, IA5String, OCTET STRING, PrintableString, y UTCTime son tipos string.

Los tipos string pueden ser vistos, para los propósitos de codificación, como consistentes de componentes, donde los componentes son substrings. Esta visión

permite codificar un valor cuya longitud no es conocida previamente (ej., un valor de entrada octect string de un fichero), con un constructor apropiado (constructed indefinite-length , del que se hablará más adelante). Ver tabla 3.

 

2.2 TIPOS ESTRUCTURADOS.

 

Los tipos estructurados son aquellos formados por componentes. ASN.1 define cuatro para la construcción de tipos de datos complejos a partir de tipos simples; todos ellos son relevantes para los PKCS estándares:

  • SEQUENCE—una colección ordenada de uno y más tipos.
  • SEQUENCE OF—una colección ordenada de cero o más ocurrencias de un tipo dado.

Sequence y Sequence of, son tipos usados para definir una lista ordenada de valores de uno o más tipos.

  • SET- una colección no ordenada de uno o más tipos.
  • SET OF—una colección no ordenada de cero o más ocurrencias de un tipo dado.

Set y Set of , son muy similares a Sequence y Sequence of, excepto que en este caso el orden de los elementos no es significativo.

Los tipos estructurados pueden tener componentes opcionales, posiblemente con valores por defecto.

 

2.3 TIPOS ETIQUETADOS IMPLICITA Y EXPLICITAMENTE.

 

ASN.1 estándar define un tipo tagged como sigue:

Un tipo definido por la referenciación de un tipo simple existente y un tag; el nuevo tipo es isomorfo al tipo existente, pero es distinto de él. En todos los esquemas de código, un valor del nuevo tipo se distingue del valor del viejo tipo.

Los tagged types (tipo etiquetados) son aquellos derivados de otros tipos por el cambio del tag de tipo subyacente(del tipo del que derivan). El "tagging" se utiliza para distinguir tipos dentro de una aplicación: podemos desear tener varios nombres de tipo diferentes tales como "nombre_empleado" y "nombre_cliente", que esencialmente son el mismo tipo.

Hay dos tipos de "tagging": La etiquetación implícita y la explícita.

La etiquetación implícita en denotada en ASN.1 [class number] IMPLICIT (ver sección 5.1). Los tipos implícitos se forman directamente de otro tipo reemplazando su tag (nombre y número). Para los propósitos de codificación sólo es usado el nuevo tag , pero el tipo subyacente es el mismo.

La etiquetación explícita es denotada por la palabra clave en ASN.1 [class number] EXPLICIT (ver sección 5.2).Los tagged types explícitos son aquellos derivados de otros tipos añadiendo un tag exterior a su tipo subyacente. Un tagged type explícito es considerado como un tipo estructurado con una componente, el tipo subyacente.

Para propósitos de codificación, el tag nuevo y el viejo han de ser reflejados.

El "tagging" es también comúnmente usado para distinguir tipos componente dentro de un tipo estructurado. Por ejemplo, componentes opcionales de un SET o SEQUENCE reciben distintos tags de context-specific para permitir la ambigüedad. Los tags implícitos resultan en códigos cortos, pero los tags explícitos pueden ser necesarios para permitir ambigüedad si el tag del tipo subyacente es indeterminado (ej., el tipo subyacente es CHOICE o ANY).

 

2.4 OTROS TIPOS.

"Otros tipos" en ASN.1 incluye CHOICE y ANY. El tipo CHOICE denota una unión de una o más alternativas; el ANY denota un valor arbitrario de un tipo arbitrario, donde el tipo arbitrario es posiblemente definido en la inscripción de un identificador de objeto o valor entero.

 

3. REGLAS BÁSICAS DE CODIFICACION. BER.

 

Las Reglas Básicas de Codificación, abreviado BER , dan una o más formas para representar cualquier valor ASN.1 como una cadena de octetos.

 

Hay tres métodos para codificar un valor ASN.1 bajo BER, la elección de cual depende del tipo de valor y de si la longitud de ese valor es conocida. Los tres métodos son:

  • primitive, código longitud-definida
  • constructed, código longitud-definida
  • unconstructed , código longitud-no definida.

Los tipos simples "no string" emplean primitive, método longitud-definida; los tipos estructurados emplean cualquiera de los métodos constructed, y los tipos string simples emplean alguno de los métodos, dependiendo de si su longitud es conocida o no. Los tipos derivados por tagging implícito emplean el método del tipo subyacente y los explícitos emplean los métodos constructed.

TABLA 5.

En cada método, el BER codificado tiene tres o cuatro partes:

    • Identifier octects.( Identificador de octeto): Esto identifica la clase y número de tag del valor ASN.1, e indica si el método es primitive o constructed.

Length octects(longitud de octetos). Para los métodos de longitud definida, estos dan el número de octetos contenidos. Para los constructed, de longitud indefinida, indica que la longitud es indefinida.

 

 

    1. PRIMITIVE, MÉTODO DE LONGITUD DEFINIDA.

 

Este método se aplica a tipos simples y tipos derivados de tipos simples por tagging implícito. Requiere que la longitud de un valor se conozca previamente. Las partes del código BER son las siguientes:

 

  • Identifier octects. Hay dos formas: numero de tag bajo (para números de tag entre 0 y 30) y numero de tag alto (de 31 en adelante)

Forma de tag baja. Un octeto. Los bits 7 y 8 especifican la clase (tabla 2), el bit 6 tiene valor 0, indicando que el código es primitive, y los bits de 5 a 1 dan el numero de tag.

TABLA 7

 

Forma de tag alta. Dos o más octetos. El primer octeto es de la forma tag corta, excepto que los bits de 5 a 1 todos tienen valor 1. El segundo y siguientes octetos dan el número de tag, que está contenido en los últimos 7 bits de cada octeto; el primer bit de cada octeto se establece a 1 excepto en el último octeto que está a 0.

 

  • Length octetcs. Este campo especifica la longitud en octetos del campo conte-nido. Hay 2 formas: corta (longitud entre 0 y 127) y larga (entre 0 y 21008 –1).

Forma corta: un octeto. Bit 8 tiene valor 0 y bits de 7 a 1 la longitud.

 

Forma larga: De dos a 127 octetos. Bit 8 del primer octeto vale 1 y los bits 1..7 dan el numero de octetos adicionales. El segundo y los siguientes dan la longitud del contenido

 

  • Contents octects. Dan una representación concreta del valor (o del valor del tipo subyacente, si el tipo es derivado por tagging implícito).

 

    1. CONSTRUCTED, MÉTODO DE LONGITUD DEFINIDA.

 

Este método se aplica a tipos string simples, a tipos estructurados, tipos derivados de tipos string simples por tagging implícito y cualquier tipo definido por tagging explícito. Requiere conocer previamente la longitud. Partes en código BER:

  • Identifier Octects. Como lo descrito en la sección 3.1, excepto que el bit 6 vale 1, indicando que el código es constructed.
  • Length octets. Sección 3.1
  • Contents octecs. Contiene la concatenación del código BER de los componentes del valor; son posibles tres casos:

 

1.- Para tipos string simple y tipos derivados de ellos por tagging implícito: la concatenación del código BER de los substrings consecutivos del valor (valor subyacente para el tagging implícito)

2.- Para los tipos estructurados y los tipos derivados de ellos por tagging implícito, la concatenación del código BER de las componentes del valor (subyacente para tagging implícito)

3.- Para tipos derivados explícitamente, el código BER del valor subyacente.

 

    1. CONSTRUCTED, MÉTODO DE LONGITUD INDEFINIDA.

 

Este método se aplica a tipos string simples, tipos estructurados, derivados implícitos de tipos string simples y estructurados, y derivados de algo por tagging explícito. No requiere conocer previamente la longitud. Partes:

  • Identifier octets: sección 3.2
  • Length octets: un octeto, 80 (en hexadecimal)
  • Contents octets. Sección 3.2
  • End-of-contents octects. Dos octetos, 00 00

 

Ya que los octetos end-of-contents aparecen donde ordinariamente se esperaría código BER (e.g., en los octetos de contenido de una secuencia de valores), el 00 y 00 aparecen como octetos identificador y longitud , respectivamente. De este modo los octetos end-of-contents son realmente los primitiveds, longitud definida codificada de un valor con clase universal, numero de tag 0, y longitud 0.

 

4. REGLAS DE CODIFICACION DISTINGUIDAS.

 

Las DER, son un subconjunto de las BER, y dan exactamente una vía para representar cualquier valor ASN.1 como una cadena de octetos. DER es empleado para aplicaciones donde es necesaria una única cadena de octetos.

 

DER añade las siguientes restricciones a las reglas dadas en la sección 3:

 

  1. Cuando la longitud esta entre 0 y 127, la forma corta de longitud debe ser usada.
  2. Cuando la longitud es 128 o mayor, debe usarse la forma larga, y la longitud debe ser codificada con el número mínimo de octetos.
  3. Para tipos string simples y tagged tipes derivados implícitamente de tipos string simples, debemos emplear primitive.
  4. Para tipos estructurados, tagged types explícitos, y derivados implícitamente de tipos estructurados, constructed con longitud definida.

 

5. NOTACIÓN PARA CODIFICADIONES DE ALGUNOS TIPOS.

 

Esta sección da la notación para algunos tipos ASN.1 y describe como codificar valores de estos tipos bajo BER y DER.

Los tipos descritos son aquellos presentados en la Sección 2.

Cada descripción incluye notación ASN.1, código BER, y código DER. Las descripciones también explican cada tipo usado en PKCS y estándares. La notación ASN.1 es generalmente solo para tipos, aunque para el tipo OBJECT IDENTIFIER, la notació2n del valor es dada como buena.

 

5.1 TIPOS ETIQUETADOS IMPLÍCITAMENTE

(TAGGING IMPLÍCITO).

Un tipo etiquetado implícitamente es un tipo derivado de otro tipo por el cambio del tag del tipo subyacente.

 

El tagging implícito es usado para componentes opcionales SEQUENCE con otro tipo subyacente que ANY en todos los PKCS, y para la alternativa extendedCertificate de PKCS#7's tipo ExtendedCertificateOrCertificate.

 

5.1.1 La notación ASN.1.

 

La notación en ASN.1 para los tipos etiquetados implícitamente es:

[[clase] número] IMPLICIT Tipo

 

clase = UNIVERSAL | APPLICATION | PRIVATE

donde Tipo es el tipo , clase es un nombre opcional de clase, y número es el número de tag dentro de la clase, debe ser un entero no negativo.

En los módulos de ASN.1 en los cuales el método de tagging por defecto es el tagging implícito, la notación [[clase] número ] Tipo es también válida y la palabra IMPLICIT se da por supuesta. Para definiciones establecidas fuera de un módulo, la inclusión explícita de la palabra IMPLICIT es preferible para prevenir cualquier tipo de ambigüedad.

Si el nombre de la clase está ausente, entonces el tag es context-specific. Este tipo de tags solo pueden aparecer en una componente de un tipo estructurado o en un tipo CHOICE.

 

Por ejemplo, el tipo PrivateKeyInfo del PKCS # [5] tiene una componente opcional attributes con un tag implícito del tipo context-specific:

PrivateKeyInfo ::= SEQUENCE {

version Version,

privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,

privateKey privateKey,

attributes [0] IMPLICIT attributes Optional }

 

Aquí el tipo subyacente es Attributes, la clase esta ausente (context-specific), y el número de tag dentro de la clase es 0.

 

5.1.2 La codificación BER.

Los métodos de codificación BER para un valor con tagged implícito pueden ser primitive o constructed, dependiendo del tipo subyacente. El contenido de los octetos es como el código BER de los valores subyacentes.

Por ejemplo, la codificación BER del componente attributes del valor PrivateKeyInfo es la siguiente:

  • Los octetos identificadores tienen 80 si el valor del tipo subyacente Attributes tiene una codificación primitive , y a0 si el valor subyacente Atributes tiene una codificación BER constructed.
  • Los octetos de longitud y contenido son los mismos que los octetos de longitud y contenido de la codificación BER del valor subyacente Attributes.

 

5.1.3 La codificación DER.

La codificación DER de un valor etiquetado implícitamente puede ser primitive o constructed.

El contenido de los octetos es como el del valor subyacente.

 

5.2 TIPOS ETIQUETADOS EXPLÍCITAMENTE

(TAGGING EXPLÍCITO).

 

El tagging explícito denota un tipo derivado de otro tipo añadiendo un tag exterior al tipo subyacente.

El tagging explícito es usado para componentes opcionales SEQUENCE con tipo subyacente ANY en todos los PKCS, y para el componente version del tipo[4] Certificate de X.509 revisado en el RFC 1114 [6]

 

5.2.1 Notación ASN.1.

La notación en ASN.1 para tipos etiquetados explícitamente es

[[clase]] número] EXPLICIT Tipo

clase = UNIVERSAL | APPLICATION | PRIVATE

 

donde Tipo es el tipo, clase es un nombre de clase opcional, y número es el número de tag incluido en la clase, un entero no negativo.

Si el nombre de la clase está ausente, entonces el tag es context-specific. Los tags context-specific sólo pueden aparecer en una componente del tipo SEQUENCE, SET o CHOICE.

En ASN.1, los "módulos" que tienen por defecto el tagging explicito, la notación [[clase] número] Tipo es aceptada, y la palabra EXPLICIT está implícita. Para definiciones establecidas fuera de un módulo, la inclusión explícita de la palabra EXPLICIT es preferible para prevenir cualquier tipo de ambigüedad.

 

Por ejemplo, el tipo ContentInfo[7] de PKCS #7 tiene un componente opcional content con un tag explícito del tipo context-specific.

 

ContentInfo ::= SEQUENCE {

ContentType ContentType,

content [0] Explicit ANY DEFINIED BY contentType OPTIONAL }

 

Aquí el tipo subyacente es ANY DEFINED BY contentType (alguno definido por contentType), la clase esta ausente (context-specific) y el número de tag dentro de la clase es 0.

Como otro ejemplo, el tipo de X.509, Certificate [4] (actualizado en el RFC 1114) tiene una componente version con un tag explicito context-specific, donde la palabra EXPLICIT está omitida:

 

Certificate ::=...

version [0] Version DEFAULT v1988,

...

 

El tag es explícito porque el método por defecto de tagging para el módulo de ASN.1 que define el tipo Certificate es tagging explicito.

 

5.2.2 La codificación BER

La codificación en BER del valor etiquetado explícitamente es siempre constructed. El contenido de los octetos es la codificación BER del valor subyacente.

Por ejemplo, la codificación BER del componente content del valor ContentInfo es la siguiente:

  • El octeto identificador es a0.
  • Los octetos de longitud representan la longitud de la codificación BER del valor del valor subyacente: ANY DEFINED BY contentType.
  • Los octetos de contenido son la codificación BER del valor subyacente ANY DEFINED BY contentType.

 

5.2.3 La codificación DER.

La codificación DER de un valor etiquetado explícitamente es siempre constructed. El contenido de los octetos es la codificación DER del valor subyacente.

 

5.3 ANY.

 

El tipo ANY denota un valor arbitrario de un tipo arbitrario, donde el tipo arbitrario está definido posiblemente en la inscripción de un identificador de objeto o asociado con un índice entero.

El tipo ANY es usado como contenido de un tipo particular contenido en el tipo ContentInfo de PKCS #7, para parámetros de un algoritmo particular del tipo AlgorithmIdentifier en X.509, y para valores de atributos de los tipos Attribute y AttributeVakueAssertion en X.501. El tipo Atribute es usado por PKCS #6, PKCS #7 y PKCS #8, y el tipo AtributeValueAssertion es usado en los nombres distinguidos de X.501.

 

5.3.1 NOTACIÓN ASN.1.

La notación ASN.1 para el tipo ANY es

ANY [DEFINED BY identificador]

donde identificador es un identificador opcional. En la forma ANY , el tipo actual es indeterminado.

La forma ANY DEFINED BY identificador solo puede aparecer en una componente de tipo SEQUENCE o SET en el cual identificador identifica algún otro componente, y ese componente tiene tipo INTEGER o OBJECT IDENTIFIER(o un tipo derivado de estos por tagging). En esta forma, el tipo actual está determinado por el valor de otros componentes, dentro de la inscripción del valor del identificador del objeto, o en la tabla de los valores enteros.

Por ejemplo, el tipo AlgorithmIdentifier de X.509 tiene una componente de tipo ANY:

 

AlgorithmIdentifier ::= SEQUENCE {

algorithm OBJECT IDENTIFIER,

parameter ANY DEFINED BY algorithm OPTIONAL }

 

Aquí el tipo actual del componente parameter depende del valor del componente algorithm. El tipo actual podría ser definido en el registro del valor de identificador en el componente algorithm.

 

5.3.2 La codificación BER

La codificación BER del valor ANY es la codificación BER del valor actual.

Por ejemplo, la codificación BER del valor del componente parameter es la codificación BER del valor del tipo actual definido en el registro del valor del identificador del objeto para la componente algorithm.

 

5.3.3 La codificación DER.

La codificación DER del valor ANY es la codificación DER del valor actual.

 

5.4 BIT STRING

 

El tipo BIT STRING denota un string arbitrario de bits (unos y ceros). Un valor BIT STRING puede tener cualquier longitud incluida la longitud cero. Este tipo es un tipo string.

El tipo BIT STRING es usado para firmas digitales en certificados extensos en el tipo ExtendedCertificate de PKCS #6, para firmas digitales en el tipo Certificate en X.509, y para claves públicas en certificados del tipo SubjectPublicKeyInfo en X.509.

 

5.4.1 NOTACIÓN ASN.1

La notación en ASN.1 para el tipo BIT STRING es la siguiente:

BIT STRING

 

Por ejemplo, el tipo SubjectPublicKeyInfo en X.509 tiene un componente BIT STRING:

SubjectPublicKeyInfo ::= SEQUENCE {

Algorithm AlgorithmIdentifier,

PublicKey BIT STRING }

 

5.4.2 CODIFICACIÓN BER

La codificación BER del valor de un BIT STRING puede ser primitive o constructed. En la codificación primitive, el primer octeto de contenido nos da el número de bits por el cual la longitud el bit string es menor que el próximo múltiplo de ocho(esto es llamado el "número de bits no usados"). El segundo y siguientes octetos contenido nos dan el valor del bit string convertido en un octet string. El proceso de conversión es el siguiente:

  • El bit string es rellenado después del último bit con los bits de cero a siete de cualquier valor para hacer la longitud del bit string múltiplo de ocho. Si la longitud del bit string ya es múltiplo de ocho no se rellena.
  • El bit string rellenado se divide en octetos. Los primeros ocho bits del bit string rellenado forman el primer octeto, del bit 8 al bit 1, y así sucesivamente mediante los últimos ocho bits del bit string rellenado

 

En una codificación constructed, los octetos de contenido nos dan la codificación BER de consecutivos substrings del bit string, donde cada substring excepto el último tiene una longitud múltiplo de ocho bits.

 

Por ejemplo, la codificación BER del bit string con valor "011011100101110111" puede ser la siguiente de entre otras dependiendo de la elecció2n de los bits de relleno, la forma de los octetos de longitud, y si la codificación es primitive o constructed.

 

03 04 06 6e 5d c0 codificación DER

03 04 06 6e 5d e0 relleno con "100000"

03 81 04 06 6e 5d c0 octetos de longitud en forma larga

 

23 09 codificación constructed : "0110111001011101" +"11"

03 03 00 6e 5d

03 02 06 c0

 

5.4.3 CODIFICACIÓN DER

La codificación DER de un valor BIT STRTING es siempre primitive. Los octetos de contenido son como para el código BER primitive, exceptuando que el bit string está rellenado con bits de valor cero.

 

Por ejemplo, la codificación DER del valor de un BIT STRING "011011100101110111" es:

03 04 06 6e 5d c0

 

5.5 CHOICE

 

El tipo CHOICE denota la unión de una o más alternativas.

El tipo CHOICE se usa para representar la unión de un certificado extendido y un certificado (de X.509) en el tipo ExtendedCertificateOrCertificate en PKCS #7.

 

5.5.1 NOTACIÓN ASN.1

En ASN.1 la notación del tipo CHOICE es:

CHOICE {

[identificador_1] Tipo_1,

...,

[identificador_n] Tipo_n }

 

donde identificador_1, ... , identificador_n (son opcionales) distinguen las distintas alternativas, y Tipo_1, ... , Tipo_n son los tipos de las alternativas. Los identificadores son principalmente para documentación; no afectan al valor del tipo ni su codificación de ninguna manera.

Los tipos deben tener distintos tags. Este requerimiento se satisface típicamente con el tagging implícito o explícito en algunas de las alternativas.

 

Por ejemplo, el tipo ExtendedCertificateOrCertificate en PKCS #7 es un tipo CHOICE

ExtendedCertificateOrCertificate ::= CHOICE {

certificate Certificate, -- X.509 certificate

extendedCertificate [0] IMPLICIT ExtendedCertificate }

 

Aquí los identificadores para las alternativas son certificate y extendedCertificate, y los tipos de las alternativas son Certificate y IMPLICIT ExtendedCertificate.

 

5.5.2 CODIFICACIÓN BER

La codificación BER de un valor CHOICE es la codificación BER de la alternativa elegida. El factor de que las alternativas tienen distintos tags hace posible distinguir entre sus codificaciones BER. Por ejemplo, el octeto identificador para la codificación BER es 30 si la alternativa elegida es certificate, y a0 si la alternativa elegida es extendedCertificate.

 

5.5.3 CODIFICACIÓN DER

La codificación DER de un valor CHOICE es el código DER de la alternativa elegida.

 

 

5.6 IA5String.

 

El tipo IA5String denota un string arbitrario de IA5 caracteres. IA5 (Internacional Alphabet 5) es semejante al ASCII. Un valor IA5String puede tener cualquier longitud, incluido el cero. Este tipo es un tipo string.

 

El tipo IA5String se usa para direcciones de correo electrónico y nombres desestructurados en PKCS #9[10].

 

5.6.1.La notación ASN.1.

La notación ASN.1 para el tipo IA5String es

 

IA5String

 

5.6.2. La codificación BER.

La codificación BER de un valor IA5String puede ser primitive o constructed. En una codificación primitive, el contenido del octeto da los caracteres en el IA5 string, codificado en ASCII. En una codificación constructed, el contenido del octeto da el encadenamiento de las codificaciones BER de los sucesivos substrings del IA5 string.

 

Por ejemplo la codificación BER del valor de tipo IA5String "test1@rsa.com" puede ser cualquiera de las siguientes, entre otras, dependiendo del formato de la longitud de los octetos y si la codificación es primitive o constructed:

 

12 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d DER codificación

12 81 0d formato largo de la longitud de los octetos

74 65 73 74 31 40 72 73 61 2e 63 6f 6d

32 13 codificación contructed: "test1"+"@"+ "rsa.com"

12 05 74 65 73 74 31

12 01 40

12 07 72 73 61 2e 63 6f 6d

 

Otro ejemplo:

 

"Jones" 1A 05 4A 6F 6E 65 73

 

5.6.3. La codificación DER.

La codificación DER de un valor de tipo IA5String siempre es primitive. El contenido de los octetos es como en la codificación BER primitive.

 

Por ejemplo la codificación DER del valor IA5String "test1@rsa.com" es

 

12 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d

 

 

 

 

 

 

5.7 INTEGER .

 

El tipo INTEGER denota un entero arbitrario. Los valores del INTEGER pueden ser positivos, negativo, o ceros, y puede tener cualquier magnitud. Además, a un valor entero individual se le puede asignar nombres para indicar un significado especifico.

 

En SNMP, todos los usos de este tipo están restringidos a un rango especifico.

 

El tipo INTEGER se usa como una versión de números PKCS, los valores [cryptographic] tales como, módulos, exponentes, y números primos en tipos PKCS #1's RSAPublicKey y RSAPrivateKey [11] y PKCS que #3's DHParameter tipos [12], un contador de mensges de digest iteraciones en tipo PKCS #5's PBEParameter, y la versión de números y serie de números en tipo X.509's Certificate [4].

 

5.7.1. Notación ASN.1.

La notación para el tipo INTEGER es

 

INTEGER [{ identificador1 (valor1 ) ... identificadorn (valorn ) }]

 

donde identificador1,...,identificadorn son distintos identificadores opcionales y valor1..., valorn son valores del entero optativos. El identificador, cuanto esta presente, se asocia con valores del tipo.

 

Por ejemplo el tipo RFC 1114's Versión [6] es un tipo INTEGER con los valores de identificadores:

 

Versión::= INTEGER{ v1988 (0)}

 

Se asocia el identificador v1988 con el valor 0. El tipo RFC 1114's Certificate usa el identificador v1988 para dar por defecto el valor 0 al componente versión:

 

Certificate ::= ...

version Version DEFAULT v1988,

...

 

Otro ejemplo:

ColorType: := INTEGER

{

rojo (0)

blanco (1)

azul (2)

}

"ColorType" es un INTEGER y sus posibles valores 0,1,2 se nombran como "rojo","blanco" y "azul" respectivamente. ColorType también podría tener cualquier otro valor entero valido, como 4 o -62.

 

 

 

 

 

5.7.2. La codificación BER.

 

La codificación BER de un valor INTEGER siempre es primitive. El contenido del octeto da el valor del entero, en formato de complemento a 2, siendo el dígito más significativo el primero, con el número del mínimo de octetos. El valor 0 se codifica como un solo octeto 00.

 

En la tabla 3 se ven algunos ejemplos de la codificación BER (sirven también para la codificación DER)

 

 

Valor entero

Codificación BER

0

02 01 00

127

02 02 00 7F

128

02 02 00 80

256

02 02 01 00

-128

02 01 80

-129

02 02 FF 7F

 

Tabla 3. Ejemplo de codificaciones BER de valores INTEGER.

 

5.7.3. La codificación DER.

 

La codificación DER de un valor INTEGER siempre es primitive. El contenido del octeto es como para la codificación BER primitive.

 

NOTA:

Formato de complemento a dos.

El bit más significativo es el bit de signo.

Numero positivo: Bit más significativo a cero y el resto representa la magnitud del numero.

Numero negativo: cuya magnitud es X, siendo X menor o igual a 2N-1 se representa calculando 2N-X. El bit más significativo va a 1.

Para calcular el valor decimal de una secuencia de N-bits en complemento a dos usamos la siguiente formula:

valor = -bn-1 * 2 N-1 + bi * 2 i

En un octeto se puede representar el rango -128..127

 

 

 

 

 

 

 

 

5.8 NULL

 

El tipo NULL denota un valor nulo.

El tipo NULL es simplemente la alternativa de que no este presente un valor en esa posición de la estructura.

Se usa para parámetros de algoritmos en varios lugares de PKCS.

 

5.8.1 Notación ASN.1

La codificacón ASN.1 para el tipo NULL es

 

NULL

 

5.8.2 Codificación BER

La codificación BER de un valor NULL siempre es primitive. El contenido del octeto es vacío.

Por ejemplo, la codificación BER de un valor NULL puede ser una de las siguientes y, como en las otras, depende del formato de la longitud de los octetos.

 

05 00

05 81 00

 

5.8.3 Codificación DER

La codificación DER de un valor NULL siempre es primitive. El contenido del octeto es vacío.

Por ejemplo, la codificación DER de un valor NULL es siempre 05 00. Serian los dos octetos siguientes:

 

00000101 00000000

tag universal 5 longitud 0

 

5.9 OBJECT IDENTIFIER

 

El tipo OBJECT IDENTIFIER denota un identificador de objeto, que es una secuencia de enteros no negativos que identifican a un objeto como un algoritmo o como el atributo nombre de directorio. Un valor de tipo OBJECT IDENTIFIER, puede tener cualquier número de componentes. Este tipo es un tipo no-string.

El conjunto de objetos definidos tiene una estructura de árbol, cada objeto es uno de sus nodos y la raíz del árbol es un objeto referenciado por el estándar ASN.1. Cada nivel j del árbol tiene n nodos numerados de 0 a n. El valor de un identificador de objetos es la lista de los números de los nodos empezando en la raíz. Esto nos da una idea de lo que representa el objeto.

Los valores OBJECT IDENTIFIER vienen dados por un estándar (registration autorithies). Cada estándar es responsable de todas las secuencias de los componentes que empiezan con una secuencia dada. Un estándar típico delega responsabilidad de los subconjuntos de objetos de su dominio a otros estándares, o para tipos particulares de objetos. Hay siempre por lo menos dos componentes.

En SNMP, la longitud de la secuencia esta limitada a un máximo de 128 elementos, y el máximo valor para un elemento es 232-1 (4294967295).

 

Ejemplo:

En el subárbol con raíz "RetailStores" el objeto "payroll" tiene de valor local {0 6 2}, y su valor completo sería {x 0 6 2} donde x es el valor de su raíz en el árbol total.

 

El tipo de OBJECT IDENTIFIER es usado para identificar el contenido en tipo PKCS #7's ContentInfo [ 7], para identificar algoritmos en tipo X.509's AlgorithmIdentifier, y para identificar atributos en tipo X.501's Atribute y tipo AttributeValueAssertion [8]. El tipo Atributo es usado por PKCS #6 [ 9], PKCS #7[ 7], y PKCS #8[ 5], y el tipo AttributeValueAssertion es usado en X.501 nombres distinguidos. Los valores OBJECT IDENTIFIER están definidos en todo el PKCS.

 

5.9.1 Notación ASN.1

La notación ASN.1 para el tipo OBJECT IDENTIFIER es

 

OBJECT IDENTIFIER

 

La notación ASN.1 para valores del tipo OBJECT IDENTIFIER es

 

{[identificador] componente1... componenten}

 

componente_i= identificador_i | identificador_i (valor_i) | valor_i

 

donde identificador, identificador1,..., identificadorn son identificadores, y valor1...., valorn son valores aleatorios del entero.

La forma sin identificador es el valor "completo" con todos sus componentes; la forma con identificador abrevia los componentes del principio con otro valor de tipo OBJECT IDENTIFIER. La intención primordial de los identificadores identificador1,... ,identificadorn es de documentación, pero deben corresponder con su valor entero cuando ambos están presentes.

Estos identificadores pueden aparecer sin el valor entero sólo si están entre un conjunto pequeño de identificadores definidos en X.208[ 2].

Por ejemplo los siguientes valores al identificador del objeto asignado a RSA Data Security, Inc.:

{ iso(1) member­body(2) 840 113549 }

{ 1 2 840 113549 }

 

La Tabla4 da algunos otros valores de identificadores de objetos y sus significados.

 

Valor del identificador del objeto

Significado

{ 1 2}

ISO cuerpos del miembro

{ 1 2 840}

US (ANSI)

{ 1 2 840 113549}

RSA Data Security, Inc.

{ 1 2 840 113549 1}

RSA Data Security Inc. PKCS

{ 2 5}

Directorio repara (X.500)

{ 2 5 8}

Directorio repara--- algoritmos

Tabla 4. Unos valores del [identifier] del objeto y sus significados.

 

5.9.2 Codificación BER

La codificación BER de un valor de tipo OBJECT IDENTIFIER siempre es

primitive. El contenido del octeto es el encadenamiento de n-1 string de octetos, donde n es el número de componentes del identificador de objeto completo. Cada string de octetos es la codificación de un valor entero, en base 128, donde el dígito más significativo es el primero, con los mínimos dígitos posibles, y con 8 bits para cada octeto excepto el ultimo que queda fijo a "1."

El bit 8 (el más significativo) de cada octeto indica si es el ultimo octeto de los subidentificadores poniendolo a 0. Los 7 bits restantes representan el valor del octeto.

Denotamos valor1,...., valorn los valores enteros de los componentes en el identificador del objeto completo. Los n-1 "subidentificadores" a partir de los cuales se deriva el octet string son como sigue:

1. El primer subidentificador es 40valor1+valor2.2

(Esto es razonable ya que valor1, que corresponde al primer nivel del árbol, está limitado a los valores 0 (ccit),1(iso) y 2(hiubt-iso-ccitt); y el valor2, segundo nivel del árbol, esta limitado por el rango 0..39 cuando valor1 es 0 o 1, y hay siempre al menos dos componentes de acuerdo con X.208 [2].)

2. El i-esimo subidentificador, 2<=i<= n-1, es el valor i+1.

La codificación de estos octetos es como sigue: el Bit 8 es 0 cuando es el último octeto del subidentificador. Los bist del 7 al 1 son la codificación del valor del subidentificador. En el caso de que necesitemos varios octetos para un mismo identificador su valor vendrá dado por la concatenación de los bist 1..7 de cada uno de los octetos necesarios.

Por ejemplo, el subindentificador para el identificador del objeto RSA Data Security, Inc's es 42=40*1+2,840,113549, y 1. La codificación de 42 es 2A, la de 840 es 86 48. la de 113549 es 86 F7 0D, y la de 1 es 01, lo que nos lleva a la siguiente codificación BER:

06 07 2A 86 48 86 F7 0D 01

5.9.3 Codificación DER

La codificación DER de un valor de tipo OBJETO IDENTIFIER siempre es primitived.

El contenido del octeto es como la codificación BER primitive.

 

5.10 OCTET STRING

El tipo OCTET STRING coge valores que son una secuencia ordenada de cero o más grupos de ocho bits. Es un tipo de string bastante simple de codificar.

Ejemplo :

Tag Universal 4 Longitud = 4

0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0

Primer octeto Segundo octeto Tercer octeto Cuarto octeto

1 1 1 0 1 0 1 1 0 0 0 0 0 1 1 0 1 0 0 1 1 0 0 1 0 0 1 1 0 1 1 1

Tag Universal 4 --> Es la etiqueta que indica que lo siguiente es un octet string.

 

5.10.1 La anotación ASN.1

OCTET STRING [SIZE ({ size| size1..size 2})]

donde podemos elegir dos formas de elegir el tamaño :

1.-Usando size1 y size2 que indican que la cadena de octetos debe

tener como mínimo 'size1' octetos y como máximo 'size2' octetos.

2.-Si usamos size el tamaño de la cadena sera exactamente 'size' octetos

Por ejemplo el tipo PBEParameter de PKCS #5's [Password-base Encryption Estándard] tiene un componente de tipo OCTET STRING:

PBEParameter2 ::= SEQUENCE {

salt OCTET STRING SIZE(8),

iterationCount INTEGER }

Aquí el tamaño del componente 'salt' tiene siempre ocho octetos.

 

5.10.2 La codificación BER

Un octet string puede ser una primitive o un constructed :

- En la codificación de una primitive, el contenido de los octetos da el valor de la cadena.

- En una codificación de un constructed, el contenido de los octetos da la concatenación de subcadenas de octetos codificadas en BER

Por ejemplo la codificación en BER del OCTET STRING con valor

01 23 45 67 89 ab cd ef

puede ser cualquiera de las siguientes, dependiendo del campo de longitud y dependiendo de si es primitived o un compuesto:

codificación BER 04 08 01 23 45 67 89 ab cd ef

la forma larga de octetos 04 81 08 01 23 45 67 89 ab cd ef

codificación de forma compleja : 01 23 45 67 89 ab cd ef

24 0c 04 04 01 23 45 67

04 04 89 ab cd ef

5.10.3 La codificación DER

La codificación DER de un valor OCTET STRING es la de una primitive. El

contenido de los octetos se trata igual que si fuera una primitive codificada en BER.

Por ejemplo en la codificación BER del valor del OCTET STRING

'01 23 45 67 89 ab cd ef ' es :

04 08 01 23 45 67 89 ab cd ef

 

5.11 El tipo PRINTABLESTRING

 

El tipo PrintableString es una cadena de caracteres en ASCII, que puede tomar cualquier valor dentro de los siguiente conjuntos de caracteres :

A, B,...,Z

a, b,..,z

0, 1,...,9

(espacio) ' () + - , . / : = ?

Es un tipo de string.

El tipo PrintableString se usa en varios tipos de atributos y palabras reservadas en X.520[Nodo directorio].

 

5.11.1 La notación ASN.1

 

PrintableString

5.11.2 La codificación BER

Un PrintableString puede ser una primitive o un constructed :

- En la codificación de una primitive, el contenido de los octetos da el valor de la cadena de caracteres en ASCII.

- En una codificación de un 'compuesto', el contenido de los octetos da la concatenación de subcadenas de caracteres codificadas en BER.

 

Por ejemplo la codificación en BER del valor PrintableString "Test User 1" puede ser cualquiera de las siguientes dependiendo del campo de longitud de los objetos y si la codificación es primitive o constructed:

La etiqueta '13' indica que es un PrintableString (Universal 19)

El campo siguiente nos indica la longitud ('0b'=11)

Codificación BER 13 0b 54 65 73 74 20 55 73 65 72 20 31

Forma Larga de los octetos 13 81 0b 54 65 73 74 20 55 73 65 72 20 31

Forma compuesta, "Test" + "User 1"

La etiqueta 33 nos indica que se trata de un PrintableString de forma compuesta.

Linea 1 --> '0f' nos indica que la longitud total de las subcadenas es 15

Linea 2 y 3--> '13' Indica que es un PrintableString Simple

Linea 2 --> '05' es la longitud de la primera subcadena

Linea 3 --> '06' es la longitud de la segunda subcadena

1. 33 0f

2. 13 05 54 65 73 74 20

3. 13 06 55 73 65 72 20 31

 

5.11.3 La codificación DER.

La codificación DER de un valor de un PrintableString es la de una primitived. El contenido de los octetos es tratado como una primitived de la codificación BER.

Por ejemplo en la codificación DER del PrintableString -> "Test user 1" es

13 0b 54 65 73 74 20 55 73 65 72 20 31

 

5.12 EL TIPO SEQUENCE

 

El tipo SEQUENCE es una lista ordenada de cero o más tipos de datos. El tipo SEQUENCE se usa en PKCS y estándares relacionados

 

5.12.1 La notación ASN.1

SEQUENCE{

[identifier 1 ] Type 1 [{OPTIONAL | DEFAULT value1}],

...,

[identifier n ] Type n [{OPTIONAL | DEFAULT valuen}]}

 

donde

- Identifier1 ,..., identifiern son optativos, y tienen que ser identificadores

distintos para los componentes

- Type1,...,Typen que son los tipos de los componentes,

- Value1,...,valuen son valores 'optativos' o 'cogidos por defecto' para los componentes.

Los identificadores son primordiales para la documentación; estos no afectan de ninguna manera a los valores del tipo o a sus codificaciones.

Tenemos dos formas de especificar que un tipo de componente es opcional en la lista ordenada:

1.- Usando OPTIONAL después del tipo del componente.

Cuando usamos esta opción, el valor indica que puede estar o no presente en la secuencia.

2.- Usando DEFAULT después del tipo del componente

Cuando usamos esta opción, el valor especificado es usado, cuando el tipo no aparece en la lista.

Los tipos de cualquier serie sucesiva de componentes con valor OPTIONAL o DEFAULT, deben tener etiquetas distintas. Este requisito se satisface con etiquetas implícitas o explicitas de algunos componentes.

Por ejemplo el tipo Validity de X.509's [Nodo Directorio] es un tipo SEQUENCE con dos componentes:

 

Validity ::= SEQUENCE {

start UTCTime,

end UTCTime }

 

Aquí los identificadores para los componentes son 'start' y 'end' y los tipos de los componentes están ambos en UTCTime.

 

Otro ejemplo :

 

Message ::= SEQUENCE {

version INTEGER { version-1(0)},

community OCTET STRING}

 

sample Message ::= {0,'EB069937'h}

 

5.12.2 La codificación BER

La codificación BER del valor SEQUENCE es siempre la de un compuesto. El contenido de los octetos es la concatenación de los valores de los componentes de la secuencia codificada en BER, en orden de definición, con las siguientes reglas para los componentes, con los valores OPTIONAL y DEFAULT:

a) Si el valor de un componente con el VALOR OPTIONAL o DEFAULT no esta en la secuencia, entonces la codificación de ese componente no esta incluida en la secuencia de octetos.

b)Si el valor de un componente con el valor DEFAULT toma un valor por defecto, entonces la codificación de ese componente puede o no incluirse en la secuencia de octetos.

La etiqueta 16 indica que es un tipo secuencia.

 

Tag Universal 16 Longitud = 9

0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 1

 

Primer octeto Segundo octeto Tercer octeto Cuarto octeto

0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0

 

Quinto octeto Sexto octeto Septimo octeto Octavo octeto

0 0 0 0 0 1 0 0 1 1 1 0 1 0 1 1 0 0 0 0 0 1 1 0 1 0 0 1 1 0 0 1

 

Noveno octeto

0 0 1 1 0 1 1 1

 

5.12.3 La codificación DER

 

La codificación DER de un valor SEQUENCE es siempre de forma compuesta. El contenido de los octetos se trata como en BER, excepto porque si el valor de un componente con el Calificador DEFAULT es un valor por defecto, no se incluye la codificación de ese componente en el contenido de los octetos.

5.13 SEQUENCE OF

El tipo SEQUENCE OF es una colección ordenada de cero o más sucesos de un tipo dado.

El tipo SEQUENCE OF es usado, en X.501[Nodo Directorio].

 

5.13.1La notación ASN.1

 

SEQUENCE OF type

 

donde type un tipo cualquiera.

Por ejemplo el tipo RDNSequence usado en X.501's [Nodo Directorio] consta de cero o más sucesos del tipo RelativeDistinguishedName :

 

RDNSequence ::= SEQUENCE OF RelativeDistinguishedName

 

5.13.2 La codificación BER

 

Es siempre igual a la de un compuesto. El contenido de los octetos

es la concatenación de los valores de los sucesos en orden de definición.

 

5.13.3 La codificación DER

.

La codificación DER de un valor SEQUENCE OF es siempre compuesta. El contenido de los octetos se trata como en BER, es la concatenación de los valores de los sucesos de la codificación DER en orden de ocurrencia.

 

5.14 SET

El tipo SET es un tipo compuesto que denota una colección desordenada de uno o más tipos, alguno de los cuales puede ser declarado como opcional. Cada valor es una lista desordenada de valores, uno de cada tipo de componentes.

En la gramática BNF se representa como:

  1. TipoSet ::= SET {Lista_de_tipos_de_elementos} | SET { }.
  2. ValorSet ::= {Lista_de_valores_de_los_elementos} | { }.

El tipo SET se usa en PKCS.

El tipo de "tag" que lo define es "UNIVERSAL 17".

5.14.1 La notación ASN.1

La notación ASN.1 del tipo de SET es

SET{

[identificador 1 ] Tipo 1 [{OPTIONAL | DEFAULT valor 1 }],

...,

[identificador n ] Tipo n [{OPTIONAL | DEFAULT valor n }]}

donde identificador1 ,..., identificadorn son optativos, y son identificadores distintos para los componentes, Tipo1,...,Tipon son los tipos de los componentes, y valor1,...,valorn son valores "optativos" o "cogidos por defecto" para los componentes.

Los identificadores son primordiales para la documentación; éstos no afectan de ninguna manera a los valores del tipo o a sus codificaciones. El valor OPTIONAL indica que el valor de un componente es optativo y indica que no está presente en el conjunto. El valor DEFAULT también indica que el valor de un componente es optativo, y le asigna a un valor por defecto cuando el componente no está.

Los tipos de cualquier serie sucesiva de componentes con valor "OPTIONAL" o "DEFAULT", deben tener etiquetas distintas. Este requisito se satisface con etiquetas implícitas o explícitas de algunos componentes.

Ejemplo:

  1. Persona ::= SET

{

nombre IA5String,

edad INTEGER,

hembra BOOLEAN

}.

Tres representaciones de esta instancia son:

{"Maggie", 4, true} {, true, "Maggie", 4} {4, true, "Maggie"}

5.14.2La codificación BER

 

La codificación BER del valor SET es siempre "constructed". El contenido de los octetos es la concatenación de los valores de los componentes de un conjunto en algún orden, con las siguientes reglas para los componentes, con los valores OPTIONAL y DEFAULT

Si el valor de un componente con el "VALOR OPTATIVO" o "DEFAULT" no está en el conjunto, entonces la codificación de ese componente no está incluida en el contenido de los octetos.

Si el valor de un componente con el valor "DEFAULT" toma un valor por defecto, entonces la codificación de ese componente puede o no incluirse en el contenido de los octetos.

Ejemplo:

definition: 31 06

SET (INTEGER, 02 01 03

INTEGER) 02 01 08

value: (3,8)

5.14.3 La codificación DER

 

La codificación DER de un valor SET es siempre compuesta. El contenido de los octetos se trata como en BER, excepto que :

1.-si el valor de un componente con el Calificador DEFAULT es un valor por defecto, no se incluye la codificación de ese componente en el contenido de los octetos.

2.- Existe un orden para los componentes, en orden ascendente de etiqueta.

 

5.15 SET OF

El tipo SET OF es un tipo compuesto que denota una colección de cero o más ocurrencias de un tipo dado. Cada valor es una lista desordenada de cero o más valores de tipos existentes.

En la gramática BNF se representa como:

  1. TipoSetOf ::= SET OF tipos | SET.
  2. ValorSetOf ::= {Lista_de_valores} | { }.
  3.  

    El tipo SET OF es usado para conjuntos de atributos en PKCS#6[9],PKCS#7[7], PKCS#8[5], para conjuntos de identificadores de algoritmos de "mensajes-digest", información "signer" y información "recipient" en PKCS#7[7] y en X.501[8].

    El tipo de "tag" que lo define es "UNIVERSAL 17".

     

    5.15.1 La notación ASN.1

     

    La notación de ASN.1 para el tipo SET OF es

    SET OF tipo

    donde "tipo" es un tipo cualquiera.

    Por ejemplo, X.501's RelativeDistinguishedName type [8] esta formado por cero o más ocurrencias del tipo AttributeValueAssertion, donde el orden no es importante:

    RelativeDistinguishedName ::= SET OF AttributeValueAssertion

    5.15.2 La codificación BER

    La codificación del valor SET OF es siempre "constructed". El contenido de los octetos es la concatenación, en algún orden, de los valores de las ocurrencias de la codificación BER en una colección.

    Ejemplo:

    definition: 31 06

    SET OF 02 01 03

    (INTEGER) 02 01 08

    value: (3,8)

    5.15.3 La codificación DER

     

    La codificación DER de un valor SET OF es siempre compuesta. El contenido de los octetos es el mismo que en BER, excepto en aquí existe un orden, ascendente ordenado por nombre en la codificación BER.

    5.16 Useful types (tipos prácticos):

    1) GeneralizadTime

    2) UTCTime.

    3) Tipos externos.

    Los "useful types", normalmente transfieren fechas y datos sobre el tiempo junto con otros tipos de datos. En lugar, de que el usuario defina los tipos para modelos de fecha y datos del tiempo. ASN.1 proporciona una sintaxis. Esta notación no solo es útil, sino que asegura uniformidad. ASN.1 define dos "useful types" para transferir el tiempo y los datos sobre la fecha, GeneralizedTime y UTCTime. Otros dos "useful types" son ObjectDescriptor y "external", que se agregaron a las normas de ASN.1 en 1988. El tipo "ObjectDescriptor" se usa con el tipo " Object identifier".

    En la gramática BNF se representa como:

  4. UsefulType ::= tipodereferencia.

 

5.16.1GeneralizadTime

 

Consistente en la fecha, especificada con dos dígitos para el año, dos dígitos para el mes, y dos dígitos para el día. Seguidos de la hora en, horas, minutos y opcionalmente segundos. Seguidos de una especificación opcional de la diferencia entre el tiempo local respecto al universal.

Tipo GeneralizedTime toma los valores de año, mes, día, hora, tiempo, minutos, segundos, y décimas de segundo en una de cualquiera de tres formas:

Tiempo local sólo. "YYYYMMDDHHMMSS.fff", donde el fff es optativo.

Tiempo universal (cronómetro UTC) . "YYYYMMDDHHMMSS.fffZ".

Diferencia entre local y tiempos de UTC."YYYYMMDDHHMMSS.fff+-HHMM".

El tipo de "tag" es "UNIVERSAL 24".

5.16.1.1 La notación ASN.1

La notación de este tipo es la palabra reservada "GeneralizedTime". Por ejemplo, si

CurrentTime: := GeneralizedTime

entonces cualquiera de lo siguiente tres valores de CurrentTime son válidos:

"19991231235959.999" es 1/1000 segundo antes del fin del siglo XX en el tiempo local; "19991231205959.999Z" es el tiempo universal con tres horas de diferencia respecto al tiempo local anterior; y "19991231235959.999+0302" indica el tiempo local tres horas por delante respecto del tiempo universal.

5.16.2 UTCTime

 

El tipo UTCTime denota una hora elegida universalmente o el

valor del tiempo en el meridiano de Greenwich(GMT).. Un valorUTCTime incluye el tiempo local preciso en minutos o segundos, y un desplaza-miento del GMT en horas y minutos. Toma una de las formas:

YYMMDDhhmmZ

YYMMDDhhmm+hh'mm'

YYMMDDhhmm-hh'mm'

YYMMDDhhmmssZ

YYMMDDhhmmss+hh'mm'

YYMMDDhhmmss-hh'mm'

donde:

YY son los dígitos menos significativos del año

MM es el mes (01 a 12)

DD es el día (01 a 31)

hh es la hora (00 a 23)

mm son los minutos (00 a 59)

ss son los segundos (00 a 59)

Z indica que tiempo local es GMT,+ indica el tiempo de desfase mayor respecto al GMT(es mayor la hora local),- indica que tiempo es menor que GMT .

hh' es el valor del desfase absoluto respecto al GMT en horas mm' es el valor del desfase absoluto respecto al GMT en minutos Este tipo es un tipo de "string".

El tipo UTCTime se usa para tiempos asignados en PKCS #9's y atributos signing-time [10] y en los tipos Validity del X.509's para certificar períodos validados.[4].

El tipo de "tag" es "UNIVERSAL 23".

5.16.2.1 La notación ASN.1

La notación del ASN.1 para el tipo UTCTime es :

UTCTime

Ejemplo:

NewTime ::= UTCTime

entonces puede tomar los siguientes valores del tiempo local: "19991232235959" o "199912312359".

5.16.2.2 La codificación BER

La codificación BER de un valor UTCTime puede ser primitive o constructed. En una codificación primitive, el contenido de los octetos da los caracteres en el string, cifrado en ASCII. En una codificación compuesta, el contenido de los octetos da la concatenación de subcadenas consecutivas de un "string" en la codificación BER. (La codificación compuesta no es particularmente interesante, porque aunque la codificación compuesta se permite, los valores que toma UTCTime son pequeños.)

Por ejemplo, el tiempo en que se escribió esta frase era 4:45:40 postmeridiano Pacificif Daylight Time del 6 de mayo de 1991, que se puede representar con el valor UTCTime , entre otros:

" 910506164540-0700"

" 910506234540Z"

 

Estos valores tienen en BER las siguientes codificaciones, entre otras:

17 0d 39 31 30 35 30 36 32 33 34 35 34 30 5A

17 11 39 31 30 35 30 36 31 36 34 35 34 30 2D 30 37 30 30

 

5.16.2.3 La codificación DER

 

La codificación DER de un valor UTCTime siempre es primitive. El contenido de los octetos es como el de las primitives en la codificación en BER.

5.16.3 External.

 

Es un tipo definido en algún documento externo.

Los valores de tipo "externos" que comunican tanto los datos como su interpretación. El tipo de dato "externo", no necesita ser un tipo de ASN.1. El tipo "externo" se usa por ejemplo en la "Association Control Service Element" (ACSE) que es común a todas las aplicaciones de OSI, como modelo un de variables cuyo tipo puede no ser especificado o especificado en otra parte. No hay ninguna restricción en la notación para especificar el tipo.

En ISO 8824 contiene la definición del siguiente tipo "externo":

EXTERNAL ::= [UNIVERSAL 8] IMPLICIT SEQUENCE

{

direct-reference OBJECT IDENTIFIER OPTIONAL,

indirect-reference INTEGER OPTIONAL,

data-value-descriptor ObjectDescriptor OPTIONAL

encoding CHOICE

{ single-ASN1-type [0] ANY,

octet-aligned [1] IMPLICIT OCTET STRING,

arbitrary [2] IMPLICIT BIT STRING}

}

 

La sintaxis de los nombres abstractos se transfieren como un nombre del tipo "OBJECT IDENTIFIER" y "Presentation Context Identifiers" (PCI) como un nombre del tipo "INTEGER" . La gestión de la capa de presentación hace al menos una referencia a "direct-reference" o "indirect-reference" obligatoriamente. Cada nombre de un identificador de una sintaxis abstracta puede ser dado por un P-usuario(sender). Se transfiere la sintaxis, luego se gestiona, se establece la conexión y se transifieren sus PCIs(para la interpretación de los valores de los datos).

Cuando los valores de los datos son una instancia de tipos simples de ASN.1, se aplican a los tipos de datos, las reglas estándar de codificación. Sino el usuario tiene que elegir entre "octet-aligned" o "arbitrary" si el valor del dato es un número entero de octetos. Pero sólo puede utilizar "arbitrary" si el valor del tipo no es un múltiplo de octetos.

Por ejemplo, suponemos que durante la gestión, el PCI de 7 está asignado a un tipo "string" por un estándar no ASN.1 y ese

String ::= EXTERNAL

está definido en ASN.1. Entonces una instancia de String es

{

indirect-reference 7,

encoding arbitrary BIT STRING

' 27ABC63'H

}

 

Donde "arbitrary" se elige para codificar y la cadena hexadecimal es la representación actual del "string" transmitido.

 

 

El tipo de "tag" es "UNIVERSAL 8".

 

6. RASGOS ADICIONALES.

 

ASN.1 también define una notación para subtipos y conjuntos de valores, y métodos para manejar la recursividad en los tipos de datos. Frecuentemente se usan subtipos y recursividad en las macros.

6.1 La notación de los subtipos y conjunto de valores.

Frecuentemente nos encontramos situaciones donde sólo nos interesa una porción de un conjunto de valores o sólo nos interesa una parte de la secuencia. Por ejemplo, podemos estar interesados sólo en los divisores de 24, valores entre dos enteros, o las primeras 9 personas en una cola. ASN.1 permite subtipos que le permiten a un usuario que especifique valores dentro del rango de valores de un tipo.

Un subtipo está derivado de un tipo padre con alguna restricción hacia el conjunto de valores del tipo padre. Esto es, el conjunto de valores para el subtipo es un subconjunto de valores del tipo padre. El proceso de crear subtipos puede extenderse a más de un nivel. Es decir, un subtipo puede ser al mismo tiempo, padre de otros subtipos y subtipo de otro.

La notación del valor de un subtipo es como la del tipo del padre.

6.1.1 La notación ASN.1

La notación del tipo es la unión del conjunto de valores entre paréntesis separados por el símbolo "|" que tiene el significado de "or", como en BNF.

ASN.1 definen seis formas de anotación para los conjuntos de valores.

Ejemplos de cinco de ellos - SingleValue, ContainedSubtype, ValueRange, PermittedAlphabet, SizeConstraint y InnerType.

6.1.2 Single value:

Un subtipo "valor simple" es una lista explícita de todos los valores que puede tomar el subtipo. Por ejemplo:

Sucesion ::= INTEGER (2 | 5 | 7 | 11 | 13 | 17 | 19 | 23 | 29).

En este caso Sucesion es un subtipo del tipo "INTEGER".

Otro ejemplo:

Meses ::= ENUMERATED ( enero (1),febrero (2),

marzo (3),abril (4),

mayo (5),junio (6),

julio (7),agosto (8),

septiembre (9),octubre (10),

noviembre (11),diciembre (12) )

Primer-Trimestre ::= ( enero | febrero| marzo)

Segundo-Trimestre ::= ( abril | mayo | junio )

Primer-trimestre y segundo trimestre son subtipo del tipo Meses.

 

6.1.3 Contained subtype

 

El "tipo contenido" se usa para nuevas formas de subtipos a partir fr subtipos ya existentes. El " tipo contenido" contiene todos los valores de los subtipos que contiene. Por ejemplo:

Medio-Año :: = Meses ( INCLUDES Primer-Trimestre | INCLUDES Segundo-Trimestre)

Un "tipo contenido" también puede incluir lista de valores explicitos:

Mezcla ::= Meses (INCLUDES Primer-Trimestre | abril )

6.1.4 Value range.

 

El subtipo "rango de valores" se aplica sólo a los tipos INTEGER y REAL. Especifica los valores numéricos dados entre los puntos finales del rango. Se pueden usar los valores especiales "PLUS-INFINITY" y MINUS-INFINITY" . Los valores especiales "MAX" y "MIN" pueden usarse para indicar los máximos y mínimos valores permitidos de los valores del padre. Los intervalos especificados pueden ser abiertos o cerrados. Cuando es abierto, la especificación del punto final es el símbolo "menor que" (<).

Ejemplos:

Las siguientes definiciones son equivalentes:

EnterosPositivos ::= INTEGER (0< .. PLUS-INFINITY)

EnterosPositivos ::= INTEGER (1 .. PLUS-INFINITY)

EnterosPositivos ::= INTEGER (0< .. MAX)

EnterosPositivos ::= INTEGER (1 .. MAX)

 

Las siguientes definiciones son equivalentes:

EnterosNegativos ::= INTEGER (MINUS-INFINITY .. < 0)

EnterosNegativos ::= INTEGER (MINUS-INFINITY .. -1)

EnterosNegativos ::= INTEGER (MIN .. < 0)

EnterosNegativos ::= INTEGER (MIN .. -1)

 

6.1.5 Permitted Alphabet.

 

El subtipo "alfabeto permitido" sólo puede ser aplicado al tipo "character string". Un "alfabeto permitido" se compone de todos los valores que pueden ser construídos usando un subalfabeto de tipo padre.

 

Ejemplo:

TouchToneButtons ::= IA5String ( FROM ( "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "*" | "#" ) )

 

CadenaDigitos ::= IA5String ( FROM ( "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ) )

 

6.1.6 Size Constraint.

 

El subtipo "tamaño obligado" limita el número de elemento de un tipo. Puede ser aplicado solamente al tipo "string" (bit string, octet string, character string) y a los tipos "sequence of" y "set of" . El elemento que obliga, depende del tipo padre, como sigue.

Tipo Unidad de medida

bit string bit

octet string octet

character string character

sequence-of valor del componente

set-of valor del componente

Un ejemplo de tipo "string", Recommendation X.121 especifica que los números internacionales de datos, están especificados por la dirección del sistema final de datos públicos en una network, incluyendo la X.25 network, que debería consistir en al menos 5 dígitos pero no más de 14 dígitos. Esto se puede especificar como sigue:

ItlDataNumber ::= DigitString ( SIZE (5 ..14) ).

Ahora consideremos un parámetro de una lista para mensajes que puede incluir 12 parámetros:

ParameterList ::= SET SIZE (0 .. 12) OF Parameter

 

6.1.7 Inner subtyping

Un "subtipo interno" sólo puede ser aplicado a los tipos "sequence", "sequence-of", "set" , " set-of" y "choice". Un subtipo interno incluye sólo algunos valores del tipo padre que cumplen una o más condiciones presentadas con los valores and/or de los componentes del tipo padre. Este es un subtipo muy complejo., y aqui sólo se dan unos pocos ejemplos.

Consideremos una unidad de protocolo de datos(PDU) que puede tomar cuatro valores distintos, no en un orden particular:

PDU ::= SET {alpha [0] INTEGER,

beta [1] 2 IA5String,

gamma [2] SEQUENCE OF Parameter,

delta [3] BOOLEAN}

 

El siguiente código especificará un test que requiere el valor booleano para ser falso y el valor entero para ser negativo:

TestPDU ::= PDU (WITH COMPONENTS

{......... delta (false), alpha (MIN ... < 0 ) } )

Una nueva representación del parámetro beta se presenta en longitud cada 5 oó 12 caracteres, consideremos el siguiente código:

FutherTestPDU ::= TestPDU (WITH COMPONENTS

{....beta (SIZE (5 | 12) PRESENT} )

En otro ejemplo, consideramos el uso de un subtipo interno en una secuencia de constructores:

Text-block ::= SEQUENCE OF VisibleString

Address ::= Text-block ( SIZE (1..6) | WITH COMPONENT (SIZE (1..32) ) ) )

Estos indican que las dirección contiene desde 1 a 6 bloques de texto y que cada bloque de texto contiene de 1 a 32 caracteres de longitud.

6.2 La recursividad.

 

La recursividad, es un rasgo común de los lenguajes de alto nivel, y también es un rasgo en ASN.1 . Los tipos de datos, como un conjunto de conjuntos, registros con uno o más componentes siendo un registro, uniones de listas, y árboles, pueden ser mejor comprendidas cuando vemos una estructura recursivas. ASN.1 permite definiciones de esos emparentados tipos de datos y valores incluidos en la recursividad. Por ejemplo, las uniones de listas de valores de enteros, en cada nodo puede ser una unión de listas de valores de enteros, está especificada:

LinkedList ::= SEQUENCE

{

label IASString,

value CHOICE

{ nodevalue INTEGER OPTIONAL,

node SEQUENCE OF LinkedList OPTIONAL

}

}

Asumir la "L", mostrada en la figura, como una instancia consistente en el tipo LinkedList de cuatro nodo etiquetados con A, B, C, D donde B es una unión de de listas de tres nodos B1, B2, B3 y B3 a su vez es una unión de dos nodos B31, B32. Los nodos cabecera no están incluídos en este ejemplo. Luego, la instancia puede ser representada:

{

label "L"

value node

{

{label "A", value nodevalue 75},

{label "B",

value node

{

{label "B1", value nodevalue 60},

{label "B2", value nodevalue 50},

{label "B3",

value node

{

{label "B31", value nodevalue 48},

{label "B32", value nodevalue 46},

}

}

}

{label "C", value nodevalue 35},

{label "D", value nodevalue 15},

}

 

6.3 MACROS

Esta notación permite al usuario extender la sintaxis de ASN.1 para definir nuevos tipos y sus valores.

Consideramos lo siguientes puntos:

  1. Hay tres niveles, que deben ser cuidadosamente distinguidos:
  • La notación de macro, usada para definir macros
  • La definición de macro, expresada en la notación macro y usada para definir un conjunto de instancias de macros.
  • Una instancia de macro, generada por una definición de macro sustituyendo valores por variables.
  1. La definición de una macro funciona como un "Super Tipo" generando una clase de instancias de macro que funciona exactamente como un tipo básico de ASN.1.
  2. Una definición de macro puede ser vista como un patrón que es usado para generar conjuntos de tipos relativos y valores.
  3. La macro es usada para extender la sintaxis de ASN.1 pero no para extender su codificación. Cualquier tipo definido por el significado de una instancia de macro es solamente un tipo de ASN.1, y se codifica como tal.
  4. Además de definir convenientemente conjuntos de tipos relativos la definición de una macro permite que el usuario incluya información semántica con el tipo.

 

7. Ejemplo

Esta sección da un ejemplo de la notación ASN.1 y codificación DER : el tipo Name[8] de X.501.

 

7.1 La notación abstracta

Esta sección da la notación ASN.1 para el tipo Name de X.501.

Name ::= CHOICE {

RDNSequence }

 

RDNSequence ::= SEQUENCE OF RelativeDistinguishedName

RelativeDistinguishedName ::= SET OF AttributeValueAssertion

AttributeValueAssertion ::= SEQUENCE {

AttributeType,

AttributeValue }

 

AttributeType ::= OBJECT IDENTIFIER

AttributeValue ::= ANY

El tipo Name identifica un objeto en un directorio de X.500 [15]. Name es un tipo CHOICE que consta de una alternativa: RDNSequence.

El tipo RDNSequence da un path(direccion) a un directorio X.500 que empieza en el root(raiz).

RDNSequence es un tipo SEQUENCE OF consistente en cero o más ocurrencias de RelativeDistinguishedName.

El tipo RelativeDistinguishedName da un nombre único a un objeto relativo al objeto superior a él en el directorio del árbol.

RelativeDistinguishedName es un tipo SET OF que consta de ceros o más ocurrencias de AttributeValueAssertion.

El tipo AttributeValueAssertion le asigna a un valor a alguno de los atributos relativo nombre seleccionado, como un nombre country o como un nombre común.

AttributeValueAssertion es un tipo SEQUENCE OF que consta de dos componentes, un tipo AttributeType y un tipo AttributeValue.

El tipo AttributeType identifica un atributo por object identifier.

El tipo AttributeValue da un valor a un atributo arbitrario. (El tipo actual de el valor del atributo es pensado para determinar por el tipo atributo , aunque ANY DEFINED BY no se emplea.)

7.2 DER codificación

Esta sección da un ejemplo de la codificación DER de un valor de tipo Name , trabajando de abajo arriba.

El nombre es ese de RSA Data Security, Inc's. "NOTARY" unidad para Internet Privacy-Enhaned Mail[ 16,17], que se representa por el path siguiente:

 

(root)

|

countryName = "US"

|

organizationName = "RSA Data Security, Inc."

|

organizationalUnitName = "NOTARY

Cada nivel corresponde a un valor RelativeDistinguishedName , cada uno de los cuales, consta de un valor AttributeValueAssertion. El valor AttributeType esta antes del signo igual, y el valor AttributeValue (un printable string para los tipos de atributos) esta después del signo igual.

AttributeType

La codificación del valor del árbol AttributeType sigue la primitive, método definite-lenght, resultando el siguiente OCTET STRING:

06 03 55 04 06 countryName

06 03 55 04 0a organizationName

06 03 55 04 0b organizationalUnitName

Aquí 'countryName', 'organizationName', y 'organizationalUnitName' son tipos de atributos X.520 [14], que tienen las siguientes definiciones :

AttributeType OBJECT IDENTIFIER::=

{ joint-iso-ccitt (2) ds (5) 4}

countryName OBJECT IDENTIFIER::={attributeType 6}

organizationName OBJECT IDENTIFIER::={attributeType 10}

organitationUnitName OBJECT IDENTIFIER ::=

{attributteType 11}

 

 

El identificador de octetos sigue la forma low-tags, como es una marca 6 para OBJECT IDENTIFIER. Los bits 7 y 8 tienen valor" 0", indicando la clase universal, y el bit 6 tiene valor" 0", que indica que la codificación es primitived. La longitud del octeto sigue la forma corta.

El contenido de los octetos es el encadenamiento de arboles octet string derivados de los subidentificadores.

subidentifiers: 85= 40+ 2+ 5; 4; y 6, 10, ó 11.

AttributeValue

La codificación DER de los valores del árbol AttributeValue siguen la primitive, método definite-lenght, resultando los siguientes octets strings:

13 02 55 53 "US"

13 17