What's inside my train ticket?

Q Misell

38th Chaos Communication Congress

30th of December 2024

Who am I?

  • Researcher at the Max-Planck Institut für Informatik
  • Runs Glauca Digital
  • Massive nerd about trains 🚂

Things I have to say

The contents of this presentation are derived of my own personal work, and have neither been funded, endorsed, nor sanctioned by the Max-Planck-Gesellschaft zur Förderung der Wissenschaften e. V., the German Government, the Verband Deutscher Verkehrsunternehmen e.V., the Union internationale des chemins de fer, the European Union Agency for Railways, the Rail Delivery Group Limited, any of their respective members, or anyone else I may be about to annoy.

What will I be covering?

  • I am from Wales 🏴󠁧󠁢󠁷󠁬󠁳󠁿 (the UK 🇬🇧)
  • I live in Germany 🇩🇪
  • I have very little experience of non InterRail travel elsewhere

What is a train?


© Sebastian Terfloth - CC BY-SA


© Union internationale des chemins de fer

Digitalisierung!

Types of digital tickets

  1. The UIC barcodes
    1. Ticket Layout Barcode
    2. Flexible Content Barcode
    3. Small Structured Barcode
    4. Element List Barcode
  2. VDV-KA Barcode
  3. RSP Barcodes
  4. Some other weird bits

UIC barcodes

TAP TSI TD B.12


UIC Envelope


                #UT02510100001<load of binary data>1337<some more binary data>
            
Type Start Length (bytes)
Fixed #UT ASCII 0 3
Version - currently 01 or 02 ASCII 3 2
RICS - e.g. 1080 for DB AG ASCII 5 4
Key ID ASCII 9 5
DSA signature Bytes 14 50
Data length ASCII 64 4
DEFLATE compressed data Bytes 68 ...

DSA signatures?

These can be insecure if done wrong - please give me your tickets!

Details on how to later in the talk.

What's a RICS?

Railway Interchange Coding System - Company Codes

Get your own RICS

Its free!
uic.org/rics

Signatures

Version Signature Encoding
1 SHA-160, DSA-512
SHA-160, DSA-1024
ASN.1
2 SHA-224, DSA-2048
SHA-256, DSA-2048
(r, s) as concatenated 32-bit integers

Public keys?

Most are published, some are not 😕

railpublickey.uic.org

Anyone have any non-public public keys? Send them to q@magicalcodewit.ch.

Contents


                U_HEAD011337...
            
Type Start Length
Field ID ASCII 0 5
Version ASCII 5 2
Data length ASCII 7 4
Data Bytes 11 ...

U_HEAD record


                5101N1PWCKWX            2010202423170DEEN
            
Start Length
RICS 0 4
Ticket ID 4 20
Issuing time - DDMMYYYYHHMM 24 12
Flags
  • 1: International ticket
  • 2: Edited by agent
  • 4: Specimen
36 1
Primary language 37 2
Secondary language 39 2

U_TLAY record


                RCT200151221012000016Hack the planet!...
            
Start Length
Layout standard 0 4
Field count 4 4
Field line 8 2
Field column 10 2
Field height 12 2
Field width 14 2
Flags
  • 1: Bold
  • 2: Italic
  • 4: Small font
16 1
Text length 17 4
Text 21 ...


© European Union Agency for Railways

U_FLEX record

ASN.1 Unaligned Packed Encoding Rules (UPER)

UnionInternationalCheminsdeFer / UIC-barcode
misc/uicRailTicketData_v3.0.3.asn


                UicRailTicketData ::= SEQUENCE {
                  issuingDetail       IssuingData,
                  travelerDetail      TravelerData                OPTIONAL,
                  transportDocument   SEQUENCE OF DocumentData    OPTIONAL,
                  controlDetail       ControlData                 OPTIONAL,
                  extension           SEQUENCE OF ExtensionData   OPTIONAL,
                  ...
                }
            

                DocumentData ::= SEQUENCE {
                  token  TokenType OPTIONAL,
                  ticket CHOICE {
                    -- Seat reservation
                    reservation            ReservationData,
                    -- AutoZug
                    carCarriageReservation CarCarriageReservationData,
                    openTicket             OpenTicketData, -- Normal ticket
                    pass                   PassData, -- InterRail
                    voucher                VoucherData,
                    customerCard           CustomerCardData, -- BahnCard
                    counterMark            CountermarkData, -- Group tickets
                    parkingGround          ParkingGroundData, -- Car parking
                    fipTicket              FIPTicketData, -- Staff ticket
                    stationPassage         StationPassageData,
                    extension              ExtensionData,
                    delayConfirmation      DelayConfirmation,
                    ...
                  },
                  ...
                }
            

Private use records

RICS + 2 chars

Shove anything you want inside!

Some examples
  • 5008TI - Deutchlandtarifverbund ticket data
  • 5008PA - Deutchlandtarifverbund passenger data
  • 0080BL - DB old style tickets, pre flex
  • 0080VU - DB VDV data (CityTicket, etc.)
  • 1154UT - České dráhy data
  • 118199 - Inexplicable ÖBB JSON

SSB Envelope

