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

WIP: Support for Portuguese Electronic ID Cards #208

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

jpbarraca
Copy link

@jpbarraca jpbarraca commented Sep 3, 2021

Support for PTEID cards was added, while replicating the structure from official development cards.

It currently seems to work ok through PKCS11 using pkcs11-tool and objects follow the same structure as official cards. Some objects (2-3 actually) still need work as the structure needs to be understood and they need to be recreated.

Included is a generator tool able to create the cryptographic objects. Future work will focus on the PTEID specific objects (address, picture, PTEID file blob).

Features added by analyzing public documentation and some reverse engineering with actual cards... some things may be incorrectly implemented.

EDIT:
To test one needs to go to pteid and python3 generate_pteid_card.py, which will produce a set of certificates a card.json.
This file should be copied to the location of the vicc file.
Then, start vicc with vicc -t PTEID

On another terminal, to generate a signature.
pkcs11-tool --login --sign -i input_file --pin 1111 -o signature -m RSA-PKCS

Most of other methods will also work.

Copy link
Owner

@frankmorgner frankmorgner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks quite interesting.

Sorry, that you stumbled across some of the problems that were introduced when migrating to python 3.

did you think about adding some automated testcase for opensc to check if pteid still works?

@@ -101,10 +101,10 @@ def __set_algo(self, data):
:param data: reference to an algorithm
"""

if data not in ALGO_MAPPING:
if data[0] not in ALGO_MAPPING:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you're using the first byte of a binary string here, right?

I think we need to change ALGO_MAPPING to map binary strings to names of algorithms instead of mapping a byte (integer) to algorithms (i.e. we need to change . In nPA.py, for example, you can see a mapping from an OID (binary string) to some algorithm....

diff --git a/virtualsmartcard/src/vpicc/virtualsmartcard/ConstantDefinitions.py b/virtualsmartcard/src/vpicc/virtualsmartcard/ConstantDefinitions.py
index d81e221..c2ebf90 100644
--- a/virtualsmartcard/src/vpicc/virtualsmartcard/ConstantDefinitions.py
+++ b/virtualsmartcard/src/vpicc/virtualsmartcard/ConstantDefinitions.py
@@ -215,20 +215,20 @@ CRT_TEMPLATE["CT"] = 0xB8  # Template for Confidentiality
 
 # This table maps algorithms to numbers. It is used in the security environment
 ALGO_MAPPING = {}
-ALGO_MAPPING[0x00] = "DES3-ECB"
-ALGO_MAPPING[0x01] = "DES3-CBC"
-ALGO_MAPPING[0x02] = "AES-ECB"
-ALGO_MAPPING[0x03] = "AES-CBC"
-ALGO_MAPPING[0x04] = "DES-ECB"
-ALGO_MAPPING[0x05] = "DES-CBC"
-ALGO_MAPPING[0x06] = "MD5"
-ALGO_MAPPING[0x07] = "SHA"
-ALGO_MAPPING[0x08] = "SHA256"
-ALGO_MAPPING[0x09] = "MAC"
-ALGO_MAPPING[0x0A] = "HMAC"
-ALGO_MAPPING[0x0B] = "CC"
-ALGO_MAPPING[0x0C] = "RSA"
-ALGO_MAPPING[0x0D] = "DSA"
+ALGO_MAPPING[b'\x00'] = "DES3-ECB"
+ALGO_MAPPING[b'\x01'] = "DES3-CBC"
+ALGO_MAPPING[b'\x02'] = "AES-ECB"
+ALGO_MAPPING[b'\x03'] = "AES-CBC"
+ALGO_MAPPING[b'\x04'] = "DES-ECB"
+ALGO_MAPPING[b'\x05'] = "DES-CBC"
+ALGO_MAPPING[b'\x06'] = "MD5"
+ALGO_MAPPING[b'\x07'] = "SHA"
+ALGO_MAPPING[b'\x08'] = "SHA256"
+ALGO_MAPPING[b'\x09'] = "MAC"
+ALGO_MAPPING[b'\x0A'] = "HMAC"
+ALGO_MAPPING[b'\x0B'] = "CC"
+ALGO_MAPPING[b'\x0C'] = "RSA"
+ALGO_MAPPING[b'\x0D'] = "DSA"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected as you suggested.

"identifier.")
dfname = b"" # make_property("dfname", "string with up to 16 bytes. DF name,"
# "which can also be used as application"
# "identifier.")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why comment this out?

selected = walk(self.currentDF(), data)
except SwError as e:
# If everything fails, look at MF
selected = walk(self, data)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically speaking, this is an error, because the application specifically did not do the selection from MF; typically, there is no fall back directory, just the error is returned...

@jpbarraca
Copy link
Author

Thank you for the time and comments.
I will take a look at them. Especially that deviation in the behaviour of the FS. Maybe there is something else that I am missing.

Regarding python, it now seems to work with version 3. But I agree it needs tests.

@frankmorgner
Copy link
Owner

Hi! It seems like I didn't realize that you did an update of the code. Thank you!

Did you also have a look at the other technical comments above? 1 2

@jpbarraca
Copy link
Author

I updated the code to fix some issues found during a course where we used the vsmartcard.
I will try to address the technical issues to complete this process.

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

Successfully merging this pull request may close these issues.

2 participants