Since 09a594d bringing ECC support to openPGP card, it did not count
with GNUK. This adds exception for GNUK to unbreak ECC signatures
as GNUK presents BCD version < 3.
This fixes a problem reported in Nitrokey forum at
https://support.nitrokey.com/t/veracrypt-encryption-with-nitrokey-error/2872
as inability to save the VeraCrypt's keyfile onto the token
after deleting an existing one, unless the PKCS11 is reinitialized.
Reason: commit cbc53b9 "OpenPGP: Support write certificate for Gnuk"
introduced a condition on getting the blob handle, which is surplus
(the pgp_find_blob() function actually does that) and prevents
the blob refresh upon deletion, breaking the logic introduced
earlier in commit 9e04ae4 and causing the higher-level effect reported.
While at it, corrected comments to actually reflect the flow logic.
Tested on Fedora 33 using the repro steps from the forum and Nitrokey Pro.
Signed-off-by: alt3r 3go <alt3r.3go@protonmail.com>
The EC Parameters are the way the EC curve is presented to the outside world,
and in most cases is present in a matching certificate in the SPKI.
card-openpgp.c is modified to add the EC named_curve to the PKCS15 public key.
OpenPGP specs only provide this via the "Algorithm Attributes" for the 3 keys
via tags C1, C2 and C3 These contain the OID (not DER encoded) for the EC curve.
PKCS15 has two ways to encode a "pubkey" as it was originally written for RSA.
But other algorithms have parameters. X509 certificates encode the public key
in the SPKI and PKIX requires the parameters to be in the SPKI. PKCS15
allows for using a SPKI as source for a public key.
pgp_get_pubkey_pem will return the DER encoded RSA pubkey as before by
calling sc_pkcs15_encode_pubkey
pgp_get_pubkey_pem will return the DER encoded EC pubkey with parameters by
calling sc_pkcs15_encode_pubkey_as_spki which calls sc_pkcs15_fix_ec_parameters
internally to map DER encoded OID to named_curve.
For readability, "sc_pkcs15_pubkey_t pubkey;" definitions are changed to
"sc_pkcs15_pubkey_t p15pubkey;"
sc_pkcs15_erase_pubkey is used to avoid memory leaks.
On branch openpgp-ec-pub-curve
Date: Tue Jan 21 09:43:56 2020 -0600
Changes to be committed:
modified: src/libopensc/card-openpgp.c
In pre-v3 cards, it is hard-coded to 254 bytes.
In v3+ cards, it is stored in the "extended capabilities" DO 00C0.
Make the determined size available as a variable in the driver data.
* pgp: initialize ecc keys for OPC3
* Add supported ECC algorithms by card version
* Add tasks identified so far
* pgp: Recognize ECC set on card
* pgp: get_pubkey_pem read ECC pubkey from card
* pgp: minor code changes for ECC compatibility
* pgp: expand sc_cardctl_openpgp_keygen_info to hold ec info
* Fix segfault problem in pkcs15-pubkey.c
* pgp: enable key generation with pkcs15-init and ECC
* pgp: adapt calculate_and_store_fingerprint to accept ECC
* pgp: adapt rest of pgp_gen_key and subfunctions to accept ECC
* pgp: add kdf parameters for ECDH fingerprint calculation
* pgp: enable key import with pkcs15-init and ECC
* pkcs15-pubkey: fix_ec_parameters onlz accpets explicit data or named_curve
* Fix some mistakes during merge
* More clean up for PR
* Fix some ugly alignments
* Improve code readability
* Prevent unitialized variable by using FUNC_RETURN
* OpenPGP: add length check
* pgp: save exponent length in bits for sc_cardctl_openpgp_keystore_info_t
* pgp: length checks and reallocations
* pgp: oid init added
* OpenPGP: slightly re-factor pgp_update_new_algo_attr()
* replace loop copy with memcpy()
* use ushort2bebytes() to set RSA modulus & exponent
* use symbolic name SC_OPENPGP_KEYFORMAT_RSA_STD for the key import format
* OpenPGP: slighly re-factor pgp_parse_and_set_pubkey_output()
* check for RSA modulus & exponent lengths not being a multiple of 8
* make sure RSA modulus & exponent lengths are always set
* remove a left-over RSA setting from the EC code
* pgp: adding BYTES4BITS
* pgp: initialization of values in pgp_build_extended_header_list based on key type
* pgp: add BYTES4BITS and remove unnecessary tests
* Fix broken pgp_update_new_algo_attr
* pgp: fix the ecpoint_len variable
* consistently use term "Invalid key ID; must be 1, 2, or 3" in error messages
about invalid key IDs instead of various alternatives.
* use error type SC_ERROR_INVALID_ARGUMENTS instead of SC_ERROR_INVALID_DATA
when the key_id was passed to the respective function
* harmonize the checks to consistently use 'key_id < ... || key_id > ...'
In addition, initialize a variable to keep clang & compilers on OSX happy.
Combine sequences
sc_log(..., "...");
LOG_FUNC_RETURN(...);
where c_log() prints a constant string
by
LOG_TEST_RET(..., "...");
This change results in shorter, more concise code as well as
better harmonized error messages.
Don't terminate the messages with a period, because they are going to end up
as the first argument to a format string of the form "%s: ...".
I.e. they will be part of a longer string and terminated by a colon anyway.
Use defined symbolic names for well-known DOs to copy data to a correctly
defined buffer 'apdu_data' using ulong2bebytes() instead of relying on
"magic" constants and C's string semantic.
Also use 'sizeof(apdu_data)' instead of additional magic constants.
Use defined symbolic names for well-known DOs to copy data to a correctly
defined buffer 'data' using ulong2bebytes() instead of relying on
"magic" constants and C's string semantic.
Also use 'sizeof(data)' instead of strange strlen() calculations.
Use defined symbolic names for well-known DOs to copy data to a correctly
defined buffer 'data' using ulong2bebytes() instead of relying on
"magic" constants.