Skip to content

Commit

Permalink
Add basic encoder support for rsa
Browse files Browse the repository at this point in the history
Only really prints key info when utils like openssl genpkey are given
options like -text

For pem or der format it currently returns error on selection and
specify null functions for encoders.

Signed-off-by: Simo Sorce <[email protected]>
  • Loading branch information
simo5 committed Sep 11, 2022
1 parent 4f00ba6 commit b8bdb2a
Show file tree
Hide file tree
Showing 4 changed files with 296 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ SHARED_EXT=@SHARED_EXT@
pkcs11_provider_la_SOURCES = \
asymmetric_cipher.c \
debug.c \
encoder.c \
exchange.c \
kdf.c \
keymgmt.c \
Expand Down
230 changes: 230 additions & 0 deletions src/encoder.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
/* Copyright (C) 2022 Simo Sorce <[email protected]>
SPDX-License-Identifier: Apache-2.0 */

#include "provider.h"
#include <openssl/bio.h>

static void print_data_buffer(BIO *out, CK_BYTE *buf, int len, int justify,
int linelen)
{
int lines = 1;
int plen = len;
int pidx = 0;

if (linelen) {
lines = len / linelen;
if (len % linelen) {
lines++;
}
plen = linelen;
}

for (int l = 0; l < lines; l++) {
int i;
if (plen > len) {
plen = len;
}
if (justify) {
BIO_printf(out, "%*s", justify, "");
}
for (i = 0; i < plen; i++) {
char c[2];
c[0] = (buf[pidx + i] >> 4);
c[1] = (buf[pidx + i] & 0x0f);
for (int j = 0; j < 2; j++) {
c[j] += '0';
if (c[j] > '9') {
c[j] += ('a' - '0' - 10);
}
}
BIO_write(out, c, 2);
}
len -= plen;
pidx += i;
BIO_write(out, "\n", 1);
}
}

DISPATCH_BASE_ENCODER_FN(rsa, newctx);
DISPATCH_BASE_ENCODER_FN(rsa, freectx);
DISPATCH_TEXT_ENCODER_FN(rsa, encode);

struct p11prov_encoder_ctx {
P11PROV_CTX *provctx;
};

static void *p11prov_rsa_encoder_newctx(void *provctx)
{
struct p11prov_encoder_ctx *ctx;

ctx = OPENSSL_zalloc(sizeof(struct p11prov_encoder_ctx));
if (!ctx) {
P11PROV_raise(provctx, CKR_HOST_MEMORY, "Allocation failed");
return NULL;
}
ctx->provctx = provctx;
return ctx;
}

static void p11prov_rsa_encoder_freectx(void *ctx)
{
OPENSSL_free(ctx);
}

