[Python-de] BER-TLV

"Martin v. Löwis" martin at v.loewis.de
Do Jan 3 20:58:17 UTC 2008


> Eine formale ASN.1 spec habe ich leider nicht.

Auf Basis des Beispiels würde ich sowas schreiben:

XXX DEFINITIONS ::=
BEGIN

   Prefix ::= [PRIVATE 25] [PRIVATE 44] IMPLICIT INTEGER
   MID ::= [PRIVATE 6] IMPLICIT INTEGER
   CardID ::= [PRIVATE 96] IMPLICIT INTEGER

   EMV ::= [PRIVATE 2] IMPLICIT SEQUENCE {
        mID MID,
        cardID CardID,
        f1 [PRIVATE 17] IMPLICIT SEQUENCE {
           f90 Prefix,
           f91 Prefix,
           f92 Prefix
        }
   }
END

Statt SEQUENCE kann es sich natürlich auch um SET handeln,
und ob die Basistypen alle INTEGER sind, kann man aus dem Code
auch nicht ersehen.

> Die Spec beschreibt nur  die Encoding der TAG und des length  fields.
> In der Zwischenzeit habe ich experimentirtund fuege das Ergebnis an.
> Die ersten drei Elemente funktionieren soweit gut.
> Aber wie kann ich die Elemente von F1 fuellen?

Wenn ich es richtig verstehe, handelt es sich um 3 Felder des gleichen
Typs - nämlich eines INTEGERs (vermutlich - Du gibst ihre Werte mit
671, 670, 490 an; richtig wäre 0x617F, 0x610F, 0x490F). Diese Felder
haben kein Universal-Tag (deshalb IMPLICIT); davor ein privates Tag
44 (kodiert in 2 Bytes); davor ein privates Tag 25.

Anbei mein Code. Es kommt nicht ganz dieselbe Bytefolge raus, nämlich

e220c60200a6df600200a6f115f905df2c02671ff905df2c02670ff905df2c02490f

Soweit ich sehen kann, ist dass aber auch richtig, weil [PRIVATE 6]
nicht unbedingt als DF06 kodiert werden muss; C6 tut's auch.

Ciao,
Martin

from pyasn1.type import univ, tag, namedtype, namedval, constraint
from pyasn1.codec.ber import encoder, decoder
import binascii

def private(N,base=False):
    return base.tagExplicitly(tag.Tag(tag.tagClassPrivate,
                                      tag.tagFormatConstructed,
                                      N))

def private_i(N,base):
    return base.tagImplicitly(tag.Tag(tag.tagClassPrivate,
                                      base[-1][1],
                                      N))


class Prefix(univ.Integer):
    tagSet = private(25, private_i(44, univ.Integer.tagSet))

class DreiMalPrefix(univ.Sequence):
    tagSet = private_i(17, univ.Sequence.tagSet)
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('f90', Prefix()),
        namedtype.NamedType('f91', Prefix()),
        namedtype.NamedType('f92', Prefix())
        )

class MID(univ.Integer):
    tagSet = private_i(6, univ.Integer.tagSet)

class CardID(univ.Integer):
    tagSet = private_i(96, univ.Integer.tagSet)

class EMV(univ.Sequence):
    tagSet = private_i(2, univ.Sequence.tagSet)
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('mID', MID()),
        namedtype.NamedType('cardID', CardID()),
        namedtype.NamedType('f1', DreiMalPrefix())
        )


r = EMV()
r.setComponentByName('mID', 0xA6)
r.setComponentByName('cardID', 0xA6)
f1 = r.setComponentByName('f1').getComponentByName('f1')
f1.setComponentByName('f90', 0x671f)
f1.setComponentByName('f91', 0x670f)
f1.setComponentByName('f92', 0x490f)

int1 = encoder.encode(r)
int2 = binascii.hexlify(int1)
print int2