-
Notifications
You must be signed in to change notification settings - Fork 711
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
sc-hsm-tool: Add options for public key authentication #1711
Conversation
CAR/CHR are tied to a limit of 7-16 bytes by BSI TR-03110. |
Ideally, one could specify the CHR and inner CAR used in the certificate signing request signed by the SmartCard-HSM when generating a new key pair. In our own PKCS#11 module we do this with proprietary CKA_ attributes that carry information like CHR, CAR, algorithm list, key use counter etc. Unfortunately OpenSC and the pkcs11-tool does not have the capability to specify custom attributes in the keygen template. In Public Key Authentication (PKA), the public key is imported and validated in the CSR format and the CHR is used as unique key identifier. With a static CHR this doesn't work with more that one key. Patch #1714 replaces the static CHR with an id based on the device serial number (which in fact is the CHR of the device certificate without serial 00000). As a result, the CSR would contain a CHR that is unique per card, which should be sufficient for PKA. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please be more efficient with certificate parsing, i.e. use OpenPACE or sc_pkcs15emu_sc_hsm_decode_cvc()
.
Your code contains a lot of cleanup overhead. We often use a goto statement to tie cleanup of ressources to the end of a function. Your code would benifit from that pattern as well.
/* return CAR */ | ||
strncpy((char*) carstr, (const char*) car, taglen); | ||
LOG_FUNC_RETURN(ctx, SC_SUCCESS); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you also want to look at OpenPACE for more extended parsing/verification of CVCs. If you want to keep this self sustained within OpenSC, you should use sc_pkcs15emu_sc_hsm_decode_cvc()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to parse this with sc_pkcs15emu_sc_hsm_decode_cvc()
, but wasn't able to. I got the following error:
Required ASN.1 object not found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is not to parse ASN.1 by hand. Please check what object is missing and why.
Thanks for the feedback @frankmorgner, I'll address the remarks. |
I tried to address all remarks. Is there anything else that needs to be changed? Should I squash commits to cleanup the commit history? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks OK, but you really need to use sc_pkcs15emu_sc_hsm_decode_cvc()
!
} | ||
|
||
/* C_DevAut */ | ||
fid[0] = 0x2F; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's EF_C_DevAut, see
OpenSC/src/libopensc/card-sc-hsm.c
Lines 509 to 552 in 93bdc8c
if (priv->EF_C_DevAut && priv->EF_C_DevAut_len) { | |
all_certs_len = priv->EF_C_DevAut_len; | |
cert = priv->EF_C_DevAut; | |
} else { | |
/* get issuer and device certificate from the card */ | |
r = sc_path_set(&path, SC_PATH_TYPE_FILE_ID, (u8 *) "\x2F\x02", 2, 0, 0); | |
if (r < 0) | |
goto err; | |
r = sc_select_file(card, &path, NULL); | |
if (r < 0) | |
goto err; | |
r = sc_read_binary(card, 0, all_certs, all_certs_len, 0); | |
if (r < 0) | |
goto err; | |
if (r == 0) { | |
r = SC_ERROR_FILE_NOT_FOUND; | |
goto err; | |
} | |
all_certs_len = r; | |
/* save EF_C_DevAut for further use */ | |
cert = realloc(priv->EF_C_DevAut, all_certs_len); | |
if (cert) { | |
memcpy((unsigned char *) cert, all_certs, all_certs_len); | |
priv->EF_C_DevAut = (unsigned char *) cert; | |
priv->EF_C_DevAut_len = all_certs_len; | |
} | |
cert = all_certs; | |
} | |
left = all_certs_len; | |
device_cert = cert; | |
r = sc_pkcs15emu_sc_hsm_decode_cvc(&p15card, &cert, &left, &cvc_device); | |
if (r < 0) | |
goto err; | |
device_cert_len = all_certs_len - left; | |
issuer_cert = cert; | |
r = sc_pkcs15emu_sc_hsm_decode_cvc(&p15card, &cert, &left, &cvc_issuer); | |
if (r < 0) | |
goto err; | |
issuer_cert_len = all_certs_len - device_cert_len - left; |
return r; | ||
} | ||
|
||
static void get_CHR(char *chrstr, int is_cvc, sc_context_t *ctx, const u8 *buf, size_t buflen) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use sc_pkcs15emu_sc_hsm_decode_cvc for parsing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding EF_C_DevAut I can see that it is set in the static function sc_hsm_perform_chip_authentication()
. sc_hsm_perform_chip_authentication()
is only called from sc_hsm_pin_cmd()
. That is, filling EF_C_DevAut currently requires PIN entry, which is not necessary for my implementation.
What would be a good way to use EF_C_DevAut, ideally without PIN entry?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding sc_pkcs15emu_sc_hsm_decode_cvc()
: I spent many hours trying to get it to work.
Like I wrote in #1711 (comment), I wasn't able to parse the device certificate and the device issuer certificate with it. For the public key, sc_cvc_t.car
is filled correctly, but sc_cvc_t.outer_car
contains garbage. Unfortunately, I couldn't figure out what the problem is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would be a good way to use EF_C_DevAut, ideally without PIN entry?
The basic idea is in sc-hsm-tool to
- force a sc-hsm card driver, as done here and
- then cast card->drv_data to
struct sc_hsm_private_data *
and use itsEF_C_DevAut
if it's available.
Additionally, you may want to transfer ownership of a newly read EF_C_DevAut to the driver for re-use. You don't need to perform CA to do this.
I tried to refactor the code in order to use
However, the device certificate and the device issuer certificate have structures like this:
which I cannot parse simply with
I could try wrapping them in a CV Certificate and add a fake outer CAR and Signature in order to also use What should I do in that regard in order to get the PR into a mergeable state? |
This reverts commit a98d1c5.
5750d63
to
1eddb58
Compare
Sorry for the late response. OpenPACE has both, The other one, would be to extend |
/* return CAR */ | ||
strncpy((char*) carstr, (const char*) car, taglen); | ||
LOG_FUNC_RETURN(ctx, SC_SUCCESS); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is not to parse ASN.1 by hand. Please check what object is missing and why.
return r; | ||
} | ||
|
||
static void get_CHR(char *chrstr, int is_cvc, sc_context_t *ctx, const u8 *buf, size_t buflen) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would be a good way to use EF_C_DevAut, ideally without PIN entry?
The basic idea is in sc-hsm-tool to
- force a sc-hsm card driver, as done here and
- then cast card->drv_data to
struct sc_hsm_private_data *
and use itsEF_C_DevAut
if it's available.
Additionally, you may want to transfer ownership of a newly read EF_C_DevAut to the driver for re-use. You don't need to perform CA to do this.
@frankbraun , you've put a lot of effort into this and I think it would be useful. However, there has been some inactivity and now there are merge conflicts, would you card to look at this again? Do you need some help regarding the comments above? |
I'm interested in finishing this pull request. Aside from merge conflicts can someone help outline what work remains to be done? Was it just the two comments from Jan 17 2020? |
Yes, indeed. The main problem is maintainability. You should use the CVC capabilities we already have. If I remember correctly, the rest of the code looked OK. |
hi, also interested in this functionality. i rebased this branch and tweaked it to share code with @nickaknudson looks like we ran into this at the same time, so if you have something ready, i'd be happy to defer. otherwise it'd be convenient to have this in upstream soon, so I'll make a new PR if there's no objections? |
created #2301 in the interest of moving this forward |
closed with #2301 |
This PR extends the
sc-hsm-tool
with options to use Public Key Authentication (n-of-m Authentication).The new options allow the
sc-hsm-tool
to:--public-key-auth
and--required-pub-keys
).--export-for-pub-key-auth
).--register--public-key
).public-key-auth-status
).What's still missing is an option to do the actual authentication.
The SmartCard-HSM version 2.6 and SmartCard-HSM version 3.1 were used during testing.
Open issue
The CAR and CHR of CV Certificates generated with OpenSC are fixed values, see:
OpenSC/src/pkcs15init/pkcs15-sc-hsm.c
Lines 265 to 266 in 19711d0
This prevents registering multiple keys (created with OpenSC) for public key authentication due to name clashes.
This issue has been discussed with Andreas Schwier from @CardContact, but no solution has been found yet.
Checklist