Recent compilers have activated some additional
checks which let the build fail. (at least with cygwin)
(Normally it would be warnings but opensc compiles
with -Werror)
GCC 9.3:
In file included from profile.c:27:
profile.c: In function '__expr_get':
profile.c:2273:18: error: array subscript has type 'char' [-Werror=char-subscripts]
2273 | while (isspace(*s))
| ^~
clang 8.0.1:
compat_getopt_main.c:102:22: error: array subscript is of type 'char' [-Werror,-Wchar-subscripts]
rc = toupper(rc);
^~~~~~~~~~~
/usr/include/ctype.h:161:25: note: expanded from macro 'toupper'
(void) __CTYPE_PTR[__x]; (toupper) (__x);})
^~~~
Actually the code is correct as isspace and others
are used here with data type char, and are to be used
with data type int.
So either the compiler should have deactivated
this error, or the ctype.h macros have to be
written so the compiler no longer complains.
As there is also a simple workaround by casting
char to unsigned char, there is no need to wait for one
of the former options to be happen sometime.
before 14e396273 sc_wait_for_event() only notified in case of a new
reader, but didn't add it to the internal list of readers. That's why
PKCS#11 needed to bail out early in this case (and the application had
to call C_WaitForSlotEvent a second time to actually get the related
slot). Since sc_wait_for_event() can now handle insertion correctly, we
can now immediately check (and reset) the events on the slots.
Expect a record number as 3rd parameter:
if this record number is greater than 0, indicating a single record,
then append the record number to the file name being constructed.
* Bug fixed
1. It solves the problem that can be signed without input PIN, and new code will check the state that the PIN value
2. The algorithm fails to verify sha256, cause signature failure
3. The format of distinguishing ECC and RSA key pair is added - after the key pair is generated successfully, ECC and RSA need to be distinguished when reading the public key. The return format of ECC is different from the RSA
4. Fix ECC information display bug - The problem is using pkcs15-tool -D to print ECC key pair information no display correctly
5. Modify the module attribute of generating ECC key pair, and add 0x04 flag according to pkcs11 standard
Check SC_READER_CARD_PRESENT flag rather than == 1.
Having no card present on the first loop and then inserting a card will
return rc = CARD_PRESENT | CARD_CHANGED (= 3). SEGFAULT ensures when we mistake
the unset opt_reader as having a present card.
In piv_general_mutual_authenticate sc_asn1_put_tag is not used correctly.
On branch piv-sc_asn1_put_tag-error
Changes to be committed:
modified: card-piv.c
Commit 4fd34e28ea unintentionally replaced top_builddir with
top_srcdir when refactoring flags variables in Makefile.am. This causes
out-of-source builds to fail.
Restore top_builddir in LDADD.
Also, remove a superfluous -L flag also referencing top_srcdir from
AM_CFLAGS while at it.
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
Closes#2027.
Treat CardOS V5_0 and V5_3 cards differently then older versions:
Use card->dvr_data as a pointer to cardos_data_t to store private driver
data to pass internally, especially between set security environment
and the crypto operations. Sc_get_encoding_flags sets sec_flags from
algo_info->flags in pkcs15-sec.c and it passed to decipher.
Some cards when doing a decipher may drop leading 00 byte when
returning data from RSA_RAW decipher. Add leading byte(s) as needed.
Get Cryptographic Mechanism Reference from Key Reference:
Key reference byte appears to be a 4 bit Cryptographic Mechanism Reference
and a 4 bit key reference.
This is only done if key reference & 0xF0 != 0 i.e. default Cryptographic
mechanism reference is 0. which appears to be the case for RSA RAW.
PKCS1 appears to be 0x10 and ECDSA 0x30
See iso 7816-4 table 55 for DST:
84 Reference of a private key
95 Usage qualifier byte - Table 57 - 40 looks OK
80 Cryptographic mechanism reference and referes to section 9.2
The 4 bit key reference limits card to 16 keys. In future this may not work,
but we can derive a Cryptographic Mechanism Reference from what OpenSC
thinks the card needs to do. Only know RSA RAW, PKCS1 and ECDSA.
ECDSA code has not been tested, but expected to work.
Allow setting CardOS type and flags from opensc.conf using card_atr stanza
This is a fallback if newer cards are added or older cards have problems
giving us time to make need changes in next release.
It will help in identifying what flags are needed for each card.
As user can report what combination of flags work for them. They do this by
adding to opensc.conf with something like this. (Change the ATR to your card's ATR):
card_atr 3b:d2:18:00:81:31:fe:58:c9:03:16 {
driver = "cardos";
# type is decimal from cards.h:
# SC_CARD_TYPE_CARDOS_V5_0 is 1009
# SC_CARD_TYPE_CARDOS_V5_3 is 1010
type = 1010;
# flags is hex from opensc.h:
#define SC_ALGORITHM_ONBOARD_KEY_GEN 0x80000000
#define SC_ALGORITHM_NEED_USAGE 0x40000000
#define SC_ALGORITHM_RSA_RAW 0x00000001 /* RSA_RAW is PAD_NONE */
#define SC_ALGORITHM_RSA_PAD_NONE 0x00000001
#define SC_ALGORITHM_RSA_PAD_PKCS1 0x00000002 /* PKCS#1 v1.5 padding */
#define SC_ALGORITHM_RSA_PAD_ANSI 0x00000004
#define SC_ALGORITHM_RSA_PAD_ISO9796 0x00000008
#define SC_ALGORITHM_RSA_PAD_PSS 0x00000010 /* PKCS#1 v2.0 PSS */
#define SC_ALGORITHM_RSA_PAD_OAEP 0x00000020 /* PKCS#1 v2.0 OAEP */
#define SC_ALGORITHM_RSA_HASH_NONE 0x00000100 /* only applies to PKCS1 padding */
# example: SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_RAW
flags = 80000101;
#example: SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_PAD_PKCS1
flags = 80000002;
}
For V5_0 and v5_3 cards, use sc_get_max_send_size and sc_get_max_recv_size
which takes care or reader sizes even on Windows where SCardControl can not get PART_10 sizes.
(commit eddea6f3c2 on Windows forces reader sizes to 255, 256
in reader-pcsc.c if not already set. It should not do this, but leave that up to card drivers.)
pkcs15-cardos.c added:
New file, pkcs15-cardos.c, added as emulation only for CardOS
V5_0 and V5_3 cards.
sc_pkcs15_bind_internal is called to get tokenInfo as CardOS
cards are substantially PKCS15 cards. But some V5_* cards have
errors in the tokenInfo, Which are corrected.
For older CardOS cards, card-cardos.c will create all the
card->algorithms.
Pkcs15-cardos.c will check for card->algorithms and if there
are none, it will do the following:
SC_CARDCTL_CARDOS_PASS_ALGO_FLAGS is called twice. First to get
the flags as set by user via opensc.conf card_atr or default
flags set by the card driver. Then after determining from the
tokenInfo what algorithms the card can support, the new flags
are passed to card_cardos.c to create card->algorithms.
https://atos.net/wp-content/uploads/2018/11/CT_181026_LPM_CardOS_V5-3_Multifunctionality_FS_en3_web.pdf
says card supports: "“Command chaining” in accordance with ISO/IEC 7816-4"
To take advantage of this with older readers, max_send_size and max_recv_size
is now based on minimum of reader limits and "data_field_length" from card.
This should allow card to work in older readers not capable of extended APDU.
So far current cards we have seen do no appear to support “Command chaining”.
Changes to be committed:
modified: src/libopensc/Makefile.am
modified: src/libopensc/Makefile.mak
modified: src/libopensc/card-cardos.c
modified: src/libopensc/cardctl.h
modified: src/libopensc/cards.h
new file: src/libopensc/pkcs15-cardos.c
modified: src/libopensc/pkcs15-syn.c
modified: src/libopensc/pkcs15-syn.h
Some cards can provide supported algorithms in tokenInfo
which contain ECDSA OID, and PKCS11 mechanism
Don't know how many Algo_refs were actually read,
and a ref of 0 may be valid. print at least one Algo_refs.
Print the mechanism from PKCS11, and print operations
Use the $(top_srcdir)/src/pkcs11/pkcs11-display.c on Unix
Use the $(TOPDIR)\src\pkcs11\pkcs11-display.obj on Windows
pkcs15.tool.c treat ECDSA OID as inline
pkcs15-tool prints PKCS11 mechanisms using pkcs11-display.c
Automake now warns that the default will change, in the future
so "[subdir-objects]" is added to configure.ac
Changes to be committed:
modified: configure.ac
modified: src/tools/Makefile.am
modified: src/tools/Makefile.mak
modified: src/tools/pkcs15-tool.c
Mismatch of ASN1 parsing of tokeninfo.supported_algos[n].paramters
in one place parameter was treated as a pointer to sc_object_id
and in another as inline structure. This caused segfaults
in pkcs15-tool when it tried to print the OID.
Changes to be committed:
modified: src/libopensc/opensc.h
modified: src/libopensc/pkcs15.c
CardOS cards may have more then 8 supported_algo_info entries in tokenInfo.
We may bemissing some. We have seen 8 in some pkcs15-tool -i -v output.
Simple fix is to incrase the limit. More appropriate fix is to remove the limit,
much like is done with sc_algorithm_info. and use realloc of the array.
On branch cardos-5.3
Changes to be committed:
modified: src/libopensc/pkcs15-prkey.c
modified: src/libopensc/pkcs15-skey.c
modified: src/libopensc/pkcs15.c
modified: src/libopensc/types.h
In tests, make sute test data is either padded, or "zero" padded
so size if data <= modlen - 11. The smallest pad in 11 bytes,
00 | NN | PS | 00. PS is at least 8 bytes.
"zero" padding has N = 00, PS >= 8 byte of 00.
On branch cardos-5.3
Changes to be committed:
modified: tools/pkcs11-tool.c
always should be used, even if a PIN pad reader is used. PIN must only
be fetched from the PIN pad reader if the corresponding parameter is
null.
Before this commit PIN was always fetch from the reader if the PIN could
be fetched from the reader.
The 'pkcs11-tool has also been updated. Before parameters was never
taken from the command line if a PID pad reader was used. Now PINs from
the command line is always used but if not existing the PIN is fetched
from the reader if a reader with a PIN pad is used, otherwise the user
is prompted for PIN(s) from the CLI.
C_SetPIN modifies the PIN of the user that is currently logged in, or
the CKU_USER PIN if the session is not logged in. ....
This was not true for "if the session is not logged in" before this fix.
- If readers are attatched, the new reader is probed for a card to check
if a notification needs to be sent
- removal of readers are not notified to the user, we assume that PC/SC
sends the correct card removal event
- The list of readers to be monitored is adjusted once a reader (dis)appears
- On macOS, without PnP notification, we always check for new/removed
readers with SCardListReaders
- fixes interrupt handling in opensc-notify on Unix
fixes https://github.com/OpenSC/OpenSC/issues/1874
* replace magic magic number used as potentially too small buffer size
by SC_MAX_EXT_APDU_RESP_SIZE
* start error message with upper-case letter
* return 0 on success
* bug fix: pass correct buffer length to sc_update_record()
* bug fix: report correct number of bytes written
* bug fix: check for offs to be small enough
* replace magic magic number used as potentially too small buffer size
by SC_MAX_EXT_APDU_DATA_SIZE
* remove print() statement that looks suspiciously like a leftover from debugging
* start error messages with upper-case letters
* use sc_strerror(r) instead of plain numeric r in error messages
* fix spaces before opening curly braces
* replace magic magic number used as potentially too small buffer size
by SC_MAX_EXT_APDU_DATA_SIZE
* remove print() statement that looks suspiciously like a leftover from debugging
* start error messages with upper-case letters
* use sc_strerror(r) instead of plain numeric r in error message
* fix spaces before opening curly braces
* replace magic magic number used as potentially too small buffer size
by SC_MAX_EXT_APDU_RESP_SIZE
* replace magic number for filename by SC_MAX_PATH_STRING_SIZE
* start error messages with upper-case letters
* use braces after sizeof, i.e. sizeof(X) instead of sizeof X
* fix indentation
* determine DO ID/tag the same way as do_find_tags()
* start error message with upper-case letter
* use sc_strerror(r) instead of plain numeric r in error message
* adapt size of buffer to SC_MAX_EXT_APDU_DATA_SIZE
* determine DO ID/tag the same way as do_find_tags()
* replace magic magic number used as potentially too small buffer size
by SC_MAX_EXT_APDU_RESP_SIZE
* change buffer type from unsigned char to u8 for consistency with
do_put_data() & do_find_tags()
* give ID/tag of DO in error message
* open target file in binary mode
* set default values for variables at declaration time
* replace magic number used as potentially too small buffer size
by SC_MAX_EXT_APDU_RESP_SIZE
* use braces after sizeof, i.e. sizeof(X) instead of sizeof X
* set default values for variables at declaration time
* use sizeof(fid) instead of magic number
* use braces after sizeof, i.e. sizeof(X) instead of sizeof X
* start error message with upper-case letter
* rename from read_and_util_print_binary_file(); adapt callers
* use large enough buffer size SC_MAX_EXT_APDU_RESP_SIZE
instead of potentially too small magic number
* fix spaces before opening curly braces
* avoid special casing SC_CARD_TYPE_BELPIC_EID: a successful read
of an empty file is still a success, even if nothing can get printed
* do not fail on SC_FILE_TYPE_UNKNOWN: be more flexible w.r.t accepting
unknown file types when the preceding card operations succeeded
* fix spaces before opening curly braces
- when listing the slots, we don't have a hotplug slot anymore with
slot->reader == NULL. Instead, we're now using this state for any left
over slots when a reader is removed. So we don't need to include this in
the slot list
- when listing the slots, we need to remember which slots the
application has seen already, to not shrink the list of slots (which is
allowed in PKCS#11 v2.2, but NSS can't handle this)
Macro DEBUG_VSS and routine _debug_virtual_slots were added.
DEBUG_VSS(slot, "printf like format string" [,args...]) will print the virtual_slots
to the opensc-debug.log showing were it was called from.
If slot is not NULL and found in the table it will be highlighted
with an "*".
In gdb: call _debug_virtual_slots(slot) can be used along with
another window to tail opensc-debug.log
On branch PKCS11-SLOTS-2
Date: Fri Feb 21 08:19:37 2020 -0600
Changes to be committed:
modified: src/pkcs11/sc-pkcs11.h
modified: src/pkcs11/slot.c
- allows re-attatching a reader to an existing reader object by
resetting the SC_READER_REMOVED flag
- readers that are flagged with SC_READER_REMOVED are not used for
SCardGetStatusChange to avoid SCARD_E_UNKNOWN_READER
fixes https://github.com/OpenSC/OpenSC/issues/1903
OpenSC PKCS11 now retains slots even when the reader is removed.
It can do this because existing OpenSC reader handling in ctx.c,
reader-pcsc.c and PC/SC allow OpenSC to do this.
This simplifies the code, and allow a reader to be reinserted
and use the existing slot. This matching is actually done
in reader-pcsc.c because PC/SC returns the unique ids based on
the OS reader names. This is then used as the manufacturerID
By not deleting slots the slot list can only increase which is a
restriction of Firefox. It does not fix all the Firefox issues, but
it does not go into a loop, when all the readers are removed.
The defaults in opensc.conf for max-virtual-readers and slots-per-card
allow for 4 different readers used during one session.
On branch PKCS11-SLOTS-3
Changes to be committed:
modified: sc-pkcs11.h
modified: slot.c
* distinguish between Internal and Working EFs
* add information optionally available in sc_file_t
- record_count
- record_length
- type_attr
* align all labelled values
Replace magic numbers, used as size of PIN-type buffers,
with the symbolic constant SC_MAX_PIN_SIZE, fixing
- readability / understandability
- too small sizes (e.g. for GnuPG cards)
* define file type SC_FILE_TYPE_UNKNOWN
* explicitly set file->type to SC_FILE_TYPE_UNKNOWN for unkown files
* store full-length file type attributes via sc_file_set_type_attr()
* parse # of records for record-oriented EFs
* parse record length for for EFs with fixed-size records
Note: I am not sure, parsing the record length only for EFs with fixed-
size records is the correct approach.
My interpretation of the norm is slightly different, but it seems
to be in-line what's currently in opensc:
- there's a comment hinting at that interpretation
- otherwise variable size records fail to be read in opensc-explorer
So I leave it this way for now.
Use __FUNCTION__ as defind in log.h so will compile with any compiler.
logprint additional handles as size_t
Add check in reader-pcsc.c pcsc_user_reader for minidriver only.
On branch minidriver-5
Changes to be committed:
modified: src/libopensc/reader-pcsc.c
modified: src/minidriver/minidriver.c
Add MD_FUNC_CALLED(pCardData, level) and MD_FUNC_RETURN(pCardData, level, ...)
macros.
Handles are type __int3264 in VS2015 are casted as size_t when printing so
all bytes are printed. size_t on Windows are also treated as 32 or 64 bits.
SC_FORMAT_LEN_SIZE is used in the format.
(Works with VS2105 needs to be tested on other platforms.)
On branch minidriver-4
Changes to be committed:
modified: minidriver.c
Minidriver.c and reader-pcsc.c - reuse OpenSC reader structure
Windows CNG is managing the insertion and removal of the reader and the card
and will call CardAcquireContext and CardDeleteContext as needed if
the card or reader change. But different processes or threads may establish
different PCSC connects to the same reader and card but with different handles.
Reuse the OpenSC reader when windows uses the same reader but with different
handles. Tests show the certutil -v -scinfo works the same.
Associate_card is only need when called from
CardAcquireContext and disassociate_card is only need when called from
CardDeleteContext.
No need to call reinit_card_for(pCardData, name) just because the handles changed.
This may be the fix for #1763 because calls like CardCreateContainerEx remain
in card state rather then being lost when the handles changed.
Changes to be committed:
modified: src/libopensc/reader-pcsc.c
modified: src/minidriver/minidriver.c
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
- turns out, you can shrink a buffer with realloc on some implementations
- realloc is never called with 0 (which would free the data)
- length checking is done in zlib, we just do the allocation
closes https://github.com/OpenSC/OpenSC/issues/1905
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.
* OpenPGP v3 increased the size for private DOs. Adapt to it.
* Use the symbolic constant from the refactored OpenPGP driver
instead of relying on magic numbers.
- turns out, you can shrink a buffer with realloc on some implementations
- realloc is never called with 0 (which would free the data)
- length checking is done in zlib, we just do the allocation
closes https://github.com/OpenSC/OpenSC/issues/1905
- remove command line option '--card-driver';
- instead force driver 'dnie' and fail if card is not a DNIe card
- overhaul option parsing
- remove unused variable 'long_optind'
- bail out with usage message on all unknown/unhandled args
- correctly terminate option parsing (no infinite loop)
- slight refactoring
- avoid magic constant '0x0f'
- make variable 'tries_left' more local
- move dependent code into if block
- remove command line option '--card-driver';
- instead force driver 'cardos' and fail if card is not a CardOS card
- overhaul option parsing
- remove unused variable 'long_optind'
- bail out with usage message on all unknown/unhandled args
- correctly terminate option parsing (no infinite loop)
- remove command line option '--card-driver';
- instead force driver 'PIV-II' and fail if card is not a PIV card
- overhaul option parsing
- remove unused variable 'long_optind'
- make work option '--reader' ( "r:" was missing in the optstring!!!)
- bail out with usage message on all unknown/unhandled args
- correctly terminate option parsing (no infinite loop)
Rename option '--driver' to '--card-driver' for increased consistency.
In addition, extend it the same way opensc-explorer was extended. I.e.
treat the question mark given as argument to option '--card-driver'
special: list all available drivers instead of stupidly bailing out.
In contrast to opensc-tool and opensc-explorer, which are card-agnostic,
I am not sure whether the option '--card-driver' makes sense on this
card-specific tool.
Extend cardos-tool the same way opensc-explorer was extended. I.e.
treat the question mark given as argument to option '--card-driver'
special: list all available drivers instead of stupidly bailing out.
In contrast to opensc-tool and opensc-explorer, which are card-agnostic,
I am not sure whether the option '--card-driver' makes sense on this
card-specific tool.
Extend piv-tool the same way opensc-explorer was extended. I.e.
treat the question mark given as argument to option '--card-driver'
special: list all available drivers instead of stupidly bailing out.
In contrast to opensc-tool and opensc-explorer, which are card-agnostic,
I am not sure whether the option '--card-driver' makes sense on this
card-specific tool.
Extend opensc-tool the same way opensc-explorer was extended. I.e.
treat the question mark given as argument to option '--card-driver'
special: list all available drivers instead of stupidly bailing out.
Make opensc-explorer a bit more user friendly by treating the question mark
given as argument to option '--card-driver' special: list all available
drivers instead of stupidly bailing out.
The corpus is generated using a local build with
#define APDU_LOG_FILE "apdulog"
and by running:
./src/tools/pkcs11-tool -L --module ./src/pkcs11/.libs/opensc-pkcs11.s
cb50689bf49ccb45a2af690848517305dcf1e429 -- my Yubikey
830e1bf4c7f0c539e9686bc1517d6f87907d4bf8 -- PIV Test Card 14
9ad3fc3cb11967be927bad9263d326783c450e37 -- CAC card
b2b75c07a2c427c15ecd40ce47a9814279745b7d -- old CAC card
7cf8e9b31dcee040ee438441aca2aecb523ed5e9 -- CardOS 5.x
741a0aae7b5b08c0ad2822ede5b3364302b28b31 -- CAC Alt token
de913ba454f894cfc38a16dd122ad673d32ac480 -- coolkey
./configure --enable-code-coverage --disable-optimization
make check
make code-coverage-capture
lcov --summary OpenSC-*-coverage.info
This does not work well with Windows so on windows it should be disabled (WIP)