|
Packit |
6b81fa |
/* libp11, a simple layer on to of PKCS#11 API
|
|
Packit |
6b81fa |
* Copyright (C) 2016-2018 MichaĆ Trojnara <Michal.Trojnara@stunnel.org>
|
|
Packit |
6b81fa |
*
|
|
Packit |
6b81fa |
* This library is free software; you can redistribute it and/or
|
|
Packit |
6b81fa |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
6b81fa |
* License as published by the Free Software Foundation; either
|
|
Packit |
6b81fa |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
6b81fa |
*
|
|
Packit |
6b81fa |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
6b81fa |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
6b81fa |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
6b81fa |
* Lesser General Public License for more details.
|
|
Packit |
6b81fa |
*
|
|
Packit |
6b81fa |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
6b81fa |
* License along with this library; if not, write to the Free Software
|
|
Packit |
6b81fa |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
#include "libp11-int.h"
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* The following exported functions are *not* implemented here:
|
|
Packit |
6b81fa |
* PKCS11_get_rsa_method
|
|
Packit |
6b81fa |
* PKCS11_get_ecdsa_method
|
|
Packit |
6b81fa |
* PKCS11_ecdsa_method_free
|
|
Packit |
6b81fa |
* PKCS11_get_ec_key_method
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* External interface to the libp11 features */
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
PKCS11_CTX *PKCS11_CTX_new(void)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
return pkcs11_CTX_new();
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
void PKCS11_CTX_init_args(PKCS11_CTX *ctx, const char *init_args)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_fork(ctx) < 0)
|
|
Packit |
6b81fa |
return;
|
|
Packit |
6b81fa |
pkcs11_CTX_init_args(ctx, init_args);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_CTX_load(PKCS11_CTX *ctx, const char *ident)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_fork(ctx) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_CTX_load(ctx, ident);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
void PKCS11_CTX_unload(PKCS11_CTX *ctx)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_fork(ctx) < 0)
|
|
Packit |
6b81fa |
return;
|
|
Packit |
6b81fa |
pkcs11_CTX_unload(ctx);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
void PKCS11_CTX_free(PKCS11_CTX *ctx)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_fork(ctx) < 0)
|
|
Packit |
6b81fa |
return;
|
|
Packit |
6b81fa |
pkcs11_CTX_free(ctx);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_open_session(PKCS11_SLOT *slot, int rw)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_slot_fork(slot) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_open_session(slot, rw, 0);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_enumerate_slots(PKCS11_CTX *ctx,
|
|
Packit |
6b81fa |
PKCS11_SLOT **slotsp, unsigned int *nslotsp)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_fork(ctx) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_enumerate_slots(ctx, slotsp, nslotsp);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
unsigned long PKCS11_get_slotid_from_slot(PKCS11_SLOT *slot)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_slot_fork(slot) < 0)
|
|
Packit |
6b81fa |
return 0L;
|
|
Packit |
6b81fa |
return pkcs11_get_slotid_from_slot(slot);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
void PKCS11_release_all_slots(PKCS11_CTX *ctx,
|
|
Packit |
6b81fa |
PKCS11_SLOT *slots, unsigned int nslots)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_fork(ctx) < 0)
|
|
Packit |
6b81fa |
return;
|
|
Packit |
6b81fa |
pkcs11_release_all_slots(ctx, slots, nslots);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
PKCS11_SLOT *PKCS11_find_token(PKCS11_CTX *ctx,
|
|
Packit |
6b81fa |
PKCS11_SLOT *slots, unsigned int nslots)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_fork(ctx) < 0)
|
|
Packit |
6b81fa |
return NULL;
|
|
Packit |
6b81fa |
return pkcs11_find_token(ctx, slots, nslots);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
PKCS11_SLOT *PKCS11_find_next_token(PKCS11_CTX *ctx,
|
|
Packit |
6b81fa |
PKCS11_SLOT *slots, unsigned int nslots,
|
|
Packit |
6b81fa |
PKCS11_SLOT *current)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_fork(ctx) < 0)
|
|
Packit |
6b81fa |
return NULL;
|
|
Packit |
6b81fa |
return pkcs11_find_next_token(ctx, slots, nslots, current);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_is_logged_in(PKCS11_SLOT *slot, int so, int *res)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_slot_fork(slot) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_is_logged_in(slot, so, res);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_login(PKCS11_SLOT *slot, int so, const char *pin)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_slot_fork(slot) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_login(slot, so, pin, 0);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_logout(PKCS11_SLOT *slot)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_slot_fork(slot) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_logout(slot);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_enumerate_keys(PKCS11_TOKEN *token,
|
|
Packit |
6b81fa |
PKCS11_KEY **keys, unsigned int *nkeys)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_token_fork(token) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_enumerate_keys(token, CKO_PRIVATE_KEY, keys, nkeys);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_remove_key(PKCS11_KEY *key)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_key_fork(key) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_remove_key(key);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_enumerate_public_keys(PKCS11_TOKEN *token,
|
|
Packit |
6b81fa |
PKCS11_KEY **keys, unsigned int *nkeys)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_token_fork(token) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_enumerate_keys(token, CKO_PUBLIC_KEY, keys, nkeys);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_get_key_type(PKCS11_KEY *key)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_key_fork(key) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_get_key_type(key);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
EVP_PKEY *PKCS11_get_private_key(PKCS11_KEY *key)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_key_fork(key) < 0)
|
|
Packit |
6b81fa |
return NULL;
|
|
Packit |
6b81fa |
return pkcs11_get_key(key, 1);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
EVP_PKEY *PKCS11_get_public_key(PKCS11_KEY *key)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_key_fork(key) < 0)
|
|
Packit |
6b81fa |
return NULL;
|
|
Packit |
6b81fa |
return pkcs11_get_key(key, 0);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
PKCS11_CERT *PKCS11_find_certificate(PKCS11_KEY *key)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_key_fork(key) < 0)
|
|
Packit |
6b81fa |
return NULL;
|
|
Packit |
6b81fa |
return pkcs11_find_certificate(key);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
PKCS11_KEY *PKCS11_find_key(PKCS11_CERT *cert)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_cert_fork(cert) < 0)
|
|
Packit |
6b81fa |
return NULL;
|
|
Packit |
6b81fa |
return pkcs11_find_key(cert);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_enumerate_certs(PKCS11_TOKEN *token,
|
|
Packit |
6b81fa |
PKCS11_CERT **certs, unsigned int *ncerts)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_token_fork(token) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_enumerate_certs(token, certs, ncerts);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_remove_certificate(PKCS11_CERT *cert)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_cert_fork(cert) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_remove_certificate(cert);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_init_token(PKCS11_TOKEN *token, const char *pin,
|
|
Packit |
6b81fa |
const char *label)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_token_fork(token) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_init_token(token, pin, label);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_init_pin(PKCS11_TOKEN *token, const char *pin)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_token_fork(token) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_init_pin(token, pin);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_change_pin(PKCS11_SLOT *slot,
|
|
Packit |
6b81fa |
const char *old_pin, const char *new_pin)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_slot_fork(slot) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_change_pin(slot, old_pin, new_pin);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_store_private_key(PKCS11_TOKEN *token,
|
|
Packit |
6b81fa |
EVP_PKEY *pk, char *label, unsigned char *id, size_t id_len)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_token_fork(token) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_store_private_key(token, pk, label, id, id_len);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_store_public_key(PKCS11_TOKEN *token,
|
|
Packit |
6b81fa |
EVP_PKEY *pk, char *label, unsigned char *id, size_t id_len)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_token_fork(token) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_store_public_key(token, pk, label, id, id_len);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_store_certificate(PKCS11_TOKEN *token, X509 *x509,
|
|
Packit |
6b81fa |
char *label, unsigned char *id, size_t id_len,
|
|
Packit |
6b81fa |
PKCS11_CERT **ret_cert)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_token_fork(token) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_store_certificate(token, x509, label, id, id_len, ret_cert);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_seed_random(PKCS11_SLOT *slot, const unsigned char *s, unsigned int s_len)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_slot_fork(slot) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_seed_random(slot, s, s_len);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_generate_random(PKCS11_SLOT *slot, unsigned char *r, unsigned int r_len)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_slot_fork(slot) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_generate_random(slot, r, r_len);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
void ERR_load_PKCS11_strings(void)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
|
Packit |
6b81fa |
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
|
Packit |
6b81fa |
#endif
|
|
Packit |
6b81fa |
ERR_load_P11_strings();
|
|
Packit |
6b81fa |
ERR_load_CKR_strings();
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_set_ui_method(PKCS11_CTX *ctx, UI_METHOD *ui_method, void *ui_user_data)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_fork(ctx) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_set_ui_method(ctx, ui_method, ui_user_data);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* External interface to the deprecated features */
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_generate_key(PKCS11_TOKEN *token,
|
|
Packit |
6b81fa |
int algorithm, unsigned int bits,
|
|
Packit |
6b81fa |
char *label, unsigned char *id, size_t id_len)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_token_fork(token) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_generate_key(token, algorithm, bits, label, id, id_len);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_get_key_size(PKCS11_KEY *key)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_key_fork(key) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_get_key_size(key);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_get_key_modulus(PKCS11_KEY *key, BIGNUM **bn)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_key_fork(key) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_get_key_modulus(key, bn);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_get_key_exponent(PKCS11_KEY *key, BIGNUM **bn)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_key_fork(key) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_get_key_exponent(key, bn);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_sign(int type, const unsigned char *m, unsigned int m_len,
|
|
Packit |
6b81fa |
unsigned char *sigret, unsigned int *siglen, PKCS11_KEY *key)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_key_fork(key) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_sign(type, m, m_len, sigret, siglen, key);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
|
|
Packit |
6b81fa |
PKCS11_KEY *key, int padding)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_key_fork(key) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_private_encrypt(flen, from, to, key, padding);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
|
|
Packit |
6b81fa |
PKCS11_KEY *key, int padding)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
if (check_key_fork(key) < 0)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
return pkcs11_private_decrypt(flen, from, to, key, padding);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int PKCS11_verify(int type, const unsigned char *m, unsigned int m_len,
|
|
Packit |
6b81fa |
unsigned char *signature, unsigned int siglen, PKCS11_KEY *key)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
(void)type;
|
|
Packit |
6b81fa |
(void)m;
|
|
Packit |
6b81fa |
(void)m_len;
|
|
Packit |
6b81fa |
(void)signature;
|
|
Packit |
6b81fa |
(void)siglen;
|
|
Packit |
6b81fa |
(void)key;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* PKCS11 calls go here */
|
|
Packit |
6b81fa |
P11err(P11_F_PKCS11_VERIFY, P11_R_NOT_SUPPORTED);
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* vim: set noexpandtab: */
|