modul OpenSSL::ASN1

Abstract Syntax Notation One (oder ASN.1) ist eine Notationssyntax zur Beschreibung von Datenstrukturen und ist in ITU-T X.680 definiert. ASN.1 selbst schreibt keine Kodierungs- oder Parsing-Regeln vor, aber normalerweise werden ASN.1-Datenstrukturen mit den Distinguished Encoding Rules (DER) oder seltener mit den Basic Encoding Rules (BER) kodiert, die in ITU-T X.690 beschrieben sind. DER- und BER-Kodierungen sind binäre Tag-Length-Value (TLV) Kodierungen, die im Vergleich zu anderen gängigen Datenbeschreibungsformaten wie XML, JSON usw. recht prägnant sind. ASN.1-Datenstrukturen sind in kryptografischen Anwendungen sehr verbreitet, z. B. sind X.509-öffentliche Schlüsselzertifikate oder Zertifikatsperrlisten (CRLs) alle in ASN.1 definiert und DER-kodiert. ASN.1, DER und BER sind die Bausteine der angewandten Kryptografie. Das ASN1 Modul stellt die notwendigen Klassen bereit, die die Erzeugung von ASN.1-Datenstrukturen und die Methoden zu deren Kodierung mittels DER-Kodierung ermöglichen. Die decode-Methode erlaubt das Parsen beliebiger BER-/DER-kodierter Daten in ein Ruby-Objekt, das dann nach Belieben modifiziert und neu kodiert werden kann.

ASN.1-Klassen-Hierarchie

Die Basisklasse für ASN.1-Strukturen ist ASN1Data. ASN1Data bietet Attribute zum Lesen und Setzen des Tags, der Tag-Klasse und schließlich des Wertes eines bestimmten ASN.1-Elements. Beim Parsen werden alle getaggten Werte (implizit oder explizit) durch ASN1Data-Instanzen repräsentiert, da ihr „echter Typ“ nur mithilfe von Out-of-Band-Informationen aus der ASN.1-Typdeklaration ermittelt werden kann. Da diese Information normalerweise beim Kodieren eines Typs bekannt ist, bieten alle Unterklassen von ASN1Data ein zusätzliches Attribut tagging, das es ermöglicht, einen Wert implizit (:IMPLICIT) oder explizit (:EXPLICIT) zu kodieren.

Constructive

Constructive ist, wie der Name schon sagt, die Basisklasse für alle konstruierten Kodierungen, d. h. solche, die aus mehreren Werten bestehen, im Gegensatz zu „primitiven“ Kodierungen mit nur einem einzigen Wert. Der Wert eines Constructive ist immer ein Array.

ASN1::Set und ASN1::Sequence

Die gebräuchlichsten konstruierten Kodierungen sind SETs und SEQUENCEs, weshalb es zwei Unterklassen von Constructive gibt, die jeweils eine davon repräsentieren.

Primitive

Dies ist die Oberklasse aller primitiven Werte. Primitive selbst wird beim Parsen von ASN.1-Daten nicht verwendet. Alle Werte sind entweder Instanzen einer entsprechenden Unterklasse von Primitive oder Instanzen von ASN1Data, wenn der Wert implizit oder explizit getaggt war. Bitte siehe Primitive Dokumentation für Details zu Unterklassen und deren jeweilige Abbildungen von ASN.1-Datentypen auf Ruby-Objekte.

Mögliche Werte für tagging

Beim Erstellen eines ASN1Data-Objekts kann die ASN.1-Typdefinition erfordern, dass bestimmte Elemente entweder implizit oder explizit getaggt werden. Dies kann durch manuelles Setzen des tagging-Attributs für Unterklassen von ASN1Data erreicht werden. Verwenden Sie das Symbol :IMPLICIT für implizites Tagging und :EXPLICIT, wenn das Element explizites Tagging erfordert.

Mögliche Werte für tag_class

Es ist möglich, beliebige ASN1Data-Objekte zu erstellen, die auch eine PRIVATE- oder APPLICATION-Tag-Klasse unterstützen. Mögliche Werte für das tag_class-Attribut sind:

Tag-Konstanten

Für jeden universellen Tag ist eine Konstante definiert

UNIVERSAL_TAG_NAME Konstante

Ein Array, das den Namen einer gegebenen Tag-Nummer speichert. Diese Namen sind dieselben wie der Name der zusätzlich definierten Tag-Konstante, z. B. UNIVERSAL_TAG_NAME[2] = "INTEGER" und OpenSSL::ASN1::INTEGER = 2.

Beispielverwendung

Dekodieren und Anzeigen einer DER-kodierten Datei

require 'openssl'
require 'pp'
der = File.binread('data.der')
asn1 = OpenSSL::ASN1.decode(der)
pp der

Erstellen einer ASN.1-Struktur und deren DER-Kodierung

require 'openssl'
version = OpenSSL::ASN1::Integer.new(1)
# Explicitly 0-tagged implies context-specific tag class
serial = OpenSSL::ASN1::Integer.new(12345, 0, :EXPLICIT, :CONTEXT_SPECIFIC)
name = OpenSSL::ASN1::PrintableString.new('Data 1')
sequence = OpenSSL::ASN1::Sequence.new( [ version, serial, name ] )
der = sequence.to_der