-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix serialization pub key #491
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -670,7 +670,7 @@ static char *uri_component(const char *name, const char *val, size_t vlen, | |
return c; | ||
} | ||
|
||
char *p11prov_key_to_uri(P11PROV_CTX *ctx, P11PROV_OBJ *key) | ||
char *p11prov_key_to_uri(P11PROV_CTX *ctx, P11PROV_OBJ *key, int selection) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using selection here makes little sense and will lead to incorrect results. I do not see how using selection here improves anything, all you get is a lie. An alternative is to pass a boolean called use_class, and when set to false the URI will not include the keytype. This may be better than trying to lie about the object type. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that this comment makes sense only if we determine that this change is needed at all, which I do not think it is, see the main review comment about this change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this case, we pointed out an error when requesting information about the public key. It's acceptable if you fix it in any way you can. As users of the pkcs11 library, it would be important for us to fix this error. Also important in this pr is the correction of UB when calling free from an object for which memory is allocated using openssl. |
||
{ | ||
P11PROV_SLOTS_CTX *slots; | ||
P11PROV_SLOT *slot; | ||
|
@@ -691,7 +691,11 @@ char *p11prov_key_to_uri(P11PROV_CTX *ctx, P11PROV_OBJ *key) | |
size_t size_hint = 0; | ||
CK_RV ret; | ||
|
||
class = p11prov_obj_get_class(key); | ||
if (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) { | ||
class = CKO_PUBLIC_KEY; | ||
} else { | ||
class = p11prov_obj_get_class(key); | ||
} | ||
slot_id = p11prov_obj_get_slotid(key); | ||
cka_id = p11prov_obj_get_attr(key, CKA_ID); | ||
cka_label = p11prov_obj_get_attr(key, CKA_LABEL); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
#define _GNU_SOURCE | ||
#include <stdbool.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <openssl/core_names.h> | ||
#include <openssl/evp.h> | ||
#include <openssl/store.h> | ||
#include <openssl/rand.h> | ||
|
||
static void hexify(char *out, unsigned char *byte, size_t len) | ||
{ | ||
char c[2], s; | ||
|
||
for (size_t i = 0; i < len; i++) { | ||
out[i * 3] = '%'; | ||
c[0] = byte[i] >> 4; | ||
c[1] = byte[i] & 0x0f; | ||
for (int j = 0; j < 2; j++) { | ||
if (c[j] < 0x0A) { | ||
s = '0'; | ||
} else { | ||
s = 'a' - 10; | ||
} | ||
out[i * 3 + 1 + j] = c[j] + s; | ||
} | ||
} | ||
out[len * 3] = '\0'; | ||
} | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
char *label; | ||
unsigned char id[16]; | ||
char idhex[16 * 3 + 1]; | ||
char *uri; | ||
size_t rsa_bits = 1024; | ||
const char *key_usage = "digitalSignature"; | ||
OSSL_PARAM params[4]; | ||
int miniid; | ||
EVP_PKEY_CTX *ctx; | ||
EVP_PKEY *key = NULL; | ||
BIO *mem; | ||
int maxlen = 4000; | ||
char buf[maxlen]; | ||
const char pub_part[] = "type=public"; | ||
int ret; | ||
|
||
ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", "provider=pkcs11"); | ||
if (ctx == NULL) { | ||
fprintf(stderr, "Failed to init PKEY context for generate\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
ret = EVP_PKEY_keygen_init(ctx); | ||
if (ret != 1) { | ||
fprintf(stderr, "Failed to init keygen\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
ret = RAND_bytes(id, 16); | ||
if (ret != 1) { | ||
fprintf(stderr, "Failed to generate key id\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
miniid = (id[0] << 24) + (id[1] << 16) + (id[2] << 8) + id[3]; | ||
ret = asprintf(&label, "Test-RSA-gen-%08x", miniid); | ||
if (ret == -1) { | ||
fprintf(stderr, "Failed to make label\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
hexify(idhex, id, 16); | ||
ret = asprintf(&uri, "pkcs11:object=%s;id=%s", label, idhex); | ||
if (ret == -1) { | ||
fprintf(stderr, "Failed to compose PKCS#11 URI\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
params[0] = OSSL_PARAM_construct_utf8_string("pkcs11_uri", uri, 0); | ||
params[1] = OSSL_PARAM_construct_utf8_string("pkcs11_key_usage", | ||
(char *)key_usage, 0); | ||
params[2] = | ||
OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &rsa_bits); | ||
params[3] = OSSL_PARAM_construct_end(); | ||
ret = EVP_PKEY_CTX_set_params(ctx, params); | ||
if (ret != 1) { | ||
fprintf(stderr, "Failed to set params\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
ret = EVP_PKEY_generate(ctx, &key); | ||
if (ret != 1) { | ||
fprintf(stderr, "Failed to generate key\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
EVP_PKEY_CTX_free(ctx); | ||
|
||
ctx = EVP_PKEY_CTX_new_from_pkey(NULL, key, "provider=pkcs11"); | ||
if (ctx == NULL) { | ||
fprintf(stderr, "Failed to init PKEY context for sign\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
mem = BIO_new(BIO_s_mem()); | ||
if (mem == NULL) { | ||
fprintf(stderr, "Failed to init BIO\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
ret = EVP_PKEY_print_public(mem, key, 0, NULL); | ||
if (ret != 1) { | ||
fprintf(stderr, "Failed to print public key\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
memset(buf, 0x00, maxlen); | ||
BIO_read(mem, buf, maxlen); | ||
if (strstr(buf, pub_part) == NULL) { | ||
fprintf(stderr, "Incorrect information about the public key\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
BIO_free(mem); | ||
EVP_PKEY_CTX_free(ctx); | ||
EVP_PKEY_free(key); | ||
exit(EXIT_SUCCESS); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this place selection may contain both flags, which means you will always print a URI that strictly refers to the public key.
You need to pass the key class not the selection to get the correct type.