libp11-0.4.11/0000755000175000017500000000000013740621135007670 500000000000000libp11-0.4.11/NEWS0000666000175000017500000002362713740615513010330 00000000000000NEWS for Libp11 -- History of user visible changes New in 0.4.11; 2020-10-11; Michał Trojnara * Fixed "EVP_PKEY_derive:buffer too small" EC errors (Luka Logar) * Fixed various memory leaks (Mateusz Kwiatkowski) * Fixed Windows VERSIONINFO (Pavol Misik) * Fixed builds with OpenSSL older than 1.0.2 (Michał Trojnara) * Fixed a double free in EVP_PKEY_meth_free() (Mikhail Durnev) * Added CKA_VALUE_LEN to EC key derivation template (Michał Trojnara) * Fixed handling keys without label attribute (efternavn) * Updated the tests (Anderson Toshiyuki Sasaki) * Made ECDH-derived keys extractable (Bent Bisballe Nyeng) * Added support for pin-source within PKCS#11 URI (Stanislav Levin) * Improved LibreSSL compatibility (patchMonkey156) * Fixed handling RSA private keys in BIND (Stanislav Levin) * Added macOS testing support (Stanislav Levin) * Fixed engine object search algorithm (Anderson Toshiyuki Sasaki) New in 0.4.10; 2019-04-03; Michał Trojnara * Added EC signing through EVP API (Bryan Hunt) * Added an empty EC private key required by OpenSSL 1.1.1 (Doug Engert) * Stored additional certificate attributes (FdLSifu, Michał Trojnara) * Engine allowed to use private keys without a PIN (Michał Trojnara) * Lazy binding used as a workaround for buggy modules (Michał Trojnara) * MinGW build fixes and documentation (Michał Trojnara) * LibreSSL 2.8.3 build fixes (patchMonkey156) * Error handling fixes (Michał Trojnara) New in 0.4.9; 2018-09-03; Michał Trojnara * Fixed EVP_PKEY ENGINE reference count with the EC EVP_PKEY_METHOD (Michał Trojnara, Anderson Sasaki) * Fixed a leak of RSA object in pkcs11_store_key() (lbonn) * Added atfork checks for RSA and EC_KEY methods (Michał Trojnara) New in 0.4.8; 2018-08-05; Michał Trojnara * RSA key generation on the token (n3wtron) * PSS signature support (Doug Engert, Michał Trojnara) * RSA-OAEP and RSA-PKCS encryption support (Mouse, Michał Trojnara) * Engine no longer set as default for all methods (Anderson Sasaki) * Added PKCS11_remove_key and PKCS11_remove_certificate (n3wtron) * Added PKCS11_find_next_token interface (Frank Morgner) * Added support for OpenSSL 1.1.1 beta (Michał Trojnara) * Removed support for OpenSSL 0.9.8 (Michał Trojnara) * Case insensitive PKCS#11 URI scheme (Anderson Sasaki) * Testing framework improvements (Anderson Sasaki) * Coverity scanning and defect fixes (Frank Morgner) * Backward compatibility for new error handling introduced in libp11 0.4.7 (Michał Trojnara) * Memory leak fixes (Frank Morgner, Doug Engert) * Added an integer overflow protection (Eric Sesterhenn, Michał Trojnara) * Several bugfixes (Michał Trojnara, Emmanuel Deloget, Anderson Sasaki) New in 0.4.7; 2017-07-03; Michał Trojnara * Added OpenSSL-style engine error reporting (Michał Trojnara) * Added the FORCE_LOGIN engine ctrl command (Michał Trojnara) * Implemented the QUIET engine ctrl command (Michał Trojnara) * Modified CKU_CONTEXT_SPECIFIC PIN requests to be based on the CKA_ALWAYS_AUTHENTICATE attribute rather than the CKR_USER_NOT_LOGGED_IN error (Michał Trojnara) * Fixed printing hex values (Michał Trojnara) * Fixed build error with OPENSSL_NO_EC (Kai Kang) New in 0.4.6; 2017-04-23; Michał Trojnara * Updated ex_data on EVP_PKEYs after enumerating keys (Matt Hauck) * Token/key labels added into PIN prompts (Matt Hauck) New in 0.4.5; 2017-03-29; Michał Trojnara * Prevented destroying existing keys/certs at login (Michał Trojnara) * Fixed synchronization of PKCS#11 module calls (Matt Hauck) * Added LibreSSL compatibility (Bernard Spil) * Added SET_USER_INTERFACE and SET_CALLBACK_DATA engine ctrl commands for certificate and CKU_CONTEXT_SPECIFIC PINs (Michał Trojnara) * Fixed error handling in RSA key generation (Michał Trojnara) New in 0.4.4; 2017-01-26; Michał Trojnara * Fixed a state reset caused by re-login on LOAD_CERT_CTRL engine ctrl; fixes #141 (Michał Trojnara) * "?" and "&" allowed as URI separators; fixes #142 (Michał Trojnara) * engine: Unified private/public key and certificate enumeration to be performed without login if possible (Michał Trojnara) New in 0.4.3; 2016-12-04; Michał Trojnara * Use UI to get CKU_CONTEXT_SPECIFIC PINs (Michał Trojnara) * Added graceful handling of alien (non-PKCS#11) keys (Michał Trojnara) * Added symbol versioning (Nikos Mavrogiannopoulos) * Soname tied with with the OpenSSL soname (Nikos Mavrogiannopoulos) * Added MSYS2, Cygwin, and MinGW/MSYS support (Paweł Witas) * Workaround implemented for a deadlock in PKCS#11 modules that internally use OpenSSL engines (Michał Trojnara, Paweł Witas) * Fixed an EVP_PKEY reference count leak (David Woodhouse) * Fixed OpenSSL 1.1.x crash in public RSA methods (Doug Engert, Michał Trojnara) * Fixed OpenSSL 1.1.x builds (Nikos Mavrogiannopoulos, Michał Trojnara) * Fixed retrieving PIN values from certificate URIs (Andrei Korikov) * Fixed symlink installation (Alon Bar-Lev) New in 0.4.2; 2016-09-25; Michał Trojnara * Fixed a 0.4.0 regression bug causing the engine finish function to remove any configured engine parameters; fixes #104 (Michał Trojnara) New in 0.4.1; 2016-09-17; Michał Trojnara * Use enginesdir provided by libcrypto.pc if available (David Woodhouse) * Certificate cache destroyed on login/logout (David Woodhouse) * Fixed accessing certificates marked as CKA_PRIVATE (David Woodhouse) * Directly included libp11 code into the engine (Matt Hauck) * Fixed handling simultaneous make jobs (Derek Straka) * Reverted an old hack that broke engine initialization (Michał Trojnara) * Fixed loading of multiple keys due to unneeded re-logging (Matt Hauck) * Makefile fixes and improvements (Nikos Mavrogiannopoulos) * Fixed several certificate selection bugs (Michał Trojnara) * The signed message digest is truncated if it is too long for the signing curve (David von Oheimb) * Workaround for broken PKCS#11 modules not returning CKA_EC_POINT in the ASN1_OCTET_STRING format (Michał Trojnara) * OpenSSL 1.1.0 build fixes (Michał Trojnara) New in 0.4.0; 2016-03-28; Michał Trojnara * Merged engine_pkcs11 (Michał Trojnara) * Added ECDSA support for OpenSSL < 1.0.2 (Michał Trojnara) * Added ECDH key derivation support (Doug Engert and Michał Trojnara) * Added support for RSA_NO_PADDING RSA private key decryption, used by OpenSSL for various features including OAEP (Michał Trojnara) * Added support for the ANSI X9.31 (RSA_X931_PADDING) RSA padding (Michał Trojnara) * Added support for RSA encryption (not only signing) (Michał Trojnara) * Added CKA_ALWAYS_AUTHENTICATE support (Michał Trojnara) * Fixed double locking the global engine lock (Michał Trojnara) * Fixed incorrect errors reported on signing/encryption/decryption (Michał Trojnara) * Fixed deadlocks in keys and certificates listing (Brian Hinz) * Use PKCS11_MODULE_PATH environment variable (Doug Engert) * Added support for building against OpenSSL 1.1.0-dev (Doug Engert) * Returned EVP_PKEY objects are no longer "const" (Michał Trojnara) * Fixed building against OpenSSL 0.9.8 (Michał Trojnara) * Removed support for OpenSSL 0.9.7 (Michał Trojnara) New in 0.3.1; 2016-01-22; Michał Trojnara * Added PKCS11_is_logged_in to the API (Mikhail Denisenko) * Added PKCS11_enumerate_public_keys to the API (Michał Trojnara) * Fixed EVP_PKEY handling of public keys (Michał Trojnara) * Added thread safety based on OpenSSL dynamic locks (Michał Trojnara) * A private index is allocated for ex_data access (RSA and ECDSA classes) instead of using the reserved index zero (app_data) (Michał Trojnara) * Fixes in reinitialization after fork; addresses #39 (Michał Trojnara) * Improved searching for dlopen() (Christoph Moench-Tegeder) * MSVC build fixes (Michał Trojnara) * Fixed memory leaks in pkcs11_get_evp_key_rsa() (Michał Trojnara) New in 0.3.0; 2015-10-09; Nikos Mavrogiannopoulos * Added small test suite based on softhsm (run on make check) * Memory leak fixes (Christian Heimes) * On module initialization tell the module to that the OS locking primitives are OK to use (Mike Gerow) * Transparently handle applications that fork. That is call C_Initialize() and reopen any handles if a fork is detected. * Eliminated any hard coded limits for certificate size (Doug Engert) * Added support for ECDSA (Doug Engert) * Allow RSA_NO_PADDING padding mode in PKCS11_private_encrypt (Stephane Adenot) * Eliminated several hard-coded limits in parameter sizes. New in 0.2.8; 2011-04-15; Martin Paljak * Bumped soname for PKCS11_token struct size changes (Martin Paljak). * Display the number of available slots (Ludovic Rousseau). * Add openssl libcrypto to pkg-config private libs list (Kalev Lember). * Fix building examples with --no-add-needed which is the default in Fedora (Kalev Lember). * Expose more token flags in PKCS11_token structure (Kalev Lember). * Check that private data is not NULL in pkcs11_release_slot (Robin Bryce, ticket #137). New in 0.2.7; 2009-10-20; Andreas Jellinghaus * If CKR_CRYPTOKI_ALREADY_INITIALIZED is returned from C_Initialize(): ignore. (Needed for unloaded/reloaded engines e.g. in wpa_supplicant.) By David Smith. New in 0.2.6; 2009-07-22; Andreas Jellinghaus * Fix new version: add new symbol to export file * fix building on MSVC plattform New in 0.2.5; 2009-06-15; Andreas Jellinghaus * Add function to export the slot id (Douglas E. Engert). * Increase library version because of the new function. New in 0.2.4; 2008-07-31; Andreas Jellinghaus * Build system rewritten (NOTICE: configure options was modified). The build system can produce outputs for *NIX, cygwin and native windows (using mingw). * added PKCS11_CTX_init_args (David Smith). * fix segfault in init_args code. * implemented PKCS11_private_encrypt (with PKCS11_sign now based on it) (Arnaud Ebalard) New in 0.2.3; 2007-07-11; Andreas Jellinghaus * update wiki export script (add images, fix links). * replaced rsa header files from rsalabs (official) with scute (open source). * allow CKR_USER_ALREADY_LOGGED_IN on C_Login. * mark internal functions as static. * add code to store public keys and generate keys. libp11-0.4.11/src/0000755000175000017500000000000013740621135010457 500000000000000libp11-0.4.11/src/libp11.rc0000644000175000017500000000161313740621064012017 00000000000000#include VS_VERSION_INFO VERSIONINFO FILEVERSION 7,4,3,0 PRODUCTVERSION 0,4,11,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x21L #else FILEFLAGS 0x20L #endif FILEOS 0x40004L FILETYPE VFT_DLL FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "Provided under the terms of the GNU General Public License (LGPLv2.1+).\0" VALUE "CompanyName", "OpenSC Project\0" VALUE "FileDescription", "PKCS#11 access library\0" VALUE "FileVersion", "7.4.3.0\0" VALUE "InternalName", "libp11\0" VALUE "LegalCopyright", "OpenSC Project\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libp11-3.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libp11\0" VALUE "ProductVersion", "0.4.11.0\0" VALUE "SpecialBuild", "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END libp11-0.4.11/src/libp11-int.h0000644000175000017500000003125213376210634012436 00000000000000/* libp11, a simple layer on to of PKCS#11 API * Copyright (C) 2005 Olaf Kirch * Copyright (C) 2015-2018 Michał Trojnara * * 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 */ #ifndef _LIBP11_INT_H #define _LIBP11_INT_H #ifndef _WIN32 #include "config.h" #endif #include "libp11.h" #define CRYPTOKI_EXPORTS #include "pkcs11.h" #if OPENSSL_VERSION_NUMBER < 0x10100004L || defined(LIBRESSL_VERSION_NUMBER) typedef int PKCS11_RWLOCK; #else typedef CRYPTO_RWLOCK *PKCS11_RWLOCK; #endif /* get private implementations of PKCS11 structures */ /* * PKCS11_CTX: context for a PKCS11 implementation */ typedef struct pkcs11_ctx_private { CK_FUNCTION_LIST_PTR method; void *handle; char *init_args; UI_METHOD *ui_method; /* UI_METHOD for CKU_CONTEXT_SPECIFIC PINs */ void *ui_user_data; unsigned int forkid; PKCS11_RWLOCK rwlock; int sign_initialized; int decrypt_initialized; } PKCS11_CTX_private; #define PRIVCTX(ctx) ((PKCS11_CTX_private *) ((ctx)->_private)) typedef struct pkcs11_slot_private { PKCS11_CTX *parent; unsigned char haveSession, loggedIn; CK_SLOT_ID id; CK_SESSION_HANDLE session; unsigned int forkid; int prev_rw; /* the rw status the session was open */ /* options used in last PKCS11_login */ char *prev_pin; int prev_so; } PKCS11_SLOT_private; #define PRIVSLOT(slot) ((PKCS11_SLOT_private *) ((slot)->_private)) #define SLOT2CTX(slot) (PRIVSLOT(slot)->parent) typedef struct pkcs11_keys { int num; PKCS11_KEY *keys; } PKCS11_keys; typedef struct pkcs11_token_private { PKCS11_SLOT *parent; PKCS11_keys prv, pub; int ncerts; PKCS11_CERT *certs; } PKCS11_TOKEN_private; #define PRIVTOKEN(token) ((PKCS11_TOKEN_private *) ((token)->_private)) #define TOKEN2SLOT(token) (PRIVTOKEN(token)->parent) #define TOKEN2CTX(token) SLOT2CTX(TOKEN2SLOT(token)) typedef struct pkcs11_key_ops { int type; /* EVP_PKEY_xxx */ EVP_PKEY *(*get_evp_key) (PKCS11_KEY *); void (*update_ex_data) (PKCS11_KEY *); } PKCS11_KEY_ops; typedef struct pkcs11_key_private { PKCS11_TOKEN *parent; CK_OBJECT_HANDLE object; CK_BBOOL always_authenticate; unsigned char id[255]; size_t id_len; PKCS11_KEY_ops *ops; unsigned int forkid; } PKCS11_KEY_private; #define PRIVKEY(key) ((PKCS11_KEY_private *) (key)->_private) #define KEY2SLOT(key) TOKEN2SLOT(KEY2TOKEN(key)) #define KEY2TOKEN(key) (PRIVKEY(key)->parent) #define KEY2CTX(key) TOKEN2CTX(KEY2TOKEN(key)) typedef struct pkcs11_cert_private { PKCS11_TOKEN *parent; CK_OBJECT_HANDLE object; unsigned char id[255]; size_t id_len; } PKCS11_CERT_private; #define PRIVCERT(cert) ((PKCS11_CERT_private *) (cert)->_private) #define CERT2SLOT(cert) TOKEN2SLOT(CERT2TOKEN(cert)) #define CERT2TOKEN(cert) (PRIVCERT(cert)->parent) #define CERT2CTX(cert) TOKEN2CTX(CERT2TOKEN(cert)) extern PKCS11_KEY_ops pkcs11_rsa_ops; extern PKCS11_KEY_ops *pkcs11_ec_ops; /* * Internal functions */ #define CRYPTOKI_checkerr(f, rv) \ do { \ if (rv) { \ CKRerr(f, rv); \ return -1; \ } \ ERR_clear_error(); \ } while (0) #define CRYPTOKI_call(ctx, func_and_args) \ PRIVCTX(ctx)->method->func_and_args extern int ERR_load_CKR_strings(void); /* Memory allocation */ #define PKCS11_DUP(s) \ pkcs11_strdup((char *) s, sizeof(s)) extern char *pkcs11_strdup(char *, size_t); /* Emulate the OpenSSL 1.1 locking API for older OpenSSL versions */ #if OPENSSL_VERSION_NUMBER < 0x10100004L || defined(LIBRESSL_VERSION_NUMBER) int CRYPTO_THREAD_lock_new(); void CRYPTO_THREAD_lock_free(int); #define CRYPTO_THREAD_write_lock(type) \ if(type) CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) #define CRYPTO_THREAD_unlock(type) \ if(type) CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) #define CRYPTO_THREAD_read_lock(type) \ if(type) CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) #define CRYPTO_THREAD_read_unlock(type) \ if(type) CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) #endif /* Emulate the OpenSSL 1.1 getters */ #if OPENSSL_VERSION_NUMBER < 0x10100003L || defined(LIBRESSL_VERSION_NUMBER) #define EVP_PKEY_get0_RSA(key) ((key)->pkey.rsa) #define EVP_PKEY_get0_EC_KEY(key) ((key)->pkey.ec) #endif /* Reinitializing the module afer fork (if detected) */ extern unsigned int get_forkid(); extern int check_fork(PKCS11_CTX *ctx); extern int check_slot_fork(PKCS11_SLOT *slot); extern int check_token_fork(PKCS11_TOKEN *token); extern int check_key_fork(PKCS11_KEY *key); extern int check_cert_fork(PKCS11_CERT *cert); /* Other internal functions */ extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR); extern CK_RV C_UnloadModule(void *module); extern void pkcs11_destroy_keys(PKCS11_TOKEN *, unsigned int); extern void pkcs11_destroy_certs(PKCS11_TOKEN *); extern int pkcs11_reload_key(PKCS11_KEY *); extern int pkcs11_reopen_session(PKCS11_SLOT * slot); extern int pkcs11_relogin(PKCS11_SLOT * slot); /* Managing object attributes */ extern int pkcs11_getattr_var(PKCS11_TOKEN *, CK_OBJECT_HANDLE, unsigned int, CK_BYTE *, size_t *); extern int pkcs11_getattr_val(PKCS11_TOKEN *, CK_OBJECT_HANDLE, unsigned int, void *, size_t); extern int pkcs11_getattr_alloc(PKCS11_TOKEN *, CK_OBJECT_HANDLE, unsigned int, CK_BYTE **, size_t *); /* * Caution: the BIGNUM ** shall reference either a NULL pointer or a * pointer to a valid BIGNUM. */ extern int pkcs11_getattr_bn(PKCS11_TOKEN *, CK_OBJECT_HANDLE, unsigned int, BIGNUM **); #define key_getattr_var(key, t, p, s) \ pkcs11_getattr_var(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s)) #define key_getattr_val(key, t, p, s) \ pkcs11_getattr_val(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s)) #define key_getattr_alloc(key, t, p, s) \ pkcs11_getattr_alloc(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s)) /* * Caution: bn shall reference either a NULL pointer or a pointer to * a valid BIGNUM. */ #define key_getattr_bn(key, t, bn) \ pkcs11_getattr_bn(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (bn)) typedef int (*pkcs11_i2d_fn) (void *, unsigned char **); extern void pkcs11_addattr(CK_ATTRIBUTE_PTR, int, const void *, size_t); extern void pkcs11_addattr_int(CK_ATTRIBUTE_PTR, int, unsigned long); extern void pkcs11_addattr_bool(CK_ATTRIBUTE_PTR, int, int); extern void pkcs11_addattr_s(CK_ATTRIBUTE_PTR, int, const char *); extern void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR, int, const BIGNUM *); extern void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR, int, pkcs11_i2d_fn, void *); extern void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR, unsigned int); /* Internal implementation of current features */ /* Allocate the context */ extern PKCS11_CTX *pkcs11_CTX_new(void); /* Specify any private PKCS#11 module initialization args, if necessary */ extern void pkcs11_CTX_init_args(PKCS11_CTX * ctx, const char * init_args); /* Load a PKCS#11 module */ extern int pkcs11_CTX_load(PKCS11_CTX * ctx, const char * ident); /* Reinitialize a PKCS#11 module (after a fork) */ extern int pkcs11_CTX_reload(PKCS11_CTX * ctx); /* Unload a PKCS#11 module */ extern void pkcs11_CTX_unload(PKCS11_CTX * ctx); /* Free a libp11 context */ extern void pkcs11_CTX_free(PKCS11_CTX * ctx); /* Open a session in RO or RW mode */ extern int pkcs11_open_session(PKCS11_SLOT * slot, int rw, int relogin); /* Get a list of all slots */ extern int pkcs11_enumerate_slots(PKCS11_CTX * ctx, PKCS11_SLOT **slotsp, unsigned int *nslotsp); /* Get the slot_id from a slot as it is stored in private */ extern unsigned long pkcs11_get_slotid_from_slot(PKCS11_SLOT *slot); /* Free the list of slots allocated by PKCS11_enumerate_slots() */ extern void pkcs11_release_all_slots(PKCS11_CTX * ctx, PKCS11_SLOT *slots, unsigned int nslots); /* Find the first slot with a token */ extern PKCS11_SLOT *pkcs11_find_token(PKCS11_CTX * ctx, PKCS11_SLOT *slots, unsigned int nslots); /* Find the next slot with a token */ extern PKCS11_SLOT *pkcs11_find_next_token(PKCS11_CTX * ctx, PKCS11_SLOT *slots, unsigned int nslots, PKCS11_SLOT *current); /* Check if user is already authenticated to a card */ extern int pkcs11_is_logged_in(PKCS11_SLOT * slot, int so, int * res); /* Authenticate to the card */ extern int pkcs11_login(PKCS11_SLOT * slot, int so, const char *pin, int relogin); /* De-authenticate from the card */ extern int pkcs11_logout(PKCS11_SLOT * slot); /* Authenticate a private the key operation if needed */ int pkcs11_authenticate(PKCS11_KEY *key); /* Get a list of keys associated with this token */ extern int pkcs11_enumerate_keys(PKCS11_TOKEN *token, unsigned int type, PKCS11_KEY **keys, unsigned int *nkeys); /* Remove a key from the token */ extern int pkcs11_remove_key(PKCS11_KEY *key); /* Get the key type (as EVP_PKEY_XXX) */ extern int pkcs11_get_key_type(PKCS11_KEY *key); /* Returns a EVP_PKEY object with the private or public key */ extern EVP_PKEY *pkcs11_get_key(PKCS11_KEY *key, int isPrivate); /* Find the corresponding certificate (if any) */ extern PKCS11_CERT *pkcs11_find_certificate(PKCS11_KEY *key); /* Find the corresponding key (if any) */ extern PKCS11_KEY *pkcs11_find_key(PKCS11_CERT *cert); /* Find the corresponding key (if any) pub <-> priv base on ID */ extern PKCS11_KEY *pkcs11_find_key_from_key(PKCS11_KEY *key); /* Get a list of all certificates associated with this token */ extern int pkcs11_enumerate_certs(PKCS11_TOKEN *token, PKCS11_CERT **certs, unsigned int *ncerts); /* Remove a certificate from the token */ extern int pkcs11_remove_certificate(PKCS11_CERT *key); /* Set UI method to allow retrieving CKU_CONTEXT_SPECIFIC PINs interactively */ extern int pkcs11_set_ui_method(PKCS11_CTX *ctx, UI_METHOD *ui_method, void *ui_user_data); /* Initialize a token */ extern int pkcs11_init_token(PKCS11_TOKEN * token, const char *pin, const char *label); /* Initialize the user PIN on a token */ extern int pkcs11_init_pin(PKCS11_TOKEN * token, const char *pin); /* Change the user PIN on a token */ extern int pkcs11_change_pin(PKCS11_SLOT * slot, const char *old_pin, const char *new_pin); /* Store private key on a token */ extern int pkcs11_store_private_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len); /* Store public key on a token */ extern int pkcs11_store_public_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label, unsigned char *id, size_t id_len); /* Store certificate on a token */ extern int pkcs11_store_certificate(PKCS11_TOKEN * token, X509 * x509, char *label, unsigned char *id, size_t id_len, PKCS11_CERT **ret_cert); /* Access the random number generator */ extern int pkcs11_seed_random(PKCS11_SLOT *, const unsigned char *s, unsigned int s_len); extern int pkcs11_generate_random(PKCS11_SLOT *, unsigned char *r, unsigned int r_len); /* Internal implementation of deprecated features */ /* Generate and store a private key on the token */ extern int pkcs11_generate_key(PKCS11_TOKEN * token, int algorithm, unsigned int bits, char *label, unsigned char* id, size_t id_len); /* Get the RSA key modulus size (in bytes) */ extern int pkcs11_get_key_size(PKCS11_KEY *); /* Get the RSA key modules as BIGNUM */ extern int pkcs11_get_key_modulus(PKCS11_KEY *, BIGNUM **); /* Get the RSA key public exponent as BIGNUM */ extern int pkcs11_get_key_exponent(PKCS11_KEY *, BIGNUM **); /* Sign with the RSA private key */ extern int pkcs11_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, PKCS11_KEY * key); /* This function has never been implemented */ extern int pkcs11_verify(int type, const unsigned char *m, unsigned int m_len, unsigned char *signature, unsigned int siglen, PKCS11_KEY * key); /* Encrypts data using the private key */ extern int pkcs11_private_encrypt( int flen, const unsigned char *from, unsigned char *to, PKCS11_KEY * rsa, int padding); /* Decrypts data using the private key */ extern int pkcs11_private_decrypt( int flen, const unsigned char *from, unsigned char *to, PKCS11_KEY * key, int padding); /* Retrieve PKCS11_KEY from an RSA key */ extern PKCS11_KEY *pkcs11_get_ex_data_rsa(const RSA *rsa); /* Retrieve PKCS11_KEY from an EC_KEY */ extern PKCS11_KEY *pkcs11_get_ex_data_ec(const EC_KEY *ec); #endif /* vim: set noexpandtab: */ libp11-0.4.11/src/eng_parse.c0000666000175000017500000002274713625654211012531 00000000000000/* * Copyright (c) 2001 Markus Friedl * Copyright (c) 2002 Juha Yrjölä * Copyright (c) 2002 Olaf Kirch * Copyright (c) 2003 Kevin Stefanik * Copyright (c) 2016-2017 Michał Trojnara * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "engine.h" #include #include #if defined(_WIN32) || defined(_WIN64) #define strncasecmp _strnicmp #endif static int hex_to_bin(ENGINE_CTX *ctx, const char *in, unsigned char *out, size_t *outlen) { size_t left, count = 0; if (!in || *in == '\0') { *outlen = 0; return 1; } left = *outlen; while (*in != '\0') { int byte = 0, nybbles = 2; while (nybbles-- && *in && *in != ':') { char c; byte <<= 4; c = *in++; if ('0' <= c && c <= '9') c -= '0'; else if ('a' <= c && c <= 'f') c = c - 'a' + 10; else if ('A' <= c && c <= 'F') c = c - 'A' + 10; else { ctx_log(ctx, 0, "hex_to_bin(): invalid char '%c' in hex string\n", c); *outlen = 0; return 0; } byte |= c; } if (*in == ':') in++; if (left == 0) { ctx_log(ctx, 0, "hex_to_bin(): hex string too long\n"); *outlen = 0; return 0; } out[count++] = (unsigned char)byte; left--; } *outlen = count; return 1; } /* parse string containing slot and id information */ int parse_slot_id_string(ENGINE_CTX *ctx, const char *slot_id, int *slot, unsigned char *id, size_t *id_len, char **label) { int n, i; /* support for several formats */ #define HEXDIGITS "01234567890ABCDEFabcdef" #define DIGITS "0123456789" /* first: pure hex number (id, slot is undefined) */ if (strspn(slot_id, HEXDIGITS) == strlen(slot_id)) { /* ah, easiest case: only hex. */ if ((strlen(slot_id) + 1) / 2 > *id_len) { ctx_log(ctx, 0, "ID string too long!\n"); return 0; } *slot = -1; return hex_to_bin(ctx, slot_id, id, id_len); } /* second: slot:id. slot is an digital int. */ if (sscanf(slot_id, "%d", &n) == 1) { i = strspn(slot_id, DIGITS); if (slot_id[i] != ':') { ctx_log(ctx, 0, "Could not parse string!\n"); return 0; } i++; if (slot_id[i] == 0) { *slot = n; *id_len = 0; return 1; } if (strspn(slot_id + i, HEXDIGITS) + i != strlen(slot_id)) { ctx_log(ctx, 0, "Could not parse string!\n"); return 0; } /* ah, rest is hex */ if ((strlen(slot_id) - i + 1) / 2 > *id_len) { ctx_log(ctx, 0, "ID string too long!\n"); return 0; } *slot = n; return hex_to_bin(ctx, slot_id + i, id, id_len); } /* third: id_, slot is undefined */ if (strncmp(slot_id, "id_", 3) == 0) { if (strspn(slot_id + 3, HEXDIGITS) + 3 != strlen(slot_id)) { ctx_log(ctx, 0, "Could not parse string!\n"); return 0; } /* ah, rest is hex */ if ((strlen(slot_id) - 3 + 1) / 2 > *id_len) { ctx_log(ctx, 0, "ID string too long!\n"); return 0; } *slot = -1; return hex_to_bin(ctx, slot_id + 3, id, id_len); } /* label_