Type Start Length (bits)
Version - currently 3 Int 0 4
RICS Int 4 14
Key ID Int 18 4
Ticket type Int 22 5
Data 27 437
DSA r Int 464 224
DSA s Int 688 225

Always 114 bytes. Ticket type values 0 to 20 are well-known, 21 to 31 are private use.

Type 1 - Integrated Reservation Ticket

6-bit ASCII

6-bit integer sequence
ASCII code point: (i + 0x20)

NS KeyCards

SSB private type 21

Type Start Length (bits)
Unknown data 0 21
Card ID 6-bit ASCII 21 84
Issuing year Int 105 4
Issuing day Int 109 9
Unknown data 118 11
Validity start day Int 129 9
Validity end day Int 138 12
Unknown data Int 150 1
Extra text 6-bit ASCII 151 216
Station ID Int 367 17
Unknown data - likely padding Int 384 79

Eurostar

  • Eurostar uses ELB barcodes
  • They're kinda boring
  • See the TAP TSI for details
  • ✨ No signatures ✨

VDV-KA Barcodes

This is where the fun reverse engineering starts!

  • Heavy use of BER-TLV
  • ISO 9796-2 Message Recovery Signatures

ISO want 194CHF for 9796-2, come talk to me afterwards if you want a copy.

VDV Envelope

Tag Contents
0x9E ISO 9796-2 Signature
0x9A ISO 9796-2 Signature remainder
0x7F21 Signing certificate
0x42 CA reference

CA reference

Somewhat like X.509 Authority Key Identifier

Type Start Length (bytes)
Name ASCII 0 5
Service indicator Int 5 1
Algorithm reference Int 6 1
Year - start from 1990 (reunification) Int 7 1

VDV Certificate

Tag Contents
0x5F4E Certificate content
-- OR --
0x5F37 Certificate signature
0x5F38 Certificate signature remainder

Chain of trust

  1. VDV Root CA
    ("EUVDV", 16, 1, 1996)
  2. Company CA
  3. Envelope Cert
  4. Ticket

ISO 9796-2 means we need the public keys to read anything.
Only the root CA is without a message recovery signature - we need the entire chain to read the ticket.

Where are the certs?

Enter the open LDAP server

ldaps://ldap-vdv-ion.telesec.de:636

ou=VDV KA,o=VDV Kernapplikations GmbH,c=de

Signature validation process

  1. Read barcode
  2. Decode VDV envelope
  3. Find company cert by envelope CA reference
  4. Decrypt company cert with root CA
  5. Decrypt envelope cert with company cert
  6. Decrypt ticket data with envelope cert

/wp-uploads to the resuce!

Danke schön Kompetenzcenter Digitalisierung NRW und Main-Taunus-Verkehrsgesellschaft!

Ticket format

Start Length (bytes)
Header 0 18
Product data (BER-TLV) 18 n
Common transaction data n + 18 17
Product transaction data (BER-TLV) n + 35 i
Ticket issue n + i + 35 12
Trailer end - 5 5

Header format

Type Start Length (bytes)
Ticket ID Int 0 4
Ticket Org-ID Int 4 2
Product ID Int 6 2
Product Org-ID Int 8 2
Validity start Datetime 10 14
Validity end Datetime 14 4

VDV Datetime

Start Length (bits)
Year - starting from 1990 0 7
Month 7 4
Day 11 5
Hour 16 5
Unused 21 2
Minute 23 4
Second 27 5

Where to get the list of Org-IDs?

https://pro.eticket.app/api/organisations/all
Username eticket-app-pro, password VDV-K3rn4ppl!kat1on

hvv Card Info app


© Hamburger Hochbahn AG

Product data

  • 0xDA - Basic data
  • 0xDB - Passenger data
  • 0xDC - Spacial validity
  • 0xDE - Private use
  • 0xD7 - Identification medium

Passenger data

  • ISO 8859-15 encoding - same as health insurance cards
  • Type 1: Forename#Surname
  • Type 2: F6e@S5e

Spacial validity

Identification medium

  • Girocard der deutschen Kreditwirtschaft (EC-Karte)
  • Kreditkarte
  • Personalausweis
  • Telefonnummer
  • Sozialpass
  • Schüler-/Studentenausweis

RSP barcodes

  • Used on UK trains
  • Also uses message recovery signatures, but a custom kind
  • Much of the work on these done by eta
  • Go read her excellent post "Reversing UK mobile rail tickets"

SNCF

SNCF have ~5 different custom ticket types
I don't have time to cover these

Look into your tickets

vdv-pkpass.magicalcodewit.ch

TheEnbyperor / vdv-pkpass

Some other features of VDV PKPass

  • Automatically updating DB and SaarVV D-Tickets
  • Pulling new tickets from DB account

How do I make my own?

  • Get a RICS
  • Generate a DSA key (ew)
  • ???
  • Profit!

If you do this and want your public keys in VDV PKPass drop me an email

Thank you! Questions?

Come donate your tickets at the Shark Corner - for science!

Email: q@magicalcodewit.ch
Fedi: q@glauca.space

Slides at magicalcodewit.ch/38c3-slides/