Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ tests/fork-change-slot-prov
tests/rsa-oaep-prov
tests/rsa-pss-sign-prov
tests/store-cert-prov
tests/rsa-keygen
tests/ec-keygen

tests/*.log
tests/*.trs
Expand Down
40 changes: 39 additions & 1 deletion src/eng_back.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,43 @@ static int ENGINE_CTX_ctrl_set_vlog(ENGINE_CTX *ctx, void *cb)
return 1;
}

int ENGINE_CTX_ctrl(ENGINE_CTX *ctx, int cmd, long i, void *p, void (*f)(void))
static int ENGINE_CTX_keygen(ENGINE_CTX *ctx, void *p)
{
int rv;
PKCS11_KGEN_ATTRS *kg_attrs = p;
PKCS11_SLOT* found_slot = NULL;

if (kg_attrs == NULL)
return 0;

/* Delayed libp11 initialization */
if (UTIL_CTX_init_libp11(ctx->util_ctx)) {
ENGerr(ENG_F_CTX_LOAD_OBJECT, ENG_R_INVALID_PARAMETER);
return 0;
}

found_slot = UTIL_CTX_find_token(ctx->util_ctx, kg_attrs->token_label);
if (!found_slot)
return 0;

/* Try logging in */
ERR_clear_error();
if (!(found_slot->token->loginRequired && UTIL_CTX_login(ctx->util_ctx,
found_slot, ctx->ui_method, ctx->ui_data)))
return 0;

rv = PKCS11_keygen(found_slot->token, kg_attrs);
if (rv < 0) {
ENGINE_CTX_log(ctx, LOG_ERR,
"Failed to generate a key pair on the token. Error code: %d\n",
rv);
return 0;
}

return 1;
}

int ENGINE_CTX_ctrl(ENGINE_CTX *ctx, int cmd, long i, void *p, void (*f)())
{
(void)i; /* We don't currently take integer parameters */
(void)f; /* We don't currently take callback parameters */
Expand Down Expand Up @@ -293,6 +329,8 @@ int ENGINE_CTX_ctrl(ENGINE_CTX *ctx, int cmd, long i, void *p, void (*f)(void))
return ENGINE_CTX_ctrl_set_vlog(ctx, p);
case CMD_DEBUG_LEVEL:
return ENGINE_CTX_ctrl_set_debug_level(ctx, (int)i);
case CMD_KEYGEN:
return ENGINE_CTX_keygen(ctx, p);
default:
ENGerr(ENG_F_CTX_ENGINE_CTRL, ENG_R_UNKNOWN_COMMAND);
break;
Expand Down
4 changes: 4 additions & 0 deletions src/eng_front.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ static const ENGINE_CMD_DEFN engine_cmd_defns[] = {
"DEBUG_LEVEL",
"Set the debug level: 0=emerg, 1=alert, 2=crit, 3=err, 4=warning, 5=notice (default), 6=info, 7=debug",
ENGINE_CMD_FLAG_NUMERIC},
{CMD_KEYGEN,
"KEYGEN",
"Generate asymmetric key pair",
ENGINE_CMD_FLAG_INTERNAL},
{0, NULL, NULL, 0}
};

Expand Down
1 change: 1 addition & 0 deletions src/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#define CMD_RE_ENUMERATE (ENGINE_CMD_BASE + 10)
#define CMD_VLOG_A (ENGINE_CMD_BASE + 11)
#define CMD_DEBUG_LEVEL (ENGINE_CMD_BASE + 12)
#define CMD_KEYGEN (ENGINE_CMD_BASE + 13)

typedef struct engine_ctx_st ENGINE_CTX; /* opaque */