static int p11prov_rsa_encoder_encode_text(void *inctx, OSSL_CORE_BIO *cbio,
const void *inkey,
const OSSL_PARAM key_abstract[],
int selection,
OSSL_PASSPHRASE_CALLBACK *cb,
void *cbarg)
{
struct p11prov_encoder_ctx *ctx = (struct p11prov_encoder_ctx *)inctx;
CK_OBJECT_CLASS class = CK_UNAVAILABLE_INFORMATION;
P11PROV_OBJ *obj = (P11PROV_OBJ *)inkey;
P11PROV_KEY *key;
CK_KEY_TYPE type;
CK_ULONG keysize;
CK_ATTRIBUTE *a;
BIO *out;

P11PROV_debug("RSA Text Encoder");

switch (selection) {
case OSSL_KEYMGMT_SELECT_PRIVATE_KEY:
class = CKO_PRIVATE_KEY;
break;
case OSSL_KEYMGMT_SELECT_PUBLIC_KEY:
class = CKO_PUBLIC_KEY;
break;
case OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS:
return RET_OSSL_ERR;
}

key = p11prov_object_get_key(obj, class);
if (!key) {
P11PROV_raise(ctx->provctx, CKR_GENERAL_ERROR, "Invalid Object class");
return RET_OSSL_ERR;
}

type = p11prov_key_type(key);
if (type != CKK_RSA) {
P11PROV_raise(ctx->provctx, CKR_GENERAL_ERROR, "Invalid Key Type");
return RET_OSSL_ERR;
}

out = BIO_new_from_core_bio(p11prov_ctx_get_libctx(ctx->provctx), cbio);
if (!out) {
P11PROV_raise(ctx->provctx, CKR_GENERAL_ERROR, "Failed to init BIO");
return RET_OSSL_ERR;
}

keysize = p11prov_key_size(key);
if (class == CKO_PRIVATE_KEY) {
BIO_printf(out, "PKCS11 RSA Private Key (%lu bits)\n", keysize * 8);
} else {
BIO_printf(out, "PKCS11 RSA Public Key (%lu bits)\n", keysize * 8);
}

a = p11prov_key_attr(key, CKA_ID);
if (a) {
if (a->ulValueLen > 16) {
BIO_printf(out, " Key ID:\n");
print_data_buffer(out, a->pValue, a->ulValueLen, 4, 16);
} else {
BIO_printf(out, " Key ID: ");
print_data_buffer(out, a->pValue, a->ulValueLen, 0, 0);
}
}
a = p11prov_key_attr(key, CKA_LABEL);
if (a) {
BIO_printf(out, " Label: %*s\n", (int)a->ulValueLen,
(char *)a->pValue);
}
a = p11prov_key_attr(key, CKA_PUBLIC_EXPONENT);
if (a) {
BIO_printf(out, " Exponent: 0x");
print_data_buffer(out, a->pValue, a->ulValueLen, 0, 0);
BIO_write(out, "\n", 1);
}
a = p11prov_key_attr(key, CKA_MODULUS);
if (a) {
BIO_printf(out, " Modulus:\n");
print_data_buffer(out, a->pValue, a->ulValueLen, 4, 16);
}

BIO_free(out);
return RET_OSSL_OK;
}

const OSSL_DISPATCH p11prov_rsa_encoder_text_functions[] = {
DISPATCH_BASE_ENCODER_ELEM(NEWCTX, rsa, newctx),
DISPATCH_BASE_ENCODER_ELEM(FREECTX, rsa, freectx),
DISPATCH_BASE_ENCODER_ELEM(ENCODE, rsa, encode_text),
{ 0, NULL },
};

DISPATCH_ENCODER_FN(rsa, pkcs1, der, does_selection);

static int p11prov_rsa_encoder_pkcs1_der_does_selection(void *inctx,
int selection)
{
switch (selection) {
case OSSL_KEYMGMT_SELECT_PRIVATE_KEY:
return RET_OSSL_ERR;
case OSSL_KEYMGMT_SELECT_PUBLIC_KEY:
return RET_OSSL_ERR;
case OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS:
return RET_OSSL_ERR;
}

return RET_OSSL_ERR;
}

static int p11prov_rsa_encoder_pkcs1_der_encode(
void *inctx, OSSL_CORE_BIO *cbio, const void *inkey,
const OSSL_PARAM key_abstract[], int selection,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
return RET_OSSL_ERR;
}

const OSSL_DISPATCH p11prov_rsa_encoder_pkcs1_der_functions[] = {
DISPATCH_BASE_ENCODER_ELEM(NEWCTX, rsa, newctx),
DISPATCH_BASE_ENCODER_ELEM(FREECTX, rsa, freectx),
DISPATCH_ENCODER_ELEM(DOES_SELECTION, rsa, pkcs1, der, does_selection),
DISPATCH_ENCODER_ELEM(ENCODE, rsa, pkcs1, der, encode),
{ 0, NULL },
};

DISPATCH_ENCODER_FN(rsa, pkcs1, pem, does_selection);

static int p11prov_rsa_encoder_pkcs1_pem_does_selection(void *inctx,
int selection)
{
switch (selection) {
case OSSL_KEYMGMT_SELECT_PRIVATE_KEY:
return RET_OSSL_ERR;
case OSSL_KEYMGMT_SELECT_PUBLIC_KEY:
return RET_OSSL_ERR;
case OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS:
return RET_OSSL_ERR;
}

return RET_OSSL_ERR;
}

static int p11prov_rsa_encoder_pkcs1_pem_encode(
void *inctx, OSSL_CORE_BIO *cbio, const void *inkey,
const OSSL_PARAM key_abstract[], int selection,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
return RET_OSSL_ERR;
}

