Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gen 2.0 support #65

Open
OscarKro opened this issue Aug 20, 2021 · 12 comments
Open

Gen 2.0 support #65

OscarKro opened this issue Aug 20, 2021 · 12 comments

Comments

@OscarKro
Copy link

For some reason I can't see the Gen 2.0 support issue so I'll post a new one I quess?

I've been asked to look into rebuilding this library to support Gen 2.0 by someone. So i'm looking into it now to get a rough idea of the amount of work. How far along is it right now? I've tried it on a file and got "First unrecognised region with magic 0 at 0x0000
There were 5219 unmatched regions (magics) in the file." So my quess is it doesn't work yet.

I've worked on a pretty big project where I created software to read digital and smart tachographs out over the net. So I'm a little bit informed in the world of tachographs and the annexes. Can't say I know everything or understand, but I know some stuff. Perhaps I can be of help.

@rimutaka
Copy link
Collaborator

Oscar, I had a client who needed v.2 support. My estimate was 1 - 2 months of work to do it properly. They could not justify the cost, so it was put on hold.
The spec looks mind-boggling with its collection of amendments the last time I looked at it. Just wrapping one's head around it all would take time.

The region mapping is not the biggest problem - it's knowing what to map (back to the spec). There is also the signing that needs to be taken care of.

There are proprietary implementations of v.2, so there is hope.

My client may be interested in co-funding the development.

@OscarKro
Copy link
Author

OscarKro commented Aug 20, 2021

Hey @rimutaka,

Thanks for the reply. I'm getting the same feeling about the amount of time needed to do this as well. Same story, A client requested this. I'll keep you updated if anything comes up or the client is willing to co-fund or whatever construction we can think of.

@graealex
Copy link

graealex commented Mar 13, 2023

My 2 cents on the issue. And a bit of rambling. I have created a proprietary library that can import and export DDD structures (and manipulate, import and export them as XML as well). The EU and the device makers have gone to great lengths to make implementation as hard as possible. Not only is the format a mish-mash of hand-crafted binary structures, where in some places space is abundant, and in some places arbitrary length restrictions apply and binary packing tricks are employed, but also ASN.1 and TLV structures. It gets even worse when you shift from the driver cards to the VU transfer protocol (which I also support). In addition, they managed to sprinkle the relevant information over 600 pages of PDF, with the important syntax information put in as JPEGs, despite the fact that PDFs are capable of type setting any complex text layout, and instead of providing one consolidated syntax file. I can barely afford the development as a commercial project, and I have little hopes of any open-source project being able to catch up soon.

And then there is shit like this, just for fun:
EU-Mist

@OscarKro
Copy link
Author

OscarKro commented Mar 29, 2023

Yeah it's complete bullshit. I'm now trying to implement the second generation structure as well. I cant even find documentation describing how the second generation is different from the first. This is such a complete rabbit hole... I feel you. Kudo's for getting this far, i'm not even close.

@jugglingcats
Copy link
Owner

@OscarKro, @rimutaka it is a terrible spec! Really awful. I spent many hours looking at hex dumps...

@graealex
Copy link

Yes, the spec is bad. Here it is, with the images in the PDF ran through OCR.
CELEX_02016R0799-20230821_EN_TXT_AG.pdf

@OscarKro
Copy link
Author

Super man! thanks. See if I can make heads or tails of it.

@tyekx
Copy link

tyekx commented Apr 1, 2023

Aside from the jpegs as tables its workable. Annoying to find that few important tables in 600 pages... anyone figured out how to load the cert into openssl maybe? feels kinda hacky to just set the public key. I would've assumed its a well known cert format

@graealex
Copy link

graealex commented Apr 1, 2023

It is a well-known cert format, so called "Card Verifiable Certificate". Unfortunately you need to buy the ISO/IEC 7816-8 for a full specification on the format.

@graealex
Copy link

graealex commented Apr 1, 2023

This gist might help you with parsing of the TLV data contained in a CV certificate. It's basically the ISO/IEC 7816-6 spec ("Interindustry data elements for interchange") put into a well-documented enum. The TLV Utilities can also be quite helpful.

@Gen1Pokiman
Copy link

I can easily update this library to support parsing Gen2 and Gen2v2 files. Contact me if you would like to share the development costs: [email protected]

@tyekx
Copy link

tyekx commented Oct 1, 2024

Aside from the jpegs as tables its workable. Annoying to find that few important tables in 600 pages... anyone figured out how to load the cert into openssl maybe? feels kinda hacky to just set the public key. I would've assumed its a well known cert format

So I got a little time and I also have a lot more experience so I tinkered around a bit with gen2 signatures and keys. I got it working, at least specifically targeting the prime256v1 sha256 cs, in the table its referred to as CS#1. Anyways, I wrote a little cpp code to verify the message signatures, i tried many many many DER functions of openssl, nothing seemed to work, so i said F that im just going to manually extract the pieces from the binary and get to work.

As noted in the docs, find the CardSignCertificate 'file' and in that you can find 204 bytes or more depending on the algo. From that I extracted the pub key. It starts with 7f 49 magic constant, then 1 byte length ofc, then an object id, in my case 10 bytes. This ID can be used to identify your algorithm just fine. Then read the key, for prime256v1, its 65 bytes, ofc the sneaky bit is that the first byte is 04, skip that, then 2x32 bytes of affine coordinates for the algorithm, i just slurped that:

EC_KEY* ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
BIGNUM* x = BN_bin2bn(pubkey.offset(1).data(), 32, nullptr);
BIGNUM* y = BN_bin2bn(pubkey.offset(33).data(), 32, nullptr);
EC_KEY_set_public_key_affine_coordinates(ec, x, y);

Then i created the public key:

EVP_PKEY* pk = EVP_PKEY_new();
EVP_PKEY_set1_EC_KEY(pk, ec);

Then you are ready to verify a signature. The signature is again 2x32 bytes of r and s parameters from the algorithm:

ECDSA_SIG* es = ECDSA_SIG_new();
BIGNUM* r = BN_bin2bn(sig.offset(0).data(), 32, nullptr);
BIGNUM* s = BN_bin2bn(sig.offset(32).data(), 32, nullptr);
ECDSA_SIG_set0(es, r, s);

Almost finally, calculate the digest for your message you want to check, the algorithm can be deduced from the cipher suit in the docs. You detect the EC algo first, then pair the noted hash function, in my example, SHA256

U8 digest[SHA256_DIGEST_LENGTH];
SHA256(sauce.data(), sauce.size(), digest);

Then finally verify:

int rv = ECDSA_do_verify(digest, SHA256_DIGEST_LENGTH, es, ec);
// rv=1: valid

I hope someone comes across this and just replies with 'oh why not just use this and this function' :D... not the prettiest, but it does verify the HMAC. Onwards to verify the cert chain :)

It is a well-known cert format, so called "Card Verifiable Certificate". Unfortunately you need to buy the ISO/IEC 7816-8 for a full specification on the format.

also CBA with standards costing 150 chf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants