diff options
author | Werner Koch <[email protected]> | 2021-03-29 12:48:11 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2021-03-29 12:49:08 +0000 |
commit | a494b29af9cc9c4c8c8323bae20e845d5a390448 (patch) | |
tree | e17f010a84c7b912ecb2aea8aa0380e437ffb857 /scd/iso7816.c | |
parent | gpg: Allow ECDH with a smartcard returning just the x-ccordinate. (diff) | |
download | gnupg-a494b29af9cc9c4c8c8323bae20e845d5a390448.tar.gz gnupg-a494b29af9cc9c4c8c8323bae20e845d5a390448.zip |
scd:p15: Support ECDSA and ECDH for CardOS.
* scd/iso7816.c (iso7816_pso_csv): New.
* scd/app-help.c (app_help_pubkey_from_cert): Uncompress a point if
needed.
* scd/app-p15.c (CARD_PRODUCT_RSCS): New.
(struct prkdf_object_s): Add fields is_ecc, token_label, and
tokenflags.
(do_deinit): Free new fields.
(cardproduct2str): New.
(read_ef_prkdf): Set new is_ecc flag.
(read_ef_tokeninfo): Store some data and move Tokeninfo diags to ...
(read_p15_info): here. set the product info here after all data has
been gathered.
(send_keypairinfo): Chnage the way the gpgusage flags are used.
(make_pin_prompt): If the token has a label and the current cert has
no CN, show the label as holder info.
(do_sign): Support ECDSA. Take care of the gpgusage flags.
(do_decipher): Support ECDH. Take care of the gpgusage flags.
--
This has been tested with Trusted Object Manager generated cards by
Rohde & Schwarz Cybersecurity.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'scd/iso7816.c')
-rw-r--r-- | scd/iso7816.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/scd/iso7816.c b/scd/iso7816.c index 8896486b8..e8ee58db1 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -758,6 +758,53 @@ iso7816_decipher (int slot, int extended_mode, } +/* Perform the security operation COMPUTE SHARED SECRET. On success 0 + is returned and the shared secret is available in a newly allocated + buffer stored at RESULT with its length stored at RESULTLEN. For + LE see do_generate_keypair. */ +gpg_error_t +iso7816_pso_csv (int slot, int extended_mode, + const unsigned char *data, size_t datalen, int le, + unsigned char **result, size_t *resultlen) +{ + int sw; + unsigned char *buf; + + if (!data || !datalen || !result || !resultlen) + return gpg_error (GPG_ERR_INV_VALUE); + *result = NULL; + *resultlen = 0; + + if (!extended_mode) + le = 256; /* Ignore provided Le and use what apdu_send uses. */ + else if (le >= 0 && le < 256) + le = 256; + + /* Data needds to be TLV format. */ + buf = xtrymalloc (datalen + 2); + if (!buf) + return gpg_error_from_syserror (); + buf[0] = 0x9c; + buf[1] = datalen; + memcpy (buf+2, data, datalen); + sw = apdu_send_le (slot, extended_mode, + 0x00, CMD_PSO, 0x80, 0xa6, + datalen+2, (const char *)buf, le, + result, resultlen); + xfree (buf); + if (sw != SW_SUCCESS) + { + /* Make sure that pending buffers are released. */ + xfree (*result); + *result = NULL; + *resultlen = 0; + return map_sw (sw); + } + + return 0; +} + + /* For LE see do_generate_keypair. */ gpg_error_t iso7816_internal_authenticate (int slot, int extended_mode, |