Expand Down
10 changes: 7 additions & 3 deletions src/libp11-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,13 @@ extern int pkcs11_generate_random(PKCS11_SLOT_private *, unsigned char *r, unsig
/* Internal implementation of deprecated features */

/* Generate and store a private key on the token */
extern int pkcs11_generate_key(PKCS11_SLOT_private *tpriv,
int algorithm, unsigned int bits,
char *label, unsigned char *id, size_t id_len);
extern int pkcs11_rsa_keygen(PKCS11_SLOT_private *tpriv,
unsigned int bits, const char *label, const unsigned char *id,
size_t id_len, const PKCS11_params* params);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use TYPE *ptr instead of TYPE* ptr to follow the project's convention.


extern int pkcs11_ec_keygen(PKCS11_SLOT_private *tpriv,
const char *curve , const char *label, const unsigned char *id,
size_t id_len, const PKCS11_params* params);

/* Get the RSA key modulus size (in bytes) */
extern int pkcs11_get_key_size(PKCS11_OBJECT_private *);
Expand Down
1 change: 1 addition & 0 deletions src/libp11.exports
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,4 @@ ERR_load_PKCS11_strings
PKCS11_set_ui_method
ERR_get_CKR_code
PKCS11_set_vlog_a_method
PKCS11_keygen
46 changes: 43 additions & 3 deletions src/libp11.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,35 @@ typedef struct PKCS11_ctx_st {
void *_private;
} PKCS11_CTX;

typedef struct PKCS11_ec_kgen_st {
const char *curve;
} PKCS11_EC_KGEN;

typedef struct PKCS11_rsa_kgen_st {
unsigned int bits;
} PKCS11_RSA_KGEN;

typedef struct PKCS11_params {
unsigned char extractable;
unsigned char sensitive;
} PKCS11_params;

typedef struct PKCS11_kgen_attrs_st {
/* Key generation type from OpenSSL. Given the union below this should
* be either EVP_PKEY_EC or EVP_PKEY_RSA
*/
int type;
union {
PKCS11_EC_KGEN *ec;
PKCS11_RSA_KGEN *rsa;
} kgen;
const char *token_label;
const char *key_label;
const unsigned char *key_id;
size_t id_len;
const PKCS11_params *key_params;
} PKCS11_KGEN_ATTRS;

/** PKCS11 ASCII logging callback */
typedef void (*PKCS11_VLOG_A_CB)(int, const char *, va_list);

Expand Down Expand Up @@ -431,20 +460,31 @@ extern void ERR_load_PKCS11_strings(void);
* duplicate the functionality OpenSSL provides for EVP_PKEY objects
*/

/**
* Generate key pair on the token
*
* @param token on which the key should be generated
* @param kgen_attrs struct describing key generation (selection of algorithm,
* algorithm parameters...)
* @retval 0 on success
* @retval -1 error
*/
extern int PKCS11_keygen(PKCS11_TOKEN *token, PKCS11_KGEN_ATTRS *kgen_attrs);

/**
* Generate a private key on the token
*
* @param token token returned by PKCS11_find_token()
* @param algorithm IGNORED (still here for backward compatibility)
* @param bits size of the modulus in bits
* @param algorithm EVP_PKEY_EC any other value select EVP_PKEY_RSA
* @param bits_or_nid size of the modulus in bits or the nid of the curve
* @param label label for this key
* @param id bytes to use as the id value
* @param id_len length of the id value
* @retval 0 success
* @retval -1 error
*/
extern int PKCS11_generate_key(PKCS11_TOKEN *token,
int algorithm, unsigned int bits,
int algorithm, unsigned int bits_or_nid,
char *label, unsigned char *id, size_t id_len);

/* Get the RSA key modulus size (in bytes) */
Expand Down
61 changes: 57 additions & 4 deletions src/p11_front.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <openssl/objects.h>

#include "libp11-int.h"

/* The maximum length of PIN */
#define MAX_PIN_LENGTH 256

/* The following exported functions are *not* implemented here:
* PKCS11_get_rsa_method
* PKCS11_get_ecdsa_method
Expand Down Expand Up @@ -401,14 +405,63 @@ int PKCS11_set_ui_method(PKCS11_CTX *pctx, UI_METHOD *ui_method, void *ui_user_d

/* External interface to the deprecated features */

int PKCS11_generate_key(PKCS11_TOKEN *token,
int algorithm, unsigned int bits,
char *label, unsigned char *id, size_t id_len)
int PKCS11_keygen(PKCS11_TOKEN *token, PKCS11_KGEN_ATTRS *kg)
{
if (token == NULL || kg == NULL || kg->id_len > MAX_PIN_LENGTH)
return -1;
PKCS11_SLOT_private *slot = PRIVSLOT(token->slot);
if (check_slot_fork(slot) < 0)
return -1;
return pkcs11_generate_key(slot, algorithm, bits, label, id, id_len);

switch(kg->type) {
case EVP_PKEY_RSA:
return pkcs11_rsa_keygen(slot, kg->kgen.rsa->bits,
kg->key_label, kg->key_id, kg->id_len, kg->key_params);
case EVP_PKEY_EC:
return pkcs11_ec_keygen(slot, kg->kgen.ec->curve,
kg->key_label, kg->key_id, kg->id_len, kg->key_params);
default:
return -1;
}
}

int PKCS11_generate_key(PKCS11_TOKEN *token,
int algorithm, unsigned int bits_or_nid,
char *label, unsigned char *id, size_t id_len)
{
PKCS11_params key_params = { .extractable = 0, .sensitive = 1 };
PKCS11_EC_KGEN ec_kgen;
PKCS11_RSA_KGEN rsa_kgen;
PKCS11_KGEN_ATTRS kgen_attrs = { 0 };

switch (algorithm) {
case EVP_PKEY_EC:
ec_kgen.curve = OBJ_nid2sn(bits_or_nid);
kgen_attrs = (PKCS11_KGEN_ATTRS){
.type = EVP_PKEY_EC,
.kgen.ec = &ec_kgen,
.token_label = (const char *)token->label,
.key_label = label,
.key_id = (const unsigned char *)id,
.id_len = id_len,
.key_params = &key_params
};
break;

default:
rsa_kgen.bits = bits_or_nid;
kgen_attrs = (PKCS11_KGEN_ATTRS){
.type = EVP_PKEY_RSA,
.kgen.rsa = &rsa_kgen,
.token_label = (const char *)token->label,
.key_label = label,
.key_id = (const unsigned char *)id,
.id_len = id_len,
.key_params = &key_params
};
}

return PKCS11_keygen(token, &kgen_attrs);
}

int PKCS11_get_key_size(PKCS11_KEY *pkey)
Expand Down
Loading
Loading