2001-12-27 17:25:10 +00:00
|
|
|
/*
|
2002-04-05 10:44:51 +00:00
|
|
|
* internal.h: Internal definitions for libopensc
|
2001-12-27 17:25:10 +00:00
|
|
|
*
|
2006-12-19 21:31:17 +00:00
|
|
|
* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
|
2005-10-30 18:05:30 +00:00
|
|
|
* 2005 The OpenSC project
|
2001-12-27 17:25:10 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
2001-12-30 21:17:34 +00:00
|
|
|
#ifndef _SC_INTERNAL_H
|
|
|
|
#define _SC_INTERNAL_H
|
2001-12-27 17:25:10 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
2010-03-04 08:14:36 +00:00
|
|
|
#include "config.h"
|
2001-12-27 17:25:10 +00:00
|
|
|
#endif
|
|
|
|
|
2005-02-02 10:21:10 +00:00
|
|
|
#ifdef __cplusplus
|
2002-04-19 14:23:31 +00:00
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2002-03-24 14:12:38 +00:00
|
|
|
#include <assert.h>
|
2008-03-06 16:06:59 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
2001-12-27 17:25:10 +00:00
|
|
|
|
2010-03-04 08:14:36 +00:00
|
|
|
#include "common/simclist.h"
|
|
|
|
#include "libopensc/opensc.h"
|
|
|
|
#include "libopensc/log.h"
|
|
|
|
#include "libopensc/cards.h"
|
2020-05-11 16:58:12 +00:00
|
|
|
#include "scconf/scconf.h"
|
2010-03-04 08:14:36 +00:00
|
|
|
|
2016-01-06 14:40:59 +00:00
|
|
|
#ifdef ENABLE_OPENSSL
|
|
|
|
#include "libopensc/sc-ossl-compat.h"
|
|
|
|
#endif
|
|
|
|
|
2001-12-27 17:25:10 +00:00
|
|
|
#define SC_FILE_MAGIC 0x14426950
|
|
|
|
|
2006-02-01 22:59:42 +00:00
|
|
|
#ifndef _WIN32
|
|
|
|
#define msleep(t) usleep((t) * 1000)
|
|
|
|
#else
|
|
|
|
#define msleep(t) Sleep(t)
|
|
|
|
#define sleep(t) Sleep((t) * 1000)
|
|
|
|
#endif
|
|
|
|
|
2010-12-06 12:52:07 +00:00
|
|
|
#ifndef MAX
|
|
|
|
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
|
|
|
#endif
|
|
|
|
#ifndef MIN
|
|
|
|
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
|
|
|
#endif
|
|
|
|
|
2002-03-01 11:52:55 +00:00
|
|
|
struct sc_atr_table {
|
2005-02-20 08:26:27 +00:00
|
|
|
/* The atr fields are required to
|
|
|
|
* be in aa:bb:cc hex format. */
|
2010-03-28 21:00:41 +00:00
|
|
|
const char *atr;
|
2005-02-20 08:26:27 +00:00
|
|
|
/* The atrmask is logically AND'd with an
|
|
|
|
* card atr prior to comparison with the
|
|
|
|
* atr reference value above. */
|
2010-03-28 21:00:41 +00:00
|
|
|
const char *atrmask;
|
|
|
|
const char *name;
|
2005-02-10 10:09:15 +00:00
|
|
|
int type;
|
2005-02-06 19:40:40 +00:00
|
|
|
unsigned long flags;
|
2005-02-22 07:59:42 +00:00
|
|
|
/* Reference to card_atr configuration block,
|
|
|
|
* available to user configured card entries. */
|
|
|
|
scconf_block *card_atr;
|
2005-02-04 15:57:38 +00:00
|
|
|
};
|
|
|
|
|
2001-12-27 17:25:10 +00:00
|
|
|
/* Internal use only */
|
2002-02-24 19:32:14 +00:00
|
|
|
int _sc_add_reader(struct sc_context *ctx, struct sc_reader *reader);
|
2010-01-24 15:25:08 +00:00
|
|
|
int _sc_parse_atr(struct sc_reader *reader);
|
2002-01-05 19:01:55 +00:00
|
|
|
|
2002-12-03 15:40:40 +00:00
|
|
|
/* Add an ATR to the card driver's struct sc_atr_table */
|
2005-02-06 19:40:40 +00:00
|
|
|
int _sc_add_atr(struct sc_context *ctx, struct sc_card_driver *driver, struct sc_atr_table *src);
|
2005-02-14 09:12:44 +00:00
|
|
|
int _sc_free_atr(struct sc_context *ctx, struct sc_card_driver *driver);
|
2002-12-03 15:40:40 +00:00
|
|
|
|
2006-06-27 17:56:19 +00:00
|
|
|
/**
|
|
|
|
* Convert an unsigned long into 4 bytes in big endian order
|
|
|
|
* @param buf the byte array for the result, should be 4 bytes long
|
|
|
|
* @param x the value to be converted
|
2011-05-23 17:33:45 +00:00
|
|
|
* @return the buffer passed, containing the converted value
|
2006-06-27 17:56:19 +00:00
|
|
|
*/
|
2011-05-23 17:33:45 +00:00
|
|
|
u8 *ulong2bebytes(u8 *buf, unsigned long x);
|
2006-06-27 17:56:19 +00:00
|
|
|
/**
|
|
|
|
* Convert an unsigned long into 2 bytes in big endian order
|
|
|
|
* @param buf the byte array for the result, should be 2 bytes long
|
|
|
|
* @param x the value to be converted
|
2011-05-23 17:33:45 +00:00
|
|
|
* @return the buffer passed, containing the converted value
|
2006-06-27 17:56:19 +00:00
|
|
|
*/
|
2011-05-23 17:33:45 +00:00
|
|
|
u8 *ushort2bebytes(u8 *buf, unsigned short x);
|
2006-06-27 17:56:19 +00:00
|
|
|
/**
|
|
|
|
* Convert 4 bytes in big endian order into an unsigned long
|
|
|
|
* @param buf the byte array of 4 bytes
|
|
|
|
* @return the converted value
|
|
|
|
*/
|
2006-06-27 17:49:19 +00:00
|
|
|
unsigned long bebytes2ulong(const u8 *buf);
|
2006-06-27 17:56:19 +00:00
|
|
|
/**
|
|
|
|
* Convert 2 bytes in big endian order into an unsigned short
|
|
|
|
* @param buf the byte array of 2 bytes
|
|
|
|
* @return the converted value
|
|
|
|
*/
|
2006-06-27 17:49:19 +00:00
|
|
|
unsigned short bebytes2ushort(const u8 *buf);
|
|
|
|
|
2017-02-27 10:05:12 +00:00
|
|
|
/**
|
|
|
|
* Convert 2 bytes in little endian order into an unsigned short
|
|
|
|
* @param buf the byte array of 2 bytes
|
|
|
|
* @return the converted value
|
|
|
|
*/
|
|
|
|
unsigned short lebytes2ushort(const u8 *buf);
|
2020-02-13 09:39:41 +00:00
|
|
|
/**
|
|
|
|
* Convert 4 bytes in little endian order into an unsigned long
|
|
|
|
* @param buf the byte array of 4 bytes
|
|
|
|
* @return the converted value
|
|
|
|
*/
|
|
|
|
unsigned long lebytes2ulong(const u8 *buf);
|
2017-02-27 10:05:12 +00:00
|
|
|
|
2020-06-04 10:21:47 +00:00
|
|
|
/* Usable for setting string elements of token info, which
|
|
|
|
* are either initialized to NULL or we need to clean
|
|
|
|
* previous value.
|
|
|
|
*
|
|
|
|
* @param strp The pointer where to store string
|
|
|
|
* @param value The string to store (is strdupped)
|
|
|
|
*/
|
|
|
|
void set_string(char **strp, const char *value);
|
|
|
|
|
2019-01-30 21:00:36 +00:00
|
|
|
#define BYTES4BITS(num) (((num) + 7) / 8) /* number of bytes necessary to hold 'num' bits */
|
|
|
|
|
2005-02-22 07:59:42 +00:00
|
|
|
/* Returns an scconf_block entry with matching ATR/ATRmask to the ATR specified,
|
|
|
|
* NULL otherwise. Additionally, if card driver is not specified, search through
|
|
|
|
* all card drivers user configured ATRs. */
|
2011-01-07 17:18:58 +00:00
|
|
|
scconf_block *_sc_match_atr_block(sc_context_t *ctx, struct sc_card_driver *driver, struct sc_atr *atr);
|
2005-02-22 07:59:42 +00:00
|
|
|
|
2002-03-08 05:59:57 +00:00
|
|
|
/* Returns an index number if a match was found, -1 otherwise. table has to
|
|
|
|
* be null terminated. */
|
2018-08-22 14:54:42 +00:00
|
|
|
int _sc_match_atr(struct sc_card *card, const struct sc_atr_table *table, int *type_out);
|
2002-03-08 05:59:57 +00:00
|
|
|
|
|
|
|
int _sc_card_add_algorithm(struct sc_card *card, const struct sc_algorithm_info *info);
|
2017-04-12 07:37:56 +00:00
|
|
|
int _sc_card_add_symmetric_alg(sc_card_t *card, unsigned int algorithm,
|
|
|
|
unsigned int key_length, unsigned long flags);
|
2002-03-08 05:59:57 +00:00
|
|
|
int _sc_card_add_rsa_alg(struct sc_card *card, unsigned int key_length,
|
2016-11-15 21:48:48 +00:00
|
|
|
unsigned long flags, unsigned long exponent);
|
2010-11-30 19:13:48 +00:00
|
|
|
int _sc_card_add_ec_alg(struct sc_card *card, unsigned int key_length,
|
2016-11-15 21:48:48 +00:00
|
|
|
unsigned long flags, unsigned long ext_flags,
|
|
|
|
struct sc_object_id *curve_oid);
|
2020-02-24 17:29:32 +00:00
|
|
|
int _sc_card_add_eddsa_alg(struct sc_card *card, unsigned int key_length,
|
|
|
|
unsigned long flags, unsigned long ext_flags,
|
|
|
|
struct sc_object_id *curve_oid);
|
|
|
|
int _sc_card_add_xeddsa_alg(struct sc_card *card, unsigned int key_length,
|
|
|
|
unsigned long flags, unsigned long ext_flags,
|
|
|
|
struct sc_object_id *curve_oid);
|
2002-03-08 05:59:57 +00:00
|
|
|
|
2005-10-30 18:05:30 +00:00
|
|
|
/********************************************************************/
|
|
|
|
/* pkcs1 padding/encoding functions */
|
|
|
|
/********************************************************************/
|
|
|
|
|
2013-05-22 10:10:26 +00:00
|
|
|
int sc_pkcs1_strip_01_padding(struct sc_context *ctx, const u8 *in_dat, size_t in_len,
|
|
|
|
u8 *out_dat, size_t *out_len);
|
|
|
|
int sc_pkcs1_strip_02_padding(struct sc_context *ctx, const u8 *data, size_t len,
|
|
|
|
u8 *out_dat, size_t *out_len);
|
2005-10-30 18:05:30 +00:00
|
|
|
int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm,
|
|
|
|
const u8 *in_dat, size_t in_len, u8 *out_dat, size_t *out_len);
|
2007-02-02 22:15:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* PKCS1 encodes the given data.
|
|
|
|
* @param ctx IN sc_context_t object
|
|
|
|
* @param flags IN the algorithm to use
|
|
|
|
* @param in IN input buffer
|
|
|
|
* @param inlen IN length of the input
|
2013-05-22 10:10:26 +00:00
|
|
|
* @param out OUT output buffer (in == out is allowed)
|
2007-02-02 22:15:14 +00:00
|
|
|
* @param outlen OUT length of the output buffer
|
2018-10-31 11:59:00 +00:00
|
|
|
* @param mod_bits IN length of the modulus in bits
|
2007-02-02 22:15:14 +00:00
|
|
|
* @return SC_SUCCESS on success and an error code otherwise
|
|
|
|
*/
|
2005-10-30 18:05:30 +00:00
|
|
|
int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags,
|
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
|
|
|
const u8 *in, size_t inlen, u8 *out, size_t *outlen, size_t mod_bits);
|
2007-02-02 22:15:14 +00:00
|
|
|
/**
|
|
|
|
* Get the necessary padding and sec. env. flags.
|
|
|
|
* @param ctx IN sc_contex_t object
|
|
|
|
* @param iflags IN the desired algorithms flags
|
|
|
|
* @param caps IN the card / key capabilities
|
|
|
|
* @param pflags OUT the padding flags to use
|
|
|
|
* @param salg OUT the security env. algorithm flag to use
|
|
|
|
* @return SC_SUCCESS on success and an error code otherwise
|
|
|
|
*/
|
|
|
|
int sc_get_encoding_flags(sc_context_t *ctx,
|
2016-11-15 21:48:48 +00:00
|
|
|
unsigned long iflags, unsigned long caps,
|
|
|
|
unsigned long *pflags, unsigned long *salg);
|
2005-10-30 18:05:30 +00:00
|
|
|
|
2006-02-01 22:59:42 +00:00
|
|
|
/********************************************************************/
|
|
|
|
/* mutex functions */
|
|
|
|
/********************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a new sc_mutex object. Note: unless sc_mutex_set_mutex_funcs()
|
|
|
|
* this function does nothing and always returns SC_SUCCESS.
|
|
|
|
* @param ctx sc_context_t object with the thread context
|
|
|
|
* @param mutex pointer for the newly created mutex object
|
|
|
|
* @return SC_SUCCESS on success and an error code otherwise
|
|
|
|
*/
|
|
|
|
int sc_mutex_create(const sc_context_t *ctx, void **mutex);
|
|
|
|
/**
|
|
|
|
* Tries to acquire a lock for a sc_mutex object. Note: Unless
|
|
|
|
* sc_mutex_set_mutex_funcs() has been called before this
|
|
|
|
* function does nothing and always returns SUCCESS.
|
|
|
|
* @param ctx sc_context_t object with the thread context
|
|
|
|
* @param mutex mutex object to lock
|
|
|
|
* @return SC_SUCCESS on success and an error code otherwise
|
|
|
|
*/
|
|
|
|
int sc_mutex_lock(const sc_context_t *ctx, void *mutex);
|
|
|
|
/**
|
|
|
|
* Unlocks a sc_mutex object. Note: Unless sc_mutex_set_mutex_funcs()
|
|
|
|
* has been called before this function does nothing and always returns
|
|
|
|
* SC_SUCCESS.
|
|
|
|
* @param ctx sc_context_t object with the thread context
|
|
|
|
* @param mutex mutex object to unlock
|
|
|
|
* @return SC_SUCCESS on success and an error code otherwise
|
|
|
|
*/
|
|
|
|
int sc_mutex_unlock(const sc_context_t *ctx, void *mutex);
|
|
|
|
/**
|
|
|
|
* Destroys a sc_mutex object. Note: Unless sc_mutex_set_mutex_funcs()
|
|
|
|
* has been called before this function does nothing and always returns
|
|
|
|
* SC_SUCCESS.
|
|
|
|
* @param ctx sc_context_t object with the thread context
|
|
|
|
* @param mutex mutex object to be destroyed
|
2006-02-05 19:35:55 +00:00
|
|
|
* @return SC_SUCCESS on success and an error code otherwise
|
2006-02-01 22:59:42 +00:00
|
|
|
*/
|
2006-02-05 19:35:55 +00:00
|
|
|
int sc_mutex_destroy(const sc_context_t *ctx, void *mutex);
|
2006-02-01 22:59:42 +00:00
|
|
|
/**
|
|
|
|
* Returns a unique id for every thread.
|
|
|
|
* @param ctx sc_context_t object with the thread context
|
|
|
|
* @return unsigned long with the unique id or 0 if not supported
|
|
|
|
*/
|
|
|
|
unsigned long sc_thread_id(const sc_context_t *ctx);
|
|
|
|
|
2006-02-05 19:00:01 +00:00
|
|
|
/********************************************************************/
|
|
|
|
/* internal APDU handling functions */
|
|
|
|
/********************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the encoded APDU in newly created buffer.
|
|
|
|
* @param ctx sc_context_t object
|
|
|
|
* @param apdu sc_apdu_t object with the APDU to encode
|
|
|
|
* @param buf pointer to the newly allocated buffer
|
|
|
|
* @param len length of the encoded APDU
|
|
|
|
* @param proto protocol to be used
|
|
|
|
* @return SC_SUCCESS on success and an error code otherwise
|
|
|
|
*/
|
|
|
|
int sc_apdu_get_octets(sc_context_t *ctx, const sc_apdu_t *apdu, u8 **buf,
|
2016-11-15 21:48:48 +00:00
|
|
|
size_t *len, unsigned int proto);
|
2006-02-05 19:00:01 +00:00
|
|
|
/**
|
|
|
|
* Sets the status bytes and return data in the APDU
|
|
|
|
* @param ctx sc_context_t object
|
|
|
|
* @param apdu the apdu to which the data should be written
|
|
|
|
* @param buf returned data
|
|
|
|
* @param len length of the returned data
|
|
|
|
* @return SC_SUCCESS on success and an error code otherwise
|
|
|
|
*/
|
|
|
|
int sc_apdu_set_resp(sc_context_t *ctx, sc_apdu_t *apdu, const u8 *buf,
|
2016-11-15 21:48:48 +00:00
|
|
|
size_t len);
|
2006-03-03 22:56:41 +00:00
|
|
|
/**
|
|
|
|
* Logs APDU
|
|
|
|
* @param ctx sc_context_t object
|
|
|
|
* @param buf buffer with the APDU data
|
|
|
|
* @param len length of the APDU
|
|
|
|
* @param is_outgoing != 0 if the data is send to the card
|
|
|
|
*/
|
2018-11-23 21:41:18 +00:00
|
|
|
#define sc_apdu_log(ctx, data, len, is_outgoing) \
|
|
|
|
sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, is_outgoing != 0 ? "Outgoing APDU" : "Incoming APDU", data, len)
|
2009-01-21 13:19:18 +00:00
|
|
|
|
|
|
|
extern struct sc_reader_driver *sc_get_pcsc_driver(void);
|
|
|
|
extern struct sc_reader_driver *sc_get_ctapi_driver(void);
|
|
|
|
extern struct sc_reader_driver *sc_get_openct_driver(void);
|
2017-02-07 14:45:10 +00:00
|
|
|
extern struct sc_reader_driver *sc_get_cryptotokenkit_driver(void);
|
2009-01-21 13:19:18 +00:00
|
|
|
|
2005-02-02 10:21:10 +00:00
|
|
|
#ifdef __cplusplus
|
2002-04-19 14:23:31 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-12-27 17:25:10 +00:00
|
|
|
#endif
|