const OSSL_DISPATCH p11prov_rsa_encoder_pkcs1_pem_functions[] = {
DISPATCH_BASE_ENCODER_ELEM(NEWCTX, rsa, newctx),
DISPATCH_BASE_ENCODER_ELEM(FREECTX, rsa, freectx),
DISPATCH_ENCODER_ELEM(DOES_SELECTION, rsa, pkcs1, pem, does_selection),
DISPATCH_ENCODER_ELEM(ENCODE, rsa, pkcs1, pem, encode),
{ 0, NULL },
};
42 changes: 42 additions & 0 deletions src/provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,46 @@ static const OSSL_ALGORITHM p11prov_kdf[] = {
{ NULL, NULL, NULL, NULL },
};

static const OSSL_ALGORITHM p11prov_encoder[] = {
{
"RSA",
"provider=pkcs11,output=text",
p11prov_rsa_encoder_text_functions,
P11PROV_DESCS_RSA,
},
{
"RSA",
"provider=pkcs11,output=der,structure=pkcs1",
p11prov_rsa_encoder_pkcs1_der_functions,
P11PROV_DESCS_RSA,
},
{
"RSA",
"provider=pkcs11,output=pem,structure=pkcs1",
p11prov_rsa_encoder_pkcs1_pem_functions,
P11PROV_DESCS_RSA,
},
{
P11PROV_NAMES_RSA,
"output=text",
p11prov_rsa_encoder_text_functions,
P11PROV_DESCS_RSA,
},
{
P11PROV_NAMES_RSA,
"output=der,structure=pkcs1",
p11prov_rsa_encoder_pkcs1_der_functions,
P11PROV_DESCS_RSA,
},
{
P11PROV_NAMES_RSA,
"output=pem,structure=pkcs1",
p11prov_rsa_encoder_pkcs1_pem_functions,
P11PROV_DESCS_RSA,
},
{ NULL, NULL, NULL, NULL },
};

static const OSSL_ALGORITHM *
p11prov_query_operation(void *provctx, int operation_id, int *no_cache)
{
Expand All @@ -345,6 +385,8 @@ p11prov_query_operation(void *provctx, int operation_id, int *no_cache)
return p11prov_exchange;
case OSSL_OP_KDF:
return p11prov_kdf;
case OSSL_OP_ENCODER:
return p11prov_encoder;
}
return NULL;
}
Expand Down
23 changes: 23 additions & 0 deletions src/provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,29 @@ extern const OSSL_DISPATCH p11prov_hkdf_exchange_functions[];
extern const void *p11prov_hkdfkm_static_ctx;
extern const OSSL_DISPATCH p11prov_hkdf_kdf_functions[];

/* Encoders */
#define DISPATCH_TEXT_ENCODER_FN(type, name) \
static OSSL_FUNC_encoder_##name##_fn p11prov_##type##_encoder_##name##_text
#define DISPATCH_BASE_ENCODER_FN(type, name) \
DECL_DISPATCH_FUNC(encoder, p11prov_##type##_encoder, name)
#define DISPATCH_BASE_ENCODER_ELEM(NAME, type, name) \
{ \
OSSL_FUNC_ENCODER_##NAME, \
(void (*)(void))p11prov_##type##_encoder_##name \
}
#define DISPATCH_ENCODER_FN(type, structure, format, name) \
DECL_DISPATCH_FUNC(encoder, \
p11prov_##type##_encoder_##structure##_##format, name)
#define DISPATCH_ENCODER_ELEM(NAME, type, structure, format, name) \
{ \
OSSL_FUNC_ENCODER_##NAME, \
(void (*)( \
void))p11prov_##type##_encoder_##structure##_##format##_##name \
}
extern const OSSL_DISPATCH p11prov_rsa_encoder_text_functions[];
extern const OSSL_DISPATCH p11prov_rsa_encoder_pkcs1_der_functions[];
extern const OSSL_DISPATCH p11prov_rsa_encoder_pkcs1_pem_functions[];

/* Utilities to fetch objects from tokens */

struct fetch_attrs {
Expand Down

0 comments on commit b8bdb2a

Please sign in to comment.