diff --git a/src/decoder.c b/src/decoder.c index 822c179f..34a2c7ad 100644 --- a/src/decoder.c +++ b/src/decoder.c @@ -12,7 +12,7 @@ #include #include -#define MAX_OID_LEN 64 +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) typedef struct p11prov_decoder_ctx { P11PROV_CTX *provctx; @@ -20,9 +20,78 @@ typedef struct p11prov_decoder_ctx { bool invalid; } P11PROV_DECODER_CTX; +static int p11prov_obj_to_ossl_obj(P11PROV_OBJ *obj, OSSL_PARAM params[4]) +{ + int object_type; + const char *data_type; + void *reference = NULL; + size_t reference_len; + CK_KEY_TYPE type; + CK_ATTRIBUTE *cert = NULL; + switch (p11prov_obj_get_class(obj)) { + case CKO_PUBLIC_KEY: + case CKO_PRIVATE_KEY: + object_type = OSSL_OBJECT_PKEY; + type = p11prov_obj_get_key_type(obj); + switch (type) { + case CKK_RSA: + data_type = P11PROV_NAME_RSA; + break; + case CKK_EC: + data_type = P11PROV_NAME_EC; + break; + case CKK_EC_EDWARDS: + switch (p11prov_obj_get_key_bit_size(obj)) { + case ED448_BIT_SIZE: + data_type = ED448; + break; + case ED25519_BIT_SIZE: + data_type = ED25519; + break; + default: + return RET_OSSL_ERR; + } + break; + default: + return RET_OSSL_ERR; + } + p11prov_obj_to_store_reference(obj, &reference, &reference_len); + if (!reference) { + return RET_OSSL_ERR; + } + break; + case CKO_CERTIFICATE: + object_type = OSSL_OBJECT_CERT; + data_type = "CERTIFICATE"; + cert = p11prov_obj_get_attr(obj, CKA_VALUE); + if (!cert) { + return RET_OSSL_ERR; + } + break; + default: + return RET_OSSL_ERR; + } + + params[0] = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type); + params[1] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, + (char *)data_type, 0); + if (reference) { + /* giving away the object by reference */ + params[2] = OSSL_PARAM_construct_octet_string( + OSSL_OBJECT_PARAM_REFERENCE, reference, reference_len); + } else if (cert) { + params[2] = OSSL_PARAM_construct_octet_string( + OSSL_OBJECT_PARAM_DATA, cert->pValue, cert->ulValueLen); + } else { + return RET_OSSL_ERR; + } + params[3] = OSSL_PARAM_construct_end(); + return RET_OSSL_OK; +} + static bool decoder_ctx_accepts_decoded_object(P11PROV_DECODER_CTX *ctx) { - return (!ctx->invalid) && (ctx->object == NULL); + return (!ctx->invalid) && (!ctx->object); } static void decoder_ctx_object_free(struct p11prov_decoder_ctx *ctx) @@ -39,7 +108,7 @@ static void *p11prov_decoder_newctx(void *provctx) P11PROV_DECODER_CTX *dctx; cprov = provctx; dctx = OPENSSL_zalloc(sizeof(P11PROV_DECODER_CTX)); - if (dctx == NULL) { + if (!dctx) { return NULL; } @@ -61,7 +130,7 @@ static CK_RV p11prov_decoder_ctx_store_obj(void *pctx, P11PROV_OBJ *obj) if (!decoder_ctx_accepts_decoded_object(ctx)) { P11PROV_raise(ctx->provctx, CKR_GENERAL_ERROR, - "Invalid decoder context"); + "decoder context does not accept any objects"); ctx->invalid = 1; decoder_ctx_object_free(ctx); p11prov_obj_free(obj); @@ -69,22 +138,15 @@ static CK_RV p11prov_decoder_ctx_store_obj(void *pctx, P11PROV_OBJ *obj) } P11PROV_debug("Adding object (handle:%lu)", p11prov_obj_get_handle(obj)); - if (p11prov_obj_get_class(obj) != CKO_PRIVATE_KEY) { - P11PROV_raise(ctx->provctx, CKR_ARGUMENTS_BAD, - "Object must be private key"); - p11prov_obj_free(obj); - return CKR_ARGUMENTS_BAD; - } - ctx->object = obj; return CKR_OK; } -static CK_RV p11prov_decoder_load_pkey(P11PROV_DECODER_CTX *ctx, - const char *inuri, - OSSL_PASSPHRASE_CALLBACK *pw_cb, - void *pw_cbarg) +static CK_RV p11prov_decoder_load_obj(P11PROV_DECODER_CTX *ctx, + const char *inuri, + OSSL_PASSPHRASE_CALLBACK *pw_cb, + void *pw_cbarg) { P11PROV_URI *parsed_uri = NULL; CK_RV ret = CKR_GENERAL_ERROR; @@ -93,20 +155,19 @@ static CK_RV p11prov_decoder_load_pkey(P11PROV_DECODER_CTX *ctx, CK_SLOT_ID nextid = CK_UNAVAILABLE_INFORMATION; if (!decoder_ctx_accepts_decoded_object(ctx)) { - P11PROV_debug("Invalid context state"); - P11PROV_raise(ctx->provctx, CKR_GENERAL_ERROR, "Invalid initial state"); + P11PROV_debug("Invalid initial state"); goto done; } parsed_uri = p11prov_parse_uri(ctx->provctx, inuri); - if (parsed_uri == NULL) { - P11PROV_raise(ctx->provctx, CKR_GENERAL_ERROR, "Failed to parse URI"); + if (!parsed_uri) { + P11PROV_debug("Failed to parse URI"); goto done; } ret = p11prov_ctx_status(ctx->provctx); if (ret != CKR_OK) { - P11PROV_raise(ctx->provctx, ret, "Invalid context status"); + P11PROV_debug("Invalid context status"); goto done; } @@ -146,20 +207,13 @@ static CK_RV p11prov_decoder_load_pkey(P11PROV_DECODER_CTX *ctx, if (ctx->invalid) { ret = CKR_GENERAL_ERROR; - P11PROV_raise(ctx->provctx, ret, "Invalid context status"); + P11PROV_debug("Invalid context status"); goto done; } if (!ctx->object) { ret = CKR_GENERAL_ERROR; - P11PROV_raise(ctx->provctx, ret, "No matching object stored"); - goto done; - } - - if (p11prov_obj_get_class(ctx->object) != CKO_PRIVATE_KEY) { - ret = CKR_ARGUMENTS_BAD; - P11PROV_raise(ctx->provctx, ret, - "Referenced object is not a private key"); + P11PROV_debug("No matching object stored"); goto done; } @@ -174,185 +228,166 @@ static CK_RV p11prov_decoder_load_pkey(P11PROV_DECODER_CTX *ctx, return ret; } -static int -p11prov_decoder_decode_p11pkey(CK_KEY_TYPE desired_key_type, void *inctx, - OSSL_CORE_BIO *cin, int selection, - OSSL_CALLBACK *object_cb, void *object_cbarg, - OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +static int obj_desc_verify(P11PROV_PK11_URI *obj) { - P11PROV_DECODER_CTX *ctx = inctx; - P11PROV_PK11_URI *key = NULL; - BIO *bin; - int ret = 0; - const char *uri = NULL; + const char *desc = NULL; + int desc_len; + desc = (const char *)ASN1_STRING_get0_data(obj->desc); + desc_len = ASN1_STRING_length(obj->desc); + if (!desc || desc_len <= 0) { + P11PROV_debug("Failed to get description"); + return RET_OSSL_ERR; + } - P11PROV_debug("P11 KEY DECODER DECODE (selection:0x%x)", selection); - if ((bin = BIO_new_from_core_bio(p11prov_ctx_get_libctx(ctx->provctx), cin)) - == NULL) { - P11PROV_debug("P11 KEY DECODER BIO_new_from_core_bio failed"); - goto done; + if (desc_len != (sizeof(P11PROV_DESCS_URI_FILE) - 1) + || 0 != strncmp(desc, P11PROV_DESCS_URI_FILE, desc_len)) { + P11PROV_debug("Description string does not match"); + return RET_OSSL_ERR; } + return RET_OSSL_OK; +} - const char *data_type = NULL; - switch (desired_key_type) { - case CKK_RSA: - data_type = P11PROV_NAME_RSA; - break; - case CKK_EC: - data_type = P11PROV_NAME_EC; - break; - default: - ret = 0; - P11PROV_raise(ctx->provctx, CKR_ARGUMENTS_BAD, "Unsupported key type"); +static int p11prov_der_decoder_p11prov_obj_decode( + const char *desired_data_type, void *inctx, OSSL_CORE_BIO *cin, + int selection, OSSL_CALLBACK *object_cb, void *object_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + P11PROV_DECODER_CTX *const ctx = inctx; + P11PROV_PK11_URI *obj = NULL; + BIO *bin; + int ret = RET_OSSL_CARRY_ON_DECODING; + const char *uri = NULL; + int uri_len; + + bin = BIO_new_from_core_bio(p11prov_ctx_get_libctx(ctx->provctx), cin); + if (!bin) { + P11PROV_debug("P11 DECODER BIO_new_from_core_bio failed"); goto done; } const unsigned char *der; long der_len = BIO_get_mem_data(bin, &der); if (der_len <= 0) { - P11PROV_debug("P11 KEY DECODER BIO_get_mem_data failed"); - ret = 1; + P11PROV_debug("P11 DECODER BIO_get_mem_data failed"); goto done; } - if ((key = d2i_P11PROV_PK11_URI(NULL, &der, der_len)) == NULL) { + obj = d2i_P11PROV_PK11_URI(NULL, &der, der_len); + if (!obj) { P11PROV_debug("P11 KEY DECODER d2i_P11PROV_PK11_URI failed"); - ret = 1; goto done; } - char oid_txt[MAX_OID_LEN]; - if (OBJ_obj2txt(oid_txt, sizeof(oid_txt), key->type, 1) > 0) { - P11PROV_debug("P11 KEY DECODER got OID %s", oid_txt); - } else { - P11PROV_debug("P11 KEY DECODER OBJ_obj2txt failed"); + if (!obj_desc_verify(obj)) { goto done; } - uri = (const char *)ASN1_STRING_get0_data(key->uri); - if (uri == NULL) { - P11PROV_raise(ctx->provctx, CKR_GENERAL_ERROR, "Failed to get URI"); + uri = (const char *)ASN1_STRING_get0_data(obj->uri); + uri_len = ASN1_STRING_length(obj->uri); + /* todo check string ends in \0 */ + if (!uri || uri_len <= 0) { + P11PROV_debug("Failed to get URI"); goto done; } - if (p11prov_decoder_load_pkey(ctx, uri, pw_cb, pw_cbarg) != CKR_OK) { - P11PROV_debug("P11 KEY DECODER p11prov_decoder_load_key failed"); + if (p11prov_decoder_load_obj(ctx, uri, pw_cb, pw_cbarg) != CKR_OK) { goto done; } - if (p11prov_obj_get_key_type(ctx->object) != desired_key_type) { - P11PROV_debug( - "P11 KEY DECODER p11prov_decoder_load_key wrong key type"); - ret = 1; + OSSL_PARAM params[4]; + if (!p11prov_obj_to_ossl_obj(ctx->object, params)) { + P11PROV_debug("Failed to turn p11prov obj into an OSSL_OBJECT"); goto done; - } - - P11PROV_debug("P11 KEY DECODER p11prov_decoder_load_key OK"); + }; - void *key_reference = NULL; - size_t key_reference_sz = 0; - p11prov_obj_to_store_reference(ctx->object, &key_reference, - &key_reference_sz); - - int object_type = OSSL_OBJECT_PKEY; - OSSL_PARAM params[4]; - params[0] = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type); - params[1] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, - (char *)data_type, 0); - /* The address of the key becomes the octet string */ - params[2] = OSSL_PARAM_construct_octet_string( - OSSL_OBJECT_PARAM_REFERENCE, key_reference, key_reference_sz); - params[3] = OSSL_PARAM_construct_end(); - object_cb(params, object_cbarg); + if (0 == strcmp(params[1].key, "data-type") + && 0 == strcmp(params[1].data, desired_data_type)) { + ret = object_cb(params, object_cbarg); + } done: decoder_ctx_object_free(ctx); - P11PROV_PK11_URI_free(key); + P11PROV_PK11_URI_free(obj); BIO_free(bin); - P11PROV_debug("P11 KEY DECODER RESULT=%d", ret); + P11PROV_debug("der decoder (cary on:%d)", ret); return ret; } -static int p11prov_der_decoder_p11_rsa_decode( +static int p11prov_der_decoder_p11prov_rsa_decode( void *inctx, OSSL_CORE_BIO *cin, int selection, OSSL_CALLBACK *object_cb, void *object_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) { - return p11prov_decoder_decode_p11pkey(CKK_RSA, inctx, cin, selection, - object_cb, object_cbarg, pw_cb, - pw_cbarg); + return p11prov_der_decoder_p11prov_obj_decode( + P11PROV_NAME_RSA, inctx, cin, selection, object_cb, object_cbarg, pw_cb, + pw_cbarg); } -const OSSL_DISPATCH p11prov_der_decoder_p11_rsa_functions[] = { +const OSSL_DISPATCH p11prov_der_decoder_p11prov_rsa_functions[] = { DISPATCH_BASE_DECODER_ELEM(NEWCTX, newctx), DISPATCH_BASE_DECODER_ELEM(FREECTX, freectx), - DISPATCH_DECODER_ELEM(DECODE, der, p11, rsa, decode), + DISPATCH_DECODER_ELEM(DECODE, der, p11prov, rsa, decode), { 0, NULL } }; -static int p11prov_der_decoder_p11_ec_decode( +static int p11prov_der_decoder_p11prov_ec_decode( void *inctx, OSSL_CORE_BIO *cin, int selection, OSSL_CALLBACK *object_cb, void *object_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) { - return p11prov_decoder_decode_p11pkey(CKK_EC, inctx, cin, selection, - object_cb, object_cbarg, pw_cb, - pw_cbarg); + return p11prov_der_decoder_p11prov_obj_decode( + P11PROV_NAME_EC, inctx, cin, selection, object_cb, object_cbarg, pw_cb, + pw_cbarg); } -const OSSL_DISPATCH p11prov_der_decoder_p11_ec_functions[] = { +const OSSL_DISPATCH p11prov_der_decoder_p11prov_ec_functions[] = { DISPATCH_BASE_DECODER_ELEM(NEWCTX, newctx), DISPATCH_BASE_DECODER_ELEM(FREECTX, freectx), - DISPATCH_DECODER_ELEM(DECODE, der, p11, ec, decode), + DISPATCH_DECODER_ELEM(DECODE, der, p11prov, ec, decode), { 0, NULL } }; -static int p11prov_pem_decoder_p11_der_decode( +static int p11prov_pem_decoder_p11prov_der_decode( void *inctx, OSSL_CORE_BIO *cin, int selection, OSSL_CALLBACK *object_cb, void *object_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) { BIO *bin; - char *pem_name; + char *pem_label; char *pem_header; unsigned char *der_data; long der_len; OSSL_PARAM params[3]; - int ret; + int ret = RET_OSSL_CARRY_ON_DECODING; P11PROV_DECODER_CTX *ctx = inctx; - P11PROV_debug("DER DECODER DECODE (selection:0x%x)", selection); - - if ((bin = BIO_new_from_core_bio(p11prov_ctx_get_libctx(ctx->provctx), cin)) - == NULL) { + bin = BIO_new_from_core_bio(p11prov_ctx_get_libctx(ctx->provctx), cin); + if (!bin) { P11PROV_debug("BIO_new_from_core_bio failed"); - return 0; + return RET_OSSL_CARRY_ON_DECODING; } - P11PROV_debug("DER DECODER PEM_read_pio (fpos:%u)", BIO_tell(bin)); - if (PEM_read_bio(bin, &pem_name, &pem_header, &der_data, &der_len) > 0 - && strcmp(pem_name, P11PROV_PRIVKEY_PEM_NAME) == 0) { + P11PROV_debug("PEM_read_pio (fpos:%u)", BIO_tell(bin)); + + if (PEM_read_bio(bin, &pem_label, &pem_header, &der_data, &der_len) > 0 + && strcmp(pem_label, P11PROV_PEM_LABEL) == 0) { params[0] = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, der_data, der_len); params[1] = OSSL_PARAM_construct_utf8_string( - OSSL_OBJECT_PARAM_DATA_STRUCTURE, - (char *)P11PROV_PK11_URI_STRUCTURE, 0); + OSSL_OBJECT_PARAM_DATA_STRUCTURE, (char *)P11PROV_DER_STRUCTURE, 0); params[2] = OSSL_PARAM_construct_end(); ret = object_cb(params, object_cbarg); - } else { - /* We return "empty handed". This is not an error. */ - ret = 1; } - OPENSSL_free(pem_name); + OPENSSL_free(pem_label); OPENSSL_free(pem_header); OPENSSL_free(der_data); BIO_free(bin); - P11PROV_debug("DER DECODER RESULT=%d", ret); + P11PROV_debug("pem decoder (carry on:%d)", ret); return ret; } -const OSSL_DISPATCH p11prov_pem_decoder_p11_der_functions[] = { +const OSSL_DISPATCH p11prov_pem_decoder_p11prov_der_functions[] = { DISPATCH_BASE_DECODER_ELEM(NEWCTX, newctx), DISPATCH_BASE_DECODER_ELEM(FREECTX, freectx), - DISPATCH_DECODER_ELEM(DECODE, pem, p11, der, decode), + DISPATCH_DECODER_ELEM(DECODE, pem, p11prov, der, decode), { 0, NULL } }; diff --git a/src/decoder.h b/src/decoder.h index 2004617f..ee482358 100644 --- a/src/decoder.h +++ b/src/decoder.h @@ -6,6 +6,9 @@ #include +#define RET_OSSL_CARRY_ON_DECODING 1 +#define RET_OSSL_STOP_DECODING 1 + /* DECODERs */ #define DISPATCH_TEXT_DECODER_FN(type, name) \ static OSSL_FUNC_DECODER_##name##_fn p11prov_##type##_DECODER_##name##_text @@ -29,8 +32,8 @@ (void (*)( \ void))p11prov_##type##_decoder_##structure##_##format##_##name \ } -extern const OSSL_DISPATCH p11prov_der_decoder_p11_rsa_functions[]; -extern const OSSL_DISPATCH p11prov_der_decoder_p11_ec_functions[]; -extern const OSSL_DISPATCH p11prov_pem_decoder_p11_der_functions[]; +extern const OSSL_DISPATCH p11prov_der_decoder_p11prov_rsa_functions[]; +extern const OSSL_DISPATCH p11prov_der_decoder_p11prov_ec_functions[]; +extern const OSSL_DISPATCH p11prov_pem_decoder_p11prov_der_functions[]; #endif /* _DECODER_H */ diff --git a/src/encoder.c b/src/encoder.c index bab9d903..389456f0 100644 --- a/src/encoder.c +++ b/src/encoder.c @@ -482,7 +482,10 @@ static P11PROV_PK11_URI *p11prov_encoder_private_key_to_asn1(P11PROV_CTX *pctx, goto error; } - out->type = OBJ_txt2obj(P11PROV_OID_URI, 1); + if (!ASN1_STRING_set(out->desc, P11PROV_DESCS_URI_FILE, + sizeof(P11PROV_DESCS_URI_FILE) - 1)) { + goto error; + } if (!ASN1_STRING_set(out->uri, uri, uri_len)) { goto error; } diff --git a/src/pk11_uri.gen.c b/src/pk11_uri.gen.c index 1fca884e..70bc733e 100644 --- a/src/pk11_uri.gen.c +++ b/src/pk11_uri.gen.c @@ -7,9 +7,8 @@ extern P11PROV_PK11_URI * d2i_P11PROV_PK11_URI(P11PROV_PK11_URI **a, const unsigned char **in, long len); extern int i2d_P11PROV_PK11_URI(const P11PROV_PK11_URI *a, unsigned char **out); extern const ASN1_ITEM *P11PROV_PK11_URI_it(void); - -P11PROV_PK11_URI -*d2i_P11PROV_PK11_URI(P11PROV_PK11_URI **a, const unsigned char **in, long len) +P11PROV_PK11_URI *d2i_P11PROV_PK11_URI(P11PROV_PK11_URI **a, + const unsigned char **in, long len) { return (P11PROV_PK11_URI *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, (P11PROV_PK11_URI_it())); @@ -18,8 +17,7 @@ int i2d_P11PROV_PK11_URI(const P11PROV_PK11_URI *a, unsigned char **out) { return ASN1_item_i2d((const ASN1_VALUE *)a, out, (P11PROV_PK11_URI_it())); } -P11PROV_PK11_URI -*P11PROV_PK11_URI_new(void) +P11PROV_PK11_URI *P11PROV_PK11_URI_new(void) { return (P11PROV_PK11_URI *)ASN1_item_new((P11PROV_PK11_URI_it())); } @@ -29,10 +27,8 @@ void P11PROV_PK11_URI_free(P11PROV_PK11_URI *a) } static const ASN1_TEMPLATE P11PROV_PK11_URI_seq_tt[] = { - - { (0), (0), __builtin_offsetof(P11PROV_PK11_URI, type), "type", - (ASN1_OBJECT_it) }, - + { (0), (0), __builtin_offsetof(P11PROV_PK11_URI, desc), "desc", + (ASN1_VISIBLESTRING_it) }, { (0), (0), __builtin_offsetof(P11PROV_PK11_URI, uri), "uri", (ASN1_UTF8STRING_it) }, }; @@ -53,7 +49,7 @@ extern int PEM_write_bio_P11PROV_PK11_URI(BIO *out, const P11PROV_PK11_URI *x); int PEM_write_bio_P11PROV_PK11_URI(BIO *out, const P11PROV_PK11_URI *x) { return PEM_ASN1_write_bio((i2d_of_void *)i2d_P11PROV_PK11_URI, - P11PROV_PRIVKEY_PEM_NAME, out, x, ((void *)0), + P11PROV_PEM_LABEL, out, x, ((void *)0), ((void *)0), 0, ((void *)0), ((void *)0)); } @@ -61,11 +57,9 @@ extern P11PROV_PK11_URI *PEM_read_bio_P11PROV_PK11_URI(BIO *out, P11PROV_PK11_URI **x, pem_password_cb *cb, void *u); - -P11PROV_PK11_URI -*PEM_read_bio_P11PROV_PK11_URI(BIO *bp, P11PROV_PK11_URI **x, - pem_password_cb *cb, void *u) +P11PROV_PK11_URI *PEM_read_bio_P11PROV_PK11_URI(BIO *bp, P11PROV_PK11_URI **x, + pem_password_cb *cb, void *u) { return PEM_ASN1_read_bio((d2i_of_void *)d2i_P11PROV_PK11_URI, - P11PROV_PRIVKEY_PEM_NAME, bp, (void **)x, cb, u); + P11PROV_PEM_LABEL, bp, (void **)x, cb, u); } diff --git a/src/pk11_uri.h b/src/pk11_uri.h index 255b515e..a32457da 100644 --- a/src/pk11_uri.h +++ b/src/pk11_uri.h @@ -6,12 +6,12 @@ #include -#define P11PROV_OID_URI "2.5.4.83" /* TODO: find a more appropriate oId */ -#define P11PROV_PK11_URI_STRUCTURE "pk11-uri" -#define P11PROV_PRIVKEY_PEM_NAME "PRIVATE KEY PK11-URI" +#define P11PROV_DER_STRUCTURE "pk11-uri" +#define P11PROV_PEM_LABEL "PKCS#11 PROVIDER URI" +#define P11PROV_DESCS_URI_FILE "PKCS#11 Provider URI v1.0" typedef struct { - ASN1_OBJECT *type; + ASN1_VISIBLESTRING *desc; ASN1_UTF8STRING *uri; } P11PROV_PK11_URI; diff --git a/src/pk11_uri.pre b/src/pk11_uri.pre index 38a1daf0..561ae508 100644 --- a/src/pk11_uri.pre +++ b/src/pk11_uri.pre @@ -10,14 +10,14 @@ DECLARE_ASN1_FUNCTIONS(P11PROV_PK11_URI) IMPLEMENT_ASN1_FUNCTIONS(P11PROV_PK11_URI) ASN1_SEQUENCE(P11PROV_PK11_URI) = { - ASN1_SIMPLE(P11PROV_PK11_URI, type, ASN1_OBJECT), + ASN1_SIMPLE(P11PROV_PK11_URI, desc, ASN1_VISIBLESTRING), ASN1_SIMPLE(P11PROV_PK11_URI, uri, ASN1_UTF8STRING), } ASN1_SEQUENCE_END(P11PROV_PK11_URI) DECLARE_PEM_write_bio(P11PROV_PK11_URI, P11PROV_PK11_URI) IMPLEMENT_PEM_write_bio(P11PROV_PK11_URI, P11PROV_PK11_URI, - P11PROV_PRIVKEY_PEM_NAME, P11PROV_PK11_URI) + P11PROV_PEM_LABEL, P11PROV_PK11_URI) DECLARE_PEM_read_bio(P11PROV_PK11_URI, P11PROV_PK11_URI) IMPLEMENT_PEM_read_bio(P11PROV_PK11_URI, P11PROV_PK11_URI, - P11PROV_PRIVKEY_PEM_NAME, P11PROV_PK11_URI) + P11PROV_PEM_LABEL, P11PROV_PK11_URI) diff --git a/src/provider.c b/src/provider.c index 0735a12e..892e4437 100644 --- a/src/provider.c +++ b/src/provider.c @@ -1132,13 +1132,13 @@ static const OSSL_ALGORITHM p11prov_store[] = { static const OSSL_ALGORITHM p11prov_decoders[] = { { "DER", "provider=pkcs11,input=pem", - p11prov_pem_decoder_p11_der_functions }, + p11prov_pem_decoder_p11prov_der_functions }, { "RSA:rsaEncryption", - "provider=pkcs11,input=der,structure=" P11PROV_PK11_URI_STRUCTURE, - p11prov_der_decoder_p11_rsa_functions }, + "provider=pkcs11,input=der,structure=" P11PROV_DER_STRUCTURE, + p11prov_der_decoder_p11prov_rsa_functions }, { "EC:id-ecPublicKey", - "provider=pkcs11,input=der,structure=" P11PROV_PK11_URI_STRUCTURE, - p11prov_der_decoder_p11_ec_functions }, + "provider=pkcs11,input=der,structure=" P11PROV_DER_STRUCTURE, + p11prov_der_decoder_p11prov_ec_functions }, { NULL, NULL, NULL } }; @@ -1326,7 +1326,7 @@ enum p11prov_cfg_enum { P11PROV_CFG_CACHE_KEYS, P11PROV_CFG_QUIRKS, P11PROV_CFG_CACHE_SESSIONS, - P11PROV_CFG_ENCODE_PK11_URI_TO_PEM, + P11PROV_CFG_ENCODE_PROVIDER_URI_TO_PEM, P11PROV_CFG_SIZE, }; @@ -1343,7 +1343,7 @@ static struct p11prov_cfg_names { { "pkcs11-module-cache-keys" }, { "pkcs11-module-quirks" }, { "pkcs11-module-cache-sessions" }, - { "pkcs11-module-encode-key-uri-to-pem" }, + { "pkcs11-module-encode-provider-uri-to-pem" }, }; int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in, @@ -1553,8 +1553,8 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in, } P11PROV_debug("Cache Sessions: %d", ctx->cache_sessions); - if (cfg[P11PROV_CFG_ENCODE_PK11_URI_TO_PEM] != NULL - && strcmp(cfg[P11PROV_CFG_ENCODE_PK11_URI_TO_PEM], "true") == 0) { + if (cfg[P11PROV_CFG_ENCODE_PROVIDER_URI_TO_PEM] != NULL + && strcmp(cfg[P11PROV_CFG_ENCODE_PROVIDER_URI_TO_PEM], "true") == 0) { ctx->encode_pkey_as_pk11_uri = true; } else { ctx->encode_pkey_as_pk11_uri = false; diff --git a/tests/openssl.cnf.in b/tests/openssl.cnf.in index d967f6af..fcddcc69 100644 --- a/tests/openssl.cnf.in +++ b/tests/openssl.cnf.in @@ -24,7 +24,7 @@ activate = 1 module = @libtoollibs@/pkcs11@SHARED_EXT@ pkcs11-module-init-args = configDir=@testsblddir@/tmp.softokn/tokens pkcs11-module-token-pin = file:@testsblddir@/pinfile.txt -#pkcs11-module-encode-key-uri-to-pem +#pkcs11-module-encode-provider-uri-to-pem #pkcs11-module-allow-export #pkcs11-module-load-behavior ##QUIRKS diff --git a/tests/tpem_encoder b/tests/tpem_encoder index add7cc16..39fbe08e 100755 --- a/tests/tpem_encoder +++ b/tests/tpem_encoder @@ -6,28 +6,31 @@ source "${TESTSSRCDIR}/helpers.sh" # We need to configure early loading otherwise no digests are loaded, # and all checks are skipped -sed -e "s/#pkcs11-module-encode-key-uri-to-pem/pkcs11-module-encode-key-uri-to-pem = true/" \ +sed -e "s/#pkcs11-module-encode-provider-uri-to-pem/pkcs11-module-encode-provider-uri-to-pem = true/" \ -e "s/#pkcs11-module-load-behavior/pkcs11-module-load-behavior = early/" \ "${OPENSSL_CONF}" > "${OPENSSL_CONF}.encode_to_pem" OPENSSL_CONF=${OPENSSL_CONF}.encode_to_pem +make-uri-pem() { + export LC_ALL=C -make-pkey-pem() { URI=$1 OUT=$2 + DESC="${3:-PKCS#11 Provider URI v1.0}" - OID="06 03 55 04 53" - URI_HEX=$(printf '%s' "${URI}" | perl -lne 'print unpack "H*", $_') + DESC_HEX=$(printf '%s' "${DESC}" | perl -ne 'print unpack "H*", $_') + URI_HEX=$(printf '%s' "${URI}" | perl -ne 'print unpack "H*", $_') { - echo "-----BEGIN PRIVATE KEY PK11-URI-----" - printf '30 82 %04x %s 0c 82 %04x %s' \ - "$((${#URI} + 9))" \ - "${OID}" \ + echo "-----BEGIN PKCS#11 PROVIDER URI-----" + printf '30 82 %04x 1a 82 %04x %s 0c 82 %04x %s' \ + "$((${#URI} + ${#DESC} + 8))" \ + "${#DESC}" \ + "${DESC_HEX[*]}" \ "${#URI}" \ "${URI_HEX[*]}" \ | tr -d ' ' \ - | perl -lne 'print pack "H*", $_' \ - | base64 - echo "-----END PRIVATE KEY PK11-URI-----" + | perl -ne 'print pack "H*", $_' \ + | base64 + echo "-----END PKCS#11 PROVIDER URI-----" } > "${OUT}" } @@ -53,14 +56,14 @@ sign-verify() { rm "${TMP_FILE}" } +RANDOM_HEX=$(od -A n -N 15 -t x1 /dev/random) +export LABEL_SUFFIX_URI=${RANDOM_HEX// /} + title PARA "Test PEM Encoding RSA support" -make-pkey-pem "${PRIURI}" "${TMPPDIR}/priuri-pkey.pem" +make-uri-pem "${PRIURI}" "${TMPPDIR}/priuri-pkey.pem" sign-verify "${TMPPDIR}/priuri-pkey.pem" "${PUBURI}" "${TMPPDIR}/64krandom.bin" -RANDOM_HEX=$(od -A n -N 15 -t x1 /dev/random) -export LABEL_SUFFIX_URI=${RANDOM_HEX// /} - export ALGORITHM=rsa export ALGORITHM_OPT=rsa_keygen_bits:2048 ossl ' @@ -69,16 +72,15 @@ genpkey -propquery "provider=pkcs11" -pkeyopt "pkcs11_uri:pkcs11:object=Test-PEM-Encode-RSA-${LABEL_SUFFIX_URI}" -out "${TMPPDIR}/rsa-pkey-uri.pem"' -grep -e "-----BEGIN PRIVATE KEY PK11-URI-----" "${TMPPDIR}/rsa-pkey-uri.pem" +grep -e "-----BEGIN PKCS#11 PROVIDER URI-----" "${TMPPDIR}/rsa-pkey-uri.pem" sign-verify "${TMPPDIR}/rsa-pkey-uri.pem" \ "pkcs11:object=Test-PEM-Encode-RSA-${LABEL_SUFFIX_URI}" \ "${TMPPDIR}/64krandom.bin" - title PARA "Test PEM Encoding EC support" -make-pkey-pem "${ECPRIURI}" "${TMPPDIR}/ecpriuri-pkey.pem" +make-uri-pem "${ECPRIURI}" "${TMPPDIR}/ecpriuri-pkey.pem" sign-verify "${TMPPDIR}/ecpriuri-pkey.pem" "${ECPUBURI}" "${TMPPDIR}/64krandom.bin" export ALGORITHM=EC @@ -89,30 +91,70 @@ genpkey -propquery "provider=pkcs11" -pkeyopt "pkcs11_uri:pkcs11:object=Test-PEM-Encode-EC-${LABEL_SUFFIX_URI}" -out "${TMPPDIR}/ec-pkey-uri.pem"' -grep -e "-----BEGIN PRIVATE KEY PK11-URI-----" "${TMPPDIR}/ec-pkey-uri.pem" +grep -e "-----BEGIN PKCS#11 PROVIDER URI-----" "${TMPPDIR}/ec-pkey-uri.pem" sign-verify "${TMPPDIR}/ec-pkey-uri.pem" \ "pkcs11:object=Test-PEM-Encode-EC-${LABEL_SUFFIX_URI}" \ "${TMPPDIR}/64krandom.bin" -title PARA "Test ambiguous key is unusable" +title PARA "Test visible string has to match" +make-uri-pem "${PRIURI}" "${TMPPDIR}/priuri-wrong-version-key.pem" "PKCS#11 Provider URI v2.0" +ossl ' +storeutl + -out "${TMPPDIR}/storeutl-priuri-wrong-version-key.txt" + "${TMPPDIR}/priuri-wrong-version-key.pem"' || : +DATA=$(cat "${TMPPDIR}/storeutl-priuri-wrong-version-key.txt") +if [[ ! ${DATA} =~ "Total found: 0" ]]; then + echo "Should fail because visible string does not match" + exit 1 +fi -make-pkey-pem "${BASEURI}" "${TMPPDIR}/baseuri-key.pem" -FAIL=0 +make-uri-pem "${PRIURI}" "${TMPPDIR}/priuri-too-long-key.pem" "PKCS#11 Provider URI v1.0-INVALID" ossl ' -pkey -in "${TMPPDIR}/baseuri-key.pem"' || FAIL=1 -if [ $FAIL -eq 0 ]; then - echo "Should fail because the pem references multiple and/or non-private keys" +storeutl + -out "${TMPPDIR}/storeutl-priuri-too-long-key.txt" + "${TMPPDIR}/priuri-too-long-key.pem"' || : +DATA=$(cat "${TMPPDIR}/storeutl-priuri-too-long-key.txt") +if [[ ! ${DATA} =~ "Total found: 0" ]]; then + echo "Should fail because visible string does not match" exit 1 fi -make-pkey-pem "${PUBURI}" "${TMPPDIR}/puburi-key.pem" +make-uri-pem "${PRIURI}" "${TMPPDIR}/priuri-too-short-key.pem" "PKCS#11 Provider URI v1" +ossl ' +storeutl + -out "${TMPPDIR}/storeutl-priuri-too-short-key.txt" + "${TMPPDIR}/priuri-too-short-key.pem"' || : +DATA=$(cat "${TMPPDIR}/storeutl-priuri-too-short-key.txt") +if [[ ! ${DATA} =~ "Total found: 0" ]]; then + echo "Should fail because visible string does not match" + exit 1 +fi + + +title PARA "Test public key is usable" +make-uri-pem "${PUBURI}" "${TMPPDIR}/puburi-key.pem" +ossl ' +storeutl + -out "${TMPPDIR}/storeutl-puburi-key.txt" + "${TMPPDIR}/puburi-key.pem"' +DATA=$(cat "${TMPPDIR}/storeutl-puburi-key.txt") +if [[ ! ${DATA} =~ "Total found: 1" ]]; then + echo "Cert not found matching by subject=${subj}" + exit 1 +fi +ossl 'storeutl "${TMPPDIR}/puburi-key.pem"' | grep "Total found: 1" + + +title PARA "Test ambiguous key is unusable" + +make-uri-pem "${BASEURI}" "${TMPPDIR}/baseuri-key.pem" FAIL=0 ossl ' -pkey -in "${TMPPDIR}/puburi-key.pem"' || FAIL=1 +pkey -in "${TMPPDIR}/baseuri-key.pem"' || FAIL=1 if [ $FAIL -eq 0 ]; then - echo "Should fail because the pem references multiple and/or non-private keys" + echo "Should fail for now URI from PEM need to be unique" exit 1 fi